---
title: Instant new session on mobile (create-on-send)
---

# Instant new session on mobile

## What it is

### What it does

On a phone, tapping **New Session** now opens a real new-session screen **instantly** — "Start a new session" with the model / thinking / MCP pickers (the **same start-config controls you get on desktop**) and a composer. No spinner, no "Starting session…", nothing sent to your computer: it's pure interface — no session is created yet, no Claude process starts, nothing crosses the network. The real session is born the moment you **send your first message** — and sending is **fire-and-forget**: you're instantly returned to whatever you were doing while the session builds **invisibly in the background**. It doesn't matter if your computer takes a minute (or an hour) to finish creating it — you never wait and never watch; the session just appears in your list when it's ready.

Because tapping is just paint, it's effectively free: you can fire off as many new sessions as you like, one after another, and every one is instant. There's no hidden session being prepared behind the scenes to "keep up with" — so a fast burst of taps can never outrun it.

This replaces the older approach on mobile, where Omniscio quietly pre-created a real blank session for every tap and tried to keep one ready ahead of you. That worked when a prepared blank happened to be ready, but on a phone — where preparing one has to travel over the network — a quick second tap, a tap from the Inbox, or a tap in a non-Claude project could miss and fall back to a several-second spawn. Create-on-send removes that whole class of "sometimes slow." (Desktop is unchanged — **Ctrl+T** keeps its own pre-warm fast path; see [instant-new-session.md](instant-new-session.md).)

## Where to find it

On a phone: the **New Session** button. The switch that turns the behavior off is **Settings → Performance → Instant new session (mobile)**.

## How it behaves

### What you see

- **Every New Session is instant** — the new-session screen appears the moment you tap, however many you create in a row.
- **A clean new-session screen, not a blank box** — a **"New session"** heading with your setup below it: **Harness, Model, and Thinking** up front, and a quiet **"Advanced"** link that reveals the rest (Provider, MCP servers, run location…) only when there's actually something to show — so the screen stays uncluttered on a phone. It's the **exact same start-config control the desktop new-session screen uses** (no mobile-specific copy). Pick your setup before you send; whatever you pick is applied to the session that gets created.
- **You can set your defaults right here, like desktop** — pick a model, engine, or thinking level that isn't your usual one and a **"Make it my default"** option appears below the pickers (only this hub, all sessions on that engine, or everywhere) — so you can promote a new favorite to your default for new sessions without ever opening Settings. The option only appears when your pick actually differs from your current default, so it never nags.
- **A photo or file on its own is enough** — attach a photo, a screenshot or a document (a PDF, a Word file, a text file…) and Send lights up even with nothing typed, just like in a running session. The session starts with it as the first message (the chat shows just the attachment), and the agent is told to take a look at it — the same way desktop Quick Launch starts a session from an attachment alone.
- **Send is instant and invisible** — hitting Send returns you to exactly where you were (the session you were reading, or whatever screen you launched from) immediately and builds the session **entirely in the background**, however long that takes on your computer. You keep working on your phone; the new row appears in your list when it's ready. No spinner, no waiting, no watching.
- **It works everywhere on mobile** — the footer **New Session** button, the inbox-group **+**, and the breadcrumb **+**, and in **non-Claude** projects (Gemini, Codex, Cursor, …) too, which the old pre-warm skipped.
- **An un-sent screen isn't a session yet.** A screen you open but never send doesn't appear in your session list — by design, nothing exists until you send. Send your first message and it becomes a normal listed session with that message already delivered.
- **A page refresh doesn't lose it.** If the page reloads while you're writing — after an update, or when your phone closes the browser tab in the background — you land back on the same new-session screen with your text, photos, files and setup. Leaving the screen yourself still throws it away, and so does closing the tab or the app.
- **Your typed text is safe.** If starting the session ever fails (you're at the 200-per-project cap, the engine isn't set up, the connection drops), you get a quiet, non-blocking notice with a clear reason and a one-tap **Retry** — it keeps your typed message and tries again in the background. It never yanks you back into the composer, so a failure can't interrupt whatever you're doing on your phone.

### Turning it off

On by default. Turn it off in **Settings → Performance → "Instant new session (mobile)"** to go back to the old behavior (Omniscio prepares the session as soon as you tap). There's also a developer kill switch, `AMC_DISABLE_MOBILE_CREATE_ON_SEND=1`, that force-disables it regardless of the setting. Either gate off reverts mobile New Session to the pre-warm/"Starting session…" path; desktop is never affected by this flag.

### Why it's safe (the "no ghost session" rule)

An earlier attempt at instant sessions once caused data loss by showing a _fake_ session that became "real" later — a placeholder that leaked into the real session list and got confused with a genuine row. Create-on-send is built so that can't happen: the empty box is a **client-only draft** that never enters your real session list, never your history cache, and can never be archived or deleted. It's a separate thing entirely — there is no session object to confuse. The real session appears only when the backend creates it on send. A guard test ([mobile-draft-no-placeholder-in-sessions.test.ts](../../tests/unit/lint/mobile-draft-no-placeholder-in-sessions.test.ts)) permanently locks that the draft can never reach the real session list, so this is actually _safer_ than the pre-warm it replaces (whose pre-created blanks were the source of the old bug).

## For agents

### How it works

- **Tap** → a client-only draft composer ([MobileDraftComposer.tsx](../../src/renderer/src/features/sessions/MobileDraftComposer.tsx)) mounts against a placeholder id held in a dedicated store ([mobile-draft-session-store.ts](../../src/renderer/src/stores/mobile-draft-session-store.ts)). Zero IPC; the draft text lives only on the phone — the in-memory drafts map plus its local mirror (no database write).
- **The screen** → the empty-state body renders the SHARED [StartConfigPicker](../../src/renderer/src/features/sessions/StartConfigPicker.tsx) in **value mode** — the same start-config component the desktop new-session screen uses, driven by a plain value on the draft (no session, no IPC). Your picks stage on the draft and ride the launch. On mobile the picker is opted into its **`advancedDisclosure`** layout (a clean "New session" heading + a tidy stack): the PRIMARY pickers (Harness + Model/Thinking) stay visible and the rest (Provider / Route / run location / MCP servers) collapse behind an **"Advanced"** toggle that self-hides when the advanced group would render nothing; desktop keeps the flat row. See [mobile-in-session-provider-chooser-contract.md](../../.claude/memory/contracts/mobile-in-session-provider-chooser-contract.md). The shared **"Make it my default"** hints render here too (desktop parity), OUTSIDE the collapse: a pick that differs from your inherited default can be promoted straight to a persistent default via the existing settings write — the draft itself stays a pure client draft until send.
- **Send** → **fire-and-forget** (orchestrated in [mobile-draft-send.ts](../../src/renderer/src/features/dashboard/mobile-draft-send.ts)): it **synchronously** returns you to EXACTLY where you were — the session you were reading, or whatever screen you launched from — by restoring the view captured the instant the composer opened (`restoreComposeView`, backed by the nav store's `composeReturn` snapshot of your selection + screen; NOT a blunt `goBack`, which used to strand you on the "No session selected" screen when you'd launched from inside a session), and dismisses the composer (`consumeDraft` clears the draft before the launch, so the tap feels instant, a second Send is blocked, and nothing lingers), then fires the atomic launch-with-first-message fully **detached** (`launchSession(projectId, …, initialPrompt = your text, background: true)` — one backend op that creates the session **and** delivers the first message, with your full staged config stamped at creation). Photos and documents both ride the launch's first-message attachments (`images` / `documents`, split by the same `splitAttachmentsForSubmit` desktop Quick Launch uses). An attachment-only first message sends desktop Quick Launch's attachment-only prompt (`quickLaunch.defaultAttachmentPrompt`) as `initialPrompt` with `displayText: ''`, so the engine gets an instruction while the chat bubble shows only the files; `sendMobileDraft` is the one place that decides whether there is anything to send. The desktop create+spawn runs for as long as it needs; the new row appears via the `SESSION_LAUNCHED` push once it's built, and never yanks you in. A submit latch (kept through the detached launch) prevents a double-tap from creating two sessions. If the launch fails, you get a quiet **Retry** toast that re-fires the same background send (your message rides the retry, so it's preserved) — the composer is **never** navigated back into view.
- **Reload** → the draft store mirrors the draft (picks + photos + documents) to sessionStorage and the composer mirrors its text to localStorage, so a reload or an OS tab reap brings it back. The Dashboard's nav-away discard leaves a rehydrated draft alone (`awaitingResume`) until the mobile cold-start restore ([useDashboardStartupRestore.ts](../../src/renderer/src/features/dashboard/useDashboardStartupRestore.ts)) resumes it into the compose view ahead of the last session, or drops it (its project is gone, create-on-send or the mobile reopen is off, the user tapped something while the app loaded, or the layout is not mobile). The composer seeds its photos from the draft and its text from the local mirror as it mounts. Invariant `a-reload-resumes-the-draft` in [keep-alive-pool-active-project-blank-mobile-contract.md](../../.claude/memory/contracts/keep-alive-pool-active-project-blank-mobile-contract.md).
- When create-on-send is on, the mobile pre-warm stack (eager blank mint + warm host) goes inert — nothing is listed until you send. Full mechanism + invariants: [keep-alive-pool-contract.md](../../.claude/memory/contracts/keep-alive-pool-contract.md) ("Mobile surface — CREATE-ON-SEND supersedes the whole pre-warm stack").

## Related

### Related

- [start-a-new-session.md](start-a-new-session.md) — the full new-session flow (projects, launch targets, picking a tool/model).
- [instant-new-session.md](instant-new-session.md) — the desktop Ctrl+T pre-warm fast path (still in use on desktop).
- [keep-alive-pool-contract.md](../../.claude/memory/contracts/keep-alive-pool-contract.md) — the behavior contract + the load-bearing "no placeholder in the session list" invariant.

