
# Omniscio — LLM Documentation Library

> Consulted by Claude Code (and the future in-app chat panel) when users ask "how do I X?" or "what is X?" about Omniscio.

## Purpose — dual audience

This library has **two readers**, and every entry is written for both:

1. **Agents with repo access** (Claude Code, subagents, the in-app chat panel) — use these pages as the authoritative reference when they need to _do something_ in the code or explain a feature.
2. **Outside AIs with no repo access** — a user can copy any single page into ChatGPT, Claude.ai, or the phone web UI and get an accurate answer without ever cloning the repo.

**Implications for authors**:

- Each page must be **self-contained** — explain the feature in prose, not by reference. Don't say "see `X.ts`" without saying _what_ that file does.
- Assume the reader has never seen the app. Describe the UI surface (what pill, which menu, which shortcut) and the user-visible behavior before going into code.
- File-path references are still valuable — an agent _can_ open them — but the page must stand on its own for a reader who can't.
- When a feature changes UX, update its page in the same PR. A silently-stale page is worse than a missing one because agents trust what the library says.

**How to use**: search the table for your topic. If your question isn't covered, Claude Code will say "not in library" and then answer from general knowledge.

> **Reading this in an agent session? Use [ROUTING.md](ROUTING.md) instead.** This file carries a
> paragraph of summary on every row, so it is far too large to return in one read — an agent that
> reads it sees roughly the first tenth of the table and silently misses the rest. `ROUTING.md` is
> the SAME rows with the summary column dropped, generated from the same pages in the same pass, so
> it fits in a single read and nothing routes there that is not here. Keep reading THIS file if you
> are a person browsing, or want the detail on a row.

**Check the two SUBDIRECTORIES before you say "not in library".** The table's rows are the top-level
pages. Two folders hold real library pages that are not individual rows here:

- **`settings/`** — the whole per-setting help corpus, reachable through its hub row _In-app settings help (per-setting "?" docs)_ further down this table.
- **`internal/`** — developer / operator / admin pages. They are deliberately **not linked from this table and not shipped**: excluded from the packaged app, from `extraResources`, and from the public [docs.omniscio.com](https://docs.omniscio.com) mirror, so a link here would both leak them to customers and dangle in the shipped build (locked by `llm-library-internal-docs-not-shipped.test.ts` — do not "fix" it by adding rows). **They are still real library pages for anyone with the repo.** If the question is about a test harness or testing regime, the cloud fleet, the sandbox, gated in-development features, the admin API, fleet telemetry, the Plain Speak harness, provider-breakage checks, the native browser, marketplace review, or the marketing drip / attribution tooling — run `ls docs/llm-library/internal/`, open the matching page, and cite it. That IS "in library". CLAUDE.md's mandated testing-regimes decision tree is one of these pages.

## Start here — find your page

<!-- INDEX TABLE — GENERATED from each page's index_title / index_summary frontmatter. Do not edit the rows by hand: change them on the page, then run `node scripts/rebuild-llm-library-index.mjs`. -->

| Feature | Summary | Link |
| --- | --- | --- |
| Aborted-response recovery (self-healing when the CLI drops a turn) | When the Claude CLI abandons a response mid-flight (process exits, stream ends without result, stall-watchdog timeout) the session used to land in the inbox as a silent `needs_you` with no question — visually identical to a real question, no automated path forward. Now every abort stamps a `response_aborted` marker, a 60-second background scan replays the user's last message through the rate-limit-recovery machinery (2 auto-retries per day, 90s cross-path debounce, counter resets when you send a real message), and an amber **Retry** pill on the session panel force-restarts immediately without waiting for the scan. Schema v256 retro-fills the silent failures you accumulated before upgrading, plus a standalone `scripts/triage-aborted-sessions.mjs` escape hatch. While recovering the session hides as a normal running row, but only for 5 minutes (2026-08-11): past that cap — or when a final answer was fully DELIVERED and only the turn-end signal dropped — it surfaces in Needs You instead of staying camouflaged. On by default; disable the auto-retry via Settings → Sessions or `AMC_DISABLE_ABORTED_RESPONSE_RECOVERY=1` (the label + Retry button stay regardless) | [aborted-response-recovery.md](aborted-response-recovery.md) |
| Deleting your account / starting from scratch | Settings → Accounts → **Delete my account** (type `DELETE` to confirm; only shown when signed in). Removes your Omniscio cloud account **immediately** — sign-in, profile, user-scoped records, Team Chat messages, and your membership of any shared workspace — and clears the copy of your data on **this computer** at the **next launch** (the local database is open and in use while the app runs, so the wipe is staged and applied before the database opens, then you land on a fresh setup). Cleared locally: the whole database and settings file — projects, sessions and their full conversation history, quick replies, recipes and automations, saved logins, notes, attachments and reports. **Kept:** billing history (amounts/timestamps/provider only — no message content — retained as required). Blocked while you are the ONLY owner of a shared workspace (add a co-owner or delete it first). Export your data beforehand via the in-card link — the export covers LOCAL data only, not cloud Team Chat. Signing back in afterwards creates a brand-new EMPTY account and restores nothing; signing in again BEFORE restarting can still show the old data because the clear-out has not run yet. Smaller resets: Supermail's Danger zone → *Reset account data* (re-syncs mail, keeps the account), and plain sign-out (deletes nothing). Keywords: delete account, delete my account, start from scratch, start over, reset account, reset everything, factory reset, wipe my data, erase my data, remove my account, close my account | [account-deletion-and-reset.md](account-deletion-and-reset.md) |
| Account Indicator (lower-left popover order) | What the lower-left account pill shows and how the rows are ordered — active login account pinned at top (active API keys fall through), login accounts ranked by current 5h/7d capacity ascending, then exhausted logins by soonest next-reset time, API keys at the absolute bottom; order recomputes live as usage pushes arrive (no freeze-on-open); footer shows fetch wall-clock + relative-time suffix (`Data from 11:19 AM · 5m ago`) with 30s tick while open and `(stale)` on errored fetches | [account-indicator.md](account-indicator.md) |
| Account Pool (multiple Claude accounts) | Hold multiple Claude logins; silent tiered auto-pick on spawn; sidebar banner + OS alert when every account is exhausted | [account-pool.md](account-pool.md) |
| Sign accounts back in automatically (automated re-login) | Drives the whole Claude sign-in for every account flagged as needing re-login — real Chrome for the page, the connected Gmail for the sign-in link, the code typed for you — and captures each back into the pool; you do only the two clicks Cloudflare and the consent screen require. Post-capture identity assertion means it can never save the WRONG account and call it success. An opt-in setting ("Sign them back in automatically", off by default) checks every three hours and repairs a stale login on its own. Balancing- cohort only; desktop-only; CLI routes POST /accounts/relogin · GET /accounts/relogin/status · POST /accounts/relogin/cancel | [account-relogin.md](account-relogin.md) |
| Default Model by Account Plan (account-tier model defaults) | Opt-in (Settings → Accounts, default off, login accounts only) — at a new Claude session's first message, picks the STARTING model from the account's plan/tier (Max/Team/Enterprise→Opus, Pro→Sonnet, Free→Haiku). Stamped onto the session once so it stays put across rate-limit / load-balance account moves; your per-session and per-project model picks always override it; never touches API-key, SSH, or non-Claude sessions. | [account-tier-model-defaults.md](account-tier-model-defaults.md) |
| Add a Claude account | Sign in via OAuth (Claude.ai login) or paste an `sk-ant-...` API key; supports multiple accounts in the pool with tier-aware auto-pick on session spawn | [add-a-claude-account.md](add-a-claude-account.md) |
| Add a project | Add a folder as a project — Quick Create (new folder under your Default Projects Folder), Browse Existing (pick any folder), or GitHub clone (paste a repo URL); color, icon, group picker | [add-a-project.md](add-a-project.md) |
| Agent action throttles | The former search/Git/install/shell and start-pacing controls are retired, default off, and retained only for settings compatibility; old saved `on` values cannot revive them. Permanent narrow protections remain: Git thread/no-lazy-fetch rules, search exclusions, find batching, worktree authority, compiler policy, OOM safety, and the package-store kernel fence. The optional V2 broker is heavy-only and independently enabled by class. | [agent-action-throttles.md](agent-action-throttles.md) |
| Agent Crews (mission teams of agents that report to a lead) | Any agent session can join a mission crew as its **lead** or a **member**. Joining renames it `[<Crew>] <Label> #<n>`, gives the lead a 15-minute heartbeat and a 6-hour deep review, sends every finished member turn — questions and approvals included — to its lead instead of your inbox (only a permission click, a failure, a failed delivery, a lead-less crew or a lead silent for over an hour reaches you), enlists a session a crew member spawns as a member straight away so it shows on the roster and keeps the name it gives on registering, keeps the lead out of Needs you (its With you view is your conversation with it, with its own check-ins folded behind a Show line, and it asks you things through inbox cards, with an overall update at least hourly), runs helpers without the person-facing prompt, archives a finished helper after 30 idle minutes, asks twice before you archive a lead that still has live helpers, and gives the crew one private board that only its lead and live members can reach. A crew session shows one crew row under its header, the same on desktop and phone: three matching menus — a Settings gear (its role and crew, heartbeat, deep review for a lead, who it reports to, and a link that opens the crew in the Overseers hub), View (Latest / With you / Agent traffic / Everything) and Swarm (every live agent in the crew with its status — click one to open it — plus the crew's message board); on desktop its title row is slim too (no Spawned count; model and cost on a quiet line under the title). Every crew is listed in the Overseers hub with its roster, board and heartbeat settings, and opens on a live Dashboard of its tasks, member statuses and activity (kept by the app, never in a file), beside an All-missions overview of every crew. Heartbeats are editable by the session, its lead or you and apply at the next wake. In-development, on by default — Settings → Lab → Agent crews. Contract: agent-crew-registry-contract. | [agent-crews.md](agent-crews.md) |
| Agent-driven sessions (external AI drives a session) | External AI agents holding the Omniscio bearer token can spawn a brand-new session with `POST /agent/sessions`, get one inbox approval, then drive it through multi-turn dialog under turn + dollar caps; user-revokable any time from the session header. Off by default at Settings → CLI Control | [agent-driven-sessions.md](agent-driven-sessions.md) |
| Agent Email (your agent's own email address) | Give your agent a real Cloudflare-backed email address (`amcmailbox.com`), surfaced as a sidebar entry under Omniscio → Agent Tools. Claim it by picking the name before the @ (live `name@amcmailbox.com` preview + instant validation); names are globally unique on the shared domain, reserved words are blocked, and the name is chosen once. Inbound mail starts or continues a session — receiving turns on automatically when you claim (no restart) with an on/off switch to pause it, gated by a "who can email it" control (Only me / approved senders / Anyone, default Only me; replies on an existing thread always pass); the agent can reply back out (per-account limits, no spoofing, bounce/complaint suppression). It's the primary way to receive email into Omniscio; the older bring-your-own-inbox "Email Inbound" is now framed as an "Advanced" option. In-development — reveal via Settings → Lab toggle or `AMC_SHOW_AGENT_EMAIL=1`. | [agent-email.md](agent-email.md) |
| Agent Firewall (screen tool output for prompt injection) | In-development, off by default. A screening layer that inspects what a tool hands an AI agent — a web page, file, or command output — and flags **prompt injection** (hidden/embedded instructions that try to hijack the agent: "ignore previous instructions", jailbreak framing, secret-exfil directives, invisible/bidi chars, base64-wrapped payloads). Runs as a Claude Code **PostToolUse hook**; on a flag it applies the enforcement level — **Advisory** (warn the agent), **Ask** (default — warn + raise a deduped inbox alert for you), or **Enforce** (tell the agent the content is blocked). Honest limit: it runs *after* the tool, so it **detects + alerts** (content already entered context) — true pre-context prevention is a planned follow-up. Scoped: when on, it screens only **externally-spawned** sessions (recipes / webhooks / cloud runners / router-spawned) **plus opt-in projects**, never your own interactive agents by default; fail-open + skip-when-busy so it can't wedge or slow an agent (`AMC_DISABLE_AGENT_FIREWALL=1`). The classifier is **pluggable**: a zero-dependency heuristic detector (default) or a **Shieldstral 3B** local-sidecar adapter (off-label content-safety model, GPU eval deferred); raw content never leaves the box. Reveal via Settings → Features (Lab) or `AMC_SHOW_AGENT_FIREWALL=1`; level via `agentFirewallEnforcementLevel`. Contract: agent-firewall-contract. | [agent-firewall.md](agent-firewall.md) |
| Agent Friction (what keeps costing your agents time) | A read-only developer-tools sidebar panel over the agent friction ledger: the problems agents keep hitting, collapsed onto ONE row per problem so that many agents hitting one wall read as one problem with a count, ranked by measured minutes lost and by how often it fires. Each row carries the severity, the report count, and the source split (an agent judged it worth reporting / a known failure seam fired / passive tool-error telemetry) - a harness-only cluster has nobody vouching for it and says so. Expand a row for the individual reports plus the command and output captured at first sighting; all agent-authored text renders as plain text. The health line tells four states apart that would otherwise all be an empty screen: collection off / nothing ever arrived / this build cannot answer / genuinely quiet. OPT-IN - one switch (`agentFrictionReportsEnabled`, default off) gates the panel, `POST /friction`, the automatic capture and the panel handlers, resolved everywhere through one shared predicate. Read-only: closing a problem out stays on the CLI. Non-spawnable built-in virtual project under the Developer Tools group. | [agent-friction.md](agent-friction.md) |
| Paved road (worktree git operations over the CLI) | The sanctioned way for an agent to do git work on its own worktree through the local CLI control server: `GET /worktrees/:id/status` to read the branch's real state, `POST /worktrees/:id/commit` to stage and commit named files, `/sync` to rebase onto the shared branch, `/ready` to stamp the SHA-bound ready-to-merge tag, `/gate-hold` and its release to mark a gate in progress, `/adopt` and `/release` to hand a worktree over, `/reclaim` to retire a stranded one, and `/remove` to retire your own. | [agent-git-paved-road.md](agent-git-paved-road.md) |
| Agent input modal (a session asks you to fill a value it must never see, e.g. an API key) | When a session is blocked on a value only you can provide — most often an **API key** the AI must never see — it pops a **well-labeled modal** in the desktop app instead of telling you to open Settings: you type the value, press Enter, and it saves through the exact same encrypted Settings path as a manual save. The AI **never sees what you typed** — it learns only `saved`/`cancelled`/`timeout`. The modal shows the app's own "Saving to: <setting>" destination label (a session can't fake where the value lands) + which session is asking; secret values are masked with a reveal toggle. It never steals focus (appears when you return to the app) and queues one at a time. On by default; disable at Settings → Features → "Allow agents to ask you for a value". Agents trigger it via `POST /input-request` (bounded poll for the outcome; the value is submitted on a desktop-only, human-only channel no agent can reach) — an agent can *ask*, only a person can *answer*. For an **AI-provider API key** the modal validates the key live against the provider before saving (valid saves; a rejected key is blocked; an unreachable provider offers **Save anyway**) — reusing the Settings key-field check. Contract: agent-input-contract. | [agent-input-modal.md](agent-input-modal.md) |
| Agent Instructions Sync (mirror CLAUDE.md to AGENTS.md, etc.) | Per-project auto-sync that mirrors your canonical CLAUDE.md (or AGENTS.md) into the other agent-instructions filenames (AGENTS.md, GEMINI.md, .cursorrules, .clinerules/base.md, .github/copilot-instructions.md, .windsurfrules) so every coding agent reads the same rules — banner-stamped writes, drift surfaced both in the sidebar (clickable amber chip) AND as an inbox alert with a one-click Review & fix, 3-action conflict dialog (discard / promote / stop syncing). Default off; flip the toggle off and the mirror files stay on disk untouched | [agent-instructions-sync.md](agent-instructions-sync.md) |
| Agent lanes (your agent talking to a teammate's) | Lets your agents and a teammate's agents message each other with no person in the loop. An agent names the teammate and says what it wants — aimed at one of their sessions or at their general session, which starts itself — and the answer comes back to the agent that asked. It travels over a private second tab on your direct message with that teammate: neither person is notified, a quiet dot marks activity, and one inbox summary a day says what the agents worked out. Nothing flows until you have both approved each other — one teammate at a time, or everyone in your workspace (never guests) with one switch — and approving is always a person's click, never an agent's. There is no message limit unless you set one. If a teammate's computer turns a message away, the asking agent is told why. In development: on for every Omniscio developer, off for everyone else. | [agent-lanes.md](agent-lanes.md) |
| Agent reply formatting and showing images | The formatting an AI reply can actually use — beyond ordinary markdown, a **fixed set** of GitHub-style shapes: callouts (`> [!NOTE]` / `[!TIP]` / `[!IMPORTANT]` / `[!WARNING]` / `[!CAUTION]`), centred and right-aligned blocks, images at a chosen width instead of full size, collapsible sections, keyboard key caps drawn the way the rest of the app draws shortcuts, and highlighted / underlined text; table columns also honour the alignment written in the separator row. It also covers **showing you a picture**: an agent can put an image file from your machine into the conversation (PNG / JPEG / GIF / WebP / SVG / BMP / TIFF, up to 50 MB), and the page says what happens when one cannot be displayed. Deliberately **only** those shapes are honoured — any other HTML reaches you as plain text, so a reply can never inject markup into the app. | [agent-markdown-formatting.md](agent-markdown-formatting.md) |
| Agent Message Display (structured prose inline) | Substantive agent prose between tool calls (markdown headings, structured bullet lists, long paragraphs) renders inline in the main message bubble; short narration still folds behind the activity pill; toggle via Settings → Appearance → Show structured agent prose inline (default on) | [agent-message-display.md](agent-message-display.md) |
| Agent Messages (watch your agents talk to each other) | One place to see every agent-to-agent message across all your sessions — who sent it, to whom, when, what it said, and whether it arrived — plus a second tab for the ones that NEVER arrived, which Omniscio has recorded whole for 30 days but has never been able to show you anywhere. The two tabs read two different records on purpose: a failure from an automated sender or a broadcast leaves no trace in the timeline, so a "failures only" filter over it would show about half of them and hide the rest (487 undelivered against 266 the timeline knew about, measured). Read-only, and it interrupts nobody — no alert, no toast, which is the other half of the September 2026 decision to remove the per-message "never arrived" inbox card for notifying the party who cannot act. In-development — reveal via Settings or `agentMessagesEnabled`. Contract: agent-messages-panel-contract. | [agent-messages.md](agent-messages.md) |
| Agent Permission Level (how much agents do before Omniscio asks) | One global setting — Read-only / Guarded / Autonomous / Full trust — gating Omniscio's Claude permission gatekeeper. read_only asks before any write/command; guarded (new-install default) auto-edits INSIDE the project but asks before shell commands, config-file EDITS, and out-of-project writes; autonomous auto-edits+commands in-project; full = legacy auto-approve-everything. A dangerous-file denylist (SSH keys, creds, /etc/passwd, shell rc) and email-session lockdown sit ABOVE every level and never relax. New installs default guarded; EXISTING installs are pinned ONCE to full on upgrade (no sudden prompt wave), never overriding a later choice. Set in a new onboarding "Agent Access" step and Settings → Workflow (dropdown above the Auto-Approve toggles). Governs Claude(-compatible) sessions AND new Codex sessions: Codex inherits the closest native sandbox/approval policy (read_only/guarded → ask every command, autonomous → project sandbox with network that asks only for outside writes, full → never ask) unless `codexApprovalMode` overrides it; Cursor/Gemini keep their own permission models. The approval card shows the command being gated; approving runs it verbatim. Reads (incl. config reads) are always allowed at guarded. | [agent-permission-level.md](agent-permission-level.md) |
| Agent self-archive (a session archives itself when done) | An AI agent can **archive its OWN finished session** when its work is done — it drops off the active board into Archived (fully reversible; send it a message or Unarchive to bring it back), stamped with an **"Agent (self-archived)"** attribution chip. TWO equivalent triggers through one shared dispatch: the agent emits the marker `[[OMNISCIO_SELF_ARCHIVE]]` on its own line in its final message (the reliable path — a fenced or mid-sentence mention never fires it, and the line is stripped from what you see; wrapping the marker in backticks is still a signal as long as it is alone on the line), OR it calls `POST /session/self-archive`. It can only ever archive **itself** (target resolved from provenance, never a supplied id). Two knobs in **Settings → CLI Control**: the **Session self-archive** master switch (default ON) and **Let finished sessions archive themselves without approval** (default OFF); enabling the bypass is itself approval-gated so an agent can never self-grant it. When a self-archive DOES queue it gets its own inbox card: a plain-English explanation shown ONCE (marked seen when you ACT on a card, so a passing glance never spends it) plus an **Always allow** button on EVERY such card that flips the narrow bypass and clears the self-archive rows already waiting — archiving a *different* session still asks every time. This is why finished sessions tidy themselves away instead of piling up as stale rows — the agent's "decide: self-archive or stay on the board" turn-end choice. When a **background nudge wakes a finished session** (the auto-lander reporting its branch merged, a gate/land watch, a scheduled wake) that turn clears the inbox card its report was sitting in, so Omniscio first **tells the agent whether you have actually seen that last message** — not seen means do not archive, seen means safe to finish. Advice, not a lock, and the note goes to the agent, never into your transcript. Contract: session-self-archive-contract. | [agent-self-archive.md](agent-self-archive.md) |
| Agent Status Board | Live board of every agent Omniscio has launched — workspace, status, dev-pipeline phase/gate, "waiting at gate", and the live to-do checklist; a global toolbar view (click a card to jump to the session) plus a collapsible per-session panel section. Each card also links the run's standardized dev-pipeline docs (Plan/Acceptance/Red Team/Elegance/Contract), snapshotted into Omniscio's own store so the links survive the run's scratch being cleaned up, opening in the in-app preview pane. Each card is saved as one row in Omniscio's database (the to-do list mirrored from the harness task store at ~/.claude/tasks/ — no hook is installed into the agent) only when it changes, and a card refreshes when its agent does something — no timer sweeps the fleet; after a restart the board comes straight back from the saved rows. Cards flag "No to-do tool" and "Skipped the to-do rule", with one inbox card per Claude Code version whose agents start without the tool. View-only; default-off (opt-in); Settings → Workflow toggle + AMC_DISABLE_AGENT_STATUS_BOARD=1 hard kill switch. While on, the to-do rule makes agents keep the list: no file edit before a to-do list exists, no dev-pipeline phase change with that phase's checklist open, and a phase moved by a shell command gets one end-of-turn follow-up (fails open; AMC_DISABLE_TODO_GATE=1). Separately, Claude Code's to-do tools are switched on for every agent Omniscio launches, board on or off (AMC_DISABLE_CLI_TODO_TOOLS=1). | [agent-status-board.md](agent-status-board.md) |
| Agent Tools (consolidated dashboard) | Sidebar parent group nesting CLI Tools / Skills / MCP Servers with a usage roll-up dashboard panel — install counts, top-invoked last 30 days, recent activity; collapsible via chevron (persisted as `agentToolsCollapsed`), 30s cache invalidated by scanner + skills-list pushes | [agent-tools.md](agent-tools.md) |
| Trigger recipes from an AI agent | Pre-approve a recipe with the "Agent triggering" toggle in the Recipe Editor; an authenticated agent can then fire it via `POST /recipes/run` — bypasses inbox approval, 30s per-tuple cooldown, optional per-run cost cap | [agent-trigger-recipes.md](agent-trigger-recipes.md) |
| AI browser — part 2 (Design mode, Visual Edit, spaces, the agent's isolated tab) | The second half of the AI-drivable browser page: what the feature added over the plain embedded browser, **Design mode** and **Visual Edit**, spaces and quick navigation, and the agent's own isolated tab with its MCP tools and permission tiers. | [ai-browser-part-2.md](ai-browser-part-2.md) |
| AI-Drivable Browser (RETIRED — use My Real Chrome) | Dark-gated upgrade to the Embedded Browser (Settings → Lab → `ai-browser`): real multi-tabs, spaces, a command palette, bookmarks, history, downloads — and an Omniscio agent that DRIVES the browser (40 tools: navigate/snapshot/click/type/screenshot + video-transcript, PDF, memory-search, and more) in its OWN isolated tab over CDP, never touching your cookies. Safety layer: per-site permission tiers + finance/payments/social watch-mode + attended-only writes + plan-approval, on top of the global control/pause setting. Signature tools for your OWN tabs: Design mode (point at an element, edit it live, hand the diff to a coding session as a source-edit intent — never live-DOM hacking), Cursor chat/Compose (in-field rewrite/draft with working undo), and Workflow recording (record clicks/types → tag variables → draft skill). Plus a Skills gallery, an autofill password vault, and semantic Memories search over your own browsing. Ships OFF; nothing changes until you enable the flag. | [ai-browser.md](ai-browser.md) |
| AI Coaching — FAQ (user-facing help page) | Frequently asked questions for end users: API key requirement, artifact detail levels, mobile support, data export, quick check-ins, privacy, deleting data, importing existing work, the 20K character limit, and how artifacts affect regular sessions. | [ai-coaching-faq.md](ai-coaching-faq.md) |
| AI Coaching — Getting Started (user-facing help page) | Plain-language intro for end users: what AI Coaching is, how to enable it (Settings → AI Coach), API key requirement, starting your first interview, understanding artifacts, and what the Core Profile does. | [ai-coaching-getting-started.md](ai-coaching-getting-started.md) |
| AI Coaching — Feature Guide (user-facing help page) | Detailed user-facing walkthrough: Dashboard overview, sessions and status groups, artifacts (viewing, editing, detail levels, version history, pinning, export), bookmarks (labels, filtering, search), Core Profile, coaching style, and how artifacts inform regular sessions. | [ai-coaching-guide.md](ai-coaching-guide.md) |
| AI Coaching sidebar — part 2 (artifacts: saving, editing, versions, restore, import) | Part 2 of the AI Coaching page: how an interview's artifact is saved, edited, versioned, restored and deleted, how pinned context and detail levels feed artifacts into sessions, and how imported work and the KMS vault mirror fit in. | [ai-coaching-part-2.md](ai-coaching-part-2.md) |
| AI Coaching sidebar — part 3 (free-form sessions, memory, Core Profile, Life Inventory) | Part 3 of the AI Coaching page: the free-form coaching sessions, the compaction summaries and durable memory facts behind the coach, the synthesized **Core Profile**, the Life Inventory surfaces, and the telemetry that proves the memory system works. | [ai-coaching-part-3.md](ai-coaching-part-3.md) |
| AI Coaching sidebar — part 4 (CLI surface, prompt editor, implementation pointers) | Part 4 of the AI Coaching page: the CLI control-server surface for AI Coaching, the developer-only interview prompt editor, and the implementation pointers for agents working on the feature. | [ai-coaching-part-4.md](ai-coaching-part-4.md) |
| AI Coaching sidebar (interview prompts and artifacts) | Virtual project for guided Claude interviews that produce saved artifacts — sub-sidebar with Dashboard / Sessions (5 status subgroups) / Artifacts / Bookmarks / Archived; the Dashboard groups prompt cards by category with per-card completion status (available / in-progress + phase bar / completed / dependency-locked) plus a "Quick check-in" snack button on completed prompts; activeSection + expanded state persist via `amc.aiCoaching.sidebar.v1`. Saved artifacts also inject as a "Things to know about the user" profile block on every regular session spawn (gated by Settings → Enable AI Coaching). | [ai-coaching.md](ai-coaching.md) |
| AI Council launcher (one-click default council) | Prompt Tools action row that opens the AI Council and starts a council from your default panel in one click (first-run opens the guided wizard); also covers the opt-in per-hub "Councils" section (right-click a hub, then Show AI Council) | [ai-council-launch.md](ai-council-launch.md) |
| Cheap / utility LLM routing (hardcoded default + per-surface model picker) | The cheap utility model (AI suggestion chips, Omni briefings, TTS, voice intent) is HARDCODED to Groq Llama 4 Scout — the global "AI Provider" Settings panel was removed (2026-06-20); the unified model picker still drives the per-surface choices (Omni briefing, Catch-Up Card, email summarizer, AI suggestions); falls back to Anthropic on error; security-critical paths always use Haiku | [ai-providers.md](ai-providers.md) |
| AI spend alerts (cost cards + opt-in daily spend digest) | Omniscio watches your AI spend and surfaces it as **inbox cards** (no top-of-window banner): four always-on cost warnings that fire only when something looks off — daily spend unusually high (with a by-feature/by-model breakdown; a genuine runaway always breaks through), voice-transcription spend over its own budget ceiling, paying for AI reply-suggestions you never accept, and suggestions costing more than usual — plus an **opt-in daily spend summary** card (off by default) splitting yesterday's real billed API spend vs plan-included usage, by provider. Every card is dismissible/snoozeable with Open-settings / Turn-off / View-spend-dashboard actions. | [ai-spend-alerts.md](ai-spend-alerts.md) |
| AI Tools group (sidebar) | Collapsible sidebar group nesting Ask Omniscio, AI Council, AI Coaching, and Mission Control — AIs you interact with, or tools that shape your AI experience; ships collapsed by default; render-only nesting | [ai-tools.md](ai-tools.md) |
| Find Ways to Integrate AI Into Your Work and Life | Guided mission (Windows + macOS) that starts a real AI-workflow interview session. The agent asks lightweight questions about the user's work, finds specific AI opportunities, then produces practical implementation ideas and example prompts. This is a normal prompt-asset mission (`missions/ai-workflow-integration-planner/mission-prompt.md`), not a preloaded or deferred Super Prompt, so onboarding `mode: "run"` starts real model work immediately. Telemetry under `ai_workflow_planner`. | [ai-workflow-integration-planner-mission.md](ai-workflow-integration-planner-mission.md) |
| Writer Studio — part 2 (toolbar, slash menu, templates, tags, cloning, theme) | Part 2 of the Writer Studio page: the formatting toolbar, find and replace, the slash menu, document templates, tags, cloning, bulk operations, rename, font and spacing controls, **Save as**, the editor theme and colour palettes, and the two writer data-model tables. | [ai-writer-part-2.md](ai-writer-part-2.md) |
| Writer Studio — part 3 (the four AI capabilities in the editor) | Part 3 of the Writer Studio page: selection edits and their review flow, options-mode variants, inline ghost-text autocomplete, and the chat assistant with its suggested edits, persisted history and voice context. | [ai-writer-part-3.md](ai-writer-part-3.md) |
| Writer Studio — part 4 (publish, send, export, import, and the tool bridges) | Part 4 of the Writer Studio page: publishing a document to Shares and sending it by email, SMS or Slack, PDF and Word export, Google Docs import and export, local file import, and the Session, Mission Control, KMS vault, Team Chat and PM-tool bridges. | [ai-writer-part-4.md](ai-writer-part-4.md) |
| Writer Studio — part 5 (writer IPC channel reference and key-files table) | Part 5 of the Writer Studio page: the complete writer IPC channel reference and the key-files table that maps each part of the feature to the source that implements it. | [ai-writer-part-5.md](ai-writer-part-5.md) |
| Writer Studio (standalone writing editor, in development) | In-development standalone AI writing editor (gated via the `ai-writer` unreleased-feature, NOT a featureFlag — same pattern as Tasks), surfaced as an Omniscio built-in virtual project labeled "Writer Studio" that docks in the main panel beside the projects sidebar (tier `native`, A-Z slot after Tasks before Zoom Quick Launch). Full-screen Tiptap-powered markdown editor with a saved-documents list, a **Writing Guidance** panel (instructions that steer AI editing), and a **Creativity Dial**. **Two Writer surfaces coexist right now**: this NATIVE one (`src/renderer/src/features/writer/`, still the shipped surface — edit this one unless a task says "the plugin"), and an in-progress port to a first-party `<webview>` plugin at `src/plugins/writer/` that reaches the same `writer_documents` rows through the identity-gated `writer.*` plugin bridge instead of IPC. The plugin covers DOCUMENTS only so far (list + search, Tiptap editor, 500 ms autosave, empty state, confirm-then-undo delete, multi-select + bulk ops, inline rename, document clone, tagging with filter, font size + line spacing, Save as Markdown/HTML export); everything AI stays native. Making the plugin marketplace-only, and the native surface's fate, belong to a later phase | [ai-writer.md](ai-writer.md) |
| Airtable (in development) | In-development real Airtable API integration (default-hidden, gated via the `airtable` unreleased-feature; `airtableEnabled` toggle in Settings → Lab, or `AMC_SHOW_AIRTABLE=1`). Adds an "Airtable" sidebar virtual project that connects to your Airtable workspace via the Airtable REST API. Connect via a Personal Access Token in Settings. Implements base/table navigation, record list and detail, record search, comments, and an `airtable-inbox` source surfacing records assigned to you as unified-Inbox rows. CLI routes for AI agents: nine `/airtable/*` routes — list bases, base schema, list records, record detail, search records, list comments, create record, update record, add comment. | [airtable.md](airtable.md) |
| Alarm Quick Add (Ctrl+Space → Alarm tab) | Text-only tab inside Quick Launch for creating an Omniscio alarm from a single natural-language line — single textarea + debounced preview, reuses the Calendar parse channel + shared $0.10/day cap, no new IPC; supports the legacy 5-value recurrence enum _and_ a rich RRULE escape hatch (_"every 3 weeks at 9am"_, _"first Monday of the month"_); rrule branch evaluates DST-safely via `rrule` npm in main, stored as two nullable columns (`rrule` / `rrule_label`) added in migration v233 — no CHECK rebuild; rrule alarms render read-only in AlarmDetail (no coercion into the 5-value dropdown), exhausted rrules soft-delete on schedule-advance; gated on `alarmsEnabled` | [alarm-quick-add.md](alarm-quick-add.md) |
| Alarms — part 2 (snooze cap, math challenge, test fire, fire limits, CLI) | The advanced half of the Alarms page: the snooze cap, the math challenge that gates Dismiss, **Test fire** previews, fire limits, missed alarms in the inbox, the mobile versus desktop split, the natural-language parse cost cap, and the CLI routes. | [alarms-part-2.md](alarms-part-2.md) |
| Alarms (phone-style reminders) | Natural-language scheduled reminders that ring inside Omniscio at a wall-clock time — type "every weekday at 7:30 AM" into the Alarms virtual project; chrono.js parses for free, Haiku fallback for ambiguous shapes (daily cap defaults to $0.10); fires as full-screen modal, banner toast, or silent banner; Snooze (5/9/15/30 min) and Dismiss with idempotent service layer; missed fires surface in the inbox via the `alarm-fired` row on desktop AND mobile; per-alarm overrides for sound/snooze/assertiveness/foreground/pierce-Focus-Mode (null = inherit global default) | [alarms.md](alarms.md) |
| Omniscio priority boost + adaptive E-core delegation (Windows) | Two Settings → Performance toggles (both off by default) for users seeing Omniscio's window stutter under heavy session load: (1) raise every Omniscio Electron process to Above-Normal priority class via `SetPriorityClass`, widening the priority gap from CLI children at Below-Normal from 1 notch to 2; (2) on hybrid CPUs (Intel 12th-gen+ / Core Ultra), monitor host CPU and pin the session Job Object's affinity to E-cores only when host > 85% for 5s, release back to all cores when < 60%; pure hysteresis, idempotent, non-fatal failure mode; no-op on macOS/Linux or non-hybrid CPUs | [amc-priority-boost.md](amc-priority-boost.md) |
| Keep Omniscio resident in memory (Windows) | A Settings → Performance toggle (off by default) and memory twin of the priority boost: sets a HARD Windows working-set minimum (`SetProcessWorkingSetSizeEx` + `QUOTA_LIMITS_HARDWS_MIN_ENABLE`, 128 MB/process) on Omniscio’s OWN Electron processes so its pages resist being trimmed to the pagefile under memory pressure — keeping the window instant when you Alt-Tab back after a heavy run. Rides on the already-enabled `SeIncreaseWorkingSetPrivilege` (no admin; NOT VirtualLock page-locking). Self-verifies via a `GetProcessWorkingSetSizeEx` read-back (loud warn if the floor didn’t take — the anti-silent-no-op guard); idempotent + 30s refresh; disable sweeps tracked ∪ live; non-fatal; no-op on macOS/Linux. | [amc-resident-floor.md](amc-resident-floor.md) |
| Omniscio awareness prompt (sessions know they're running in Omniscio) | A short, on-by-default note injected into every session's system prompt: it tells the agent it runs inside Omniscio and how to reach Omniscio's controls (the omniscio-control skill, or the local REST API at 127.0.0.1:19519 with the token from ~/.amc/cli-token), and to self-identify via $AMC_SESSION_ID so its actions trace back. Available, not nagging. Skipped on SSH-remote sessions and the Ask Omniscio / Ask-about-this-page helpers. One global toggle: Settings → Features → "Make sessions Omniscio-aware". | [amc-session-awareness.md](amc-session-awareness.md) |
| Animated logo (the swirling orb: where it plays, when it rests, how to turn it off) | The brand orb swirls in the title bar and Quick Launch while you use that window (it starts still, begins on your first mouse move or key press, and stops in the background, when minimized, or after two idle minutes), on the startup loading card while the app loads, and in the Windows downloader while its window is open. Turn it off in one step: right-click the title-bar logo and untick "Animated logo", or Settings → Appearance → Motion → Animated logo (instant, no restart). The computer's reduce-motion setting, Motion & Polish switched off, and Low Power Mode always keep it still; the downloader follows Windows' "Show animations in Windows". The browser version keeps the still logo. | [animated-logo.md](animated-logo.md) |
| Anthropic outage alerts (API status monitor) | Watches Anthropic's official public status feed (status.claude.com summary JSON — the page behind status.anthropic.com) and tells you when an Anthropic incident is what's failing your Claude sessions, so you never check the status page by hand. Polls every 5 min (60s during an incident) AND checks instantly the moment a session fails with a transient Anthropic API error (rate-limited, Anthropic-account sessions only). A relevant incident (Claude API / Claude Code components; claude.ai-web-only incidents filtered out) raises ONE deduped inbox card whose primary button is **View status page** (shown alongside the universal "Start session"), fires ONE desktop notification, and drops one "likely their outage, not your setup" note into each failing session's chat; when Anthropic resolves it (2 clean polls — flap-guarded) the card auto-archives + a "resolved" notification fires. Dismissing the card sticks across restarts (only a genuinely NEW incident re-raises). Never alerts about the status page being unreachable (that's your network — the offline banner's job). On by default; Settings → Notifications → Anthropic outage alerts (`anthropicStatusMonitorEnabled`); inert in e2e/sandbox instances. | [anthropic-status-monitor.md](anthropic-status-monitor.md) |
| Anti-Gravity provider (CLI-backed sessions) | Spawn Claude-Code-style sessions backed by Google's Anti-Gravity CLI (`agy`) alongside `claude`, `codex`, and `gemini` — gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via Settings → Account Anti-Gravity CLI binary + "Allow Anti-Gravity sessions" toggle; **no API key step** (Google Sign-In via OS keyring); per-turn block-mode subprocess (`agy --print`) with synthesized multi-turn (Omniscio prepends prior conversation into each prompt); per-launch ChangeProviderButton + per-project default; sky-blue "Anti-Gravity" pill in the session header | [antigravity-provider.md](antigravity-provider.md) |
| API Keys (unified key hub) | One Agent Tools sidebar row, two tabs. **My API Keys** — generate a personal, long-lived `jls_sk_` key so your OWN scripts/automations can call a pool of AI APIs (Claude, GPT, Groq, DeepSeek) through Omniscio’s shared keys without per-provider signups; shows pre-paid credit balance + usage example, key shown once (fingerprint stored, never logged), Regenerate/Revoke confirm-gated, metered + billed at a flat surcharge (also at Settings → My API Keys). **Stored Keys** — read-only inventory of every key/secret Omniscio can see (DPAPI vault, provider keys, Claude accounts, automation creds), names + metadata only, never values (never-decrypt); search/remove/change. Merged the two former rows 2026-06-21. | [api-keys.md](api-keys.md) |
| App is already running, or frozen (restart the stuck copy) | Launching Omniscio while it's already open normally just brings the existing window to the front with an "already running" notification. If the running copy has FROZEN (still holds the single-instance lock but stopped responding), Omniscio now detects it, records a diagnostic, and shows an "Omniscio is not responding" dialog with a **Restart Omniscio** button that force-closes the stuck copy and opens a fresh one — instead of the old silent "nothing happens". Fail-safe: never restarts a copy that's merely starting up or busy (it counts as frozen only after 10 minutes with no heartbeat, then checks again 30 seconds later), verifies the process is really Omniscio before closing it, re-checks it's still frozen, and after repeated freezes shows a "keeps freezing — reinstall / contact support" message. | [app-already-running-or-frozen.md](app-already-running-or-frozen.md) |
| App Tour (guided onboarding overlays) | 21 JSON-authored guided tours. Surfaced from Setup Wizards: Welcome to Omniscio, Your First Session, Productivity Power-Ups, Recipes & Filters, Gmail, RSS & Webhooks, Filters, Archive & Search, Voice Commands, Settings Deep Dive, Start a New Hub, Tasks, Vault and the dev-gated Keyboard Demo. Surfaced contextually instead: SMS, Screen Capture, Mind Map, Interactive Demo, Writer Studio Tour, Managing Your Sessions (menu-launched practice tour on a safe sample workspace) and `__example__`; spotlight steps highlight UI by `data-ui-anchor` name, overlay steps full-screen explain; markdown / rich-block descriptions; tours loaded eagerly + Zod-validated at boot (malformed tour fails boot) | [app-tour.md](app-tour.md) |
| App Update Notifications (banner + error self-recovery) | Silent auto-update of the Omniscio binary every 4h via electron-updater + GitHub Releases — banner shows download progress, "Restart Now" when ready, and a visible "Download latest from releases" link if the check fails. Lifecycle events write `[app-update]` lines to `main.log` | [app-update-notifications.md](app-update-notifications.md) |
| Approvals hub (sidebar) | Sidebar hub listing the pending agent-permission (cli-pending) approvals — the CLI permission prompts a session raises to run a command / write a file — so they're reachable from the Hubs list, not only the Inbox; reuses the shared approve/deny flow; shows a "Needs you now" list plus a collapsible read-only "Past approvals" history (resolved approved/rejected); each approval ALSO shows up in the Needs-You section of the project hub it is attached to (the project it targets, else the session it targets, else the session that asked) while staying listed here; gated by `approvalsSidebarEnabled` (default on), nested under the System group next to Alerts | [approvals-hub.md](approvals-hub.md) |
| Archive a session | Ctrl+W / E from the keyboard, middle-click on the row (desktop only — never an X button), right-click → Archive, mobile swipe, or the mobile session-header button (always the far-right header action, like every mobile detail view); soft-delete with Undo toast; auto-unarchive on next send; to archive many sessions at once, multi-select them first — see [bulk-select-sidebar.md](bulk-select-sidebar.md); a finished session can also **archive itself** when done ("Agent (self-archived)") — see [agent-self-archive.md](agent-self-archive.md) | [archive-a-session.md](archive-a-session.md) |
| Arij (issue tracker) | First-party Jira-style tracker, off by default via a plain `arijEnabled` flag toggled in its own Settings → Arij section (exactly like Ollert — NOT lab/unreleased-gated). Surfaces as an "Arij" sidebar virtual project (`__arij__` / `ARIJ_PROJECT_ID`) whose panel renders beside the Omniscio side nav (panelOwnsLayout, like Ollert); `omniscio://arij/<path>` deep links open the panel on a specific route. Backed by the amc-back `arij-api` cloud backend and gated on Omniscio's Firebase Global Auth sign-in (no arij login of its own — the main process brokers Firebase ID tokens, the backend dual-auths + links existing arij accounts by verified email): organizations + projects + role-based membership, kanban board with swimlanes and saved JQL boards, backlog + sprints, issues (types, priorities, points, labels, components, versions, worklogs, watchers, attachments, links, @mention comments + notifications), profile editing (display name + data-URL avatars), per-project/org automation rules, summary dashboard + reports, per-project markdown docs tree, Jira import/export — and the headline: every issue can launch and track a REAL agent session in the project's mapped local folder (`settings.arijProjectFolders`), with live status mirrored back onto the card and Workflows trigger/action nodes | [arij.md](arij.md) |
| Artifact Sharing | Right-click → Share a session/message/selection as a self-contained public HTML page with expiration | [artifact-sharing.md](artifact-sharing.md) |
| Asana board (in development) | In-development experimental integration (default-hidden, gated via the `asana-board` unreleased-feature; `asanaBoardEnabled` toggle in Settings → Lab, or `AMC_SHOW_ASANA_BOARD=1`). Adds an "Asana" sidebar virtual project that talks to Asana's REST API via a Personal Access Token. Implements a rate-limited request queue (5 concurrent, 429 backoff), board sections + tasks, move-to-section, reorder; plus an `asana-inbox` source surfacing tasks assigned to you as unified-Inbox rows (poll with `diffMode: 'updated-at'`), and a workflow trigger (created/completed/updated events, 2-min poll). Board panel UI not yet built. CLI: POST `/asana/move-to-section`, POST `/asana/reorder` | [asana-board.md](asana-board.md) |
| Asides (side question without polluting main thread) | Ctrl+B opens muted aside composer; spawns one-shot --fork-session per question; auto-collapse after next real turn; settings for hide-by-default + cost cap | [asides.md](asides.md) |
| Ask about this page (floating screen-aware helper) | Non-blocking chat popover that drops down from a top-bar button (sparkle icon next to Bookmarks/account; + Ctrl+J, desktop-only) and asks Claude about whatever is on screen — captures a snapshot of the active session / inbox / visible panel and spawns a REAL background helper session into its own `__ask_page__` scratch workspace (separate from Ask Omniscio), re-attaching the snapshot every turn; persistent history (continue-on-open + New chat + reopenable list); inline approvals; first-use consent gate. KMS/secrets vault + `[data-sensitive]` regions are NEVER captured, screen text is wrapped as untrusted data. These helper sessions are hidden permanently from sidebar/inbox/counter/`/state`. In-development — hidden by default; reveal via Settings → Lab toggle, `AMC_SHOW_ASK_ABOUT_THIS_PAGE=1`, or shipped status. | [ask-about-this-page.md](ask-about-this-page.md) |
| Ask Omniscio (in-app help agent) | A sidebar project hosting Claude sessions pre-seeded with Omniscio docs + your live state — answers questions about the app and configures it via approval-gated mutations | [ask-amc.md](ask-amc.md) |
| Attach a file | Paperclip button + drag-drop + paste + Ctrl+U — no per-type count cap (per-file size caps still apply); Office formats blocked at attach with a toast; PDFs render natively AND save to workdir | [attach-a-file.md](attach-a-file.md) |
| Audit Framework (bundled audit skills) | Eight interlocking Claude Code skills bundled with Omniscio that run compaction-resilient codebase audits across 80+ named audit shapes (bug hunt, security sweep, test coverage, UI/UX, performance, efficiency, etc.) and apply findings as commits on a dedicated branch; auto-installed into `~/.claude/skills/` on launch; audit + apply worktrees are tag-protected so the cleanup sweep skips them | [audit-framework.md](audit-framework.md) |
| Choose how your Claude sessions sign in (sign-in methods) | Pick a single sign-in method for every Claude (Anthropic) session in Settings → Accounts → Claude — Managed accounts (Omniscio's multi-account pool), Your API key (paste your own `sk-ant-...` key into an isolated slot), or Claude Code login (Omniscio uses your own `claude login` at `~/.claude` and stores nothing); switching shows a "switch your sign-in method?" confirm, applies to all Claude sessions, affects only Anthropic (other providers untouched), and the three methods stay completely isolated — Managed accounts only appears when it's available to you. | [auth-pathways.md](auth-pathways.md) |
| Auto-lander dashboard (watch + pause the merge auto-lander) | The **Auto-lander** tab in the Dev Pipeline panel — one place to watch and lightly control the auto-lander (the background service that auto-merges *ready-to-merge* branches into their main branch locally, forward-only, never pushing). Shows **live daemon status** (idle / landing / resolving a conflict / backing off / paused / off, updated on push with no refresh), a **queue** of ready-to-merge branches grouped per watched repo — each repo shown as Watching or Paused, with the branch the daemon will attempt next marked **Next up** and how long ago each was tagged — and **land history** (Landed / Conflict) whose rows expand to show the detail + new base commit + a **Go to session** jump for a landed branch, or the base it conflicted against + the exact files for a conflict. Two quick actions write the SAME auto-lander settings the Setup tab does (`autoLanderEnabled` + the per-repo `enabled` flag — one source of truth, so the tab and Setup can never disagree, and both are CLI/API-reachable through the normal settings routes): a **global pause/resume** and a **per-repo pause/resume** (a paused repo stays visible so you can resume it) — both confirm when you turn landing back ON, naming what arming does, and pause with one click (arming is the consequential direction; pausing is reversible and loses nothing). The heavier configuration (add/remove repos, integration branch, observe-only) stays in the **Setup** tab — this tab is read-mostly monitoring, so the pipeline's controls stay in Setup while the monitoring gets its own home. The queue is computed live from git (the same `selectReadyBranches` the daemon reads each cycle — no stored copy to go stale) via the read-only `AUTO_LANDER_QUEUE_GET`; the tab self-refreshes while open (the daemon's status push + a light timer that catches a branch tagged while it's idle) and costs nothing when closed; pausing never interrupts a land already in progress. Separately, once an hour the lander checks for **finished work that never reached master** — committed work whose workspace folder is already gone and that was never marked ready, so nothing else can see it — and raises ONE inbox card ("Finished work never reached master") naming each branch with its repo, why it was never landed, how long it has sat and how many commits are not on master. It REPORTS only: it never marks, lands or deletes anything, and its Start-session button opens a triage session pre-loaded with the list. Part of the Dev Pipeline panel (shipped — visible to everyone); works on mobile / Web Access. Contract: dev-pipeline-panel-contract. Since 2026-09-24 every reason the lander can refuse a branch is one row in a **land standards** catalogue, each with a mode — block, advisory or off — that you read with `GET /auto-lander/standards` and set with `PATCH /auto-lander/standards/:id` (or the `landStandardModes` setting); an agent's own token cannot switch a standard off. | [auto-lander-dashboard.md](auto-lander-dashboard.md) |
| Auto-open a session that needs you (idle sessions panel) | On the embedded, reusable **Sessions** panels (Tasks "Sessions" tab, SMS, KMS, Mind Maps, Whiteboard, Flowchart, NightyTidy2, plugins, the detached project window) — when nothing is selected and a session **newly** enters "Needs You", its chat opens automatically instead of leaving you on the empty "Pick a session" pane. New-arrival only (closing with the X lands on the empty state and doesn't re-grab; a session that returns to Needs You re-opens); never steals focus from a session you're already viewing; desktop-only (mobile keeps the list visible); opens an existing chat only, never spawns. The main per-project sidebar is unchanged. | [auto-open-needs-you-session.md](auto-open-needs-you-session.md) |
| Auto-replies (auto-respond to a session's own output) | The **lightweight** half of Omniscio's two auto-response tools — a simple rule that watches a session's **finished output** (Claude **or** a non-Claude engine: Codex / Gemini / OpenCode / …) and fires **exactly ONE** action when its trigger matches: `keyword` / `project` / `tag` / `time` (single condition, no AND/OR). Six actions: **Reply** (inject a message / Quick Reply so the session keeps going), **Rename the session**, **Archive the session**, **Start a new session** (billable), **Add an inbox note**, and **Organize** (file into a folder). Split into its own sidebar row 2026-08-14 from the former "Auto-Reply & Triage"; the heavy conditions + action-chain engine now lives beside it as **Automation Rules** — both in the **Automation** sidebar group, sharing one on/off toggle (`automationsEnabled`). Code-block / inline-code / blockquote trigger text is ignored so a session that merely *quotes* your trigger won't fire the rule. | [auto-replies.md](auto-replies.md) |
| Auto-restart stuck sessions | Very rarely, the agent's underlying process **freezes right after you send a message** — it stops producing output but still *looks* like it's working (the "thinking…" spinner forever; the CLI is alive but silently queued the turn). The feature detects a wedged session and auto-restarts it so your message actually runs. | [auto-restart-stuck-sessions.md](auto-restart-stuck-sessions.md) |
| AutoHotkey integration | Edit `.ahk` files in Monaco inside Omniscio, auto-reload on save via signal file, generate AI script index | [autohotkey-integration.md](autohotkey-integration.md) |
| Automation credentials | Store the Slack / GitHub / Discord / Notion / Telegram / HTTP / Google service-account / SMTP secrets that v2 actions reference by id. Lives at Settings → Workflow → Automation Credentials. Per-kind Zod shape validation, OS-keyring encryption (`safeStorage` + `enc:` prefix), opt-in gate (`allowHighRiskCredentialKinds`, default off) on creating / rotating the two high-risk kinds; secrets never cross IPC | [automation-credentials.md](automation-credentials.md) |
| Automation group (sidebar) | Collapsible sidebar group nesting Cron Jobs, Recipes, Automations, Quick Replies, and Scheduled Messages — ships collapsed by default; render-only nesting, members keep running while hidden | [automation-group.md](automation-group.md) |
| Automation Builder (build automations for non-programmers; sidebar/page display name, formerly "Automation Helper") | Sibling of Ask Omniscio that BUILDS automations: a full-tools Claude session interviews the user in chat, scaffolds a folder + private GitHub repo, writes code + docs, safely smoke-tests, and registers the automation on Omniscio's cron engine (as a pending-approval inbox row) under a "My Automations" sidebar divider; on-disk `automation.json` manifest is the source of truth (no DB table); cron failures route to a one-click "send it back to the Helper to fix" inbox handoff; keeps track of what it built — a derived "Automations you've built" list (name / schedule / live status) linked from its create-focused landing to the My Automations panel and consulted before building so it won't duplicate, read via `GET /automation-helper/list` or the `automation-helper:list` IPC channel; on by default (`automationHelperEnabled`); ids/sentinel/flag stay `automation-helper` (display-only rename) | [automation-helper.md](automation-helper.md) |
| Share automations (the automation marketplace) | Share your recipes with others — a **Share** button on any recipe packages it into a copy-paste **code** (secrets / API keys / file paths / account+project fields stripped by allow-list, secret-shaped values flagged) or **Publishes** it to the browsable **Automations** tab in the Marketplace (GitHub sign-in; **curated** — an admin Review queue approves before it's listed); **Import** (paste a code) / **Install** (from the catalog) always lands the automation **paused** until you review its steps and approve it; non-portable recipes (sub-recipe / script / promptFile / project-scope) are refused with a reason; public browse grid is **data-gated** (appears once the cloud catalog deploys), the code-based import path works fully offline; catalog lives in the marketplace's own `amc-marketplace-jls` project | [automation-marketplace.md](automation-marketplace.md) |
| Automations — part 2 (auto-response badge taxonomy, activity log, implementation map) | The second half of the Automations page: the auto-response badge taxonomy that names which automated path produced a message, the activity log's per-step breakdown, and the implementation map of the engines, stores and IPC. | [automations-and-auto-replies-part-2.md](automations-and-auto-replies-part-2.md) |
| Automations & Auto-replies | **Sidebar entry now labeled "Auto-Reply & Triage" (renamed 2026-08-10, display-only).** Auto-respond to messages — Auto-replies match a session's output text (keyword/tag/project/time) and fire one of 5 actions (reply / rename the session / archive it / start a new session / add an inbox note), optionally scoped to one project; Automations for multi-step action chains with AI conditions; `cli_session` action accepts template-interpolated prompts (`{{body}}` / `{{subject}}` / `{{sender}}` / `{{channel}}`) and `projectResolution: 'auto'` to fuzzy-match a project from a GitHub URL in the message body; **Backtest** card replays the last 24h of channel messages against a draft rule with no real side effects | [automations-and-auto-replies.md](automations-and-auto-replies.md) |
| Hide background check-ins (collapse background-job acknowledgment turns) | Off-by-default **Settings &rarr; Sessions &rarr; "Hide background check-ins"** toggle that collapses the short status line a session posts when its OWN background job finishes and the harness re-invokes it ("Tests green (exit 0). Build still running.") into a one-line marker you click to expand — nothing deleted, **Show system messages** reveals them whole. AND-gated: a turn must be a genuine `turnBoundary` self-resume AND its reply must match a `BACKGROUND_ACK_PATTERNS` rule (exit-code / check-result / N-of-M / still-running) after clearing a length cap + question veto + deliverable veto. Never collapses a question, a real deliverable, or an in-flight turn. Like the waiting detector: regex rules proven by a read-only live-DB backtest (0 false positives) before shipping; the hide is a live render decision so the toggle flips the view instantly. | [background-ack-detector.md](background-ack-detector.md) |
| Backup Mirror — part 2 (activation, sync modes, encryption, restore, IPC) | The second half of the Backup Mirror page: first-time activation, the automatic-sync modes, the encryption envelope, the archive's internal layout, retention, the restore safety defences and the IPC channels. | [backup-mirror-part-2.md](backup-mirror-part-2.md) |
| Backup Mirror (full snapshot to cloud-sync folder — migration / disaster recovery) | Continuous encrypted full-state mirror — entire SQLite DB (conversations included) + config + attachments tree — written to a folder you choose (typically inside Dropbox/OneDrive/iCloud) so an Omniscio install can be reconstructed on another machine. Piggy-backs on the local backup-service cadence (no separate scheduler), AES-256-GCM + PBKDF2-SHA256 600k, atomic `.tmp`+rename writes, prune-newest retention (default 5). Two restore modes: Replace (pre-restore snapshot + stage + startup swap) and Merge-conversations (schema-gate + ATTACH + INSERT new rows only). Resume-after-restore re-spawns sessions cleanly via NULL `cli_session_id` + `forceTranscriptOnNextSpawn=1` (migration v180), so restored sessions inject their transcript on next spawn | [backup-mirror.md](backup-mirror.md) |
| Base-branch picker (fork a session from — and merge it back into — a chosen branch) | When you start a session, a **Base branch** dropdown in the Start-session dialog lets you pick which git branch the session's worktree forks from — and that same branch is where its work merges back, instead of always master. Pick nothing and it's byte-identical to today (fork from HEAD, merge to master). The dropdown appears under the Repo picker once a project with branches is chosen, defaults to the project's current branch, and is fed by a live read-only branch-list IPC (`PROJECT_BRANCHES_GET`). The fork is a validated `git worktree add` start point; the chosen branch is saved as the session's `land_target_branch`; the in-app merge advances that branch's ref directly (never touching a live working tree, refusing if it's checked out elsewhere). The background **auto-lander is intentionally untouched** — a `ready-to-merge`-tagged base-branch session still lands to master. Shipped for the Start-session dialog; the Quick Launch picker + a CLI `baseBranch` are follow-ups. Contract: base-branch-picker-contract. | [base-branch-picker.md](base-branch-picker.md) |
| Beautify Site (make a page look designed, not machine-made) | A bundled skill that takes a bland or obviously AI-generated page and makes it deliberate, in four ordered steps: pin ONE design direction and persist it as a `MASTER.md` the rest of the work reads, fit components to that direction, layer motion that aids comprehension, then audit the BUILT artifact and strip every AI tell by restructuring the element rather than softening it. Bold by default — it commits hard to one idea and varies the direction every time, because converging on a house style is itself a tell — and dials back only when you ask for quiet or the project's own design docs say so (and when those conflict, it surfaces the conflict instead of quietly picking restraint). Five patterns fail the audit outright: gradient text, thick side-stripe accents, small letterspaced labels above headings (and announcement pills over a hero), full stops ending headings, and fake terminal / code-block / IDE mockups. Never traded for boldness: reduced motion, focus rings, touch targets, contrast, no-JS readability, no sideways scroll on a phone. Self-contained — every helper tool it can use is optional with a documented fallback. OPT-IN: default OFF, gated by `beautifySiteSkillEnabled` (Settings → Features), installed at the next launch once enabled; ~170 tokens of always-on description overhead only while it is on. Skill: .claude/skills/beautify-site; manifest: src/shared/integrations/beautify-site.ts. | [beautify-site.md](beautify-site.md) |
| Blank-screen recovery button (survives a full React unmount) | When the React app silently unmounts and `#root` goes empty, a non-bundled guardian IIFE in `src/renderer/public/blank-screen-guardian.js` paints a centered **"Reload Omniscio"** button into `<body>` after a 1500 ms grace (250 ms when a chunk-load error fired). Click invokes `app:recover-blank-screen` — main records `[MANUAL-RECOVERY]` into `heartbeat.log`, dumps the ring buffer to `heartbeat-final.log`, clears the WebContents cache, and `reloadIgnoringCache()`. Survives unmount because the script lives outside the bundle and the button is appended to `<body>` (not `#root`). Kill switch: `window.__amcDisableBlankScreenGuardian = true` before the IIFE installs | [blank-screen-recovery-button.md](blank-screen-recovery-button.md) |
| Block agent messages (stop one session receiving them) | Turns other agents’ messages AWAY from one session instead of merely hiding them — the ⋯-menu neighbour of “Hide agent messages”, which is only a view filter, so the messages still arrived, still woke the session and still cost tokens. Set from the session ⋯ menu; stays on until turned off, no timer. Closes the channel to AGENT SESSIONS only: your own messages, system notices (a branch landed, a cloud check finished), anything you scheduled, and a decision of yours being relayed back all still arrive — they carry no sender session, which is the discriminator the delivery seams read. Refuses LOUDLY: the sender gets a terminal HTTP 403 target_blocked meaning permanently closed rather than busy so it stops retrying, the payload is dead-lettered whole and readable in Agent Messages → Undelivered, and no inbox card is ever raised. Agent messages already queued when you switch it on are cleared the same way, so it takes effect at once. HUMAN-ONLY — an agent can neither block itself nor a peer. Contract: agent-messaging-contract, the clause a-veto-delays-and-only-the-human-may-refuse. | [block-agent-messages.md](block-agent-messages.md) |
| Boards (read-only window onto the shared agent board) | A read-only panel under **Agent Tools** that shows the shared agent board: the channels your agents coordinate on first, most-recently-posted first within each group, each row carrying its name, its kind and its activity, and the selected channel's posts oldest-first with each author named. Every repository also gets its own board, so one post reaches every agent working it; it is named after the project and never offered to an agent working a different one. A post never restarts an agent you stopped — that session stays a member and can read the board, but is not told. The direct-message channels — where the automatic copy of every one-to-one agent message lands, and by far the board's biggest traffic — sit behind a **Direct messages** toggle so they cannot crowd the list out. DMs are labelled for the other participant, never the raw `dm:<id>\|<id>` address; an unresolvable end reads "Direct message" and an author whose session is gone reads as unnamed rather than as an id. Reads are bounded — the panel asks for one page when you open a channel rather than pre-loading everything. Deliberately NOT gated by the Overseer feature: the board is written by Overseers, swarms and ordinary agent-to-agent messages alike, so it must stay reachable with Overseers switched off — its own sidebar row, `boardsSidebarEnabled` (default on), governs visibility. Empty, loading and error are real states: an empty board gets an empty state and a failed read gets a humanized sentence, never a raw error. Manifest: `src/shared/integrations/boards.ts`. | [boards.md](boards.md) |
| Bookmarks — part 2 (CLI routes and the implementation map) | The reference half of the Bookmarks page: the localhost CLI routes with their kill switch, curl examples and response shapes, plus the implementation map of the queries, launcher, favicons, IPC channels and renderer state. | [bookmarks-part-2.md](bookmarks-part-2.md) |
| Bookmarks | Toolbar bookmark icon opens a popover (mirrored at Settings → Workflow → Bookmarks) holding URL/path/executable/command rows in a searchable folder tree; first-time cmd launches gated by a confirmation modal; kept in the local `bookmarks` table (synced when Cross-Device Sync is on); also exposed via CLI control (`/bookmarks/*` — exe rejected, cmd first-run still gated) | [bookmarks.md](bookmarks.md) |
| Books (built-in plugin — read EPUB/PDF with highlights, notes, AI study tools) | A bundled first-party sandboxed plugin at `src/plugins/books/` (NOT Marketplace-only — it ships inside the app). Import EPUB/PDF books you own onto a shelf, read them, highlight passages, keep notes, and use AI study tools; reading progress is remembered per book. Hand-authored vanilla-JS webview over `window.AgentMC` (`db`), strict `script-src 'self'` CSP. Owns a `books` collection; tracked in FEATURE_REGISTRY (`books`, an `imported` event). | [books.md](books.md) |
| Bot Creation Mode (build a bot from one sentence) | Agent Tools action row that launches a guided interview and then BUILDS the bot — its own hub pre-loaded with a persona, knowledge, and skills; covers why installed skills are named rather than copied, how a missing skill installs into one bot only, and the untrusted-fencing of fetched material | [bot-creation-mode.md](bot-creation-mode.md) |
| Branch header | Off by default — turn the branch name on app-wide at **Settings → Appearance** (`showCurrentBranchInHeader`); the per-project three-dot menu only HIDES it for one project. Read-only (no branch switching), desktop-only, live-updating; a folder-plus-branch icon marks a worktree session | [branch-header.md](branch-header.md) |
| Browse archived sessions | Open the **Archived** sub-section in any project; swipe / J / K / chevron buttons walk through the archived list (project-scoped, or cross-project under Search) | [browse-archived-sessions.md](browse-archived-sessions.md) |
| Browser Logins (log in once, every agent reuses it) | Settings → Browser Logins, or the Agent Tools → Browser Logins sidebar row — open a browser, log into any site and close it, and Omniscio captures the login automatically (named after the site, renameable); every agent you run can then reuse it (its own clone, many at the same time) until the site signs you out. Local-only, no passwords stored. Saved-logins list with per-login rename + enable/disable + remove, a zero-friction "Add a login" capture (no form), and a read-only usage log. In-development — ships dark behind the Settings → Lab toggle. A separate opt-in surface; never touches Claude Code sessions or your connected providers. | [browser-logins.md](browser-logins.md) |
| Bug intake safety screen (a cheap AI checks every outside bug report before an agent starts on it) | Before Omniscio starts an agent on a bug report sent from inside the app, handed over by a teammate, opened on GitHub or raised by Sentry, a very cheap AI reads everything that agent would receive — the text, screenshots and text attachments — and checks it for prompt injection and dangerous requests. One call per report, a fraction of a cent, on its own $2-a-day budget. A report it flags, or cannot check (provider down, budget spent, too long, an attachment it cannot read), is HELD: it waits in Bug Intake → Review and as its own inbox card with the reason, nothing starts it automatically, and only you can start it (**Spawn anyway**) or dismiss it, from the app. Always on while Bug Intake is on; emailed reports keep using the email screen. | [bug-intake-safety-screen.md](bug-intake-safety-screen.md) |
| Bug Report Intake — part 2 (the Gmail, Sentry and GitHub channels) | Part 2 of the Bug Report Intake page: the three channels Omniscio watches for you — a connected Gmail inbox, a Sentry organization and GitHub repositories — how to add, test and edit each source, what happens on every poll, and how a source that keeps failing raises a durable alert. | [bug-report-intake-part-2.md](bug-report-intake-part-2.md) |
| Bug Report Intake — part 3 (what the spawned investigation receives) | Part 3 of the Bug Report Intake page: what an auto-spawned investigation actually receives — the fenced report, your appended instructions, email attachments and in-app screenshots — how a reply threads back to its session, how repeat reports of one issue collapse into a single investigation, and the safety guarantees behind all of it. | [bug-report-intake-part-3.md](bug-report-intake-part-3.md) |
| Bug Report Intake — part 4 (unrouted-report decisions, analytics, code map) | Part 4 of the Bug Report Intake page: the table of decisions you can see when a report does not route, the analytics events intake records, what is deliberately out of scope for the first version, and a map of every file and route behind the feature for readers who have the repository open. | [bug-report-intake-part-4.md](bug-report-intake-part-4.md) |
| Bug Report Intake (email + Sentry + GitHub → spawned sessions) | Bug reports flow in three ways into one unified **Bug Intake** sidebar virtual project (Sources / Review / Ignored / Audit tabs) — testers email `[BUG: <slug>]` / `[FR: <slug>]` (per-project slug, prescreen-gated, daily-capped, idempotent, replies thread back) OR Omniscio polls a Sentry org every 5 min and spawns a session per new unresolved issue (auto-spawn toggle, first-connect cap of 5, 24h-failure escalation, per-source mutex, global "Pause all polling" switch) OR Omniscio polls a GitHub repo's open issues every 5 min and spawns a session per new issue (gh-CLI auth, no stored token, optional label filter, no triage gate, first-connect cap of 5); all three share a 90-day retention sweep + one `bug_intake_processed` audit table; **24h duplicate detection** collapses the same issue reported again into one investigation (intake-side hint → agent verifies → archives the duplicate + notes the original), toggled by **Dedup pre-check** (`intakeDedupEnabled`, default on). Sentry issues now run through the **triage gate** before spawning — see next row | [bug-report-intake.md](bug-report-intake.md) |
| Built-in AI helpers (paid cloud vs free BYO key) | How Omniscio's background AI helpers (session titles, suggestions, reply drafts, daily digest) are powered — plan-gated since 2026-07-20. **Your own key always wins** (an `sk-or-…` OpenRouter key at Settings → API Keys → "Your OpenRouter key", or an Anthropic API-key account) → runs direct on your key, any plan. **Paid plan, no own key** → Omniscio's company-paid cloud gateway (the built-in-AI benefit). **Free plan, no own key** → the helpers PAUSE with an "add your key" prompt (no silent cloud fallback, no bundled key). Tier is the Firebase-verified plan claim read fail-safe-to-free (a free/unidentifiable user is never billed to the company pool); the old experimental "Route internal AI through the cloud (test)" toggle was removed (routing is plan-decided). Also carries **the per-tier allowance numbers** (as of 2026-08-25 the pooled-AI allowance is `$0` on EVERY tier — owner decision, so the helpers run on your own key, except session titles, which every paid plan includes since 2026-09-30; every tier is listed explicitly at `$0` because a missing entry means uncapped; resets the first instant of the next UTC month; two company-wide ceilings sit above — a monthly hard-stop lane cap whose shipped value is `DEFAULT_GLOBAL_MONTHLY_USD` in company-ledger.ts, read from there and never from a number typed into a page) and **the two distinct "helpers stopped" cards** — `no-plan-allowance` ("Built-in AI helpers are paused" — nothing was spent) vs `allowance-exhausted` ("Monthly AI allowance used" — a real allowance ran out), which must never be swapped. | [built-in-ai-helpers.md](built-in-ai-helpers.md) |
| Bulk-select sidebar items | Archive multiple sessions at once, bulk pause, bulk snooze — Ctrl+click or Shift+click to multi-select sidebar rows, then E to bulk archive (or P to pause, H to snooze); Shift+J/K extends selection; right-click for the full set of bulk actions. Works on inbox rows too (any type). The fastest way to batch-archive when you have many sessions to clean up | [bulk-select-sidebar.md](bulk-select-sidebar.md) |
| Stop, restart, pause, archive, or message many sessions at once; see what is waiting to start or restart, and cancel queued restarts | A **Manage sessions** picker modal for when lots of sessions are open and you want to act on a hand-picked set, with **seven** views. **Stop** ends the running/starting ones you tick (each left as "ended", so it stays in the list and restarts on your next message); **Restart** relaunches the error/stalled/interrupted ones — plus stopped sessions that still have a conversation — resumed with `--resume`, in list order; **Pause** parks every live/steady session (Needs You included) where it is, so unpause picks the same conversation back up; **Archive** files away anything not already archived (the widest list — it stops a still-running session first). Pick per-row, **Select all**, or use the **first/last** dropdown + a number to grab the first N from the top or the last N from the bottom, and **filter by title** to narrow a long list (the filter scopes Select all / the count / the first-last picker / Apply to just the matching rows, and plain Enter in it never fires the action). Each tab keeps its OWN ticks. The two *ending* views never touch a live "Needs You" session — even when its dot looks red/orange from an error sub-state — because the buckets are decided by true status, not dot color; Pause and Archive deliberately do include it, since neither destroys the conversation. Two homes: a toolbar item acts on ALL projects; a per-project three-dot (⋮) menu item acts on just the project you're viewing (greyed out when nothing qualifies). No second "are you sure?" — the modal (open + pick + a count-naming Apply) is the deliberate gate. **Pause and Archive are Ctrl+Z-undoable** (putting them back is free); Stop and Restart deliberately are not, since the only reversal is a paid re-spawn. **Message view** is the broadcast — type one message, tick recipients, **Send to N**; each gets it as a real turn labelled as coming from you, delivered one at a time. Opened from the toolbar it reaches every project, from a project's ⋮ just that repo. It lists a much wider set than the others (running / needs-you / stalled / paused / stopped / errored) but never a usage-limit-parked, blank, closing, closed, or silent-automation session — not even a running silent one. **Archived recipients are opt-in** behind an off-by-default tickbox, since messaging one reopens it and restarts its agent (paid), so Select-all can never wake an archive. No undo — a delivered turn is already being worked on. **Refill view** is the auto-restarter’s own queue — the interrupted sessions Omniscio would bring back on its own to reach your target, each row saying why it qualifies, with **Restart now N** to do it immediately. **Queued view** is what IS restarting right now: the sessions actually waiting in line, in the order they will come back, merging the ones resuming after an app restart with the ones you queued yourself in the Restart view. It shrinks live as each returns, and **Cancel restart N** pulls just the ticked ones out of the line while the rest keep coming — unlike the “Resuming N sessions” toast’s Stop, which halts the whole wave. A cancelled session is left stopped (restartable any time, no nagging card); a pick that already launched is reported as such rather than counted as cancelled. Under them, read-only, it lists the **new sessions waiting to start** — the ones agents and automations asked for, the same requests the “Session-spawn queue is backing up” alert counts — each with how long it has waited and which session asked for it; the view refreshes itself every 10 seconds while open. | [bulk-stop-restart-sessions.md](bulk-stop-restart-sessions.md) |
| Calendar Quick Add — part 2 (parser design, ambiguity rule, code map) | Part 2 of the Calendar Quick Add page: why the parser is regex-first with the AI as a rare fallback, why the preview shows more than one row only when the input is genuinely ambiguous, and the repo-aware code map underneath the tab. | [calendar-quick-add-part-2.md](calendar-quick-add-part-2.md) |
| Calendar Quick Add (Ctrl+Space → Calendar tab) | Pinned tab inside Quick Launch for creating Google Calendar events from a single natural-language line — recurrence is parsed inline (even a dangling "…every" typed after the day), with a **Repeat** checkbox + frequency picker as a manual fallback; regex-first parser with Haiku LLM fallback (capped at $0.10/day shared), SnoozePalette-style multi-row preview when the parse is ambiguous, main-window toast with **Open** + one-click **Undo**; pinned by default via one-shot startup migration, hidden from the strip when `calendarEnabled` is false; pick any writable calendar (remembered as default) | [calendar-quick-add.md](calendar-quick-add.md) |
| Calendar Scheduler (plugin — booking links into your Google Calendar) | Free marketplace plugin: event types, availability, public booking links, Google Calendar connect, approvals, cancel/reschedule, webhooks, and a "Today's agenda" inbox setting that is on by default. Powers the Send Booking Link action in Team Time. | [calendar-scheduler.md](calendar-scheduler.md) |
| Canva integration (design creation + management via MCP) | Injects the official Canva remote MCP server into Claude sessions so agents can create designs, search your library, export to PDF/PNG/JPG, manage brand templates, and more (~30 tools) — OAuth via browser redirect on first use (no API key needed), feature-flagged; no granular design editing (text color, fonts, element positions, backgrounds are NOT supported by the Canva Connect API — open in Canva for detailed edits); brand templates require Enterprise, resize requires Pro; individual accounts only (team support planned) | [canva-integration.md](canva-integration.md) |
| Cashbox (side-project finance plugin) | First-party plugin that tracks money in, money out and profit for each of your side projects. Type what happened in plain words and it saves the entry at once, reads it with your AI account, converts other currencies at the European Central Bank rate for that day, spots repeating costs and exports to a spreadsheet. Ships switched off (Settings → Plugins), keeps your numbers on this computer, works with the AI switched off, and lets other Omniscio sessions log entries but never edit or delete them. | [cashbox.md](cashbox.md) |
| Catch-Up Card (currently disabled) | 4-line pinned summary at the top of a long session — force-disabled and unwired from Settings as of 2026-04-30 while we evaluate removing it; code preserved | [catch-up-card.md](catch-up-card.md) |
| Channel Invitations (per-channel roles + who-can-post, in Team Chat) | In Team Chat, a channel's membership is explicit: click the **member count** at the top to open the **Members** panel, then **Add members** to search the workspace and add up to 50 people at once, each as a **Member** or **Read-only** (instant add, no accept step — a system line records it). Every member has one of three per-channel roles: **Manager** (post + add/remove members + change roles/settings; the last manager can't be removed or demoted), **Member** (read + post), or **Read-only** (read + react, can't post — sees a "you have read-only access" banner instead of the composer). A manager or workspace admin can set **Who can post** in the channel's Edit dialog to **Everyone** (default) or **Managers only** (non-managers then see "only managers can post"). Roles live in a Firestore `channelMembers` subcollection (`{uid, role, addedBy, addedAt}`) with a denormalized `memberUids` index + a `postingPermission` field; the composer swap is via `resolveComposerReadOnly()`/`ReadOnlyBar`, enforced again in `firestore.rules`. Shipped, on by default (`AMC_SHOW_CHANNEL_INVITATIONS=1` / `channelInvitationsEnabled`). Contract: team-chat-channel-invitations-contract. | [channel-invitations.md](channel-invitations.md) |
| Chat attachments — part 2 (the send pipeline, non-Claude engines, pastes, on-disk files) | Part 2 of the Chat attachments page: the send pipeline that partitions every attachment and delivers it, how non-Claude engines receive attachments as files in the workdir, how a large paste becomes a chip instead of flooding the composer, and where the attachment files live on disk. | [chat-attachments-part-2.md](chat-attachments-part-2.md) |
| Chat attachments (PDFs, text docs, images) | Three-tier handler when you attach files in the composer — images become inline `image` blocks, PDFs become `document` blocks (vision) and save to workdir, text docs save to workdir with their path injected into the prompt; Office formats blocked at attach with toast | [chat-attachments.md](chat-attachments.md) |
| Chat Depth (Flat / Soft / Glass message-depth dial) | A 3-way Settings → Appearance dial — **Flat** (classic flat look), **Soft** (default; gentle shadow + top sheen), **Glass** (stronger glassy depth) — controlling how much shadow/translucency the chat bubbles, the "N actions" activity pill, and the composer have. Independent of the visual theme (theme = colors, this = depth); applies live to the main + pop-out windows. No per-bubble live blur (perf); depth is paint-only shadow + sheen, so it never disturbs chat scroll. | [chat-depth.md](chat-depth.md) |
| Chrome Extension Dev (build and test a Chrome extension autonomously, via agent-browser) | When a project is a Chrome extension (has a `manifest.json` with `manifest_version` 2 or 3), equips the session with an extension-dev workflow that lets the agent load the unpacked extension into a real Chrome, click the popup, take screenshots, read the console, and reload after edits — building and testing without manual clicking. Requires the `agent-browser` CLI + Chrome-for-Testing (one-click "Set it up for me" install). Auto-writes a git-excluded `agent-browser.json` to the project root. Chrome only; no Firefox/Safari; no Chrome Web Store publishing. Includes a "Build a Chrome Extension" guided coaching mission. Privacy-safe: launches a clean managed Chrome, never your real profile. In-development — reveal via Settings → Lab toggle or `AMC_SHOW_CHROME_EXTENSION_DEV=1`. | [chrome-extension-dev.md](chrome-extension-dev.md) |
| System Instructions sub-group of Auto Context | The first of the three Auto Context sub-groups — one-click access to the four AI-context files (project + global `CLAUDE.md` and `MEMORY.md`) — two-line rows show name on top, `mtime · ~tokens` below; click opens the file peek overlay; size-based token estimate (`bytes/4`); virtual projects show globals only; **deliberately exempt from bulk-select** to protect the agent's persistent rules + memory. Renamed from "Claude Files" 2026-05-27 | [claude-files-sidebar.md](claude-files-sidebar.md) |
| Clean Room (spawn a vanilla AI with none of your customizations — a control group) | A special built-in project in the projects sidebar (like Session Search — not a folder) where every session spawns a deliberately **vanilla, blank-context AI**: a control group with **none of your customizations and none of Omniscio's added layers**. Stripped: your global `~/.claude` rules + memory, custom skills, project instructions, connected tools (MCP), and Omniscio's injected context (the awareness note, Plain Speak, markers, and the publish/convert/download helpers). Clean sessions are fully **hook-free** and start in an **empty scratch folder**. It stays **real Claude Code** — the engine's own base identity and built-in tools remain (this is NOT a raw model). Use it to isolate whether a behavior comes from the model itself vs. something you or Omniscio inject, or as a from-scratch baseline. A **per-session engine picker** chooses the engine (defaults to **Claude**; v1 also supports the Claude-compatible **DeepSeek, Kimi, GLM, MiniMax**). Known ceiling: the engine's own base identity and built-in tools always remain (that's the definition, not a gap); everything else — rules, memory, skills (global, project, and plugin), MCP tools, settings, and plugins — is isolated via the engine's safe-mode. | [clean-room.md](clean-room.md) |
| Clear a hub's waiting items (middle-click a hub) | Middle-click a hub in the left sidebar to clear everything waiting on you in that hub — the same rows its **Needs You** section shows; middle-click the **Inbox** row to do it across every hub. A confirmation always comes first, naming the hub, the exact number and the rows themselves, and nothing is cleared until you accept. Sessions are archived the way archiving one by hand does, with ONE Undo that restores each to the status it held; every other row clears through its own integration's path. A hub with nothing waiting does nothing at all. Rows whose clear cannot be undone (pending approvals, doc-token / bloat alerts, connection requests) are listed separately under their own warning heading, and the dialog then opens with **Cancel** focused so Enter never fires a rejection. Left-click still opens the hub and right-click still opens its menu. Desktop-only by construction — touch has no middle button. Deliberately has no hotkey: a keystroke that clears a whole hub is too easy to hit by accident. | [clear-a-hub.md](clear-a-hub.md) |
| Account re-login over HTTP (`POST /accounts/login-capture`) | How an agent completes an Anthropic account **re-login end to end over the CLI control server** without a human driving the desktop UI — the HTTP twin of the account panel's "Log In" button, including which browser it signs into. | [cli-account-login-capture.md](cli-account-login-capture.md) |
| Recent CLI Activity (audit log of CLI control-server calls) | Read-only card at Settings → CLI Control recording every call to the local control server (`127.0.0.1:19519`) — plain-English summary + outcome dot + clickable "Triggered by" / spawned-session links; **Actions** (default) vs **All** filter; actions kept 90 days, reads 7 days, 50,000-row hard cap; liveness pings (`/ping`/`/status`/zapier) skipped; bearer token never stored (coarse caller kind only); best-effort post-response capture that never blocks the request, spawns recorded at source so a client disconnect can't lose them | [cli-activity-log.md](cli-activity-log.md) |
| AI Coaching via CLI (manage coaching artifacts and start interviews from an AI agent) | 41 routes over 29 paths on `127.0.0.1:19519`. Thirteen of them — the artifact and interview routes — are enumerated below; the rest (memory, core profile, goals, bookmarks, stats, feedback, insights, search, snack templates, custom interviews, compaction summaries) are named under "The rest of the namespace" and listed exhaustively in `endpoint-index.md`. Kill-switched via `aiCoachingCliEnabled` (default `true`); optimistic concurrency on PATCH via `expectedLatestVersion`; idempotency via `X-Client-Request-Id` | [cli-ai-coaching.md](cli-ai-coaching.md) |
| CLI Control — part 2 (the endpoints that change things) | Part 2 of the CLI Control page: the endpoints an outside script or AI uses to change things on your behalf — driving a running session, registering, editing or deleting a project, adding and removing project docs, away-mode rules, and firing a recipe — plus how the approval queue and the rate caps treat each one. | [cli-control-part-2.md](cli-control-part-2.md) |
| CLI Control — part 3 (the surfaces an outside AI can look at and drive) | Part 3 of the CLI Control page: AI Coaching interviews and artifacts, bookmarks, inbox alerts, a snapshot or screenshot of the window, an on-screen spotlight it can point with, and a jump straight to one setting. | [cli-control-part-3.md](cli-control-part-3.md) |
| CLI Control (control Omniscio from scripts and hotkeys) | Localhost HTTP server on `127.0.0.1:19519` — navigate, launch sessions, manage cron jobs from AutoHotKey/PowerShell/curl/Python; `GET /ui/snapshot` + `GET /ui/screenshot` + `POST /ui/highlight` let an external AI **discover** what's on screen (structurally as anchored elements, or as a real downscaled PNG via `/ui/screenshot`) and then **spotlight** any DOM element with a Markdown title + body — single step for one-off pointing or a multi-step `{ steps: [...] }` flow with Previous / Next navigation for guided sequences | [cli-control.md](cli-control.md) |
| File a bug / feature request from an AI agent | `POST /feedback` mirrors the toolbar bug-icon flow — type (bug / feature / feedback / question), message, optional email + screenshots; diagnostics auto-attached; runs the shared report-delivery chain (email and Firestore, both gated by the one `bugReportEmailEnabled` send switch); delivered is 200, a safely-kept-for-later report is 202 (retried automatically by the hourly outbox drain), and only a report that could neither be sent nor saved is 502; apply-immediately, shared 10/min rate-limit. `POST /feedback/with-video` attaches ONE full-length video by publishing it as a never-expiring video share and putting the link in the report body — named by library recording id or by a path on disk (a scoped agent token is confined to the share allow-list), a screenshot or an unfinished recording is refused, a refused publish files nothing, and the share token comes back on every outcome so the link stays revocable | [cli-feedback.md](cli-feedback.md) |
| Change keyboard shortcuts by asking AI | Tell an external AI "remove E as the close-panel hotkey" or "rebind snooze to Shift+S" — the `omniscio-control` skill bundle (keybindings surface) PATCHes `/keybindings/:actionId`; applies immediately, no approval gate | [cli-keybindings-control.md](cli-keybindings-control.md) |
| CLI Pending Actions — part 2 (after the decision, the denylist, overrides) | Part 2 of the CLI Pending Actions page: what happens after you decide — how the session that asked is told your answer, what the queue does when a card is never answered, which settings can never be patched from outside, the note rules, the in-app bypass, and the ready-mint override card. | [cli-pending-actions-part-2.md](cli-pending-actions-part-2.md) |
| CLI Pending Actions (approve external AI changes) | External AI requests to change settings or pause/snooze/archive sessions land as approval rows in your inbox; modal shows a humanized field-by-field breakdown (resolved project / session / tag / recipe names, formatted timestamps + currency, "Yes" / "No" for booleans) with a collapsible **Show technical details** expander for the raw JSON; consent titles read "X?" (no verb prefix); informational kinds read "Acknowledge: X" (cron failure alert, session budget warning / exceeded, Nighty Tidy summary); `settings.patch` rows show a leaf-level diff against the prior value Omniscio stashed at queue time ("Will change N field(s):" + per-leaf rows; "No effective changes" for no-op patches); shared queue cap; in-app sessions bypass | [cli-pending-actions.md](cli-pending-actions.md) |
| Quick Replies via CLI (manage the quick-reply library + folders from an AI agent) | 10 routes on `127.0.0.1:19519` for the snippet/divider/folder library — `GET /quick-replies/list` (flat) + `GET /quick-replies/tree` (nested), `POST /quick-replies/create` (discriminated union: snippet \| divider \| folder, each with optional `parentId`), `POST /quick-replies/move` (reparent + reorder), `PATCH /quick-replies/:id` (label/text/autoSubmit only — `.strict()`, reparent via move), `DELETE /quick-replies/:id` (folders need `?mode=cascade\|promote`), `POST /quick-replies/reorder` (bulk reorder), `POST /quick-replies/restore` (undo a CLI delete from a full snapshot; `409` if a live row holds that id), `GET /quick-replies/export` (whole library as a portable bundle) + `POST /quick-replies/import` (add-only merge of a bundle; `400` on a bad payload); **every mutation apply-immediately** (no inbox approval), no idempotency dedup | [cli-quick-replies.md](cli-quick-replies.md) |
| CLI session recovery (unstick sessions over HTTP) | Get stuck sessions going again over the CLI — list accounts (`GET /accounts`) to find a healthy target, then `restart` (process dead), `move-account` (account frozen/rate-limited), or `nudge` (alive-but-idle). All apply immediately, bearer-authed, no approval queue | [cli-session-recovery.md](cli-session-recovery.md) |
| SMS via CLI (read, triage, and send texts from an AI agent) | 18 routes on `127.0.0.1:19519` for the Pushbullet SMS integration — bearer-gated reads (`GET /sms/status`, `/sms/devices`, `/sms/conversations(/:phoneNumber)`), apply-immediately triage (`read`/`archive`/`unarchive`/`snooze`/`unsnooze`/`dismiss`/`contact-name`/`sync`/`connect`/`disconnect`, each emitting `sms:conversation-updated`), and approval-gated `POST /sms/send` (counts against the monthly limit; a failed send is never reported as sent and is never auto-retried); set-token / device-pick / the paid AI helpers stay desktop-only | [cli-sms.md](cli-sms.md) |
| Tags via CLI (manage the tag library from an AI agent) | 8 routes on `127.0.0.1:19519` for the curated tag library — `GET /tags`, `GET /tags/:id/sessions` (the reverse lookup: which sessions carry a tag), approval-gated `POST /tags`, `PATCH /tags/:id`, `DELETE /tags/:id` (with cascade preview), and immediate per-session `POST /sessions/:id/tags`, `DELETE /sessions/:id/tags/:tagId`, `GET /sessions/:id/tags`; library mutations land in the Omniscio inbox until approved, per-session apply/unapply applies right away; idempotency via `X-Client-Request-Id` | [cli-tags.md](cli-tags.md) |
| ClickUp (in development) | In-development real ClickUp API integration (default-hidden, gated via the `clickup` unreleased-feature; `clickupEnabled` toggle in Settings → Lab, or `AMC_SHOW_CLICKUP=1`). Adds a "ClickUp" sidebar virtual project that connects to your real ClickUp workspace via the ClickUp API v2. Connect via a Personal API Token in Settings. Implements workspace/space/folder/list navigation, kanban board by status, task detail drawer (description, assignees, tags, checklists, comments), task search, and a `clickup-inbox` source surfacing tasks assigned to you as unified-Inbox rows. CLI routes for AI agents: POST /clickup/update-task-status, POST /clickup/create-task. Rate-limited (4 concurrent, auto-retry on 429). SSRF-guarded to api.clickup.com. | [clickup.md](clickup.md) |
| Clipboard history (in-app clipboard manager) | Clipboard manager built into Omniscio — a background watcher remembers the recent things you copy (text + images, system-wide). Reach it two ways: a clipboard button in the chat composer (toggleable), or a standalone **Win+V** pop-up (Windows) that appears anywhere even when Omniscio is unfocused — pick a copy and it lands on your clipboard and auto-pastes into the app you were in (auto-paste toggleable). Saved encrypted across restarts by default (with a 14-day auto-cleanup, pinned copies exempt; switch it off to keep the history in-memory only), keeps capturing while Omniscio is unfocused, and skips items apps mark sensitive (password managers / Win+V "exclude" markers). Never logged or sent anywhere; the renderer only sees a text preview + image thumbnail. **On by default**, with one real off-switch at Settings → Features → "Clipboard history" (off stops capture, hides both surfaces, and deletes the encrypted on-disk copy). The picker's default shortcut is **Ctrl+Alt+V**, not Win+V — Windows reserves Win+V for its own clipboard history, so Omniscio's runs alongside it with nothing to turn off. | [clipboard-history.md](clipboard-history.md) |
| Letting an agent run its checks here (cloud-enforce window) | A bounded window, granted from an ordinary approval card, in which one agent may run its heavy checks on this machine while the testing setting (cloud first) would otherwise send them to a remote test machine. It covers one agent by default, always expires on its own, and never turns enforcement off for anyone else. | [cloud-enforce-window.md](cloud-enforce-window.md) |
| Returned cloud work lands itself | A cloud session's finished work comes home as a branch and lands on its own — this app's checkouts via ready-to-merge, any other project on its own tests; dependency changes and unscanned secrets never auto-land; secret cleanup failures remain visible | [cloud-returned-work.md](cloud-returned-work.md) |
| Cloud session templates (saved starting copy) | Later cloud sessions of a project start from a saved copy of its first one, so only what changed is sent and dependencies are reused only when their recorded inputs match; built in the background on its own machine, switchable off | [cloud-session-templates.md](cloud-session-templates.md) |
| Cloud session won't start: the real reason, and what to do | A cloud session measures your upload before renting a machine and refuses openly when it cannot finish; uploads now take turns so a wave of sessions no longer starves your connection; every stop names the real reason | [cloud-session-when-it-wont-start.md](cloud-session-when-it-wont-start.md) |
| Coaching Tips (contextual hints) | Low-frequency inbox cards that teach you shortcuts and unused features — 5 categories, full opt-out | [coaching-engine.md](coaching-engine.md) |
| Code blocks that are really prose | A fenced block that is actually hard-wrapped PROSE (a prompt to copy, a quoted message) used to render ragged, because its soft wraps sat flush left and read as real newlines. Such blocks now render as flowing paragraphs. A free instant check settles ~95% of blocks as code and never touches them; only the leftovers (about five a day) get one cheap-model question, and only an explicit "prose" answer reflows. Real code is never reflowed, anything uncertain renders exactly as before, lists and tables keep their line structure, and copying always yields the original text. Contract: code-block-prose-classification-contract. | [code-block-prose-rendering.md](code-block-prose-rendering.md) |
| Codebase Stats (project health dashboard) | 7-tab modal analyzing project size, health, git activity, deps, coverage, and AI spend per project | [codebase-stats.md](codebase-stats.md) |
| Codex provider — part 2 (managed sign-ins, per-project engine, model and effort) | Part 2 of the Codex provider page: how Omniscio holds and manages your Codex sign-ins, how a project remembers which engine its sessions start on, and how you pick the OpenAI model and the reasoning effort a Codex session runs with. | [codex-provider-part-2.md](codex-provider-part-2.md) |
| Codex provider — part 3 (what runs on start, the streamed turn, the code map) | Part 3 of the Codex provider page: what actually runs when you start a Codex session, how Omniscio talks to it and streams a turn back, and where the pieces live in the codebase. | [codex-provider-part-3.md](codex-provider-part-3.md) |
| Codex provider (CLI-backed sessions) | Spawn Claude-Code-style sessions backed by OpenAI's Codex CLI alongside `claude` and `gemini` — gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via Settings → Account OpenAI API key + Codex CLI binary + "Allow Codex sessions" toggle; long-lived JSON-RPC app-server child per session, emerald "Codex" pill in the session header, per-launch ChangeProviderButton + per-project default | [codex-provider.md](codex-provider.md) |
| Coffer (in development) | In-development first-party personal-finance tracker (default-hidden, gated via the `coffer` unreleased-feature; `cofferEnabled` toggle in Settings → Lab, or `AMC_SHOW_COFFER=1`). Adds a "Coffer" sidebar virtual project (Productivity group, sentinel `__coffer__`) whose panel renders a native full-screen Mint.com-style finance UI: typed accounts, a transactions ledger (splits, payee rename, bulk edit), auto-categorization via a staged learning rules engine with a review queue, budgets with rollover + Everything Else + an auto-starter budget, Mint-CSV/generic-CSV/OFX import (never screen scraping), and an Overview card dashboard with net worth. Fully local (SQLite `coffer_*` tables, integer minor-unit money); spec in docs/research/mint/. | [coffer.md](coffer.md) |
| Communication group (sidebar) | Collapsible sidebar group nesting Team Chat, Email Cleanup, Email Summarizer, Drip, Meetings, Screenshots, Screen Recording, Voice History, and Voiceprint Studio — send, receive, or manage messages and meetings; ships collapsed by default; render-only nesting | [communication.md](communication.md) |
| Auto-delete old message content (opt-in communications retention) | Opt-in, **off by default** privacy control (**Settings &rarr; General &rarr; "Auto-Delete Old Message Content"**) that permanently erases communications content older than a window you set (30&ndash;3650 days, default 365): SMS/Telegram/Slack/webhook messages, email-summarizer samples, voiceprint data, daily digests, and meeting raw audio + transcript. There is **no undo** &mdash; the safety is the opt-in choice plus a one-time inbox notice plus a **30-day grace** before the first deletion. Never touches your agent sessions, vault/KMS notes, saved contacts, or meeting **notes** (the summary + action items are kept; only the raw recording/transcript go). Runs on the daily retention tick; direct hard-delete (no soft-delete columns, no migration &mdash; the opt-in + notice + grace are the safety). CLI: it is a normal setting `communicationsRetentionDays` (0 = off, else 30&ndash;3650) over `GET`/`PATCH /settings`. | [communications-retention.md](communications-retention.md) |
| Compaction Summary (expandable inline) | "Show summary ▾" on the "Conversation compacted" divider expands Claude's structured 9-section summary inline, with a Copy button — streamed from the CLI JSONL on click | [compaction-summary.md](compaction-summary.md) |
| Composio connector (in development) | In-development Composio connector (default-hidden, gated via the `composio` unreleased-feature; `composioEnabled` toggle in Settings → Lab, or `AMC_SHOW_COMPOSIO=1`). Adds a "Composio" sidebar virtual project (sentinel `__composio__`) where you connect external apps (Gmail, Slack, GitHub, Notion, 1000+ more) through Composio using your OWN free API key (encrypted at rest, never returned to the renderer). Omniscio mints a per-user Composio Tool Router MCP URL in the background and injects it (url + `X-API-Key` header) into every spawned Claude session — fail-safe, never in the spawn hot path, never into secret-excluded/KMS sessions, only when a key is set and ≥1 app is connected. CLI: GET /composio/status, GET /composio/toolkits, GET /composio/connections, POST /composio/connect, DELETE /composio/connections/:toolkit. | [composio.md](composio.md) |
| Connection Request Inbox Items | An incoming Team Chat connection request appears as an inbox item — an approval-routed row with the requester's name, avatar, and email plus Accept/Decline — for EVERY authenticated user, even before Team Chat is enabled in Labs (the cross-org connections listener runs unconditionally). Accept auto-enables Team Chat if needed and opens the new DM; Decline deletes the pending request; dismissing an inbox row only snoozes it (never accepts/declines). The Team Chat sidebar's own Connections section shows the same pending requests from the same Firestore source. | [connection-request-inbox.md](connection-request-inbox.md) |
| Console window sentinel (stray black console windows are hidden) | ON by default on Windows, nothing to set up: a small helper Omniscio starts with the app watches for console windows the moment they appear and HIDES the ones that belong to automation — a console opened anywhere inside an agent session's process tree, by an Omniscio helper, or by a Windows Scheduled Task running in the user's session (the "black window pops up over Omniscio and steals my typing" bug, 2026-09-08). It never hides a console the user opened (Explorer, Windows Terminal, a shortcut), leaves anything it cannot attribute visible and logged, only hides the window (the program keeps running; no Windows setting changes), never shows an inbox card, and logs every hide/leave decision with the owning process chain — `npm run console-sentinel:report` prints the recent lines. Companion guard: an agent may not register a scheduled task with a bare console program (`powershell`, `cmd`, `node`, …); the refusal names the hidden form `conhost.exe --headless …` (acknowledge a deliberately visible task with `AMC_ALLOW_VISIBLE_TASK=1`). A program that must stay visible declares `AMC_ALLOW_VISIBLE_CONSOLE=1`. Off switch for developers: `AMC_DISABLE_CONSOLE_SENTINEL=1`. Limits: a one-frame flicker at most; a window that carries neither the app's `PATH` marker nor any traceable ancestry stays visible (`unknown`); dev / `npm run dev` installs only (packaged builds do not ship the helper yet). Related setting: Reduce terminal popups (which terminal HOSTS a stray console). Contract: console-window-sentinel-contract. | [console-window-sentinel.md](console-window-sentinel.md) |
| Consumer Terms gate (accept updated Anthropic terms) | When an Anthropic account must accept updated Consumer Terms & Privacy Policy, Omniscio detects the API 400 in the synthetic placeholder event, stops the session with a clear "accept terms at claude.ai" message instead of retrying in a loop, excludes the account from the spawn pool, and surfaces an inbox card. Fix: sign in at claude.ai, accept terms, restart Omniscio. | [consumer-terms-gate.md](consumer-terms-gate.md) |
| Context Details (what's in the agent's context window) | Popover with a token breakdown of what's consuming the current session's context — summary row + expandable per-source sections (system prompt, MCPs, skills, memory, etc.); reachable from the **⋯ three-dot menu → Context Details** (always available, percent badge inline) or from the optional donut-ring indicator in the session header (Settings → Sessions toggle, off by default) | [context-details.md](context-details.md) |
| Out-of-context stall recovery (auto-continue a turn that ran out of room) | When a turn ends with the context window near-full and the agent didn't ask a question, isn't parked waiting, and didn't ALREADY deliver its final answer, Omniscio auto-sends a "Please continue" nudge so the CLI compacts and the agent finishes the thought it ran out of space for — shown with an "Auto-recovering…" note. Near-full is not the same as stuck: a turn that hit the ceiling but still wrote its closing reply is FINISHED and is left alone (2026-08-25). Bounded: after a few un-freeable nudges it stops, posts a "may need a fresh session" note, and drops the session into your inbox; never loops forever. On by default. | [context-stall-recovery.md](context-stall-recovery.md) |
| Context usage warnings (75% and 90%) | Amber in-chat warnings when a session's context window reaches 75% or 90% capacity — persistent divider lines with triangle-warning icon and token counts; **both thresholds ship OFF by default** (2026-08-25; NEW installs only — an existing config.json keeps its stored value, there is no force-off migration), turned on in Settings → Sessions → Advanced OR right from a warning already showing (⋯ options button / right-click → explainer popover with both on/off switches); checked at turn-complete in the default mode (the 90-second poll timer is legacy-only, `smoothLoadEnabled: false`); flags reset after compaction so the next ramp-up re-triggers | [context-warnings.md](context-warnings.md) |
| ContextDock (Native) (in development) | In-development local-first rebuild of the ContextDock library UI that reads Omniscio's OWN authoritative store (docs / bundles / lists / tags + on-demand context assembly) over the local `contextdock-store:*` IPC — distinct from the vendored ContextDock integration above (which snapshots a remote workspace). Adds a "ContextDock (Native)" sidebar virtual project (Productivity group, sentinel `__contextdock_native__`, NON-spawnable) whose panel has five panes: Library, Bundles, Lists, Tags, and Export (assemble a selection into one context payload, copy / download). Default-hidden, gated via the `contextdock-native` unreleased-feature (`contextdockNativeEnabled` toggle in Settings → Lab, or `AMC_SHOW_CONTEXTDOCK_NATIVE=1`). Desktop-only — the local-store reads + writes are blocked on the mobile/web bridge until cutover. | [contextdock-native.md](contextdock-native.md) |
| ContextDock Integration — part 2 (what it won't do, the error map, the caps) | Part 2 of the ContextDock integration page: what the integration deliberately does not do, the full error-and-recovery map for every failure code, the size caps that decide how much linked content can reach a session's first message, and what to gather before filing a bug. | [contextdock-part-2.md](contextdock-part-2.md) |
| ContextDock Integration — part 3 (on-disk snapshots, the cache, the IPC surface) | Part 3 of the ContextDock integration page: where a linked snapshot is written on disk, the sentinel header that marks it as Omniscio-managed, how the picker cache is kept warm, how a snapshot reaches a session's first message, and the full agent-facing IPC surface. | [contextdock-part-3.md](contextdock-part-3.md) |
| ContextDock integration | Link bundles AND lists from your ContextDock workspace into Omniscio projects so every session sees the contents automatically — Settings → ContextDock → API key, then Add Project Doc → ContextDock tab (inner Bundles / Lists / Library sub-tabs with per-tab search); picker reads from a SQLite cache populated by a startup preload so it renders instantly, `Updated Xm ago` caption + 🔄 button for manual refresh; **Bundles** get a one-click Add at their author-set `preferLevel` (defaults to Key Points); **Lists** carry both an **Add** (whole list as a single doc, same shape as a bundle) and a **Browse** that drills into a per-doc surface with native level `<select>` per row, a one-shot bulk-apply select, and running token totals; **Library** full-text-searches your whole doc library and links one individual doc at a chosen compression level (works even with zero bundles/lists); per-doc rows reorder by whole-row long-press drag (no grip) and carry an inline compression chip; snapshot-at-link-time (no auto-refresh), 🔄 button on project-docs rows refreshes individual snapshots, sentinel header marks Omniscio ownership, 30 KB / 100 KB hook caps; `vendor_broken` install-fix hint when the vendored CLI bundle is corrupt | [contextdock.md](contextdock.md) |
| Copy / export a session as Markdown | Session `⋯` → **Exports** submenu — **Download** the transcript to a `.md` file, **Copy as Markdown** to the clipboard, or **Copy since last compaction** (most recent `/compact` divider forward; falls back to the whole thread with a clarifying toast when never compacted, or when a just-landed compaction has no post-compaction agent reply yet). Exports are **visible-only** (2026-05-25): operator + agent prose including intermediate narration; mechanical `▸`/`←` tool-call/result lines stripped fence-aware; system rows dropped; tool-only agent turns skipped. Each menu item shows the approximate token size (`~Xk`) **right in the submenu before you click** via the read-only `SESSION_EXPORT_TOKEN_PREVIEW` IPC, and the success toast shows the same number; the count never enters the file body. Asides (sidechain branches) excluded from every export | [copy-session-as-markdown.md](copy-session-as-markdown.md) |
| Cost Control (watch spend + manage every cap in one place) | Top-level sidebar surface (System group, next to Stats): live spend at the top and every budget cap editable inline — the per-session / daily-per-account / per-metered-vendor caps (reused from Sessions), the workflow + automation caps, and the per-feature daily caps. Composes the existing spend data + settings-backed controls (no second copy); a cap edited here is the same setting its home screen writes. Toggle `costControlSidebarEnabled` to hide. | [cost-control.md](cost-control.md) |
| Crash recovery — part 2 (crash-loop breaker, death watchdog, what is never resumed) | Part 2 of the Crash recovery page: the crash-loop circuit breaker that quarantines a session, the silent-death watchdog that alerts you the moment the app is killed, the states that are never auto-resumed, why revivals trickle, and where each piece lives in the code. | [crash-recovery-part-2.md](crash-recovery-part-2.md) |
| Crash recovery (auto-resume after crash/restart) | When Omniscio starts and detects sessions that were running last time it exited (crash or clean shutdown), those sessions auto-resume — sidebar paints them as `starting` immediately, single-worker queue drains over the next minute (3 s gap between launches) so the window stays responsive, each revived session receives a `"Please continue"` operator turn with an auto-response badge, a `Resuming N session(s) from last shutdown` toast fires once. 120 s recency filter rules out genuinely old failures; 30 s per-launch timeout + 15 min hard ceiling; gated by **Settings → Workflow → Auto-Resume Sessions on Restart** (`autoResumeOnCrash`, default on) | [crash-recovery.md](crash-recovery.md) |
| Create a cron job by asking AI | Tell an external AI "schedule X every day at 9am" — it creates an Omniscio cron job via the auto-delivered CLI token (approval-gated) | [create-cron-job-with-ai.md](create-cron-job-with-ai.md) |
| Creative group (sidebar) | Collapsible sidebar group nesting Writer, Flowcharts, JLS Image Studio, and Decks — make, capture, or produce content; ships collapsed by default; render-only nesting | [creative.md](creative.md) |
| Cron failure alerts (toast + inbox card) | When a cron job fails (and self-healing isn't taking it over), Omniscio fires a Windows toast and inserts a single inbox card per job — error preview, failure count, optional "Self-heal pending…" chip; click for the full-detail dialog with Acknowledge / Open Job / Enable Self-Healing / Run Now / Snooze 24h. Auto-dismisses on next-run success. Suppressible by silence / mute / Focus Mode (toast only) and an open `cron.failure_heal` row (card too) | [cron-failure-alerts.md](cron-failure-alerts.md) |
| Rename a cron group header | Hover-revealed pencil on each cron-view group header (project mode only) opens an inline rename input — Enter saves, Esc cancels, empty/whitespace/equal-to-live commits a reset back to the canonical project name; per-install override map keyed by project id, frequency-mode headers are not renameable, orphan keys auto-pruned on startup + project delete | [cron-group-rename.md](cron-group-rename.md) |
| Cron Jobs (create and manage scheduled jobs in the app) | The Cron Jobs screen: creating a scheduled job by hand and managing it afterwards. Three job types — Script (a shell command), Recipe (a saved multi-step workflow) and Session (start a new Claude session with a prompt) — each with its own fields, plus the schedule, the approval switch that puts every run in your inbox first, self-healing, run-if-missed and per-job environment variables. The dashboard lists and searches every job grouped by project or by frequency, each job carries its own run history and a Run Now control, and a job can be chained to run after another one completes. It also explains what happens at fire time: the three rate controls that can delay a start by up to about two minutes on a busy machine (and why a manual Run Now never is), and the six alerts the scheduler can raise, one row each. | [cron-jobs.md](cron-jobs.md) |
| Run if missed (cron catch-up) | Per-job toggle (default off; recurring/limited only) — when Omniscio was closed across a scheduled fire, the job runs ONCE on next open, catching up misses from the last 7 days. Boot recovery leaves the past-due `next_run_at` unadvanced so the next tick fires it through the normal path (approval gate + at-most-once idempotency inherited); all missed windows collapse into one run. Settable via editor or `POST/PATCH /cron/jobs` | [cron-run-if-missed.md](cron-run-if-missed.md) |
| Cron self-healing | When a cron job fails permanently, a per-job opt-in spawns a Claude session pre-loaded with the failure to diagnose, edit, /run, and /toggle the schedule back on; auto-fire restricted to timeout/network; 3-strike escalation card | [cron-self-healing.md](cron-self-healing.md) |
| Cron job — Session spawn type | Third cron job type alongside Script and Recipe — fires `createSessionWithPrompt(projectId, prompt)` at the scheduled time, equivalent to clicking "+ Session" with a pre-typed prompt; project + prompt required, sessionName optional, 5-minute minimum interval to protect against account drain | [cron-session-jobs.md](cron-session-jobs.md) |
| Cross-device agent messages (your agents on your own computers) | **In development, off by default.** Your agents on two computers signed into the same account can message each other. A conversation is a named thread, routed on EACH computer to a session you choose there, so one computer can run three conversations into three sessions while the other points the same three wherever it likes. Switch it on on both machines and they see each other without any setup — then you connect them, one click on each computer, and until that agreement exists on both sides nothing at all is delivered. Messages ride a private channel only your account can be a member of, and every conversation starts muted and held out of your Team Chat — no sidebar row, no unread dot, no badge — until you unmute it, at which point it becomes an ordinary channel you can read along with. What arrives is framed as another machine's words, never as your own instructions, and never wakes a session you archived. A turn budget (six turns with no human message, fifty a day, a fifteen-second gap) stops two agents talking to each other forever, and one switch stops everything at once. You drive it from its own Settings section — rename this computer, point each conversation at a session, mute, unmute, refill the budget — or over the command line. | [cross-device-agent-messages.md](cross-device-agent-messages.md) |
| Cross-Device Sync (seamless, Omniscio-hosted, end-to-end encrypted) | **Off by default (opt-in)** — the Settings toggle is the real off-switch: sync runs only when you turn it on, it takes effect live (no restart), and the background loop paces itself so it never slows the app. Sign into Omniscio on any of your computers and your setup is already there — sessions, projects, recipes, automations, non-secret settings — kept in sync end-to-end encrypted through an Omniscio-hosted **encrypted courier** the server can't read (zero-knowledge; local SQLite stays authoritative). Evolves the folder-based Backup Mirror. Unlock is **device enrollment** (no password): the first device makes a data key + a one-time high-entropy **recovery code**; a new machine enrolls by **approving it from another device** (ECIES re-wrap, shown with a key fingerprint) OR **pasting the recovery code**, then rebuilds its local DB (additive-merge, never a wipe) and runs the Post-Restore Credential Wizard. Device management: a per-user device list, **de-enroll**, and **rotate keys** (re-encrypts the whole locker + revokes a removed device, new recovery code). Secrets never sync. Keywords: cross-device sync, sync across devices, new computer, device enrollment, recovery code, rotate keys, de-enroll, zero-knowledge, encrypted sync | [cross-device-sync.md](cross-device-sync.md) |
| Connect with someone in another company (cross-org DMs) | Start a 1:1 direct message with ANY Omniscio user by their sign-in email — a coworker in your workspace or someone in a completely different organization. You send a request from Team Chat’s Connections section and the connection forms ONLY when they approve, so nobody can message you uninvited. | [cross-org-connections.md](cross-org-connections.md) |
| Cross-Session Messaging — part 2 (undeliverable messages, how an arrival draws, controls) | Part 2 of the cross-session messaging page: what happens to a message that cannot be delivered, how an arrival is drawn for the receiver and for the sender, who the overseer is right now, and the controls that quiet or unfold an exchange. | [cross-session-messaging-part-2.md](cross-session-messaging-part-2.md) |
| Cross-Session Messaging — part 3 (delivery limits, boundaries, the full reference) | Part 3 of the cross-session messaging page: the delivery limits and retry safety, the plain-language boundaries of the feature, and the full request and response reference with the code that implements it. | [cross-session-messaging-part-3.md](cross-session-messaging-part-3.md) |
| Cross-session messaging (agent → agent) | Twin HTTP endpoints — `POST /sessions/:id/peer-message` injects an operator turn: a busy target is held (not dropped) unless you confirm `confirmInterruptTurn`, and a paused/archived/ended/error target is refused 409 unless you confirm `confirmInactiveTarget`; `POST /sessions/:id/peer-aside` is RETIRED (answers 410) — an aside is the human's side-question channel and Omniscio never uses one to talk to an agent. A 120/hour per-bearer-token rate limit. Apply-immediately, not approval-gated — bearer token is the authority. A receiving agent can end its turn with `[[OMNISCIO_COLLAPSE_EXCHANGE]]` to fold the arrival AND its own reply into one expandable line (display only; never applies to a turn the user opened, a turn asking them a question, or audit mode) | [cross-session-messaging.md](cross-session-messaging.md) |
| Cursor provider (CLI-backed sessions) — part 2 | Part 2 of the Cursor Provider page: how a turn actually runs under the hood — the cursor-agent process Omniscio launches, how its output is turned into an ordinary Omniscio session stream, and the stream format as validated against a real capture. Part 1 covers what changes on screen, the readiness gates, choosing a model and the error states. | [cursor-provider-part-2.md](cursor-provider-part-2.md) |
| Cursor provider (CLI-backed sessions) | Spawn Claude-Code-style sessions backed by the Cursor CLI (`cursor-agent`, Anysphere's Composer model) — a **first-class** alternative provider (indigo "Cursor" session-header pill, per-project default, switch-to-able). Gated behind master "Show alternative AI providers" (off by default), then opt-in via Settings → Account Cursor CLI binary (PATH-only, detect-only) + **Cursor's own** API key (env `CURSOR_API_KEY`, not Anthropic) + "Allow Cursor sessions" toggle; per-turn one-shot subprocess (`cursor-agent -p --output-format stream-json --force`) with token-by-token NDJSON streaming and native `--resume <id>`; 3 readiness gaps (`toggle-off`, `binary-missing`, `key-missing`); no virtual project; **records $0 cost** (Cursor's CLI emits no usage); codex-grade lifecycle teardown. ⚠️ stream-json fixture is synthetic — reconcile against a real capture before trusting end-to-end | [cursor-provider.md](cursor-provider.md) |
| Custom model instructions (write your own instructions for a specific engine or model) | Free-text instructions you write once and Omniscio auto-adds to a specific engine's or model's prompts — steer Codex one way, Claude another, or one model differently from its siblings, without retyping per session. **Settings → Accounts → Custom model instructions**: build a list of **rules**, each a block of text plus **targets** — a whole engine/family (a checkbox for Codex/Claude/Gemini/… = all that engine's models) and/or specific **model ids** (comma-separated, e.g. `gpt-5.5-codex`). A session gets **every rule whose engine OR effective model matches**, concatenated — so one rule can cover a model, a family, or many at once, and a broad family rule layers with a model-specific add-on. Delivered via the shared engine system-prompt bundle: Claude-family engines get it in the real system prompt (`--append-system-prompt`), **Codex** (recent versions) through Codex's own `developerInstructions` system-prompt channel, other external engines (Gemini/…) as the invisible first-message context (never shown in chat). Off until you add a rule (empty = inert); not applied to the Ask Omniscio helpers; matching uses the session's effective model (its pick, else the engine default). Known gap: sessions inside the dedicated `__codex__`/`__gemini__` sidebar projects get no injected context (like Plain Speak there) — a normal project folder works fully. Setting `customPromptRules`; contract: engine-prompt-bundle-contract. | [custom-model-instructions.md](custom-model-instructions.md) |
| Custom Providers (bring your own web AI provider) | Add almost any web AI provider yourself — an OpenAI-compatible or Anthropic-compatible endpoint (name + base URL + API key + models) — and run it as a named provider inside the Claude Code harness. OpenRouter ships built-in. The base URL is SSRF-validated (http/https only, no loopback / private-network addresses) and the API key stays encrypted in the main process. Shipped; setting `customProvidersEnabled`. | [custom-providers.md](custom-providers.md) |
| Custom Render Rules (turn your own regex matches into inline badges) | Define your own rules — each a **regex** whose matches in conversation text (**both** agent output and your own messages) render as an inline **badge** instead of plain words, so the things you care about (a `PR #1234`, a `TODO`, a ticket id) pop out. Each rule sets a **tone** (color: neutral/accent/success/warning/danger/info), an optional **icon** (a short curated set: tag, check-circle, git-pull-request, rocket, flag, bug, …), an optional **label** template, and an optional clickable **http/https link** template — both templates built from the match with `$0` (whole match) and `$1`..`$9` (capture groups). Manage them in **Settings → Sessions → Custom Render Rules**: add/edit/reorder (first match at each spot wins)/toggle/delete, with a live **"test it" preview** showing the badge + resolved link before you save, plus a **master toggle** that disables all rules without deleting them. Rendering is safe (real React badges, **no raw HTML**; **http/https-only** links; skips code blocks & existing links; guarded against invalid/zero-width/greedy regex) and **zero-cost** when no rules exist. Reuses the existing message-render path (a rehype pass in the lazy Markdown chunk) + the normal external-link opener; runs on-device, no AI/token cost. Setting keys `customRenderRules` + `customRenderRulesEnabled`. Synonyms: regex render rules, message badges, custom badges, status pill, PR badge, highlight rules. | [custom-render-rules.md](custom-render-rules.md) |
| Custom Session Groups (create your own collapsible sidebar sections) | Make your OWN sections in the left session sidebar — like **NEEDS YOU** / **PAUSED** — to organize sessions ("Client X", "Experiments"). A "group" is a library **tag** you flag **"Show as a sidebar group"** in the tag editor; it then renders as a collapsible section listing the current project's sessions carrying that tag. Scope is the tag's own — **Global** (appears in every project) or **per-project** (only there). It's an **overlay, not a folder**: a grouped session ALSO still appears under its status section (Live/Paused), and empty groups self-hide. A session can be in several groups; each folds independently **per project**; works on **desktop + mobile**. **Opt-in** — part of the tag system (`sessionTagsEnabled`, off by default): create a group in **Settings → Tags**, add sessions via a session's **⋯ → Tag** menu. Under the hood a `tags.show_in_sidebar` flag reuses the whole tag system (membership, scope, CLI) with **no new IPC channel**; the built-in status sections are untouched. Contract: session-groups-contract. | [custom-session-groups.md](custom-session-groups.md) |
| Custom share URL name (custom slug + short link) | Paid users (Pro or above) can replace the random 64-hex token in a share link with a memorable **name**, so the public page reads `https://shares.omniscio.com/s/<name>` instead of `/s/<token>`. An optional **short link** (`omnisc.io/<code>`) can be minted for the same share at publish time. Applies to any share through the standard publish pipeline; toggled by the `customShareUrlEnabled` setting (Settings → Sharing), default off. | [custom-share-url.md](custom-share-url.md) |
| Customize the header toolbar (pin / remove / right-click) | The header toolbar's pinned icons plus the three-dot "More" overflow menu. A fresh install ships a **lean** pinned bar (Notifications · Scratchpad · Feedback · Settings) with everything else one click away in the overflow, which is **organized into labeled sections** (Notes & capture, Sessions & workflow, Notifications & focus, System & diagnostics, Help & support, Integrations, Experimental) so it stays scannable. Right-click ANY button (pinned or in the overflow) for a context menu — **Go to settings** (jumps to that feature's settings page; hidden for action-only buttons like Hard Reload / Help), **Pin / Unpin** (move between the bar and the overflow), and **Remove from header** (hide from both — does NOT disable the feature; toast with Undo). Removed buttons are re-added from Settings → Widgets (which also offers pin/unpin/reorder + Reset to defaults); the Settings gear is never removable. **Right-clicking the header bar itself** (its content — app name / account / widgets — not the empty drag-middle) opens a widget menu: an inline add/remove toggle list + a "Manage widgets…" escape (`type:'header'`, guarded by `shouldOpenHeaderContextMenu`). Distinct from Auto-Tidy, which demotes rather than removes. Every left-sidebar tool — and any plug-in you enable — ALSO appears as a derived button in the overflow (pinnable like any other), so the header tracks the sidebar automatically with zero per-plug-in wiring. | [customize-toolbar.md](customize-toolbar.md) |
| Daily Brief | One calm inbox card a day: what shipped, what could not merge, what is held waiting on you, and how many approvals were auto-cleared. Deterministic, no AI call. Quiet day sends nothing. Distinct from Daily Digest (which has no visibility into landings) | [daily-brief.md](daily-brief.md) |
| Set Up My Daily Briefing (guided digest-enable mission) | guided mission that switches on the built-in Daily Digest at a chosen hour, reversibly. | [daily-briefing-mission.md](daily-briefing-mission.md) |
| Daily Digest | Once-a-day AI briefing of what happened across sessions + channels + calendar, with follow-up Q&A chat | [daily-digest.md](daily-digest.md) |
| Daily Journal Check-In (AI Coaching daily/weekly check-in nudge) | Opt-in inbox nudge to run a short **Daily Check-in** or a longer **Weekly Review** journaling interview with your AI coach at a chosen time (the weekly review on a chosen day; never both in one day). It runs as a real coaching interview, so entries accumulate as versioned artifacts that feed the Core Profile — but they are **coaching-only**: stamped `coaching_only=1` at save and excluded from the "Things to know about the user" block ordinary sessions get, at the single `buildSessionProfileContext` chokepoint (`includeCoachingOnly: false`). A 5-min scanner raises the nudge (gated on `dailyJournalEnabled` + `aiCoachingEnabled` + a usable key + the interview being seeded; once-per-period via the nudge's own inbox dedup key — no extra table); its "Start check-in" button launches the interview via an `AlertInboxViewer` carve-out with a fixed constant promptId. Shipped; nudge time + weekly-day configurable in Settings → AI Coach. | [daily-journal.md](daily-journal.md) |
| Daily Spend Report (plugin — a daily AI value & spend inbox card) | A first-party sandboxed plugin (`src/plugins/daily-spend-report/`, bundled + on the Marketplace) that posts ONE deduped Inbox card each day summarizing your AI coding value and real out-of-pocket spend, read from the host ledger via `ctx.spend.getBreakdown()`. A daily cron (`reportTime` setting, default 09:00) fires `ctx.inbox.postAlert`; a per-day storage stamp catches up a missed post on next app-ready. Free — reads the ledger, makes no model call. | [daily-spend-report.md](daily-spend-report.md) |
| Data folder recovery (your data looks gone after an update) | Where Omniscio keeps your data (`~/Library/Application Support/omniscio`, `%APPDATA%\omniscio`, `~/.config/omniscio`) and what happens when the folder name changes in an update: the old folder is moved onto the new name; a never-used leftover under the new name (no database, or a database with zero sessions that no running copy owns) is set aside — never deleted — and the move proceeds; and when BOTH folders hold real data the app asks **"Your previous Omniscio data was found"** with **Use my previous data and restart** (one-shot switch + relaunch) or **Keep this profile** (remembered, asked once). Includes the manual folder swap for an install that already shows an empty app, and why "Restore from backup" cannot fix that case. | [data-folder-recovery.md](data-folder-recovery.md) |
| Export / import all data (backup ZIP) | Manual full export/import at Settings → Backup & Restore. One click writes a ZIP of the whole DB (projects, sessions, full conversation history, quick replies, automations, recipes, RSS, webhooks, SMS, spam rules, Slack), settings/preferences, global recipes, and attachments — credentials/API keys never included. Import is a full replace: preview (created/version/platform/counts + warnings) → confirm → terminate sessions → automatic pre-import safety backup → replace in one transaction → restart. Newer-schema backups refused, older import with defaults, cross-platform path warning. Also a Settings-only JSON export/import (Settings Portability). Desktop only — unencrypted (use Setup Backup / Backup Mirror for encrypted/scheduled) | [data-transfer.md](data-transfer.md) |
| Reclaim disk space (shrink a large database) | Why `mission-control.db` grows to gigabytes (SQLite keeps deleted rows' space as reusable free pages) and how to shrink it: **Settings → Diagnostics → Reclaim disk space** clears the `session_turns_cache` and schedules a one-time in-place `VACUUM` for the next launch (you must restart — Omniscio won't relaunch itself; splash shows "Reclaiming disk space…"). Crash-safe; skips itself below ~1.2× free disk, takes a pre-compaction safety copy at ≥2.2× (deleted after 7 days), fails open if free space can't be measured. It also compacts the cold-storage archive (`mission-control-archive.db`) when that holds ≥1 GB of empty space, and does so once automatically after the archive's tool-output cleanup catches up (splash "Compacting the database…"; 17.5 GB → 7.5 GB in 14.8 min on a real archive copy). Delivered queued messages are purged after 7 days, but the space only returns to disk on Reclaim. Backups are non-blocking (async online-backup API) and compressed (zstd) before encryption, so they are smaller than the live file; only compaction shrinks the live file itself. Compaction never touches your conversations | [database-compaction.md](database-compaction.md) |
| Database Encryption (opt-in at-rest encryption of the live database) | **Available, off by default** (shipped 2026-07-25; appears as its own **Database Encryption** section in Settings). Opt-in encryption of the **live** local database at rest — `mission-control.db` + its cold-storage archive become ciphertext on disk, unreadable without your key. **Off by default**, so anyone who never enables it is unaffected. Built on an encryption-capable SQLite engine (a drop-in driver swap). A random data-encryption key (DEK) encrypts the DB; the DEK is stored **wrapped** — the transparent tier seals it with your **OS keychain** so the app unlocks automatically, and the zero-knowledge **passphrase** tier (built) wraps it behind a passphrase you set — prompted at launch before the DB opens, with set/change/remove from Settings as an instant re-wrap. A one-time **recovery code is mandatory** at enable (protects against a lost keychain / OS reinstall) and unlocks in both tiers. Encrypt/decrypt runs as a crash-safe migration at the next restart; the key never touches disk in plaintext or crosses to the UI, and turning it on/off is a human-only action agents can't invoke. Keywords: encrypt database, database encryption, at-rest encryption, encrypt mission-control.db, SQLCipher, recovery code, passphrase, zero-knowledge | [database-encryption.md](database-encryption.md) |
| Database upgrades & migrations (what happens to your data when you update Omniscio) | Your `mission-control.db` upgrades itself automatically the first time you launch a new Omniscio version — schema migrations run in order (a frozen numbered baseline through 260, plus newer individually-dated "ledger" steps tracked in an `applied_migrations` checklist) to bring the database up to what this build expects, and your data is preserved because migrations only ADD structure (tables/columns/indexes), never delete chats or settings. A complete pre-upgrade backup (`mission-control-vNNN.db`, 3 most recent kept) is written to `<userData>/backups/` before any migration runs. Forward-only: rolling back to an older build does NOT downgrade the schema — Omniscio logs a warning and boots anyway; restore a pre-upgrade backup if a feature misbehaves. Same behavior however the new version arrived (installed auto-update / portable re-download / reinstall). Distinct from disk-space compaction (structure, not size). | [database-migrations.md](database-migrations.md) |
| Decks — part 2 (per-card generation, layouts, publishing, export, the data model) | Part 2 of the Decks page: what each card is told when it is generated, how the topic colour and the 13-layout library work, publishing a deck to a web link, real images and generative art, presenter mode and speaker notes, PDF, HTML and PowerPoint export, and the data model, IPC surface and key files. | [decks-part-2.md](decks-part-2.md) |
| Decks (AI presentation builder) | A Gamma-style presentation builder built into Omniscio: type a prompt and Claude drafts an outline, then generates slide cards across ~10 hand-designed layouts (title / text / split / bullets / two-column / full-bleed image / icon-grid / timeline / comparison / quote), themeable (Clean / Midnight / Ember / Paper). Uses your existing Omniscio Claude login + cost tracking with a daily spend cap; renders in a native built-in virtual project beside the projects sidebar (NON-spawnable — no Claude session). A first-party built-in **plugin**, off by default — enable it in **Settings → Plugins** (adds `decks` to `enabledPlugins`); there is no Lab toggle or `AMC_SHOW_DECKS` env var (the old Lab toggle was retired and migrated to the plugin). | [decks.md](decks.md) |
| Deep Links | `omniscio://` URLs — open inbox, jump to project, start new session with prompt, link to a specific session, open a specific KMS note | [deep-links.md](deep-links.md) |
| DeepSeek balance forecast (run-out warning) | Warns you BEFORE your DeepSeek API account hits zero. Every 15 minutes Omniscio reads the account balance and measures the actual drain, then projects it forward; when it lands inside your warning window (default 24 hours) you get ONE inbox card with a one-click Recharge button, showing the balance, the hourly burn rate and what you have spent today. **On by default** — switch it off in Settings → Notifications → "DeepSeek balance forecast". Runs only when you have a DeepSeek API key saved. It fires on a **measured drain**, never on a balance that is merely low while nothing is spending, and it only ever READS the balance — it never spends, recharges, or resumes a session. A separate card appears if the balance cannot be read. | [deepseek-balance-forecast.md](deepseek-balance-forecast.md) |
| DeepSeek Harness provider (DeepSeek's own harness over ACP) | Spawn sessions on DeepSeek's **own** agent harness CLI (`dsh`) — **DISTINCT from the DeepSeek provider above**, which runs DeepSeek *models* inside the Claude Code harness; this one is DeepSeek's harness itself, with its own tools, skills and runtime modes. Opt-in via Settings → Accounts → "Allow DeepSeek Harness sessions" (off by default); needs the `dsh` CLI on PATH (the account card links to the install page) + a DeepSeek API key (the SAME `deepseekApiKey` slot — no second key). Kept-alive `dsh --profile acp` Agent Client Protocol child — a `persistent-external` engine with native multi-turn streaming; Omniscio injects `DEEPSEEK_API_KEY` because dsh advertises no ACP auth methods. 3 readiness gaps (`toggle-off`, `key-missing`, `binary-missing`). **Developer preview** (dsh 0.1.x). Per-session model + reasoning-effort pickers are wired — dsh takes both from the protocol session, so the choice is applied there at session start. v1 limits stated honestly: no images, no SSH, no crash-resume, permissions auto-approve, and cost reads "not reported" (the protocol's usage frame carries context-window occupancy, not billable tokens). A first start can exceed two minutes while the CLI resolves its plugin profile. | [deepseek-harness-provider.md](deepseek-harness-provider.md) |
| DeepSeek provider (Anthropic-compat API) | Spawn Claude-Code-style sessions backed by DeepSeek's Anthropic-compatible API alongside `claude`, `codex`, `gemini`, and `antigravity` — gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via Settings → Account DeepSeek API key + "Allow DeepSeek sessions" toggle — or no key at all, paying with Omniscio credits through DeepSeek's supply list (Settings → Accounts → Who pays & who serves), which also decides whether a reseller (DeepInfra, RunInfra, InferX) serves the model. **No binary check** — reuses the standard `claude` CLI; routing happens via spawn-env (`ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic` + `ANTHROPIC_AUTH_TOKEN=<vendor key>`); 2 readiness gaps (`toggle-off`, `key-missing`); identical tool-approval UX to Claude (no yolo mode) | [deepseek-provider.md](deepseek-provider.md) |
| Default Agent Instructions (presets injected into every session) | Curated instruction presets (no AI attribution, cloud safety, private repos, README standards) automatically injected into every spawned Claude Code session via `.claude/amc-instructions.md`; master toggle + per-preset on/off + custom instructions textarea; also manages `.claude/settings.json` attribution field; default ON | [default-agent-instructions.md](default-agent-instructions.md) |
| Default Claude Project (chat without software context) | Auto-created `~/Claude` project for general chats — equivalent of claude.ai, home base for Super Prompts | [default-claude-project.md](default-claude-project.md) |
| Delete a project | Remove a project from Omniscio (does NOT delete the folder on disk) — three-dot menu → Delete; soft-delete with Undo toast | [delete-a-project.md](delete-a-project.md) |
| Deploy Profiles (tell the AI which account to deploy a project under) | Named, reusable bundles of service→account mappings (Google/Firebase-gcloud, Vercel, Netlify, Render, AWS, or free-text Other) that tell an AI which cloud account to deploy a project under. Create/edit in Settings → Access & Sharing → Deploy Profiles; assign one per project via the Deploy Profile picker under Edit/Add Project → **More options** (hidden for virtual projects). On session spawn Omniscio injects a `## Deploy Profile` system-prompt block with per-service CLI hints (`firebase login:use`, `vercel --scope`, `export AWS_PROFILE`, …) via `--append-system-prompt`, so the agent verifies the right account before deploying. Stores only **non-secret identifiers** — never credentials/tokens — and is advisory guidance, not a hard account switch. Persisted in SQLite (migration v125: `deploy_profiles` + `deploy_profile_entries` + `projects.deploy_profile_id`, ON DELETE SET NULL); profile name is not unique (find-or-create); editing deletes-and-reinserts entries. Fully shipped (not Lab-gated). Assigning a profile routes over `PATCH /project/:id`; profile CRUD is desktop-only. | [deploy-profiles.md](deploy-profiles.md) |
| Detached session window (Pop Out) | Pop a single session out of the main window into its own floating BrowserWindow — useful on multi-monitor setups; main window shows an `ExternalLink` chip on the sidebar row + a placeholder in the panel area with **Bring window to front** / **Reattach here** buttons; per-session window-position memory (x/y/width/height) restored on next pop-out; sandboxed (`sandbox: true`, `contextIsolation: true`); stays open read-only after the session ends; no notification dedup. Always available — `Pop Out to Window` in the session's `⋯` overflow menu (desktop only, hidden inside detached windows and for terminal sessions) | [detached-session-window.md](detached-session-window.md) |
| Dev Pipeline Maintenance (auto-installed worktree-cleanup + merge-all-ready skills, run daily; also retires old BRANCHES) | Two housekeeping skills that ride with the Dev Pipeline, plus branch retirement — a provably-finished branch is deleted for you, and one that cannot be proven finished is left alone (the daily approval cards that used to ask about it are off by default; `AMC_ENABLE_STALE_BRANCH_RETIRE_ASK=1` brings them back): **worktree-cleanup** (reap git worktrees whose branch is provably merged into the integration branch — GitHub-optional, degrades to a local merged-ancestor check; never touches locked/dirty/active/unmerged worktrees or the main checkout) and **merge-all-ready** (land every local branch marked ready-to-merge onto the integration branch, one at a time, atomically and **local-only** — never pushes, never touches origin, never force-merges, and skips + reports anything it can't resolve safely). Both are bundled + installed into `~/.claude/skills` the moment you turn ON the Dev Pipeline (gated on `devPipelinePanelEnabled`) and removed when you turn it off. As **part of the Dev Pipeline** they also run **automatically once a day**: an in-process maintenance job finds repos that had dev-pipeline activity that day, participate in the pipeline, and actually hold a git repository, and spawns one background session per repo per day to run both skills — honoring the daily spend cap, with an off switch in the Dev Pipeline panel's Setup tab (`devPipelineDailyMaintenanceEnabled`, on by default). The daily run **quietly self-archives whenever nothing needs you** — a clean sweep archives itself even when it reaped worktrees and landed branches, and the only thing that reaches your inbox is a **Needs a look** item (a skipped branch, an unresolvable conflict, an errored step, a decision), reported back in a short scannable summary; every run stays readable in the Archive either way. By default it runs on a low-cost **Claude Sonnet** to keep it cheap, but right under the Setup-tab toggle you can **choose the engine, model, and thinking level** it uses — the picker offers the Claude-family engines, since the run uses the Claude Code housekeeping skills. The job can never re-trigger off its own runs BY CONSTRUCTION: maintenance sessions run the skills, not the pipeline, so they never record a dev-pipeline run — the only thing the daily activity signal reads. (The tag is provenance, not the guard.) | [dev-pipeline-maintenance.md](dev-pipeline-maintenance.md) |
| Dev Pipeline panel — part 2 (Auto-lander tab, QA Fleet tab, Setup tab, and the internals) | The second half of the Dev Pipeline panel page: the three remaining rail entries — the auto-lander with its live status, watch list and land history; the QA Fleet results, findings triage and coverage ranking; and the Setup tab with worktree cleanup, the testing-gate bypass, where checks run (the testing setting) and session-based cleanup — plus how the panel is put together for anyone working on the code. | [dev-pipeline-panel-part-2.md](dev-pipeline-panel-part-2.md) |
| Dev Pipeline panel (oversee runs + timing/monitoring + worktrees + auto-approve gates + auto-lander + worktree cleanup) | A built-in sidebar panel that oversees the dev-pipeline workflow in one place: the live pipeline runs happening now (which step each is on and whether it's waiting at a gate — with a live `waiting <time>` counter — click to jump to the session), a **Timing** run-monitor that shows where each recent run's time went split into working vs. waiting-on-you-at-a-gate vs. stuck (rate-limited/errored/blocked) — a summary strip (avg gate-wait, biggest stall) + a per-run split with durable history of finished runs (captured by Omniscio off the always-on status bus, not the AI; deterministic wait/stuck/total, best-effort phase labels), the git worktrees piled up per repo with a guarded one-click cleanup (open / jump / remove; Remove refuses in-use, uncommitted, or unlanded worktrees and never the main checkout), a per-gate auto-approval switch list (Plan · Red Team · Build · Elegance · Docs) plus a select-all master and the two standards-gate toggles (🚦 Check / 🔬 Audit, persisted separately) — by default Red Team / Build / Elegance / Docs auto-approve when an agent reports them done, while Plan + Ready-to-Merge wait for you, the auto-lander (on/off, which repos it watches, live status, and a persisted history of every branch it has landed or handed back on conflict), and a **worktree cleanup** dashboard (Windows-only, off by default) that surfaces + controls the scheduled disk-reclaiming cleanup — live status, run history, a verdict grid explaining why each worktree is kept or reaped, recover-a-reaped-worktree, and run-now — while the reaping stays in the battle-tested scripts, plus a **QA Fleet** tab carrying the QA runs' own results (open-findings count badge on the rail, totals + a 14-day open-findings trend, per-finding Resolve / Dismiss / Reopen triage with undo, a per-feature E2E PASS/FAIL list, and a least-recently-exercised ranking). Read-only oversight + a few controls; a NON-spawnable built-in virtual project. **Shipped** — visible to everyone, no Lab toggle needed (`devPipelinePanelEnabled` no longer gates the reveal). It is instead the Dev Pipeline's own opt-in, and it defaults **off**: turning it on is what arms the auto-lander, the worktree-mutation lockdown, daily maintenance and git-store maintenance — until then none of them run. | [dev-pipeline-panel.md](dev-pipeline-panel.md) |
| Dev Pipeline (bundled skill — end-to-end dev workflow) | Opt-in bundled Claude Code skill (off by default; toggle via Settings → Features → "Enable Dev Pipeline skill") that drives a full software-development task end to end — worktree, investigate, plan, red-team, 🚦 standards check, build, code-elegance pass, docs, 🔬 standards audit, git-prep — with five hard approval gates so you stay in control, plus two always-on auto-approving standards phases (eight phases in total). Installed to `~/.claude/skills/dev-pipeline/` on enable; removed on disable. | [dev-pipeline.md](dev-pipeline.md) |
| Developer Broadcasts (push an inbox card to users) | Admins push an inbox card to users' apps from Settings → Broadcasts (or programmatically via `publishBroadcast`) — targeted to everyone or a simple group (platform / tier / app-version range); cloud-delivered on each app's hourly poll, exactly-once via a local ledger, recallable (switch off → archives the card everywhere), behaves like any ordinary inbox card; admin-only (verified-claims gated), kill switch `AMC_DISABLE_BROADCASTS`; users can OPT OUT (`developerMessagesEnabled`, honored client + server) and a per-user daily delivery frequency cap limits over-messaging; can be SCHEDULED for a future go-live (`startsAt`, the inverse of `expiresAt` — client-gated delivery timing, not an embargo); surveys collect responses + a delivered→opened→responded funnel, with a CROSS-CAMPAIGN Analytics tab rolling that funnel up across all campaigns over a time window (read-only Firestore aggregation, admin-only); a recipient can REPLY in free text even when no survey was attached (the Reply button on any announcement card — a delivered broadcast, the welcome-video cards, the founding-team note — delivered over the existing feedback channel, carrying the sender's address so the team can write back, and suppressed on a card that already shows a survey so one card never offers two ways to answer); a card can also EMBED a full live web page (the `embed` content type — a Shares-hosted page rendered inline in an opaque-origin sandbox, made to look native: chromeless + auto-height + theme-matched; forms post to the page's own backend and/or back to Omniscio; gated by the `broadcast-embed` flag) | [developer-broadcasts.md](developer-broadcasts.md) |
| Developer guardrails (guard EVERY Claude session on the machine, not just Omniscio's) | Opt-in (default OFF), cross-platform, SHIPPED **machine-wide** sibling of Git guardrails: installs ONE master-safety hook into your GLOBAL `~/.claude/settings.json`, so EVERY Claude Code session on the machine is guarded — including ones Omniscio never spawned. Blocks the same ops as Git guardrails (commit/write while on `master`/`main`, push targeting a protected branch, destructive `git stash`, editing a file while the repo is on a protected branch) by **reusing the git-guardrails engine** — a co-versioned `git-guardrails.mjs` copy the deployed entrypoint imports as a sibling, with a baked-in rule config; the rule logic stays single-source and git-guardrails' own behavior is untouched. Turn it on in **Settings → Features → Developer guardrails (machine-wide)**. Git guardrails' ready-to-merge push gate is on here too: a feature-branch push needs the branch's current SHA-bound tag, or the owner's PR-push grant for that commit (`~/.claude/.push-approvals.json`). Shares the same time-boxed pause (`~/.claude/.master-approval.json`) + per-repo exclusion (`~/.claude/.master-block-exclusions.json`) escape files, so one pause/exclusion covers Git guardrails, Developer guardrails, and the hand-installed guards. Those escape files are themselves write-protected against agents (see Git guardrails above). The manager deploys the Node bundle + injects one `node` PreToolUse hook, **self-tests before wiring** (benign → allow AND `--selftest` → block, so a broken engine import can never silently disable it), self-heals on a ~15-min tick, migrates a prior Windows-only PowerShell box cleanly, and reverts cleanly when off. Fail-open. Contract: developer-guardrails-contract. | [developer-guardrails.md](developer-guardrails.md) |
| Developer Tools group (sidebar) | Collapsible sidebar group nesting Dev Pipeline, Job Monitor, and Running Apps + a "New Terminal" launcher row that opens a terminal in the active project; ships collapsed by default; render-only nesting, members keep their own toggles | [developer-tools-group.md](developer-tools-group.md) |
| Devin (Cognition) provider (remote REST-poll sessions) | Run Cognition's Devin cloud coding agent as a **first-class, SHIPPED** session provider alongside `claude`, `codex`, and `grok` — gated behind master "Show alternative AI providers" (off by default), then opt-in via Settings → Account Devin API key (`apk_`) + "Allow Devin sessions" toggle. **No binary** — remote v1 REST API driven by POLLING (no local child, no webhooks); billed in ACUs on your own Devin account (a hard per-session ACU cap is always sent on create); **cost not reported** (`costReporting:'none'` — the session shape carries no per-turn ACU figure); `restartResumable:false` (no re-attach after an app restart); first message budgeted to 29,000 chars (Devin 400s at 30k). Shipped 2026-08-25 (was gated behind the `devin-provider` unreleased feature). | [devin-provider.md](devin-provider.md) |
| Review changes (diff viewer) | Built-in git diff review for a project's changed files - a desktop surface (in the File Explorer) and a separate touch-native phone screen. A Changes panel lists changed files (folder tree, Project/Session toggle, status filter, sort, commit picker, live auto-refresh, and a per-repo commit box — AI ✨Generate a Conventional Commits message, then Commit / Commit & Push, never prompting) and the Diff viewer renders the diff with accept/reject per hunk AND per file (file-reject discards — confirms), unified/split view, in-diff find (F/Ctrl+F), git blame (B), inline annotations, whitespace toggle (W), font size, minimap, and J/K/Y/X/V/O keyboard review. Built on Monaco (VSCode's editor engine); binary / over-1 MB files show a "can't show inline" placeholder. On a phone, the session menu's **View Diffs** opens a separate Monaco-free screen: changed-file list (per-repo sections), the diff as tappable +/- blocks with thumb-sized Keep/Revert per block (re-fetching after each so positional indexes cannot go stale), file-level keep/discard, a commit box per repo with a confirm before Commit & Push, a type-to-confirm Discard ALL, and pull-to-refresh - no split view, in-diff search, blame, annotations or minimap. Off by default (Settings > Lab); reaches git WRITE channels over the phone bridge by an explicit 2026-09-08 owner decision | [diff-viewer.md](diff-viewer.md) |
| Import a Discord server into Team Chat | A step-by-step wizard that copies a Discord server’s channel history into Team Chat: paste a bot token, pick which channels to bring over, match Discord people to your workspace members, then watch it run with live progress. In development, behind the `discord-import` flag. | [discord-import-wizard.md](discord-import-wizard.md) |
| Distribute Sessions Across Accounts (load balancing) | On by default (Settings → Accounts, needs 2+ login accounts) — spreads new sessions across login accounts by available capacity, with a bounded preference for an account whose usage window resets soon — weighted most toward the weekly (7-day) window (harvest about-to-expire capacity before it's forfeited), instead of piling onto one; each session keeps its own account; a cap re-spreads only that account's sessions. When on, the toolbar account pill shows a balance-scale icon + count of accounts currently in use + a pool-health glyph (green/amber/red) that replaces the misleading single-account %, and dropdown rows get a per-account "N live" chip. On by default (existing users flipped on once by a one-time migration); byte-identical to old behavior when off. | [distribute-sessions-across-accounts.md](distribute-sessions-across-accounts.md) |
| Doc Token Alerts (agent-instructions size watchdog) | Amber inbox card fires when a project's always-loaded agent docs (root `CLAUDE.md` + `AGENTS.md` + `.claude/memory/MEMORY.md`) cross a threshold (default 40,000 tokens). `bytes/4` estimate via `lstatSync` only (no file-content reads), debounced 60s scan on session-turn-ended + startup fan-out across spawnable projects. Per-project threshold overrides on top of a global default (the `'global'` rule cannot be deleted). Archiving the card acknowledges at the current size, with a tiered re-alert (default +50% growth or 30 days); snooze routes through the universal `isInboxItemSnoozed` gate. Settings → Notifications → Doc Alerts | [doc-token-alert.md](doc-token-alert.md) |
| Drip — part 2 (the internals, and the inbox side of a released item) | The second half of the Drip page: the five tables and the services a drip is built from, the book extractor and the integration registration, the full CLI surface with its approval gating and session provenance — and what the inbox does with a released item, from previews and queue thumbnails to right-click actions and the in-place text editor. | [drip-part-2.md](drip-part-2.md) |
| Drip (queue-and-trickle inbox feeder) | Stash mixed content (text, links, files, watched folders) into named queues that release into your inbox on a user-chosen cadence; per-drip itemsPerRelease + skip-next-on-snooze; folder scanner walks watched dirs and queues new files; auto-archives when the queue drains | [drip.md](drip.md) |
| Drive Omniscio (watch & steer an AI operating Omniscio's UI — dev/QA tool) | A developer tool that boots a VISIBLE, isolated sandbox Omniscio and points a Claude session at it to operate the real UI toward a goal you type — clicking, navigating, toggling, exercising features — narrating each step in its chat so you watch beside the app and steer via the composer (the cockpit is just the popped-out driving session window next to the headed sandbox window). Sandbox-only and fails closed (the driver attaches only to the sandbox CDP endpoint and refuses unless instanceId=claude-sandbox, so it physically can't touch your real install); free navigation/settings by default, spawning a real sandbox session is a separate per-run cost-gated opt-in. Invoked explicitly as `/drive-amc <goal>`; a dev/QA tool, never a shipped end-user feature. | [drive-amc-cockpit.md](drive-amc-cockpit.md) |
| Google Drive integration (agent-driven) | Claude gets 7 Drive tool-use calls (list, get, create_folder, delete, move, share, quota) inside any chat — no Drive UI in Omniscio; same single "Connect Google" OAuth as Calendar/Sheets/Gmail | [drive-integration.md](drive-integration.md) |
| Dropbox integration (file browser and management) | Sidebar file browser for Dropbox — browse, upload, download, search, rename, copy link, delete; OAuth2+PKCE auth via Dropbox REST API v2 (no SDK); channel-adapter pattern with virtual project sentinel `__dropbox__` | [dropbox-integration.md](dropbox-integration.md) |
| Edit a project | Rename, recolor, change icon, pin / unpin, move to a different sidebar group, move its folder to a new location (relocate, or merge into an existing project), toggle the branch header — three-dot menu on the project row | [edit-a-project.md](edit-a-project.md) |
| Edit a user message | No in-place edit, but you can **edit & re-run from here** — fork a NEW session from that message that SHOWS the chat up to it (cloned in, so it reads as the same conversation); the original is untouched. Same-session alternatives short of forking: Esc + corrective follow-up, plain follow-up, `/clear`, new session, or archive | [edit-a-user-message.md](edit-a-user-message.md) |
| Eligible phrases (browse & save every phrase you repeat) | A tab in the Quick Replies sidebar listing EVERY phrase you repeat (a lower floor of 3, broader than the nudge), most-repeated first (cap 100), each with Save (opens the add-form prefilled) + Dismiss (hides it + stops future nudges). Reuses the repeated-phrase nudge's raw-text scanner + `quick_reply_nudges` ledger; excludes phrases already saved; labels each New / Already suggested / Dismissed. Local, no-AI, always available; fetched on tab-open + manual Refresh. The browse-all companion to the one-at-a-time nudge. | [eligible-phrases.md](eligible-phrases.md) |
| Email Cleanup | AI-guided inbox-cleanup walkthrough that first works out **who matters to you** — your bank, colleagues on your own domain, people you reply to, mined known-contacts, and an editable keep-list — and **never** recommends removing them (no more "unsubscribe from your bank"). For the rest it judges each sender from real behavior — Gmail category, read-rate, and how you **dispose** of the mail (deleting drives removal; opening alone never does) — recommends an action per group with a reason (a low-confidence group shows its real recommendation, e.g. "Review N", never a false whole-group "keep"), offers one-tap batch cleanup on the confident subset (always confirmed) + a chat box. Protected senders show a "kept because" shield; self-sent + automated mail gets its own lane; a **Protected Senders** panel + verdict CLI routes manage the keep-list. Classic flat sender-list behind a rollback flag; same safe execution engine (mass archive, safe unsubscribe, auto-archive filters). The standalone sidebar panel is RETIRED — reach it via the in-Gmail ✨ Clean Up button or the Inbox Concierge mission (Missions hub, missions-hub.md). A **read-only** CLI analysis route (`GET /gmail/cleanup/analysis`) returns the recommendations but never executes an action. Keywords: email cleanup, who matters, protected senders, unsubscribe, declutter inbox, whole inbox, AI walkthrough, categorize senders, delete rate, self-sent, automation lane, chat, archive, CLI analysis. | [email-cleanup.md](email-cleanup.md) |
| Email inbound prescreen (editable prompt, now holds every route's flagged mail) | Built-in Gemini/Haiku classifier screens every inbound email for prompt injection and exfil before an agent sees it — on the Email Inbound / AgentMail path, the agent's own hosted address, and the Gmail bug-report inbox alike. A flagged or unreadable email is held for owner review, never bounced; the user edits the entire classifier prompt in Settings → Email Inbound (default CORE pre-filled, 16000-char cap, JSON contract always enforced) | [email-inbound-prescreen.md](email-inbound-prescreen.md) |
| Email Summarizer (forwarded mail + Gmail labels) | Two source paths under one feature: (1) forward emails to an AgentMail inbox — Haiku summarizes and (optionally) replies on-thread, with per-newsletter From/Subject/List-ID rules + backtest panel + 3-step setup wizard; (2) tag any Gmail thread with a label — a 5-min watcher polls, summarizes, emails the summary back to your own Gmail address, and removes the source label; shared daily cost cap (default $1.00) covers both flows; rules table is unified (Gmail rule = non-empty `gmailLabelId`); idempotent + self-loop-safe per-thread processing with partial-UNIQUE-backed dedup and amber "N failed today" badge on rules with NULL-summary rows | [email-summarizer.md](email-summarizer.md) |
| Embedded Browser | Sidebar virtual project (sky-blue Globe icon, between Automations and CLI Tools) opens a full-pane Electron `<webview>` with back / forward / reload / home / URL bar — persistent cookies + localStorage under the `persist:browser` partition so logged-in sessions survive restarts; an engine-pinned Chrome User-Agent + aligned `Sec-CH-UA` Client-Hints (and, for Google docs linked from email, a "Continue in your browser" fallback) mitigate Google's embedded-webview detection; v1 has no tabs, no bookmarks, no DevTools, no downloads | [embedded-browser.md](embedded-browser.md) |
| Empty-inbox discovery tip (one-time "you can archive to clear your inbox" card) | A one-time Inbox card that tells a user their inbox can be cleared by **archiving** the items they're done with — shown at most once, ever, the first time the VISIBLE Inbox has piled up (~15+ attention items, the same count the app badge shows) AND the user has never archived anything (`countArchivedSessions() === 0` is the archive-usage signal — no new counter or migration; the moment they archive anything it can never fire again). Fires once at startup from the `STARTUP_TASKS` registry via `maybeSurfaceEmptyInboxTip`, gated in order by the `AMC_DISABLE_EMPTY_INBOX_TIP` env kill switch → Tips & Guidance → the one-shot `emptyInboxTipSeen` setting → the visible attention count (`countSessionsByStatus(..., {excludeHiddenTags:true})`, so "N items" matches what the user sees) reaching `EMPTY_INBOX_TIP_MIN_ATTENTION` (15) → zero-archived. The card is COPY-ONLY: it carries no primary-action button, because its copy names no manual step to take. It explains the archive gesture and closes with "This tip appears only once." Both are pinned by `tests/unit/services/empty-inbox-tip-alert.test.ts`. The dedupKey is the idempotency backstop and any error is swallowed so it can't break startup. No dedicated toggle (a self-limiting one-time card); suppress via Tips & Guidance off. Contract: empty-inbox-tip-contract. | [empty-inbox-tip.md](empty-inbox-tip.md) |
| Bake-Off (one prompt across many projects × harness setups) | Launch one prompt as many sessions at once — the cross-product of a **Projects** multi-select and a list of **Harness & model setups** (each the SAME Harness · Provider · Model · Thinking · MCP · Local/Cloud bar as a new session, reused as ONE shared module — session mode there, value mode here). One session per (project × setup) pair, with a live "p × s = k sessions" count. **Shipped — visible to everyone** in the **Prompt Tools** sidebar group (the `fanout` feature is `status: 'shipped'`, so the old `fanoutEnabled` Lab toggle no longer gates it); also opened via a "Bake-Off…" command-palette action. Capped at 20/launch (over-cap disables Launch; >10 confirms); each spawn is background + paced by the cli-spawn pacer (a controlled burst, never an un-throttled storm); bad targets are skipped-with-a-reason and never abort the batch; per-setup MCP is stamped BEFORE the first spawn. Also a first-party (**builtin-only**) plugin capability `session.fanout` behind the new `sessions.launchAny` permission (a marketplace/dev plugin declaring it is refused), and a `POST /fanout` CLI route mirroring the spawn route's deny-by-default auth; blocked from the phone bridge. Contract: fanout-launch-contract. | [fanout.md](fanout.md) |
| Fathom (meeting transcripts via MCP) | Built-in stdio MCP server wrapping the Fathom.ai REST API — gives sessions five tools to list/search meetings, read speaker-labeled transcripts, and view AI summaries; API-key auth encrypted at rest, credential-safety clamped for Search/Ask/KMS sessions | [fathom-mcp.md](fathom-mcp.md) |
| Feature Discovery Nudges (daily "try this feature" inbox card) | A roughly-daily inbox card pitching one Omniscio feature you have never used, with a spotlight popup (hand-written pitch + animation + a one-click "Start using it" that turns the feature on and takes you straight to it, OR — for on-by-default features like the desktop icon badge — a live on/off switch right in the card via the `toggleSettingKey` start-action); rotates through unused curated features, releases at most one per ~24h, auto-stops once you've seen them all, each card dismissible + snoozeable. Reads the existing `feature_events` usage signal (no new tracking); backed by its OWN `feature_nudge_releases` table + a standalone inbox source (NOT the shared alert/Drip table); groups under a "DISCOVER" header. Off by default — opt-in via the Settings → Lab toggle (in-development behind the `feature-discovery-nudge` gate). Complementary to (not a duplicate of) the weekly LLM-written Weekly-Summary feature-discovery suggestions — this is the daily, deterministic, hand-curated, free surface with a richer popup + one-click enable. | [feature-discovery-nudges.md](feature-discovery-nudges.md) |
| Feature Recommendations (which released feature fits a goal) | GENERATED goal-to-feature map built from the Feature Roadmap by `npm run features:recommendation-index` and rebuilt rather than hand-edited: 19 plain-English "Want to:" goals (run more agents at once, know what needs me, spend less on AI, never lose work, work from my phone, go hands-free, ship code safely, give my agents memory, get started...) each listing the RELEASED features that serve it with a one-line pitch and a power-user/integration/notification tag. Deliberately lists released features ONLY, so an assistant answering "what should I use for X?" can never recommend something unreleased; pairs with feature-suite-recommendations.md, which groups features into themed suites instead of by goal. | [feature-recommendations.md](feature-recommendations.md) |
| Feature Suite Recommendations (which features work well together) | Cross-cutting reference for the AIPM and AI Coaching: 10 themed feature suites (Organizer, Automator, Deep Work, Learner, Team Player, Orchestrator, Briefer, PM Power, Developer, Communicator), trigger signals mapping user behaviors to suite recommendations, cross-suite synergies, 6 recommended bundles (New User, Solo Power User, Team Lead, Developer, Executive, Automation Builder), and a coaching-context table mapping work/life complaints to concrete features | [feature-suite-recommendations.md](feature-suite-recommendations.md) |
| Feedback channel opt-out (silence outbound email per install) | Two user-level toggles at Settings → Diagnostics — `bugReportEmailEnabled` gates both legs (Resend email and Firestore) of the shared report-delivery chain (toolbar bug icon, overlay report, QW-miss report, CLI `POST /feedback`); `telemetryEmailEnabled` gates the entirety of `sendTelemetryEmail()` (crash alerts + weekly digest). Both default `true` so every install (CEO inclusive) keeps emailing as before; only an explicit `false` from the user's flipped toggle silences this install. The on-disk fallback and the Sentry path are untouched. No migration writes to anyone else's config | [feedback-channel-opt-out.md](feedback-channel-opt-out.md) |
| Convert files between formats (on-device, agent-callable) | On-device file-format conversion any Omniscio agent can call — PDF→Markdown, DOCX→PDF, images (PNG/JPEG/WebP/GIF/TIFF/SVG/AVIF, HEIC→JPEG/PNG) + image→PDF, audio/video (MP4→MP3, video↔GIF, video frame-grab, MKV/AVI, FLAC/Ogg/Opus/AAC/AIFF), data (CSV↔JSON↔YAML, CSV→table), spreadsheets (Excel xlsx↔csv/json, xlsx→md/html), subtitles (SRT↔VTT). Agent-first via `POST /convert` plus a spawn-prompt shim that teaches every spawned session it can convert files; writes a NEW file next to the original (never overwrites — suffixes on a clash), runs locally at **$0** with no AI tokens, bounded by input-size + timeout caps. Documents/images/subtitles work out of the box (HEIC via a bundled WASM codec); audio/video need system ffmpeg (humanized "install from Settings → Toolchain" when absent). A one-click **PDF→Markdown** UI exists in project docs (right-click → keep-both/replace) + chat attachments, plus a full user-facing **File Converter** tool (in development, gated `fileConverterEnabled`, toggle in Settings → Features) opened from the toolbar to drag/pick a file and convert to any supported format (desktop writes next to the original + **Open** the result in-app or in the OS default app & **Show in folder**, allow-list-gated; mobile downloads). The File Converter also has a desktop-only **Download from web** mode — a SEPARATE opt-in, off by default (`webMediaDownloadEnabled`, Settings → Features), so enabling the converter is conversion-only until you turn the downloader on too — paste a URL (YouTube/Vimeo/direct link) and `yt-dlp` saves it to Downloads as Video (MP4) / Audio (MP3) / Best (needs yt-dlp + ffmpeg from Settings → Toolchain). Per-conversion **quality/size options** (image quality/resize, audio bitrate, video resolution — a `/convert` `options` field, or the UI's Options panel) and desktop **batch** convert (drop many files → one target → convert all) are supported. A high-fidelity on-device reader also converts Word (`.docx`/`.doc`), PowerPoint (`.pptx`/`.ppt`), OpenDocument (`.odt`/`.ods`/`.odp`), EPUB, RTF, and legacy Excel (`.xls`) **to Markdown** with clean GFM tables — `docx→md`/`pdf→md` route through it and fall back to the built-in extractor so nothing regresses. Conversion takes a local file (no URL inputs); PDF tables flatten and a scanned/image-only PDF needs OCR (not done on-device). | [file-conversion.md](file-conversion.md) |
| File Explorer (browse a project's files) | Collapsible desktop-only sidebar pane to browse a project's folder on disk — a **Files** tab with an expandable file tree (click to open in the Peek Viewer; right-click for Open / Show in folder / Copy path / Delete-with-confirm) plus a **Changes** tab (the diff viewer). Gated `hidden md:flex`; no CLI control route — browsing files is an in-app, desktop-only action | [file-explorer.md](file-explorer.md) |
| Publishing the websites (how the docs site, homepage and apps reach production) | The seven public websites Omniscio serves, what publishes each one, and how every push publishes them from the developer's own computer — the only path now, since GitHub no longer runs those jobs and the hosting workflow that did was removed. | [firebase-hosting-from-this-box.md](firebase-hosting-from-this-box.md) |
| First Mission (guided onboarding experience) | Coached computer health-check that launches automatically after setup (first run only) — four card beats: kickoff → scan → reveal findings → approve plan → done with undo; read-only scan, explicit consent before any change; replay via the project empty-state "Run a guided mission" button; ships on Windows and macOS | [first-mission.md](first-mission.md) |
| First-time setup | Two-phase onboarding wizard from fresh install to first working session — Welcome / Account / optional API Key / Setup tool-check / Transition, then Theme / Project; auto-creates the `~/Claude` project and the Omniscio sidebar group. Also covers the **starter agents** pre-spawned at the end of setup on a company-funded lane and the two caps that stop them ($0.50 per starter session, $1.00 per person), plus how to switch the pre-spawn off | [first-time-setup.md](first-time-setup.md) |
| Flashcards (plugin) | Spaced-repetition flashcards plugin: pack CRUD, review sessions (four-grade FSRS + onboarding two-pile), Anki .apkg import, per-card image attachments, per-card + per-pack Claude session spawn, and a dashboard tile with retention + streak + forgetting-curve forecast. First-party builtin-source plugin under `src/plugins/flashcards/`; core services (FSRS scheduler, .apkg importer, media store, task-system integration, migrations, CLI routes at `/flashcards/*`) stay in main. Plugin install + enable is the user-facing gate. | [flashcards.md](flashcards.md) |
| Flowcharts (visual flowchart editor, in development) | In-development standalone visual flowchart editor (gated via the `flowchart` unreleased-feature, `flowchartEnabled` / `AMC_SHOW_FLOWCHART=1` / Settings → Lab toggle), surfaced as an Omniscio built-in virtual project labeled "Flowcharts" that docks in the main panel beside the projects sidebar — mounted like Decks (`panelOwnsLayout` + `mobilePrefersPanel`, so it also works on a phone). Draw boxes + connectors on a React Flow canvas, drop shapes from a palette, organise them into swimlanes, keep a saved library, and export Mermaid (one-way). The editor's own Charts/Sessions tabs live inside the panel; the **Sessions** tab spawns AI sessions into the same `__flowchart__` project (resolver-mapped to `<userData>/flowchart-agent`) that can read + draw on the open board. A **Build with AI** entry (Charts empty-state + header) turns a one-line description into a whole chart — it starts a regular AI session (you pick the model) that builds the graph via the CLI, and Omniscio auto-arranges the result. Stored as one graph blob (`{ nodes, edges, lanes }`) per row in the soft-deleted `flowcharts` table. | [flowchart.md](flowchart.md) |
| FlowVoice (OS-wide dictation + history) | OS-wide dictation: hold a global hotkey, speak, release, and the cleaned transcript is typed at the OS cursor in whatever app is focused (not just Omniscio's composer). Self-contained FlowVoice port under `flowvoice/` with its own `flowvoice:*` IPC + JSON settings/history stores; streaming-only via the FlowVoice `/stream` WebSocket; clipboard-paste injection. Two hotkey slots (Hold to talk, default Ctrl/Cmd+Shift+D, + Toggle, unbound by default); floating HUD pill + session-composer mic button; history lives inline in the settings card (the sidebar tile was retired); configured at Settings &rarr; Voice Control &rarr; Dictation (FlowVoice), or in place by right-clicking the composer mic button (the same card opens in a dialog over the session). | [flowvoice.md](flowvoice.md) |
| Focus mode | Toolbar bell pill batches inbox alerts so notifications fire on a count/time threshold instead of per-item; per-project rules (with a 'global' default), AND/OR operator, hard-kill switch, session whitelist, pierce-state passthrough; right-click pill / chevron / long-press opens header popover with master toggle + hard-kill + rule editor without leaving the dashboard; legacy F-key sidebar filter still toggles a view-only sidebar collapse | [focus-mode.md](focus-mode.md) |
| Forms (plugin — build a form, publish a public link, collect responses) | Free marketplace plugin: build forms, publish them as public links, collect responses, and optionally auto-send a new response to an agent session through a capped, armed-by-you rule. Adds a Forms sidebar row. | [forms.md](forms.md) |
| forward_email transport (Gmail default, AgentMail opt) | `forward_email` action supports `transport: 'gmail'` (default) or `'agentmail'`; pre-flight gates, failure notif text, v1 limitations | [forward-email-transport.md](forward-email-transport.md) |
| Foundry marketplace-only + how plugins update | Foundry (the PRD-authoring plugin, id `prdstack`) is no longer baked into Omniscio — it's a pure Marketplace plugin, so a fresh install downloads the latest published version at install time. Installed plugins are never WIDENED silently: an update that asks for nothing new is applied in the background, and one that wants access you have not approved stops and waits for your click in the Updates window (which shows the newly-requested permissions). Existing built-in Foundry users are migrated automatically on the first boot of the new Omniscio version, with their in-progress PRDs (stored in `%APPDATA%`) intact and no reinstall needed. Fail-safe throughout: network/registry/download/checksum failures never block startup and never remove a working copy, and a failed migration simply retries next boot (its `*BuiltinMigrated` flag stays unset). Mechanism: the loader's `BUILTIN_EXCLUDE = new Set(['prdstack','reading-queue','repoguard','writer'])` bars the built-in (a Marketplace copy always wins; no packaging change needed) and the `plugin-update-service` StartupTask runs `runBuiltinMigrations` ONCE at boot, while the unattended update pass it also hosts rides the renderer's existing check cadence (no recurring backend timer). Prerequisite: Foundry must stay published on the Marketplace (v1.2.1+) for the auto-migration to succeed. | [foundry-marketplace-only-autoupdate.md](foundry-marketplace-only-autoupdate.md) |
| Fresh-install starting point (a new install skips the migration ladder) | A brand-new install copies a committed, generated database image into place instead of replaying ~1,170 migrations (~9.2s once per user). The image is built from the real ladder by `npm run db:build-fresh-start`; it is used only while its own ledger proves it is a prefix of the shipped migrations, holds the seeded rows as well as the schema, and declines itself — running the ordinary ladder — the moment it cannot. | [fresh-install-starting-point.md](fresh-install-starting-point.md) |
| Frozen-panel retention (instant switch-back to recent sessions) | Keep recently-viewed, non-streaming session panels fully built in memory (the Chrome-tab model) so switching back is instant — no shell&rarr;heavy rebuild. Off by default; **Settings &rarr; Sessions &rarr; "Keep recent sessions instant"**. Bounded LRU (the last 12 of up to 32 viewed ids), runtime-only / not persisted, additive to and disjoint from the keep-alive pool. Two gates — the setting plus env kill switch `AMC_DISABLE_FROZEN_PANELS=1` (kill switch wins); OFF is byte-for-byte the pre-feature renderer. | [frozen-panel-retention.md](frozen-panel-retention.md) |
| Gauntlet Loop (build, blind-judge, repeat until a builder passes) | A developer-tools sidebar panel that runs Matt Shumer's "gauntlet loop": several **builder** agents each write an attempt at a goal, fresh **blind critic** agents score every attempt (0-100) against a concrete bar, and it loops round after round until a builder clears your pass score or the run hits its round ceiling or **cost cap**. v1 handles TEXT goals (a written artifact); a new-run form (goal + builders/critics/rounds/pass-score/cost-cap, `Ctrl+Enter` to run), a history list of past runs (status · goal · cost · rounds), and a per-run detail (each round's builder attempts + critic scores + the winning artifact). A capped run **pauses** at its cost ceiling with an "Add budget & resume". **Desktop-only** (it spawns multiple paid agents) and **non-spawnable** built-in virtual project under the Developer Tools group. In-development — reveal via Settings → Lab (`gauntletLoopEnabled`) or `AMC_SHOW_GAUNTLET_LOOP=1`. | [gauntlet-loop.md](gauntlet-loop.md) |
| Gemini provider (CLI-backed sessions) | Spawn Claude-Code-style sessions backed by Google's Gemini CLI alongside `claude` and `codex` — gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via Settings → Account Gemini API key + Gemini CLI binary + "Allow Gemini sessions" toggle; kept-alive `gemini --acp` (Agent Client Protocol) harness — a `persistent-external` engine with native multi-turn — and `--yolo` auto-approve; per-launch ChangeProviderButton + per-project default; violet "Gemini" pill in the session header | [gemini-provider.md](gemini-provider.md) |
| Git guardrails (stop agents committing/pushing to master) | On by default — a shipped safety feature (turn it off, switch it to warn-only, or edit the protected-branch list in Settings → Features → Git guardrails or the Dev Pipeline panel's Setup tab; `AMC_SHOW_GIT_GUARDRAILS=1` force-reveals) that stops the AI sessions Omniscio spawns from doing dangerous git ops: committing/writing while on a protected branch (`master`/`main`), pushing to a protected branch from any branch, destructive `git stash` (push/pop/drop/clear/apply — reads allowed), and editing a file while the repo is on a protected branch; an opt-in extra "ready-to-merge gate" (default off) also refuses a feature-branch push unless the branch carries a current SHA-bound ready-to-merge tag matching HEAD. Reads, moving *onto* a protected branch, `git fetch`, and creating a branch stay allowed. **A bare `git worktree add` is refused** (2026-08-31): a hand-rolled worktree stays invisible to the Worktree Ledger until a background sweep adopts it, and that sweep can never recover who was working or why — so creation goes through `POST /worktrees/create`, which registers it with the calling session as owner. Escape hatch `AMC_ALLOW_RAW_WORKTREE_ADD=1` keeps the raw command working for repos the create API cannot serve (it only knows repos registered as projects). Two levels: **required** (hard-block, default) or **advisory** (warn-only); protected branch names are configurable. Enforcement is a Claude Code **PreToolUse hook** (`resources/git-guardrails/git-guardrails.mjs`) that fires even in bypassPermissions/autonomous mode (where an Omniscio permission card would be auto-approved), auto-wired per session via a private `--settings` file + the `AMC_GIT_GUARDRAILS` env — never by writing into your repo; it keys directly on the `gitGuardrailsEnabled` setting (decoupled from the old hidden-feature gate), so the Settings off-switch actually disables it. Fail-open (never wedges a session). A **human-only** in-app override UI (Settings → Features / the Dev Pipeline panel) drives a time-boxed **pause** (live countdown) and a per-repo **exclusion** list, writing the same `~/.claude/.master-approval.json` window + `~/.claude/.master-block-exclusions.json` list the hook reads; because pausing or excluding LOWERS the guardrail, those actions have no CLI route and are blocked from the mobile/web bridge, so an AI agent can never switch off its own guardrail. **The override FILES are guarded too (2026-08-25)** — an agent tool call that writes either file, or the deployed guard bundle, is refused through both the edit tools and the shell, and refused even while a window is open, so one approval can never authorize the next; only app-issued markers are honoured, and a hand-shaped window is refused outright rather than shortened to fit. Until then the CHANNELS were locked but the FILES were not, and a blocked agent could write its own approval window and retry (`~/.claude` is not a git repo, so the protected-branch check never applied there). A window may also be SCOPED to a single agent session, leaving every other agent blocked for its whole life. A safety RAIL, not a sandbox (deliberate obfuscation can evade a shell-command checker); solo-first (per-user setting; team policy is a follow-up). | [git-guardrails.md](git-guardrails.md) |
| Git history missing (store-loss alert — the app pauses its own git writes) | A watch reads every managed project's .git every 30 seconds; when the history is deleted, emptied or re-initialised (master gone, its packs gone, or the worktrees pointing at it no longer known to it), one data-safety inbox alert appears within a minute and the app's own writers stand still — the auto-lander, worktree cleanup and retire paths, and worktree creation (which answers store-lost). The alert's button starts a recovery session, which restores the history from a background copy the app keeps on a different drive; writers resume by themselves after three healthy checks. Always on; incident kill switch AMC_DISABLE_GIT_STORE_LOSS_GUARD. | [git-history-missing.md](git-history-missing.md) |
| Compact git storage (reclaim disk + speed git back up, on any repo) | Settings → Diagnostics → **Git storage** lists every git repository Omniscio knows about with its real size on disk, pack-file count, and loose-object count, and compacts the ones you pick — routinely reclaiming several GB and making every git command faster on a bloated store. Because a full compaction cannot run while anything else uses the repository (and Omniscio itself runs git constantly for sessions, worktrees, and branch tracking), it runs during Omniscio's own **startup** — before the window opens and before any session resumes, the one moment with no git activity of its own. That is why it needs a restart, and why it never has to kill anyone's processes. Two paths: **Compact on next restart** (nothing happens now) or **Restart & compact now** (behind a confirm naming the real cost). Takes 5–30 min with live progress on the startup screen; sessions suspend and resume; a compaction you schedule also deletes git data nothing has used for two weeks (newer unused data is set aside for a later run), never anything a branch, history or worktree still uses; force-quitting mid-run is safe because git only swaps the new data in at the very end. Refuses with a plain reason — and changes nothing — for a moved/deleted folder, a non-repo, a *linked worktree* (compacting it would act on the parent repo), or a drive without ~1.5× the repo size plus 1 GB free. Complements rather than replaces the automatic background repacking, which deliberately backs off under load and so can go days without a turn on a busy machine. Agents: schedule via the `repackReposOnNextStartup` setting, read results from `lastGitRepackResults`. Contract: git-store-maintenance-contract § Manual compaction (R1–R7). | [git-storage-compaction.md](git-storage-compaction.md) |
| Code Search (GitHub) | **Removed from Omniscio core (in-core GitHub detachment) — plugin-only now.** Formerly: search code across your GitHub repos from the "Code Search" sidebar tab: explicit-submit search (10 req/min API budget), scope picker (mine / org / repo), results open in the built-in file viewer at the exact indexed snapshot, scrolled to the matched line; honest default-branch-only + rate-limit copy | [github-code-search.md](github-code-search.md) |
| New Issue button (create a GitHub issue from Omniscio) | **Removed from Omniscio core (in-core GitHub detachment) — plugin-only now.** Formerly the "+ New issue" button on the GitHub Issues tab: pick a repo (recent-first), enter a title, prefill the body from the repo's issue template, optionally set labels/assignees, then create — the new issue opened in the tab immediately. Shells out to `gh` like its parent tab; `gh:issue-create-meta` + `gh:issue-create` IPC; registered shipped in the unreleased-feature registry (id `github-issue-create`) | [github-issue-create.md](github-issue-create.md) |
| GitHub Issues (cross-repo GitHub issue manager) | **Removed from Omniscio core (in-core GitHub detachment) — plugin-only now.** Formerly a sidebar tab that listed the open GitHub issues you are involved in across every repo your account can access — filter chips for All / Created / Assigned, open an issue to read its Markdown body and comment thread, then add a comment or close / reopen it (close is confirmation-gated, reopen is one click) without leaving Omniscio. The list is open-only and excludes pull requests. Shells out to the `gh` CLI (one-click Connect GitHub if `gh` is missing); virtual project `__github_issues__`, all data over `gh:issue-*` IPC, registered shipped in the unreleased-feature registry (id `github-issues`) | [github-issues.md](github-issues.md) |
| GitHub Releases (view + create) | **Removed from Omniscio core (in-core GitHub detachment) — plugin-only now.** Formerly the "GitHub Releases" sidebar tab (in-development flag `githubReleasesEnabled`): pick a repo to view its releases (notes / read-only assets / draft+prerelease+latest badges) and create a release. Create defaults to a DRAFT (outward-facing); explicit publish-vs-draft copy, existing-or-new tag (new tag picks a target branch), optional title, manual notes and/or auto-generate (independent). Write is REST `gh api .../releases` (never `gh release create`, so it never touches local git); errors humanized stderr-first; `gh:release-*` IPC, virtual project `__github_releases__` | [github-releases.md](github-releases.md) |
| GLM provider (Anthropic-compat API) | Spawn Claude-Code-style sessions backed by Zhipu's GLM Anthropic-compatible API (hosted at `z.ai`) alongside `claude`, `codex`, `gemini`, `antigravity`, `deepseek`, and `kimi` — gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via Settings → Account GLM API key + "Allow GLM sessions" toggle. Who pays is GLM's supply list (Settings → Accounts → Who pays & who serves): your z.ai accounts, the backup key, an Omniscio credits row (Pro plan) and reseller rows (DeepInfra for GLM 5.2, RunInfra for GLM 5.3 Flash). **No binary check** — reuses the standard `claude` CLI; routing happens via spawn-env (`ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic` + `ANTHROPIC_AUTH_TOKEN=<vendor key>`); default model `glm-5.2[1m]` (1M context; bare `glm-5.2` fallback); 2 readiness gaps (`toggle-off`, `key-missing`); identical tool-approval UX to Claude (no yolo mode) | [glm-provider.md](glm-provider.md) |
| Global Memory System (agent memory tree — browse, load, auto-write) | A progressive-disclosure, agent-written memory library on the Context Dock native store — Omniscio's own docs system made live. Milestone 1 is the READ path: agents browse memory as a budget-aware tree (fixed branches About You / This Project / People → tag-groups → memories, each showing its short/medium/full token cost) and load any memory at the chosen level over the CLI control server (`GET /memory/map` / `open` / `load`), plus a tiny always-loaded root map injected into each session's first message. A "memory" IS a Context Dock store doc (reuses its 3 compression levels + token counts + summary — no new store). Gated OFF by default (`globalMemoryEnabled` / the `global-memory` unreleased feature), agent-facing (no UI), desktop-only; it composes NO MCP server — the five tools it once shipped (`memory_map`/`open`/`load`/`remember`/`search`) became `/memory/*` routes on 2026-09-02, retiring one subprocess per session. M2 adds the WRITE path, now led by the agent that DID the work: a `memory-capture` system-prompt fragment asks it, at the end of its work, only what the USER revealed about themselves or corrected — never what the session produced, which is what kept turning the library into a changelog. The post-hoc session-end distiller is demoted to an opt-in fallback (`memoryDistillerModel: 'off'`), and a mid-work `POST /memory/remember` remains; each memory is scoped (About You / project / People) and deduped within scope, linked to its source session. Search/RAG (M3) and a janitor + persistent nested-index table (M4) are later milestones. Contract: global-memory-system-contract. | [global-memory.md](global-memory.md) |
| Global Search | Ctrl+K search across every channel (Claude/SMS/Slack/Telegram/RSS/webhook) — FTS5 ranking, deep-link navigation | [global-search.md](global-search.md) |
| Gmail integration | Triage inbox inside Omniscio — AI reply chips, DOMPurify-sanitized viewer, inbound-security prescreen with Haiku | [gmail-integration.md](gmail-integration.md) |
| Google Docs Export (publish Markdown → Google Doc) | Two convergent surfaces (right-click on project docs / scratchpads / agent messages via IPC `GDOC_PUBLISH_MARKDOWN`, external `POST /gdoc/publish` on the CLI server) all feed one publisher pipeline that copies a template, runs a LOCKED three-batch apply (text → lists → styles+tables), and trashes older versions of the same title; preserves headings, bullets, fenced code, blockquotes, links, and native Docs tables; shared Google OAuth (`documents` + `drive` scopes); stable error codes (`GDOC_FEATURE_DISABLED` / `_NOT_AUTHENTICATED` / `_SCOPE_INSUFFICIENT` / `_PARSE_FAILED` / `_API_FAILED` / `_NO_TAB`); off by default (`googleDocsExportEnabled`) | [google-docs-export.md](google-docs-export.md) |
| Google Integrations (Calendar, Drive, Sheets) | Single "Connect Google" OAuth; Claude gets 23 tool-use calls to query/edit calendar events, Drive files, Sheets; Calendar also has a full panel UI (Agenda/Week/Month views, event editor with attendees/recurrence/reminders, AI chat drawer, Today/Tomorrow sidebar list) | [google-integrations.md](google-integrations.md) |
| Google Meet (meeting history, transcripts, recordings from Google Meet API) | In-development built-in integration that pulls **Google Meet meeting history** into Omniscio: conference records, participant rosters, cloud recordings, and speaker-attributed transcripts via the Google Meet REST API v2 (GA 2025). Syncs automatically in the background (every 15 minutes, 90-day rolling window) and shows meetings in a dedicated sidebar panel (Communication group, blue video-camera icon) with two tabs: **Meetings** (conference list + detail with participants, transcript, recordings sub-views) and **Settings** (connection status, scope check, manual sync). Piggybacks on Omniscio's existing Google OAuth sign-in (`meetings.space.readonly` scope added additively; no separate auth flow). Requires a **Google Workspace Business Standard** (or higher) account; consumer Gmail accounts get a clear 403 message. Sub-resource reads (participants, transcripts, recordings) are live API calls, not cached. All IPC channels blocked from the WebSocket/mobile bridge for the initial release. In-development, off by default — reveal via Settings → Lab toggle or `googleMeetEnabled`. | [google-meet.md](google-meet.md) |
| Google Workspace MCP (Docs read/edit, Sheets, Drive for CLI) | MCP server subprocess giving Claude CLI sessions 17 tools for Google Docs (read, edit, find-and-replace, batch edit), Sheets (read, update cells), and Drive (list folder) — runs alongside the CLI via `.mcp.json`, same Google OAuth; requires Docs API + Sheets API enabled on the GCP project | [google-workspace-mcp.md](google-workspace-mcp.md) |
| Granola | Experimental Granola meetings integration — a "Granola" sidebar tab listing recent meeting notes (title/date/summary, cursor-paginated), a read-only transcript viewer drawer, a one-click "Use as context" that copies summary+transcript to paste into a new Claude session (never auto-spawns), connect via a Granola API key, plus a "granola-inbox" newly-created-meetings source. | [granola.md](granola.md) |
| Work through interrupted sessions — auto-advance | Act on a session in a project's **Interrupted** section (archive, snooze, close, or revive via send / "Please continue" / Restart) and Omniscio advances to the next Interrupted session — the WHOLE section (ended, waiting, non-reconnecting error/stalled, failed needs_you), not just ended (broadened 2026-08-23) — bouncing back within the section, never crossing into Live/Paused; when the section is exhausted it falls to the on-screen neighbour. Project view only; the Inbox + OpenClaw / Ask-Omniscio / Search areas stay status-blind. | [gray-session-triage.md](gray-session-triage.md) |
| Grok provider (CLI-backed sessions) | Spawn Claude-Code-style sessions backed by Grok Build (`grok`, xAI's agentic coding CLI, `grok-build-0.1` model) — a **first-class** alternative provider (monochrome "Grok" spark pill, per-project default, switch-to-able). Gated behind master "Show alternative AI providers" (off by default), then opt-in via Settings → Account Grok CLI binary (installs to `~/.grok/bin` via x.ai/cli, detect-by-existence) + an **xAI** API key (env `XAI_API_KEY`, shared with Grok voice — a dedicated `grokApiKey` overrides) + "Allow Grok sessions" toggle; per-turn one-shot subprocess (`grok --prompt-file <f> --output-format streaming-json --always-approve`) with token-by-token `thought`/`text`/`end` NDJSON streaming and resume via `-s <uuid>`→`--resume <id>`; 3 readiness gaps (`toggle-off`, `binary-missing`, `key-missing`); no virtual project; **cost not reported** (Grok emits no usage); no tool markers + no MCP (v1); config-isolated via `GROK_CLAUDE_*`/`GROK_CURSOR_*` env toggles (Grok runs no `.claude` hooks, so no worktree isolation). Verified live against grok 0.2.93 (stream schema + resume round-trip). | [grok-provider.md](grok-provider.md) |
| Habit Tracker (personal habit / daily-routine tracker, in development) | In-development, off by default (gated by the `habits` unreleased-feature — `habitsEnabled` / `AMC_SHOW_HABITS=1` / Settings → Features). A first-party personal habit tracker in the **Productivity** sidebar group, the sibling of Coffer, fully local (no cloud / AI / cost). A native full-pane panel (`panelOwnsLayout`, mobile `ready`) with four top tabs: **Today** (tap-to-log checklist — a check for yes/no + duration habits, a −/+ stepper for counts, a 1–5 picker for scale — with a day-completion ring, streak flames, and an empty-first-run state offering one-tap Exercise/Water/Sleep starters), **Habits** (manage/create by category via an editor modal: name, kind, target, cadence = specific weekdays XOR a times-per-week goal, optional reminder), **Calendar** (per-habit 16-week contribution grid + current/longest streak + completion %), and **Trends** (completion-by-category bars + a 14-day sparkline). Streaks + completion are derived on read from the logged entries against the habit's current target (no stored completed flag; DST-safe local dates). Optional daily reminders reuse the AI-coaching nudge engine — one passive inbox nudge per habit per day when its time arrives and it isn't done, with an "Open Habit Tracker" action (`habitsRemindersEnabled`, on by default). Data: two local tables `habit_definitions` + `habit_entries` (PK (habit_id,date), idempotent per-day log). | [habits.md](habits.md) |
| Header widgets (account, hardcore, cpu-burst, helpdesk) | The four named controls in the app's top header — account switcher, hardcore mode, CPU burst, help desk. Each is a `ToolbarItemDef` in the existing toolbar registry; fully user-manageable (show/hide/reorder) via Settings → Widgets; existing users keep them via a one-time pin migration; interactive widgets render through the shared `WidgetShell` building block; plugins contribute via `toolbar.setItems()` (no new permission). Contract: header-widget-contract. | [header-widgets.md](header-widgets.md) |
| Heap snapshot diagnostics (memory bloat investigation) | `POST /diagnostics/heap-snapshot` on the CLI control server — agent-callable endpoint that captures a V8 heap snapshot, parses it, and returns ~5 KB JSON summary (totals, byNodeType, topClassNames, largeStrings); replaces the dead `Ctrl+Shift+I` workflow; bearer-token gated, single-flight, rate-limited | [heap-snapshot-diagnostics.md](heap-snapshot-diagnostics.md) |
| Heavy-operation admission | The former default-on filesystem/PID background-job pacing is retired. Ordinary commands and idle agents perform zero broker I/O. A replacement authenticated local broker exists only for explicitly classified heavy search, Git, process-start, build/test, and install work; it is default-off, class-by-class opt-in, and remains off pending crash/latency/long-soak evidence. The compatibility Settings control cannot enable either generation. | [heavy-job-pacing.md](heavy-job-pacing.md) |
| Help & Docs Panel (in-app docs site) | Built-in browser at `Ctrl+Shift+/` (or toolbar HelpCircle) loads `docs.omniscio.com` inside an Electron `<webview>` — back / forward / home / Browser button / close header, title syncs to active section, external links route to OS default browser; deep-linkable via `window.__helpPanelNavigate` | [help-and-docs-panel.md](help-and-docs-panel.md) |
| Help Desk email tickets (plain-English support mail → a tracked ticket) | A person emails support in plain English — no `[BUG:]` / `[FR:]` marker — and it becomes a real Help Desk ticket instead of a one-off answered email: it lands in the operator **Incoming** queue with the sender's name on it, carries a lifecycle stage that advances to Building by itself when the investigation spawns, and their replies append to the SAME ticket (reopening it if resolved) rather than opening a second one. Judged human by transport headers only (`List-Unsubscribe` / `-Post` / `Precedence` / `Auto-Submitted` / no-reply sender), classified bug/feature/feedback/question by the SAME prescreen LLM call (no second call, cost flat), and given its own per-sender daily limit. Claude DRAFTS; a human presses send from any operator's console, and the computer that received the email mails that reply to the reporter on their original thread (`In-Reply-To` the thread root) exactly once — a send that fails is retried automatically, and three failures in a row raise the shared "can't send your agent's email replies" card. Nothing auto-replies: the claim suppresses the catchall and the tracking row is written pre-closed under a sentinel session id. An install may also name ONE **public support address** anyone may email — judged by its own sender rule while every other address keeps the install's policy, refused server-side for a desk name like `support@` unless the caller is an owner — and the desk answers AS that address so the reporter's reply returns to support; a new ticket sends ONE receipt, and help-desk tickets have their own board. Investigation model is a TIER (never a stale id) and the existing global + per-project appended-instruction boxes customise its prompt for free. Three of the four bulk signals need the Cloudflare worker deployed; every hop treats the headers as optional so deploy order does not matter. In-development, OFF by default — Settings → Features (`helpdeskEmailTicketIntakeEnabled`) or `AMC_SHOW_HELPDESK_EMAIL_TICKET_INTAKE=1`. | [helpdesk-email-tickets.md](helpdesk-email-tickets.md) |
| Get Help (Helpdesk) — part 2 (operator queue, developer console, watchers, key files) | The second half of the Get Help page, for the team answering: the operator queue with its views, custom filters and tag colours, and the developer console — the always-visible ticket header (sender, Email or In-app chat, subject, assignee), quoted email history folded behind "Show quoted text", assignment alerts, status tabs, drafts with AI, routing rules and aging/SLA — plus the boot-time reply listener, the incoming-question watcher, the test seams and the key files. | [helpdesk-part-2.md](helpdesk-part-2.md) |
| Get Help (Helpdesk — in development) | Ctrl+Shift+H panel: type a question in plain English, get an AI answer grounded in the bundled help docs with clickable source chips, rate it 👍/👎; 10 asks/min cap; "Send to developer" escalation writes to Firestore `helpdesk_threads`, sends email alert via resend-service, and adds a thread to the dev console Incoming tab; boot-time reply listener mirrors developer replies to the user as Inbox items; gated dev console (`AMC_SHOW_HELPDESK_DEV_CONSOLE=1`) stays in-development even after helpdesk ships; `AMC_HELPDESK_FAKE=1` swaps the cloud to an in-memory fake for tests; hidden by default, user gate revealed via `AMC_SHOW_HELPDESK=1` or the Labs toggle; Crisp-style ROUTING rules (dev console → Routing) auto-assign incoming escalations to operators by language/country/tier/platform/keyword with round-robin + offline fall-through, plus manual assign in the details rail and an All/Mine/Unassigned queue filter | [helpdesk.md](helpdesk.md) |
| Hermes provider (ACP-backed sessions) | Spawn Claude-Code-style sessions backed by the local Hermes CLI (`hermes`, Nous Research's model-agnostic coding agent) — a **first-class** provider (amber "Hermes" pill, per-project default). Gated behind master "Show alternative AI providers" (off by default), then opt-in via Settings → Account Hermes CLI binary (detect-only, no installer) + "Allow Hermes sessions" toggle; **no API key step** (Hermes runs on your own model + key via `hermes setup`); **kept-alive `hermes acp --accept-hooks` child** (Agent Client Protocol, `persistent-external`, same pattern as Kimi Code/Gemini) with token-by-token JSON-RPC streaming and **native stateful multi-turn memory** (ACP session, real — migrated from one-shot `-z` on 2026-08-01 to fix a v0.19.0 regression); **2 readiness gaps** (`toggle-off`, `binary-missing`); no virtual project; **records $0 cost** (`costReporting:'none'`, Hermes ACP v1 exposes no usage); `restartResumable:false` (ACP session state lives in child). A migration on-ramp for existing Hermes users. | [hermes-provider.md](hermes-provider.md) |
| Hooks (manage the Claude Code hooks Omniscio injects into your agents) | An Agent Tools sidebar panel to manage the Claude Code hooks Omniscio composes into every session it spawns — the **built-in** hooks it ships (Git Guardrails, Secret Paste Guard, Write-Time Lint, Agent Firewall — surfaced read-mostly) plus **user-defined custom hooks** you create: a lifecycle event (PreToolUse / PostToolUse / etc.) + an optional tool matcher + a command to run, each **global with per-project overrides** (turn a hook on/off for one project). Custom hooks are composed into the ONE session-private `--settings` file Omniscio already injects at spawn — it NEVER touches your global `~/.claude/settings.json`. A **two-pane** surface (sub-sidebar + detail) like MCP Servers / Skills: the left pane has a **Hooks\|Sessions** tab strip — the Hooks tab groups rows into **Built-in** and **Your hooks**, and clicking one opens its detail on the right (view + **inline-edit** its Settings, plus an **Activity** view showing the projects the hook is currently active in — derived, zero-capture, never observing individual firings). The **Sessions** tab spawns an AI helper session that **drafts** a hook for you to save (`__hooks__` is a spawnable session host; hook creation stays human-only). **Desktop-only** (hook mutation runs an arbitrary command, so it is human-only and blocked from the mobile/web bridge). In-development — reveal via Settings → Lab (`customHooksEnabled`) or `AMC_SHOW_CUSTOM_HOOKS=1`. Sibling of Skills / MCP Servers / Browser Logins. Contract: hooks-panel-contract. | [hooks.md](hooks.md) |
| Hotkey Training Mode (block the mouse to learn the keyboard) | Opt-in mode (Settings → Sessions, default off): the FIRST left-click on a button that also has a keyboard shortcut is blocked + shows a "Press &lt;key&gt;" bubble. A 3-click soft escape hatch: the 2nd click on the same control is still blocked ("Click again to allow"), the 3rd passes through with a green "Allowed ✓" confirmation. Keyboard untouched; inert on touch screens; the Settings gear is never blocked. Registry-backed marker + a build-time completeness guard so a new hotkey button can't silently escape the mode | [hotkey-training-mode.md](hotkey-training-mode.md) |
| Hotkey Usage (which shortcuts people actually press) | Stats sub-tab + cloud admin ranking — records every keyboard-shortcut PRESS by action id + surface (key-repeat excluded), ranked most→least so the least-used shortcuts surface as candidates to drop or leave unassigned by default. In-app **Stats → Hotkey Usage** (your own data, immediate) plus anonymized fleet + per-user rankings in the admin console. Distinct from Shortcut Efficiency (mouse-vs-keyboard). | [hotkey-usage.md](hotkey-usage.md) |
| Hub Descriptions (what each part of Omniscio is, in one line — editable) | Gives every "hub" — each built-in tool/integration, each sidebar category, and each of your projects — a short plain-English line saying what it is and when it matters, so your Chief of Staff and any agent you ask actually know what each part of Omniscio does. Built-in tools and categories ship with a written default; your projects start blank. Edit any line yourself in **Settings → Tools & Maintenance → Hub Descriptions** (240-char box with a counter), or press **Regenerate with AI** to have a cheap Haiku call draft one — it only fills the box, you press Save, so nothing is written without you seeing it. Your edit always beats the built-in default; **Reset to default** / **Clear** undoes it. Read by exactly two consumers, pull-only (never forced into every session's prompt): the Chief of Staff gets the enabled hubs each time it starts, and any agent can read `GET /hubs` (your projects are deliberately excluded from that route). No "regenerate everything" button by design. On by default; Settings → Lab hides the editor with one flip (the descriptions keep working). Contract: hub-descriptions-contract. | [hub-descriptions.md](hub-descriptions.md) |
| Hub jumper (Ctrl+G — type two letters, jump to any hub) | A centred search palette opened with **Ctrl+G** that replaces scrolling the sidebar with typing: type two or three letters, see the matching hubs ranked, press **Enter** to switch. It exists because the projects sidebar stops working as a *navigation* surface past ~20 hubs (the owner runs 140+), where finding a hub becomes a scan rather than a jump. Two things make it more than a filter box: it ranks by **your own** recency and frequency of visiting each hub — not alphabetically — so the hub you actually use beats an equally-good name match you have never opened; and with an **empty box** it lists your most-recently-visited hubs newest-first, so **Ctrl+G then Enter** bounces straight back to the hub you just left. It also reaches hubs inside **collapsed** sidebar groups, which a filter over the visible list cannot. Matching reuses the same shared fuzzy engine as the Team Chat channel switcher (subsequence match, so `taskm` finds "Task Management"), with matched letters emboldened; rows show the hub’s sidebar group on the right. Visit history is per-device (not synced, not in the database) and records the app’s startup restore as a non-visit. Desktop only; the existing **Ctrl+1–Ctrl+0** slot jumps are deliberately untouched. Contract: hub-jumper-contract. | [hub-jumper.md](hub-jumper.md) |
| Release idle sessions to reclaim RAM (cross-platform) | Periodically RELEASES (kills) the persistent Claude CLI process of a session that finished its turn and sat idle past a threshold — reclaiming all of its RAM (~250–450 MB each), not just trimming it; the conversation stays on screen (stored by Omniscio) and the next message transparently re-spawns via `--resume` (a slightly longer first reply). Never releases a session mid-turn, recovering, waiting on its own wakeup, running subagents, or waiting on a question / plan-approval (those keep their process). Settings → Performance `idleSessionReleaseMinutes` (default 15, 0 = off) + `AMC_DISABLE_IDLE_RELEASE=1` kill switch; releasing after 15 min adds no token cost (prompt cache already expired) | [idle-session-release.md](idle-session-release.md) |
| Image Bridge for text-only models | Optional session setting for image attachments on text-only models. Default off: unsupported images keep the existing warning and are not sent. When enabled, Omniscio sends attached images to a vision-capable model first, creates a query-targeted visual brief with OCR/layout/uncertainty and image prompt-injection safeguards, then passes that brief to the selected text-only model. Image-capable models keep native image delivery and never pay bridge cost. | [image-bridge.md](image-bridge.md) |
| Image Studio (native panel — generate, compare, library, stats, templates, post-processing) | Omniscio's first-class, in-app image studio — a native four-tab panel (**Studio · Library · My Stats · Templates**) plus a full-screen viewer — for generating AI images and managing a whole history without the older embedded website it replaces. **Generate** from a Subject (+ optional Style) across **8 models** (Gemini Flash / NB2 / NB2 Lite / Pro, SeedDream 4.5, Ideogram 3, GPT Image 2 / 1.5) at **0.5K–4K** and six aspect ratios; **multi-prompt** (a blank line or a `---` line splits one box into several batches), **reference images** (separate content + style drop zones, combined cap 14, per-model limits, 20 MB, PNG/JPEG/WebP/GIF), a **1–10 count** with a live **cost-estimate pill**, and a ≥20-image confirm. **Multi-model comparison** runs **2–8 models** on the same prompt (1–3 images each) grouped side-by-side. The **Library** is your saved history with prompt search (recent-500 window), model + date filters, comparison grouping, multi-select, bulk delete, and **ZIP export**. The **viewer** zooms/pans/navigates and offers **post-processing** — AI **upscale 2×/4×** (Topaz) and **background removal** (BRIA / 851-labs), each creating a new, separately-billed image. **My Stats** shows all-time totals + per-model breakdown + personal bests; **Templates** save subject/style/reference images (not model/size) up to 50. **Desktop-only, sign-in required**; every generation **spends prepaid gateway credit** — the cost pill is only an estimate (the server sets the real charge; a failed image isn't billed; out of credit → top up). **No in-panel share links or collections** — those live in the Image Studio MCP tools and the standalone JLS web app. Currently behind the in-development `image-studio-native` flag (off by default, hidden until shipped). Contract: unified-image-gen-billing-contract. | [image-studio-native.md](image-studio-native.md) |
| Approved senders for message channels (who can auto-start a session via SMS/Slack/Telegram) | A per-channel allowlist of who may **auto-start an AI session or run an automation** from an inbound SMS, Slack, or Telegram message. **Fail-closed: an empty list = nobody** (deliberately the opposite of the older Email Inbound box, which has its own secret-token gate) — so an unknown texter or a stranger in a monitored Slack channel can't spin up a paid AI run before you've said who you trust. Blocked senders' messages still arrive in your inbox; only the automatic session/automation start is gated. Set it in Settings → Connections → Channels → SMS / Slack / Telegram (an **Approved senders** card of removable chips + an Add box). Because "empty = nobody" can pause an auto-start you relied on, the first block per channel (only if you have automations on) drops ONE Inbox note naming an example sender to add. Not a security wall (a phone number / Slack ID is spoofable — it's a convenience + cost guard). Closed security-sweep F018/F020/F021/F022/F026. | [inbound-sender-allowlist.md](inbound-sender-allowlist.md) |
| Inbox alerts (how an agent gets your attention) — part 2 | Part 2 of the Inbox alerts page: how an alert is actually authored — adding a new alert type, the route an agent posts one through, the text handling it has to survive, and the app-generated cards that arrive with their own custom actions attached. | [inbox-alerts-part-2.md](inbox-alerts-part-2.md) |
| Inbox alerts (how an agent gets your attention) — part 3 | Part 3 of the Inbox alerts page: the Alerts screen and an alert's life after it arrives — the cooldown that keeps a dismissed problem quiet, the recently-dismissed view, starting a session from an alert, automatic remediation, provenance, and the once-a-day digest. | [inbox-alerts-part-3.md](inbox-alerts-part-3.md) |
| Inbox Alerts (agent-sourced persistent inbox rows) | Any Claude Code session or CLI control server call can drop a persistent inbox row on demand via `POST /alert`; text / link / file content types; `dedupKey` groups repeated alerts into a single ×N badge row; archived/snoozed via the universal inbox mechanics; scoped-to-project rows also surface in that project's Needs You section; EVERY alert type has its own off switch (from its card, or Settings -> Notifications -> Alert types), enforced at the one chokepoint so scripts and scheduled jobs are covered too; a handful about losing data or access cannot be silenced and say why; the `agentAlertsEnabled` switch stops AGENTS posting cards (POST /alert and its replay) and never hides the app's own cards | [inbox-alerts.md](inbox-alerts.md) |
| Inbox Attention Analytics (how your inbox triage behaves — local) | Built-in **100% local** report on how you work your Omniscio inbox (not its contents): avg time-to-clear, time-weighted avg items waiting, a "looked without acting" rate, and avg view time, shown in a new **Inbox** tab in the Stats virtual project with a Today / 7d / 30d / 90d / All range plus by-type / by-project / top-sessions / actions-taken breakdowns. Renderer-driven capture (`InboxAttentionTracker` diffs the visible inbox for arrivals/clears and times the open item; suppresses the launch snapshot) buffered fire-and-forget over `inbox-analytics:record` into a dumb-storage local `inbox_item_events` table; windowed report via `stats:inbox-analytics-report`. The inbox counterpart to UI Usage tracking — on by default (Settings → Diagnostics "Track inbox attention analytics"), never sent anywhere (kept out of the portable backup + fleet telemetry), stores only bounded dimensions (item type / project id / session id) with no content, pruned after 90 days. | [inbox-analytics.md](inbox-analytics.md) |
| Inbox backlog nudge (archive when sessions pile up) | A once-a-day inbox card nudging you to archive when 15+ sessions have been waiting 3+ days AND you're active but not archiving (quantity + age, not a raw count); runs locally with no AI; self-clears when the backlog clears; "Turn off these nudges" mute + Settings → Notifications (`inboxBacklogNudgeEnabled`, default on) | [inbox-backlog-nudge.md](inbox-backlog-nudge.md) |
| Inbox overview | Unified cross-project triage view at the top of the sidebar — 10 source types (sessions, daily digest, SMS, Telegram, cron approvals, automation approvals, CLI Pending, recipe approvals, recipe authoring approvals, recipes); J/K navigation; frozen group order | [inbox-overview.md](inbox-overview.md) |
| Inbox Pilot (an AI that triages your inbox for you) — part 2 | Part 2 of the Inbox Pilot page: running it in observe-only mode before trusting it, turning it on for new sessions or in bulk, the pill that shows it took a look, the decisions log, what it does with your data, and the limits worth knowing. | [inbox-pilot-part-2.md](inbox-pilot-part-2.md) |
| Inbox Pilot | Cheap LLM call after each agent turn that decides if the session needs you, can be hidden, archived, snoozed, or replied to on your behalf | [inbox-pilot.md](inbox-pilot.md) |
| Pre-render inbox sessions (instant switch into needs-you sessions) | Inbox ("needs you") sessions are pre-built heavy in the background so clicking into one is instant instead of a loading shell. Bounded to the 12 most-recently-active inbox sessions (`MAX_WARM_NEEDS_YOU`) so a large inbox stays fast — the rest load on click (~0.5s); every inbox session is still kept alive as a cheap shell (pool membership stays uncapped). Fixes the "big inbox feels slow, same sessions run fast" report. On by default; two-gate with the `AMC_DISABLE_NEEDS_YOU_WARM=1` env kill switch. Settings → Performance → "Pre-render inbox sessions". | [inbox-prerender.md](inbox-prerender.md) |
| Inbox Rules Engine (auto-suppress / archive / snooze matching alerts) | User/CLI rules that auto-act on new agent alerts — match on source, dedupKey (exact/prefix), title substring/regex, or project, then suppress (recoverable) / archive / snooze; highest-priority rule fires once, synchronously before the inbox is notified (no flash); safety allowlist never lets a rule silently suppress account-reauth / backup / low-memory / low-disk / low-spec alerts; CLI-created rules land pending until you approve them; every fire is audited; off by default (`inboxRulesEnabled`, Lab feature `inbox-rules`); Stage A governs the `alert` integration only. Contract: inbox-rules-engine-contract | [inbox-rules.md](inbox-rules.md) |
| Inbuilt terminal (xterm.js + node-pty, project-scoped shell) | A real shell terminal inside Omniscio, scoped to a project — click the terminal icon in the sidebar header (**Ctrl/Cmd+T** when focused) to spawn a `pwsh.exe`/`cmd.exe` on Windows or `$SHELL` on macOS/Linux, rendered via `xterm.js`. **Persistent scrollback** (last 100 KB per session, restored on remount). **Ctrl/Cmd+K** opens a snippet palette (fuzzy search → paste-only insert; user hits Enter). Bookmark button in the header opens a Save-snippet dialog; Settings → **Terminal snippets** manages them (undo on delete). **Ctrl/Cmd+F** reveals a Find bar. Live theme rebind on light/dark toggle. Gated behind the `inbuilt-terminal` Labs flag (off by default; `AMC_SHOW_INBUILT_TERMINAL=1` env override) | [inbuilt-terminal.md](inbuilt-terminal.md) |
| Insights group (sidebar) | Collapsible sidebar group (formerly "Insights") nesting Session Search, Settings, Tags, Alerts, Marketplace, Marketplace Review, Stats + Shares — app-level settings, search, and management; ships collapsed by default; keeps the byte-stable insights-group id | [insights-group.md](insights-group.md) |
| Instant new session (Ctrl+T fast path) | Ctrl+T / N reveals a pre-warmed real blank session synchronously — zero IPC, composer textarea focused in the same frame. One genuine empty DB row (auto-numbered **"Session N"**, like any new session) is pre-created (debounced `SESSION_ENSURE_BLANK`) and its panel render-warmed per active project via the keep-alive pool's P3 carve-out (invariants I14 / I15). Never a client-side placeholder; never overwrites a typed draft (the draft gate lives in the store layer); falls through to the normal launch path on any miss. On desktop (Ctrl+T) and mobile (New Session — the blank is reserved + inserted optimistically the instant you enter a project, so the reveal is instant regardless of network); regular Claude provider only. Toggleable: Settings → Performance → "Pre-load new sessions" (on by default). Kill switch: `AMC_DISABLE_INSTANT_NEW_SESSION=1` | [instant-new-session.md](instant-new-session.md) |
| Interaction trace (slow-click, jank, navigation latency) | `interaction.log` — a continuous tape (size-bounded at 1 MB, 5 rotated backups) of every interaction above 200 ms, long animation frame above 100 ms, and phased session-switch timing; reveal button at Settings → Diagnostics → Interaction Trace; TOP 10 worst-offenders summary; kill switch `AMC_DISABLE_INTERACTION_TRACE=1` | [interaction-trace.md](interaction-trace.md) |
| Interrupted sessions section (sidebar) | Sessions whose process stopped (status `ended`) — PLUS plain errored/stalled sessions (2026-08-11: error/stalled are now non-attention → quiet in Interrupted, no inbox/badge/chime; a reconnecting one stays in Live) — are grouped into an **Interrupted** section rendered above Live (Paused sits below Live) in the project sidebar — ember-colored AlertTriangle icon, collapsible, default expanded. Distinguishes "process died / errored" (Interrupted) from "user chose to freeze" (Paused). Shown whether or not "show ended sessions" is on. | [interrupted-sessions-section.md](interrupted-sessions-section.md) |
| Is my data encrypted? (what Omniscio encrypts at rest) | Map of Omniscio's encryption at rest, surface by surface — answers "is my database/data encrypted?", "are my backups encrypted?", "data security / privacy". **Encrypted:** automatic local backups + the cold-storage archive (AES-256-GCM, key in this computer's system keychain — written UNENCRYPTED with a warning when that keychain is unavailable), the **Backup Mirror** (passphrase-encrypted, portable to a new machine), the weekly **Setup Backup** to Gmail (encrypted only once you set a passphrase; a plain ZIP until then), and your API keys / account logins / integration tokens (OS-keychain `safeStorage`). **Optionally encrypted at rest (in development):** the live `mission-control.db` the app actively uses — off by default (protected by your OS login + optional full-disk encryption like BitLocker/FileVault), with a new opt-in to encrypt the live file itself ([database-encryption.md](database-encryption.md)). **Not encrypted at rest:** the manual "Export all data" ZIP (deliberately, since you choose to create and share it). | [is-my-data-encrypted.md](is-my-data-encrypted.md) |
| Fast typing (isolated composer) | Off-by-default **Settings &rarr; Sessions &rarr; "Fast typing (isolated composer)"** toggle that fixes per-keystroke typing lag in very large sessions. ON: the chat message box owns its draft text locally so a keystroke re-draws only the textarea, not the whole session panel (the lag is worse in the dev build). OFF (default): the original composer, byte-for-byte unchanged. Live kill switch — flip OFF anytime, no restart, to return to the classic composer; the OFF path is never edited so it can't regress. Drafts (persisted across restarts), paste, quick-replies, voice, scheduled-send, aside mode, and tours all work identically in both modes. | [isolated-composer.md](isolated-composer.md) |
| Isolated session view (experimental) | Opt-in performance mode: the ACTIVE session's chat renders in its own background renderer process embedded invisibly inside the main window (one window always, at most one extra process — sessions swap into the single embedded view in place, never one process per session). Switching + typing stay fast under heavy shell load — measured click→content p50 34ms / p90 75ms loaded vs 222/413ms inline (~6×), typing ~2–3ms/key throughout. Settings → Performance → "Isolated session view (experimental)", default OFF, desktop only; Pop Out wins over staging; ANY failure silently falls back to the normal inline panel (never a dead panel); env kill `AMC_DISABLE_ISOLATED_SESSION_VIEW=1` (force-OFF only); costs ~195MB (one extra renderer process) while staged | [isolated-session-view.md](isolated-session-view.md) |
| Jev (decision model) | A fast DECISION model your agents call through a small command-line tool: hand it a situation plus typed questions and it answers each with a calibrated confidence instead of prose - classify, route, extract, rate, or judge another model output. Nothing runs in the background. Metered to your gateway AI credit (Settings -> Plan & Usage), with your own OpenRouter key used only as a fallback. If nobody can be asked it says so plainly, which is deliberately not an answer of no. | [jev-cli.md](jev-cli.md) |
| Jira board (in development) | In-development experimental integration (default-hidden, gated via the `jira-board` unreleased-feature; `jiraBoardEnabled` toggle in Settings → Lab, or `AMC_SHOW_JIRA_BOARD=1`). Adds a "Jira" sidebar virtual project that talks to Jira Cloud over its REST API. Connect in-panel via the header gear / "Set up Jira" button with your Atlassian email + API token + site URL (token encrypted at rest; SSRF-guarded to `*.atlassian.net`). Implements board columns + cards, lazy issue detail, transitions, comments, assign, in-place edit (summary / description / priority / labels), create issue, drag-and-drop between columns, quick filter, load-more pagination, and a board/backlog/sprint scope switcher; plus a `jira-inbox` source surfacing issues assigned to you as unified-Inbox rows | [jira-board.md](jira-board.md) |
| JLS Image Studio (embedded website, full-panel sidebar tab) | Embeds the live jls-image-studio.web.app web app inside Omniscio as a full-panel sidebar tab via a hardened Electron `<webview>` — the panel owns the whole content area (sessions sidebar + main panel). You sign in with your own JLS account inside the pane; the login persists across restarts via a dedicated `persist:jls-image-studio` partition (a webview is its own WebContents, so the site's X-Frame-Options can't block it). Default-off; enable in Settings → Connections → JLS Image Studio (`jlsImageStudioAppEnabled`). Desktop-only (`mobile: { status: 'desktop-only' }` — a webview is blank over Web Access; on a phone open the site directly). DISTINCT from the JLS Image Studio MCP integration (image-generation tools for AI sessions, in Accounts & Providers). | [jls-image-studio-app.md](jls-image-studio-app.md) |
| JLS Image Studio MCP (image generation for Claude CLI sessions) | Built-in MCP server giving any Claude CLI session 12 tools for image generation and management via the JLS Image Studio API — generate from a text prompt (7 models: gemini-2.5-flash-image, gemini-3.1-flash-image-preview, gemini-3-pro-image-preview, seedream-4, seedream-4.5, ideogram-v3, gpt-image-2), compare models side-by-side, enhance prompts, estimate cost, browse and download your generation history, save reusable prompt templates, create/list/revoke shareable links, and open an image for manual annotation in the JLS web app (annotation is a placeholder pending API enrichment). Replaces the earlier Nano-Banana MCP. Enable at Settings → Accounts & Providers → JLS Image Studio with an `jls_ak_` API key (encrypted at rest). Composed per session via `mcp-config-orchestrator.ts` alongside MemPalace, KMS, Google Workspace, and Zapier; force-disabled for KMS sessions. | [jls-image-studio.md](jls-image-studio.md) |
| JLS SOP Assistant (JLS-only SOP lookup — plugin) | Built-in plugin restricted to the **jlstradingco** workspace (manifest `plugin.requiresOrganization`). Ask a question → the panel ranks the shared SOP library (Firestore `organizations/{orgId}/sopLibrary`, member-only rules) → its backend reads the top SOPs with the user's OWN Google access (auth.session broker, `documents` + `spreadsheets`) → a normal agent session on the user's OWN Claude account answers (rendered markdown, source chips from the library's own URLs) and returns summaries/keywords that are saved back to the library. Chats live in plugin storage on the device, one session per chat, so follow-ups keep context. Members may add SOPs outside the master index (create-only, "Added by" their member name). Owners/admins seed the library from the JLS master SOP index sheet ("Library settings → Save & sync"; an admin's panel re-syncs changed rows once a day). Summaries only, never full SOP text. Desktop only. | [jls-sop-assistant.md](jls-sop-assistant.md) |
| Job Monitor (test/build/dev process dashboard) | Sidebar virtual project — read-only dashboard of every long-lived vitest / Playwright / dev-server / sandbox / build process held by the filesystem-lock gates (`%TEMP%/amc-test-slots/`, `%TEMP%/amc-e2e-slots/`) plus walker-discovered processes that escaped the gate; rows show type / workspace / pid / uptime / cpu / mem / status (running / stale / dead); Kill button hard-kills the Windows process tree via `taskkill /F /T`; Release-dead-slot frees a sidecar lock whose PID is confirmed dead; non-spawnable virtual project, panelOwnsLayout | [job-monitor.md](job-monitor.md) |
| Job Object orphan-kill (Windows) | How Omniscio guarantees Claude CLI / MCP server children die with it under crash, force-kill, or BSOD — single Win32 Job Object with `KILL_ON_JOB_CLOSE`, every long-running spawn assigned at creation; no-op on macOS/Linux (kernel reparents to init) | [job-object-orphan-kill.md](job-object-orphan-kill.md) |
| Journal (freeform and guided reflection) | Virtual project for personal reflection with two modes: **Freeform** (title + body text editor, auto-save 1.5 s debounce, tags, live word count + reading time, favorite toggle) and **Guided** (Socratic chat with Claude Haiku following a structured template — five built-in: General/Coach, Gratitude, Daily Reflection, Problem Solving, Emotional Processing; rate-limit status shown above input). New-entry screen shows a binary choice: "Just Write" (freeform) or "Talk with Coach" (guided with General template). Entries stored locally in SQLite; guided mode calls Anthropic Messages API directly (no spawned session). Feature gate enforced at IPC handlers (`assertJournalEnabled()`) and CLI routes (`journalPreamble()` → 403). Sub-sidebar layout (entry list + content pane) mirrors AI Coaching. Tags normalized lowercase + deduplicated; search with 250 ms debounce; sort (newest/oldest/recently updated); date-range filter; favorites filter; writing stats dashboard (entries, words, streaks); soft-delete. Opt-in, off by default (Settings → Lab). | [journal.md](journal.md) |
| Keep computer awake while sessions are running (cross-platform) | Settings → Performance toggle (off by default) that holds an Electron `powerSaveBlocker('prevent-app-suspension')` open while ≥1 session is in the running state, so the OS won't sleep mid-turn and freeze an in-flight CLI request; releases the instant the running count hits zero (idle / needs-you / ended sessions never hold it). Blocks SYSTEM sleep only — the display still sleeps (the work is headless). Reliable on Windows/macOS, best-effort on Linux (depends on the desktop environment). Running recipe/pipeline lanes are covered transitively by their always-running orchestrator session. | [keep-awake.md](keep-awake.md) |
| Keep recently-opened panels loaded (instant switching) | On-by-default, desktop-only **Settings &rarr; Performance &rarr; "Keep recently-opened panels loaded for instant switching"** toggle that keeps recently-opened non-chat panels — AI Coaching, Calendar, Drive, Sheets, Supermail, Team Chat, and the Mind Map / Whiteboard docked editors — mounted-but-hidden after their first open so returning is an **instant display flip** instead of a cold rebuild + refetch. One shared switch (`panelKeepWarmEnabled`) + env kill switch `AMC_DISABLE_PANEL_KEEP_WARM=1` (kill switch wins); OFF is byte-for-byte today (each panel mounts on open, unmounts on leave). KMS and Tasks keep their own separate "Keep … loaded" toggles; **Gmail** needs none (its list is already kept in memory). No auto-eviction — bounded to those panels, desktop-only; mobile always mounts fresh. | [keep-panels-loaded.md](keep-panels-loaded.md) |
| Keyboard shortcuts (every binding, and how to change them) — part 2 | Part 2 of the keyboard shortcuts reference: the bindings that drive sessions and the message box, and the ones for quick replies and the AI helpers. Continues from the overview page, and the navigation, search and display bindings follow in part 3. | [keyboard-shortcuts-part-2.md](keyboard-shortcuts-part-2.md) |
| Keyboard shortcuts (every binding, and how to change them) — part 3 | Part 3 of the keyboard shortcuts reference: moving around the app, searching, changing what is displayed, and the bindings that only apply inside a particular project — Gmail, the diff review view, and the daily digest. | [keyboard-shortcuts-part-3.md](keyboard-shortcuts-part-3.md) |
| Keyboard shortcuts (every binding, and how to change them) — part 4 | Part 4 of the keyboard shortcuts reference: how the binding system actually works underneath — what happens when you press a key, how a binding is registered and checked for conflicts, and how the one-handed layout and training mode reuse the same machinery. | [keyboard-shortcuts-part-4.md](keyboard-shortcuts-part-4.md) |
| Keyboard shortcuts | Common shortcuts (Ctrl+T new session, Ctrl+W archive, Shift+F focus mode, J/K nav, Ctrl+K search, Ctrl+Shift+M global focus, Ctrl+Space new-session global, Ctrl+Alt+S quick-scratchpad global, Ctrl+= / Ctrl+- text size) and how to rebind via Settings → Keyboard Shortcuts — unified panel with System-wide / General / Navigation / Session / Focused message / Gmail / Diff Review / Briefings groups (Focused message = the per-message cursor at Shift+↑/↓ with Ctrl+C copy, Ctrl+Shift+T tool-activity toggle and Ctrl+Shift+B re-run); search "hotkey" pins it to top; on a Windows PC with a Chinese/Japanese/Korean keyboard, a dismissible warning offers a one-click rebind off the Ctrl+Space input-method clash | [keyboard-shortcuts.md](keyboard-shortcuts.md) |
| Kimi balance monitor (low-balance + auto-recharge alerts) | Opt-in background watcher (OFF by default) that polls your Moonshot (Kimi) prepaid balance and covers two surprises: (a) raises ONE deduped inbox card + desktop/phone notification with a one-click **Recharge** button (opens platform.moonshot.ai) when your available balance drops below your threshold — before Kimi sessions start failing with "insufficient balance"; and (b) a SEPARATE deduped "Kimi balance auto-recharged" card (with a **Manage billing** button) when the balance **jumps UP** between checks — the tell-tale of a silent linked-card auto-recharge that billed you, which the low-balance alert can never catch (auto-recharge keeps the balance above the low mark). Checks ~every 4h via Moonshot's free balance API (no AI tokens, $0), only when the feature is on AND a Kimi key is set; a failed fetch skips the tick (never a false alert); the balance baseline persists across the 4h gap AND an app restart, and the first-ever poll only seeds the baseline. Threshold is user-set ($5 default, $0–$10,000; $0 disables the check). Deduped so it never nags; re-fires if you go low again after recharging. Settings → Notifications → Kimi balance monitor (`kimiBalanceMonitorEnabled` / `kimiBalanceThresholdUSD`); kill switch `AMC_DISABLE_KIMI_BALANCE_MONITOR`; inert in e2e/sandbox. | [kimi-balance-monitor.md](kimi-balance-monitor.md) |
| Kimi Code provider (ACP-backed sessions) | Spawn Claude-Code-style sessions backed by Moonshot's own **Kimi Code CLI** (`kimi`) — DISTINCT from the **Kimi** provider (the Kimi MODEL run through the Claude CLI on an API key). A **first-class** provider (Kimi Code mark in the header, per-project default, last in the picker). Gated behind master "Show alternative AI providers" (off by default), then opt-in via Settings → Accounts: the Kimi Code CLI binary (detect-only; install from Moonshot, then `kimi login`) + "Allow Kimi Code sessions" toggle; **no API key step** (Omniscio holds no Moonshot key — the CLI's own login). **Kept-alive `kimi acp` child** (Agent Client Protocol, `persistent-external`, the slim ACP base shared with Hermes) with token-by-token streaming and native multi-turn memory; a 120s first-response window; **images sent inline and your project's MCP servers handed over when the CLI advertises them on its start-up handshake** (a visible note when it cannot read images); optional per-session `--model`; **2 readiness gaps** (`toggle-off`, `binary-missing`); cost "not reported" (`costReporting:'none'`); `restartResumable:false`. | [kimi-code-provider.md](kimi-code-provider.md) |
| Kimi provider (Anthropic-compat API) | Spawn Claude-Code-style sessions backed by Moonshot's Kimi Anthropic-compatible API alongside `claude`, `codex`, `gemini`, `antigravity`, and `deepseek` — gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via Settings → Account Kimi API key + "Allow Kimi sessions" toggle — or no key at all, paying with Omniscio credits through Kimi's supply list (Settings → Accounts → Who pays & who serves), which also decides whether DeepInfra serves Kimi K2.7 Code. **No binary check** — reuses the standard `claude` CLI; routing happens via spawn-env (`ANTHROPIC_BASE_URL=https://api.moonshot.ai/anthropic` + `ANTHROPIC_AUTH_TOKEN=<vendor key>`); 2 readiness gaps (`toggle-off`, `key-missing`); identical tool-approval UX to Claude (no yolo mode) | [kimi-provider.md](kimi-provider.md) |
| KMS agent tools (expose your vault to spawned Claude sessions) | Five read-only MCP tools — `kms_search`, `kms_read`, `kms_list_tags`, `kms_list_recent`, `kms_get_backlinks` — let every Claude Code session Omniscio spawns query your Markdown vault the same way the in-app editor does. Off by default at Settings → Workflow → Features → "Expose KMS vault to spawned agents" (gated by the parent KMS toggle). Hidden notes never surface; payload-capped at 100 KB per call with cursor pagination; cross-vault scope; zero API spend (local SQLite + per-session MCP subprocess via `ELECTRON_RUN_AS_NODE`); writes/deletes ship in a follow-up sub-PR behind an approval queue | [kms-agent-tools.md](kms-agent-tools.md) |
| KMS callout blocks (Obsidian-compatible admonitions in the editor) | 12 callout types (note, info, tip, warning, danger, todo, bug, example, quote, success, question, abstract) using Obsidian's `> [!type] Title` blockquote syntax, plus 14 aliases for vault portability. Each type has a distinct color and icon. Optional fold via `+`/`-` markers. Integrated into the toolbar overflow menu, slash commands (one per type), and the command palette (6 common types). Full markdown round-trip — unknown types and alias names are preserved, never rewritten. Plain DOM NodeView with editable content hole; transient fold state (no dirty doc). Dark mode + glass theme support via CSS `color-mix()` | [kms-callouts.md](kms-callouts.md) |
| KMS knowledge aggregation (periodic AI-curated session summary notes) | Periodic background pipeline (daily/weekly) that collects notable session outputs, scores them for notability (turns, cost, keywords), runs selective Haiku deep-dives on the top N, and writes one curated markdown summary note per project to `Agent Insights/` in the vault. Three-stage: Collect (free DB) → Deep-dive (selective AI, cost-capped) → Synthesize (one Haiku call). Off by default; gated by `nothariEnabled` + `nothariAggregationEnabled`; integer micro-USD cost cap (default $0.50); CLI: POST/GET `/kms/aggregation/{run,status,history,settings}`; IPC: `KMS_AGGREGATION_RUN_NOW/STATUS/HISTORY`. DB: `nothari_aggregation_runs` (migration 20260714003031). Worker lifecycle tied to KMS service start/stop via `createPeriodicTask` | [kms-knowledge-aggregation.md](kms-knowledge-aggregation.md) |
| KMS Obsidian Import Wizard (migrate an Obsidian vault into KMS) | Guided wizard at Settings → Features → KMS → Import from Obsidian. Copies `.md` files (preserving folder structure), content-addressed images (SHA-256 dedup via `importImageBytes`), and rewrites Obsidian `![[image.png]]` embeds to standard `![](assets/<sha>.ext)`. Skips `.obsidian/`, `.git/`, `.trash/`, `.canvas`, non-image attachments, >5 MB files. Name collisions auto-number. Cancellable mid-flight. Desktop-only. | [kms-obsidian-import.md](kms-obsidian-import.md) |
| KMS (the Vault) — notes, editor, search and sharing — part 2 | Part 2 of the KMS page: the editor itself — its toolbar and slash commands, how links, tables, footnotes, lists, headings and code are written and rendered, how the view behaves while you type and save, and what happens to an imported note that is not perfectly formed. | [kms-part-2.md](kms-part-2.md) |
| KMS (the Vault) — notes, editor, search and sharing — part 3 | Part 3 of the KMS page: how the vault looks and how you find a note in it — the colour and theme options, the sidebar you can hide, wiki-link autocomplete as you type, the unified search modal, and the quick-switcher for jumping straight to a note by name. | [kms-part-3.md](kms-part-3.md) |
| KMS (the Vault) — notes, editor, search and sharing — part 4 | Part 4 of the KMS page: images, media and the links that turn into something — how a picture is added, stored and displayed in a note, how attachments are kept from bloating the vault, and what happens when you paste a bare web address into a note. | [kms-part-4.md](kms-part-4.md) |
| KMS (the Vault) — notes, editor, search and sharing — part 5 | Part 5 of the KMS page: what the AI adds to the vault — the note summaries and agent tools, asking a question seeded from a note, keeping the vault loaded so it opens instantly, the standalone window, deep links to a note, and publishing one to a public web address. | [kms-part-5.md](kms-part-5.md) |
| KMS (the Vault) — notes, editor, search and sharing — part 6 | Part 6 of the KMS page: using the vault away from the desktop and under the hood — the mobile experience, what happens after a crash, what is deliberately not built yet, the command surface an agent or script calls, how the vault is put together, and what it promises about your notes. | [kms-part-6.md](kms-part-6.md) |
| KMS Quick Reference Wizard (first-time user walkthrough) | 7-step educational wizard that walks first-time KMS users through core concepts (notes, search, agent tools, Ask Vault, power features) and ends with interactive vault folder setup; auto-opens on first KMS enable (`nothariQuickReferenceCompleted`), replayable from Settings > Setup Wizards and Settings > Features > KMS, one-shot inbox alert for existing users (`kmsWizardAlertSeen`); completion state resettable via `PATCH /settings/nothariQuickReferenceCompleted` | [kms-quick-reference-wizard.md](kms-quick-reference-wizard.md) |
| KMS Session Seeds (multi-note briefing + project context notes) | Two ways to pre-load KMS notes into Claude sessions. **Multi-note briefing**: select 2-5 notes in the file tree, right-click → "Start briefing", optionally type a question, launch a session with every note's full body as context (20 KB/note, 80 KB total cap). **Project context notes**: pin 1-5 notes as standing context for a real project; every new session in that project automatically receives the pinned notes' current bodies via a content-matched SessionContextProvider. Living context — updated notes appear in the next session automatically. Gated by the KMS toggle; CLI CRUD at `/kms/project-context` | [kms-session-seeds.md](kms-session-seeds.md) |
| KMS note summaries (AI auto-summary + drift lifecycle + in-editor chip) | One-paragraph (≤300 char) AI summary embedded at the top of each note as a `<!-- kms:summary v=1 hash=… -->…<!-- /kms:summary -->` HTML-comment marker. Canonical-hash drift detection on save flips `current → stale` (content edit) or locks `user_edited` (you hand-edit the summary text or a future marker version). Opt-in periodic worker (off by default; Settings → Features: enable toggle + scan-interval + per-note-cooldown minute inputs, ms-backed, 1 min–24 h) regenerates stale-and-unlocked notes; concurrency 2 / 50-per-tick are fixed, not knobs. Per-account daily $ cap (default $2, range $0.50–$50, local-midnight, counts summary + bulk spend, fails open). Four IPCs live (`kms:generate-summary` with `force` bypassing the lock, `…get-summary-status` the only `cost-capped` reporter, `…clear-summary`, `…set-summary-user-edited`). **In-editor SummaryStatusChip** in the status bar's left slot surfaces all six states (Up to date / Stale / Locked / Generating / Budget reached / hidden when none); single-click on stale regenerates, click on any other state opens the chip menu, right-click always opens the menu; menu items are Regenerate now / Force regenerate (when locked, confirm-gated) / Mark or Unmark user-edited / Clear summary marker (confirm-gated) | [kms-summaries.md](kms-summaries.md) |
| KMS Vault Overview (searchable inventory table of every note) | A searchable, sortable table of every visible note in the active vault — title, tags, AI summary state + text (decoded from the body HEAD only, never a full read), token estimate (`ceil(body_bytes / 4)`), byte size, updated-at. Opened from the KMS toolbar and command palette; gated by `nothariOverviewEnabled` (default on). Backed by the same `inventory-core.ts` shared query that powers the `kms_inventory` MCP agent tool (paginated, default 100 / max 500 rows per page, cursor-based, cross-vault, zero API spend). The Overview never generates summaries — it only surfaces those already present. | [kms-vault-overview.md](kms-vault-overview.md) |
| KMS Web Clipper (clip web pages & screenshots to the Vault) | Clip any web page by URL — or a screenshot by OCR — into the Vault's Web Clips/ folder as a clean Markdown note with YAML frontmatter (source URL, timestamp, tags). Pages are fetched and extracted with Mozilla Readability then converted to Markdown; screenshots use Anthropic vision OCR (a small per-clip API cost). Shipped. | [kms-web-clipper.md](kms-web-clipper.md) |
| KMS (Markdown vault editor + images — Phase 5) | Point Omniscio at a folder of `.md` notes ("vault"), the indexer parses every file once, a chokidar watcher reacts to on-disk changes, and an in-app TipTap-based editor with autosave / tabs / find-replace / source view / wiki-link autocomplete owns the panel. **Phase 5 adds images**: paste / drop / picker import, content-addressed dedup under `<vaultRoot>/assets/<sha256>.<ext>`, Gallery panel + Lightbox, AI-derived per-image title / description / OCR / tags / category, FTS5 image search via the Unified Search modal's `kind:image` chip. Off by default at Settings → Features; single vault root via `nothariVaultRootPath`; watcher ignore-list (`.git/`, `.kms/`, `.trash/`, `assets/`, non-`.md`) and path validation are hard-coded; soft-delete moves notes to `.trash/` | [kms.md](kms.md) |
| Language Support (UI language picker + 17 pilot languages) | Switch Omniscio's UI language in Settings → Appearance → Language. English ships complete; 17 pilot languages (Spanish, Tagalog, Traditional Chinese, Cebuano, Ilocano, Hiligaynon, Waray, Bikol, Kapampangan, Pangasinan, Indonesian, Serbian, Hindi, Urdu, Romanian, Hungarian, Turkish) appear in the picker once their Lab toggle is on AND the catalog passes the 90% coverage gate (a half-translated language never surfaces). AI replies are independent of the UI language — agents auto-match the language you write in, and the TTS voice follows. Registry ids `language-setting` + `<name>-pilot`; catalogs in `resources/locales/` | [language-support.md](language-support.md) |
| Lazy content load (instant cold-mount + truly lazy Actions widget) | Cold-mount on any session paints in a few hundred ms regardless of message count — the SELECT no longer projects the full `content` column, lite shape carries a stripped `summary_prose` instead; per-turn "Actions" pill content is fetched on first click via `SESSION_GET_TURN_CONTENT` IPC, released on close. Function-pair `getSessionHistoryLite()` (not a flag) lets the TypeScript compiler enforce per-call-site consumption; export / share / audit / FTS keep using full `getSessionHistory`. Desktop AND mobile safe. Kill switch: `AMC_DISABLE_LITE_COLD_MOUNT=1` | [lazy-content-load.md](lazy-content-load.md) |
| Lean hidden panels (keep chat responsive under heavy load) | Hidden background session panels that aren't pre-warmed render as a **subscription-free placeholder** so they stop reacting to every other session's streaming output — keeps scrolling smooth and the chat landing in the right place when 40+ sessions are open (the per-update cost stops growing with session count). The active session, pinned "Needs You" inbox panels, and recently-viewed frozen panels stay fully built. On by default; **Settings &rarr; Performance &rarr; "Keep chat responsive under heavy load"**. Two gates — the setting plus env kill switch `AMC_DISABLE_LEAN_HIDDEN_PANELS=1` (kill switch wins); OFF is byte-for-byte the pre-feature renderer (every hidden panel mounts in full). | [lean-hidden-panels.md](lean-hidden-panels.md) |
| Life Inventory (AI Coaching 1-to-5 self-assessment) | Two bundled inventories inside AI Coaching (Symptoms 942 items / 12 categories, Strengths 1246 / 16, rated 1-5 with inventory-specific words). Stored locally per re-takeable "take" (`life_inventory_takes` / `life_inventory_ratings`); re-takes pre-fill from the last completed take. A small labeled summary (~800 chars) rides in every regular session's profile — i.e. it is part of the prompt sent to the model provider on a first-party Anthropic lane, in any project, with no per-session opt-out short of turning AI Coaching off — and full detail is written to `~/Claude/ai-coaching/life-inventory.md` for coaching sessions to open on demand. Keyboard-first take flow (ported from the original source app): one focused item at a time — **1-5** rates it and auto-advances to the next unanswered (and to the next sub-category page when one completes), **↑/↓** move focus, and the focused card auto-scrolls into view; one sub-category per page, ARIA. No AI calls of its own (zero cost); ratings stored locally, but the short summary IS transmitted in the session prompt. Shipped (on by default within AI Coaching; previously gated behind `lifeInventoryEnabled`). | [life-inventory.md](life-inventory.md) |
| Linear | Experimental Linear integration — a "Linear" sidebar board (teams → workflow-state columns → issue cards), connect via personal API key, GraphQL client, plus a "linear-inbox" assigned-issues source. | [linear-board.md](linear-board.md) |
| Link hover web-title preview (hover a chat link → see the page title) | Hover any external `http`/`https` link in an agent reply to see the web page's title (article headline / repo name) instead of the bare URL — fetched once when the pointer dwells, the domain shown while it loads, cached per-URL; failure shows just the domain. Desktop-only (no hover on touch ⇒ zero mobile web requests). Fetched in Main through the SSRF-safe redirect-aware fetch (blocks private/loopback/metadata + DNS-rebinding, http/https only, 8 s + ~100 KB caps); the title extractor is linear/ReDoS-safe and renders as inert plain text. The first link of a reply still also shows the Ctrl+Shift+Q "open first link" hint. | [link-hover-title.md](link-hover-title.md) |
| Lite mode (optimize Omniscio for a less powerful computer) | One Settings → Performance switch that makes Omniscio lighter on low-spec machines by flipping a bundle of existing, individually-tested perf settings at once: Low Power Mode on, stop keeping/pre-building extra chats in memory, stagger session loading at startup, hold new sessions when memory is low, reclaim idle-session RAM (Windows). Off by default; fully reversible (snapshots prior values when turned on, restores them on off — it WRITES the real settings, not a computed master). Both weak-hardware inbox cards (weak graphics, and below recommended specs) carry a one-click "Turn on Lite mode" button, shown once per install (an offer, never an auto-apply). | [lite-mode.md](lite-mode.md) |
| LMS (Courses — HR dashboard, course/lesson editor, learner surfaces, Docebo import) | Wave 1 courses platform shipping as an **in-repo plugin webview** (`src/plugins/lms/`). Author + teach + learn: HR-manager Dashboard rolls up totals + active courses + AI insights; Course editor drags modules + adds doc/quiz lessons + generates an AI outline; Lesson editor writes markdown docs + multi-choice quizzes; Learner Home + Lesson viewer + Progress + Certificate PDF; Docebo Import wizard (Pick source → Preview + select → AI review → Import progress) with polling status. Backend + services stay in `src/main/services/lms/**` and reach the plugin via one `handleLmsBridgeCall` dispatcher (33 methods). CLI routes under `/lms/*` for agent access. Feature gate is the plugin's install-and-enable — no separate flag. Wave 2 wires push subscribers, active-account credentials for AI outline + Docebo AI review, and hardened OAuth + LinkedIn URL bridges. | [lms.md](lms.md) |
| Local Chat (chat with a local model via Ollama) | A gated "Chat" area to converse with an AI model running locally on your PC via Ollama — free, private, offline, no API key or account. A first-run wizard detects Ollama (one-click Download if missing), scans your RAM to recommend a model (✅ runs great / ⚠️ slow / 🚫 too big), downloads it with a progress bar, then drops you into a streaming chat with saved, renamable conversations. Plain-text only; no tools or file access (that's what coding sessions are for); never silently falls back to a paid cloud model. In-development — reveal via Settings → Lab toggle or `AMC_SHOW_LOCAL_CHAT=1`. | [local-chat.md](local-chat.md) |
| Logs & Debugging | Where logs live on disk, the in-app Debug Log Viewer, exporting logs + crash dumps for support; **Settings -> Diagnostics -> Running build** answers which code is actually running (branch / short commit / build time, baked in at build time, `Unknown` when the build has no git identity - the version number cannot answer this, and a dev install has its bundle drift behind its checkout); the same values ride in every bug report; **attach the conversation transcript to a bug report** (opt-in tick-box in the feedback dialog, off unless ticked, per-report — the right evidence for a missing/wrong agent reply because it is built from stored message text and bypasses the display fold); **automatic crash reporting** (auto-send-every-crash by email + Sentry, on by default independent of telemetry, catches live JS / native / silent-death crashes via the heartbeat sentinel, scrubbed payloads, `crashAutoSendEnabled` toggle + `AMC_DISABLE_CRASH_AUTOSEND=1` kill-switch + 15/day cap) | [logs-and-debugging.md](logs-and-debugging.md) |
| Low Power Mode (inbox notice + effect kills) | Settings → Performance toggle (default off) that trims GPU-expensive effects — backdrop blur, decorative shadows/hover-lift, and the visual-theme animated blurred background blobs (the soft static gradient stays) — and slows idle/streaming re-renders, while keeping a clean attractive look. Turned on by the user — the one-click "Make Omniscio lighter" weak-hardware offer (the Lite mode preset) or the Settings toggle — never silently auto-enabled. A persistent dismissible inbox notice with a "Restore full effects" action is raised/cleared on the lowPowerMode transition (any path that flips it); never re-nags on boot. Also applied as software-render safe mode. | [low-power-mode.md](low-power-mode.md) |
| Machine Migration (move Omniscio to a new computer) | How to migrate Omniscio to a new machine, new computer, new desktop, or new laptop — or recover after a hard drive failure, SSD death, or fresh OS install. Covers all three backup/restore paths: **Backup Mirror** (recommended — encrypted full-state snapshot including conversations, attachments, and settings), **Export/Import** (manual ZIP fallback when no mirror exists), and **Setup Backup to Gmail** (configuration-only, no chats). Step-by-step for both source-machine setup and target-machine restore. Explains Replace vs Merge mode, what transfers and what doesn't (API keys/OAuth are OS-bound and must be re-entered), transcript-injection resume for restored sessions, and troubleshooting (wrong passphrase, schema mismatch, missing credentials). Also covers the broader development environment: **drive letter mappings** (Dev Drive, worktree drive, `worktree-locations.json`), **external CLI toolchain** (auto-installable vs manual-install tools, plus reinstalling your own CLIs), **re-authentication checklist** (GitHub CLI, gcloud, gws, gogcli, MCP server secrets, SSH remotes, cron env vars), **gogcli special handling** (OAuth credentials can't be re-downloaded), **Claude Code files that don't transfer** (`settings.json`, `skills/`, `scripts/`, `secrets/`, `amc-repo.path`), and a **post-migration environment checklist**. Start here when you hear: migrate, migration, new computer, new machine, transfer data, move to another computer, switch machines, disaster recovery, backup restore, fresh install, dev drive, drive letter, toolchain, re-authenticate, gogcli, CLI tools, environment setup, drive mapping | [machine-migration.md](machine-migration.md) |
| macOS permissions (what Omniscio asks the Mac for, and the repeating "prevented from modifying apps" notification) | Reference for every macOS privacy prompt Omniscio can produce and what each is actually for. All are opt-in and requested AT POINT OF USE, never at startup. Two things it settles for worried users: Omniscio has **no system-volume code at all** (the fear comes from macOS's Automation prompt, which can only grant control of System Events as a whole — the general scripting gateway — even though Omniscio uses it for just three narrow jobs: paste dictated text, read the frontmost window title, open a Terminal); and **Bluetooth is no longer declared** (it was inherited framework boilerplate with zero call sites, now deleted and guard-locked). Separately documents the repeating **App Management** notification — the only macOS permission that reports a denial as a passive notification with no dialog and no reason. macOS blames the app that STARTED a command, so a command Omniscio runs for you (installing a tool, cleaning a build folder) is reported against Omniscio even though it never touched the file. Omniscio never modifies other apps and never requests App Management; instead Settings → Diagnostics → "Blocked by macOS App Management" reads the macOS privacy log and names the exact app, command and path that was blocked. Nothing is ever changed by a block. Contract: macos-permission-surface-contract. | [macos-permissions.md](macos-permissions.md) |
| Main-process heartbeat (silent-crash forensic trail) | `heartbeat.log` — 5-second-tick tape of event-loop lag + RSS/heap + last IPC op + active-resource counts; sibling `heartbeat-final.log` holds `[FATAL]` exceptions and the next launch writes `[POST-MORTEM]` markers (with Windows Event Log scrape) when the previous run ended without a `[CLEAN-EXIT]`/`[GOODBYE]` pair; reveal button at Settings → Diagnostics → Main-Process Heartbeat; kill switch `AMC_DISABLE_MAIN_HEARTBEAT=1` or `mainHeartbeatEnabled: false` in config.json | [main-heartbeat.md](main-heartbeat.md) |
| Claude Code extensions (all optional, not installed at setup) | Both extensions now OPTIONAL — nothing force-installed; onboarding + nag banner retired; one-time dismissible card lets existing users uninstall Superpowers for the built-in Dev Pipeline | [mandatory-claude-extensions.md](mandatory-claude-extensions.md) |
| Export to Word / PDF (Markdown → .docx / .pdf) | One **Export…** menu turns any Omniscio Markdown into a **Word (.docx)** or **PDF** file saved to disk, and folds in the existing **Publish online** (Omniscio Shares link) + **Export to Google Docs** actions. Appears wherever Markdown is exportable — agent chat messages (`⋯` menu), `.md` file previews, project docs, scratchpads, chat file-links — plus **Export to Word/PDF** for a whole conversation in the session `⋯` → **Exports** submenu, and a standalone **Quick Launch → Export File** tab that exports ANY `.md` on disk. Word/PDF are free, local, always-on (no setting, no account). One sanitized-HTML intermediate feeds both formats — PDF via Electron `printToPDF` on a hidden sandboxed window, Word via `@turbodocx/html-to-docx`; all conversion runs main-process only, never in the renderer bundle. | [markdown-doc-export.md](markdown-doc-export.md) |
| Master-Debt Auto-Fixer (fix pre-existing master-branch debt, unreleased) | In-development: when a session's ready-to-merge run finds check failures that already exist on `master` (debt, not the branch's fault), Omniscio handles them per file — it dedups, holds an on-disk claim, and either drops ONE inbox approval card per failing file ("ask first", the default) or — when you turn auto-fix on — spawns ONE paid background fixer session per file. The fixer is briefed to root-cause the failure and is FORBIDDEN to weaken the check (no `.skip`/delete/relax). Bounded so it can't run away: one fixer per file, ≤3 in flight, ≤3 attempts then it asks a human, crash orphans released. A markdown tracker + JSON ledger live in `~/.amc`. Intake via `POST /master-debt/triage` (feature-gated, Omniscio-internal). Off by default — reveal via Settings → Lab toggle or `AMC_SHOW_MASTER_DEBT_AUTO_FIXER=1`. | [master-debt-auto-fixer.md](master-debt-auto-fixer.md) |
| Mission Control automations (act when a board changes) | The automation layer for Mission Control boards — an event-driven engine that fires a chain of actions whenever board data changes, plus a channel bridge for cross-system automations and workflow-engine integration. The sync service snapshots board state before each sync and diffs after, so automations run off real changes. | [mc-automations.md](mc-automations.md) |
| MC Chat Bot (Mission Control → Team Chat bridge) | A bot that posts Mission Control project-health alerts (at-risk items, cascading delays, pattern detections, health drops, periodic digests) into a designated Team Chat channel. Configurable severity threshold (info/warning/critical, default warning) and mode (event-driven, digest, or both). Off by default; set up in Settings → Team & Admin → MC Chat Bot (`mcChatBotEnabled`, `mcChatBotChannelId`, `mcChatBotMode`, `mcChatBotSeverityThreshold`). Feature registry: `mc_chat_bot`. | [mc-chat-bot.md](mc-chat-bot.md) |
| Mission Control dashboards (roll several boards into one view) | A workspace dashboard that aggregates data across multiple boards into one drag-and-resize grid: Numbers tiles, charts (bar / column / pie / donut / line) and three sprint widgets (Velocity, Planned-vs-unplanned, Burndown). Every widget is computed client-side from already-loaded board data, and a board id from another account simply 404s rather than leaking anything. | [mc-dashboards.md](mc-dashboards.md) |
| Mission Control templates (reuse a board’s structure) | Save a board’s whole structure as a reusable template — right-click a board, “Save as template”, choose shared or private and whether to include items — then deploy it into new boards from the Template Category Picker. | [mc-templates.md](mc-templates.md) |
| MCP Overhead (MCP server token/RAM/unused-server watchdog) | Amber inbox card fires when the GLOBAL MCP configuration crosses an overhead limit — estimated tool-definition tokens (labeled an estimate; servers are never started), measured active-session MCP RAM (best-effort, skipped when no session is live), or the count of configured-but-unused servers (zero tool calls in the usage window). Any enabled leg trips it; a limit of 0 disables that leg. One inbox card (per-server breakdown, Archive, Manage MCP servers, Start session) + universal snooze; one global rule (no per-project) with tunable limits + tiered re-alert at Settings → Notifications → MCP Overhead. | [mcp-bloat-alert.md](mcp-bloat-alert.md) |
| MCP Servers (manager + per-project/session control + usage tracking) | Sidebar virtual project: **+ Custom** manager to add/edit/delete your own MCP servers (stdio or remote, secrets encrypted at rest, off-by-default); a **browse-and-install catalog** of 80+ official remote servers (the Hermes Agent set plus independently vendor-verified additions — GitHub/HubSpot/Firecrawl/Perplexity/PagerDuty/Box/Zoom/… — opt-in, nothing added until you click Install, vendor-verified URLs, installs via the standard add path; full list in `src/shared/mcp-install-catalog.ts`); **per-project/per-session control** — each server resolves session→project→global (Edit Project → MCP servers; session ⋯ → MCP servers; Settings = default for all sessions), credential-safety clamp always wins, custom + the 4 composed built-ins controllable, Drive/Mobbin stay global; plus per-server **usage** (count/last-used/tool breakdown, sort Most/Least/Never, reset/clear). Resolver `mcp-selection.ts`; orchestrator composes per-session `.mcp.json`; contract `mcp-server-control-contract.md` | [mcp-servers.md](mcp-servers.md) |
| Markdown merge driver (auto-resolves append-only memory-doc conflicts) | A custom Git merge driver that auto-resolves the most common merge conflict in this repo — two agents independently appending to the same memory document — by unioning purely-additive changes; it declines and falls back to normal conflict markers for anything else (a deletion, an edit, a frontmatter change). Developer/repo-maintenance infrastructure — no UI, no setting, runs automatically inside `git merge`. | [md-merge-driver.md](md-merge-driver.md) |
| Media link open (mp3 / mp4 / pdf → default OS player) | Click a markdown link an agent wrote to a binary media file (mp3, mp4, pdf, zip, exe…) or HTML file and Omniscio hands it to your OS default app via `shell.openPath`; images still go to the in-app Peek Viewer; failure surfaces as a red `Couldn't open <filename>: <error>` toast | [media-link-open.md](media-link-open.md) |
| Meeting Rooms (speed-dial for video conferencing links) | Store recurring meeting URLs across platforms (Zoom, Google Meet, Teams, Skype, Webex, Other) and personal room links, launch with one click or Ctrl+Shift+Z palette — local-only, no API; sidebar virtual project; categories, personal-room badges, platform auto-detection + badges, recency-sorted palette, `shell.openExternal()` launcher | [meeting-rooms.md](meeting-rooms.md) |
| Meetings | Experimental, in-development Meetings integration — a "Meetings" sidebar tab for browsing and working with meeting notes inside Omniscio. Hidden by default (gated via the unreleased-feature registry, id `meetings`); still being built out. | [meetings.md](meetings.md) |
| Computer feels slow? (free-first troubleshooting guide for a slow computer) | Plain-English, do-this-in-order guide for when your computer feels slow while running Omniscio — ordered cheapest-first, with buying new hardware as the very last resort. Step 0 is a **read-only AI scan** (the Windows **First Mission** health-check, or a paste-in prompt + `Get-`-only PowerShell) — or the in-app **Resources** monitor (Settings → Tools & Maintenance → Diagnostics → Resources), a live per-process CPU/RAM view. **Tier 1** = instant Settings → Performance toggles (`Lite mode`, reserve + dedicate a CPU core, `Real-conversation layout`, release idle sessions, `Low Power Mode`, hold-new-sessions-when-low). **Tier 2** = restart Omniscio, bulk-stop unused sessions, sweep abandoned worktrees (auto-swept on a schedule via the Dev Pipeline Setup tab), compact Omniscio's own bloated database (Settings → Diagnostics → "Reclaim disk space"), and an optional fenced **Advanced Windows** cleanup (Defender/backup exclusions, a **Dev Drive** for heavy file activity (and the **Windows file-cache balloon** it can trigger on ReFS — available RAM low while your apps aren't, cleared by a restart or an agent-set system-file-cache cap), moving Omniscio's data folder to a quieter drive via `DATA_DIR` when only Omniscio is slow during heavy disk work, cap the pagefile, raise the desktop heap — admin, or let your agent do it). **Tier 3** (developers) = run heavy builds/tests off-hours via Recipes + Cron, or offload them to the cloud (`--cloud`). **Tier 4** = more RAM (RAM beats CPU; e.g. 64→128 GB). Core idea: ~90% of slowness is **RAM exhaustion → disk swap-thrash**, not "too many sessions" — the two non-RAM exceptions being a **stuck Windows background service** (whesvc/webthreatdefsvc spinning in the kernel with RAM free) and a **spawn storm** (a burst of short-lived processes created in one instant floods the scheduler — caught by turning on process-creation/Event-4688 auditing and grouping the burst by parent, fixed by pacing job starts), each with its own detection + fix section. Written for both the user and an AI agent to follow; reminds the reader that settings apply live but app fixes need a restart.\|[slow-computer.md](slow-computer.md)\|\|Memory reclaim (free up RAM automatically when your computer runs low)\|Pressure-triggered RAM reclamation with two levels. **Tier 1** (on by default, safe, Windows-effect): when your computer's free memory stays below a threshold (default 15%), Omniscio trims the working sets of its OWN idle sessions — never a session that's mid-reply or waiting on you — via the same safe primitive the working-set-trim scheduler uses; no admin, no effect on macOS/Linux. **Tier 2** (opt-in, hidden/in-development, Windows only): a system-wide reclaim (empty every process's working set + purge the standby list) run through a one-time-admin-consented scheduled task whose reclaim command is embedded inline (no user-editable elevated script). One shared trigger — sustained low free memory with hysteresis + cool-down so it never thrashes. Settings → Performance (Tier 1 toggle + % threshold); Tier 2 via Settings → Lab / `AMC_SHOW_MEMORY_RECLAIM_ADVANCED=1`. | [memory-reclaim.md](memory-reclaim.md) |
| MemPalace — persistent cross-session memory | Agents remember things across sessions via 6 MCP tools; browse the memory palace in a 3-pane UI | [mempalace-memory.md](mempalace-memory.md) |
| Merge-tooling approval card (approve the code the app merges with) | The one inbox approval card behind the merge tooling: the small helper programs the app runs while it merges your finished branches. Those programs come from your project, and they used to run straight from whatever happened to be on disk, so an edit to one became code the app executed on the very next merge with nobody checking it. The app now runs that tooling only from a version a **person** approved, and this card is how a newer version gets approved. It appears **only when the tooling actually changed**, so ordinary merges never show it. The card names the project (never a folder path) and lists the files that changed and the commits that changed them; it deliberately does not show a long commit id. **Approve** switches merges to the newer version; **Decline** keeps the version you last approved and that exact version is not asked about again, and nothing is lost either way. **While a card is waiting, merges keep using the last version you approved**, so a waiting card never runs anything new and never blocks your work. Only a person can answer it, and no agent route or setting can. To stop being asked, use the card's **Always allow** option (the small arrow beside Approve, then Everywhere): later cards then approve themselves, and Settings → CLI Control → Always-allowed actions undoes it. Contract: approved-merge-tooling. | [merge-tooling-approval.md](merge-tooling-approval.md) |
| Mermaid diagrams (render diagrams in chat) | A ```mermaid fenced block in a chat message renders as an actual diagram (flowchart / sequence / state / class / etc.) instead of raw text — theme-matched, horizontally scrollable, with a hover view-source toggle + copy. While a reply is still streaming it shows the source and draws the diagram once the turn settles; a broken or oversized diagram falls back to the source text so nothing is lost. Untrusted-safe: rendered in mermaid `strict` mode AND SVG-sanitized before display. The same shared `MermaidDiagram` engine also draws the file-explorer `.mmd` preview and the Mind Map "View as Mermaid" panel. Always on; no setting. | [mermaid-diagrams.md](mermaid-diagrams.md) |
| Message image carousel (3+ images in a reply become a swipeable carousel) | When an AI reply embeds **3 or more consecutive** images (e.g. full-page screenshots of "N versions"), they collapse into ONE swipeable/clickable **carousel** — one image at a time with a corner **count** (`3 / 12`) — instead of a tall scroll-through stack. **Phone:** swipe through them, and the swipe stays inside the carousel (it never flips your session the way a normal side-swipe does); **desktop:** ‹/› arrow buttons (greyed at the ends); either way **tap to open full-screen** in the existing image viewer. A run of **1–2** images, images **separated by text**, and images **nested in a list** stay inline; the small attachment thumbnails under a message and **Team Chat** are unaffected. **Display-only** (copy/export keep the original), a fixed-height `object-contain` frame so paging between different sizes doesn't jump, **no autoplay**, honors reduce-motion. Grouped by a rehype plugin ([rehype-group-images.ts](../../src/renderer/src/lib/rehype-group-images.ts), threshold `CAROUSEL_MIN_IMAGES` = 3) into an `amc-image-carousel` element rendered by [MessageImageCarousel.tsx](../../src/renderer/src/components/ui/MessageImageCarousel.tsx), which **stops touch propagation** so `useSwipeNavigation` never fires inside it. Always on; no setting. Contract: message-image-carousel-contract. | [message-image-carousel.md](message-image-carousel.md) |
| Meta provider (Anthropic-compat API, Muse Spark) | Spawn Claude-Code-style sessions backed by Meta's Muse Spark Anthropic-compatible API (hosted at the BARE HOST `api.meta.ai`) alongside `claude`, `codex`, `gemini`, `antigravity`, `deepseek`, `kimi`, `glm`, and `minimax` — gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via Settings → Account Meta API key + "Allow Meta sessions" toggle. **No binary check** — reuses the standard `claude` CLI; routing happens via spawn-env (`ANTHROPIC_BASE_URL=https://api.meta.ai` — the ONE bare-host base, no `/anthropic`; the CLI appends `/v1/messages` — plus `ANTHROPIC_AUTH_TOKEN=<vendor key>`); a 4-id picker (`muse-spark-1.3` — the default, tracking the current flagship — plus `1.2` / `1.1` at $1.25/$4.25 per M with a $0.15/M cache read, re-priced from tokens, and the cut-price `-contributor` tier, which Meta may train on and which therefore runs ONLY on your own Meta key — Meta's supply list never sends it to its Omniscio credits row, and with no own key that can serve it is refused by name before launch); who pays is Meta's supply list (Settings → Accounts → Who pays & who serves — your own key and/or Omniscio credits); 2 readiness gaps (`toggle-off`, `key-missing`); identical tool-approval UX to Claude (no yolo mode) | [meta-provider.md](meta-provider.md) |
| Mind Map — notes, layers, AI and the internals (part 2) | The second half of the Mind Map page: hidden notes attached to a node, drilling into a layer behind one, themes and layout, importing, exporting and sharing a map, the two AI features (which cost money), how a map behaves under your finger on a phone, and what is still rough. | [mindmap-part-2.md](mindmap-part-2.md) |
| Mind Map (mind-mapping canvas, in development) | In-development standalone mind-mapping canvas (gated, `mindmapEnabled` default OFF, or `AMC_SHOW_MINDMAP=1`; toggle in Settings → Features), opened from the toolbar — docked in the shell by default with a full-screen toggle. Build a single-rooted tree of text ideas edited by keyboard (Tab child / Enter sibling / outliner Enter / arrows / cut-copy-paste / undo) and mouse (hold-to-commit drag to reorder, re-parent, or two-side the root), auto-laid-out by d3-hierarchy in four flow directions. Saved-maps library with debounced autosave + auto-title, a per-row right-click / long-press menu (Rename / Delete, confirmation-gated) and title search; per-map color mode / visual theme / flow direction; inline-markdown labels; import/export JSON, Markdown outline, and Mermaid (read-only preview); PNG; an interactive XSS-safe read-only Share page (frozen content snapshot); AI expand-node / generate-map (Haiku, API-key account, default $1/day cap); hidden per-node notes/annotations (a note icon + hover-peek + click-to-edit box, the `n` hotkey, right-click + mobile "Add/Edit note", AI-writable via `PATCH /mindmaps/:id/nodes/:nodeId`); mobile touch action bar + bottom-sheet drawer. 2000-node cap. | [mindmap.md](mindmap.md) |
| MiniMax provider (Anthropic-compat API) | Spawn Claude-Code-style sessions backed by MiniMax's Anthropic-compatible API (hosted at `api.minimax.io`) alongside `claude`, `codex`, `gemini`, `antigravity`, `deepseek`, `kimi`, and `glm` — gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via Settings → Account MiniMax API key + "Allow MiniMax sessions" toggle — or no key at all, paying with Omniscio credits through MiniMax's supply list (Settings → Accounts → Who pays & who serves), which also decides whether DeepInfra serves MiniMax M3 / M2.5. **No binary check** — reuses the standard `claude` CLI; routing happens via spawn-env (`ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic` + `ANTHROPIC_AUTH_TOKEN=<vendor key>`); default model `MiniMax-M3` (switchable M3/M2.7/M2.5/M2); 2 readiness gaps (`toggle-off`, `key-missing`); identical tool-approval UX to Claude (no yolo mode) | [minimax-provider.md](minimax-provider.md) |
| Mission Control — the table, the views and the board (part 2) | Part 2 of the Mission Control page: the Main Table and everything you can do to it — filters, grouping, the alternate views over the same items, the Kanban board's card actions, colouring and swimlanes, finding a teammate, and the per-board preferences you can set. | [mission-control-part-2.md](mission-control-part-2.md) |
| Mission Control — workspaces, people and publishing (part 3) | Part 3 of the Mission Control page: workspace membership and accounts, sharing a board or inviting someone into a workspace, the permissions and trust controls around them, and the strategic layer above a board — goals, portfolios, and publishing work to a public web address. | [mission-control-part-3.md](mission-control-part-3.md) |
| Mission Control — templates, calendars, meetings and notifications (part 4) | Part 4 of the Mission Control page: how boards connect to the rest of the app and to the world outside it — board and recipe templates, the calendar overlay, session linking, the meeting bridge, voice actions, search and knowledge, outbound webhooks, and the notification intelligence that decides what is worth telling you. | [mission-control-part-4.md](mission-control-part-4.md) |
| Mission Control — automation and the internals (part 5) | Part 5 of the Mission Control page, for anyone working on it: the board automation engine and the events it fires on, the bridge that lets the app's own automation react to a board event, the workflow-engine nodes that poll a board, where the local data mirror lives, and the command surface an agent or script drives. | [mission-control-part-5.md](mission-control-part-5.md) |
| Mission Control (the built-in project-management system — boards, views, dashboards) | Omniscio's built-in **project management system**, an isolated React sub-app surfaced as a sidebar virtual project (gated on `missionControlEnabled`): the typed-EAV **Main Table**, nine addable alternate **views** (Kanban, Cards, Calendar, Chart, Timeline/Gantt, Roadmap, Form, Workload, Map), the item card + Updates feed, drag-and-drop reorder, batch actions, cross-board surfaces (**Search Everything**, **My Work**, **Notifications**, **Dashboards**, **Activity log**), and the automations engine. The canonical overview doc for how Mission Control works end to end. | [mission-control.md](mission-control.md) |
| Missions Hub (chat-first "do-it-for-me" agents) | A permanent top-level toolbar surface (WandSparkles **Missions** button) — a full-page gallery of guided missions where **Start** launches each as a chat session the user lands in (reuses `launchSession(source)`), no bespoke per-mission UI. Lists `visibleMissionsForPlatform` (host platform ∩ feature-gated). Includes the NEW **Inbox Concierge** (`inbox-concierge`) Gmail-cleanup mission: it checks/connects Gmail, then clears the inbox one sender at a time, reversible. Separate from the retired onboarding mission surfaces; the standalone Email Cleanup sidebar panel is retired in its favor (the engine + the in-Gmail button are unchanged). Keywords: missions, missions hub, do it for me, agentic missions, inbox concierge, clean up my inbox, guided mission, start a mission. | [missions-hub.md](missions-hub.md) |
| Mobbin MCP (real-world design inspiration) | Connects Claude to Mobbin — a searchable library of real-world app screenshots, user flows, and UI patterns — so Design Overhaul (and any recipe that asks) can ground its work in shipped designs instead of a generic AI aesthetic. Off by default at Settings → Sessions; one-time inline cookie-paste auth (paste your mobbin.com cookie, no browser popup, no spawned session), works with free or Pro Mobbin accounts; registers the npm `mobbin-mcp` server at Claude Code user scope. The Design Overhaul recipe’s first step researches Mobbin and skips gracefully if it is unavailable | [mobbin.md](mobbin.md) |
| Mobile back gesture (back steps back, doesn't exit the app) | On the installed mobile app, the phone's Back gesture (Android system Back; iOS 16.4+ standalone edge-swipe) steps back one screen INSIDE Omniscio instead of closing the app — an open Search / file preview closes first, a secondary page (Help/Archive) returns to the dashboard, then the projects→sessions→session drill-down unwinds one level at a time (a hub opened in place from an alert, like its Open Settings, is undone first, back to that alert); only a final Back at the top (projects list) exits. One shared history owner + one listener (a second hand-rolled listener can't double-fire). Desktop unaffected; no setting. | [mobile-back-gesture.md](mobile-back-gesture.md) |
| Instant new session on mobile (create-on-send) | On a phone, tapping **New Session** paints an empty composer **instantly** — no session is created and no Claude process starts until you send your first message, so a fast burst of taps is always instant and never falls back to a several-second spawn. Replaces the older mobile approach that pre-created a real blank per tap (which could miss and go slow on a quick second tap, an Inbox tap, or a non-Claude project). Desktop is unchanged — Ctrl+T keeps its own pre-warm fast path. | [mobile-create-on-send.md](mobile-create-on-send.md) |
| Mobile device tracking (protect your pairing token) | Remembers which devices use your Mobile Access pairing token: **trusts your first device silently** and raises an inbox alert ("A new iPhone just connected…" + a one-click **Review device**) the moment a NEW/unrecognized device connects, so a leaked token is caught. A **Devices** card in Settings → Remote Access lists each device (type, first/last seen, network) with **Trust / Rename / Block**. **Block** refuses one device at connect (both the in-main and off-loop transports) without rotating the token and kicking everyone; **Regenerate token** stays the full kill-switch. Identity = a server-assigned HttpOnly `amc_device_id` cookie (not phone-supplied; survives Wi-Fi↔cellular), with a UA+token fingerprint fallback for cookie-less clients. Inbox-only (no phone push). Detection is fail-open (never blocks/slows a connection). Honest limit: detection not prevention — defends a leaked token, not full browser-session theft. The four management channels are Zod-validated, have headless CLI routes, and are blocked from the phone bridge (desktop-only); an agent's CLI approve/trust only raises the device's inbox card and unblock is refused — only your click grants. Contract: web-access-device-tracking-contract. | [mobile-device-tracking.md](mobile-device-tracking.md) |
| Mobile multi-select (long-press sessions) | Long-press a session row 500ms on mobile to enter selection mode, tap more rows to add/remove, then run Snooze / Pause / Archive from the action bar that replaces the tab bar; mobile-only, sessions-only, scroll cancels the press | [mobile-multi-select.md](mobile-multi-select.md) |
| Mobile network priority (phone traffic before other managed internet work) | Active authenticated phone traffic receives Omniscio's highest cooperative network-admission priority. Phone work starts immediately; ordinary interactive work yields for at most 150 ms and background work for at most 2 seconds while the phone is active. Recent activity opens a 15-second priority window and disconnect keeps a 10-second reconnect grace period. Always on, bounded, and non-destructive: it delays only new Omniscio-managed starts, never cancels in-flight work and does not claim operating-system packet scheduling or control over third-party webviews and external-process sockets. | [mobile-network-priority.md](mobile-network-priority.md) |
| Mobile Perf Regression Prevention | Three-layer safety net — `predev` auto-rebuild + watcher keeps `out/renderer/` fresh during `npm run dev`, CI bundle-budget gate blocks PRs that grow the renderer, rolling-window alert fires when real phone load times regress (median totalMs > 3500 ms) | [mobile-perf-prevention.md](mobile-perf-prevention.md) |
| Mobile Access — staying connected (part 2) | Part 2 of the Mobile Access page: what the phone shows when the connection is poor and how it recovers — the offline and reconnecting indicators, how fast a page resumes, the recovery that runs when the app looks stuck, the transport that survives a freeze, signing in on a phone, and the settings behind it all. | [mobile-remote-access-part-2.md](mobile-remote-access-part-2.md) |
| Mobile Access — when something is wrong (part 3) | Part 3 of the Mobile Access page: the troubleshooting walkthrough for a phone connection that will not behave, followed by the internals — how the mobile transport, session handling and resume actually fit together for anyone working on the code. | [mobile-remote-access-part-3.md](mobile-remote-access-part-3.md) |
| Mobile Access (triage from your phone) | Serve a mobile-optimized web UI to triage your inbox from your phone, privately over Tailscale by default (only your own signed-in devices; public Funnel is an off-by-default Advanced switch) or over same-Wi-Fi HTTP; opens on the unified Inbox with boot data fetched in parallel with the tunnel handshake (2026-08-08 boot overhaul — fast first paint, no sign-in flash, translated from frame one); PWA manifest lets Android Chrome **Install app** to the home screen so taps reuse a standalone window instead of spawning new tabs | [mobile-remote-access.md](mobile-remote-access.md) |
| Reopen your open session on mobile (refresh / reopen) | On a phone, refreshing the page or reopening the app while you have a session open drops you **straight back into that session** (not the projects/inbox list) with its latest message already on screen — and a session you tap **while the app is still loading** opens and stays open, never overridden by the load finishing. Before this the phone kept the open session only in memory, so any refresh forgot it and dumped you on the Projects list. Always reopens the exact session you had open (no recency cutoff; back out to the inbox first if that's what you want); an archived/ended/deleted session falls back to your inbox list, never a blank screen. Mobile / Web Access only; desktop unchanged. No UI toggle (advanced kill switch `AMC_DISABLE_MOBILE_SESSION_RESTORE`). | [mobile-reopen-session.md](mobile-reopen-session.md) |
| Tap the project title to jump to the top (mobile) | On a phone, tapping the project name at the top of a project's session-LIST screen scrolls the list back to the top (iOS-style "tap the title bar to jump to top") — smooth, or instant under Reduce Motion. Real project lists only (the global Inbox title + embedded integration panels like AI Coaching/Settings don't scroll). While READING a session the same title still navigates back to the list (unchanged). The breadcrumb reuses its ONE button (stays at its raw-button baseline) and bumps a mobile-nav store nonce (`requestScrollSessionsToTop`) that the list consumes via the `useScrollSessionsListToTop` hook (imperative subscribe → no re-render; nonce never reset by nav, so it can't self-trigger). Mobile-only; desktop unaffected; no setting. | [mobile-scroll-to-top.md](mobile-scroll-to-top.md) |
| Swipe a mobile pop-up away (flick down to close) | On a phone, a downward flick closes a screen-covering overlay — the account panel (the account-button menu + usage bars) and Omniscio's shared bottom sheets (project picker, filter/options sheets). Additive over tap-outside + close buttons (a phone has no Escape key); every pop-up (account panel + bottom sheets) has a grab handle that closes it immediately however far scrolled, or a downward drag on the list itself first scrolls back to the top then a further pull closes; needs a real flick (50px offset OR 500px/s), ignores a pinch. Mobile-only; desktop byte-identical. Deliberately NOT wired to the full-screen Quick scratchpad (protects typed input). One shared `useSwipeToDismiss` hook. | [mobile-swipe-dismiss.md](mobile-swipe-dismiss.md) |
| Model safeguard refusals (a model declines a turn) | A model's own safety system sometimes declines an ordinary turn — Claude Code's own words are "this sometimes happens with safe, normal conversations". Omniscio recognises that refusal as its own class: it counts it, names the model and the stated reason in the session transcript, and leaves the existing automatic retry alone, because that retry rebuilds the conversation from the transcript rather than re-sending the refused request, which is why most refusals recover on their own. A session declined TWICE IN A ROW is different — that is a loop — so it is stopped and parked visibly in the state no automatic retry touches, with the reason in front of you. No model is ever switched on your behalf. Measured before this shipped: 282 refusals across 47 sessions in ten days, 21 of those sessions declined more than once. | [model-safeguard-refusals.md](model-safeguard-refusals.md) |
| Who pays & who serves (model vendors — one supply list per model family) | Every non-Claude model family (DeepSeek, GLM, Kimi, MiniMax, Meta, Qwen, OpenRouter) has ONE ordered supply list, edited in Settings → Accounts → Who pays & who serves (also on the phone, and as JSON text). Each row says who pays — your own account with the maker or with a reseller (DeepInfra, RunInfra, InferX), Omniscio credits (Omniscio picks the company), or the company lane for enrolled Omniscio developers — and every connection (a local session, a cloud session, a side question) uses the first row that can serve right now: a credential exists, the row is not known to be out of credit, and its company serves the model. The model you picked never changes. Each row shows its live state (Serving now, Ready if needed, Not set up, Out of credit, Waiting for peak hours, …); a reseller row whose company gives no discount on repeated text carries a "No cache discount" tag; and a DeepSeek row can be limited to DeepSeek's peak-price hours (the moon button, or "onlyDuring": "deepseek-peak" in the JSON) so DeepInfra serves while DeepSeek charges double. When a row runs out of credit, the ACCOUNT behind it (so every family's row that pays from it) is skipped by every session until Omniscio tries it again — one session every ten minutes — or a balance check sees money; the running session moves to the next row it can use and resends, noting the switch once in its history; one inbox card per account ("Out of credit: …") says so; and a session whose list cannot pay is refused with a message naming the model. A started session's model pill shows "Paid by: …" on hover (desktop). A cloud session is never given your key: on your own account (the maker or DeepInfra) it gets a one-run pass, and its requests come back over its connection to your computer, which adds the key. It replaced the Model vendors pins and "Auto (cheapest ready)", automatic cheapest-vendor routing, the per-provider payment order, the Omniscio-lane pin and the "Use Omniscio … credits" switches; resellers are no longer engines and CrofAI is retired. Older settings were converted into the lists on first connection. | [model-vendors.md](model-vendors.md) |
| Monday.com Cloud (in development) | In-development integration with the REAL monday.com Cloud API (id `monday-cloud`, distinct from the self-hosted clone above). Connect via personal API token (encrypted at rest); view boards, manage items, edit column values, post comments, create/move items. Inbox poller surfaces assigned items in the unified inbox; workflow trigger fires on item create/update/status-change. CLI routes at `/monday-cloud/*`. Gated via the `monday-cloud` unreleased-feature (`mondayCloudEnabled` / `AMC_SHOW_MONDAY_CLOUD=1`). | [monday-cloud.md](monday-cloud.md) |
| More replies below indicator (quiet "N more replies" scroll pill) | A quiet pill in the session's bottom-right scroll controls showing a down arrow + count ("↓ 3 more replies") when REAL agent replies sit below your current scroll position, hidden under collapsed muted markers (background check-ins, "waiting on a background process", woken no-ops) that otherwise look like the end of the thread. Counts substantive replies ONLY — muted filler never inflates it and the reply you're on isn't counted; recomputed live as you scroll and as replies arrive (positional, since sessions keep no read/unread store). A single tap reads FORWARD to the next real reply (not jump-to-bottom), walking you through the buried ones; a deliberate gesture — long-press / rapid double-tap / Shift-Ctrl-Cmd+click — instead jumps straight to the latest message (mirrors the up-arrow's hold-to-top); it hides at the bottom. When only filler is below, the plain jump-to-bottom arrow shows instead. On by default; Settings → Sessions → "Show 'more replies below' indicator" (`moreRepliesBelowIndicatorEnabled`) — off = byte-identical to before. Keeps the existing auto-scroll-onto-the-key-reply untouched. Contract: session-scroll-contract § "More replies below signal". | [more-replies-below.md](more-replies-below.md) |
| Motion & Polish (visual flourishes, on by default) | Master switch + per-effect toggles for visual flourishes — ALL ON by default since 2026-07-16 (hover-lift buttons, count-up Insights stats, ambient welcome gradients, depth, crossfades, sidebar glide, Inbox Zero); one master switch still kills everything, opt-outs survive. Mirrors the Chat Depth plumbing; auto-quiets on reduced-motion / low-power. | [motion-polish.md](motion-polish.md) |
| Move a session between projects | From a session’s menu (right-click a sidebar row, or the ⋯ menu atop an open session) → "Move to" → pick the destination project (search box + eligible-projects list); session re-homes immediately with an exact Undo toast. A started session keeps its original working directory (pinned, so a live agent isn’t repointed); a never-spawned session adopts the destination’s folder. Virtual/sentinel, soft-deleted, and the current project are never valid targets. Desktop only — no CLI route (unlike pause/snooze/archive) | [move-a-session.md](move-a-session.md) |
| Multi-Model Council — asking, verdicts and cost (part 2) | Part 2 of the Multi-Model Council page: putting a question to the council from a session, what a verdict actually shows you, the actions available on each turn, debate mode, attaching files, how the conversation remembers itself, what a run costs, and where the code lives. | [multi-model-council-part-2.md](multi-model-council-part-2.md) |
| Multi-Model Council (in development) | In-development parallel-panel feature: one question goes to several AI models simultaneously, a judge model synthesizes their answers into one verdict; an optional council-level **Orchestrator agent mode** turns the judge into an active agent that plans the task with the panel (advisors propose approaches, judge merges into one `===PLAN===` shown as a card) then executes it itself with tools at a Read-only/Full-access tier (Claude-only judge; the single agentic path that replaced the removed per-panelist "Run as agent" — existing agent panelists auto-migrate), asking the panel only when stuck (bounded to 2 re-consults); conversation memory uses judge verdicts (not raw member answers) as history; an **Ask the Council** button on a session's lettered question hands that question + every option verbatim + recent conversation to a fresh standalone (never-agentic, fail-closed) council for a second opinion without answering the session, and the verdict is returned to the asking session by hand from the turn's ⋯ menu; single `multi-model-council` cost-source label + daily cap (fails open on DB error, judge wall-clock cost captured exactly once); gated via the unreleased-feature registry (id `multi-model-council`) | [multi-model-council.md](multi-model-council.md) |
| Quick Music Recommendations (liked-songs → new music, quality-gated) | A bundled skill + one-click recipe that turns your liked-songs export (CSV/JSON, or a Spotify token) into genuinely-NEW music delivered as no-login YouTube "Play all" playlists per genre, on a mobile page. Node-only (no Python, no paid API for the default path). The intelligence comes from a selectable "brain" — Claude music-knowledge (default, licensing-clean, keyless), ListenBrainz (open booster), or Last.fm (free key, personal-use only) — because Spotify killed its recommendation/audio-feature APIs for new apps. A red-team QA pass runs before delivery: BLOCKING gates (never an already-owned artist/song — fuzzy so Ke$ha=Kesha and remixes count; no systemic resolution collapse) fail the run rather than lie; FILTERING gates drop hallucinated/unresolvable songs, off-genre picks, artist-hogging, and duplicates. One shared normalizer across the recommender, verifier, and gate fixes the prototype's #1 bug (37/40 "new" picks were already owned). Graceful degradation (no yt-dlp → list without links). Interactive Spotify login is best-effort only. Skill: .claude/skills/music-recommendations; recipe: resources/recipe-patterns/quick-music-recommendations.pattern.json. | [music-recommendations.md](music-recommendations.md) |
| My Automations | The one MANAGE home that lists every scheduled automation — Automation-Builder-built ones (badged) plus your other scheduled cron jobs, in one friendly list; the Automation Builder page links here (building lives there, managing here); open it from the Automation section of the left sidebar | [my-automations.md](my-automations.md) |
| Reply by Voice (talk back to a session from a narration message — in development) | The reply sibling of [Spoken Narration](spoken-narration.md): a mic button beside each message's narration play button opens a window where you speak, see a live transcript, edit it, and send it to that session — reusing the existing voice capture + speech-to-text + send path (no new engine). Opening the window stops the recap audio (no echo) and cleanly takes over the mic so the global voice system can't double-send your words. Review-then-send by default, or auto-send-on-silence (guarded with a min length + a cancelable countdown); requires Voice Input on; works on desktop + mobile web (mobile best-effort). Off by default behind the `narration-voice-reply` in-development gate (`narrationVoiceReplyEnabled`; reveal via Settings &rarr; Lab). | [narration-voice-reply.md](narration-voice-reply.md) |
| Native slash commands (run /model, /clear, /cost, /context, /status for real) | Type Claude Code's own slash commands in the chat composer and have them execute in the underlying Claude Code session — switching the model live, clearing context, or showing the real cost / usage / context / status — instead of being sent to the model as literal text. Claude Code sessions only. Shipped; setting `nativeSlashCommandsEnabled`. | [native-slash-commands.md](native-slash-commands.md) |
| New model alerts (new-model watcher) | Watches each provider you've configured (Claude, DeepSeek, GLM, MiniMax, Meta, OpenAI, Gemini, Kimi) for newly-released models and raises ONE deduped inbox card + desktop notification per genuinely-new model, with a one-click **Add it for me** button (the card's Start-session button) that spawns a session to add it properly — look up real pricing (flag rather than guess if unknown), add it to the picker with a label, add the pricing row, update tests, and leave the work on a branch (never pushes/merges). "New" means new since a per-provider baseline seeded on first run — SILENTLY for old models (no day-one storm) but still surfacing current-generation not-yet-listed models by their release date (`created`/`created_at`, ~60-day self-calibrated window) — NOT "absent from Omniscio's curated list"; the already-offered check is CROSS-picker (`isOfferedByAnyProvider`), so a vendor polled as e.g. `openai` whose models live under the `codex`/`gpt` pickers still counts as offered (a provider-scoped check failed open and suppressed every openai alert); only polls providers you have a key for; per-provider noise filters (OpenAI chat-only, Kimi k-family, Gemini GA, Claude ignores re-dated snapshots) + id sanitization. NOT available for Antigravity / Hermes / Terminal / OpenClaw / OpenCode / Pi (no model-list endpoint or per-session model) — Cursor is a planned fast-follow. Free (a metadata call, no AI tokens; the "Add it for me" session is the only paid part). Alerts once per model, ever (dismissal sticks across restarts). On by default; Settings → Notifications → New model alerts (`newModelWatcherEnabled`); kill switch `AMC_DISABLE_NEW_MODEL_WATCHER`; inert in e2e/sandbox. | [new-model-watcher.md](new-model-watcher.md) |
| New Settings layout (the reorganized "rooms") | The Settings screen reorganized into clearer, plainer-language **"rooms"** — the six settings-redesign prototype groups (General, Agents, Apps, Connections, Input, System, plus an owner-only Team & Admin) — changing only the **grouping, labels, and order** of the settings nav, never adding/removing/changing any individual setting. Section ids are identical to the old layout, so deep links, Settings search, UI-anchors, and legacy aliases all still resolve to the same panels. Shipped as the default for everyone. Building on it, the **Settings redesign** ([settings-redesign.md](settings-redesign.md)) gives each large page per-page **tab strips** (Appearance / Sessions / Voice) with Basic/Advanced folding and live previews — shipped as the default for everyone (no toggle); quick-setup presets remain a separate in-development feature. | [new-settings-layout.md](new-settings-layout.md) |
| Night Shift (overnight task sequencer) | Overnight task orchestration layer — define a plan of ordered phases (wait for sessions, spawn a batch, spawn fixes from audit findings, delay, run a recipe), start it, and go to sleep; the sequencer ticks every 60 seconds advancing one phase at a time with restart-safe state in SQLite; progress and completion appear as inbox cards; stall watchdog alerts after configurable inactivity; single active plan constraint; extensible via the `PhaseHandler` interface (type + Zod schema + start/poll/describe/abort). CLI routes at `/night-shift/plans` (create, list, get, start, abort). In-development | [night-shift.md](night-shift.md) |
| Nighty Tidy — how it works and its limits (part 2) | Part 2 of the Nighty Tidy page: the machinery under an overnight run, the sessions it tags as its own, how to drive it from an AI operator session, and the boundaries you should know about before trusting it with an unattended night's work. | [nighty-tidy-2-part-2.md](nighty-tidy-2-part-2.md) |
| Nighty Tidy (the full-vision audit panel) | THE Nighty Tidy going forward (the original is untouched legacy) — native React panel on desktop AND mobile with four live-updating screens: Run (read-only or read-write + auto-fix, scope picker with preset buttons + folder browser + custom instructions, push-driven progress queue), Automate (the calm one-line-per-repo page — repo · outcome signal · On/Off toggle where the toggle IS the create; a repo-detail page of four apply-on-change pickers Schedule/Audits/Auto-fix/Advanced; a global pacing & limits editor), History (every run incl. visible pre-flight failures; soft-delete), Findings (structured `findings.json` view, status-aware empty states). OWN run history (`nighty_tidy_2_runs`) + automations (`nighty_tidy_2_subscriptions`) + a stateless nightly scheduler (every due audit per automation, one global concurrency-cap setting, startup rescue of finished-but-unrecorded runs). Reuses the SHARED audit framework; keeps installed specs CURRENT via a sha-provenance refresh that never overwrites user edits ("Edited" badge; Omniscio-specific audits badged). AI operator sessions drive it over the gated `/nighty-tidy-2/*` CLI API (run-now approval-gated; saves replay-idempotent). Bundled plugin `nightytidy2`, off by default at Settings → Plugins, moon-icon sidebar `__plugin_nightytidy2__` | [nighty-tidy-2.md](nighty-tidy-2.md) |
| Notification History (past toasts + dismissed alerts) | One combined place to look back at notifications — a Toasts tab (recent pop-ups, persisted across restarts) and an Alerts tab (the full archive of dismissed agent alerts, restorable); opens from one sidebar row in the System group, on desktop and mobile | [notification-history.md](notification-history.md) |
| Notifications & Silence | Mute globally or per-project, pick sounds per alert type, control OS toasts, tune post-send navigation, toggle the desktop app-icon attention-count badge (`desktopIconBadgeEnabled`, default on) | [notifications-and-silence.md](notifications-and-silence.md) |
| Notion | Experimental Notion integration — a "Notion" sidebar board (database → status/select columns → page cards), connect via internal integration token, REST client, CLI routes (search, query, create/update pages, comments), workflow engine nodes (3 actions + page trigger with 2-min polling watcher), plus a "notion-inbox" recently-edited-pages source. | [notion-board.md](notion-board.md) |
| Off-machine backup (first-run prompt to set up a backup that survives losing your computer) | A gentle, consent-first one-time banner + chooser (and a Setup v2 cascade step) that invites a new user to set up an OFF-machine backup: connect Gmail (Setup Backup) or pick a cloud-sync folder + passphrase (Backup Mirror). It exists because a default install's only on-by-default backup writes to the SAME disk as the database, so a lost/failed/stolen machine loses everything with no off-box copy. Consent-first: it never enables a backup itself — it routes each choice into the hardened Settings → Backup & Restore config and records a one-time dismissal (`backupOffMachineSetupOfferDismissed`); shown only post-onboarding, on desktop, with no off-machine backup configured yet, and never on mobile. Honest about Gmail when no Google account is connected. Also rewords the fatal database-open dialog so it no longer steers a disk-loss recoverer to the same-volume backups folder. | [off-machine-backup-onboarding.md](off-machine-backup-onboarding.md) |
| Offline banner (network-connectivity indicator) | A slim amber bar across the top of the app that appears when your computer loses its internet connection ("You are offline. Some features are unavailable." + Wi-Fi-off icon), so a failing session or stalled sync reads as your network, not Omniscio. Always on, no setting. Driven by a main-process connectivity service that polls `net.isOnline()` every 10 s (2 s while offline) and emits `NETWORK_STATUS_CHANGED` on a transition; the renderer debounces ~5 s (`useOfflineBannerGate`) so a transient blip never flashes it. While offline the same signal also **pauses the automatic session-retry engines** (the stuck-session re-arm sweep + the inline api-error retry) so Omniscio never burns doomed retries — a session holds quietly (a "no internet — will retry when you're back online" note) and resumes on reconnect (`AMC_DISABLE_OFFLINE_RETRY_GATE`). This is the "that's your network" job the Anthropic status monitor defers to. | [offline-banner.md](offline-banner.md) |
| Ollert (native port) | Sidebar virtual project (Ollert brand icon, in its alphabetical slot) that mounts a native React kanban board full-pane inside Omniscio — boards/lists/cards over a separately-hosted Ollert backend with Ollert's own email/password login. Off by default (`trelloEnabled`); backend URL is `trelloApiUrl` (default `http://localhost:3000`). Vendored + tooling-isolated in `src/plugins/ollert/`; in-memory router, `.ollert-scope` scoped Tailwind, renderer-direct API calls. Phase 1 = sidebar + shell + login | [ollert.md](ollert.md) |
| Omniscio Control (bundled skill — how AI agents change Omniscio live) | One bundled Claude Code skill auto-installed into `~/.claude/skills/omniscio-control/` on every Omniscio launch — teaches any AI agent (Claude Code, external Claude, ChatGPT with file access) to read and change a running Omniscio install via the localhost `127.0.0.1:19519` HTTP control server instead of editing `config.json` or restarting; hub-and-spoke layout (SKILL.md + 10 surface files: settings / sessions / cron / automations / recipes / projects / away-mode / tags / keybindings / pending-actions); cosmetic changes apply immediately, anything affecting inbox / billing / data lands in your Approvals inbox first; one bearer token auto-fetched from DPAPI vault | [omniscio-control.md](omniscio-control.md) |
| Onboarding Guardian | An **invisible AI assistant** that quietly watches a new user move through the **Setup v2** cinematic onboarding flow and the **interactive tour**. Stays silent almost always and surfaces a single gentle hint only when you appear genuinely stuck (e.g. idle on a step with no forward progress). Can also *act* on your behalf during onboarding — highlight the control, open the right panel, or launch your first task — but never does anything destructive and never runs outside onboarding. | [onboarding-guardian.md](onboarding-guardian.md) |
| OneDrive integration (file browser + cloud storage) | Sidebar file browser for Microsoft OneDrive — browse, upload, create folders, rename, delete, move, copy, search, share files; Microsoft Graph API v1.0 with OAuth2 + PKCE; channel-adapter pattern with unified inbox integration | [onedrive-integration.md](onedrive-integration.md) |
| Open Settings | Gear icon in the toolbar OR the **Settings** virtual project in the Omniscio sidebar group — same `<Settings />` modal, two entry points. A fresh open lands on the **Settings Home** page; same-session reopens restore your last section; deep links always go straight to their target | [open-settings.md](open-settings.md) |
| Port your OpenClaw setup into Omniscio | Bring an existing OpenClaw gateway into Omniscio with minimal typing — first connect (smart-paste / import the gateway address + auth token, parser normalizes http→ws client-side), then optionally have a Claude session recreate your scheduled jobs + command/agent personas inside Omniscio. The applier (`POST /openclaw-port/apply`) is the trust boundary, validating plans against Omniscio's own cron/recipe schemas; secrets are never imported. | [openclaw-port.md](openclaw-port.md) |
| OpenClaw (alternative provider) | Run sessions via a remote WebSocket gateway instead of local Claude CLI — cloud execution, virtual `__openclaw__` project | [openclaw-provider.md](openclaw-provider.md) |
| OpenCode provider (CLI-backed sessions) | Spawn Claude-Code-style sessions backed by the OpenCode CLI (`opencode`) — a local CLI that runs Claude (Sonnet) models through your Anthropic API key. Gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via Settings → Account OpenCode CLI binary (PATH-only, no installer) + Anthropic API key + "Allow OpenCode sessions" toggle; one shared persistent `opencode serve` HTTP/SSE server (a `persistent-external` engine, owned by opencode-server-supervisor) that multiplexes every OpenCode session with token-by-token SSE streaming; emits authoritative per-turn cost (written to `api_cost_log`); 3 readiness gaps (`toggle-off`, `binary-missing`, `key-missing`); shows the OpenCode mark in the session header; no virtual project; per-launch ChangeProviderButton only | [opencode-provider.md](opencode-provider.md) |
| OpenRouter provider (Anthropic-compat "Anthropic Skin", no account) | Spawn Claude-Code-style sessions backed by OpenRouter's Anthropic-compatible endpoint (hosted at `https://openrouter.ai/api`) — the SEVENTH anthropic-compat member and the **"connect with one key, no Claude account"** onboarding run path. Picked in first-run setup (or Settings → Accounts behind the master toggle); ONE `sk-or-…` key runs agents AND powers the built-in AI helpers (reuses the shared `userOpenrouterApiKey` slot). **No binary check, no proxy** — reuses the standard `claude` CLI; routing via spawn-env (`ANTHROPIC_BASE_URL=https://openrouter.ai/api` — the CLI appends `/v1/messages` — plus `ANTHROPIC_AUTH_TOKEN=<key>`); model ids are `vendor/model` OpenRouter slugs, default `qwen/qwen3-coder` (the cheapest current model that answered on a live test) with `qwen/qwen3.8-flash` + `deepseek/deepseek-chat` + `anthropic/claude-sonnet-4.6` + the Kimi pair selectable, re-priced from tokens; **ALSO runs on OMNISCIO COMPANY CREDITS** — the Omniscio credits row of OpenRouter's supply list (Settings → Accounts → Who pays & who serves; by default right after your own key) routes it through the gateway's `/v1/openrouter` lane on the company key, UNGATED (any signed-in user, no Pro tier — unlike Pro-only GLM), covering every model OpenRouter serves, priced from OpenRouter's LIVE rate list (fetched hourly) at the standard markup; 2 readiness gaps (`toggle-off`, `key-missing`); identical tool-approval UX to Claude. DISTINCT from the flag-gated `customOpenai` OpenRouter preset (proxy-backed). | [openrouter-provider.md](openrouter-provider.md) |
| Share automations with your workspace (the Workspace tab) | Your company's own private automation catalog inside the Marketplace, beside the public Automations tab — browse and install recipes shared only within your workspace, never published publicly and never seen by Omniscio staff. Publish from any automation's Share dialog; a workspace can require admin approval before a shared automation appears. | [org-marketplace.md](org-marketplace.md) |
| Orphaned Workspace Archive (folder reclaimed after 24h, branch and work kept) | Background job that frees the DISK of a workspace (git worktree) whose session has been gone 24 h while KEEPING its branch and every change — the missing third outcome between "keep the folder forever" and "delete the branch" (measured 2026-09-04: 718 workspace folders, 210 abandoned that nothing could archive, drives 95-96% full). Uncommitted work is committed to the branch AND saved under `refs/amc/preserved-wip/` first, and a workspace is left completely alone if preservation cannot be PROVEN. Never touches one that is in use, being reworked after a merge conflict, pinned, locked, do-not-delete-marked, running a live command, freshly created, recently written to, product-owned scratch, or already landed. Owner statuses treated as "still yours" include a rate-limit park, which auto-resumes. Pick a branch back up with `POST /worktrees/create` — every commit and auto-save is there. First run REPORTS ONLY. At most one inbox note a day, breaking down what was held back by safety check and what is waiting on its session rather than the clock; the note asks nothing of you. Hourly, ≤25 per run, stands down while the drives are BUSY but deliberately not because they are FULL. Setting `orphanWorktreeArchiveEnabled` (on by default); kill switch `AMC_DISABLE_ORPHAN_WORKTREE_ARCHIVE=1`. Contract: worktree-retire-sweep `archiving-is-a-third-outcome`. | [orphan-worktree-archive.md](orphan-worktree-archive.md) |
| Abandoned helper processes are cleaned up (orphaned tool-call process trees) | The helper tree a timed-out agent tool call strands (the npm / npx / git shell shim and everything under it) is found by a fifth, shape-positive pass of the orphan sweep: dead launcher, tool-call shape, 15-minute floor, transient-script allow-list, no gate ownership, no git work, session-Job membership for enforce. Ships in SHADOW (a durable would-reap ledger read by `npm run orphans:status`, nothing ended) until the owner flips `orphanToolTreeReaperEnforce`; `npm run orphans:reap [-- --enforce]` runs the same filter by hand | [orphaned-helper-process-cleanup.md](orphaned-helper-process-cleanup.md) |
| Outbound Webhooks (push Omniscio events to your own server) | Omniscio POSTs a signed JSON payload to a callback URL you control when an internal event fires — agent started/finished/needs-you/errored, budget warning/exceeded, recipe/job finished, alert raised (a curated default-deny set, each with a safe minimal payload). Configure a webhook with a public https callback URL, an event filter (empty = all events), and an active toggle; the signing secret is shown exactly once (rotate for a new one); view per-webhook delivery history and send a test ping. Each delivery is a POST (application/json) with `X-AMC-Signature` (HMAC-SHA256 hex of the raw body), `X-AMC-Event`, and a stable `X-AMC-Delivery-Id`; body envelope `{ event, deliveryId, deliveredAt, webhookId, data }`; 3 attempts with jittered backoff + 10s timeout, return 2xx to acknowledge, auto-disable after 3 consecutive failures, 500-row history. Verify a delivery by recomputing HMAC-SHA256 over the RAW received body and comparing (constant-time) to `X-AMC-Signature` — Node + Python samples included. SSRF-guarded (private/loopback/metadata URLs rejected); the secret is never returned on reads. In-development, off by default — reveal via Settings → Lab, turn on with the master delivery toggle. | [outbound-webhooks.md](outbound-webhooks.md) |
| Overseer worker titles (how a worker session an Overseer spawns is named) | A worker an Overseer spawns is titled `[<Category>] <Role> <N>: <Task>` — say `[Verdict] Fixer 1: Fix the flaky auth test`. The Category is the Overseer's own one-or-two-word tag for what it is managing, so a crew groups together in the sidebar; the Role is the worker type's label; the Task is the job it wrote. `<N>` is that role's running count under that Overseer and it comes from a stored counter per (Overseer, role), never a tally of session rows — so archiving or purging old workers cannot hand the same number out twice, and "the 46th Fixer" always means one session. Numbering starts at 1 with no backfill (the worker type was never recorded on a session, so earlier workers cannot be attributed to a role); a failed spawn skips a number rather than reusing one. A title set this way is never rewritten, because the AI auto-titler only touches sessions still carrying a placeholder name. Only Overseer spawns are affected — cron, ordinary agent-driven and your own launches are unchanged. The Overseer sends `agentType` and a short `category` and does NOT send a name; an Overseer that sends no category gets `Fixer 1: …` rather than empty brackets. | [overseer-worker-titles.md](overseer-worker-titles.md) |
| Overseers — running one (part 2) | Part 2 of the Overseers page: keeping one working — how it wakes up, stays alive across restarts, and watches for stalls; how to copy one or run several; how to point one at specific sessions and where the answers it collects end up; and how to ask it something or tell it it got something wrong. | [overseers-part-2.md](overseers-part-2.md) |
| Overseers — the work, the settings and the internals (part 3) | Part 3 of the Overseers page: the kinds of work an Overseer can hand out and the jobs it may start on its own, what it notices without being told, how agents hand notes to each other, the spend circuit breaker and the settings that govern it all — plus the internals for anyone working on it. | [overseers-part-3.md](overseers-part-3.md) |
| Overseers (the Overseer system: always-alive assistants, their swarms, and the one hub you reach them from) | A permanently-alive AI session that screens your inbox (holds cards for up to 10 minutes, batches/silences/merges before you see them), answers agent questions concurrently over HTTP, sweeps the fleet for patterns, and restarts itself on a schedule (default 24 h) so context never grows unbounded — its durable memory lives in `NOTES.md` and survives every restart via re-composition. Fail-open: four independent paths guarantee a broken Overseer can never silence your inbox. Per-project Overseers supported; each slot has its own single-flight spawn claim. The **Overseers hub** is the SINGLE user-facing entry point (O71) — the sidebar row and two-column panel for Overseers AND swarms: a plain list on the left (state dot, waiting-on-you number, swarms nested, New + Fleet settings in the header) and the selection on the right. An Overseer has four tabs (Chat / Sessions / Board / Settings); a swarm gets its own six-tab screen; New opens a four-step wizard whose Start IS the approval to spend. Everything else that mentions Overseers is a LINK into that hub — no second screen, dialog or wizard, and the Overseer's own session home is never offered as a hub you can start a session in. Every create/edit/switch/delete goes through the main-process slot writer (O53) and the Board is a bounded fail-open READ (O54). Its Chat tab's **Just us** view shows only what you and it actually said — app-injected briefings are excluded by a positive test on the turn, never inferred from a missing label, and the Overseer can tag one of its own replies as a routine status update to keep that out too (nothing is deleted; **Everything it does** shows all of it, O72–O74). The heartbeat wake-up is the app's own clock and is never drawn as a message in either view, and a round that found nothing stays out of the chat by itself (a round that found something is always shown). In-development — reveal via Settings → Lab or `overseerEnabled`. Contract: overseer-contract (O40, O53, O54, O71, O72–O74) · overseer-heartbeat-hiding-contract. | [overseers.md](overseers.md) |
| Paste Rich Text → Markdown | Pasting from Google Docs, web pages, Notion, or any HTML source converts to Markdown automatically in chat compose and Add Project Docs Paste tab; hold Shift to bypass for plain text; inline base64 `<img>` data URIs are dropped (would otherwise dump multi-kilobyte payloads into the textarea); external `https://` image references still convert to `![](url)` | [paste-rich-text.md](paste-rich-text.md) |
| Pattern Oracle (plugin — recurring patterns across PRs and sessions) | Free marketplace plugin: scans pull requests and sessions on a schedule, writes a ranked report of recurring patterns and recommendations, and tracks which ones you addressed. Needs a GitHub token; each run is capped by a per-analysis dollar limit. | [pattern-oracle.md](pattern-oracle.md) |
| Pause or stop a session | P to pause (graceful kill, status flips to `paused`), Esc to interrupt mid-stream, End to mark a session ended; sending while paused auto-resumes the CLI; one-click Nudge button on grey paused/ended sessions | [pause-or-stop-a-session.md](pause-or-stop-a-session.md) |
| Work through paused sessions — auto-advance | Acting on a paused session (archive, reply, or unpause) auto-advances you to the next paused session in that project's "Paused Sessions" group; when none remain, the next "Needs You"; else stays put. The paused-pile sibling of gray-session triage. | [paused-session-triage.md](paused-session-triage.md) |
| Peek Viewer (preview files + sibling-image nav) | Click a file path or image link in an agent message to open a side-panel preview; messages with multiple image links enable in-place navigation (arrow buttons, ArrowLeft/Right keys, mobile swipe); counter `N / M` shows position; wraps at edges; hidden entirely for single-image previews. Text files open editable (pencil → Save) on desktop AND mobile; the raw view wraps markdown/plain-text on every viewport while code/data keep horizontal scroll on desktop, and the phone back-gesture confirms before discarding unsaved edits | [peek-viewer.md](peek-viewer.md) |
| Interrupting or waking a peer session (confirmed escalations) | The two opt-in confirmations on `peer-message`, in depth: `confirmInterruptTurn` kills a busy target's in-flight turn instead of waiting; `confirmInactiveTarget` wakes a paused/archived/ended/error target past its 409 refusal, with its two exemptions (a self-send, a reply to the asker), its `user_closed`/`noWakeFromArchived` hard guards, and the internal per-status list one mechanical sender uses to reach an archived target it could never ask for confirmation. Also the per-target circuit breaker: three terminal refusals in two hours and the next send is refused `409 target_circuit_open` (with the count, the last reason and the reset instant) rather than attempted, because a send that keeps failing is a loop. Includes the sharp edge: `POST /session/:id/message` interrupts a busy target unconditionally, with no confirmation flag at all. | [peer-message-interrupt-and-wake.md](peer-message-interrupt-and-wake.md) |
| Per-model thinking level (a default reasoning level per model) | Settings → Session card (below the single Thinking Level) that gives EACH model its own default reasoning/effort level — Opus → Max, Haiku → Low, Codex GPT-5.6 → High — so a new session inherits the right level for its model without hand-setting it. A supplement, not a replacement: a model on "Inherit default" falls back to your single Thinking Level (Claude) or the model's own default (Codex). Covers every effort-capable engine (Claude + Codex today, via `providersWithReasoningEffort`); legacy Claude models aren't listed (still overridable per-session). "Inherit default" (removes the entry) is distinct from an explicit "Auto" (pins the model to its own default). Precedence: session pick → project default → per-model default → single global Thinking Level. Validated at read time so a Claude-only level (Max) never leaks onto a Codex model or a Codex-only level (Minimal) onto a Claude one; an invalid/stale entry is dropped. Starts empty (no migration). Stored as `modelDefaultThinkingLevels`; the spawn + the session chips read ONE shared resolver (`resolveModelGlobalThinking`) so the pill can't drift from what launches. | [per-model-thinking-level.md](per-model-thinking-level.md) |
| Per-session update isolation | Opt-in performance mode: each mounted session panel reads its per-session state (pending action, permission, auth-retry, subagent, usage) through ONE consolidated `selectSessionPanelSubscriptions` selector instead of five separate subscriptions, so a streaming token re-runs one selector per panel instead of five — deterministic ~80% fewer per-commit selector executions at 30 panels, behavior-identical (proven by a re-render parity test). Settings → Performance → "Per-session update isolation", default OFF, flips live (no restart, component-swap like Fast session switching); env kill `AMC_DISABLE_PER_SESSION_SUB_ISOLATION=1` (force-OFF only). The residual per-update cost after the adaptive-hidden-window throttle. | [per-session-update-isolation.md](per-session-update-isolation.md) |
| Per-window zoom (each pop-out has its own saved zoom) | True browser-style zoom for every SECONDARY / pop-out window — Ctrl `+`/`-`/`0` and Ctrl+wheel scale the WHOLE window (text, icons, images) via CSS `zoom` on that window's document root, saved per window (session pop-outs per session id; KMS / Scratchpad / Quick Launch / Job Monitor / Support Chat / Clipboard History / project windows per window). Same 75%–150% seven-step ladder as Text size, but per-window and everything-scaling. The MAIN window is untouched (keeps app-wide Text size); the embedded isolated-view guest is excluded (null zoomKey); the KMS/Scratchpad editor keeps its Ctrl+- (keyboard zoom yields to a focused editor, Ctrl+wheel still zooms). Factors persist in a `window_zoom` table via Zod-validated `window:zoom-get` / `window:zoom-set`, clamped client- and server-side. | [per-window-zoom.md](per-window-zoom.md) |
| Governance control + triage (what is being paced, by which governor, and why — and why is it slow) | The ONE screen and the ONE ordered entry for the agent-load governance family, replacing "read three overlapping readouts and hope". **`npm run perf:control`** (also `GET /perf/control` and the control section of the Performance Monitor panel, all three from ONE assembler, so a panel reading and a scripted reading cannot disagree) shows the fused harm verdict with every contributing AND every blind term, main-thread lag p99 against its bound, caught stalls with their `blockedOp` causes, kernel share, disk runway, and **`userInteractiveHeldMs`, which must read 0** — then the governor band, live mode, admission coverage and **who last flipped it and when**, then EVERY registered governor with its four counts (`offered`/`admitted`/`held`/`refused`), its coverage and **its kill-switch name**, then the top load producers by class. Three words carry the honesty and none is ever rendered as `0`, `ok` or `off`: `not-counted` (nothing counts it, so no observation is possible), **`unproven`** (the counter moved but the gate has never once held or refused — measured 2026-09-15, two gates read fully green having paced nothing) and `unknown` (unobservable from this process). One switch, `--mode observe\|enforce --source "<who/why>"`, where **`--source` is mandatory and refused before the request is made** — authentication is not attribution, and an unidentified bearer once re-armed this governor and stalled every agent for 18 minutes. **`npm run perf:triage`** runs six readouts in a fixed cheap-discriminator-first order and ends in ONE ranked verdict from a closed enum, with the measurement that ranked it and the next command; `unmeasured` outranks a guess, a selective symptom can never be ranked to a global cause, and there is no "too many sessions" verdict. Neither command takes its own sample of the machine. | [perf-control.md](perf-control.md) |
| The load curve (how long agent commands take at different session loads) | `npm run perf:load-curve` — per-tool-call WAIT bucketed by live-session count (0-25 / 25-50 / 50-75 / 75-100 / 100-125 / 125+), p50/p95 per command class (`git` · `test` · `build` · `search` · `install` · `node` · `other`), joined against the governor tape (lag p99, band), the heartbeat's caught stalls and cloud gate durations in the SAME buckets. Ends by naming the class whose p95 grows fastest with load and the bucket where it first doubles. Under 30 samples a bucket prints `(thin)` rather than a percentile it cannot stand behind; a missing input reports `UNMEASURED` with its reason, never a zero; `--self-test` is the positive control that proves the bucketing and knee detector are not dark. The full command is never stored — only a redacted class. It NEVER recommends a session count: the box is meant to run 100+, and the curve exists to show which per-session cost the APP must shrink. | [perf-load-curve.md](perf-load-curve.md) |
| Performance Monitor (see how this machine and the app are actually doing) | One answer to "how is this performing right now?", read three ways from the SAME snapshot so a panel reading and a scripted reading can never disagree: a read-only **Developer Tools** panel, `GET /perf/status`, and `npm run perf:status`. Blocks: box (CPU · kernel share · pressure faults · event-loop lag · RAM free **and** available, labelled apart) · the app main thread stall share, stalls, longest stall, memory, blocking fs holds and GC pauses · the external-memory pool and its refill slope · fleet sessions and process starts/s by program · per-volume disk free plus **runway hours** at the measured slope, with box-wide loose dirs kept separate · cloud verdict share incl. **no verdict** (a run that answered nothing) · the auto-lander pulse · the load-gate verdicts. Read from the app own logs and in-memory state IN PROCESS — it starts no probes, so it cannot go dark under the spawn storms it measures. Every block is **ok / unavailable / not-on-this-build** and states how much of the window it saw, so a missing number can never read as a healthy zero; it also names what it cannot see. The app watches these numbers itself and raises sustain-gated, self-withdrawing inbox cards (inbox-only — none page a phone). Panel in-development, off by default (`perfStatusEnabled`); the watch, alerts and route are NOT gated on it. | [perf-status.md](perf-status.md) |
| What the fleet finished at each session load (lands, ready tags, inbox deliveries) | `npm run perf:work-output` — the answer to "did the fleet produce less per session as the load rose?", read as three countable measures rather than tokens: commits landed, ready-to-merge tags applied, and items brought to the owner's inbox, each per hour for the whole fleet AND per session-hour, at every live-session count (0-25 up to 125+). Every measure comes from a record the app already wrote, each carries its own coverage, and a source that cannot be read reads `unmeasured` with its reason — never a zero that looks like a quiet fleet. Both window bounds are printed in full ISO so the numbers can be checked against a git log. It NEVER recommends a session count: a peak is a reading, not a cap. | [perf-work-output.md](perf-work-output.md) |
| Phone Control (drive an Android phone from Omniscio) | An optional in-development feature that drives a connected **Android** phone over local `adb`, with two surfaces off one flag: (1) **agent tools** — any session gets `mobile_*` tools (tap, swipe, type, screenshot, list/launch/install apps) via the bundled `@mobilenext/mobile-mcp` server; (2) a **"Phone" panel** (Developer Tools group) to drive a device yourself — a device picker, a live screenshot (2s poll), a Wake button, and an app launcher. On first enable it **auto-provisions** the runtime (detects or downloads `adb` + mobile-mcp into its data folder — no manual install), and the agent tools stay dormant until the runtime is present. A dropped **wireless** link self-heals — the panel remembers connected addresses and re-issues `adb connect` on its device poll. **Android-only locally** (iPhone automation is macOS-only, so there is no local iPhone path from Windows; a paid Mobile Next Cloud route is a possible future add). **Desktop-only** (both surfaces shell to local `adb`) and off by default; phone commands run with no shell + a strict character allowlist, no secrets in the session config, and mobile-mcp telemetry disabled. Reveal via Settings → Lab (`phoneControlEnabled`) or `AMC_SHOW_PHONE_CONTROL=1`. Contract: phone-control-contract. | [phone-control.md](phone-control.md) |
| Pi provider (CLI-backed sessions) | Spawn Claude-Code-style sessions backed by Pi (`pi --mode rpc`, the pi.dev `@earendil-works/pi-coding-agent` CLI) — a **first-class** alternative provider (sky-blue "Pi" π pill, per-project default, switch-to-able) that runs **any model** (Anthropic / OpenAI / Google / OpenRouter) on your OWN provider keys (reused — no new Pi key). Gated behind master "Show alternative AI providers" (off by default), then opt-in via Settings → Account **Allow Pi sessions** toggle + `pi` CLI binary (PATH-only, detect-only) + a model picker; the required key depends on the chosen `provider/model` (a resolver gate, like OpenCode — `google` routes to `GEMINI_API_KEY`, not `GOOGLE_*`). Long-lived stdio-JSONL-RPC child (`persistent-external`, like Codex) with strict newline-delimited framing, token-by-token streaming, lazy spawn, native multi-turn (no cross-restart resume); **records REAL per-turn $ cost** (from Pi usage); tools auto-execute (no approval prompts, v1); 3 readiness gaps (`toggle-off`, `binary-missing`, `key-missing`/`model-unsupported`); no virtual project; no images / MCP in v1. ⚠️ protocol verified against pi-mono source, not a live binary run. | [pi-provider.md](pi-provider.md) |
| Plain Speak overlay feedback (Report bad overlay) | "Report bad overlay" item in the agent-message 3-dot menu, visible only while the Plain Speak rewrite is shown — opens a shared notes-only dialog, delivers a JSON bundle to the Resend + Firestore dispatcher (toggle-gated by `bugReportTransport`) in parallel (agent message + rewrite + preceding thread + optional user note + active pipeline id) tagged `[BUG: amc-overlay]`; bundle is drop-in compatible with `tools/plain-speak/fixtures.json`. Every-leg-fail falls back to `<userData>/bug-reports/overlay-...json`. 5-minute per-(message, kind) cooldown. Toggle off via Settings → Plain Speak | [plain-speak-feedback.md](plain-speak-feedback.md) |
| Plain Speak — what you see (part 2) | Part 2 of the Plain Speak page: the rewrite as it appears on a message, what happens when a reply is flagged as unsafe to rewrite, and the whole experience of waiting — what is on screen while the rewrite is still being computed. | [plain-speak-part-2.md](plain-speak-part-2.md) |
| Plain Speak — gates, cost and privacy (part 3) | Part 3 of the Plain Speak page: the reports a build pipeline gets, exactly what the rewrite is allowed to see, the built-in prompt it is locked to, the master switch and the spending controls behind it, the log of decisions it made, and what leaves your machine. | [plain-speak-part-3.md](plain-speak-part-3.md) |
| Plain Speak — implementation notes (part 4) | Part 4 of the Plain Speak page: the implementation notes for anyone working on the code — where the rewrite is computed, the shape of the output, how a failure is handled, and the tests that pin the behaviour. | [plain-speak-part-4.md](plain-speak-part-4.md) |
| Plain Speak | Pluggable rewrite of each agent end-of-turn into a 5-section markdown card; default is a 5-stage cascade (Qwen draft → Qwen critic → regex → Haiku word-fix → gpt-oss-20b guardrail), switchable in Settings to a single Sonnet or single Qwen call. Click the **Plain Speak / Original** pill in the message header (or press **V**) to flip views. Session held out of inbox / chime / OS toast until the rewrite settles. Default daily cap $10 | [plain-speak.md](plain-speak.md) |
| Plan & Usage (the one money screen) | The ONE customer-facing money screen at **Settings → Accounts & AI → Plan & Usage** (renamed + expanded from "Plan & Billing" on 2026-08-18): your current tier and this month's **AI allowance** (fetched on open only, never polled; clamps at 100%, hides when the tier has no cap), the prepaid **credit balance + Buy-Credit** (moved here from API Keys, shown as a distinct number from the allowance — never merged), a **Free/Pro/Team** comparison with **upgrade / manage** ($15/mo Pro via Stripe hosted Checkout, Upgrade only when signed in AND on Free), and **bring your own API key**. It absorbed the retired mock **Pricing** screen, so it is the single storefront (the free→workspace `upgrade_required` prompt routes here). The gateway pins `client_reference_id` to the **verified uid server-side**, and a **separate** Firebase webhook flips the `tier` claim free↔pro — the grant rides a verified webhook, not the browser returning. A failed card keeps Pro for Stripe's ~3-week retry window; a subscription never overwrites an admin-granted team/enterprise tier. The credit balance + Buy-Credit render via a shared `CreditBalanceCard` (also used compact by My API Keys). | [plan-billing.md](plan-billing.md) |
| Plugin AI-Native Sessions | Shipped always-on 2026-08-06, no Lab flag — the in-plugin session experience: a Sessions pane inside every plugin surface ("+ New session" right there, shared SessionHostSidebar, webview yields to the chat on open), user-started plugin sessions first-class in the inbox/badges, and purpose-built first-message auto-context teaching the AI the plugin's live CLI actions, the `/plugins/:id/cli/:path*` call recipe, the 202+approvalRequired inbox-approval semantics, and opt-in grant-scoped reach into the user's OWN repos via `ui.sessions.realProjectContext` (the plugin builds the block from its own `context` action) | [plugin-ai-native-sessions.md](plugin-ai-native-sessions.md) |
| Plugin Bridge Capabilities — part 2 (the higher-power capabilities) | The second half of the plugin bridge page: the capabilities a plugin must ask for by name — `sessionHistory` (a per-project scoped read of your past work), `ctx.workspace` plus its write/exec slice (files inside a project you picked, and approved commands), `documents.*` with reopen-after-restart, `ai.generateStructured`, `stt.*`, `share.publishArtifact`, `spend.getBreakdown` and `inbox.postAlert` — and how they fit together into one consent story. | [plugin-bridge-capabilities-part-2.md](plugin-bridge-capabilities-part-2.md) |
| Plugin Bridge Capabilities (what a plugin can call) | The sandboxed `window.AgentMC` bridge methods a plugin calls to reach host powers — including watching a session live (`host.sessionOutput` for a session the plugin launched, `sessions.observeStatus` for the ambient overlay status feed) — documents the higher-power capabilities: `export.savePdf` (render HTML→PDF through the native Save dialog, no permission), `ctx.sessions.*` (spawn and drive a Claude session — with NO `scope` it runs in the plugin's own virtual project `__plugin_<id>__`, with a `scope` of `{ projectId, worktree }` it runs in a REAL user-granted repository with full tool access and needs THREE things at once: the `sessions` permission, the `workspace.exec` manifest tier (a read-tier consent string cannot authorize a writing/running agent) and a live per-project workspace grant that is re-checked on EVERY later call, so revoking a project stops a session already running; `worktree: null` = the main checkout, the host resolves the directory from the grant and never re-derives it from the caller's string, ownership asserted per call. WORKER LEG ONLY: cursor polling via `getMessages(id, { after, limit })` — every message carries the opaque cursor pointing AT it, it survives an app restart, a cursor-less call returns the NEWEST page not the oldest, the body field is `text`, and partial/streaming rows are deliberately INCLUDED as the liveness signal; the webview read has no cursor, filters partials and uses `content`. `fanout` is gated on `sessions.launchAny`, NOT `sessions`), `sessionHistory.*` (read the user's GRANTED past session/project history under a scoped + audited + persisted privacy model, permission `sessions.readHistory`), `ctx.workspace.*` (read actual FILES on disk inside one user-picked project and its worktrees — WORKER-BACKEND ONLY, no `AgentMC.workspace`; default-deny, handle-addressed rather than path-addressed, built-in sentinel projects (`__claude__` et al) refused via `isSentinelPath` NOT `isVirtualProject`, project-local secrets refused by the shared deny-floor, revoke lands mid-walk; ONE live worktree list via `listWorktrees(projectId)` that blocks on git rather than a cache and is guaranteed to agree with the read gate, with reach outside the four conventional layouts earned PER CANDIDATE by proving the directory's git dir lives inside the project; permission `workspace.read`. `workspace.write` adds `writeFile`/`writeFiles`/`mkdir`/`deleteFile` behind a hardened write gate; `workspace.exec` adds TWO command paths that share ONE authorization — `run` (one-shot, 30s default / 120s max, output returned once, silent for exactly `git status --porcelain`/`--short` and confirmed otherwise) and the JOB runner `exec`/`execStatus`/`execResults`/`execCancel` (hours-long, ALWAYS confirmed, no wall-clock cap — killed by 15-min silence on both streams, never by age — head+tail output, per-plugin job ids, no host path ever returned). PATH points opposite ways on purpose: `run` strips the project's own `node_modules/.bin`, `exec` prepends it. Contract: plugin-workspace-exec-contract; and every command a plugin actually runs is RECORDED — a bounded per-day rollup per distinct command, flagged when it ran without asking, shown in the plugin's access panel and readable over `GET /plugins/:id/workspace-commands`), `documents.*` (read AND WRITE the raw bytes of ONE binary file the user picked in a native dialog — the only plugin-reachable write outside its own data dir; no declared permission because the dialog IS the consent, opaque Handles that carry no path and grant no folder reach, saving is append-only compare-and-append with `expectedLength` under a bound that can never discard more bytes than it writes, a Handle authorizes a FILE not a path, so an ordinary rename-over save is re-validated and carried over while a redirect onto a protected file is refused; reads are serialized against saves under a lock keyed on the canonical PATH (identity cannot key it once identity is allowed to move); `~/.claude`/`.ssh`/`.env`/private keys are refused on READ as well as write and a multi-select is all-or-nothing; the read URL carries a per-Handle capability token; handles are capped 32/plugin + 64 MiB/file with a rate-limited picker; and the whole namespace ships DARK behind the `plugin-documents-io` flag), `ai.generateStructured` (forced-tool structured generation on the user's account under a host-enforced per-plugin daily spend cap, permission `ai`), `share.publishArtifact` (publish HTML to a shareable link, permission `firebase`), `spend.getBreakdown` (read-only, no-args typed AI-spend breakdown — coding VALUE vs real out-of-pocket, host owns now/tz, permission `spend`), and `inbox.postAlert` (post a persistent MARKDOWN inbox card, forced text/agent + security dedupKey prefix `plugin:<id>:<key>`, reuses permission `inbox`), and `stt.transcribe`/`stt.isConfigured` (hand the host a recording, get a transcript back, the speech-provider key never reaching plugin code — batch only, 10 MB decoded cap matching the providers' own limit, oversize REJECTED never truncated; SILENCE RESOLVES `{ text: '' }` while only a real failure rejects, so an expired key can never surface as "no speech detected"; failures carry a machine-readable `err.code`; `mimeType` is advisory and the byte-sniff wins. Gated on `stt`, which is deliberately SEPARATE from the new `microphone` permission that governs opening the mic in the plugin's own webview — one ships the user's speech to a third party, the other opens a live sensor, and holding either does not grant the other; spend rides the user's existing daily voice cap + the Pro entitlement check, with no per-plugin dollar cap because STT bills to `stt-<unit>` not `plugin:<id>` so such a cap would read zero forever); points to bridge-method-schemas.ts + plugin-permissions.ts for the full surface | [plugin-bridge-capabilities.md](plugin-bridge-capabilities.md) |
| Plugin Capability Card | A one-line, dismissible "{plugin} can take actions for you with AI. Anything sensitive asks your approval first." disclosure at the top of a plugin's Sessions pane. Shipped always-on 2026-08-06, riding on `plugin-ai-native-cli` (no dedicated flag of its own): shows whenever the plugin manifest declares >=1 `cli.endpoint`, until dismissed. Dismissal (the card's ✕) is per-plugin and permanent (`dismissedPluginCapabilityCards` setting). DISPLAY-ONLY — no endpoint list, no counts, no approval badges, nothing to click but Dismiss; DF-0005 confirm/approve/execute is unchanged. | [plugin-capability-card.md](plugin-capability-card.md) |
| Plugin CLI Discovery (using plugins from any session) | How any session discovers installed marketplace plugins and drives them via CLI. When a user mentions a tool/service by name and the session does not recognize it, call `GET /plugins` to check if it is an installed plugin (returns id, name, version, enabled state). Plugins may expose CLI endpoints at `/plugins/<id>/cli/<path*>` (shipped always-on 2026-08-06, no Lab flag); approval-gated actions return HTTP 202. Covers the Our Four AI-native plugins (Smrzz content summarization, GitHub Integration, Calendar Scheduler, Newsletter Builder) and scales to any future marketplace plugin. | [plugin-cli-discovery.md](plugin-cli-discovery.md) |
| Plugin Developer Mode (load unpacked) | Settings → Plugins → **Developer Mode** — build plugins straight from a source folder on disk, Chrome-extensions style: toggle the mode (explicit trust copy; OFF = kill switch that unloads every dev plugin), **Load unpacked plugin** picks a folder with a `manifest.json` (invalid manifests show the verbatim error), the plugin loads with a **DEV** badge and outranks marketplace/built-in copies of the same id; hot reload (UI edits reload the webview, manifest/backend edits auto-cycle), per-plugin live status + verbatim last error + log tail, webview dev toolbar with Reload + Open DevTools, Reset storage, and Remove (never deletes the source folder). Desktop-only; channels `plugin:dev-*` are WS-blocked; settings pair is INTERNAL_ONLY | [plugin-dev-mode.md](plugin-dev-mode.md) |
| Documents Permission (what a plugin must ask before touching your writing) | The permission card at install / re-approve. Two levels on the `workspace.read`/`.write` precedent: **"Read your documents"** (open, search, AND publish to a connected Google account — publishing is named because `publishToGoogleDoc` is EGRESS and "open and search" would understate it) and **"Create, edit and delete your documents"** (deletion in the LABEL, not the small print, because it is the irreversible part). No separate delete tier: a plugin that can `saveContent('')` already destroys the document. All 27 `writer` methods are gated PER METHOD via an exhaustive `Record<WriterMethod, PluginPermission>` — a method with no row fails to COMPILE, and an unmapped one is DENIED (stricter than the `decks` case, which leaves unmapped ungated). The paid `ai*` methods stay on `ai`. The AI Writer now declares what it uses, so existing users get a one-time "Needs your permission" re-approval — it always could delete their documents, the card just never said so. **Migration steps 1-3 only:** the `pluginId !== 'writer'` identity check still stands, so NO third party can reach documents yet; step 4 is a separate release, and the SDK gap is NAMED (`SDK_PENDING_PERMISSIONS`) until it lands. Contract: plugin-core-data-permission-contract. | [plugin-documents-permission.md](plugin-documents-permission.md) |
| Plugin Marketplace — part 2 (privacy, quality and the developer side) | The second half of the marketplace page: exactly what data a plugin may ask to read and what it can see you doing, the rating and error surfaces, the developer dashboard, and the machinery behind a listing — who may submit (the publisher gate), package signing, and how the registry, install and update paths actually work. | [plugin-marketplace-part-2.md](plugin-marketplace-part-2.md) |
| Plugin Marketplace | Settings → Plugins → **Browse Marketplace** card — fetches a public GitHub registry, shows install/uninstall buttons per plugin, amber **Update** chip when your version is stale; SHA-256 checksum per file, 15s timeout, 256KB / 5MB size caps, 5min cache TTL, atomic temp-dir install + rename; IPC channels `marketplace:fetch-registry` / `:install` / `:uninstall`, push event `plugin:registry-changed` | [plugin-marketplace.md](plugin-marketplace.md) |
| Plugin Settings Panel (a plugin's own settings screen) | Settings → Plugins → the plugin's card → **Settings**. A plugin declaring `ui.settingsPanel.entryPoint` gets a Settings button that opens its own settings screen full-width with a back link (the list's search/sort/filters survive the round trip). The panel is ADDITIVE — the manifest-declared `settings` fields always still render above it, so a panel that fails to load can never lock the user out of configuring the plugin; the card shows the button XOR the inline field disclosure, never both. Grouped by plugin by construction: no Settings nav row and no section id, so a plugin cannot place itself in the top-level Settings list. Adds NO permission and NO bridge namespace (it is the plugin's own webview at its own entry point). `entryPoint` is validated stricter than its `ui.entryPoint` / `overlay.entryPoint` siblings — no scheme, no absolute/drive-qualified path, no `..` segment — rejected at manifest parse rather than at runtime with a blank frame. Contract: plugin-settings-panel-contract. | [plugin-settings-panel.md](plugin-settings-panel.md) |
| Shared Sign-In (one Google login across the plugins you allow) | The elevated `auth.sharedSignIn` permission. Plugin panels each got their OWN cold `persist:plugin:<id>` partition, so Google's account chooser was empty in every plugin and a user retyped their password once per machine PER PLUGIN. A plugin declaring the permission renders on ONE shared jar (`persist:plugin-signin`) and may open an OAuth popup (previously pinned off for every plugin), so a sign-in in any opted-in plugin warms the chooser for the rest; a plugin that does not declare it is byte-for-byte unchanged. **The first sign-in still happens once** — the jar starts empty, and it is deliberately NOT `persist:browser` (sharing the user's general browsing jar was considered and rejected). The cost, named in the consent copy: all plugins share one 127.0.0.1 ORIGIN and are separated only by partition, so opted-in plugins can read each other's saved sign-in data — hence the elevated tier, the consent card NAMING current jar members, and a Settings list + one-click sign-out. Main is the authority: the renderer's `partition` attribute is a REQUEST, re-checked against main's own registry, FAILING CLOSED with no authority callback and loopback-src only (a `file://` cold-start panel keeps its own jar). The jar is keyed to no plugin, so a sibling uninstall cannot wipe it and a sweep clears it once nobody opts in. Contract: webview-oauth-popup-contract. | [plugin-shared-signin.md](plugin-shared-signin.md) |
| Plugin UI Contributions | Plugins can add their own buttons to the header toolbar and session menus, and navigate the app to a session, hub, or view. Shipped always-on 2026-08-06 (no Lab flag, setting `pluginUiContributionsEnabled`). Plugin chrome is desktop-only — the phone/WS bridge blocks plugin navigation and dispatch over the wire. | [plugin-ui-access.md](plugin-ui-access.md) |
| Plugin widgets (a plugin shows LIVE content in the titlebar) | **In-development, off by default** (`plugin-widgets`). A plugin pushes a declarative `WidgetSpec` via `widget.set` / `widget.clear` and **Omniscio renders every pixel**: five closed shapes (stat / pill / dot / gauge / sparkline), a closed semantic tone enum mapped to the app's own `status-*` tokens (the plugin picks a MEANING, never a colour), an icon by NAME from an allow-list that shares no glyph with a header widget or Settings, and 8/16/120-character text caps that are an **anti-phishing control, not layout** — the titlebar is where the account switcher lives, so a plugin able to draw freely there could fake a sign-in prompt beside the real control. The plugin draws arbitrary pixels ONLY inside the click-to-open popover: its own sandboxed webview, lazily mounted, under a host-drawn attribution bar rendered in Omniscio's DOM that it cannot restyle, hide, or cover. Needs `chrome` **plus** its own `chrome.widget`, so a plugin already approved for a header BUTTON does not silently gain the titlebar; gated in BOTH processes; desktop-only; vanishes the moment its plugin is disabled. Reuses the header block row, so drag-reorder and Settings → Widgets hiding work with no new code. Reference consumer: RepoGuard's fleet-health score. Contract: plugin-widget-contract. | [plugin-widgets.md](plugin-widgets.md) |
| PM Agent Trust (G13 — trust levels and approval gates) | In-development trust layer controlling what AI agents can do on PM boards — three board-level trust levels (read-only / status-only / full-access) and three approval tiers that gate destructive actions, with progressive trust that can promote safe actions over time. | [pm-agent-trust.md](pm-agent-trust.md) |
| PM Calendar Overlay (due dates on the calendar) | Shows PM item due dates and sprint timelines on the Google Calendar panel alongside real calendar events, read from the local SQLite mirror, color-coded by board, with overdue highlighting. Read-only overlay (no mutation of Google Calendar). Requires `missionControlEnabled` + `pmCalendarOverlayEnabled` (default true). | [pm-calendar-overlay.md](pm-calendar-overlay.md) |
| PM Composability (G3 — feature interaction validation) | In-development validation engine governing which of the 65 PM features can be enabled, disabled, and combined — a directed dependency graph with enable-time, runtime, and disable-time checks, plus 13 internally-consistent presets across three categories. | [pm-composability.md](pm-composability.md) |
| PM Cross-Board Intelligence (G2 — cross-board reasoning) | Shipped backend infrastructure that aggregates data across all PM boards into materialized snapshots (hot/warm/cold tiers) for cross-board reasoning, natural-language querying, seasonal urgency, lead-time tracking, and pattern detection. | [pm-cross-board-intelligence.md](pm-cross-board-intelligence.md) |
| PM Cross-Entity Links (link items to vault notes, mind maps, GitHub, etc.) | Bidirectional linking between PM items and 14 entity types (vault notes, mind maps, diagrams, whiteboards, flowcharts, URLs, writer documents, email threads, meetings, GitHub PRs/commits/branches/issues). LinksTab in item card, backlink chips in linked tools, a plugin bridge path for sandboxed surfaces. GitHub commit and PR links can be created automatically by polling scanners. | [pm-cross-entity-links.md](pm-cross-entity-links.md) |
| PM Data Density (earn-the-right-to-speak gatekeeper) | In-development density tracker that monitors per-domain usage accumulation across six domains and determines when the PM has enough data to speak intelligently — distinguishes fresh-start from import users and detects six behavior patterns (repeated status changes, batch behavior, time-of-day, etc.). | [pm-data-density.md](pm-data-density.md) |
| PM Discovery Callouts (proactive inbox suggestions) | In-development feature that surfaces cross-tool connection nudges and automation offers based on detected behavior patterns as inbox cards, with a background scanner running every 6 hours. | [pm-discovery-callouts.md](pm-discovery-callouts.md) |
| PM Documents, Spreadsheets & Forms (three workspace entity types, in development) | Three workspace-scoped entity types inside Mission Control — **documents** (a title and a body, in a draft / published / archived state), **spreadsheets** (a title, a description and a saved config) and **forms** (the same plus a draft / active / closed state and a response count) — each with its own left-nav section, list page and detail page, plus ten built-in starter templates (four documents, three spreadsheets, three forms). The whole area sits behind ONE in-development switch (`pm-documents`, setting `pmDocumentsEnabled`, default off; also requires `missionControlEnabled`), and off means invisible everywhere: the nav sections are gone, the six routes are unregistered so a typed URL or stale bookmark redirects home, every CLI route 404s, the three template categories stay "Coming Soon", and none of its data is fetched. Deleting is soft — the row survives and is stripped from every read path — and every read and write is checked against the item's own workspace, so an item id is not permission to see it. | [pm-documents-spreadsheets-forms.md](pm-documents-spreadsheets-forms.md) |
| PM Email Integration (link emails to PM items) | In-development integration bridging PM items with Gmail, Agent Email, and Supermail — link email threads to items, create items from emails, and trigger workflow automations on incoming emails, with PM action buttons across all three email surfaces. | [pm-email-integration.md](pm-email-integration.md) |
| PM Feature Profiles (G12 — per-board progressive disclosure) | In-development progressive disclosure engine that controls which PM features are visible per board via three presets (Tasks / Projects / Operations) plus per-board customization and a contextual nudge engine that suggests features based on board data patterns. | [pm-feature-profiles.md](pm-feature-profiles.md) |
| PM Goals (hierarchical goal tracking) | Workspace-scoped hierarchical goals with auto/manual progress tracking, board linking, activity feeds, and comments. Goals sit above boards as strategic objectives. | [pm-goals.md](pm-goals.md) |
| PM Import Framework (import data into Mission Control boards) | Universal import gateway that converts external data from 11 adapters (CSV, Google Sheets, Excel, Trello, Notion, Jira, Monday.com, Asana, ClickUp, Linear, Airtable) into local PM boards via a 7-stage pipeline: extract (adapter produces a canonical IR), map (column type inference), validate (structure + limits), execute (transaction-wrapped SQLite writes via pm-queries.ts upserts), report (counts + entity map), landing board (post-import board selection + table view guarantee), preset application (auto-apply engineering presets for Linear/Jira imports). Adapter pattern: implement `ImportSourcePlugin.extractToIR()` and the pipeline handles the rest. Job tracking in `pm_import_jobs` + cross-job entity dedup in `pm_import_entity_map` (liveness-checked). Conflict strategies: skip (default), overwrite, and merge. Includes an import wizard UI, 8 CLI routes for programmatic access, and connected source refresh for Google Sheets. | [pm-import-framework.md](pm-import-framework.md) |
| PM Intelligence Advisor (cross-board strategic advice + quick questions, in development) | In-development advisory intelligence layer for the AI Project Manager (gated via the `pm-intelligence-advisor` unreleased-feature, `pmIntelligenceAdvisorEnabled` / `AMC_SHOW_PM_INTELLIGENCE_ADVISOR=1` / Settings → Lab toggle), surfaced as an Omniscio built-in virtual project labeled "PM Advisor" (`__pm_advisor__`) docking in the main panel beside the projects sidebar — NON-spawnable (renders its own UI, hosts no Claude session). Turns the PM Cross-Board Intelligence snapshots into actionable advice: strategic insights ranked by severity (resource conflicts, cascading delays, effort drift, seasonal risk, cross-department), strategic coaching, Monte-Carlo completion prediction narratives with what-if, automation policy recommendations, shift-handoff enrichment, and a plain-English quick-question box grounded in the current board data (template-first, LLM-escalated per the PM AI comfort setting, daily-capped). The first panel wires the insights list + the quick-question box. | [pm-intelligence-advisor.md](pm-intelligence-advisor.md) |
| PM My Work (cross-board personal task view) | A cross-board personal task view aggregating every item assigned to you across all Mission Control boards, organized into six date buckets (Past Dates through Without a Date) with table and calendar views. | [pm-my-work.md](pm-my-work.md) |
| PM Notification Preferences (per-board notification controls) | Shipped per-board notification preferences for Mission Control — mute, promote, email delivery mode (off / instant / digest), and digest frequency (daily / weekly) per board. | [pm-notification-preferences.md](pm-notification-preferences.md) |
| PM Onboarding Features (import + post-import flows) | Three in-development PM onboarding features for users migrating from other platforms — a persona-C import entry screen with multi-select platform cards and auto-applied presets, discovery callouts, and post-import guidance. | [pm-onboarding-features.md](pm-onboarding-features.md) |
| PM Onboarding and Help (preset-scoped checklist + contextual tips) | In-development onboarding checklist and contextual help system giving PM users preset-scoped guidance (tasks/projects/operations) through four surfaces — a floating checklist, an auto-created Setup Checklist board with AI-guided steps, contextual tips, and help triggers. | [pm-onboarding-help.md](pm-onboarding-help.md) |
| Ops Engine (PM operational dashboard, in development) | In-development operational dashboard for the AI Project Manager (gated via the `pm-operations-engine` unreleased-feature, `pmOpsEngineEnabled`), surfaced as an Omniscio built-in virtual project labeled "Ops Engine" (`__pm_ops_engine__`) docking in the main panel beside the projects sidebar — NON-spawnable (renders its own dashboard UI, hosts no Claude session). Per-board per-action-type policies (Auto / Propose / Never, default Propose), 10 registered action types, session shepherd (60s tick), work queue manager, trust promotion after 5 consecutive approvals, shift handoff reports, and a cached dashboard with health scores. Zero AI cost (all rule-based). Kill switch: `AMC_DISABLE_PM_OPS_ENGINE=1`. No CLI routes registered yet. | [pm-operations-engine.md](pm-operations-engine.md) |
| PM Portfolios (cross-board aggregation) | Named groupings of PM boards within a workspace for unified status summaries (total items, done items, status-bucket breakdown across boards). | [pm-portfolios.md](pm-portfolios.md) |
| PM Predictive Analytics (G9 — velocity, forecasts, risk) | In-development predictive analytics layer: velocity tracking over configurable windows, Monte Carlo completion forecasts, what-if scenarios with three lever types, and risk heatmaps with cascading cross-board impact. | [pm-predictive-analytics.md](pm-predictive-analytics.md) |
| PM Search Integration (PM items in global search) | PM items in global search (Ctrl+K) via full-text and semantic embedding similarity, with a "Use as context" clipboard action and a `PM_SUGGEST_ITEMS` semantic suggestion channel. Session-PM dedup removes standalone PM results when a session is linked. Embeddings in `pm_item_embeddings` (384-dim float32). | [pm-search-integration.md](pm-search-integration.md) |
| PM Session Link (bidirectional session-to-item linking) | A working session can link to a PM item bidirectionally: the session header shows a chip with the item's name, and the board shows the agent's live progress (idle/running/needs_you/finished/error). The link is atomic (one SQLite transaction). CLI route `POST /pm/items/:id/start-session`. | [pm-session-link.md](pm-session-link.md) |
| PM Sprints (time-boxed iteration management) | Sprint lifecycle (planned/active/completed), item assignment, velocity tracking with burndown/trend charts, and AI-powered retrospectives with spend caps. | [pm-sprints.md](pm-sprints.md) |
| PM Stickers (decorative stickers on item cards) | Decorative emoji-style stickers (thumbsup, heart, star, check, clock, warning, celebrate, rocket) that users place on board items with free positioning, rotation, and z-ordering. 5 IPC channels, SQLite-backed with soft-delete. | [pm-stickers.md](pm-stickers.md) |
| PM + Team Chat Integration (item mentions, task creation, status updates) | In-development bridge between PM and Team Chat — #item mentions with rich inline chips, create-task-from-chat with bidirectional links, automatic status-update messages in linked channels, and a chat-messages section on PM item detail drawers. | [pm-team-chat-integration.md](pm-team-chat-integration.md) |
| PM Time Tracker Bridge (time tracking from item cards) | Time tab in the Mission Control item card to start/stop timers and view logged time against any PM item. Entries link via `pm_item_id` on `time_entries`. Reuses existing Time Tracker channels (no new write channels). Preserves single-running and derive-once-money invariants. | [pm-time-tracker-bridge.md](pm-time-tracker-bridge.md) |
| What Changed (unified cross-board PM activity feed, in development) | In-development unified PM activity feed (gated via the `pm-unified-feed` unreleased-feature, `pmUnifiedFeedEnabled` / `AMC_SHOW_PM_UNIFIED_FEED=1` / Settings → Lab toggle), surfaced as an Omniscio built-in virtual project labeled "What Changed" (`__pm_unified_feed__`) docking in the main panel beside the projects sidebar — NON-spawnable (renders its own feed UI, hosts no Claude session). A cross-board activity timeline ranked by significance (static weights + recency / board / mention factors), with a board / time / type / actor filter bar, inline actions (mark done, open in board), deterministic per-entry summaries plus AI batch summaries of the visible events, and an 8 AM daily digest delivered as an inbox alert. Backed by a multi-filter + paginated query layer over the existing PM event stream. No CLI routes registered yet. | [pm-unified-feed.md](pm-unified-feed.md) |
| PM Voice Actions (hands-free PM operations) | Hands-free PM operations via voice commands: create, move, update status, read, and list items. Reads work offline (local SQLite mirror); writes need a live connection. Swappable STT provider (Deepgram default, on-device Whisper alternative). | [pm-voice-actions.md](pm-voice-actions.md) |
| PM Voting (upvote items to signal priority) | Per-item vote toggling on board items to signal priority. 2 IPC channels (`pm:vote:toggle`, `pm:vote:data`), SQLite-backed, dedup on toggle, gated on `collab-voting` board feature flag. | [pm-voting.md](pm-voting.md) |
| PM Webhooks (outbound subscriptions and inbound receiver) | Outbound webhook subscriptions for PM board events with HMAC-SHA256 signed delivery, 3-retry backoff, auto-disable after 3 consecutive failures, and a dead-letter queue with periodic retry (15-min tick, 10-retry budget, 14-day backstop). Also the inbound receiver at POST /pm/webhooks/inbound/<token> — a public URL-token endpoint that takes external POSTs and folds them into board events, with an opt-in `X-Webhook-Signature: sha256=<hex>` HMAC over the raw body, a 401 (bad signature) vs 503 (secret unreadable, retry later) split, a 64 KiB body cap and a per-board 60/min limit. CLI routes for subscription CRUD and the inbound receiver's own management routes. | [pm-webhooks.md](pm-webhooks.md) |
| Pomodoro (focus-timer with schedules + stats) | Built-in pomodoro timer rendered as a tab of the Alarms virtual project — preset library (focus / short-break / long-break / cycles-until-long / total-cycles + per-preset alarm overrides + optional default project), single active run with 1Hz tick + phase chimes + pause/resume, recurring **schedules** that auto-start a preset at a wall-clock minute via atomic `last_fired_minute` claim (idempotent across restarts), pre-start toast 30s before, master kill switch `pomodoroScheduleEnabled` (default on), per-preset foregrounding default `pomodoroPhaseForeground` (default OFF — deliberately split from Alarms' default-true), Today / This Week / by-project stats with planned-vs-actual block; local-only, no AI, no cost; desktop-only configuration | [pomodoro.md](pomodoro.md) |
| Pop out a project or integration window | Pop a whole project (its session list + open conversation, switchable, can start new sessions) OR an integration's panel (Tasks / Recipes / Skills / Tools / Stats / …) into its own desktop window via **Open in new window** in the projects-sidebar right-click menu; ONE `projectId`-keyed window reuses the main `index` renderer entry via `?window=` (no new Vite entry); real projects render the workspace, virtual projects render their integration panel; the Google **Calendar / Drive / Sheets** panels pop out too (channel-adapters, eligible via the main-safe `POPPABLE_CHANNEL_PANELS` table); per-project window-position memory; theme-following; **Ctrl+W** (Cmd+W) closes it like its close button, as it does every pop-out window; KMS / Scratchpads excluded (they ship their own dedicated windows); Gmail + SMS (two-pane list+reader) deferred. Desktop only. | [pop-out-project-window.md](pop-out-project-window.md) |
| Portable Backup (one-file encrypted export/import, `.amcbackup`) | Settings → Backup & Restore → Portable Backup: one encrypted `.amcbackup` file (magic `AMCPB1`, format v2) you export and carry to another machine yourself (USB/cloud drive/email) — distinct from Backup Mirror's continuously-synced shared folder. Full mirror bundle (DB + config + attachments), zstd-compressed and then sealed under a random DEK (AES-256-GCM); the DEK is wrapped into unlock slots — a recovery-code slot (Crockford-base32, 160-bit, shown to the user exactly once, never persisted) always present, plus a device-key slot when this machine's OS keyring is available (an `'account'` slot type is reserved for a future phase). Import auto-selects FULL RESTORE on an empty install or an additive ALL-TABLE MERGE (existing rows always win) on a populated one, always preceded by a mandatory pre-import safety snapshot. **The two machines do NOT need the same app version** — rows are copied by column NAME, so an older or newer backup still merges; a newer backup reports anything this version cannot store, and only a genuinely incompatible backup (missing a required column, or a differing frozen baseline) is refused. Every SQLite table must be deliberately classified merge/exclude-system/exclude-ephemeral/session-engine before it can be imported (coverage-guarded). Opt-in `includeCredentials` re-wraps the config.json secrets into the sealed payload so an OS reinstall / machine change doesn't silently lose them — restored under the new machine's keyring (live on merge, staged-config reseal on full-restore); a keyring-unavailable import refuses rather than writing plaintext. CLI: `POST /portable-backup/export` (auth only; optional `{ includeCredentials }`) + `POST /portable-backup/import` (always approval-gated). A SECOND, independent off-machine copy of the same encrypted archive can live on Omniscio Cloud — `POST /portable-backup/cloud-export`, `POST /portable-backup/cloud-restore` and `DELETE /portable-backup/cloud-backup`; restore and delete are always approval-gated and full-CLI-token-only, and the delete is PERMANENT (it removes the off-machine recovery point with no undo). Currently an in-development ("Lab") feature, hidden by default (`portableBackupEnabled`) | [portable-backup.md](portable-backup.md) |
| Portable startup splash | Two-phase startup affordance for the portable .exe — static `build/splash.bmp` ("Unpacking files" + accent rule, no animation) during the C++ wrapper's ~1.6 GB re-extraction on EVERY launch, then a frameless live BrowserWindow during Electron's boot (~2–10 s) with a spinner + a step line driven by startup-trace marks, over a separate "still working" reassurance line; auto-closes on main-window `ready-to-show`; 90 s watchdog; env-var kill switches (`AMC_DISABLE_SPLASH=1`, plus test/e2e/sandbox skips); creation failures swallowed so splash can never block startup; ALSO documents the two release formats — single-file `.exe` (re-extracts every launch) vs instant-launch `(unzip-and-run).zip` (no extraction phase / no Phase-A splash) | [portable-startup-splash.md](portable-startup-splash.md) |
| Post-Restore Credential Wizard | After a Backup Mirror replace-mode restore on a different machine, Omniscio auto-detects that saved credentials (API keys, OAuth tokens, MCP server secrets) can no longer be decrypted and opens a wizard showing which ones are broken, with per-item Re-check and links to the right Settings screen. Three probe categories: Omniscio Accounts, Provider API Keys, MCP Server Secrets. Also accessible manually via Settings → Backup & Restore → "Run credential check…". CLI: `GET /post-restore/health`. Inbox alert raised when broken credentials are detected after a restore | [post-restore-credential-wizard.md](post-restore-credential-wizard.md) |
| PR Janitor (nightly closer for already-landed PRs, now in-repo) | The nightly job that closes GitHub pull requests on `jlstradingco/Agent-Orchestrator` whose work is already 100% on `origin/master`, investigates everything it leaves flagged read-only, and starts one de-duplicated rebase session per PR genuinely stuck on a conflict. Its program (`scripts/pr-janitor/`), its nightly procedure (`PROMPT.md`), and the short pointer stored in the cron job's own prompt (`CRON-POINTER.md`) live in this repo now — previously the whole thing was a database row and a folder on one machine. Two tables (`pr_janitor_runs`, `pr_janitor_dispositions`) record what each run did; a **PR Janitor** section inside the PR Merge Queue panel reads that history back read-only and offers **Dry run** (asks the engine what it would do, never `-Execute`, and writes no run record of its own) and **Pause** (stops the schedule). The engine judges against its own machine-local checkout, refreshed from `master` via `git archive`, never the shared repo checkout. Contract: pr-janitor-in-app-contract. | [pr-janitor.md](pr-janitor.md) |
| PR Merge Queue — part 2 (the machinery behind a queued PR) | The second half of the PR merge queue page, for the reader who needs to know what the queue does to a PR: what gets persisted, the in-flight dedup that stops a PR being handled twice, custom merge instructions and how to edit the merge prompt, the lane decision tree, the IPC channels, the auto-merge daemon and the AI summaries. | [pr-merge-queue-part-2.md](pr-merge-queue-part-2.md) |
| PR Merge Queue (GitHub PR triage + AI-merge) | Toolbar `<GitPullRequest>` icon opens an 8-lane board (`fast` / `standard` / `batch` / `conflict-likely` / `risky` / `hold` / `escalate` / `reject`) of open PRs across configured repos — pulls via `gh pr list` + `gh pr view`, runs triage (size + risky-paths + CI + overlaps) and orchestration locally, then a per-PR **Merge** button spawns a worktree-isolated Omniscio session on the PR branch with a composed merge prompt (bring the PR in / resolve / test / stop — never pushes); per-repo config (project, gh slug, base branch, risky globs, trust level) in `AppSettings.prMergeQueueRepos` | [pr-merge-queue.md](pr-merge-queue.md) |
| PR Visual Evidence (before/after UI screenshots + recordings on a coding-agent's PR) | When a coding-agent session finishes a UI-affecting change on an opted-in repo, Omniscio captures a **before/after screenshot** of the changed screen — or a short **before/after screen recording (video)** of the changed flow (Phase 2) — and attaches it — **privately to the session by default**, and to the **public GitHub PR** only on the repo's SECOND opt-in. The "before" is real: the platform rebuilds the pre-change version in a throwaway worktree, launches its dev server via the repo's **preview command**, captures it, then tears it down. **Best-effort** — a missing preview / failed build / missing ffmpeg / no PR never blocks the code change; the agent also skips when the two shots don't differ or synthetic data can't be guaranteed. Screenshots host on **GitHub user-attachments** — an access-controlled URL that follows repo membership (never a public capability link) — while a recording is size-capped and reuses the app's existing ffmpeg + short-expiry video-share machinery (no new dependency); the target PR is auto-detected from the session's own branch on its own origin repo (ownership-validated, idempotent). **In-development, OFF by default** (`prVisualEvidenceEnabled` + per-project `prVisualEvidence` / `previewCommand` / `postToPublicPr` in Edit Project → More options). Capture reuses the embedded browser scoped to this feature. Contract: pr-visual-evidence-contract. | [pr-visual-evidence.md](pr-visual-evidence.md) |
| Foundry (AI-powered app builder) | Bundled plugin in the Omniscio built-ins divider — walks you through writing a PRD as a 13-step AI interview, with optional User/Developer/Designer red-team passes and an **Autopilot** mode that drives every step itself from a one-paragraph idea description (decision-card feed, step-grouped cards, decomposer + Build This Now handoff to a real coding session); settings for prompt-flow version and red-team toggle | [prdstack.md](prdstack.md) |
| Presentation Mode (recording-safe "show only what I pick") | A persisted switch (`presentationModeEnabled`) that makes the dashboard safe to screen-record: it hides your real products (projects) and sessions, your account name/email/avatar, live cost/spend, and leaky header chrome, revealing ONLY items you explicitly pick PLUS any session you personally start while on (auto-revealed by session `source` `'ui'`/`'quick-launch'`; automation/recipe/cron/background spawns stay hidden). Hiding is an ALLOWLIST (hidden unless revealed) and RENDER-TIME ONLY — nothing stored is ever mutated, so exiting restores everything instantly and it survives a restart. Three hide styles for a non-revealed item: **Remove** (filtered out; default + safest), **Blur** (masked in place), **Placeholder** (neutral/custom label). Controls: a header LIVE toggle, a backstage **Staging** panel (`PresentationStagingPanel`) to pick reveals + demo identity + hide style, two command-palette actions, and a **panic control** ("hide everything now") that forces the mode on and clears every reveal — bindable in Settings, with NO default key since it fired mid-typing on a commonly-mistyped chord and blanked a user's whole hub sidebar. Also suppresses transient leaks while on — routine toasts muted, the app-icon badge frozen to 0, OS/mobile push held — by REUSING the existing Do Not Disturb `silenceUntil` switch (crash-safe restore marker), plus an optional **content-scrub** that blurs message text inside an open session. Every sidebar visibility chokepoint applies `isPresentationHidden`, locked by a coverage lint. If it hides EVERY hub, the sidebar renders a named empty state with a one-click exit (never a toast — toasts are muted while presenting). Known limit: scoped to the on-camera sidebars + identity/cost/title/toast/badge/push chrome — the SMS/KMS/Mind Map/AI-Coaching integration sub-sidebars are out of scope, as is the MOBILE hub list, which applies no presentation filter at all. Contract: presentation-mode-contract. | [presentation-mode.md](presentation-mode.md) |
| Productivity group (sidebar) | Collapsible sidebar group nesting Tasks, Scratchpads, KMS, Time Tracker, File Converter, Browser, Ollert, Arij, ContextDock, Coffer, Habits, and Mission Control — the catch-all for organize/track/manage-your-work tools; ships collapsed by default; render-only nesting | [productivity.md](productivity.md) |
| Auto Context — part 2 (instruction docs, CLI Control and the internals) | The second half of the Auto Context page: how one doc is promoted to an authoritative instruction, how files are added or removed from outside the app through CLI Control, and the plumbing underneath — where the docs live, how they sync into `CLAUDE.md`, and how a binary rides along on the session's first message. | [project-docs-auto-injection-part-2.md](project-docs-auto-injection-part-2.md) |
| Auto Context (Claude.ai Projects parity) | Unified Dashboard-sidebar panel **Auto Context (N)** with a search filter + three sub-groups — **System Instructions** (project + global CLAUDE.md / MEMORY.md, view/edit-only), **Always-inject** (`.claude/docs/` top level, auto-injected, counts toward 125K cap), **On-demand context** (`.claude/docs/rag/`, TOC-only catalog the agent `Read`s on demand, uncapped). Drop files in `<project>/.claude/docs/`; text syncs into `CLAUDE.md`, binaries auto-attach to every session's first message. Renamed from "Project Docs" 2026-05-27 | [project-docs-auto-injection.md](project-docs-auto-injection.md) |
| Auto Context — selection mode + bulk actions | Multi-select on the **Auto Context** sidebar panel — Select square at the right end of the filter search row enters selection mode, click toggles a row, Shift+click ranges, Ctrl/Cmd+click auto-enters; bulk **Copy** concatenates contents with `--- filename ---` headers (5 MB cap, binary placeholder), bulk **Delete** loops through FILES_DELETE behind one confirm; right-click adapts to bulk menu when 2+ selected; single-doc **Copy contents** added to both menus; focus-scoped Esc / Ctrl+A / Ctrl+C / Delete shortcuts (Ctrl+A respects current search filter); **System Instructions rows never participate** — bulk-select skips them so a stray Ctrl+A + Delete can't wipe CLAUDE.md/MEMORY.md; desktop only | [project-docs-selection.md](project-docs-selection.md) |
| Project folder missing (recreate or relink) | Red "Project folder is missing" banner with Recreate Folder button when the session's project path no longer exists on disk (moved, renamed, unmounted drive) | [project-folder-missing.md](project-folder-missing.md) |
| Project Kickstart (second guided mission) | The second guided mission — turn an idea into a starter project folder (folder + plan + a file you can open); reached from the mission picker (blank-session nudge or project empty-state); never auto-launched; six card beats: kickoff → pick type → quick interview → confirm understanding → approve plan → done with undo; Windows-only in v1 | [project-kickstart.md](project-kickstart.md) |
| Project Notes (markdown scratchpad per project) | Per-project local markdown note — private, not searched, not shared with Claude; three-dot menu → Edit Notes | [project-notes.md](project-notes.md) |
| Projects Sidebar — default Omniscio group | Fresh installs seed an "Omniscio" divider grouping the 14 built-in virtuals (Session Search, Quick Replies, Automations, Daily Digest, Recipes, Cron Jobs, Skills, CLI Tools, Tags, Foundry, AI Coaching, Suggestions, Stats, Settings); upgrades re-parent ungrouped virtuals only | [projects-sidebar.md](projects-sidebar.md) |
| Pre-send spend warning (warn before an expensive prompt) | Warns you before you send a prompt estimated to cost more than a threshold you set — API-key users set a per-model dollar cap, subscription users set a 5-hour rate-limit percentage. Catches a pricey turn before it sends (vs. AI spend alerts, which report after the fact). Off by default. Shipped; setting `promptSpendWarningEnabled`. | [prompt-spend-warning.md](prompt-spend-warning.md) |
| Prompt Tools group (sidebar) | Collapsible sidebar group nesting Super Prompts, Super Prompt Creator, Bake-Off, AI Council, and Clean Room — craft, run, and reuse prompts; ships collapsed by default; four action rows fire a dialog/picker/launch on click instead of switching projects | [prompt-tools.md](prompt-tools.md) |
| Auto-continue on balance refund (resume out-of-credit DeepSeek/Kimi sessions once funded) | When your own API-key **account runs out of credit** (DeepSeek or Kimi), the provider rejects the turn for non-payment; the session first moves to the next row of the model family's Who pays & who serves list, and only when no row can pay does Omniscio park it in a red **"Out of credit"** state with the provider's Add-credit link. With this feature on, a background governor (~every 10 min) watches the account balance and **auto-continues every out-of-balance session the moment you top the account up** — no manual restart — and **reopens the account for every list** at once instead of waiting for its ten-minute re-check (its "Out of credit" inbox card goes away too). It polls each provider's balance ONCE per tick (free, no AI tokens), resumes only when the account is genuinely funded (never on a failed check or an empty balance, so no paid turns are wasted), and leaves parked sessions visibly red until you add credit. Covers only providers with a balance endpoint — **DeepSeek + Kimi** (GLM/MiniMax/Meta have none, so a parked session there is resumed by hand, and their accounts come back only on the ten-minute re-check). Load-aware, per-session attempt cap, DB-owner-gated, kill switch `AMC_DISABLE_PROVIDER_BALANCE_RESUME=1`; balance-poll API keys stay Main-only (never to the renderer, never logged). Distinct from the Kimi balance *monitor* (which only *alerts*). **In-development, off by default** (`providerBalanceAutoResumeEnabled`; graduates to on-by-default). Contract: provider-balance-autoresume-contract. | [provider-balance-autoresume.md](provider-balance-autoresume.md) |
| Sync config to other AI CLIs (in development) | In-development, off-by-default feature (gated via the `provider-config-sync` unreleased-feature; Settings → Lab toggle or `AMC_SHOW_PROVIDER_CONFIG_SYNC=1`). Installs your flagged custom MCP servers — plus optional agent instructions and your real skill folders (whole `SKILL.md` folders copied into each tool's skills dir so they're runnable; OpenCode reads `~/.claude/skills` natively; Cursor into picked project folders) — into the machine's other installed AI CLIs (Codex, Gemini, OpenCode, Cursor) via each tool's own `mcp` command or a direct config-file merge. Additive, idempotent, fail-soft; secret-bearing servers are never written out; never touches Omniscio's per-session `.mcp.json`. Reach the panel via Settings search. | [provider-config-sync.md](provider-config-sync.md) |
| Provider outage alerts (multi-provider status monitor) | The same automatic outage alerting Claude has, extended to the OTHER API providers you use — but only surfaced for a provider you have actually USED in the last 7 days (a coding session OR a background feature that billed against it), so your inbox never fills with noise about providers you don't touch. Watches only providers with a reliable public status feed: OpenAI (status.openai.com — Codex/GPT), Cursor (status.cursor.com), and Groq (groqstatus.com), on top of Claude's own monitor. Providers with no reliable feed are deliberately not watched (Google/Gemini, xAI/Grok whose feed blocks automated access, DeepSeek/OpenRouter). A relevant incident raises ONE deduped inbox card + ONE desktop notification per provider, with a **View status page** button opening that provider's OWN status page (a fixed trusted address, never a feed URL) alongside the universal Start-session; auto-clears on recovery, dismissal sticks across restarts, and a card is quietly revoked if you stop using that provider. An unused provider isn't even polled. On by default; Settings → Notifications → Other provider outage alerts (`providerStatusMonitorEnabled`); kill switch `AMC_DISABLE_PROVIDER_STATUS_MONITOR`; inert in e2e/sandbox. | [provider-status-alerts.md](provider-status-alerts.md) |
| Pull Requests (cross-repo GitHub PR manager) | **Removed from Omniscio core (in-core GitHub detachment) — plugin-only now.** Formerly a sidebar tab that listed the GitHub pull requests you are involved in across every repo your account can access — filter chips for Created by me / Review requested, open a PR to see its description, changed files, checks, and review timeline, then add a comment, Approve / Request changes, or Merge (confirmation-gated, the one irreversible action) without leaving Omniscio. Shells out to the `gh` CLI (shows a one-click Connect GitHub install + sign-in if `gh` is missing); virtual project `__pull_requests__`, all data over `GH_PR_*` IPC, registered shipped in the unreleased-feature registry (id `pull-requests`) | [pull-requests.md](pull-requests.md) |
| Question Widget — part 2 (the parser, the format hint and persistence) | The second half of the Question Widget page: the literal `## Questions` heading in a Plain Speak rewrite that anchors the parser so lead-in prose cannot trigger a false widget, the short formatting hint Omniscio puts in your first message of each session, which parser version every install runs, how widget state survives a restart, and the implementation pointers for anyone touching the code. | [question-widget-part-2.md](question-widget-part-2.md) |
| Question Widget (inline answer pills) | Agent multiple-choice questions render as pill widgets inside the message — but the clickable widget appears only on the **last VISIBLE agent message**, and it retires the moment you answer it — a pill, a typed reply or a Quick Reply — or once a newer visible agent reply supersedes it (a nudge, a folded no-op or a check-in counts as neither); arrow-key navigate multi-question sets; question text stays at a stable Y across navigation; toggle off via Settings → Sessions → Keep question position stable; in Plain Speak rewrites, a literal `## Questions` heading anchors the parser so lead-in prose can't trigger false-positive widgets | [question-widget.md](question-widget.md) |
| Queue a message ("send after the agent finishes") | Line up one or more messages that auto-send as the agent finishes each turn — WITHOUT interrupting the current step. Entered via the Send Later picker's "After the agent finishes" option (first choice, above the time presets, offered only while the agent is working and until you type a time); a per-session queue (cap 50) shown by the composer that you can edit / reorder / remove, delivered one-at-a-time in order via the normal send path, durable across restart, retries-then-visibly-gives-up on failure. Distinct from time-based Send Later (one reply, clock trigger). | [queue-a-message.md](queue-a-message.md) |
| Quick Email — part 2 (how it works inside) | The second half of the Quick Email page, for a repo-aware reader: the file-level internals behind the composer — the main-side send service, the pending-send map and its timers, the push toasts, the global undo claim, and the rest of what runs when you press Ctrl/Cmd+Enter. | [quick-email-part-2.md](quick-email-part-2.md) |
| Quick Email (Ctrl+Space → Email tab) | Send a short email in two keystrokes from the Quick Launch / Control Space composer — pick a saved recipient (up to 6, each with optional name/email/global-hotkey), optional subject (hidden by default), type a body, Ctrl/Cmd+Enter; sends through your connected Gmail account after a configurable send-with-undo window (default 10s, clamped 1–30); main-side `quickEmailService` holds an in-memory pending map + Node timers and fires four push toasts (PENDING / SENT / CANCELLED / ERROR); a global Ctrl+Z (claimed only while a send is pending, released on drain) cancels the most-recent send LIFO; per-recipient global hotkeys open the composer pre-targeted at that person via `QUICK_LAUNCH_OPEN_TO_EMAIL`; pure-logic hotkey planner, injected `ShortcutBridge` for test isolation; gated on `quickEmailEnabled` (off by default), desktop-only | [quick-email.md](quick-email.md) |
| Quick Launch Modal — part 2 (the tabs) | The second half of the Quick Launch page: the tab strip beside the Session tab — what a non-Session tab is, repo tabs and how one is added, and the quick-actions sheet the same surface becomes on a phone. | [quick-launch-modal-part-2.md](quick-launch-modal-part-2.md) |
| Quick Launch Modal — part 3 (how it works and why) | The third part of the Quick Launch page: the internals for a repo-aware reader — where the modal lives in the code, how it decides which engine a session starts on, and the design decisions worth knowing, including the ones that look odd until you know why. | [quick-launch-modal-part-3.md](quick-launch-modal-part-3.md) |
| Markdown merge driver (auto-merge additive memory-doc edits) | Custom Git merge driver that auto-resolves the common parallel-worktree conflict — two agents independently _appending_ to the same memory doc (`MEMORY.md`, `postmortems/*`, `gotchas-*`, `feedback_*`/`project_*`/`reference_*`) — by unioning both sides' inserted lines with per-position dedupe, and falls back to standard `\|Quick Launch Modal (global-hotkey floating composer)\|Spotlight/Alfred-style floating composer that pops up over any app on Ctrl+Space (rebindable) for starting a new Claude session — textarea + project chip + mic + paste/drop attachments; own BrowserWindow, primary-display centered, hide-not-destroy across opens; voice dictation suppresses the main-window intent parser so transcripts go into the textarea instead of firing commands; Settings → System has hotkey / on-off toggle / default-project picker. On mobile the same pinned actions open from a ⚡ quick-actions sheet in the top header bar (session/repo tiles route to the native new-session flow) | [quick-launch-modal.md](quick-launch-modal.md) |
| Quick Replies (manage quick-reply library) | Sidebar "Quick Replies" virtual project with 3-tab sub-sidebar (Settings / Quick replies / Sessions); inline-edit list of quick replies + dividers + folders (unlimited nesting, `parent_id` column from v169), drag-into-folder or "Move to folder…" menu, collapse state in `collapsedQuickReplyFolders`, TWO-button delete-folder dialog (cascade vs. promote), AI Suggestions mirrored from main Settings, AI edit sessions seeded with full library inventory; toolbar Export (JSON file) / Share (public Omniscio Shares link) / Import (preview-then-confirm, add-only merge) | [quick-replies.md](quick-replies.md) |
| Declutter unused quick replies (remove one you've stopped using) | Local, no-AI background scan that notices a saved quick reply gone unused for 30+ days and drops ONE dismissible inbox card offering to REMOVE it in one tap, with Undo (a toast button + Ctrl+Z) that restores it exactly — the reverse of the repeated-phrase nudge. One card per scan (gentle drip), never re-nudges (a `quick_reply_declutter_nudges` ledger), and never flags built-in defaults, folders/dividers, building-block replies, or Inbox-Pilot-eligible replies. On/off in Settings → Features (`unusedQuickReplyDeclutterNudgeEnabled`, default on; also gated by Tips & Guidance). | [quick-reply-declutter-nudge.md](quick-reply-declutter-nudge.md) |
| Repeated-phrase quick-reply nudge (save a phrase you keep typing) | Local, no-AI background scan that notices when you type the same short phrase many times and drops ONE dismissible inbox card offering to save it as a quick reply — the exact (raw, un-scrubbed) phrase prefilled in the add-editor, nothing saved until you click Save. One nudge per scan (gentle drip), never re-nudges (a `quick_reply_nudges` ledger) and skips phrases you already saved; excludes Omniscio's own auto-replies. Threshold default 10 (2–100) + on/off in Settings → Features (`repeatedPhraseQuickReplyNudgeEnabled`, also gated by Tips & Guidance). Replaces the Weekly Summary's old `save-quick-reply` suggestion (removed from the digest 2026-07-06). | [quick-reply-nudge.md](quick-reply-nudge.md) |
| Quick SMS (Ctrl+Space → SMS tab) | Send a quick text from the Quick Launch / Control Space composer — pick a saved favorite, a recently-texted contact, or type any number, write a line, Ctrl/Cmd+Enter; sends through the existing SMS pipeline (`IPC.SMS_SEND`) after a fixed ~6s send-with-undo window. Mirrors the Message/DM tab (not Quick Email's main-process service): `QUICK_SMS_SCHEDULE` relays to a main-window `quick-sms-scheduler` that shows a "Sending… Undo" toast (toast-button undo only, NO global Ctrl+Z, so no collision with Quick Email) and fires the send; a `data.success:false` becomes a humanized error toast. Recipient suggestions come from your SMS conversations; a `quickSmsRecipients` favorites list (Settings → SMS, local-draft commit-valid-only) is the optional curated layer. Gated on `smsEnabled` (off by default), text-only, desktop-only. | [quick-sms.md](quick-sms.md) |
| QW miss reporting (Report missed question widget) | "Report missed question widget" item in the agent-message 3-dot menu, visible on any agent message — opens the same notes-only dialog, delivers a JSON bundle to the Resend + Firestore dispatcher (toggle-gated by `bugReportTransport`) in parallel (agent message + up to 200 preceding messages + optional user note + active `qwParserVersion`) tagged `[BUG: amc-qw-miss]`; the parser team drops the bundle into `tests/fixtures/question-widget/should-render/` as a new fixture. Every-leg-fail falls back to `<userData>/bug-reports/qw-miss-...json`. 5-minute per-(message, kind) cooldown. Toggle off via Settings → Lab → QW miss reporting | [qw-miss-reporting.md](qw-miss-reporting.md) |
| QW Parser Snapshots (regression-diff baseline) | Frozen 18,271-message production snapshot at `${os.tmpdir()}/qw-mining/messages.jsonl` used to diff QuestionWidget parser changes — what it is, where it lives, why it's deliberately stale, how to re-capture (Electron-as-Node + atomic write), and how `qw-cycle.sh` consumes it. Developer doc | [qw-parser-snapshots.md](qw-parser-snapshots.md) |
| QW Triage Tool (mine the live DB for parser bugs) | Read-only rule-based scorer (`npm run triage:qw`) that scans every `source='agent'` message in the live Omniscio DB, scores each 0-100 for likely silent-miss / over-fire bugs, and writes a sorted JSONL review queue to `tests/fixtures/question-widget/_triage/<UTC-timestamp>/`. Idempotent (pure function of DB + parser SHA + scorer regex), $0, complementary to the snapshot-diff workflow. Developer doc | [qw-triage.md](qw-triage.md) |
| Qwen provider (Anthropic-compat API, Alibaba DashScope) | Spawn Claude-Code-style sessions backed by Alibaba's Qwen via the DashScope Anthropic-compatible API (hosted at `dashscope-intl.aliyuncs.com/apps/anthropic`) alongside `claude`, `codex`, `gemini`, `antigravity`, `deepseek`, `kimi`, `glm`, `minimax`, and `meta` — the SIXTH anthropic-compat member; gated behind master "Show alternative AI providers" toggle (off by default), then opt-in via the "Allow Qwen sessions" toggle plus a way to pay — your own DashScope key, Omniscio credits, or both, in the order of Qwen's supply list (Settings → Accounts → Who pays & who serves; the credits lane is `FUNDABLE_PROVIDERS` in fundable-providers.ts). **No binary check** — reuses the standard `claude` CLI; routing happens via spawn-env (`ANTHROPIC_BASE_URL=https://dashscope-intl.aliyuncs.com/apps/anthropic` — the `/apps/anthropic` path, region-overridable via `AMC_QWEN_BASE_URL` — plus `ANTHROPIC_AUTH_TOKEN=<vendor key>`); models `qwen3.8-flash` (default, $0.16/$0.47 per M) + `qwen3.8-max` and its pinned checkpoint `qwen3.8-max-0902` ($2/$6 per M, $0.25 cache-read) + `qwen3.7-plus` ($0.40/$1.60) + `qwen3.8-27b` ($0.50/$3.00), re-priced from tokens; company-credits capable (the `qwen` lane is funded by the pooled OpenRouter key, so a personal key is optional); 2 readiness gaps (`toggle-off`, `key-missing`); identical tool-approval UX to Claude (no yolo mode) | [qwen-provider.md](qwen-provider.md) |
| Export a raw thread (troubleshooting transcript with shown / folded / hidden labels) | Session `⋯` → **Exports** → **Export raw thread** saves every message the session stored, verbatim and unredacted (tool activity, markers, hidden instructions, automatic messages), each labelled with where the session window actually put it: VISIBLE, FOLDED behind a control the user could open, HIDDEN with no toggle, or DROPPED, with the reason on the row. Answers "did the agent never answer, or answer and get hidden?" for a user report. The labels are replayed from the window's own layout rules, never guessed; the file names its own gaps. Desktop save and phone download produce the same Markdown file; agents read it via `GET /session/:id/raw-thread`. | [raw-thread-export.md](raw-thread-export.md) |
| Reading Queue (Marketplace plugin — save links, auto-summary, read aloud) | **A sandboxed first-party Marketplace plugin** at `src/plugins/reading-queue/`, NOT core code — installed from the Marketplace, deliberately excluded from the app bundle. Hand-authored vanilla-JS webview UI talking to the host only via `window.AgentMC` (`db`/`ai`/`http`/`tts`). Owns its own `reading_items` collection; search + tag filtering run in JS (the plugin `db` has no LIKE/FTS). Read-aloud goes through the permission-gated `tts` capability with a per-plugin daily spend cap. The native built-in (`__reading_queue__`, `readingQueueEnabled`) was DELETED 2026-07-22; `reading_queue_items` remains an unread tombstone table. | [reading-queue.md](reading-queue.md) |
| My Real Chrome v2 (PUBLISHABLE — scripting + native messaging, no debugger, in-development) | A clean-room, **Chrome-Web-Store-approvable** rebuild of My Real Chrome that drives your real signed-in Chrome **without the `debugger` permission** — it uses `chrome.scripting` (inject a driver), `chrome.tabs.captureVisibleTab` (screenshots), and **native messaging** (a Chrome-launched host relaying to the app over a token-authed local **pipe**, no TCP port), the same architecture as Anthropic's published Claude extension. Fully **separate** from v1 (own folder `real-chrome-extension-v2/`, engine `real-chrome-bridge-v2`, flag). Solves v1's two shipping blockers: not Web-Store-approvable, and poisoned by other extensions' frames (LastPass) — v2 has no debugger so neither applies. Agent drives via gated `/real-chrome-v2/*` routes; fresh-tab guardrail + per-site access you grant with a click + AI-control banner on every driven tab. Documented limits vs. a debugger: synthetic input only, no file uploads, visible-active-tab screenshots, DOM-derived a11y snapshot, no JS-dialog/console/network capture. Settings → Features → **"My Real Chrome v2"** or `AMC_SHOW_REAL_CHROME_BRIDGE_V2=1`; ships OFF, desktop-only. | [real-chrome-bridge-v2.md](real-chrome-bridge-v2.md) |
| My Real Chrome — Full (RETIRED 2026-09-15 — use My Real Chrome v2) | Lets an Omniscio agent drive your **real, already-logged-in Chrome** (the default profile the Native Browser can't reach — Chrome 136+ blocks remote-debugging there) by pairing a small companion **MV3 Chrome extension** that relays the DevTools Protocol over a **loopback, token-secured** WebSocket. The agent drives via gated CLI routes (`/real-chrome/status` + open-tab/navigate/screenshot/click) and only ever touches **fresh tabs the extension opened** — never your existing banking/email tabs. Also docks a **live-view Browser pane** — watch the tabs your agents drive stream live (CDP screencast) + **take over** to drive by hand, desktop-only + never over the web bridge (I12). Security linchpin: LOOPBACK (127.0.0.1 only) + 256-bit pairing TOKEN checked at the WS upgrade + FRESH-TAB guardrail; **desktop-only** (never reachable from a paired phone). Reuses the Native Browser's tab controller unchanged. **RETIRED 2026-09-15 (owner decision)** — its `debugger`-permission extension can never be approved in the Chrome Web Store, so the feature is hidden for everyone: **the Settings toggle is gone and `/real-chrome/*` answers 404.** The code and routes are kept; reveal for testing only with `AMC_SHOW_REAL_CHROME_BRIDGE=1`. Use **[My Real Chrome v2](real-chrome-bridge-v2.md)** (Web-Store-approvable) instead. | [real-chrome-bridge.md](real-chrome-bridge.md) |
| Real-conversation layout (chat shows just the dialogue) — part 2 (how the panel decides what to render) | The decision layer behind the real-conversation layout: which rows the chat panel is allowed to show, how it decides that a turn was real conversation rather than plumbing, the opt-in marker that pins a final answer, the pipeline stepper on dev-pipeline gate reports, and the one-line collapse for a turn that ended with no answer. The visible layout and its settings toggle are in part 1; the compact clamp and the code map are in part 3. | [real-conversation-layout-part-2.md](real-conversation-layout-part-2.md) |
| Real-conversation layout (chat shows just the dialogue) — part 3 (the compact clamp and the code map) | The last details of the real-conversation layout: how the cold-mount fetch interacts with the `/compact` clamp, and a map of the code the whole feature lives in. Part 1 covers the visible layout and its setting; part 2 covers how the panel decides what to render. | [real-conversation-layout-part-3.md](real-conversation-layout-part-3.md) |
| Real-conversation layout (chat shows just the dialogue) | Default cold-mount renders the **real conversation** only — your messages + the agent's real final replies + inline `/compact` dividers as landmarks; first user message pinned at the top with nothing above it; per-turn tool chatter folds into one collapsed "N actions" pill per turn that fetches its content lazily on click. Auto-continues (`is_auto_response = 1`) and intermediate agent chatter are hidden by default. Search / export / share / audit still see every row. Settings → Sessions toggle (default on). | [real-conversation-layout.md](real-conversation-layout.md) |
| Scheduling a recipe (the calendar / recurrence UI) | The Schedule Recipe dialog: put a recipe on a calendar with one of four frequencies — Interval (quick-select presets from 30 minutes to 12 hours, or a custom interval down to a 15-minute floor), Daily, Weekly (pick the days) or Monthly (day of 1–28) — each with a time, a Next run preview, and a pause/resume toggle once scheduled. A scheduled recipe starts a paid Claude run every time it fires, so the form's defaults are chosen to be safe. | [recipe-scheduling.md](recipe-scheduling.md) |
| Author a recipe by asking AI (CLI authoring) | Tell an external AI "build me a recipe that…" — the `omniscio-control` skill bundle (recipes surface) drafts, validates, and saves it via `127.0.0.1:19519`; lands as `pending` until you approve in the Omniscio inbox | [recipes-cli-authoring.md](recipes-cli-authoring.md) |
| Record for Agent (record your screen, mark the moments, send it to an agent) | A mode on top of the **Screen Recorder**: record while you narrate, mark the moments that matter, then send the whole thing to ONE agent conversation that shows you a cropped screenshot every time it refers to something. Four ways to mark, freely mixed — a rebindable **global hotkey** (default `Ctrl/Cmd+Shift+6`, the only path that also captures the text of the field you are typing in), a **typed note** on the recording bar (stamped when the box OPENS, not when you hit Enter), **saying** a trigger out loud ("flag this", "mark this" — the rest of the sentence becomes the label, resolved from the transcript afterwards so the timing is exact), and **drawing a box** on screen with an optional label. A drawn box also lands in the video editor as a normal annotation you can drag, resize and retime — whatever you leave it as is what the agent gets cropped. Before sending you get a **review list** of every moment found, numbered exactly as the agent will refer to them, and untick anything you do not want. **It never files anything** — no tasks, no tickets, no notes; the conversation IS the output. **It always shows the picture**: every moment ships pre-cropped and pre-highlighted with a ready-to-paste line, and each agent reply carries a green **Grounded** or amber **No screenshot in this reply** badge so a skipped screenshot is impossible to miss (not impossible to skip — the model's text is the deliverable). Timestamps run through the recorder's single media clock, so a moment seeks to the frame you meant rather than the aftermath of the capture warm-up; one marked during the warm-up is flagged as unreliable rather than described confidently. Privacy: pointer tracking turns on **for that recording only** (starting the take IS the consent, with an on-screen indicator); on Windows the focused field's text is read only on the hotkey path; **password fields are refused inside the native helper**, so those characters never reach Omniscio; there is still no keylogger — the key hook keeps discarding which key you pressed. Off switch: Settings → Screen Capture → Extras → Record for Agent. Auto-detected moments are deliberately absent (the candidate detector missed a small error badge 100/100 on measured fixtures). Contract: screen-recorder-contract I19–I24. | [record-for-agent.md](record-for-agent.md) |
| Records (gamified personal bests / trophy case) | Stats sub-tab — ~18 all-time personal-best trophies across 7 categories (single-session feats, efficiency, lifetime tier ladders, streaks, daily bests, leverage, and a Peak Parallelism family). Locked/earned cards, named tier rungs + progress bars, unconditional confetti on celebration-worthy breaks, opt-in app-wide toast (Settings → Notifications, default off). Peak Parallelism seeded by a one-time history sweep + kept live by a 60s sampler; The Mint has an anti-gaming floor. Local SQLite only | [records.md](records.md) |
| Recurring Special Events (birthdays/anniversaries/holidays → Google Calendar + reminders) | A **tab inside the Google Calendar panel** ("Recurring Events"; shown by default when **Google Calendar is enabled** — `calendarEnabled`; desktop-only) for adding yearly occasions that fan out into **Google Calendar** events plus lead-time reminders. Three recurrence modes — a **fixed annual date** (e.g. June 13), an **Nth weekday of a month** (e.g. the 3rd Sunday of May), or a **built-in holiday** from a hardcoded catalog (Mother's/Father's Day, Memorial/Labor Day, Thanksgiving, Easter via Computus, Christmas, …). Each event creates a day-of entry plus any chosen lead reminders — day-of, a day before, a week before, a month before, or a **custom number of days before** — as separate visible calendar events, mirroring the user's original Birthday/Anniversary Reminder Sheet. Fixed-date reminders become single perpetual yearly-recurring Google events (RRULE); floating (nth-weekday / holiday) lead reminders are computed EXACTLY per year and materialized across a rolling multi-year horizon (topped up on panel load), so "10 days before Mother's Day" lands correctly every year even though the holiday moves. Reuses Omniscio's existing Google Calendar integration (OAuth + `createEvent`, idempotent); desktop-only for the initial release; if Google isn't connected it prompts to connect in Settings. | [recurring-special-events.md](recurring-special-events.md) |
| Weekday Reflection Nudge (once-a-weekday "could an agent do this?" inbox card) | A gentle once-per-weekday inbox card that nudges you to reflect on what you've been doing and whether an Omniscio agent/automation could take some of it off your plate. Fires at a random-but-deterministic time in an early window (~9am–3pm), Mon–Fri in local time — but ONLY when you're genuinely active right now (you sent a real human message in the last ~15 min, which also proves the chat can launch, so it never dead-ends) and hasn't already fired today (the scanner's own fire-gate via `findLatestCreatedAtByDedupKey`, not the global re-raise throttle). The wording rotates tone day to day from a fixed pool — zero AI cost to show. Its **"Let's talk about it"** button opens a foreground Claude chat pre-seeded to interview you, brainstorm agent/automation ideas, and hand off to the automation builder or Foundry; the universal Start-session button, snooze, and dismiss all work (a dismissed card doesn't return until the next weekday). Keys on YOUR messages (never your agents'), so it can't land while you're away. In-development, off by default — reveal via Settings → Lab toggle or `AMC_SHOW_REFLECTION_NUDGE=1`. Setting `reflectionNudgeEnabled`; contract: reflection-nudge-contract. | [reflection-nudge.md](reflection-nudge.md) |
| Test Regime Monitor (see your merge-gating + cloud-testing health at a glance) | A read-only **Developer Tools** panel that opens on an **Overview** tab (one verdict — Healthy / Degraded / Breaking / Inconclusive — for the whole local + cloud regime, six end-to-end stage cards each carrying its raw number, and a worst-first list of what is breaking) and also shows the end-to-end **merge gate** per active branch (typecheck / lint / tests as running / passed / failed / **stale** = passed on an older commit, read from the existing `landing-proof.json` receipt + a tiny "running" marker each check writes — **no new database**) plus the **cloud testing** picture on the operator box (fleet health, last scheduled master build + freshness, in-flight & recent `--cloud` runs, 24h spend). The gate side polls a few seconds while open (nothing when closed); the cloud side reflects the 15-min / ~6-hour snapshot, ~60s-memoized, with an honest "updated N ago". Fail-open per source; off the operator box the cloud cards degrade to *unknown*. Read-only over `REGIME_STATUS_GET` (mobile-ready, secret-free payload). In-development, off by default (`regimeStatusEnabled`); contract: regime-status-panel-contract. | [regime-status.md](regime-status.md) |
| Is my bug actually fixed? (the release ledger) | Answers two questions the app could not: which reported bugs are REALLY fixed (and in which release), and which features actually shipped. Follows a trail that already existed and was never joined — your report -> the session started to fix it (`bug_intake_processed.session_id`) -> the commits that session wrote (the `AMC-Session:` commit trailer) -> the release containing them. Surfaces: the **Report Tracker** board, where a traced card reads **Fixed** and shows its receipts ("5 changes · in v0.1.105"), and **`npm run release:ledger`** (`--days` / `--markdown` / `--json`) for the wider picture including features. Five verdicts: Fixed and released · Fixed, ships next release · Being worked on now · **Finished with no code change** (the bucket worth reading) · Cannot be traced (filed before commit stamping began 2026-09-08 — unknowable, NOT unfixed). Key distinction: **Done** is a guess (the investigating session stopped) while **Fixed** is evidence (real commits traced), which is why Done now means finished-with-no-code-landed. Reports only; the CLI needs Omniscio running and never changes anything. | [release-ledger.md](release-ledger.md) |
| Relentless session relaunch (keep retrying a launch hiccup until the session is back) | When a session that was running fails to launch because the machine is momentarily overloaded (a transient OS spawn failure — `errno -4094` / `EMFILE` / `EBUSY`), Omniscio keeps relaunching it with a backoff that grows toward ~30 s (throttled by the concurrent-retry budget) instead of giving up after 3 quick tries and going red. Genuine errors (auth, real crash, missing binary) still surface immediately; status announces once then every 10th attempt. **Settings → Workflow → "Keep Relaunching a Session Until It's Back"** (`relentlessSessionRelaunch`, default on); kill switch `AMC_DISABLE_RELENTLESS_RELAUNCH=1`. | [relentless-relaunch.md](relentless-relaunch.md) |
| Remove a Claude account | Sign out / unlink a Claude account from the pool — Settings → Accounts → trash icon; encrypted credentials wiped from `config.json` | [remove-a-claude-account.md](remove-a-claude-account.md) |
| Rename a session | Give a session a custom title instead of the auto-generated one — right-click the title at the top of the open chat → **Rename**, the ⋯ header menu → Rename, or right-click a sidebar row → Rename dialog (single-selection). Inline edit box, Enter to save; 100-char max; renaming by hand stops the auto-titler from overwriting your name; Ctrl+Z undo. Right-click-the-title is desktop-only (mobile uses the ⋯ menu). | [rename-a-session.md](rename-a-session.md) |
| Renderer stall profiler (what the app was doing when it froze) | A recording of the app window itself. When the app window freezes for a second or more, Omniscio saves what its code was doing — a `.cpuprofile` you open in Chrome DevTools, plus one `[renderer-stall-profile]` line naming the heaviest functions. It watches only while the window is struggling, never changes how the app behaves, and keeps the newest 25 recordings under a size cap. Read the summary line first: if it could not record, it says WHY (`unavailable=<reason>`) rather than staying silent. Turn it off with `AMC_DISABLE_RENDERER_STALL_PROFILER=1`; its state shows on `npm run perf:status`. Desktop main window only — the phone/web view is a different window and is deliberately out of scope. | [renderer-stall-profiler.md](renderer-stall-profiler.md) |
| Reorder projects in the sidebar | Drag projects up or down in the sidebar; Omniscio group divider holds the built-in virtuals together; pinned projects sit above the rest | [reorder-projects.md](reorder-projects.md) |
| Reply Method (how your cursor got into the chat box per reply) | Stats sub-tab — for every reply you SEND, records how your cursor got into the composer: you clicked in, pressed the Reply shortcut (R), the auto-focus setting placed it, or another way (e.g. Tab). Read-only summary card + a per-source row (count + percentage) in the Stats virtual project. One count per genuinely typed reply (quick-replies excluded); fully local, no message text ever stored. | [reply-method.md](reply-method.md) |
| "Reply to start" nudge (waking the agents prepared for you during setup) | A calm, dismissible one-time banner shown just after setup, telling you the one thing nothing else did: the first agents Omniscio prepared for you in the background are **waiting**, not running, and **replying** is what starts one. It exists because those agents are deliberately launched deferred (opening question written, no model spawned, $0) and the old completion message claimed they were "already working" — so a new user could finish setup, see four seemingly-busy agents, and never touch them. **Show me** opens the Onboarding Hub with a waiting agent selected so the reply box is right there; the X hides the banner without cancelling anything. It appears ONLY when an agent is genuinely still waiting (desktop, setup finished, past the learn-the-app window), renders nothing at all otherwise, and puts itself away once you have started them all. The completion message was corrected to match, in every language. | [reply-to-start-nudge.md](reply-to-start-nudge.md) |
| Replying to a message from another agent (for the AGENT that received one) | How an agent answers a message another agent sent it — a chat reply lands in its own transcript and the sender never sees it, so the reply must go back over the CLI to the sender's session. Carries the exact command plus the four things that bite: presenting your OWN session's token — `$AMC_CLI_TOKEN`, the same on every machine, with no file to read — minting the retry id ONCE per message rather than per attempt, treating a timeout as UNKNOWN-not-failed and re-running with the SAME id so the server replays instead of double-delivering, and letting a busy target HOLD the message instead of queueing it by hand — the queue route reaches only the caller's own session, so on a cloud box it is a dead end. Exists because the full instructions are now injected into each session ONCE and later arrivals carry only the sender id plus a link here — re-teaching a constant command on every one of ~2,600 daily messages cost ~310 tokens apiece and taught nothing new. | [replying-to-an-agent-message.md](replying-to-an-agent-message.md) |
| Repo Foundations (set a repo up with strong AI-agent foundations) | An opt-in bundled skill + a "Set up this repo" action (Lab-gated) that inspects any repository and, after you approve a full preview, installs a tailored documentation system and a Claude-rules baseline (a testing regime is a fast-follow) plus a `.claude/foundations.json` manifest — writing into the working tree for you to review; it never commits, pushes, or overwrites anything marked `custom`, and scales the output to the repo's size. The dashboard action also sets up **cross-tool reach**: you pick the canonical instructions file (CLAUDE.md ⇄ AGENTS.md), it turns on Agent Instructions Sync to mirror that to your other AI tools, and it mirrors `.claude/skills` → `.cursor/skills` for Cursor (one-shot, never watched — a deliberate anti-lag rule). The dev-pipeline reads the manifest to keep the `amc-default` modules in sync on future runs. The "Set up" action — on the project dashboard card or in the Dev Pipeline panel's **Repo Foundations** section (Setup tab) — spawns a real paid session (with a cost heads-up). In-development. | [repo-foundations.md](repo-foundations.md) |
| RepoGuard (repo health & security scanner) | Plugin that scans repos for security vulns, dependency issues, config problems, and code quality — 7 scanner categories, composite 0-100 score with A-F grades, actionable findings with fix suggestions; Quick Scan (fast) or Full Audit (comprehensive); optional Sentry integration for runtime health; **Fix Issues** button on the project detail view launches a one-click remediation session pre-loaded with the full scan report and category-aware fix prompt (private vs public repo branching for secrets) | [repoguard.md](repoguard.md) |
| Report conversations ("Your reports" — support's replies to a bug report, idea or question) | Every report sent from the toolbar Feedback button (bug, feature idea, feedback or question) also opens ONE Help Desk conversation owned by the sender, keyed on the report's own id, so the support team answers from the Help Desk console and the reply reaches the person in the app — even with Get Help turned off. Replies show under **Your reports** (a row at the top of the Feedback form, a dot on the Feedback button while one is unread, and the reply notification opens it directly); the person can write back while the report is open with support, and a resolved one is read-only. Human-only: the AI assistant never answers one, and with Get Help off nothing else of Get Help is reachable. The conversation carries the report's own text plus the name, email and plan the report already carried — no screenshots, diagnostics or device details — and sends no extra alert email. Any report sent by someone other than the operator is answered by a person: it starts no automatic investigation, the sender gets one "we've got it" acknowledgement, and a reply is already drafted for support to check before they send it. The operator's own reports, the report's own email copy and its single Tracker card are unchanged. The computer that RECEIVES a report opens its conversation when the sending app is too old to — the report's own id keeps it to one conversation either way. One that could not open (offline) is retried hourly for a day. On by default; switch off with **Report conversations** in Settings → Lab (`reportConversationsEnabled`). | [report-conversations.md](report-conversations.md) |
| Branded report template (agents fetch a ready-made report page) | Every report deliverable an agent produces (research findings, tool roundups, audits, comparisons) starts from ONE standard **Aurora-branded HTML template** shipped inside the app, instead of a from-scratch page per session — so reports published to Shares arrive consistent and on-brand: orb + wordmark, aurora gradient, optional answer-first brief (verdict, next move, takeaways), plain-text sections with expandable evidence, glass cards, ranked "Start Here" list, scroll-tracking section nav, light/dark toggle (dark default), mobile-verified, print-clean, reduced-motion-safe. Agent-first mechanics: the template is a **bundled asset** (`resources/report-template/`), fetched in one step via `GET /report-template` on the local CLI server (scoped agent tokens accepted — public brand asset, no secrets), and every non-SSH spawn is told about it automatically by the standing `[ BRANDED REPORT TEMPLATE ]` instruction (same delivery as Shares/convert/download; SSH excluded — can't reach the local server). The agent replaces ONLY the data block between the template's two `REPORT-DATA` marker comments with its own `REPORT` object (schema documented in the template header; optional blocks omit cleanly; the `<title>` is the only other allowed edit) and publishes to Shares as usual. Markers are build-guarded to appear exactly once, so a splice can never hit the wrong spot. Contract: report-template-contract. | [report-template.md](report-template.md) |
| Re-run from here (edit a message & re-run in a new session) | Pick any message and re-run the chat from that point in a NEW forked session — reword one of your own messages, or write a fresh next message after an AI reply. The prior conversation is SHOWN in the new session (cloned as visible operator+agent rows) so it reads as the same chat continued; if it exceeds the model's memory a note says the assistant only remembers the recent part (you still see all of it). The original session is left untouched; a "Spawned by" note links back. Surfaced from the message ⋯ menu / a bubble icon → a small edit box → Ctrl+Enter. Text-only carry; the fork continues on the source session's own engine and model. | [rerun-from-message.md](rerun-from-message.md) |
| Resources Diagnostic Panel (in-app process monitor) | Settings → Maintenance → Resources — Task-Manager-style read-only view of every Omniscio-spawned process (main, renderer, CLI sessions, MCP servers, asides, other) with per-row CPU sparkline, memory, uptime, account/project label, status; tree-by-default with Flatten toggle; Kill button on killable types opens a confirm dialog with type-specific consequence text; partial-deploy gate fails closed if the sampler is missing | [resources-diagnostic-panel.md](resources-diagnostic-panel.md) |
| Restart attribution (dev-only — no restart is ever anonymous) | A dev restart tears the window down for the ~2-minute supervisor rebuild, so an unattributed `POST /app/restart` reads as a mystery crash (2026-08-02: three anonymous cli-token restarts). Every restart command must now identify itself — a validated `X-AMC-Source-Session-Id` (agents have `$AMC_SESSION_ID`), a validated active `X-AMC-Source-Cron-Job-Id`, or the dev supervisor's own `X-AMC-Restart-Origin` (closed set, sent on its automatic relaunches) — an anonymous caller gets a clear 400 and NO restart happens (attribution, not authorization; the separate `allowAgentAppRestart` owner switch — default OFF — additionally 403-gates ALL headless restarts). The relaunch then raises ONE deduped inbox notice — "Omniscio was restarted at <time> at the request of <session> … a deliberate restart, not a crash" — with the requesting session as provenance; user-button restarts stay silent, and a stale (>6h) record or a genuine crash never produces a false card. Contract: restart-amc-invariants-mechanism-contract (`I10`). | [restart-attribution.md](restart-attribution.md) |
| Review session titles (how an AI reviewer session is named) | A session started to review something is titled `[<Kind> Review] <AI>: <what it reviews>` — say `[Code Review] GLM: Fix the login redirect` or `[Plan Review] DeepSeek: Nightly backup retry`. The Kind is Plan or Code, the AI is the app's own name for the engine doing the review (so `glm` always reads `GLM`), and the subject starts with the words the agent asking for the review wrote, with a short angle appended when several reviewers look at the same thing. Omniscio composes the fixed part itself, inside the Review Service, keeps the whole title within 100 characters by shortening only the subject, and refuses a review with a blank subject or an unrecognised kind before any reviewer starts — every review is a locked session, with no way to ask for one that is not. The Dev Pipeline's AI reviewers (the AI Code Review phase and cross-vendor peer review) always use it. A title set this way is never rewritten by the auto-titler. Existing sessions keep their old names. | [review-session-titles.md](review-session-titles.md) |
| RSS feed integration | Polls configured RSS/Atom feeds and surfaces each new entry in the unified inbox — read-only channel, SSRF-protected URL validation, snooze/archive/automate per entry | [rss-integration.md](rss-integration.md) |
| Run a file from chat (right-click a runnable path → Run / Run as administrator) | When a chat message mentions a runnable file by its path (e.g. a PowerShell fix script `` `C:\tmp\amc-excl-fix-j.ps1` ``), right-click the path → **Run** or **Run as administrator** to launch it without copying it into a terminal. A confirmation dialog shows the EXACT path first (paths can be AI-written); the file then runs in a terminal window that stays open. Admin uses the OS's own prompt (Windows UAC / macOS password) — Omniscio can't bypass it. Runnable set: Windows `.ps1/.bat/.cmd/.exe/.com/.msi`, macOS `.sh/.command/.app` (menu matches the host OS; desktop-only — not from the phone client). For programs/installers a left-click REVEALS the file in its folder instead of running it (running is right-click-only); scripts left-click to a read-only preview. Injection-proof launch (Windows `-EncodedCommand`, macOS two-layer escaping, no shell); the launched window outlives Omniscio; deliberately works for files anywhere on disk (the gate is your confirm + the OS prompt, not a folder restriction). | [run-files-from-chat.md](run-files-from-chat.md) |
| Runaway agent commands (the "has run N minutes" card with a Stop button) | When an agent's search or listing has run 10+ minutes and is still busy while the other agents are slowing — or any command looks like an unbounded search — Omniscio shows ONE inbox card naming the session and the command, with what it measured and a Stop button (desktop or phone). A command a timed-out tool call left running is watched the same way. A build, test run, install or merge gate never gets the card just for being busy. Stop ends only that command and what it started, and its session keeps running. Read-only searches past 20 minutes are stopped automatically (at most two per check); anything that writes, installs, builds or tests is never stopped without you. An agent that starts a second copy of a command still running is told so, once. On by default. | [runaway-command-watch.md](runaway-command-watch.md) |
| Running Apps | Sidebar virtual project (emerald AppWindow icon) listing the live dev servers Omniscio launched through the bundled **portless** proxy, each at a stable `<slug>.localhost` URL; click a URL to open it in an embedded `<webview>`, or Stop the preview; live-updates via a poll push (`portless:apps-changed`); needs portless + system Node 24; HTTPS `.localhost` previews load via a narrow `.localhost`-scoped certificate-error trust; off by default (`runningAppsEnabled`) | [running-apps.md](running-apps.md) |
| Safe Mode (Windows-Safe-Mode-style recovery boot) | A boot mode that restarts Omniscio with ALL automatic/background behavior off — auto-landing, auto-spawning from email/chat, inbox pilot, scheduled sends, every integration's background activity, the mobile tunnel, self-acting watchdogs — plus a basic-graphics fallback so it opens even if the display/GPU broke; you keep full manual control (view sessions, change settings, run sessions yourself). Reachable three ways: a separate **"Safe Mode"** shield-icon launcher in the install folder (works even when the normal app won't open), a **Restart in Safe Mode** button in Settings → Diagnostics, or launching with `--safe-mode` / `AMC_SAFE_MODE=1`. Sticky across restarts (even a crash) until you hit the top banner's **Restart Normally**; the signal is a standalone marker file (not a setting) so it survives a broken database; never runs two copies on your data. New background features are off-in-Safe-Mode by default. `GET /state` reports `safeMode`. | [safe-mode.md](safe-mode.md) |
| Save a session | Press B or right-click → Save to bookmark a session into the collapsible Saved sidebar section (between Snoozed and Archived); orthogonal flag (`saved_at`), not a status change; saving a snoozed session clears the snooze; archiving clears the save; CLI routes apply immediately (no approval queue) | [save-a-session.md](save-a-session.md) |
| Scheduled Messages (compose-to-self, fire-into-inbox) | Write a rich-markdown note to yourself (subject + Markdown body + inline images), schedule it once or recurring (daily / weekdays / weekends / specific days), and a 60s background scanner silently drops a persistent inbox delivery when it fires (survives restart). One-way item — read/archive only, no approvals. On by default (`scheduledMessagesEnabled`); the standalone sidebar row is hidden by default via a separate UI flag (`scheduledMessagesSidebarEnabled`), Alerts-style. Distinct from Send Later, which defers a reply into a live agent session | [scheduled-messages.md](scheduled-messages.md) |
| Scratchpads (quick notes) — part 2 (images, formatting, deletion, the CLI and the contracts) | The second half of the Scratchpads page: how images, Markdown formatting and the list hotkeys behave inside a pad, the soft-delete trash with its 30-day purge, backward compatibility with the original plain-text pads, the command-line surface an agent uses, and the architectural contracts anyone touching the code must respect. Part 1 covers the pad itself, the quick-capture overlay, popping one out into its own window and finding a note. | [scratchpads-part-2.md](scratchpads-part-2.md) |
| Scratchpads (quick notes) | Chrome-style persistent notes as an Omniscio virtual project — two-pane list + rich `contenteditable` editor with optional **markdown styling toggle** (Type icon — lights up headings / bold / italic / code / blockquotes / lists / links / fenced code blocks while keeping raw syntax visible), 500ms-debounced auto-save with "Saved" pill, title auto-derived from first line (inline-editable), most-recently-updated sort; Ctrl+Shift+S opens a centered quick-capture overlay (Esc / click-outside closes, body ≥ 3 chars saves, re-attach to last pad within 60s; **Ctrl+T inside the overlay saves the current note and resets to a blank fresh draft without closing — overlay stays open**); **Ctrl+Alt+S opens that same quick-capture overlay from any app** (rebindable as the "Quick scratchpad" System-wide hotkey); Copy-all + hard delete with Undo toast; single-window guard per pad; bullet/numbered **list hotkeys** (`Ctrl+.` / `Ctrl+Shift+8`, `Ctrl+/` / `Ctrl+Shift+7`) toggle the leading `- ` / `1. ` marker, mirroring KMS; **Ctrl+F** opens a browser-style find bar to search WITHIN the open note (highlight-all + active match, "N of M" counter, Enter/Shift+Enter to step, Esc to close; desktop-only; distinct from the pad-list filter and the Ctrl+K global search) | [scratchpads.md](scratchpads.md) |
| Screen Recorder (built-in Loom alternative) — part 2 (projects, the data model and the agent surface) | The second half of the Screen Recorder page: multi-asset Projects (still in development), the data model a recording is stored in, importing a video you did not record, letting an agent read frames from a recording, and the IPC channels the recorder is built on. Part 1 covers recording, the hotkeys, the editor, the library and sharing. | [screen-recorder-part-2.md](screen-recorder-part-2.md) |
| Screen Recorder (built-in Loom alternative) | Built-in screen recorder + a video-only library — the video half of Omniscio's screen capture, the **Screen Recording** sidebar entry (Camera icon, red-400, split 2026-08-03 from the former unified "Screen Capture" panel; sibling of Screenshots). Capture screen/window/monitor with optional mic + webcam, multi-source compositing, and an auto-PiP webcam overlay; local-first MediaRecorder capture in a hidden host renderer, ffmpeg transcode/composite to MP4 on stop. Grid/list library with inline-rename cards + a crash-recovery section; Review Window (inline rename, expiry, Share → public `shares.omniscio.com/s/<token>/run` link, Publish to Vimeo, footer Discard · Copy link · Done); built-in light editor (Back + inline rename, preview stage + transport, clip timeline, Save, Export-bake popover) with the full compositor gated off for v1. Six globally-registered, Settings-editable hotkeys (Quick Record Fastpath = Ctrl/Cmd+Alt+R). A separate Storage panel manages the store: approximate usage with a Calculate-exact walk, age/size auto-cleanup (off by default; live-shared captures never auto-deleted), a Clean up now that previews the exact set before permanently deleting it, and a copy-verified relocate. Opt-in (`screenRecorderEnabled`, off by default); desktop-only, but an agent session drives it through the CLI control server's `/capture/*` routes rather than IPC. | [screen-recorder.md](screen-recorder.md) |
| Screenshot / Snip Tool (built-in screenshot capture) | Built-in screenshot tool — the image half of Omniscio's screen capture, its own **Screenshots** sidebar entry (split 2026-08-03 from the former unified "Screen Capture" panel; sibling of Screen Recording), gated by its own `screenshotsEnabled` toggle since the 2026-08-08 split — independent of Screen Recording (turning it off unbinds the snip hotkey; existing "Screen Capture on" users are carried forward by a one-time migration). Triggering a snip (global hotkey default **Ctrl/Cmd+Alt+A**, tray menu "Take snip", New snip button, or quick-launch) opens the operating system's own snipping experience: on Windows the built-in Win+Shift+S overlay (rectangle / freeform / window / full screen, works on any monitor/DPI arrangement); on macOS `screencapture -i`; on Linux gnome-screenshot / Spectacle / slurp+grim. Omniscio watches for the result (Windows: clipboard, up to 3 minutes; macOS/Linux: capture file), then writes the PNG to `<userData>/screen-recordings/screenshots/<uuid>.png`, inserts a `screen_recordings` row with `type='image'`, copies the PNG to the clipboard, and fires a `screenshot:captured` push. The post-capture toast (Annotate / Share) is focus-aware: shown in-app when Omniscio is focused, or as a small floating always-on-top toast over your current app when it isn't (so a snip taken from another app is never hidden). Cancelling (Esc) saves nothing. If the Windows snipping experience can't launch, Omniscio falls back to a full-screen grab under the cursor (crop in the annotation editor after). Copy-only mode (`screenRecorderSnipCopyOnly`) skips the library row. Snips land in the Screenshots library (snips-only); clicking one opens the snip viewer (zoomable lightbox, inline rename, expiry, Share → public link, Discard, Reveal in Explorer). Screenshots settings (its own page since the 2026-08-08 split): hotkey rebind, capture-notification level (all / errors only / off), capture sound (on by default), copy-only toggle. Full annotation editor unchanged: text / arrow / box / highlight / line / ellipse / step badges / blur / non-destructive crop, undo, Save as copy, share. Agent/CLI capture route (`POST /capture/screenshot`) unchanged. | [screenshot-snip-tool.md](screenshot-snip-tool.md) |
| Scroll position memory | When you leave a session and come back, Omniscio restores your last scroll position — but only if no new content arrived while away (running/streaming sessions still pin to bottom) | [scroll-position-memory.md](scroll-position-memory.md) |
| Secret Paste Guard (paste a key without leaking it to the model) | Paste an API key into the composer and Omniscio stores it **locally by a handle**; Claude-based engines substitute the real value only at execution (the model never sees it), and a **log-scrub** cleans the local transcript; other engines get partial history-scrub protection. | [secret-paste-guard.md](secret-paste-guard.md) |
| Semantic Search (AI-powered meaning search) | Augments Ctrl+K with vector-similarity matches — local 33MB model, on by default, zero data leaves machine | [semantic-search.md](semantic-search.md) |
| Send a message | Composer behavior — Enter / Shift+Enter / Ctrl+Enter (configurable submit key), draft auto-save, slash commands passed through verbatim, `/`-typed skill autocomplete menu, send-blocked-on-paused, send-later via Ctrl+Shift+L | [send-a-message.md](send-a-message.md) |
| Send Later (scheduled responses) | Queue a response for future send (Ctrl+Shift+L) — same picker as Snooze, 3-retry delivery, preserves images / PDFs / text docs / pasted-text chips at delivery time | [send-later.md](send-later.md) |
| Sender Run Cards (back-to-back messages become one quiet line that opens to a swipeable deck) | Two or more messages arriving back to back render as ONE quiet line — a count plus the senders — which opens to a single swipeable card deck, one card per message, instead of a stack of bubbles. The run’s first message paints the line and the rest render nothing, which is safe only because a message joins a run solely when its turn renders nothing but its own bubble. Runs span ANY sender with nothing rendered in between, so a reply breaks it and a message can never appear after the answer it belongs to; each card still names its own sender. Messages you wrote and the agent’s own prose are never folded, and identical repeats keep the existing “Repeated N times” fold. Each card keeps its own identity, so search, the scroll buttons and deep links still open the right card. Show all drops the deck to a plain stack. On by default (`senderRunCardsEnabled`), and switching it off restores the previous rendering exactly. Contract: sender-run-cards. | [sender-run-cards.md](sender-run-cards.md) |
| Sentry Triage Gate (decide whether to spawn; review/ignore/auto-promote) | A decision step between "noticed a new Sentry issue" and "spawn a session" — ignore-list → consolidate-by-class → severity bar → cheap capped AI second-look, cheapest first, first match wins. Issues not auto-spawned land in the **Review** tab with Spawn / Ignore this / Ignore class / Dismiss; ignore rules live in the **Ignored** tab (un-ignore restores). Held issues **auto-promote** when their event count crosses a threshold (default 100) or level escalates. AI second-look is OpenRouter-only, deduped to one call per error class per poll, daily-$-capped (`sentry-triage-ai`), apikey-or-hold, fail-safe to held. Master switch `sentryTriageEnabled` (default on; off = byte-for-byte pre-triage auto-spawn). Schema v259 (`triage_class_key` + `triage_meta` + `intake_ignore_rules`) | [sentry-triage.md](sentry-triage.md) |
| Session auto-color rules (keyword-based or project-inherited automatic session coloring) | Automatically assign a color bar to sessions based on user-defined rules. Two mutually exclusive modes: **Match project color** (toggle ON, session inherits its project's color) or **Keyword rules** (toggle OFF, ordered keyword-to-color mappings, first case-insensitive substring match wins). Manual colors always win. Settings stored in AppSettings (`autoColorMatchProject` + `autoColorRules`). Engine runs on every session rename across all 8 sites. A retroactive "Apply to Existing Sessions" backfill button colors sessions that match but were created before the rules. Settings > Sessions > Auto-Color Rules. | [session-auto-color.md](session-auto-color.md) |
| Pin session commands to the session bar (Snooze, Pause, etc.) | Promote the everyday session actions — Snooze, Pause/Unpause, Send Later, Copy link, Aside Mode, Archive/Unarchive — out of the session **⋯** overflow menu and onto the session header bar as one-tap icon buttons. Pin/unpin from a checklist at **Settings → Sessions → "Session bar"** (or the **"Customize session bar…"** entry in the ⋯ menu). A pinned command leaves the menu and shows on the bar; Pause/Unpause and Archive/Unarchive are each one state-aware button. Empty by default; **desktop-only** display in v1 (the phone header keeps everything in the ⋯ menu). A command is hidden from the menu ONLY while it's actually shown on the bar, so nothing is ever unreachable. Setting: `pinnedSessionCommandIds`. | [session-bar-commands.md](session-bar-commands.md) |
| Session CPU cap (Windows) | Soft-caps the combined CPU usage of every Omniscio Claude CLI process tree (sessions, subagents, npm test, vitest, builds) under host contention + applies below-normal priority class so Omniscio yields to foreground apps; same Win32 Job Object as orphan-kill, two new attributes; Settings → Performance toggle (off by default, 25–90% range step 5, default 60%); no-op on macOS/Linux. Also documents the two always-on default siblings: below-normal session-tree CPU priority AND the low DISK+MEMORY priority sweep ("Let sessions yield the disk to the app", `sessionTreeLowIoPriority` — the STARVED-input-delay fix; IO/page priority don't inherit, so a 30s job-PID sweep covers descendants). ALSO documents the sibling **session PROCESS cap** — a per-session CONCURRENT-process ceiling (`JOB_OBJECT_LIMIT_ACTIVE_PROCESS`, default 512; `AMC_SESSION_MAX_PROCESSES` tune / `AMC_DISABLE_SESSION_MAX_PROCESSES` kill; Settings → Performance toggle, default ON) that kernel-caps a runaway fork-bomb / `xargs -P` / parallel fan-out so a single session can't flood the box | [session-cpu-cap.md](session-cpu-cap.md) |
| Session Event Log (troubleshoot one session — its lifecycle events) | A per-session view (the **Events** option on a session's All/Agent/You message filter, in the "⋯" overflow menu) that lists only that session's lifecycle events — auth-token refreshes, Claude-account switches (naming which account → which), restart/crash recovery, pauses, snoozes, compaction — hiding the chat and the high-volume `subagent-result` tool output. Account switches show the accounts' human names resolved live from OPAQUE account ids stored on the event (never the email/label), so sharing/exporting a session can't leak an account address; an unresolvable (removed) account degrades to generic wording. Reuses the existing session-history feed (no new data channel; works on mobile/web, which loads full history on open). v1 names the common rate-limit / load-balance moves; a rarer silent respawn-time move is listed but unnamed. Contract: session-event-log-contract. | [session-event-log.md](session-event-log.md) |
| Session Files & Links (what files and links a session made) | A read-only, per-session list of every file the agent created or edited and every link it presented, newest first, deduplicated and clickable. Opens from a **Files** button in the session header (also **Ctrl+Shift+O**), on desktop AND mobile — deliberately, because a phone has no file explorer at all, so the chat was previously the only route to a session's files. Files come from the session's CLI transcript (the `file_path` on its write/edit tool calls); links come from saved agent messages, so links still work on an engine with no transcript. A link counts only when the agent PRESENTED it (a markdown link, or a URL alone on its line) — a URL mentioned mid-prose is almost always an API endpoint inside a shell command, and counting those measured 357 junk rows against 2 real ones on a live session. Rows open through the EXISTING file-peek click routing, so no new opener and no second scope check. Derived on demand — no table, no migration, no tracker — and secret-scrubbed before it crosses IPC. States its own limits on screen: files created by a `Bash` redirect are not captured, and a rotated transcript shows its current file only. In-development, off by default; setting `sessionFilesLinksEnabled`; contract: session-files-links-contract. | [session-files-links.md](session-files-links.md) |
| Weekly Session Analysis (agent-friction dashboard + weekly deep analysis) | A developer-tools sidebar panel that mines your past agent sessions for friction and waste. Two layers: a **free deterministic dashboard** (bounded periodic transcript scan counting command timeouts, hook blocks, tool errors, redundant `cd` prefixes, plus spend concentration + the priciest-sessions tail, plus free **agent workflow insights** cards — correction load, launch-template automation candidates, reactive-vs-proactive mix — projected from the already-computed dialogue aggregates, F016) and an **opt-in weekly deep AI analysis** (spawns one silent, cost-capped `session-forensics` session that writes a ranked, lever-tagged forensic report you can read / mark-read / dismiss in the panel). Freeze-safe (≤40 recent long sessions/scan, streamed + yielding); the deep run is approval-gated over the CLI, one-at-a-time, with a daily spend cap. Non-spawnable built-in virtual project under the Developer Tools group. In-development — reveal via Settings → Lab (`sessionForensicsEnabled`) or `AMC_SHOW_SESSION_FORENSICS=1`. | [session-forensics.md](session-forensics.md) |
| Session handoff (carry a long chat into a fresh session) | One click in a session's ⋯ menu ("Hand off to a fresh Omniscio session…") summarizes the session into a seven-section handoff document — including a "what NOT to redo" list — and starts a **new linked session** in the same project, folder and branch already holding it, plus the last stretch of the conversation word-for-word when there is room. The old session is left completely untouched. A session crossing **150,000 tokens of context in use** also gets one in-chat note offering the same thing; the note NEVER spends (no summary, no file, no spawn) — only clicking through the confirm box does. Absolute tokens, not a percentage, because quality degradation tracks context LENGTH, and 150k is both Anthropic's own compaction default trigger and exactly what the old 75% warning meant in the 200k-window era. One handoff per session; chain depth capped; the project `HANDOFFS.md` entry is opt-in and capped at 20 entries. | [session-handoff.md](session-handoff.md) |
| Session hibernation (a heartbeat session goes quiet between beats) | A session woken on a schedule — an overseer that checks the fleet every 15 minutes — used to finish every beat into your inbox, roughly **96 cards a day from one session**, all of them saying nothing happened. With hibernation the agent ends such a beat with `[[OMNISCIO_HIBERNATE]]` on its own line and the session instead **stays green and running, quietly, until its next beat** — the same held state you already know from a session waiting on a build, not an archive and not a pause (you can message it any time and it answers). Two things must hold, both checked every time: the agent ASKED (nothing is ever inferred from prose), and something is genuinely scheduled to wake it (no live wake schedule ⇒ refused, and it lands in your inbox exactly as today). The hold window is measured from the session's OWN next scheduled beat rather than a fixed guess, always a little longer than the gap so a late beat still lands inside it — and a beat beyond the shared four-hour wait ceiling is REFUSED rather than given a hold that would expire hours early and interrupt it anyway. It cannot lose a session: the hold ends when the beat arrives OR when the window runs out (Omniscio checks in, then surfaces it), and a restart ends it too. A turn that asks you a question is NEVER hibernated — and a session still waiting on your answer when a heartbeat or another agent's message wakes it goes straight back to your inbox with the same question, no new chime. On by default, no setup; kill switch `AMC_DISABLE_SESSION_HIBERNATION=1`. Contract: session-hibernation-contract. | [session-hibernation.md](session-hibernation.md) |
| Session isolation (a session runs in its own copy of the project) | Hold the **+** button and toggle **Isolate** to give one session its own copy of the project — a git worktree on its own branch, created in a `<project>-worktrees` folder beside your project folder — so two sessions running at once cannot overwrite one another. Off by default; also settable per project (**Edit Project → More options → Isolate new sessions**) and as an app-wide default. Covers where the copy lives (and how to move it per project), what is inside it (your tracked files plus your `.env` files; other untracked files are not copied), that dependencies are prepared in the background so the first moments may be missing them, that the session's branch is merged back into your project automatically when the session is archived (with an automatic conflict resolver and a Retry Merge fallback if it fails), and how the copies are reclaimed. | [session-isolation.md](session-isolation.md) |
| Session auto-lander queue-status notice (where a handed-off branch sits in the merge queue, shown in the session thread) | A small **read-only** in-thread notice at the foot of the conversation (below the last reply, where the "Auto-landed" note appears) showing where that session's ready-to-merge branch is in the auto-lander's merge queue — **next up · queued (#N of M — your slot + the queue count) · landing now · waiting (with the auto-lander's own reason + minutes)**. The terminal outcomes are NOT shown here: the passive "Auto-landed" / "Couldn't auto-land" transcript notes already cover merged / gave-up, and a conflict is handed back to the author — so it never shows a "Merged to master" line; it is purely the live queue heads-up (the merge itself then lands as its own "Auto-landed" note below it). Appears ONLY once a session has "handed off" and has an active queue status; purely informational (no buttons); **updates live but only while you are viewing that session** — the visible panel drives the refresh (mount load + the auto-lander on-change push + a light poll while in flight); hidden panels read the one shared slate passively, so it is near-zero cost when unwatched. Derived on demand from the auto-lander's EXISTING reads (the ready-to-merge queue + live worker status + durable land-event history), keyed to the session by the SAME branch→session resolver the durable land history uses. The per-session view of the same data the Dev Pipeline panel shows globally; works over Web Access on mobile. | [session-land-status-strip.md](session-land-status-strip.md) |
| Adaptive memory paging (Windows) | Under host RAM pressure (>85% in use), caps each session process's resident working set via `JOB_OBJECT_LIMIT_WORKINGSET` so Windows pages the overflow to the pagefile — frees physical RAM, sessions keep running (just slower), releases at <70%; same Win32 Job Object as the CPU cap; Settings → Performance toggle (off by default); soft (paging) not a commit cap, so nothing is killed; Omniscio itself never trimmed; no-op on macOS/Linux | [session-memory-paging.md](session-memory-paging.md) |
| Customize the session menu (reorder + hide items) | Let each person reorder the items in a session's **⋯ (more actions) menu** and hide the ones they never use, so the menu shows what they reach for in their order — a per-person preference applied to every session. The menu is grouped into **labeled, collapsible sections** with a **filter box** above them (Session / Organize / Share start open; Setup / View / This session start collapsed) — that part ships for **everyone**. With the customization feature on it additionally renders in the user's saved order with hidden items removed; nothing is hidden by default any more, so compactness comes from the collapsed sections rather than an invisible hidden set. Customize from **Settings → Sessions → "Session menu"**: drag (or up/down arrows) to reorder, a switch per row to show/hide, and **Reset to default**; the customizer only lists items that can actually appear for you (dev-only CPU Burst, desktop-only Pop Out, mobile-only Scroll Log, and feature-gated rows are filtered out). The bottom entry is always shown and can never be hidden, so you can't strand yourself — it reads **"Customize menu…"** with the feature on and **"Customize session bar…"** with it off. Per-person, persists across restarts, applies to the mobile ⋯ menu too (set from Settings — no right-click on a phone). Separate from pinning a command to the session bar (the two compose: pinned → on the bar, hidden → gone from the menu). Feature-gated behind `session-menu-customization` (off by default — while off the menu simply ignores any saved order/hidden set, so someone who never opened the customizer can never have one applied; the sections and filter render either way). Settings `sessionMenuOrder` + `sessionMenuHidden`. Contract: session-bar-commands-contract. | [session-menu-customization.md](session-menu-customization.md) |
| Session provenance (trace inbox actions + spawned sessions to their origin) | When an agent triggers an inbox action or spawns a session through Omniscio's local control API, Omniscio records which session caused it and surfaces a clickable link back — the session's name in an inbox item's detail view (on an agent-raised TEXT alert it rides inside the message's own chat bubble, as the sender; on a pending approval it is a "Generated by <session>" line) — and a pinned "Spawned by <session>" note at the top of a spawned session's conversation. Agents Omniscio spawned self-identify automatically (`AMC_SESSION_ID` → the `X-AMC-Source-Session-Id` header); manually-typed / external callers record no origin (shown as nothing, never guessed). A trace breadcrumb, not a security boundary — the origin is self-declared, so never gate a decision on it. | [session-provenance.md](session-provenance.md) |
| Quiet chip (the "16m" clock badge on a session row) | The small grey **clock + duration** (`16m`, `2h`) on the right of a sidebar session row: this session is **running but has produced no output** for that long. A silence timer, **not** an error and not a progress bar — a session thinking hard or running a long tool wears it and is fine. Shows only on `running`/`starting` sessions (deliberately narrower than `LIVE_STATUSES`), appears after **15 minutes**, self-updates on a 30s tick (nothing ever *announces* silence, so only a timer can notice), and clears the moment the session speaks again. Muted `surface` tokens on purpose — it never claims your attention; the separate `session-silence-backstop-service` is what actually rescues a stranded session. Hovering the ROW explains it ("No output for a while") alongside the row's other indicators. | [session-quiet-chip.md](session-quiet-chip.md) |
| Keep this many sessions running (Session Refill Governor) | Lab feature, **off by default**. When fewer sessions are working than your target, it quietly restarts **interrupted** ones every five minutes until you are back up to the number. "Interrupted" means the turn ended **abnormally and left work unfinished** — the process stopped mid-work (ended / failed), a sub-agent never returned, a declared wait went silent, automatic recovery gave up, or Omniscio closed on it. It **never** restarts a session that finished its turn cleanly, one that is asking you something (question / plan approval / permission / merge conflict / ready-to-ship), one **you** stopped, one needing you to sign in again, or one that recovers on its own (usage limit, out of credit, a cut-off answer the recovery pass already owns). Because it starts real turns, every limit is load-bearing: a target, a **per-session daily cap (default 1 — the limit that makes a restart loop impossible)**, a per-session cooldown (a delay, *not* a budget), a per-check batch, a restart-safe daily $ ceiling, a daily count backstop, and the per-account cap. Reopening sessions **you** closed is a separate opt-in, off by default. Each restart logs which interrupted signal picked it; a restart-nothing check logs the pool composition, so an empty pool can never read as healthy. Kill switches `AMC_DISABLE_SESSION_GOVERNOR=1` / `AMC_DISABLE_REFILL_REOPEN=1`. Contract: session-refill-governor-contract. | [session-refill-governor.md](session-refill-governor.md) |
| Your own scrolling always wins (the reader owns the view) | Once you move a session's transcript yourself (finger, wheel, keys, scrollbar, the arrows, the "more replies" pill, a search jump), nothing automatic moves it again during that visit — no late image, new reply, keyboard, header change or end of a turn — except keeping you at the very bottom while you sit there. A fresh open, your own send, or jump-to-latest hands the view back. Phone and desktop. | [session-scroll-reader-control.md](session-scroll-reader-control.md) |
| Session Search (sidebar virtual project) | Sidebar Session Search project spawns a Claude chat that curls the local RAG server (`/search/semantic`, `/search/fts`) and replies with deep-link results. Ctrl+K Semantic tab was removed 2026-04-26 — semantic ranking now blends silently into Ctrl+K (see semantic-search.md). Ctrl+K's **Ask AI** button opens a pre-filled popover that spawns a BACKGROUND, active-tab-scoped Session Search chat (Conversations folds in filters · Notes → KMS · Settings → injected catalog); a toast with an Open action + normal sidebar status let you switch in when ready. | [session-search.md](session-search.md) |
| Session Starter Bot (auto-spawn AI sessions from Team Chat keywords) | A per-channel automation in Team Chat that watches for messages matching configured keywords and spawns an AI session in a chosen project. Two reply modes: canned acknowledgment (default) and conversational reply (opt-in, the agent reads the channel and posts a genuine reply). Loop-safe (agent never replies to another agent), rate-limited, deduped. Configure via right-click channel > Session Bot. | [session-starter-bot.md](session-starter-bot.md) |
| Session stuck in "needs you" | Diagnose and clear the 7 pending-action causes (question, plan, permission, rate-limit, auth, API error, stopped) | [session-stuck-in-needs-you.md](session-stuck-in-needs-you.md) |
| Tag a session | Centered Tag picker palette opened with the **T** hotkey or via the session overflow menu's "Tags…" row — type-and-Enter to create, "Browse all" lists every existing tag with counts, ×/Backspace removes; max 10 tags / 30 chars; deterministic 8-color chips on the session header | [session-tags.md](session-tags.md) |
| Session title style (write your own session-naming rules) | Free-text instructions for how AI-generated session titles should be written — set once **globally** (Settings → Sessions → **Title Style**) and optionally refined **per project** (right-click a project → Edit Project). The two stack, global first. Your text is APPENDED to Omniscio's built-in title instructions, never a replacement, so four rules always win: the 80-character ceiling (a longer title is discarded, so "be more detailed" yields no title at all), stripping of secrets / tokens / emails / IPs / full paths, the exact `Untitled Session` wording Omniscio matches on to retry a failed title, and one-line plain-text output. Both boxes are empty by default and an empty box is genuinely inert — the unchanged code path runs, so nothing differs until you type something. Only active in the *AI-generated title* naming mode (the card says so when it is not); applies to first-message titling, **AI Rename**, and the automatic retry. Costs nothing extra — it rewords a call already being made. Because it is a request to a model, treat it as a strong preference, not a guarantee. Contract: session-title-style-contract. | [session-title-style.md](session-title-style.md) |
| Session Trajectory (see what an agent did in a session) | A read-only **full log** of every tool call an agent made in a session — each with its **full input, full result, and per-call timing** — read from the session's Claude CLI transcript. Reachable two ways: its own row in a session's "⋯" menu, and a **cross-session browser** tile in the sidebar's **Developer Tools** group (pick any session, see its log). A **metrics strip** (Turns · Tool calls · Tokens · Cost · API time) tops it; each call expands to its full input/result (errored calls flagged; long fields truncated with a note; very long sessions capped at their most recent actions). Data (main-process, read-only): resolve the session's `cliSessionId` → the `.jsonl` transcript → a pure parser (pairs tool_use↔tool_result by id, times from line timestamps, excludes sidechain, **secret-scrubbed** + capped), served over the `SESSION_TRAJECTORY_GET` IPC (**mobile-ready** — WS-baselined, and the raw session I/O is **secret-scrubbed** before it crosses the phone/web bridge). An engine with **no transcript** (Codex, Gemini, …, or a not-yet-spawned session) **degrades** to the marker-level summary from the loaded messages, with an honest note — never blank or an error. In-development, off by default (Settings → Lab → Sessions & agents → "Session Trajectory view"); read-only, works on **desktop and mobile** (a responsive two-column/tap-through sidebar browser). Setting `sessionTrajectoryEnabled`; contract: session-trajectory-contract. | [session-trajectory.md](session-trajectory.md) |
| Set up Email Inbound (receive email into sessions) | One-time provisioning to receive email at an AgentMail inbox and have Omniscio spawn / continue Claude sessions for each message — covers the AgentMail account + inbox creation, the API-key + OS credential store step (Windows / macOS / Linux), the Settings → Email Inbound paste + Test flow, and automatic attachment delivery (images → vision blocks, PDFs → document blocks + workdir save, text/Office → workdir save + path-injection, with a 10-attachment cap and 30 MB / 32 MB per-file caps) | [set-up-email-inbound.md](set-up-email-inbound.md) |
| Set up SMS integration | Receive session notifications on your phone, respond via SMS — through Pushbullet or your own phone (native) | [set-up-sms-integration.md](set-up-sms-integration.md) |
| Right-click setting affordances (Hide / jump to setting) | Right-click 9 settings-gated live UI elements (subagent activity card, Auto-Waited tag, voice button, screenshot button, close (X) button, Send Later button, context-% ring, alternate-providers chip, current-branch badge) to **Hide** them — turns that element setting off immediately, with an Undo + Open-settings toast — or jump straight to their **setting** | [setting-affordances.md](setting-affordances.md) |
| Multi-level Settings navigation (category drill-down) | Instead of one long scrolling list, Settings opens to a **category picker**: pick a room, then the specific page within it — a two-level drill-down with a breadcrumb back to the top. Enables the room grouping (the reorganized "rooms"); the two travel together (the drill-down is the entry point for the room-grouped layout). Shipped as the default for everyone **2026-08-03** (a **New Settings layout** toggle returns to the legacy single-list view while it remains available). Settings search and direct deep links still jump straight to any setting, skipping the drill-down entirely — the path you take to reach a setting changes, not the setting itself. Section ids, Settings search, and UI-anchor targets all resolve to the same panels as before. | [settings-drilldown-nav.md](settings-drilldown-nav.md) |
| Settings Home (landing page: search hero, popular tiles, changed-from-default, reset) | The pinned Home page Settings opens on: a hero search box (the one settings search, placed front-and-center), ~8 popular-setting tiles that JUMP to the real row (never duplicated controls), a device-local **Recently changed** list (last ~20 deliberate changes; incidental UI persists never recorded), **Changed from default (N)** with one-click **Reset** (writes the shipped default through the normal save path; secret-bearing keys never diffed/listed/reset), browse-all group cards, and quick links. Every standard setting row also shows an accent **dot + hover Reset** when its value differs from the default, and the ~50-card Sessions page gains grouped subsections with a sticky "On this page" chip row. On phones the mobile menu (the de-facto home) shows compact Recent/Changed blocks instead of a Home row. Landing precedence: deep link > last-visited section this app session > Home | [settings-home.md](settings-home.md) |
| Settings patch approval (deep dive on the diff renderer) | The detail page behind the `settings.patch` mention above — four render branches (scalar `theme: light → dark`, nested object leaf-list with "(M other fields unchanged)" tail, no-op message, prior-unavailable fallback), why a list or object ALWAYS shows its real contents rather than a placeholder count — items joined, object leaves as `Label: value`, project references resolved to project NAMES, nothing dropped without the trailing "…" mark, and credential-shaped fields masked, the Tier-2 "what it does" line reused from each shipped setting's own Settings description (registry-defined settings only — precise coverage, never a wrong line), how the backend snapshots `priorValue` at queue time so the diff stays time-correct even if other surfaces mutate the same setting before you review, the 50,000-char inline cap on the technical-details expander, sensitive-key denylist before the snapshot path, what triggers a row (AI agents, plugins, external scripts hitting the bearer-token-auth'd CLI endpoint) | [settings-patch-approval.md](settings-patch-approval.md) |
| Settings redesign (tabbed pages) | The app's largest Settings pages split into **tabbed sub-pages** — Appearance (Theme & Visual / Sidebar / Text / Motion / Layout Mods), Sessions (Behavior / Display / Waiting / Cost / Custom Render), and Voice & Speech — with rarely-used knobs folded under an **Advanced** disclosure and small **live previews** (text size, chat depth) that update as you change them. Changes only the presentation of settings, never adding/removing/renaming any setting. Shipped as the default for everyone with **no toggle** (the former Lab preview toggle is retired). Distinct from the "rooms" nav grouping (new-settings-layout) and from the separate in-development quick-setup presets. | [settings-redesign.md](settings-redesign.md) |
| Settings reference (every configurable setting) | The comprehensive, always-current list of every setting you can change in Omniscio — one row per setting with its key, value type, accepted values, and what it does — split into the toggles/fields shown in the Settings UI and the CLI/advanced settings that have no UI control. Generated from the settings schema so it never drifts; the place to answer "does a setting for X exist?" and "how do I configure X?". | [settings-reference.md](settings-reference.md) |
| Lingering emergency settings-revert alerts | When an AI agent flips a setting off as an emergency workaround ("kill-switch until the fix lands") and it is still overriding the app default 3+ days later, Omniscio raises ONE dismissible inbox card quoting the original reason, with an "Open this setting" button that jumps straight to the exact setting. Dismissing is a permanent answer for that revert; restoring the setting clears the card automatically. Only agent-made (approval-note-audited) changes are watched. | [settings-revert-alerts.md](settings-revert-alerts.md) |
| Settings Search telemetry (what people search for in Settings, to improve ranking) | Stats sub-tab + a local-only log. When you search the Settings panel and pick a result, Omniscio quietly records the query, which result you picked and **how far down the list it sat**, and whether you then changed a setting — plus when a search falls back to "Ask AI" (the keyword results came up empty). The **Settings Search** tab in the Stats virtual project reads it back as three lists: **Top searches**, **Buried picks** (searched X but the wanted result ranked low — candidates to bump up), and **Fell back to AI**. Stays on this device (no upload), auto-trims (~1 year / 100k rows), and recording is fire-and-forget so it can never slow down or break search. It COLLECTS + shows only — it does NOT yet auto-change the live search ranking. | [settings-search-telemetry.md](settings-search-telemetry.md) |
| Settings — virtual project entry | Alternate entry to Settings via the Omniscio group sidebar — same `<Settings />` component as the gear-icon modal, with three documented v1 limitations on App.tsx-threaded deep-link callbacks | [settings-virtual-project.md](settings-virtual-project.md) |
| In-app settings help (per-setting "?" docs) | Every setting in the Settings screens has a small "?" that opens an in-app drawer with that setting's documentation, rendered instantly from a copy bundled in the app (works offline), plus a "view full docs online" link. Organized as one page per area, each setting a section anchored by its key — the same content that powers the in-app "?" drawer. | [settings/_index.md](settings/_index.md) |
| Setup Backup to Gmail | Weekly encrypted backup of your Omniscio configuration (projects, bookmarks, snippets, settings, recipes, skills — NOT chats) emailed to your own Gmail with the `Omniscio Backup` label; AES-256-GCM + PBKDF2-SHA256 600k iterations; one-click Replace or Merge restore with VACUUM-INTO snapshot, Zip-Slip defense, and 5MB-per-skill / 20MB total caps | [setup-backup.md](setup-backup.md) |
| Tune background pacing during severe lag | Change how many seconds Omniscio waits between background starts while severe interface lag is detected. The 1–60 second control applies live without a restart, preserves queued work and fairness, and never slows healthy operation or user-started actions. | [severe-lag-background-pacing.md](severe-lag-background-pacing.md) |
| Share a session with a teammate (owner half of Multiplayer Sessions) | Session-header Share button (`Ctrl+Shift+G`) → ONE step: type a teammate's email, pick View only / Can reply, press Enter. The share doc is minted on that FIRST invite (no separate create click), and the share is registered before the invite is attempted so a failed invite can never orphan it. A one-time upload notice GATES the create — dismissing it creates and sends nothing. The teammate reads the ENTIRE history, not just what follows their invite (the backfill mirrors the whole conversation), and the AI is told exactly that, prompt-only, before its next word — no extra turn, never in the transcript, so it cannot reach the mirror. Stop sharing tells the AI too, so it does not stay guarded forever. The AI's `[[OWNER_ONLY]]` passages are stripped before anything leaves the machine and render to the owner as a labelled private note; malformed markers withhold the WHOLE message rather than half-showing it. A convention, not a wall — the enforced guarantees are that only the owner approves, and a guest turn inherits no auto-approve. Creating needs the team tier; being invited does not, and the guest's replies spend the OWNER's tokens. Gated on `multiplayer-sessions`, desktop-only in v1. Unrelated to the Shares artifact-publishing feature. | [share-a-session.md](share-a-session.md) |
| Share Artifacts (publish local files and pasted content as links) (part 2) | The opposite of "Republish as new": keep the same public link but swap in new content. Use it when you regenerated a report at the same path, or want an already-shared link to reflect an edit without re-sending it — viewers of the old URL automatically see the new version. It reuses the share's existing token via the service's republishToken → updatedInPlace path (the same in-place mechanism KMS/Vault page-publishing uses, generalized to any artifact share). | [share-artifacts-part-2.md](share-artifacts-part-2.md) |
| Share Artifacts (publish local files and pasted content as links) (part 3) | The publish pipeline is in src/main/services/share-artifact/share-artifact-service.ts — single chokepoint for both the renderer IPC (SHAREPUBLISHARTIFACT) and the CLI POST /share/publish. Both routes pass through createShareArtifactService({ publisher }) so they share one storage publisher. | [share-artifacts-part-3.md](share-artifacts-part-3.md) |
| Share Artifacts (files + pasted content + chat-link right-click) | Publish a local file (file-peek Share button), right-click any file path / attachment link Claude wrote in chat ("Share as public artifact"), or paste arbitrary HTML / Markdown / Text / React JSX into a modal, get back a `https://shares.omniscio.com/s/<token>` public URL — HTML and React run live in an opaque-origin sandboxed iframe (scripts execute, but cannot read other shares' storage), Babel-standalone transpiles JSX/TSX in the browser; content-hash dedup, allow-listed source paths, magic-byte validation, 22 MB image / 18 MB PDF / 2 MB pasted-content caps; optional expiration | [share-artifacts.md](share-artifacts.md) |
| Share via CLI (publish / list / revoke / delete) | Four CLI control server endpoints (`POST /share/publish`, `GET /share/list`, `POST /share/:token/revoke`, `DELETE /share/:token`) for publishing files or content from a script or AI; same publish pipeline as the in-app flow, telemetry tags `sourceType: 'cli'`; bearer-token auth, 10 mutations/minute, apply-immediately (no inbox approval — publish doesn't spawn Claude) | [share-cli.md](share-cli.md) |
| Share Comments (inline and general commenting on shares) | In-development commenting system for Omniscio Shares — viewers sign in with Google and leave general comments, inline text-selection comments (markdown/text/code/SVG), coordinate-pin comments (image/PDF), iframe-bridged text-selection comments (HTML/React via `postMessage`), or **video-timestamp comments** on a shared **screen recording** ("Comment at 2:35" + click-to-seek, the Loom-style surface). A recording that hosts comments is served as a first-party comment **shell** (`/s/<token>`) that frames the `/run` video doc + hosts the comment app; the `/run` viewer carries a `share-comment-video-*` bridge. Comments stored in Firestore (`shares/{token}/comments/{commentId}`) with real-time `onSnapshot` delivery to all viewers; a standalone React IIFE sidebar injected into the share shell handles the UI. Desktop-side: a periodic poller mirrors comment counts to SQLite, creates inbox items (`shareCommentsNotifyInbox`), and the Shares detail pane shows a collapsible Comments section with a per-share "Allow comments" toggle; anchored comments are visually highlighted in the HTML/React preview iframe with gold dotted underlines and click-to-scroll navigation. An `onCommentCreate` Cloud Function cross-posts new comments to a linked Team Chat channel (`shareCommentsCrosspostTeamChat`). CLI: `POST /share/publish` accepts `commentsEnabled` and `teamChatChannelId`. Gated behind `shareCommentsEnabled` (Settings -> Lab or `AMC_SHOW_SHARE_COMMENTS=1`). | [share-comments.md](share-comments.md) |
| Share view events (privacy + audit log) | Privacy contract for the share view-tracking pipeline — what's captured per view (coarse `cf-ipcountry` + per-install-salted SHA-256 of UA + IP, never raw), where the data lives (Firestore authoritative + SQLite mirror capped at 100 rows/share), how the 60s poller diffs view counts and fires per-share notify-on-view notifications crash-safely (SQLite-write-before-notify, `share-view-<id>-<count>` dedupe key), and what happens to events on revoke vs delete (revoke keeps the audit trail, delete batch-removes the entire `events` subcollection) | [share-view-events.md](share-view-events.md) |
| Shareable page links (Copy link to this page) | Copy a `https://` link to a specific app page — the Inbox, a top-level panel, a settings pane — and send it to a teammate. When they open it, Omniscio navigates them straight to that page on their own machine. | [shareable-page-links.md](shareable-page-links.md) |
| Shared chat engine for non-Claude sessions (unified turn engine) | Makes Codex / Pi / Gemini / OpenClaw store + render a turn like Claude does, so their chats are consistent — a self-resumed reply opens a fresh message instead of hiding the prior one (and fixes amber-while-streaming). **Settings → Chat**, **default ON**; flip a single engine back via the toggle, or force it off app-wide with `AMC_DISABLE_UNIFIED_TURN_ENGINE=1`. Claude is unaffected (it joins the shared engine last). | [shared-chat-engine.md](shared-chat-engine.md) |
| Shared recording rich previews + embeddable /embed player | When you share a screen recording by link, the link **rich-previews** (thumbnail + title + a transcript-derived description) in Slack, Notion, Gmail and other unfurlers instead of showing a bare URL, and can be **embedded** on another site as a minimal chromeless player via a dedicated `/embed` URL. The share page (`/s/<token>/run`) carries OpenGraph + Twitter **player**-card tags an unfurler reads directly; the preview thumbnail is the recording's poster re-encoded to PNG at `/s/<token>.png` (best-effort — a failure drops to a text card, never blocks the share). The `/embed` route is served by the share Cloud Function with **no `X-Frame-Options`** so third-party pages can iframe it (safe: a pure media player with nothing to hijack), and is gated exactly like the viewer so a revoked / expired / password-protected recording never previews or embeds. Video recordings only (image snips are unaffected). The `/embed` player card needs the share function deployed; pre-deploy the thumbnail + text card still work. | [shared-recording-rich-preview.md](shared-recording-rich-preview.md) |
| Shared with me (invitee half of Multiplayer Sessions) | Sidebar entry under Communication listing sessions a TEAMMATE shared in — never your own, because the owner is deliberately not a participant on their own share. Opens that conversation read-only with a Load more; a reply box appears ONLY for someone the owner granted `replier` (a viewer gets no composer element at all). Signed-out, nothing-shared and request-failed are three DISTINCT states, because the backend returns an empty list for all three. Replying spends the OWNER's tokens. Gated on `multiplayer-sessions`, desktop-only in v1. Unrelated to the Shares artifact-publishing feature. | [shared-with-me.md](shared-with-me.md) |
| Shares view (master/detail sidebar + in-app webview viewer for shared links) (part 2) | Sidebar entry. Registered in INTEGRATIONREGISTRY (left of the existing Settings / Skills rows in the Omniscio group) as a virtual project with sentinel SHARESPROJECTID (from src/shared/virtual-project-ids.ts). UI registry shape. The Shares entry in src/renderer/src/integrations/ui-registry.ts is a two-component integration: panelComponent: lazy(() => import('../features/shares/SharesDetailPane')) + sidebarComponent: lazy(() => import('../features/shares/SharesSidebar')). | [shares-view-part-2.md](shares-view-part-2.md) |
| Shares view (sidebar entry for managing shared links + in-app webview viewer) | Top-level sidebar entry (Omniscio group, between Settings and Skills) listing every share — threads, artifacts, digests — with Kind/Status filter chips, per-row Copy / Edit / Revoke / Delete actions, and a Publish-pasted-content button; replaces the old Settings → Sharing list, leaves only Firebase Configuration + an "Open shares in app" toggle in Settings. The detail pane has a three-mode viewer (edit / view / fullscreen): edit mode shows all editing controls, view mode renders the share in an Electron `<webview>` with a floating auto-hide toolbar (Edit, Maximize, Open in browser, Copy URL), and fullscreen mode portals the viewer to cover the whole window (Escape to exit). Share URLs clicked anywhere in Omniscio are automatically intercepted and opened in-app instead of launching an external browser; the "Open shares in app" setting (`sharesOpenInApp`) swaps CLI-published URLs to deep links (`omniscio://share/<token>`) that open directly in the viewer. `SHARE_UPDATE` IPC backs the inline edit form | [shares-view.md](shares-view.md) |
| Google Sheets integration (agent-driven + rich formatting) | Claude gets 10 Sheets tool-use calls inside any chat; the Sheets grid renders cells with native Google Sheets formatting (background colors, text colors, bold, italic, font size, alignment, actual column widths); **Trusted Sheets** (Settings → Google Sheets) mark specific spreadsheets as safe with per-column edit permissions — editable columns auto-unlock (green-tinted headers, no warning dialog), non-editable columns stay locked with a pointer to Settings; same Google OAuth | [sheets-integration.md](sheets-integration.md) |
| Shortcut Efficiency (mouse-vs-keyboard stats + rough time-savings) | Stats sub-tab — for the handful of actions that have BOTH a clickable button AND a keyboard shortcut, shows how often you reached for the mouse vs the keyboard and a rough estimate of time you could reclaim by using the shortcut instead. Read-only summary card + per-action grid in the Stats virtual project, built from usage data Omniscio already collects in the background | [shortcut-efficiency.md](shortcut-efficiency.md) |
| Show only active projects (funnel filter) | A funnel toggle in the projects-sidebar header (desktop + mobile) that filters the project list to only projects with a running / needs-you / error session — i.e. the ones showing a colored count badge — and hides the quiet rest. Off by default; the currently-open project always stays; an empty "Nothing active right now" state with a one-tap "Show all projects" appears when nothing qualifies. Persists as `showOnlyActiveProjects` (appearance AppSettings, rides the mobile bootstrap). Reuses the search-filter plumbing (drag-reorder frozen while filtered; collapsed groups expand non-destructively). | [show-only-active-projects.md](show-only-active-projects.md) |
| Show system messages (per-session diagnostic toggle) | Per-session toggle that reveals the plumbing rows the real-conversation layout hides — unkinded system status events ("Session ready"/"Session interrupted"), system-injected continues (auto-continue, stall-retry, rate-limit/crash/restart recovery), and away-mode auto-replies. Off by default; persists per-session across restarts; render-only (nothing deleted or re-queried); kinded markers (compaction, snooze, auth-retry, rate-limit, seed-context, sub-agent results) always show regardless. Found under the session ⋯ menu → More → Filter Messages → Show system messages. Only meaningful while the real-conversation layout is on (its default) | [show-system-messages-toggle.md](show-system-messages-toggle.md) |
| Collapse the sidebars (maximize chat area) | Two independent toggles hide either the projects sidebar or the sessions sidebar to maximize chat area — inline PanelLeftClose button in each header, thin 8-px edge gutter with hover-revealed PanelLeftOpen icon to re-open, keyboard shortcuts Ctrl+\ (projects) / Ctrl+Shift+\ (sessions), persisted via `projectsSidebarHidden` + `sessionsSidebarHidden` AppSettings; Settings → Appearance mirrors. The projects sidebar ALSO has an intermediate ICONS-ONLY rail — ⋮ menu → **Collapse to icons**: a ~56px strip of just project icons (names on hover, one status dot each), an expand button restores the prior width, persisted via `projectsSidebarIconsOnly`, desktop-only | [sidebar-collapse.md](sidebar-collapse.md) |
| Drift chip + warning levels (dev-only — the sidebar footer pill) | The small pill beside the version number at the foot of the sessions sidebar, in a dev build only, carrying four readings at a glance: the **window icon** (code on disk vs the code this window is running — `↓` is updates a restart would load, `↑` is changes a restart would **drop**), the **cloud icon** (this checkout vs its remote — `↑` unpushed, `↓` unpulled; only a push or a pull closes it), the **branch icon** (finished branches tagged ready and still waiting for the auto-lander, with the oldest wait), and the **folder icon** (your worktrees — `●` in use, `○` parked and still holding disk). Every number always prints, a zero included — `↓0 ↑0` is a reading, not an absence — and a single `—` means the reading could not be taken at all (no upstream, a detached HEAD, a ledger that would not answer), deliberately never drawn as a `0` because "nothing is wrong" and "I could not tell you" must not look alike. Each number is shaded as it reaches **levels you set**: **right-click the chip** (or use the **Warning levels…** row at the foot of its panel) for one warn-at and one goes-critical-at per reading, with the branch-age row in minutes. Defaults are the shipped numbers, edits apply live (no Save button — the chip behind the dialog is the preview), critical can never be set below warn because each box is bounded by its partner, and the levels are held read-only while colouring is off. The same dialog carries a **Colour the drift numbers** switch: off is a hue change only — every number, arrow and age still prints. Hovering gives a sectioned card (one section per reading) built from the same source as the panel you get by clicking, so the two can never disagree. Contract: sidebar-drift-chip-contract. | [sidebar-drift-chip.md](sidebar-drift-chip.md) |
| Choose which items appear in the sidebar | Show or hide the projects sidebar's optional items (Ask Omniscio, Mission Control, Scratchpads, KMS, Browser, Ollert, Arij, JLS Image Studio, Supermail, Drip, Screen Capture, automations, developer tools…). Open the sidebar header's **⋮ overflow menu** and choose **Sidebar Items**, then flip a per-item toggle (grouped by category: AI Tools, Productivity, Creative, Communication, Agent Tools, Automation, Developer Tools, System). Each toggle writes one AppSettings boolean; the change is immediate and persists. (This panel used to have its own checklist icon in the header; it now lives inside the ⋮ menu.) | [sidebar-items-visibility.md](sidebar-items-visibility.md) |
| Sort projects by usage | Opt-in projects-sidebar display mode (**off in base settings, but ON for 2 of the 4 onboarding personas**) — ranks projects by sessions started in the last 30 days, most-active first. Turn it on from the sidebar header's **⋮ overflow menu → Sort by usage** (`sidebarSortByUsageEnabled`; window presets 7/30/90 via `sidebarUsageWindowDays`). Ranking happens **within each divider** — projects refill the slots they already occupied, so dividers, section headers, parent groups and pinned rows keep their exact positions and a project never jumps between dividers. **It can never HIDE a project** — a dormant one just sorts last inside its own group. A second pass used to demote zero-usage projects into a collapsed "Rarely Used" group; REMOVED 2026-08-28 after it blanked two users' sidebars (the count comes from the LIVE session list, so archiving your conversations made every hub read as never-used). Pinned projects, parent-group members and virtual/plugin projects are never touched. Display-only — nothing is renamed, moved, archived or deleted, and turning it off restores your manual drag order exactly (drag-disable on group children is gated on the setting). Runs before the Unused / Auto-Tidy split so Auto-Tidy membership can't shift underneath it. | [sidebar-sort-by-usage.md](sidebar-sort-by-usage.md) |
| Signing in to Omniscio (Google · GitHub · email + password, and one-account-per-address) | The sign-in wall you meet before Omniscio opens, plus the matching card at **Settings → Accounts** — separate from the Claude/Anthropic login that runs your sessions. Sign-in is **required** (no skip button on any build) and **desktop-only**; a phone gets in by pairing with a desktop that already signed in. Three doors: **Google**, **GitHub** (only where that OAuth app is configured — otherwise the button is hidden rather than dead), and **email + password**. **One address is one account** (`allowDuplicateEmails` is off), so the doors converge on the same account by design — same projects, plan, and history. The case that used to trap people: a Google account has **no password**, so typing that same address into the email form answers "that email already has an account" on Create and fails on Sign in. Neither means a broken account — the screen now names the two routes that work (use the Google button, or **"Forgot password?"**, which despite the name *adds* a password to the existing account rather than replacing anything). You can also add one deliberately at **Settings → Accounts → Linked providers → Email + password → Set a password** (12-character minimum; desktop-only, because a paired phone must never be able to mint a permanent credential for your account). Sign-in errors are deliberately vague and a password reset always answers "if that address has an account…", so neither can be used to check whether someone has an Omniscio account. **The other direction is covered too:** the account **email is fixed to your sign-in** and cannot be changed in the app (re-signing in under a different address makes a separate account with none of your data; support can change it), while the **display name and photo** are editable at **Identity → Edit**. **Sign out** lives at **Settings → Accounts → Identity → Sign out** (confirms first; ends the cloud session and clears the Team Chat / User Management / Agent Email stores, deletes nothing else — your projects, sessions and settings stay put), with a second **Use a different account** button on the sign-in gate itself. Contract: global-auth-gate-contract. | [signing-in.md](signing-in.md) |
| Silent recipe sessions | Per-recipe "Silent on success" toggle (and per-cron tri-state override) hides the orchestrator session from sidebar/inbox while a recipe runs to a clean finish, then auto-archives inline (no "Archive ses…" pile-up); failures and attention states still surface; 6h watchdog rescues stuck silent runs; Settings → Features → "Clear archive-approval pile-up" drains the existing backlog in one sweep | [silent-recipe-sessions.md](silent-recipe-sessions.md) |
| Simple Mode (guided concierge chatbox for non-technical users) | A toggle-on "concierge" mode that turns Omniscio into a single plain-language chatbox for people who don't want the full cockpit: type what you want ("remind me at 4", "save this note", "what needs my attention?") and it does the work through Omniscio's own control server — no projects, sessions, or jargon. The concierge is an ordinary AI session **cloned from Ask Omniscio** with three guard rails baked in for a trusting non-technical user: a **guarded permission floor** (asks in plain English before anything outward, costly, or destructive), **untrusted fetched content** (an email/web/note that reads like an instruction is surfaced, never obeyed), and **fresh-every-chat** (no memory carries between conversations). It can't write files, hands real build work to a separate dev session (only on your explicit ask), and uses the same "your model first, company Haiku as the safety net" logic as Ask Omniscio with a per-session spend cap on the company path. **In-development, off by default** (`simpleModeEnabled` / `AMC_SHOW_SIMPLE_MODE=1` / Settings → Lab); UI reuses existing components only. Contract: simple-mode-contract. | [simple-mode.md](simple-mode.md) |
| Skill Budget Alert (per-engine skill overload) | When Omniscio syncs your skills into other AI CLIs (Codex, Gemini, Cursor), a **strict-loader** engine like Codex can receive more skills than it can handle and warns "skills over length". This feature notices that and **lets you decide what to hold back** — it never cuts skills on its own. | [skill-budget-alert.md](skill-budget-alert.md) |
| Skill Overhead (installed-skills frontmatter-token/unused-skill watchdog) | Daily review of one unused skill as a single question — Archive it? — with the recorded usage and the estimated token cost in one sentence under it, one prominent action, a quiet Keep, and the source, description and remaining metadata behind one collapsed disclosure. Keep and Archive both work on desktop and on paired phones. Show more skills opens the Skills manager, including bundled-skill restore. Global token/unused limits and reminder settings live in Settings → Notifications → Skill Overhead. | [skills-bloat-alert.md](skills-bloat-alert.md) |
| Import a Slack workspace into Team Chat | The Slack twin of the Discord wizard: finds your connected Slack workspace, lets you choose channels, shows you the automatic Slack-to-Omniscio people match to review, then imports with live progress and a final report. In development, behind the `slack-import` flag. | [slack-import-wizard.md](slack-import-wizard.md) |
| Slack Workspace Import (migrate Slack into Team Chat, in development) | In-development 6-step guided wizard (gated via `slack-import` unreleased-feature, `slackImportEnabled` / `AMC_SHOW_SLACK_IMPORT=1` / Settings -> Lab). Imports channels, messages, threads, reactions, pins, files, and members from a Slack workspace into Team Chat. Auto-maps Slack users to Omniscio accounts by email; unmapped are attributed to the importer. All writes through a Cloud Function batch relay (admin SDK, never direct Firestore). Renderer + IPC + schemas fully built; Cloud Function deployment pending. Distinct from the Slack integration (which triages live Slack messages). Contract: team-chat-slack-import-contract | [slack-import.md](slack-import.md) |
| Slack integration | Triage selected channels and DMs from the Omniscio unified inbox — Socket Mode WebSocket for real-time delivery, reply as bot or as you, AI-suggested replies, Quick Responses | [slack-integration.md](slack-integration.md) |
| Computer feels slow? A step-by-step fix-it guide (free fixes first, new hardware last) (part 2) | Widen the start spacing (do this first if a burst is what hurts). A machine usually tips over when many things start in the same instant, not from the amount of work. Settings → Performance gives you two spacing dials — "Spacing between sessions when many restart at once" and "Wait between automation-created new sessions" — so a big wave trickles in instead of landing all at once. Same work, no spike. Full explanation under If RAM is fine but it freezes in bursts: a spawn storm below. | [slow-computer-part-2.md](slow-computer-part-2.md) |
| Computer feels slow? A step-by-step fix-it guide (free fixes first, new hardware last) (part 3) | (Developers only — skip if you don't use Omniscio to run coding sessions.) Git stores a project's history in two forms: fast, compact pack files, and slow, individual loose object files (one tiny file per saved object). Normally git tidies loose objects into packs on its own. | [slow-computer-part-3.md](slow-computer-part-3.md) |
| Keep my computer smooth under load (smoothLoadEnabled master toggle) | Master **Settings → Performance** toggle (on by default) for Omniscio's load-smoothing behaviors; off = Omniscio's exact previous behavior. Today it fullness-gates the background context-usage poll: a running session whose free in-memory fullness estimate is below 60% skips launching the per-session `claude --resume … /context` helper process, so running many sessions at once doesn't pile up one helper launch per session every ~90s. No context warning is ever missed — a session at/above 60% re-polls every cycle, keeping the authoritative number fresh through the entire 75% / 90% range; staleness is only possible below 60%, where no threshold lives. Fails open (polls) when fullness is unknown. Cross-platform. Built as a master switch so future load-smoothing behaviors fold under one control. | [smooth-load.md](smooth-load.md) |
| Emoji and GIFs in SMS | Two extra buttons in the SMS composer (New-SMS dialog + in-conversation reply bar), desktop + mobile: an emoji picker (searchable, categorized, localStorage "Recent" row; inserts at the caret via the composer handle) and a Klipy GIF picker (trending on open, debounced search, animated thumbnails). A chosen GIF is fetched in Main into a bounded `data:image/gif` URL and staged UN-downscaled (`stageRawDataUrl`) so its animation survives the existing MMS picture send path. GIF search + byte fetch run in Main (Klipy) so the key never crosses IPC; the download is SSRF-gated (https + a Klipy-media-host allow-list before any fetch, `image/gif` content-type, a byte cap under the send gate). Built-in Klipy key ships on (free at scale); optional per-user key in Settings → SMS via `SecretKeyInput`. GIFs count against the Pushbullet MMS allowance; receiving GIFs is unsupported. | [sms-emoji-and-gifs.md](sms-emoji-and-gifs.md) |
| When a text leaves your inbox | Opening an SMS conversation clears it from your Inbox and drops its unread dot in the same breath — reading a text is dealing with it. Only threads you actually open are removed; the app's own automatic selections never clear anything. | [sms-inbox-attention.md](sms-inbox-attention.md) |
| Instant SMS taps in the inbox (preload) | On the phone/web view, tapping an SMS conversation in your inbox used to show a ~0.5–1s loading shimmer (a network round-trip over the Tailscale tunnel); Omniscio now background-preloads the most-recent inbox conversations so the tap is instant. Desktop was always instant (local DB). | [sms-inbox-preload.md](sms-inbox-preload.md) |
| Send & receive pictures in SMS (MMS) | Attach or paste an image in the SMS composer (New-SMS dialog + in-conversation reply bar) and send it as an MMS from your own number via the existing Pushbullet bridge — auto-downscaled to a carrier-friendly JPEG, uploaded (`/v2/upload-request` → multipart → `/v2/texts` with `file_type` inside `data` + `file_url` a sibling), shown inline in the thread (stored as a bounded `data:` URL on the message row) with a click-to-fullscreen lightbox; image-only sends allowed; works desktop + mobile. RECEIVING now works too — an inbound MMS's image_urls is fetched (SSRF-guarded: https-only, Pushbullet/Backblaze hosts, size-capped) and shown inline like a sent picture; a fetch that can't complete falls back to a "📷 Photo — open on your phone" placeholder, and existing received pictures are backfilled a few per sync. Counts against your Pushbullet texting allowance / may need Pushbullet Pro. CLI + scheduling stay text-only. | [sms-pictures.md](sms-pictures.md) |
| Schedule a text (SMS Send Later) | Queue an outbound SMS to send once or recurring (daily / weekdays / weekends / custom days) — a "Send later" button on the New-SMS compose dialog + the in-conversation reply bar opens a scheduler (recurrence/time picker + plain-English "when" box, reusing the Scheduled Messages parser); a 30s background service fires due texts through the SAME send path as a manual Send (so they appear in the thread). See & cancel pending texts in an in-thread banner + a collapsible "Scheduled" section. Send-first/at-least-once (rare visible double, never a silent miss); offline-waits; bad-number-skips-the-occurrence. Scheduling is desktop-only; viewing/cancelling works on mobile. Distinct from the agent Send Later (defers a session reply) and Scheduled Messages (notes to your own inbox) | [sms-send-later.md](sms-send-later.md) |
| SMS short-code name inference | Auto-fills descriptive contact names for SMS short codes (62438 → "eBay security code") via Qwen3-32B (~$0.0001/call) — pencil-icon override in the viewer header lets you correct the AI's guess; multi-brand short codes get labeled "Verification codes (multi-brand)" with no model call; daily cost cap | [sms-shortcode-name-inference.md](sms-shortcode-name-inference.md) |
| Where the unread SMS texts start (the "N new messages" divider) | Opening an SMS conversation with unread texts draws an accent "N new messages" marker just above the first text you have not read — the same treatment Team Chat uses. It appears only for a thread you actually opened with something unread, and it is gone once you have read the thread and moved on. | [sms-unread-divider.md](sms-unread-divider.md) |
| Copy a verification code from a text | Detect verification codes in your texts and copy them in one click — a toast with a Copy action the moment a code text arrives, and a "Most recent code" panel pinned at the top of a thread that is essentially all codes (at least 80% of its messages are incoming code texts). Codes are matched by shape ("Your Acme code is 123456", "123456 is your Acme code", "Acme code: 123456", or a 4-8 digit number in a message mentioning code / OTP / PIN). Incoming only; the copy always puts the bare digits on the clipboard. Works on desktop and mobile. | [sms-verification-codes.md](sms-verification-codes.md) |
| Snooze a session (part 2) | The snoozedUntil field on Session (an ISO timestamp or null) is the single source of truth for the snoozed/active flip. The chat marker is implemented as a system message in the conversationmessages table with metadata.kind === 'snooze-marker'. Its metadata shape is the SnoozeMarkerMetadata interface: snoozedUntil — ISO timestamp the snooze ends. Immutable after insert. note? — optional plain-text note, ≤500 chars, newlines preserved. Immutable after insert. | [snooze-a-session-part-2.md](snooze-a-session-part-2.md) |
| Snooze a session | Hide a session until a later time; optional plain-text note for future-you; amber chat marker hoisted above the last agent message that mutates in place to "Returned from snooze" on expiry/unsnooze | [snooze-a-session.md](snooze-a-session.md) |
| Snooze any inbox item | Right-click any inbox row (sessions, SMS, Telegram, alarms, approvals, recipes, RSS, drips, digests, weekly summaries — all 15 kinds) to snooze it; 12 universal kinds route through the new `inbox_snoozes` table, 3 reserved kinds keep per-table `snoozed_until`; one Snooze Palette, one `isInboxItemSnoozed` gate (lint-enforced), 60-second expiry sweep | [snooze-an-inbox-item.md](snooze-an-inbox-item.md) |
| Snooze everything else (keep a few things, hide the rest for a while) | The inverse of an ordinary snooze: instead of picking what to HIDE, you pick what to **KEEP** and everything else goes quiet until a time you choose, then comes back on its own — one Undo restores the lot. Two ways in: select the rows you want to stay (Ctrl/Cmd-click, or Shift-click a run) and right-click **"Snooze everything else…"**, or click a project's **"Snooze others (N)"** header button to keep a whole project without selecting anything (real projects only — never the Alerts or Approvals sections). It sweeps task reminders and pending approvals too, which is why it confirms once and tells you the real number first; anything already snoozed is left alone, and rows that share one underlying item don't drag each other away. Uses the same snooze mechanism as every other item, so there is no separate restore path; unrelated to Focus Mode, which batches alerts instead. | [snooze-everything-else.md](snooze-everything-else.md) |
| Trim unused snooze times (personalized snooze menu) | Quietly removes the snooze durations you never pick (after about a month of watching your choices) so the menu shows only the options you actually use — the rest stay in the standard order. Decluttering only; snooze behavior is unchanged, and off shows the full list. Shipped; setting `snoozeSmartOrderEnabled`. | [snooze-personalized-ordering.md](snooze-personalized-ordering.md) |
| Something's not working? Start here (the troubleshooting front door) | The symptom-first router for when Omniscio is misbehaving — the missing front door over the ~15 scattered recovery pages, which previously had no index tying them together (a user had to already know which page to look for). Routes by what the user actually SEES, in their words, not by feature name: **the app itself** (won't open · blank white window · slow + freezing · sessions vanished after a crash · isolate it with Safe Mode); **a session is stuck** — four stucks that look alike but have different fixes (amber "Needs You" → read the sub-label; spinner "thinking" forever → auto-restart usually catches it; stopped part-way through a reply → the context-stall nudge; a reply just disappeared → aborted-response retry); **connection / sign-in / scheduled work** (offline banner, auth pathways, cron failure alerts, browser logins); and **under the hood** (Resources panel, Safe Mode). Ends with the two moves that cover most of the rest — restart, or simply describe the symptom to an agent, which can read diagnostics the user cannot see. Carries a fenced **for developers** footnote for the two token-gated surfaces (CLI session recovery, heap-snapshot diagnostics) so a non-technical reader is never sent at them. Pure routing — no new fixes; every destination is an existing page. | [something-not-working.md](something-not-working.md) |
| Spam filter (texts, agent email, Help Desk + calendar) | An automatic spam filter for texts, your agent's email address, the Help Desk support address and calendar invites. Only strangers are checked, by one small AI decision per message paid from prepaid credit; contacts, people you've written to and ongoing conversations never are. Junk starts nothing and waits in the Inbox's Spam list; "Not spam" puts it back and lets that sender through, "Mark as spam" blocks one. Unsure, failed or out of credit means the message goes through. In development (Settings → Lab), off until you switch it on. | [spam-filter.md](spam-filter.md) |
| Spoken Narration (spoken audio recap of each agent reply — in development) | The audio sibling of [Plain Speak](plain-speak.md): the agent writes a short spoken script inline below a `[[OMNISCIO_NARRATION]]` marker (no extra AI call), captured to a `feature='narration'` `ai_manager_decisions` row (`narration_text` col) and auto-played per-message via TTS (`narrationMode`, default `auto`) or a per-message ▶ play button that expands in place into a mini-player (pause/resume · go-to-beginning · stop) and greys out with a reason (daily limit reached / no voice set up / offline / read-aloud off) when it can't play — plus a third "Narration" view (in the Plain Speak / Original pill) that shows the script as readable text. The reply text streams live and is never blocked by narration; availability delivery is presence-only (a boolean `hasNarration` + a text-free push — the auto-play path never carries the script text; audio is synthesized on demand, and the read-view lazily fetches the text only when you open it); metered under its own `narrationDailyCapUSD` cap with a distinct `tts-narration` cost source (no double-count). Off by default behind the `spoken-narration` in-development gate (`narrationEnabled`; reveal via Settings &rarr; Lab). | [spoken-narration.md](spoken-narration.md) |
| SSH Remote | Run individual sessions on a different machine (GPU box, cloud VM) — Ed25519 keys, TOFU host verification | [ssh-remote.md](ssh-remote.md) |
| Stalled session (orange) + Continue alert | A session goes orange **"Stalled?"** when its Claude Code process produces no output past the stall-detection time (Settings → Sessions). The chat panel — and ONLY the chat panel — shows an inline orange alert with a one-click **Continue**; the inbox/sidebar row stays a plain orange dot (no label, no button). Auto-Continue Mid-Task (Settings → Workflow, off by default) tries up to 3 "Please continue" nudges first, otherwise the session is flagged immediately. | [stalled-session.md](stalled-session.md) |
| Start a new session | "+ New Session" button or Ctrl+T / N — spawns a fresh Claude CLI in the active project's folder; isolation toggle per session; blank-session reuse; a failed launch offers a "Try again" retry; the row tracks the session's real status (never "ready" before its process is up); a New Session request survives closing the app and returns with your own opening message; pre-first-message Harness → Provider → Model → Thinking picker (Claude Code spans Claude/DeepSeek/Kimi/GLM/MiniMax; customizable tool list + "always use my default" hide-mode) | [start-a-new-session.md](start-a-new-session.md) |
| Startup trace (single-file launch perf log) | `startup.log` — a self-contained per-launch timeline (main-process phases, renderer phases, slowest 5 gaps, summary) designed to attach to slow-startup bug reports; reveal button at Settings → Diagnostics → Startup Trace; 5 rotated backups; self-describing header for outside AIs | [startup-trace.md](startup-trace.md) |
| Stats (cost, tokens, sessions, trends) | Built-in virtual project — total cost, tokens, LLM/active time, per-project breakdown, feature-usage counts, and trend charts, with a 7d / 30d / all-time selector. A **Spend** tab gives the central all-feature AI-spend breakdown (coding sessions + every background feature, engine double-counts removed). Extracted from Settings → Statistics on 2026-04-30. Companion **Usage** tab hosts the four-chart rate-limit forecast (see usage-forecast.md) | [stats.md](stats.md) |
| Sticky Notes (floating scratch-pad overlay) | Draggable, resizable, color-coded notes that persist across sessions; toolbar icon creates first note on click, toggles visibility after; new-note button on each note's title bar; 6 pastel presets, auto-contrast text, debounced auto-save, minimize to chip; gated by `stickyNotesEnabled` (default on) | [sticky-notes.md](sticky-notes.md) |
| Unfinished work card (branches nobody is coming back for — folder kept or freed) | Inbox card for branches that still hold commits master lacks while their session is gone. A row whose folder is still on disk offers "Pick it back up" (starts one paid agent there) and "Let the folder go" (saves any unsaved work to a recovery ref first, frees the folder, keeps the branch). A row marked "Folder reclaimed — branch kept" is a branch whose folder was already freed: it shows no path, and "Pick it back up" makes a FRESH folder on that exact branch before starting the agent. It also carries the branches HELD for your complete-or-drop decision — those nobody ever asked to finish — so the same two buttons work on them; the daily summary names them every day until you answer. A row leaves the card once its branch is picked back up, lands, or is deleted — never because the card was opened. Found by a background watch every 10 minutes (switch AMC_DISABLE_KEPT_BRANCH_WATCH=1) plus the hourly held-branch inventory. A branch that was known to still hold unlanded work and then stopped existing raises its OWN card naming the lost tip, so the work is never lost silently. Contract: stranded-work-triage I90-I99, I90a-I90b. | [stranded-work-card.md](stranded-work-card.md) |
| Buy Credit (prepaid gateway AI credit top-ups via Stripe checkout) | A signed-in user tops up prepaid **gateway AI credit** with a credit card. Pick an amount — presets **$10 / $25 / $50 / $100** or a custom amount (**$5** min, **$1,000** max) — and Omniscio opens **Stripe's hosted Checkout page** in the browser (card details never enter Omniscio). It's **1:1 face value** (pay $25, get $25 of credit; the processing fee is absorbed). Credit is applied by a **verified Stripe webhook** — not by the browser returning — so a closed tab or flaky network can't leave you paid-but-not-credited; the balance updates shortly after payment (refresh if it hasn't). Refunds and chargebacks **auto-debit** the credit back out, so the balance always reflects settled money. The **Buy Credit** card lives on the **Settings → Accounts & AI → Plan & Usage** screen, under the **Credits remaining** balance (the balance also shows under Settings → API Keys, where minting a key needs it; moved here 2026-08-18). | [stripe-credit-topups.md](stripe-credit-topups.md) |
| Stuck-task helper (get unstuck when you keep snoozing the same thing) | Notices when you snooze the SAME session / email / PR / message three separate times and drops one dismissible Inbox card — "Want a hand getting unstuck?" — that starts a short AI chat pre-briefed about the stuck item; it interviews you about the resistance (unclear / too big / boring / blocked / nervous) and helps you take a tiny first step. A durable per-item counter survives the snooze→return cycle; offered once per item (ever) and capped at ONE active card at a time so a bulk snooze can't flood the Inbox; never nags; dismiss-snoozes and active-snooze edits don't count. The coach reuses the instant-greeting deferred Super-Prompt launch (not the wellness AI-Coaching feature). In-development — reveal via Settings → Lab toggle or `AMC_SHOW_STUCK_TASK_HELPER=1`. | [stuck-task-helper.md](stuck-task-helper.md) |
| Summarize Video Skill (smrzz to KMS capture) | A Claude Code skill (`/summarize-video`) that takes a video, podcast, or article URL, sends it to the smrzz plugin for AI summarization, creates a single KMS note in `Summaries/` with frontmatter tags and the full summary, then offers a follow-up interview for additional extraction (to-dos to Mission Control, separate concept notes, etc.). Requires smrzz connected + KMS enabled. | [summarize-video-skill.md](summarize-video-skill.md) |
| Super Prompt Creator (design a new super-prompt) | One-click launcher for the builtin PromptArchitect super-prompt — it interviews you, then generates a ready-to-use super-prompt; a Prompt Tools sidebar row with a deferred pre-loaded launch | [super-prompt-creator.md](super-prompt-creator.md) |
| Supermail AI Filtering (AI triages your incoming email) | In-development (off by default, `supermailAiFilterEnabled`), the AI-powered sibling of Supermail's rule-based Filters: AI reads each genuinely-new email and triages it against a plain-language instruction into a CLOSED, reversible action set — keep / archive / label / mark-read / star, **never trash**. Mirrors the Inbox Pilot's evaluator for email: the paid classification runs in the MAIN process (Qwen via OpenRouter + a Haiku fallback; only sender/subject/snippet are sent, never the body/attachments), the reversible action is applied in the vendored plugin, joined by a bridge/IPC channel (`SUPERMAIL_AI_FILTER_EVALUATE`). **Preview mode is the DEFAULT** (shows what it would do, acts on nothing) until you switch to Live; **baseline-on-enable** (never re-scans your existing inbox); a MAIN-side daily cost cap (not renderer-tunable); fail-closed; a clear "needs a paid plan or your own key" state. v1 runs while Supermail is open on desktop — the eval channel is blocked over the mobile web bridge (a spending channel). Contract: supermail-ai-filter-contract. | [supermail-ai-filtering.md](supermail-ai-filtering.md) |
| Supermail AI Summary ("Catch me up") | In-development (off by default, `supermailAiSummaryEnabled`), an optional two-part AI summary in the Supermail thread view: **the thread so far** (the earlier messages) then **the latest email**. The vendored UI sends the open thread's full bodies to a MAIN-process summarizer (`llmProviderService.chat`, cheaper OpenRouter model first + a Claude fallback, one-shot JSON, `source: supermail-ai-summary`), joined by a desktop-only bridge/IPC channel (`SUPERMAIL_AI_SUMMARY` — it spends AI credit + carries full bodies, so it is blocked over the mobile web bridge). A trigger setting (`supermailAiSummaryTrigger`: manual button / auto-on-open; auto runs at most once per thread+latest-message) + an editable prompt (`supermailAiSummaryPrompt`, strong default — the override shapes style only; the strict-JSON + never-obey-the-email security envelope stays fixed in Main) + a user-selectable model (`supermailAiSummaryModel`, a ModelPicker over the full model catalog scope=all; empty = the cheap OpenRouter default, Claude Haiku always the fallback, provider resolved in Main from the catalog). MAIN-side daily cost cap (not renderer-tunable); untrusted email text is injection-fenced (forged fence markers neutralized); fail-honest unavailable/capped states; does not PII-scrub (your own inbox). | [supermail-ai-summary.md](supermail-ai-summary.md) |
| Archive Insights AI Digest (opt-in AI cleanup suggestions for the senders you archive) | Opt-in (default OFF, dev-gated `supermail-archive-digest`). An AI reviews the senders/domains you archive — especially the never-opened ones — and suggests **filter / unsubscribe / mute**, each with a one-click **Create filter**. Two surfaces: an on-demand **"Analyze with AI"** section in SuperMail → Archive Insights (with a behavioral-insight line), and an **automatic Daily/Weekly inbox card** that runs even while SuperMail is closed. Opting in sends the **sender + subject** of archived emails to the AI provider (stated on the toggle, Settings → Email & Summaries); nothing leaves the device otherwise. The paid call runs **only in Main** (bounded candidates, Main-built injection-fenced prompt, per-account daily $ cap, schema-validated + every rec dropped unless it matches a sent candidate). **State-aware** — on-demand + automatic share one *hashed* recs-made memory in Main so nothing repeats, and already-filtered senders are skipped. The automatic card runs off the last **encrypted-at-rest** snapshot synced while SuperMail was open (skipped if stale). Desktop-only. Week-over-week trends are a v1.1 follow-up. Contract: supermail-archive-digest-contract. | [supermail-archive-digest.md](supermail-archive-digest.md) |
| Supermail Archive Insights (what you archive + how long you spend) | On-by-default, device-local tracking of the emails you ARCHIVE — recorded at the single `inbox-store.archiveThreads` chokepoint, each tagged with whether it had been opened (`wasRead`) and, when it was the open thread, how long it was open before archiving (`openMsBeforeArchive`, via an order-independent capped open-tracker); automated filter-archives (a different code path) are not counted. Events buffer in memory and flush past the ~10s undo window so an undo never counts; grouped by sender / domain / normalized subject (`Re:`/`Fwd:` folded) with an opened-vs-never-opened split + average time-open, in an Insights view at `/archive-insights` (command palette + Settings launcher) that filters All / Never opened / Opened-then-archived. Each row + a rate-limited proactive toast nudge (keyed on the NEVER-OPENED signal only) open the Filter editor pre-seeded with a one-click auto-archive rule. Three toggles (master tracking · suggest-filters · time-spent/dwell, all default ON), non-destructive idb v2 (legacy rows read as never-opened), 90-day / row-cap retention, PII-redacted logging, fails safe if IndexedDB is unavailable. Client-only in the vendored plugin (`src/plugins/supermail/ui/src/features/archive-insights/`, own `README.md`). | [supermail-archive-insights.md](supermail-archive-insights.md) |
| Supermail Assistants (inbox-wide AI launchers) | Always on (a permanent, non-toggleable part of Supermail — owner decision 2026-08-03): a one-click "Assistants" strip at the top of the Supermail Sessions tab. Four inbox-wide assistants — **Inbox Copilot** (process the inbox one email at a time), **Draft My Replies** (draft in-your-voice replies staged in Drafts, never sends), **Filter & Declutter** (clear low-value noise in reversible approved batches + PROPOSE filter rules), **Filter Architect** (design, back-test, and actually BUILD a Supermail filter — also reachable as the "Build a filter with AI" button in the Filters panel). Mirrors the Tasks macro-session pattern: a button spawns a session into `__supermail__` via the DEFERRED stock-first-response launch (instant greeting, model cold-spawns on first reply) — registry `supermail-assistants.ts` → resolver → IPC `SUPERMAIL_LAUNCH_ASSISTANT` → `createSessionWithPrompt({ deferredStart })`; strip `SupermailAssistantsLaunchers.tsx`; the Filters-panel button goes through the `launchFilterArchitect` host-bridge method (reuses the same channel). Filters posture is by PROMPT DESIGN, not capability: the SCOPED token can't hit `/supermail/filters` (cliTokenOnly, IDOR guard) but the host shim tells every session to fall back to the GLOBAL `~/.amc/cli-token` — so Filter & Declutter deliberately PROPOSES while Filter Architect CREATES/edits (confirmation-gated). Propose-never-send (outbound approval-gated); email untrusted; each is a real deferred Claude session. Contract: supermail-assistants-contract. | [supermail-assistants.md](supermail-assistants.md) |
| Supermail Contact Groups (reusable send-to groups in compose) | In-development (off by default, `supermailContactGroupsEnabled`): name a reusable group of people once and drop it into a Supermail recipient field (To/Cc/Bcc) — pick a group and everyone is added as an individual, removable recipient (a group never sends as an opaque blob). TWO sources merged in the recipient autocomplete (groups shown ABOVE contacts, tagged by source): (1) the user's READ-ONLY Google Contacts groups — read via Omniscio's shared `contacts.readonly` grant (no new consent), main-process People API `contactGroups` → members resolved to {name,email}, returned over a desktop-only bridge/IPC channel (`SUPERMAIL_CONTACT_GROUPS`, blocked over the mobile web bridge); token never leaves main, fetched contacts memory-only (never disk); (2) device-local groups the user creates in Settings → Email & Summaries → "Contact groups" (create/rename/add-remove members/delete-with-undo), stored per-account in localStorage. Email-bearing members only; expands to individual recipients before send. Contract: supermail-contact-groups-contract. | [supermail-contact-groups.md](supermail-contact-groups.md) |
| Supermail email rendering (instant open + email dark mode) | How Supermail paints an email body. **Instant open:** each message's security-clean (DOMPurify) + parse + quote-detection + dark-invert decision is precomputed ONCE off the click path into a cache keyed to that exact message (by id, body-validated so it can't serve the wrong email), idle-warmed for the messages you hover, the previous/next in a thread, and the first N visible inbox rows — so a click is a cache read + paint, not a fetch-and-clean; the sandboxed frame consumes the pre-cleaned HTML (the old double-sanitize per open is gone). **Email dark mode (only in the "Carbon" dark theme):** simple emails already inherit the theme (dark bg, light text); designed emails (newsletters/branded HTML) get a smart color-invert (`invert(1)` + `hue-rotate(180deg)`, with images/logos re-inverted true-color — the same technique as the Omniscio Gmail viewer); an email that already declares a clearly-DARK canvas is auto-detected and left on its original light canvas; every inverted email has a per-message **"Show original (light)"** toggle. **Light ("Snow") mode is byte-identical** to before. Dark is read from Supermail's OWN `theme-carbon` class (it's an isolated bundle, so it can't use the host `.dark` or import the Gmail helper — the invert CSS is replicated). Warming is bounded, deduped, idle-scheduled (never janks). Contract: supermail-email-render-contract. | [supermail-email-rendering.md](supermail-email-rendering.md) |
| Supermail — Inbox Emails & Row Density (emails-in-inbox + row-spacing control + layout polish) | Three Mail changes: (1) **Layout polish** — the Mail/Sessions tab row moved into a compact header above the email list, eliminating the ~160 px empty sidebar column in overlay-nav mode (no setting). (2) **Row spacing** (`supermailDensity`: `compact`/`comfortable`/`spacious`, default `comfortable`) — Settings → Email & Summaries → "Row spacing"; a themeable **baseline** + per-level shift: Comfortable = `--supermail-row-py` (a custom theme's `supermailRowSpacing`, else each variant's vendored default — dense 6 px / preview 12 px — so no-theme is pixel-identical, no regression), Compact = baseline − 3 px, Spacious = baseline + 8 px. Omniscio-owned globals.css rule = `max(0, var(--supermail-row-py,…) + var(--supermail-row-delta,0))`, scoped to the thread-list container (`data-supermail-view` on the vendored list) so search/pickers are untouched and dense/preview aren't flattened; the picker sets `--supermail-row-delta` via `data-density`. A custom theme thus controls the DEFAULT spacing (custom-theme-tokens-contract I5); legacy `supermailCompactDensity:true` migrated once to `'compact'`. (3) **Emails in inbox** (`supermailEmailsInInbox`, default OFF) — Settings → Email & Summaries → "Emails in inbox"; each incoming email creates a dismissible Omniscio inbox item with an inline reply box; reply goes to the last sender only (never reply-all), via main-process send. One card per thread (dedup key `supermail-mail-<threadId>`); counts toward the Needs-You badge (owner decision 2026-07-31); reply blocked over the mobile bridge. Contract: supermail-inbox-reply-contract. | [supermail-inbox-and-density.md](supermail-inbox-and-density.md) |
| Supermail (part 2) | Three refinements to the inbox list (the first two apply to the dense single-line rows shown when the reading pane is off): Soft edge fade instead of a trailing "…". When a row's text is too long for one line it now fades out softly at the right edge rather than ending in a "…". | [supermail-part-2.md](supermail-part-2.md) |
| Supermail (part 3) | The authoritative gap analysis + per-feature status lives in src/plugins/supermail/SUPERHUMANPARITY.md. As of 2026-06-23 the client is at near-parity; the non-AI gaps are closed end-to-end: Undo send is a true deferred send — the composer sends with undoWindowSeconds, the backend holds it on a pendingsends row and fires the real sendMessage when the window elapses; Undo cancels it server-side (DELETE /messages/pending/:id). | [supermail-part-3.md](supermail-part-3.md) |
| Supermail — Reading View: Focus Mode & Auto-Hiding Toolbar (how reading + focus mode works) | Reading-view chrome in the native Supermail plugin. The top toolbar (Reply/Filter/Focus/Pin) and the bottom action bar **auto-hide** and peek back on hover / keyboard-focus (a **Pin** locks them open; a touch / no-hover device keeps them shown). **Focus mode** — the Focus button or **Z** — hides the chrome for distraction-free keyboard reading, and is **always escapable**: an always-visible **"Exit focus mode"** button shows while it is on, moving your mouse to the top of the email brings the full toolbar back **without** leaving focus mode, or press Z (touch / no-hover relies on the button). The header **"Start a session"** button (Omniscio desktop only) is **icon-only** (icon + hover tooltip). Automatic, **device-local** plugin prefs (not synced AppSettings); **distinct** from the app-level bell / batch-alerts Focus Mode. No contract (plugin-local UI). | [supermail-reading-focus-mode.md](supermail-reading-focus-mode.md) |
| Supermail — Send Behaviors, Reply Focus & Rebindable Shortcuts (how replying + sending works) | Composer behavior in the native Supermail plugin. **Reply focus:** pressing **R** opens the reply with the cursor already in the box (J/K email-nav still work — suppressed only while the caret is in the box, resume on Escape; no "navigate mode"). **Three post-send behaviors:** Send & Archive (archive + advance — the DEFAULT), Send & Next (advance, keep in inbox), Send & Stay (just send) — each on its own **rebindable** shortcut (**Send & Archive on Cmd/Ctrl+Shift+Enter** — the default action, so the Send button does it too; a plain Cmd/Ctrl+Enter just sends & stays; Cmd/Ctrl+Alt+Enter is Send & Next). The Send button runs your default (Settings → Email & Summaries → Sending: a default-behavior dropdown + per-behavior key reassignment with conflict detection + reset, persisted per-device); a ▾ menu beside Send lists all three with live keys. **Instant reply:** your sent reply shows in the thread immediately (optimistic overlay, de-duplicated when it syncs, cleared on undo); undo also reverses the archive + returns you to the thread. Real send / undo-send window untouched. Contract: supermail-send-shortcuts-contract. | [supermail-send-shortcuts.md](supermail-send-shortcuts.md) |
| Supermail — Sidebar Labels, Settings & Overflow Menu (label sort + pin/More-labels + ⋯ menu) | A 2026-08-02 sidebar rework: user labels sort **alphabetically** everywhere (sidebar, collapsed rail, menu); only **pinned** labels show inline, the rest behind a searchable **"More labels…"** menu (star to pin/unpin; pins are device-local + account-safe via prune-against-live); Settings / Hide sidebar / Sign out moved into a single **three-dot (⋯) overflow menu** in the header + the slide-out drawer; the three-line hamburger is retired (a panel-open button + a clean drawer close). Menus use a plugin-local portaled `Dropdown` primitive. Contract: supermail-sidebar-labels-contract. | [supermail-sidebar-labels.md](supermail-sidebar-labels.md) |
| Supermail Video Summaries (Loom & Vimeo) | In-development (off by default, `supermailVideoSummariesEnabled`), an optional AI helper that reads Loom and Vimeo video links sent in **incoming** Supermail messages and shows a short AI-written summary card in the message detail. The renderer sends only `{threadId, host, videoId}`; MAIN fetches the video's **captions** (Loom GraphQL `FetchVideoTranscript` / Vimeo player-config `text_tracks` — id-only, fixed-host, never the raw message URL) and, when no usable captions exist, **auto-transcribes the audio** via the reused Groq Whisper core (the card notes "Captions" vs "Audio transcription"), then summarizes the text via a MAIN-process paid call (`source: supermail-video-summary`, per-account daily $ cap). Untrusted caption/transcript text is injection-fenced (sentinel fences + contact-PII scrub + bounded truncation); one video per message (the first Loom/Vimeo link); auto-runs for incoming only, never outgoing/drafts; in-memory per-message result cache (no re-billing on re-open); fail-honest unavailable/capped states. Desktop-only bridge/IPC channel (`SUPERMAIL_VIDEO_SUMMARY` — blocked over the mobile web bridge: it spends AI credit + needs desktop keys). Contract: supermail-video-summary-contract. | [supermail-video-summary.md](supermail-video-summary.md) |
| Supermail (native port) | Sidebar virtual project (mail icon, in the Omniscio built-ins group) that mounts a native React port of the vendored Supermail UI (`src/plugins/supermail/ui`) full-pane inside Omniscio — a Superhuman-style email client (folders, compose, snooze, follow-ups, splits, flows) over a remote Supermail backend with its own `agentmc://supermail/auth` deep-link sign-in (`omniscio://` accepted as an alias). Off by default (`supermailEnabled`); a separate `supermailInboxEnabled` toggle pushes unread items into the Omniscio unified inbox. Non-spawnable — hosts no Omniscio Claude sessions (`panelOwnsLayout` suppresses the empty SessionsSidebar); virtual-project sentinel `__supermail__` (legacy `__plugin_supermail__` rows retired by the 2026-06-19 migration). Vendored + tooling-isolated (own tsconfig / scoped `.supermail-scope` Tailwind build). Also documents the **CLI control surface** — 4 routes (`GET`/`PATCH /supermail/settings`, `GET /supermail/commands`, `POST /supermail/command`) that let agents read/write all 29 device settings and dispatch any command headlessly; sensitive writes + destructive commands are approval-gated; reads work while the panel is closed via a main-side persisted cache. Also covers **new-mail notifications** — with unified sign-in the desktop alert is produced from the local mirror copy (no backend session in the path, so nothing expires), while Supermail's own sign-in keeps the backend stream. | [supermail.md](supermail.md) |
| Support Chat | In-app chat for Omniscio users to contact support directly from the toolbar — floating panel (bottom-right), Firebase Firestore backend, operator inbox source, mandatory display name, per-install device ID keying, 30s polling | [support-chat.md](support-chat.md) |
| Swarms (a lead agent running a team of workers toward a goal) | Give a goal in plain English, a worker cap and a daily budget; a lead session decomposes it into a work queue, spawns worker sessions with different angles (builder/critic/researcher/integrator/fixer), and drains that queue once a minute. Each finished worker produces a lesson that is briefed into every future worker, so the swarm gets better as it runs. Workers coordinate on a LOCAL board with three visibility tiers the lead assigns (a worker can never be granted lead clearance); direct agent messaging is reused as-is. Worker-built tools stay swarm-scoped and are promoted to real skills only by the user. Six independent cost stops; a budget that cannot be read counts as out of money. OWNED BY the Overseer (amended 2026-09-06): the Overseer proposes, starts, watches and stops swarms, and their spend shares ONE budget with it. A swarm still keeps its own sentinel, enumerator, spawn path and tick — those are mechanical, not a separation of ownership — and the shared budget is an accounting join at the read, never a merged sentinel, so raw swarm spend still must not reach the Overseer's anomaly breaker unadjusted. Lives ONLY inside the Overseers hub (nested under its Overseer, with its own six-tab screen; created from the hub's New wizard) — the standalone Swarms sidebar row was retired 2026-09-07. In-development — reveal via Settings → Lab or `swarmEnabled`. Contract: swarm-contract. | [swarm.md](swarm.md) |
| Switch the active Claude account | Account indicator dropdown in the toolbar — pick which account spawns the next session, or let the pool auto-pick by tier | [switch-active-account.md](switch-active-account.md) |
| Switching between AI providers | Unified guide to session providers (Claude, Codex, Gemini, Antigravity, DeepSeek, Kimi, Kimi Code, GLM, MiniMax, Cursor, Hermes, Pi, OpenCode, OpenClaw) and the separate utility AI provider — reveal the alternative providers, switch per-session / per-project, read the provider pill, and troubleshoot the readiness gates (toggle / binary / API key). Who pays for a DeepSeek, GLM, Kimi, MiniMax, Meta, Qwen or OpenRouter session, and which company serves it, is that family's supply list (Who pays & who serves), never the engine picker; resellers such as DeepInfra are not engines there. | [switching-providers.md](switching-providers.md) |
| Restart offer (dev-only — new code synced under a running app) | Running from source, `npm run dev` builds what is on disk at boot, and the 2-hourly **Sync Master** job then rewrites those files underneath the running app — backend changes trigger the launcher's own relaunch, but interface changes do NOT (renderer hot-swap is deliberately off), so you can sit on hours-old UI with nothing telling you. An automatic restart would be an unannounced outage of several minutes, so Omniscio OFFERS instead: a clean sync that actually advanced local `master` raises ONE deduped inbox card ("N new commit(s) synced — restart to use them") whose **Restart now** button opens the SAME "Restart Omniscio?" confirm the header button uses. Confirm → graceful quit (running sessions auto-resume) + supervisor relaunch, and the card archives itself so no stale offer is left behind; cancel, ignore, or archive → nothing happens at all. Silent when the sync found nothing new, was skipped/failed, auto-recovered (that raises its own card), ran as `--check`/`--recover`, or when no dev restart supervisor is present (a packaged install — where the button could only refuse). The button can only ASK: it dispatches the shared restart event so the single confirm owner decides, which is why a fabricated `POST /alert` card can mislead but never restart. Contract: restart-amc-invariants-mechanism-contract (`I11`). | [sync-restart-offer.md](sync-restart-offer.md) |
| System file cache cap (Windows — stop the file-cache freeze) | Windows-only **Settings → Performance** card (+ a one-click button on the "Windows file cache is crowding out memory" inbox alert) that installs an opt-in **hard cap** on the Windows system file cache to prevent a whole-computer freeze: heavy file activity (many agent worktrees on a ReFS Dev-Drive) can balloon the file cache until it eats most of RAM, available memory collapses, and the box freezes for minutes. Install/remove go through Windows' own **admin (UAC) prompt** — opt-in, reversible, and desktop + human-only (no agent/phone/CLI can trigger it). The cap size auto-scales from RAM (~24 GB on a 128 GB machine, within a safe floor/ceiling). Under the hood it registers a **SYSTEM scheduled task** that re-applies `SetSystemFileCacheSize` at every startup, with the cap logic self-contained in the task (no user-writable script to tamper). Status is read via `GetSystemFileCacheSize` (works without admin), NOT the scheduled task (a SYSTEM task is access-denied to an unprivileged query). Windows only (hidden on macOS/Linux). Contract: system-cache-cap-contract. | [system-cache-cap.md](system-cache-cap.md) |
| App messages in the transcript (system message cards) | Messages Omniscio itself sends into an agent's session ("injected by Inbox", "injected by Auto-lander", Gate watch, Land watch, Worktree Ledger, Scheduled wake, Session Refill, Crew check-in, gate restart recovery) render as readable cards instead of walls of agent instructions: a status icon and colour, a plain-words headline ("Request approved", "Couldn't land: it conflicts with master", "Tests passed"), the branch and a short fact line, and the requests an Inbox decision covered. Relayed words (a wake-up prompt, a check-in report) stay in full under a header. "Show the original note" reveals the exact text and is never cut off. The agent's copy is untouched, and only the app's own named senders get a card. | [system-message-cards.md](system-message-cards.md) |
| **tag-manager** | The curated session-tag library, scope rules, picker, free-form coexistence | [tag-manager.md](tag-manager.md) |
| Tags (browse sessions by tag) | Sidebar virtual project laid out like any regular project — middle-column tag-list sidebar (resizable, default ~268 px) lists every library + free-form tag (deduped, library wins), main panel shows every session carrying the selected tag grouped by project with project icon + name in each group header; Foundry strip at the bottom of the sidebar; right-click rename (library only) / delete (both); mobile drill-in; live refresh on `tags:changed` + `tags:session-tags-changed` | [tags-view.md](tags-view.md) |
| Tasks (markdown outliner, in development) (part 10) | Local control server (127.0.0.1:19519), in src/main/services/cli/cli-server-tasks-v2-routes.ts. Every handler runs the shared feature gate (tasksReadAuth / tasksMutationGate → isCliFeatureVisible('tasks-v2')) first and returns 403 with disabled: true when the feature is off — deliberately not a 404, so a caller can tell "feature off" from "id not found". On these routes a 404 means only that the id is missing. Send the plain local time. Do not convert to UTC yourself. | [tasks-v2-part-10.md](tasks-v2-part-10.md) |
| Tasks (markdown outliner, in development) (part 11) | The key-files reference for Tasks: one row per file that carries a piece of the feature — the migration that creates the tasks table, the main-process service, the IPC handlers, the renderer components, the CLI routes, and the writer that mirrors the task tree to disk — so anyone working on the code can go straight to the right file. | [tasks-v2-part-11.md](tasks-v2-part-11.md) |
| Tasks (markdown outliner, in development) (part 12) | The strategic half of the Tasks page: the task data model used as a platform — AI ordering and quadrant classification with their provenance, the day-log reflection ritual, snooze-as-signal procrastination detection, planning personalisation, caught task proposals, delegation records, estimation accuracy, the waiting-on people graph, meeting prep, calendar fusion, and the key-files table. | [tasks-v2-part-12.md](tasks-v2-part-12.md) |
| Tasks (markdown outliner, in development) (part 2) | These command keys are rebindable. Open Settings → Keyboard Shortcuts → Tasks (the tab appears once Tasks is enabled) to remap any of the command-mode actions — snooze, deadline, priority, estimate, waiting on (A), finish, context, launch agent, break-down, command line, insert link (Ctrl/Cmd+K), the focus moves, the one-hand move keys (Shift+W/A/S/D), cut/paste (Ctrl/Cmd+X / Ctrl/Cmd+V), move to project (V), fold/unfold (F), and help. | [tasks-v2-part-2.md](tasks-v2-part-2.md) |
| Tasks (markdown outliner, in development) (part 3) | Snoozing tucks the task into a "Snoozed" section. Once a task is snoozed into the future, it leaves the list and collects under a single collapsible ⏰ Snoozed (N) row pinned at the bottom — so the list stays focused on what's actually actionable, while the count tells you at a glance what's parked. | [tasks-v2-part-3.md](tasks-v2-part-3.md) |
| Tasks (markdown outliner, in development) (part 4) | Tasks doesn't just show deadlines and snoozes on the row — it tells you when they come up. A quiet background check (running whenever Tasks is on) raises one Inbox alert the moment: a task's deadline arrives (its due date/time passes), or a snoozed task comes back (its snooze runs out). | [tasks-v2-part-4.md](tasks-v2-part-4.md) |
| Tasks (markdown outliner, in development) (part 5) | Every task can carry a little more than its text — all optional, all surfaced as small chips on the row only when set (so rows stay clean): An Importance dial — None / Low / Medium / High. Stored as a real column (importance, integer 0–3) so a later "what should I do right now" view can sort on it quickly. (Urgency was removed from the Tasks surface — its urgency column stays but is no longer shown.) A scheduled start date (startat) — "when I plan to start this," separate from the due deadline. | [tasks-v2-part-5.md](tasks-v2-part-5.md) |
| Tasks (markdown outliner, in development) (part 6) | A dedicated Today surface holds the day's true priorities across every project. It is a non-destructive overlay: a task on Today keeps its home project and listid — Today just flags it (dailyplatedate = the local day). Nothing is moved or copied; at day's end a task simply drops off Today and is still sitting in its project. It behaves like any other project — fully editable. | [tasks-v2-part-6.md](tasks-v2-part-6.md) |
| Tasks (markdown outliner, in development) (part 7) | Press / (or Ctrl/Cmd+F), or click the header's Find button (🔍), and a slim find bar opens under the header. Type, and the list filters live — in the giant All-Projects view and in a single project alike. Matches (and their parent tasks, so you can see where they live) stay visible; everything else drops away; the matched letters are highlighted in each row. It searches task text and #tags, ignores case and accents ("cafe" finds "Café"), and shows a live "N found" count. | [tasks-v2-part-7.md](tasks-v2-part-7.md) |
| Tasks (markdown outliner, in development) (part 8) | Any task can host its own Claude agent chat. On a focused outliner row, the "Launch agent" button or the g key runs open-or-launch: If the task already has a chat, it reveals in the Sessions tab and selects it — free, no spawn, no pop-out. If it doesn't, an editable launch-prompt popup opens, showing the visible task message the agent starts from (the task text + its open subtasks) — editable — plus a session-type picker (Custom / Break it down / Work through resistance / Tame the overwhelm /... | [tasks-v2-part-8.md](tasks-v2-part-8.md) |
| Tasks (markdown outliner, in development) (part 9) | An eighth agent session type, Define & enrich, is the fuller sibling of Clarify & enrich: it not only sharpens each task's wording, it also captures the context behind it. Like Clarify it is project-launch only — it never appears on a single-task launch (the picker filters it via LISTONLYSESSIONTYPES), because its whole job is to walk the list. Launch it from a project's "Launch agent…" menu (the launch popup in list mode) and pick Define & enrich. | [tasks-v2-part-9.md](tasks-v2-part-9.md) |
| Tasks (markdown outliner, in development) | In-development next-gen task outliner (Labs-gated, `tasksV2Enabled` default OFF, or `AMC_SHOW_TASKS_V2=1`), surfaced as a sidebar virtual project labeled "Tasks" between Tasks and Zoom Quick Launch. Keyboard-driven tree where each row's text is real markdown — renders in view mode, swaps to a raw-source contenteditable on click; rows nest (Tab/Shift+Tab), reorder (Alt+up/down), and carry due / snooze / ctx chips. Persists in the `tasks_v2` SQLite table and mirrors to `<userData>/tasks-v2.md` (atomic write, 500ms debounce). Separate feature from the shipped Tasks v1 — different table, store, IPC channels, and mirror file | [tasks-v2.md](tasks-v2.md) |
| Teach Omniscio About Me (guided personalization mission) | guided mission that saves a reversible "About me" profile into Custom Instructions so every future session is personalized. | [teach-amc-about-me.md](teach-amc-about-me.md) |
| Teach Recorder (record your screen to generate a reusable AI skill) | Off-by-default Windows feature that records your clicks, keystrokes, and screen state and turns the recording into a reusable parameterized AI skill — always-on-top indicator pill with pause/resume/stop while recording, then pick the recording and click **Generate skill** to send it to the AI; produced skills are stored with the recording and can be referenced or exported. | [teach-recorder.md](teach-recorder.md) |
| Team Chat API Platform (OAuth2 third-party access, planned) | In-development: an OAuth2 authorization layer for the Team Chat messaging API. The 13+ existing CLI routes (channels, messages, reactions, pins, search, threads, read-state, DM inbox, members) already have Zod validation, pagination, idempotency, and content dedup — the gap is solely the OAuth2 auth surface for third-party consumption. Needs: OAuth2 provider, scope definitions, token validation middleware, per-app rate limits, developer portal. Registered as unreleased feature `team-chat-api-platform`. | [team-chat-api-platform.md](team-chat-api-platform.md) |
| Team Chat dead-letter recovery (re-file failed scheduled messages) | When a scheduled Team Chat message exhausts its retry budget, it moves to a dead-letter collection rather than being lost. A production-grade Cloud Function (`teamChatRefileScheduledSend`) atomically re-files a dead-lettered message back into the live scheduled queue with a fresh retry budget (author-gated, membership-checked, shape-validated). The server-side recovery path is 100% complete. No UI surface exists yet for users to discover dead-lettered messages or trigger re-filing. | [team-chat-dead-letter-recovery.md](team-chat-dead-letter-recovery.md) |
| Team Chat history export (planned) | In-development, not yet built (registered as unreleased feature `team-chat-export`) — will let you export a Team Chat channel or DM's history. | [team-chat-export.md](team-chat-export.md) |
| Team Chat hover toolbar extensibility (future plugin/integration hooks) | Planned, no code yet — depends on a broader plugin/extension framework that would let plugins add their own actions to the message hover toolbar. | [team-chat-hover-toolbar-extensibility.md](team-chat-hover-toolbar-extensibility.md) |
| Team Chat internal-link warning (a link only you can open) | A non-blocking amber notice under the **Team Chat** composer when your draft contains a native/internal-only link a teammate can't open — an `omniscio://` app deep link (session/note/mind-map/project/settings), a `localhost`/`127.0.0.1`/private-network address, or a local file path (`C:\…`, `file://…`). A normal public web link (including an existing `shares.omniscio.com/s/…` share) and plain text never trigger it. The notice offers the fix that fits: a **local file** → **Publish & replace** (publishes to Shares, reusing the chat-link publish, and swaps in the public link; desktop-only), an **`omniscio://share/…`** link → **Use shareable link** (swaps to the public web address); anything else is warn-only. Sending is NEVER blocked — you can ignore it and send as-is (the notice clears when the link leaves your draft). On by default; Settings → Sessions composer settings → "Warn about links only you can open" (`warnInternalLinksInTeamChat`). Detection is a pure, renderer-safe, ReDoS-safe classifier (`findInternalLinks`); it flags only internal patterns so there's no public-domain allow-list. Contract: team-chat-internal-link-guard-contract. | [team-chat-internal-link-warning.md](team-chat-internal-link-warning.md) |
| Team Chat message forwarding (forward/share a message to another channel or DM) | In-development, gated via the `team-chat-message-forwarding` unreleased feature and not yet visible to users — will let you forward a message to another channel or DM. | [team-chat-message-forwarding.md](team-chat-message-forwarding.md) |
| Team Chat Message Translation (inline AI-powered translation, planned) | In-development: on-demand inline translation of Team Chat messages using the existing LLM infrastructure. A "Translate" action in the hover toolbar sends message text to the LLM layer and displays the translation below the original. Ephemeral (client-side cache only). Registered as unreleased feature `team-chat-message-translation`. | [team-chat-message-translation.md](team-chat-message-translation.md) |
| Team Chat (built-in channels and direct messages) — part 2 | Part 2 of the Team Chat page: the second wave of features — day dividers, drafts, saved items, custom status, scheduled send, attachments and custom emoji — plus the workspace story, with per-channel roles and invitations, self-serve workspaces you create and share by invite code, and 1:1 connections with people in other organizations. | [team-chat-part-2.md](team-chat-part-2.md) |
| Team Chat (built-in channels and direct messages) — part 3 | Part 3 of the Team Chat page: the phone client and the surfaces that sit around the core chat — the standalone phone web app and its push notifications, notification preferences, rich link previews, the project-management bridge, share-comment cross-posting, starting a Claude session from a thread, the Session Starter Bot, the media gallery and video-call backgrounds. | [team-chat-part-3.md](team-chat-part-3.md) |
| Team Chat (built-in channels and direct messages) — part 4 | Part 4 of the Team Chat page: what the feature deliberately does not do and the shortcuts still to come, then the engineering — how messages, threads, pins and reactions are stored and kept honest, how search is built and why it is not switched on yet, and what an operator still has to do to take Team Chat live. | [team-chat-part-4.md](team-chat-part-4.md) |
| Team Chat summarization (planned) | In-development, not yet built (registered as unreleased feature `team-chat-summarization`) — will summarize a Team Chat channel or thread. | [team-chat-summarization.md](team-chat-summarization.md) |
| Team Chat (built-in channels + DMs, a Slack replacement) | A built-in real-time team messenger inside Omniscio — channels + direct messages delivered live to every device (desktop and phone) via the cloud, using your existing Global Auth identity (no separate account) — plus fully self-serve workspaces you create yourself and share by a 10-char invite code (a separate Firestore-native tenant `chatWorkspaces/*` beside your governed company workspace in one switcher rail; server-gated join, chat-local roles only, no billing/claim coupling). Create public/private channels and 1:1/group DMs (addressed by a deterministic participant id, so a DM never forks), send with @mentions, optimistic send + offline queue (no double-posting), self-profile widget + manual availability overrides, presence + typing indicators, unread badges, and "load older" history. Self-serve workspace tiles can be given a custom gradient color (right-click or long-press) for visual distinction; an owner can **delete** a self-serve workspace with a **30-day undo** (soft-delete + Undo toast, then a scheduled reaper permanently erases it — F046). Renders as a native built-in virtual project beside the projects sidebar (NON-spawnable — no Claude session); the renderer talks to Firestore directly (not through Omniscio IPC), authorized entirely by Security Rules. $0 of AI spend. Custom emoji: workspace admins upload party-parrot-style images (PNG/GIF/WebP ≤256 KB) with a `:shortcode:` that works in the emoji picker, reactions, custom status, and inline in message text. In-development — reveal via Settings → Lab toggle or `AMC_SHOW_TEAM_CHAT=1`. | [team-chat.md](team-chat.md) |
| Team sharing (share skills, automations & saved prompts with teammates) | Hand a **skill**, **automation (recipe)**, or **saved prompt** to teammates two ways. A one-off **share code** — a self-contained text string, no cloud: the **Share** button produces it (secret-scanned first; an over-cap skill is refused, not truncated), and **Import a shared item** previews then installs it — works today for everyone. Plus an **in-development, off-by-default Team Library** (`team-library` flag): a members-only per-workspace shelf where **Share to your team** publishes an item once and teammates see it under a **Team** tab and **Install** in one click (the creator or a workspace owner/admin can **Remove**). **Nothing runs on import** — skills land as files (never executed until used), prompts as a library row, automations **paused** until approved; a secret scanner flags keys/paths before a code exists. The Team Library is members-only, enforced by cloud rules (`sharedLibrary` under the org/workspace), not the UI alone; distinct from public **"Shares"**. Turning it on is a separate gated `firestore.rules` deploy. Contract: team-sharing-contract. | [team-sharing.md](team-sharing.md) |
| Team Time (world clock dashboard) | Built-in feature for managing team members across timezones — live clocks with working-hours status (green/amber/red), meeting planner with overlap detection and copy-summary, reverse time converter for scheduling emails at specific times in someone else's timezone; IANA timezone picker, group organization, 30s auto-refresh; gated on `teamTimeEnabled` (default off), Globe toolbar icon, Quick Launch tab | [team-time.md](team-time.md) |
| Microsoft Teams | Experimental Microsoft Teams integration — a "Microsoft Teams" sidebar tab listing synced online meetings from Microsoft Graph API (date-grouped: upcoming/today/earlier), meeting detail view (attendees, join URL, organizer, location), OAuth 2.0 with PKCE (/common tenant for personal + work/school accounts), periodic background sync with delta queries for incremental updates. Read-only: never creates or modifies meetings. Gated via `teams` unreleased-feature (`teamsIntegrationEnabled`). | [teams.md](teams.md) |
| Telegram Bot channel (talk to your agents from Telegram) | A BotFather bot you message to talk to your Omniscio agents — one durable agent session per Telegram chat / group / forum topic, the agent's final answer relayed back to the same chat, survives restarts. Long polling with durable dedup + offsets; pairing / allowlist AUTHENTICATION (separate from the automations Approved Senders cost guard); `/start` `/new` `/status`; text-only in this version. Separate from the personal-account Telegram integration below. Settings → Channels → Telegram Bot; CLI `/telegram-bot/*`. Contract: telegram-bot-channel-contract | [telegram-bot-channel.md](telegram-bot-channel.md) |
| Telegram integration | Read and reply to Telegram chats from Omniscio using your real account (MTProto user-API via **mtcute**; the archived gramjs engine remains a reversible opt-out) — phone+code+2FA login, encrypted session storage, real-time delivery, photos/voice notes. **Bring your own API key:** a build that ships without Telegram credentials now says so plainly instead of offering a Connect button that cannot work, and Settings → Telegram accepts your own `api_id`/`api_hash` from my.telegram.org (stored encrypted, main-only, effective without an app restart). It is also the escape hatch when Telegram throttles a too-widely-published shared key (`API_ID_PUBLISHED_FLOOD`), so it stays reachable even when a key IS bundled. Changing the key clears the saved session — an MTProto session is bound to the api_id it was authorised under — but keeps your message history | [telegram-integration.md](telegram-integration.md) |
| Telegram via mtcute engine (default) | The mtcute engine is the default Telegram MTProto engine — Settings → Channels → Telegram engine (mtcute default / gramjs opt-out), one-time re-auth per engine | [telegram-mtcute.md](telegram-mtcute.md) |
| Text size (separate Desktop and Mobile) | Two independent Appearance settings — `fontSize` (desktop; Ctrl+= / Ctrl+- and Ctrl+mouse-wheel step it) and `mobileFontSize` (the mobile / narrow-touch layout). Seven steps Extra-Small…XXX-Large; desktop defaults Medium, mobile defaults Extra Large; the phone no longer inherits the desktop size. Resolved per-surface by `resolveFontSize` / `useEffectiveFontSize` so the rendered rem and every layout measurement agree. | [text-size.md](text-size.md) |
| Time Tracker (local per-project time tracking — timers, timesheets, billable hours) | A built-in, off-by-default personal time tracker inside Omniscio. Press **Start** when you sit down to work and a live timer runs; press **Start** again (or **Stop**) and the block drops onto a colour-coded **Today** timeline. Each block can be tagged, attributed to a **tracker project**, and marked **billable**; a stats strip shows today / this-week / by-project totals plus today’s billable dollar figure (hours on the clock × the project's hourly **rate**, derived once per project so totals never drift by a penny, and kept fully separate from Omniscio's AI-spend tracking). One timer at a time — starting a new block auto-stops and logs the previous one; a **runaway-timer** banner lets you **Keep**, **Stop** (keeping the time so far), or **Discard** a timer left running unusually long (e.g. overnight or across a restart). Runs as an Omniscio built-in **virtual project**: the panel owns the whole area beside the projects sidebar and works on a phone too, and it is **NON-spawnable** (hosts no Claude session). 100% local — no AI, no internet, no cost. It also folds completed **Pomodoro focus** sessions onto the same timeline (as green focus blocks), and lets you **plan** intended time ahead and compare **planned vs. actual** — planned "ghost" blocks plus a per-day / per-project **variance** readout (planned hours vs. actual hours, over/under), kept **time-only** (planned time never affects billable dollars). A **Reports** tab rolls up a date range (today / this week / this month / custom) into total hours, hours by project (with billable $) and by tag, and exports a **detail** CSV (one row per entry, no dollar column) or a **summary** CSV (per-project + per-tag rollup) — billable $ derived once from actual entries, CSV cells formula-injection-safe. Automatic foreground-app capture, recurring/repeating plans, reminders, a formatted **PDF** report, invoices, and clients are planned follow-ups. In-development — reveal via **Settings → Lab → Time Tracker** (unreleased-feature registry id `timeTracker`, setting key `timeTrackerEnabled`, default off). | [time-tracker.md](time-tracker.md) |
| Toolchain Updates (background checks + one-click "update in a terminal") | How Omniscio checks for CLI-tool updates and lets you update each one yourself, easily — every recommended tool gets a one-click **Update** that opens a terminal running its own update command (claude-code → `claude update` on the real binary, git/gh → winget/brew, npm tools → `npm i -g`, Go tools → `go install`); claude-code no longer silently npm-updates the wrong copy. When Claude Code, Codex or another recommended tool falls behind, an inbox card with a one-click **Update now** runs that same terminal update (a download page for a hand-installed tool; on by default, two Settings toggles). An optional silent-npm background path (the `autoUpdateTools` toggle, off by default) still covers playwright/agentmail/repomix. | [toolchain-update-v3.md](toolchain-update-v3.md) |
| Tools View (browse installed CLIs + linked skills) | Dedicated virtual project listing 31 CLIs by category with install status, version chip, and chips that jump to skills depending on each tool | [tools-view.md](tools-view.md) |
| Tray and window | System tray icon, `closeToTray` setting (default `false` — X quits, not hides), Quit menu, global focus hotkey (Ctrl+Shift+M), new-session global hotkey (Ctrl+Space), single-instance enforcement, popped-out windows reopen on relaunch (detached session / KMS / Scratchpad / project / Support Chat; `AMC_DISABLE_POPOUT_RESTORE` off-switch) | [tray-and-window.md](tray-and-window.md) |
| Tree diagrams in chat | An agent-drawn tree (`├── / └──`) keeps its meaning in COLUMN ALIGNMENT, which cannot survive a column narrower than its widest line — on a phone the block wrapped and a label folded flush against the `│` rail, destroying the structure. Such blocks now render as a real tree: labels wrap under themselves, each branch folds via a chevron, depth comes from indentation + a guide rail rather than character padding, and a rail-indented description stays with its own label. Detection IS the parse (no separate heuristic, no AI call, no network, no cache) and is all-or-nothing — one unreadable line renders the whole block exactly as before, as do language-tagged fences, tables, panels, arrow flow diagrams, and rootless fragments. Opens fully expanded; the original is one tap away and copying always yields it. Setting `treeDiagramWidgetEnabled` (Appearance → Message Formatting). Contract: ascii-tree-diagram-widget-contract. | [tree-diagram-rendering.md](tree-diagram-rendering.md) |
| Trello (in development) | In-development real Trello REST API integration (default-hidden, gated via the `trello` unreleased-feature; `trelloEnabled` toggle in Settings → Lab, or `AMC_SHOW_TRELLO=1`). Adds a "Trello" sidebar virtual project that connects to your real trello.com account via the Trello REST API v1. Connect via an API Key + API Token in Settings. Implements board list sidebar, kanban columns by list, card detail drawer (description, checklists, comments, labels, members, due dates), card search, and a `trello-inbox` source surfacing cards assigned to you as unified-Inbox rows. CLI routes for AI agents: POST /trello/move-card, POST /trello/create-card, POST /trello/comment. Rate-limited (6 concurrent, auto-retry on 429). SSRF-guarded to api.trello.com. Separate from Ollert (the self-hosted native port). | [trello.md](trello.md) |
| Trickle back (staggered snooze — bring a pile back a few at a time) | Take 2+ selected inbox rows OR Supermail email threads and have them return from snooze **a few at a time on a cadence** instead of all at once — a snooze variant that returns items in waves. Pick how many come back per wave (1/2/3/5) and the pace (a simple interval like "every 30 min" OR a clock schedule like "weekdays at 9am"); the dialog previews when the last wave returns. Inbox trigger: the right-click "Trickle back…" on a selected row (desktop) + the "Trickle" button in the mobile selection bar; Supermail trigger: the hourglass button in the inbox selection toolbar — both shown only at 2+ selected. It's **snooze with staggered return times** — NO new background service and NO new table: each item is snoozed to its own wave time via the surface's normal per-item snooze (sessions, universal inbox kinds, or the mode-aware Supermail snooze), and the existing 60-second snooze sweeps bring each wave back. Capped at 100/trickle; a bad clock schedule refuses the whole batch; a single un-snoozeable item is skipped. v1 management is the existing Snoozed views (+ a whole-batch Undo on the inbox); a "trickle group" unit is a fast-follow. Contract: trickle-snooze-contract. | [trickle-back.md](trickle-back.md) |
| Turn duration (how long Claude took to respond) | Every turn in chat carries a duration label — live `streaming… 1m 12s` ticker while the session is `running`, frozen `… · took 1m 30s` once settled; on every `/compact` divider an activity bubble rolls up the work between this divider and the previous one as `13 actions · took 1h 42m`, using operator-row splitting so user-idle gaps between turns don't inflate the total (a real 7h 54m wall-clock fixture with one 5h 56m idle gap reduces to `1h 42m` active); ticker hides whenever the session leaves `running`; paused-then-resumed turns are a documented edge case that inflates the in-bubble label because the underlying operator/reply timestamps don't shift on pause | [turn-duration.md](turn-duration.md) |
| Tweet cards (X/Twitter links render the tweet, everywhere) | Any X/Twitter status link surfaced ANYWHERE in Omniscio — an agent message, your own message, an inbox alert, a Field-Theory drip item, or a team-chat message — renders the tweet as a pixel-identical screenshot card (the same render KMS paste produces), regardless of who produced it or how it arrived; click to open on X. Vault-free cache keyed by tweet id (rendered once per tweet, served over `tweetshot://` on desktop + `/tweetshot` on mobile); cost-bounded (permanent cache + hourly new-render budget + `AMC_DISABLE_TWEET_SHOT_CARDS` kill switch) and SSRF-safe (fixed relay host, numeric id only); any failure falls back to the plain link. | [tweet-cards.md](tweet-cards.md) |
| Typing Insights (passive typing-speed stat) | Measures your real typing speed in the session composer and shows it as a **Typing Speed** card in Statistics → Overview (average WPM for the range + peak). On by default; **Settings → System → "Track my typing speed"** toggles it (env kill switch `AMC_DISABLE_TYPING_INSIGHTS=1`). Built near-zero-cost: it rides the composer's EXISTING per-keystroke hook and does only O(1) work (no React state, no per-keystroke IPC), flushing one fire-and-forget sample per typing BURST on idle. Counts genuine single-char typing only — pastes, edits, IME, and thinking pauses excluded. Main recomputes WPM (a local `computeWpm`, formerly shared with the Typing Tutor engine — inlined when that engine moved into the Typing Tutor plugin) and upserts a bounded per-day tally (`composer_typing_daily`, migration `20260711133626`). Distinct from the Typing Tutor: this reports your real typing and never feeds the tutor's drills. Fully local, no cost; main composer only (v1), English/Latin, desktop-first. | [typing-insights.md](typing-insights.md) |
| Typing Tutor (learn touch typing — plugin) | Self-contained **marketplace plugin** (formerly a built-in integration), desktop-oriented touch-typing tutor — its screens run in the plugin's own webview: a sidebar (modes / Practice-Progress / settings / reset) with the practice area in the panel beside it. Three modes: **Learn** (beginner — starts on the home row, on-screen keyboard shows the next key + which finger, unlocks a new key only once the current set is mastered), **Drill** (real words biased toward your weak keys), and **Challenge** (a timed 60s run with a personal best). The "intelligence" is a pure, deterministic **local** engine (a per-key speed/error model → mastery-gated progression + weak-key-weighted practice — the keybr idea, offline + private + free; an AI-generated practice mode is a planned fast-follow). Game layer: XP + levels, a daily streak, unlockable achievements, and personal bests; the Progress view adds a WPM-over-time chart, a per-key mastery heatmap, and the achievements grid. Scoring runs locally in the webview; a corrupt save falls back to a fresh profile. Data lives in the plugin's own storage collections (`typing_profile` blob + `typing_sessions`); a one-time migration carries a prior built-in user's progress in. Keystrokes are captured on a focused `contentEditable` so global shortcuts stand down. QWERTY only, single local profile, desktop-oriented, marketplace-only (reset is a confirm-gated UI button, no CLI route). | [typing-tutor.md](typing-tutor.md) |
| UI Auto-Tidy (auto-demote — never delete — controls you never use; opt-in, default off) | Builds on UI Usage: an **opt-in** (Settings → Diagnostics toggle, **off by default**) loop that, on launch + once daily, demotes sidebar integrations + toolbar icons you've **never used in 30+ days** into a quiet spot — integrations collapse into a low-key **"Unused (N)"** group in the projects sidebar, toolbar icons drop into the **"…" overflow** — and posts **one consolidated inbox notice** per run. **Demote ≠ delete/disable**: nothing is removed or turned off, only moved; the feature still works in its quiet location. A curated allow-list is the only eligible set (essentials like Send/Stop/Settings are absent; the Alerts integration is excluded); a 30-day **global** history floor + a **rolling** "not used in the last 30 days" per-feature signal (only *established* controls — used >30d ago, or on-screen ≥30d — so a control used long ago but not lately is now fair game while a brand-new one is spared) + a soft per-run cap of 8 keep it gentle and dodge the cold-start "everything's unused on day one" problem. Everything is restorable one-click in **Settings → Diagnostics → Hidden items** — and simply **using** a demoted item (opening the integration or clicking the toolbar control) auto-restores it, the tidy notice's own peek link excepted — with a restored item entering a `kept` set so it's **never auto-demoted again**. 100% local — reads `ui-usage:summary` + raises an inbox alert only, no new egress/table; all logic renderer-side. Deferred: chat-bar "⋯" zone, stale real projects | [ui-auto-tidy.md](ui-auto-tidy.md) |
| UI Usage tracking (which controls + integrations you use vs never use — local Stage 1) | Settings → Diagnostics card + "Track which UI controls you use" toggle (on by default) that records, **100% locally**, which named controls you click (button/link/toggle/tab/menuitem `data-ui-anchor`s) and which sidebar integrations you open, then shows most-used + a **"Never used"** list for each over a today / 7d / 30d / all window with a "tracking since" note — so unused things can later be removed or auto-hidden. Captured by one root capture-phase click listener (allow-list = the interactive, non-internal `data-ui-anchor` registry; templated `session-row:<id>` etc. ignored) plus the `setActiveProject` chokepoint for integration opens (counts hotkey/palette opens; startup `source === 'restore'` re-open suppressed); buffered + fire-and-forget flushed via `ui-usage:record` (every event platform-stamped mobile/desktop; integration *closes* recorded with dwell alongside opens) to a dumb-storage `ui_usage_events` SQLite table, with the renderer computing "never used" by diffing windowed counts against the catalogue FILTERED to controls that can render here (a `visibility` gate excludes dev-only / other-platform / off-unreleased controls — off ≠ unused, now for controls too, tagged via a `gatedBy()` per-file helper) + the CURRENTLY-VISIBLE integrations, and showing a mobile/desktop split (the anonymous fleet-digest read stays platform-free and fails closed on the new `integration_close` kind, so neither leaves the device). The "Never used" lists look large on day one (everything's unused until clicked) by design. `usageTrackingEnabled` is decoupled from telemetry consent (local feature switch, not send-consent); an anonymous install id is minted now but stays dormant/unused. Nothing leaves the device in Stage 1; a future opt-in Stage 2 (anonymized cross-user rollup) is not built | [ui-usage-tracking.md](ui-usage-tracking.md) |
| Unclaimed-Check (sign-in-gated US unclaimed-property lookup, agent-callable) | A free, agent-callable capability that checks whether a person is owed US unclaimed property (money a state holds) by name — covers CA & NY, every match links to the official state site to claim for FREE. Exposes the existing unclaimed-check Cloud Run service to EVERY signed-in Omniscio user by proxying through the jls-gateway on the user's own Firebase sign-in, so the shared service key never reaches the client. Desktop route `POST /unclaimed/search` (self-gates on the in-development `unclaimed-check-capability` flag, 404 when off; `allowAgentSession`) attaches the Firebase token and forwards to the gateway's `POST /v1/unclaimed/search`, which verifies the sign-in with an open-to-all authenticator (allowlist skipped — the capability is free + rate-limited), rate-limits per-uid (30/min + 300/day) + per-IP (60/min, env-tunable, fail-open), and calls upstream with the server-side x-api-key. Free (no credits — the rate limits ARE the cost control). Privacy: names transit as headers never a URL, and are never logged or stored on either hop. Ships DARK — OFF by default AND the gateway route is secret-gated (503 until `gateway-unclaimed-key` + `UNCLAIMED_CHECK_URL` are configured and the gateway is redeployed, a separate human-gated step). Bundled skill: .claude/skills/unclaimed-check. | [unclaimed-check.md](unclaimed-check.md) |
| Update Vault (/update-vault skill) | Built-in skill that scans Omniscio sessions and logs findings (PRs, bugs, features, tests, costs) into KMS vault notes. Two modes: this-session (before archiving) or batch scan (all sessions from last 24h). Matches sessions to QA feature notes (01-17) or auto-creates Projects/ notes for non-QA work. Introduced during onboarding via a cascade theory card after the daily-briefing mission. | [update-vault.md](update-vault.md) |
| Usage Cascade (what to run when your Claude subscription is out) | A user-ranked ladder of OTHER-VENDOR fallbacks, walked at spawn when EVERY Claude account is at its usage limit, and at turn end when a session on a ladder vendor (GLM, DeepSeek, Kimi, MiniMax) hits that vendor's usage limit or runs out of balance. Each rung names a vendor and a max-parallel cap; a session takes the first rung that is switched on, set up, not full and not one it already ran out on, and otherwise waits exactly as today. Ships EMPTY = inert, so nothing changes until you configure it in Settings -> Accounts -> Usage cascade. A moved session keeps its conversation and says so once in its transcript; one that left Claude returns (same model) at its next spawn once capacity is back, one that started on a vendor stays on its rung. Paid rungs are labelled "Bills per token". No cheaper-Claude-model rung. Kill switch AMC_DISABLE_USAGE_CASCADE=1 | [usage-cascade.md](usage-cascade.md) |
| Usage Forecast (predicted rate-limit exhaustion) — part 2 | Part 2 of the Usage Forecast page: how to read each per-account forecast state, the threshold that fires an early warning, the data-freshness line, the four-card Usage Stats page, the optional header widget and the architecture behind it all. | [usage-forecast-part-2.md](usage-forecast-part-2.md) |
| Usage Forecast (predicted rate-limit exhaustion) | Global rollup banner at top of the Accounts popover ("3.2h until you run out") plus a per-account projection row under each 5-hour bar; second muted line shows hour-of-day-aware buffer % from 14-day history ("Learning your patterns" until 7 distinct days); opt-in early warning when exhaustion drops below your threshold; new Usage Stats sub-page (Statistics → Usage) with four charts (pool trajectory, hour-of-day heat-map, per-account contribution, 7-day daily projection) plus per-card audit callouts | [usage-forecast.md](usage-forecast.md) |
| Use Quick Responses | AI-suggested replies (Alt+1/2/3), your saved Quick Replies (Alt+S — drill-in picker with breadcrumb + auto-flatten search), one-click Zap button (Alt+Z); AI chips and Zap stay flat (never drill into a folder) | [use-quick-responses.md](use-quick-responses.md) |
| Recipe Drafter (NL → validated `RecipeConfig`) | Describe a workflow in natural language; Omniscio returns a draft `RecipeConfig` (pattern-matched or synthesized) plus reasoning, warnings, and remaining validation errors via `RECIPE_CREATE_FROM_NL` | [use-recipe-drafter.md](use-recipe-drafter.md) |
| Use Recipes (multi-step agent workflows) | Save multi-step agent playbooks as `.recipe.json`; run against one or many projects, schedule via cron, chain via sub-recipes; right-click any real project row → **Run Recipe** submenu for one-hover launch (My Recipes + Templates); **Running now + History sidebar sections** show every live + past run across every recipe (1,000-row history, expand for variables/per-step status/View links, Resume — no engine-idle gate, runs can resume concurrently); per-run **Timeline tab** renders steps as a Gantt chart (status-colored bars, retry stacks, approval-gate hatching, cost annotations, bottleneck indicator, forEach expansion) for 2+ step runs; per-recipe history adds row sparklines + a **Compare runs** stacked-timeline view with recurring-bottleneck and failure-correlation badges; deep-linked from the boot reconcile toast (interrupted runs), an inline chef-hat chip on recipe-spawned session headers, and a mobile "X running" pill in the tab bar; also surfaced as `runningRuns` in the Ask-Omniscio `/state` snapshot | [use-recipes.md](use-recipes.md) |
| Use Skills (browse, install, edit) | Install, edit, and update Claude Code skills from the in-app catalog | [use-skills.md](use-skills.md) |
| Use Super Prompts (reusable prompt library) | 190 curated starter prompts for the Claude project (Ctrl+Shift+K); pin, duplicate, author your own, silent remote refresh | [use-super-prompts.md](use-super-prompts.md) |
| User Management (owner/admin-only org admin console) | Owner/admin-only console for an Omniscio **organization** — part of the optional cloud Global Auth identity layer that is OFF on installs without the sign-in gate, so the whole section is absent unless the gate is on. Once signed in, the Settings row shows for **every** user, but its label + contents are role-shaped: a global owner/admin sees the full **User Management** console described here; a plain member sees the same row labeled **Workspaces**, opening only the self-serve workspace surface (list + switcher + Create). Settings → User Management (Accounts & AI / Team & Admin group), three tabs: **Users**, **Access Requests** (amber pending badge), **Workspace**. Invite one or bulk-invite by email, approve/deny join requests, change **role** (owner/admin/member/trial) or **tier** (enterprise/pro/starter/free), enable/disable/delete accounts, and assign Team Chat workspace membership (org_admin/member). Self-protection: you can't change/disable/delete your own row. The nav-row role check is only cosmetic; the real boundary is server-side — every op calls `assertCallerIsAdmin()` then a token-verifying Cloud Function that re-verifies admin from cryptographically-verified Firebase ID-token claims (`manage_users` needs role ≥ admin). Deleting removes the profile doc, not the Firebase Auth login. The core console is NOT a Lab/in-development feature — gated purely by role. Cloud-backed (Firebase). Also documents the **self-serve workspaces** layer (`self-serve-workspaces`, shipped 2026-07-19): a paid-tier user creates/owns their own workspace, switches the active one, and a workspace owner/admin gets a scoped roster — all-Firebase by owner decision (2026-07-17), membership subcollection is authority. A free user who tries to create a workspace is routed to the real **Plan & Usage** storefront to upgrade (the old mock **Pricing** screen was retired 2026-08-18; its config path is kept dormant). | [user-management.md](user-management.md) |
| Utility AI model (which model runs background AI features) | Omniscio uses a small, fast AI model in the background for dozens of minor tasks that don't need a full coding session — generating session titles, drafting suggestions, daily digests and weekly summaries, summarising articles and meetings, correcting text, and more. The **Utility AI model** setting picks which model runs this background workhorse. | [utility-ai-model.md](utility-ai-model.md) |
| Vendor server fault recovery (a temporary provider error never asks you to change models) | When a provider's own servers return an error, Omniscio treats it as temporary and keeps retrying in the background — including on a brand-new session whose first turn failed, which used to be parked with "choose another model" instead. Covers the signals it reads, what it tells you, and which failures still stop the session for a real decision. | [vendor-server-fault-recovery.md](vendor-server-fault-recovery.md) |
| Verdict panel (is the verdict road healthy, and where is it backed up?) | The Developer Tools **Verdict** panel: one status sentence ("the line is flowing" / "backed up at Dispatch — 14 waiting, oldest 11 min"), six headline stats each judged against a normal band (Answered · 3 h vs the 80% floor, Time to answer p90, In the line, Fleet healthy + spend on pace, This box user-harm, Landing oldest ready — fixed where a rule exists, else 1.5× the last 24 h with the coverage stated), the road drawn as an eight-station line (Ask → Seal → Dispatch → Run → Verdict → Deliver → Tag → Land) with two distinct bottleneck marks (biggest pile, slowest vs its own normal), alarms only when something tripped, and one-click drill-downs into every station, the fleet, this machine and the broker machinery, each ending in a raw-rows disclosure. Every number carries its source and as-of time and is one of three states — measured, stale, or "no reading" (never zero, never green). Answers waiting on sessions you paused are shown quietly and never counted as faults. Read-only (Refresh · Copy readout · reveal a file); computed in the main process from the broker's own tick ledger, the telemetry day files, gate-honesty, fleet-vitals, the performance readout, the sessions table and the worktree ledger; agents read the same snapshot at `GET /verdict/observatory`. In-development, off by default (`verdict-panel`). Contract: verdict-panel-contract. | [verdict-panel.md](verdict-panel.md) |
| Verdict results in the transcript | A test result delivered by Verdict arrives as a message written for the AGENT — ticket, tree oid, closure key, raw `meta:` JSON, a `[GATE-VERDICT]` line — in which "did it pass?" carries no more weight than a 40-character id. Such arrivals now render as a result card: the outcome in plain words and colour, one muted line of numbers, the failing files with per-file detail and the master-vs-branch split, and a caveat row only when the answer is stale or lost its merge receipt. A total-time chip shows how long the answer took, and a bar splits it into every step that was measured — queue, setup, install, run, delivery — plus "other" for any time no step covers, so no time on the card is ever unlabelled. An infrastructure failure is orange, never red — nothing was checked either way. Recognition IS the parse, so an ordinary peer message or a future format version renders exactly as before; the agent's copy is never rewritten and "Show the original note" reveals it in full. Internal ids stay off the card. | [verdict-result-cards.md](verdict-result-cards.md) |
| Video/Voice Calls in Team Chat (LiveKit WebRTC, in development) | In-development channel-scoped voice and video calls (gated via `video-calls` unreleased-feature, `videoCallsEnabled` / `AMC_SHOW_VIDEO_CALLS=1` / Settings -> Lab). Renderer-side code fully built: Zustand store state machine, LiveKit room hook, call UI (controls, grid, incoming overlay, background picker), IPC schemas. Deployment blockers: Cloud Functions (callStart/callJoin/callEnd) not yet deployed to Firebase, LiveKit DPA pending, server-side stale-heartbeat cleanup not yet implemented. Up to 50 participants; $0 AI spend (media is peer-to-peer via LiveKit). Contract: team-chat-video-call-contract | [video-calls.md](video-calls.md) |
| Video playback speed (remembered between plays) | Every video in Omniscio — a **drip** feed video, a chat/gallery **lightbox** video, a **screen-recording** review, a **Telegram** video message, an inbox card, a shared link and the embeddable page — plays in the ONE video player, whose **speed control** (0.5× · 0.75× · 1× · 1.25× · 1.5× · 1.75× · 2× · 2.5× · 3×) sits in the control bar along the bottom, beside full screen, and comes along into full screen (the player goes full screen as a whole). Keyboard: **Shift+>** faster, **Shift+<** slower. Inside the app the choice is saved as one global `videoPlaybackRate` setting (range 0.5–3, default 1×) and re-applied to each video on load (browsers reset playbackRate on every new source); a shared link or embed has no access to settings, so it starts at 1× every time. Speeds + bounds are one shared source (`video-speed.ts`); no dedicated CLI route (it's an ordinary setting). | [video-playback-speed.md](video-playback-speed.md) |
| The video player (one player everywhere) | Every video in Omniscio plays in ONE player — the app (drip feed, lightboxes, recording review, Telegram video, inbox card), a **shared link** page, the **embed** page, and a **live code-drawn film**. Same controls everywhere, all in the bar along the bottom: play/pause, seek bar with time, volume, a **speed control** (0.5×–3×), captions, picture-in-picture, download (when the video offers one) and full screen of the WHOLE player, with the Omniscio mark leading the row. Same keys everywhere: Space/K play, J/L ±10 s, ←/→ ±5 s, ↑/↓ volume, M mute, F full screen, C captions, Shift+>/< speed, 0–9 jump, Home/End. Keys act only while the player has focus, and never also trigger an app shortcut. Controls hide after 2.5 s of playing untouched; a tap on a phone shows them. If the player ever fails to start, the browser's own controls stay. Links shared before it existed keep their old page. | [video-player.md](video-player.md) |
| Virtual Pets (plugin — converted from built-in) | Pixel-art companion plugin (free, Omniscio Marketplace) — pet roams window edges, reacts to session events, idle-escalates; 9 species, click/double-click interaction; uses Plugin SDK overlay capability, desktop-only | [virtual-pets.md](virtual-pets.md) |
| Visual Themes | 13 bundled skins (incl. the frosted **Liquid Glass**) + custom `.theme.json` imports — instant recolor, no code changes | [visual-themes.md](visual-themes.md) |
| Voice "about to act" highlight (voice) | During a voice (Layer 2) confirmation, spotlight the on-screen thread the confirmed action will touch so you can see what you are confirming before saying "yes"; off by default and in development (`voiceActHighlightEnabled`, Settings -> Lab); visual-only (never acts, never changes the confirm gate); no new AI call (a pure lookup of the already-decided action); reuses the existing UI highlight overlay via `voice:act-highlight-show` / `hide` IPC; targets the always-present `session-panel` anchor and shows nothing for off-screen targets; wired on the `confirm` + `confirm_ask_agent` directives only | [voice-act-highlight.md](voice-act-highlight.md) |
| Voice, TTS & Wake Word (hands-free Omniscio) — part 2 | Part 2 of the Voice, TTS & Wake Word page: the engines behind the voice stack. It covers the wake-word engines and the retired Picovoice option, the speech-to-text providers with their keys and costs, the Omni Session Briefing, spoken output that follows the content's language, third-party dictation and spoken thinking fillers. | [voice-and-tts-part-2.md](voice-and-tts-part-2.md) |
| Voice, TTS & Wake Word | Four TTS providers (Fish Audio default, Grok xAI, ElevenLabs, Speechify/Simba) read agents aloud; voice dictation (wake word or toolbar mic delivers transcript to active session, auto-send or review-first); voice commands via Alt+V hotkey; offline openWakeWord wake word (Porcupine retired); Omni per-session briefings (Ctrl+Shift+J); settings now at Settings &rarr; Voice Control; spoken thinking fillers during slow voice lookups (conversational response style only, off by default) | [voice-and-tts.md](voice-and-tts.md) |
| Voice Attachment (Omniscio Voice vs Session Voice indicator + pin) | A glanceable chip showing whether voice targets **Omniscio Voice** (app-level L1/L2) or a specific **Session Voice** (L3/L4) target (`pinned ?? focused`), a per-utterance route receipt, and an explicit **pin** that keeps voice on one session while you browse elsewhere. Click the chip to change target (Omniscio Voice = unpin, or pick a running session), or say "pin voice to this session" / "unpin voice" / "where is my voice attached". Precedence is locked: named > deictic-then-focus > pin > focus (a pin never steals "this conversation"). Off by default and in development (`voiceAttachmentEnabled`, Settings -> Voice Control); ephemeral (a pin never survives a reload); auto-unpins when the pinned session ends; no new AI call and no new IPC. | [voice-attachment.md](voice-attachment.md) |
| Microphone calibration (voice barge-in) | A short guided 2-step test (stay quiet ~5s, then read one fixed sentence ~5s) that tunes voice barge-in sensitivity to your specific microphone and room so background noise does not falsely interrupt the AI and quiet talkers still register; experimental, behind the off-by-default `voiceBargeInLabFlag` Lab flag (general-availability toggle arrives in a later slice); Settings &rarr; Voice Control &rarr; Voice Report Back, via a first-toggle nudge ("Calibrate now" / "Skip for now") plus an always-available "Calibrate microphone" button; per-microphone (keyed by device id in `vadThresholdsByDeviceId`), calibrates once per mic and persists; "Skip for now" / uncalibrated uses a sensible default identical to the prior fixed sensitivity and saves nothing; no-mic / blocked-access / too-noisy / too-quiet all block with a clear message and save nothing | [voice-barge-in-calibration.md](voice-barge-in-calibration.md) |
| Voice History (Omniscio Voice + Session Voice) | Sidebar virtual project (`__voice_history__`) that persists + lists past voice conversations — both **Omniscio Voice** (app-level, L2 orchestrator) and **Session Voice** (L3/L4, tied to a session) — in one recency-ordered two-pane viewer (list + transcript) with a type filter and soft-delete; live-refreshes on the `voice:history-changed` push. Backed by the soft-deleted `voice_conversations` / `voice_turns` tables. | [voice-history.md](voice-history.md) |
| Voice L3 - Ask About a Thread (voice) | Hands-free `session:converse` intent; off by default (`voiceL3Enabled`); two phrasings -- summary ("tell me about the X thread", reuses Omni briefing) and question ("in X, what is blocking it?", answered by xAI Grok via OpenRouter from that thread's transcript only); fuzzy session-name resolution, falls back to active session; strictly read-only (nothing queued to live agent); daily cost cap (`voiceL3DailyCapUSD`, default $1); Slice 1a is single-shot -- no follow-up turn, no queue-to-agent | [voice-l3-session-voice.md](voice-l3-session-voice.md) |
| Voice L4 - Ask the Live Agent (voice) | Hands-free `session:ask-agent` intent; off by default (`voiceL4Enabled`); queues spoken questions to LIVE running sessions (read-only-framed) via a managed ready-queue + on-screen panel (asked -> working -> ready status); when answers land, announces at a polite idle moment and reads one at a time (go ahead / next / skip / what's ready?); running threads only (never spawns); one question per thread; no new AI call (the agent answers); queue is live-only (resets on restart) | [voice-l4-ask-agent.md](voice-l4-ask-agent.md) |
| Voice Report Back (read voice-command answers aloud) | After a voice command's LLM-layer prose response, Omniscio speaks it back through whichever TTS provider you've picked (Fish Audio / Grok / ElevenLabs); off by default; Settings &rarr; Voice Control &rarr; Voice Report Back; gates on enabled + `source === 'llm'` + non-empty + daily cost cap; slices long answers to `voiceReportBackMaxChars` (default 600) with a `[Speak more]` button on the floating voice-result card for the remainder; per-utterance cost row logged to `api_cost_log` under source `voice-report-back-tts`; Slice 1 has no barge-in, no tool-confirmation speech, no mid-speech cancel | [voice-report-back.md](voice-report-back.md) |
| Voiceprint Studio (build an email style guide in your voice) | An in-development sidebar panel that builds + sharpens an **email style guide** — the doc you paste into any AI to draft email in your voice ("voiceprint" = your WRITING voice, NOT audio/TTS). Four tabs: **Corpus** (pull your Gmail Sent folder; each email auto-guessed You/AI with the reason; confirm/flip), **Calibrate** (the AI re-drafts one of your real emails BLIND — it never sees your reply — then a 3-pane compare with optional blind mode; Nailed it / Off → note → the AI proposes one guide rule → Approve & save), **Style Guide** (the living, versioned guide), **Progress** (pass rate). The default profile seeds from AND mirrors approved fixes back to `~/Claude/default-email-voiceprint.md` (atomic write + .bak; reads on open, writes only on Save/Approve). Needs Gmail connected + an Anthropic key (graceful messages if missing); sent mail stored locally; the blind-draft context excludes your real reply (test-locked); never sends email. Reveal via Settings → Lab toggle or `AMC_SHOW_VOICEPRINT_STUDIO=1`. | [voiceprint-studio.md](voiceprint-studio.md) |
| Waiting detector — part 2 | Part 2 of the Waiting detector page: what happens when a silent wait reaches its cap, how an agent-stated ETA becomes the wait window, the Keep waiting and Check in buttons, the automatic check-ins on both sides of your inbox, the inbox right-click menu, the hidden confirmation probe for ambiguous waits and the Plain Speak Wait card. | [waiting-detector-part-2.md](waiting-detector-part-2.md) |
| Waiting detector — part 3 | Part 3 of the Waiting detector page: everything the detector deliberately never does, the optional AI second opinion that double-checks the pattern match, and the first half of the technical reference for anyone working on the code — the single chokepoint every needs-you flip passes through and the pattern library behind it. | [waiting-detector-part-3.md](waiting-detector-part-3.md) |
| Waiting detector — part 4 | Part 4 of the Waiting detector page: the ScheduleWakeup check-in mode an agent can opt into, then the rest of the technical reference — the three rejection guards, the live-corpus validation, every setting and kill switch, the subagent defense-in-depth gate and the idempotency and race protections. | [waiting-detector-part-4.md](waiting-detector-part-4.md) |
| Waiting detector (suppress spurious "needs you" flips) | When the agent ends its turn with prose like "Waiting on lint" or "I'll continue once tests pass" without using the `ScheduleWakeup` tool, Omniscio keeps the session running for up to 30 minutes of silence instead of flipping it to your inbox (any fresh activity resets the window) — and if the wait stays fully silent for the whole window it then surfaces to your inbox (`wait_timeout`) rather than re-waiting indefinitely; 18 high-confidence regex patterns + question-always-wins; Settings → Sessions → **Detect waiting agents** (default on), with an optional **official-text-only** match mode (`waitingDetectorCorpusEnabled` — recognize ONLY Omniscio's own wait phrase instead of the full phrase corpus, for near-zero misfires); the canonical wait sentence can carry an optional `ETA <N> minutes.` — Omniscio then waits that long (clamped 10–240) and checks in at the ETA regardless of the auto-check-in toggle, bounded to 3 (invariant **I19**); **Tier-3 confirmation** (`waitConfirmEnabled`, opt-in, default off) sends the agent ONE invisible confirmation on weak/ambiguous "am I waiting?" language instead of flipping straight to your inbox — bounded to one probe per wait (can't loop), the whole exchange hidden, on the not-waiting path your original message surfaces unchanged (kill switch `AMC_DISABLE_WAIT_CONFIRM=1`); kill switch `AMC_DISABLE_WAITING_DETECTOR=1` | [waiting-detector.md](waiting-detector.md) |
| You don't need to watch a running agent (in-session hint + weekly leverage card) | Two on-by-default, device-local nudges to stop babysitting a running agent. A small in-session HINT (desktop) appears once you've actively watched a running agent ~45s (window focused + mouse moving; the timer accrues active time and pauses—never resets—on a still-mouse gap), reassuring you it'll come to your inbox when done. A weekly leverage CARD lands at most once every 7 days on a notable-watching day, tallying your watch-time and nudging you to run more agents in parallel; "Turn off these notices" mute. No AI. Settings → Notifications (`watchingRunningAgentNudgeEnabled` + `watchingTimeRecapCardEnabled`, both default on). Contract: watching-agent-nudge-contract | [watching-agent-nudge.md](watching-agent-nudge.md) |
| Wayfinding (titlebar breadcrumb + back/forward) | The desktop titlebar's left cluster carries a location trail plus browser-style back/forward arrows (`Ctrl+[` / `Ctrl+]`, rebindable, shown in the `?` overlay). The trail reads `Group > Panel > Tab` (`Developer Tools > Dev Pipeline > Auto-lander`) and is not depth-capped; every crumb but the last is a real link. Location is TWO-dimensional -- the view AND the active virtual project -- because 14 of the 17 top-level views are full-screen and almost every destination is a virtual project inside the dashboard; group/panel names come from the same integration manifests the sidebar reads, so a crumb cannot drift from its sidebar row. A third crumb is opt-in per panel (22 publish, Settings among them -- it publishes its SECTION, so the trail names which settings page you are on); a strip that toggles which list the SIDEBAR shows, a filter, or a dialog's tabs is deliberately excluded because a confidently WRONG crumb is worse than a short one -- a ratchet test fails the build if a new panel with tabs neither publishes nor gives a written reason. History is browser-style, bounded at 20, and deliberately skips the app tour, the post-onboarding landing, and boot restore so Back can never strand you mid-tour. Desktop-only (mobile has its own breadcrumb + back stack). | [wayfinding-breadcrumb.md](wayfinding-breadcrumb.md) |
| Web-app verification (functionally test a web app you build, via Obscura) | Gives a coding-session agent a single `verify_web_app` tool that functionally checks a web app it built — does it load, are key elements present, does navigation/forms work, any console errors — by running real `playwright-core` against Obscura, a lightweight Rust headless browser, instead of full Chrome. Functional only: no screenshots / visual checks (Obscura has no rendering engine). Opt-in + installed on demand; the tool appears only on web-app projects when Obscura is installed and the capability is enabled. In-development — reveal via Settings → Lab toggle or `AMC_SHOW_WEBAPP_VERIFY=1`. | [web-app-verification.md](web-app-verification.md) |
| Webhooks (receive HTTP POSTs) | Local HTTP server accepts authenticated POSTs at per-source URLs and surfaces each request as an inbox row — receive-only, 1 MB body limit, bearer-token auth | [webhook-integration.md](webhook-integration.md) |
| Weekly Summary (Monday-morning recap, folded into Daily Digest) — part 2 | Part 2 of the Weekly Summary page: the feature recommendation rules, the Build it now buttons a suggestion can carry, the first-launch backfill and its past-due gate, the nominal AI usage figure, the phrase exclusion, the commit tally, the cost cap, the Workflow Coach retirement and the stored tables and settings keys. | [weekly-summary-part-2.md](weekly-summary-part-2.md) |
| Weekly Summary (folded into Daily Digest 2026-05-14) | Once-a-week ISO-week (Mon→Sun local) Haiku-written recap with stats card (sessions / messages / top projects / top features / weekly AI spend) and 3-5 personalized suggestions citing the same 6 detectors that powered Workflow Coach. **Now ships as a briefing inside the Daily Digest "Briefings" sidebar entry + inbox section** — no standalone surface. Settings live at the bottom of Settings → Email & Summaries → Daily digest. Generated every Monday at your hour (default 7 AM); first launch backfills up to 4 prior weeks; default off; daily cost cap $0.10. Migration v179 retires the `__weekly_summary__` virtual project | [weekly-summary.md](weekly-summary.md) |
| Where checks run (the testing setting — cloud first, cloud only, this computer) | One per-machine setting decides where heavy checks (tests, type checks, lint) run. Cloud first sends them to the cloud and keeps checks answering through a cloud outage by running a few at a time here; cloud only never runs heavy work here; this computer runs everything here and needs no cloud. Dev Pipeline → Setup → Where checks run, or npm run testing. A person changes it; an agent can only ask, and a person approves the card. | [where-checks-run.md](where-checks-run.md) |
| Where's My Work (what happened to your changes) | A read-only screen that answers "what actually happened to my changes?" — it reads your project's copy of the repo plus GitHub and files every branch into one of six plain-language buckets (Landed, Waiting on review, Turned down, Stranded, Couldn't check, Housekeeping), with per-branch counts of changes not shared yet. | [wheres-my-work.md](wheres-my-work.md) |
| Whiteboard (Excalidraw canvas + agent draw, in development) | In-development freeform whiteboard (gated, `whiteboardEnabled` default OFF, or `AMC_SHOW_WHITEBOARD=1`; toggle in Settings → Features), opened from the toolbar — a self-hosted MIT Excalidraw canvas (no watermark / key / cost, fully offline) docked by default beside a Boards/Sessions sidebar (optional canvas-only full-screen pop-out), the Sessions tab hosting AI sessions that draw on the open board. Standalone boards persist the Excalidraw element array + optional app-state in the `whiteboards` SQLite table (monotonic `version`, soft-delete) with a debounced de-duped autosave. The headline is the **AI glue**: an Omniscio agent reads + draws on a board via the bearer-authed `/whiteboards` CLI routes (GET list/one, POST create, PUT scene, DELETE — 404 when the feature is off, apply-immediately, structure-validated, optional `expectedVersion` 409 optimistic-concurrency), and on each external write `WHITEBOARD_CHANGED` reloads the open canvas live + supersedes a stale local autosave (anti-clobber). Fonts self-hosted under `public/excalidraw-assets/` (CJK dropped for v1); CSP adds `font-src`/`worker-src blob:`. Mermaid→shapes shortcut is a planned fast-follow. | [whiteboard.md](whiteboard.md) |
| Whole-Conversation Capture (screenshot an ENTIRE chat — clipboard + Screenshots library) | Takes a screenshot of a session's **whole conversation** — every message, rendered the way the chat renders it — from the session's **⋯ menu → Exports → Screenshot whole conversation**. It exists because the ordinary screenshot shows only one screenful. A **progress notification** appears the moment you click (loading the history → laying out messages N of M → taking the screenshot X% → saving) with a **Cancel** button. The result is a **normal screenshot**: it goes through the app's own screenshot system, so it is **copied to your clipboard** and saved to the **Screenshots library**, announced by the usual "Screenshot saved and copied to clipboard" notice with **Annotate / Share**, and it honours the snip settings (copy-only, notification level, sound). A conversation that fits comes back as **ONE image** (up to 32,767 px tall, drawn at normal size or sharper); a longer one becomes **several images in order** — the first on the clipboard, the rest in Screenshots — and the notice says how many. Images are **never silently shrunk**; only a single message taller than a whole image is drawn a little softer to fit. It normally keeps running if you switch to another conversation or app; if the conversation is closed it stops, and says so. **Desktop-only** — the command is hidden on the phone. An agent can request one with `GET /session/:id/screenshot`; that capture is private to the agent (the app's own data folder — never your clipboard, library or screen) and useful only to a **vision-capable** model (a text-only engine should use `GET /session/:id/markdown`). Contract: whole-conversation-capture-contract. | [whole-conversation-capture.md](whole-conversation-capture.md) |
| Windows Installer (branded bootstrap stub + real-progress NSIS, zero-click updates) | TWO layered Windows artifacts (2026-08-15): the PRIMARY download is `Omniscio-Installer-<v>.exe`, a ~2MB fully-custom branded bootstrap stub (Aurora/glass window with the orb + OMNISCIO wordmark drawn live for crisp text at any DPI, editable location, ONE Install click → real-% download from the update feed → SHA-512 verified BEFORE execution → silent per-user install with an honest indeterminate marquee (no fabricated time) → a Done screen with a Launch button, never a silent close; the exe + taskbar carry the orb icon via a linked resource; honest failures with a full-installer fallback link; zero-crate Rust, locked by bootstrap-installer-contract); the full `Omniscio-Setup-<v>.exe` NSIS (2026-08-14 re-engineering: DETERMINATE % + MB progress over a live step log, branded welcome/who-for/folder pages, Safe Mode shortcut, no license page, zero-click auto-update applies, uninstall data prompt) is no longer listed on the download page (removed 2026-09-01) and remains the silent engine the stub + auto-updates drive. NSIS side powered by the pnpm patch (Nsis7z::ExtractWithDetails) + build/installer.nsh; locked by installer-progress-display-contract | [windows-installer.md](windows-installer.md) |
| Woken no-op sentinel (hide "nothing to do" wake-up replies + skip the re-ping) | Default-ON: every Claude session is instructed to reply with ONE canonical sentence ("Nothing to do here. Everything was already finished before this background wake-up.") when a background event re-wakes it after it already finished with nothing to do. Omniscio whole-message exact-matches that sentence on a genuine self-resume turn, **hard-hides** the throwaway reply, and **silently restores** the pre-wake state (no fresh chime) if the session was already waiting on you. Distinct from "Hide background check-ins": deterministic instructed sentence (not fuzzy), hard-hide (not collapse), default on, own no-ping. No Settings toggle; **Show system messages** reveals hidden rows; kill switch `AMC_DISABLE_WOKEN_NOOP_SENTINEL=1`. | [woken-noop-sentinel.md](woken-noop-sentinel.md) |
| Workflow Coach (RETIRED 2026-05-14) | Subsumed by Weekly Summary. The 6 privacy-preserving detectors live on as inputs to Weekly Summary's Haiku prompt; the standalone Suggestions panel + weekly inbox alert + Settings → Experimental → Workflow Coach are gone. Settings migrate once on first launch (`workflowCoachEnabled` → `weeklySummaryEnabled`, cap value copied) | [workflow-coach.md](workflow-coach.md) |
| Workflows (n8n/Zapier-style automation canvas, in development) | In-development visual automation builder (gated via the `workflows` unreleased-feature, `workflowsEnabled` / Settings → Lab toggle), surfaced as an Omniscio built-in virtual project labeled "Workflows" docking in the main panel beside the projects sidebar (`__workflow__`, mirroring Flowcharts). A workflow is a trigger plus a DAG of steps — deterministic actions, branching if/else, and AI steps — that Omniscio runs automatically once you approve it from the inbox (nothing executes silently); data flows between steps via `{{ NodeName.path }}` template references. Like Flowcharts, the panel has a Workflows\|Sessions tab strip — the **Sessions** tab hosts AI build sessions in the same `__workflow__` project (spawnable + resolver-mapped); a **Build with AI** entry turns a plain-English description into a whole graph via a hidden CLI-driven primer, then stops for you to review + request approval. The underlying trigger/DAG-executor engine is documented separately: `.claude/memory/contracts/workflow-engine-contract.md`. | [workflows.md](workflows.md) |
| Workspace icon color (Team Chat workspace tile customization) | Right-click (or long-press on mobile) a self-serve Team Chat workspace tile to pick a gradient color from an 8-color palette (green, blue, red, purple, orange, pink, slate, teal); stored locally per device (localStorage). The active tile always shows the accent fill; custom colors appear on inactive tiles. "Remove color" resets to the default ring outline. Firestore has an `iconColor` field but server persistence is a follow-on. | [workspace-icon-color.md](workspace-icon-color.md) |
| Worktree Cleanup Skill (reap landed worktrees, safely and reversibly) | A Claude Code skill (`/worktree-cleanup`) that reaps the git worktrees whose work has already landed and keeps the rest. **Pure git, GitHub-OPTIONAL** — it judges "landed" by CONTENT (ancestor, then patch-id via `git cherry`, then an interactive-only squash-trap check), so it catches squash / rebase / replay merges a plain `merge-base --is-ancestor` misses; GitHub PR status is only a fourth, optional signal and is skipped with no error when `gh`/the remote is absent. Classes are Landed / Keep-viable / Ambiguous. Never loses work: SHA-logged branch deletes plus a rescue patch of any uncommitted changes BEFORE removal, so `--force` is conditional, never unconditional. Runs interactively (present a plan, wait) or unattended (`--auto` — provably-landed only, no confirmation), the mode the Dev Pipeline's daily maintenance uses. Also offers archive, bare-branch, and opt-in stale-guard passes. Complementary to the in-app worktree cleanup dashboard (which drives the scheduled PowerShell scripts). | [worktree-cleanup-skill.md](worktree-cleanup-skill.md) |
| Zap coach (a nudge when you type something you could one-tap) | Local, no-AI background check that notices when you hand-type a phrase you could have sent in one tap (your Zap / a saved quick reply / the "Please continue" button) and drops ONE gentle inbox card naming the shortcut — the exact INVERSE of the repeated-phrase nudge. OFF by default (`zapCoachEnabled`, also gated by Tips & Guidance); each phrase tipped once (a `zap_coach_detections.nudged_at` ledger); re-validates the target before showing; ~5 hand-types / 30 days. | [zap-coach.md](zap-coach.md) |
| Zapier integration (8,000+ app connections via MCP) | Injects the user's Zapier remote MCP server into Claude sessions so agents can trigger Zaps, read app data, and manage workflows across 8,000+ services — URL-based auth, feature-flagged, no local server needed | [zapier-integration.md](zapier-integration.md) |
| Zoom API (meetings + cloud-recording metadata, in development) | In-development integration with the real Zoom Cloud API (id `zoom-api`). Connect via Zoom OAuth (PKCE + a Basic-auth client-secret token exchange, per Zoom's app-type requirement; a refresh token renewed on every refresh, encrypted at rest); mirrors your meetings and cloud-recording *metadata* (file type/size/play/download links, not the video/audio, not a transcript) into a local cache on a background sync (5–120 min interval, default 15, plus a manual Sync Now). Surfaces as a "Zoom" sidebar row: a filterable (All/Upcoming/Past) paginated meeting list, a detail view with a Join-meeting link + recordings, and its own in-panel settings dialog (connection status, disconnect, sync interval) reached via the panel's gear icon rather than the main Settings menu. Read-only: never creates/edits/joins a meeting; no CLI route family. Foundation PR: no transcript content, no in-app recording playback, no scheduling. Gated via the `zoom-api` unreleased-feature (`zoomApiEnabled` / `AMC_SHOW_ZOOM_API=1`), revealed today in Settings → Lab. Known gap: the sidebar row is not yet hidden behind that toggle and Connect currently errors until a startup-wiring fix lands; see the zoom-api-contract for specifics. | [zoom-api.md](zoom-api.md) |
