5. Sessions
A session is one continuous conversation context.
5.1 Persistence
AVL Code appends every message to disk; power loss, shutdown and restart never lose data. Each message has a timestamp and an author tag. Tool calls, plan edits and approval results are recorded as their own cards — the whole session works as a complete engineering audit trail.
5.2 Session operations
- New: session tab bar → New, or
⌘N/Ctrl+N. One workspace keeps at most one empty draft session: hitting+,⌘Nor/newreuses that one draft, and it doesn't appear in the sidebar until you've sent the first message — no more piles of "New session 1 / 2 / 3 …" ghost drafts. - Switch: click a tab, or
/s <short-id>on WeChat, or search session titles in the header command palette (Cmd+K). - Rename: right-click → Rename.
- Smart naming: sessions you haven't manually renamed get an LLM-suggested short title after the first AI reply (default on, toggle in Settings → Context); manually-renamed sessions are permanently exempt from auto-rename. The Rename dialog has a "Smart Name" button that asks the LLM to propose a new title any time.
- Archive: right-click → Archive. Archived sessions leave the main list and can be restored from Session Archive.
- Export / Share: right-click → Share — Save screenshot, Save HTML or Copy as Markdown; "Export session (.zsession)" packs the whole session into a portable archive file. Exported HTML matches what's on screen: it follows the Compact density tier (grey-scale slim rows + same-kind calls grouped with counts, failures still counted), renders subagents as cards, and colours user-message bubbles by source.
- Duplicate as new session: branch a new session from this one; the original is unchanged.
Right-click summons the menus directly: session entries and the two title-bar ⋯ menus above them open on a plain right-click — no need to aim at the ⋯ button; a menu close to the bottom of the window is no longer clipped, and right-clicking no longer text-selects the entry.
5.2.1 User-message timestamp toggle
A timestamp label sits to the left of your own messages. Clicking cycles through three formats:
| Format | Example |
|---|---|
| Relative time | Just now, 3 min ago |
| In-session offset | +1m23s (since first message) |
| Absolute time | 14:32 |
Each session remembers its own preference.
5.3 Message anatomy
A conversation is a sequence of "message cards":
- User message
- Assistant reply (streamed
- Tool call (collapsible card containing parameter summary, elapsed time, result)
- Plan / todo update (structured, separately editable)
5.3.1 Code blocks: syntax highlighting + one-click copy
Fenced code blocks (```) in the conversation render as cards with a header:
- Syntax highlighting: powered by highlight.js (
lib/common), coloured by language; unknown languages fall back to plain-escaped text and still render correctly. - Language label: shown in the top-right of each code block (e.g.
python/go/tsx). - Copy button: top-right one-click copies the whole block to the clipboard — no manual selection; on success the button briefly reads "✓ Copied".
- Line-number grid preserved: cross-line syntax spans are split per source line and paired up, so the line-number column and code column stay aligned — highlighting never breaks the row grid.
5.3.2 Mermaid diagrams: fenced code rendered as a picture
Fenced code blocks tagged mermaid in the AI's replies are rendered as vector diagrams automatically (flowcharts, sequence diagrams, state diagrams, Gantt charts and so on) instead of staying as source nobody can read.
- Rendering is asynchronous: the block first appears as an ordinary code block and is upgraded to SVG in place once drawn, so a long reply never stalls on a diagram.
- On a syntax error the original code is kept and an error is shown — the block doesn't silently vanish.
- The rendered graphic is sanitised before it is inserted into the page.
- Diagram / source toggle: once the diagram is drawn, a "Diagram | Source" toggle appears on the right of the code block's title bar (next to "Copy"), so you can look back at the source at any time; diagrams with identical source switch together.
- Three themes: each click on the theme button in the title bar moves to the next theme, cycling "General" (default, follows the app's light / dark mode) → "B&W" → "Journal color". The journal styles use a white background with black lines and text, and the color tier uses a colorblind-friendly palette — good for screenshots in reports or for printing. The theme preference applies to every Mermaid diagram and is remembered on this machine; there is no such option in Settings — it is switched only from the diagram's title bar.
- These buttons are hidden automatically when exporting HTML.
5.3.3 Image input: hand the AI a screenshot
With a model marked as accepting image input, you can send images along with your message (UI screenshots, error dialogs, photos of a diagram) and let the AI actually look at them.
Three ways to add one:
| Way | How |
|---|---|
| Paste | {{kbd:Cmd+V}} / {{kbd:Ctrl+V}} straight into the input box |
| Drag and drop | Drop image files onto the input box (a "Release to add images" hint appears while dragging) |
| "+" menu | "Add images to current message" — its own group, labelled "Sent with this message only" — opens a file picker |
Limits and processing:
- PNG / JPEG / GIF / WebP are supported; anything else is refused with a clear message.
- At most 6 images per message; each one ≤ 1536 KB after processing and ≤ 3 MB in total — beyond that you're asked to shrink them or send fewer.
- Oversized images are scaled proportionally to a 1568 px long edge; small PNGs (≤ 400 KB) are kept as-is to preserve the crispness of text in screenshots, the rest are converted to JPEG.
- Images can't be attached while a turn is running — wait for it to finish.
- If the current model isn't marked as accepting image input you're prompted to switch models, or to tick "Accepts image input" for that model under Settings → Models → Providers.
After you send:
- Images appear as thumbnails in your message bubble; click to "View original" at full size.
- Images go out only with the turn that sent them: later turns don't ship the same picture again and again, which is both cheaper and more accurate. The rule is that an image retires once that turn has been answered normally and you have provided new input, so continuation / auto-advance turns never lose the image by mistake.
- Switching to a model without image support degrades the historical images gracefully rather than breaking the request.
Models known to accept image input: the built-in model table flags qwen-3.8-27b (verified) and the Landi N2.7 series; for providers you add yourself, tick "Accepts image input" on the model entry.
5.4 Message-stream control
- While the assistant is running, the send button on the right becomes Stop — pressing it cancels the main assistant and all subtasks together, and also cancels this session's session routines (see §15.6.1).
- If you want to add something mid-run, just press Enter to queue it (live guidance) — by default it is merged in after the current turn ends naturally instead of interrupting; to make it take effect sooner, click "Prioritize" or "Handle now" on the "Pending" strip (see §5.4.2).
- Each tool-call card can be expanded / collapsed / copied independently.
- Press ↑ / ↓ in the input box to recall input history; executed
/slash commands are now included too (normalized to/<name> <args>), ready to re-run or edit. - Every message has a "message handle" on its left that opens that message's action menu: the menu header shows the message's timestamp (absolute and relative, read-only), and below it are copy, copy selection, edit, retry, write to memory palace, append to result draft and so on.
- You can still edit a message after stopping: whatever was streamed before you pressed Stop is persisted, so it doesn't turn into a ghost record that reports "message not found" — edit and retry keep working.
- When the service is busy, the message stream shows a countdown to automatic continuation, with controls to switch models or stop waiting; subagent panels and off-screen sessions also retain the waiting notice. Main turns, subagents and parallel tasks share the wait; four or more branches start at staggered times, and the parallel block shows how many await recovery.
- Retry is disabled in the message menu while the turn is running or waiting for automatic retry. After repeated failures, the countdown to restart the turn shows the attempt number out of three; restarting collapses the old error into a previous-failure-retried notice. Waiting notices are not forwarded as companion replies or saved in zTUI conversation history.
5.4.1 Restate intent: agree on the goal before starting
To avoid going off the rails from the first move, AVL Code runs a lightweight confirmation on the session's first message: the AI first restates the goal as it understands it and outlines how it plans to proceed (in multi-agent mode it also gives a phased plan — split into subtasks → dispatch subagents in parallel → hand back to you for review), and waits for your nod before acting. It's on by default and can be turned off under Settings → Agent → Reflection (toggle: Restate intent).
- Confirmation happens inline in the message stream, not a popup, styled like a normal message.
- It auto-starts after 60 s by default; hovering over the confirmation pauses the countdown so you have time to read.
- The confirmation offers three choices:
- Confirm & start — accept the AI's restatement and go;
- Edit — tweak the restatement before sending (both goal and plan are editable);
- Keep my original — don't adopt the restatement, continue with your original message instead.
- Clicking "Cancel" puts your original message back into the input box, intact — nothing is lost, so you can refine and resend.
- Only asks when it should: it triggers solely on the first message you typed yourself (not auto/program-triggered), and only when that opening message is short (≤30 chars) or simple; a long, clear opening (multi-line, a numbered list, or more than 3 separators like 、 or commas) is taken at face value and runs straight away.
- To manually re-confirm intent on a message, pick "Analyze intent & restart from here" from that message's actions menu (it ignores the conditions above, forces one restatement, and restarts from there); it first hides the messages after the restart point and places the confirmation below them so you can see the scope.
- Choice stats: how often you Confirm / Edit / Keep original / Auto-start (timeout) / Cancel, and the character counts, are recorded and shown as a table under Settings → Agent → Reflection, so you can review whether this confirmation step is actually helping.
5.4.2 Live guidance: chiming in while it runs
While the Agent is running, typing in the input box and pressing {{kbd:Enter}} doesn't interrupt the current turn; the message goes into the "Pending" queue instead (the input placeholder reads "Live guidance: Enter to queue; injected in batch when the current turn ends…") and shows up as a "Pending N" strip (forms described in §5.5.1).
- When it queues: only the current session counts — it queues only while this session's Agent is running (or a companion-messaging outbound delivery is in progress), or while this session is sending or generating; when the session is idle the message is sent directly, and another session compacting or sending doesn't affect the current one. Re-sending exactly what is already being sent is ignored, with a notice.
- Default timing: when the turn ends naturally, the queue is merged in enqueue order into one message (separated by blank lines) and sent; it goes out as soon as the session becomes idle, not a whole turn late. The queue is kept while you switch to another session and is sent as usual when you switch back.
- Per-item buttons:
| Button | Effect |
|---|---|
| Prioritize | Delivered to the Agent as soon as the current step finishes (after this batch of tool results arrives, before the next model request) rather than waiting for the whole turn; if the model is writing its final reply, this item is handled right after the reply is written |
| Handle now | Cuts off what the model is currently outputting and handles this item immediately: body text and reasoning already output are kept, unfinished tool calls are not executed; tools already executing are not interrupted — it is delivered once that batch of tools finishes |
| Remove (×) | Discards this item; shown only for items not yet delivered |
- "Prioritize" can be upgraded to "Handle now". Once delivered, the item shows "Prioritized · handled when the current step finishes" or "Handling now" and leaves the queue automatically once it arrives; a delivered item can't be withdrawn.
- "Clear all" discards only items not yet delivered.
- Nothing is lost: if it can't be inserted right now (e.g. the session isn't actually running), the item stays in the queue and goes out as a new turn when this turn ends; if the turn never got started (manual stop, send cancelled or failed, regenerate failed, etc.), queued guidance is returned to the input box (ahead of any existing draft), with the notice "Returned N guidance message(s) to the input box".
- Images can't be attached while a turn is running, and messages with images don't queue — wait for the turn to finish before sending.
5.4.3 Marked messages: gather the ones that matter
Right-click a message (or click its message handle) and pick "Mark message"; pick it again ("Remove mark") to unmark. A marked message shows a bookmark badge on its left (the badge is only an indicator — to unmark, use the menu or the strip below).
When the session has marks, a "Marked N" strip appears (forms described in §5.5.1), listing every mark in the order the messages appear in the session:
| Action | Description |
|---|---|
| Click a row | Jumps to that message; if it sits earlier in the session and isn't loaded yet it is loaded first, and if it is inside a collapsed tool group the group is expanded |
| Copy as Markdown / Save HTML | Exports only marked messages that have body text — messages with only tool calls, reasoning or attached images are skipped; when none of the marked messages has body text both buttons are greyed out, with the reason on hover |
| Export .zsession | Opens the same confirmation dialog as session export (including the redaction option) and packs the marked messages into a session file; a reply with tool calls is exported together with its tool results (marking a tool result also brings along the reply it belongs to), and the session name gets the suffix "(标记摘录)" ("marked excerpt") |
| Bookmark button at the row end | Removes the mark from that message |
| Clear marks | Removes every mark in this session — messages are not deleted |
- Marks are saved with the session; duplicating a session and starting a new session from a message both keep the marks (marks after the branch point are not carried over). When a message is deleted, its mark disappears from the list automatically.
- Messages that haven't finished saving (e.g. still streaming) can't be marked yet.
5.5 The "generating" card
- Collapsed thinking: scrolls smoothly left to show new text, fading long content on the left; when finished, shows an opening summary. Compact mode shows only Thinking.
- Token count interpolates smoothly: the streaming token counter no longer jumps; it interpolates to the target value (~0.4 s) with a brief brand-blue colour change and a tiny upward bump. With "reduce motion" on, it just jumps.
- Elapsed time tiered: under 60 s shows
5s/12s; over a minute upgrades to1m 30s; over an hour,2h 15m 30s. Short tasks see no visual change; only long tasks switch units. The generation footer also identifies seconds spent waiting; the statistics panel’s rate-limit/retry row shows retry count, rate-limit count and waiting seconds for the latest call. - Context-usage ring changes colour by tier: the ring showing the current context-window usage changes colour by tier — yellow at 75%, red at 90% — to flag more prominently that you're approaching the context limit (time to continue / compact).
5.5.0 Message density (Normal / Compact)
Settings → General → Message density offers two tiers (config field message_density, default detailed); the "Density" slider in the header quick menu's "Display" group switches it in one click, without opening Settings:
| Tier | Behaviour |
|---|---|
Normal (detailed, default) |
Full cards + parameter preview / argsSummary; zero regression |
Compact (compact) |
No cards, grey-scale slim rows, minimal chrome; only process rendering is compacted — your prompts and the AI's reply text show in full as usual; row height is no longer compressed |
In Compact mode, process content auto-groups with counts:
- Consecutive tool-call results merge into a single row with a count.
- Multiple thinking + tool-call blocks merge into a "Thinking N · Tools M" row (with a pop animation on count change).
- In-flight tool calls without results yet merge into "N tool-call attempts".
- Any failures in a summary row are tinted light red — visible without being harsh.
Density switching keeps scroll position stable, no jitter; the legacy "collapsed" tier auto-migrates to "compact".
5.6 Scroll and follow
- Auto-follow tracks the bottom during generation.
- As soon as you scroll up — the "Jump to bottom" button appears, meaning you're reading; auto-follow stops.
- Dragging the scrollbar up during generation no longer pins you down: while the AI is streaming, dragging the scrollbar up to re-read earlier content used to get yanked back to the bottom on the same frame (the "won't move" feeling); now an upward drag releases auto-follow synchronously so you can scroll up freely, and you return to the bottom to resume following the newest output.
- Jump to bottom or scroll there manually to resume following. Deliberate jumps and search results scroll smoothly; returning to a session restores its position directly. When the system’s reduced-motion setting is enabled, clicking “Jump to latest message” goes directly to the latest message.
- The frame-level race between the wheel event and the streaming chunk has been fixed; you won't be interrupted any more.
- List-wide jitter fixed: in some situations the message list would rapidly bounce up and down — root cause was a few messages having their heights re-measured repeatedly. Realized heights are now cached (including a height of 0); the list no longer ping-pongs, and scrolling is steadier.
- "Jump to bottom" lands in one click: previously you had to click several times before it actually stuck at the bottom. Now it continuously re-pins until the content height (
scrollHeight) settles — one click is enough, and first-open of long sessions no longer shows the "the button feels unresponsive" multi-click behaviour. - Rapid duplicate Send clicks no longer fire multiple times: a synchronous in-flight interception ensures rapid clicks send only one message.
5.6.2 Long-session lazy paging
Opening a very long session shows the most-recent segment first, then loads earlier messages page-by-page as you scroll up:
- Scroll to the top and keep scrolling → the previous page loads, with a centred progress indicator when multiple pages are needed. Loading preserves the position without animation.
- Under the hood: a line-offset index makes paging
O(range)instead ofO(scan-from-line-1), a frame is yielded between multi-page loads, and deduplication is built-in — long sessions open and scroll noticeably faster and feel more responsive. - The session-outline jump correctly locates messages that haven't been loaded into the window yet — it loads up to that point first, then scrolls to it.
- Display-fold of oversized single messages is off by default now — previously huge single messages were collapsed into a summary for performance; the new default keeps them fully expanded. Re-enable folding from settings if you want it back.
5.6.0 Session outline + one-click jump
To the left of the session title there's a new session-navigation button (a List icon). Clicking it opens a table-of-contents popover:
- Lists every user prompt in the session, taking the first non-empty line as the entry title; whitespace is collapsed; entries over 120 characters are truncated (with
…). - Click an entry → smooth-scroll to that message and close the popover.
- Current entry highlighted (plain greyscale, restrained professional style) — determined by the user message currently visible in the viewport, refreshed live as you scroll, so the last entry is also selectable correctly (no longer stuck on the first).
- Dismiss:
Esc/ click outside / window resize. - Virtualization-safe: locates by
data-message-id(placeholder messages also carry that attribute with the correct height), so long sessions jump accurately. - The button only appears when there are user prompts to jump to; empty sessions don't show it.
- Rendered via the browser Popover API (
popover=manual+ top layer) — doesn't rely on z-index, so it can't be obscured by dialogs / drawers / etc.
5.5.1 Session strips: the form follows the window width
The File changes / Memory / Todos / Plan / Goal / Subtasks / Interrupted / Pending (live guidance, see §5.4.2) / Marked (see §5.4.3) / Routines (session routines, see §15.6.1) / Result draft / Attached materials / Suggested tasks / Self-check gate strips pick their presentation automatically from the window width:
- Narrow window — a row above the input box: several strips sit side by side above the input box and auto-wrap when there isn't enough width (filling the line adjacent to the input box first, then stacking upward); the gaps tighten and labels on the non-bottom rows revert to full pill form — no clipping, no overlap. Opening one shows a popover that pops upward.
- Wide window — a vertical status stack at the top-right of the message area: when the window is wide enough these strips move to a vertical stack at the top-right of the message area and stop taking up space above the input box. Opening one shows a stacked drawer on the right: no scrim, no squeezing of the body text; it is anchored to the stack as a whole, so the drawer stays put when you switch between strips, and it opens leftwards or rightwards depending on the space available on either side. On very wide windows the drawer slot is permanently reserved, so opening and closing it never makes the body text jump sideways.
With density set to "Compact", the row form above the input box is always used. Switching form only changes position, never the width of the body text.
5.6.1 Session-level path attachments: let the AI temporarily access folders outside the workspace
The input box's "+" menu has two new entries:
| Entry | Permission |
|---|---|
| Attach directory (read-only) | AI may read / list / search; no writes |
| Attach directory (read-write) | Read-only plus write / delete / create |
Typical use: let the AI reference another project's code, write outputs to a designated directory, etc.
A confirmation appears first, clearly stating which permission you're granting. Once attached, an "Attached Paths" strip appears (above the input box on narrow windows, at the top-right of the message area on wide ones — see §5.5.1) showing the current session's attachments and letting you remove them at any time. Pressing {{kbd:Enter}} in the confirmation dialog no longer triggers a button by accident — you have to click.
Pick the scope: this session only, or the whole workspace: the confirmation dialog lets you choose how far this attachment reaches.
| Scope | Meaning |
|---|---|
| This session only (default) | Only the current session can reach the directory / file; other sessions can't see it |
| Project-workspace-wide | Other sessions in the same workspace can use it too, so you don't have to attach it once per session |
Remote workspaces: picking an attachment inside an SSH workspace opens a remote file picker (browsing the remote tree over SFTP); the selection is pushed to the remote sandbox immediately.
Subagents can read them too: a dispatched subtask inherits the parent session's attachment list as of its creation, so you don't have to attach anything again inside the subtask (previously subagents couldn't reach the parent's attached paths at all).
Scope and safety:
- With the scope set to "this session only", attachments are per-session; other sessions are unaffected.
- Persist with the session; still in effect after restart (re-applied automatically in the background — no need to re-attach).
- Only file I/O (read / write / search / list) is broadened; other safety policies stay in place.
- Search results under attached directories carry absolute paths, so the source is unambiguous.
- The session identity is injected into the call chain by the system, so the AI can't forge its identity to use another session's attached permissions.
Unified "attached materials" entry: session-attached directories / files and the workspace's samples / attachments are now merged into a single "attached materials" strip, with attach progress and status visible in real time. The two keep clear, distinct semantics: removing a session-attached item only unmounts it (the original file isn't deleted), while deleting a workspace sample / attachment goes through an inline double-confirm — so nothing is deleted by accident. The strip auto-refreshes when files change (no manual reload after the AI edits files), presents directories as a multi-level tree, and ignores macOS junk files (e.g.
.DS_Store,__MACOSX/). A local workspace file added to attached materials now shows as "Ready" (no longer the misleading "Upload / Uploaded" for local files) — "Upload" is reserved for genuinely-outbound cases (submitting feedback, upload scanning); the scope badge also uses a more legible indigo colour.
5.7 Clickable links and file paths in messages
URLs and file paths with common extensions in AI replies (including in inline-code backticks) are clickable:
- Workspace-internal file paths → once clicked you can "Preview" it, or "Show in folder" to locate and select it in your system file manager (Finder / Explorer).
- External URLs → open in your default browser.
- Paths inside inline-code backticks (e.g.
`src/main.go`) are also clickable; plain inline code is untouched. - Clickable code references (verifiable grounding): code locations cited in the AI's answer, and
file:linein tool results, are now clickable too — for a workspace file with a line number, "Preview" opens a source preview scrolled to that line, so you don't have to flip there yourself. This makes thefile:lineevidence fromcode.search/code.askvisible and checkable. - Click pops up a non-modal floating toolbar ("Preview", "Show in folder" and "Copy" for files; "Open" and "Copy" for external links); click elsewhere, scroll or
Escto dismiss. - The toolbar uses the browser Popover API and renders at the top layer; even clicking from inside the "About", "Release notes" or "Update" dialogs it isn't obscured.
- Path detection is precise: only strings with a known extension (e.g.
src/main.go,README.md) or a well-known filename (Dockerfile,Makefile,go.mod, etc.) count as clickable paths; plain directories or unknown-extension fragments (e.g.a/b,/etc/hosts) are no longer mis-flagged.http(s)links are always clickable. After rendering, the file must also be confirmed to actually exist and to fall inside the workspace or the attachment scope before it truly becomes clickable. - "filename:line" is clickable: forms like
main.go:42,a.ts:3:7orDockerfile:3jump straight to that line when clicked; what precedes the colon must be a recognised filename, so addresses such asexample.com:8080aren't mistaken for files. - If it can be previewed, it can be located: the toolbar's "Preview" and "Show in folder" use the same path resolution — relative paths written by the AI, files attached to the session, files in project-workspace-wide shared attachments, and files in recently used workspaces that aren't open all preview and locate correctly. When the attachment list loads later than the messages, or attachments are added / removed afterwards, paths in messages already on screen are re-evaluated for clickability.
- Remote workspaces: files in an SSH workspace don't offer "Show in folder" (the file isn't on this machine); paths attached in an SSH workspace aren't previewable and are never misread as a same-named local file, while files inside the workspace can still be previewed.
- When preview, Save As or locate fails, the notice includes the specific reason.
- AI replies only: links and paths in your own messages are no longer clickable, to avoid mistapping. Only the assistant's replies surface the inline toolbar.
- Safety: non-
http(s)protocols are blocked; file reveal has workspace-defence checks; it can't escape the workspace.
5.7.1 File preview drawer
Click a file link in the conversation and the inline toolbar has a Preview button — read the contents right there without switching to an editor.
- Far more than Markdown: common source code (Go / TypeScript / Python / Rust / Java / C·C++ / Ruby / PHP / Swift / Kotlin, …), config (YAML / TOML / JSON / INI / .env), front-end (HTML / CSS / Svelte / Vue / Astro), scripts (sh / bash / ps1 / bat), text and data (md / txt / csv / tsv / xml / sql / diff), images and common binaries (png / jpg / svg / pdf / zip, …), plus extension-less well-known filenames such as
Dockerfile,Makefile,go.modand.gitignore. - Source code gets syntax highlighting, using the same palette as code blocks in the conversation; very large files (over roughly 256 KB) aren't coloured, but line numbers and navigation still work. An icon matching the format is shown in front of the file path so you can tell the type at a glance.
- Binary files are shown as a hex dump (hex + character column, up to 64 KiB) instead of garbled text. Raw bytes of binary files on remote workspaces can't be fetched, and that is stated plainly rather than faked.
- What can be previewed: the file is looked up inside the workspace first, then matched against the directories / files attached to the current session — attached files preview too. Paths that can't be previewed simply don't get a Preview button, so you never click one that does nothing.
- The form is picked automatically from the window width: with enough room outside the content it stays docked as a right-hand side panel (the body text isn't narrowed); when there isn't enough room it falls back to a floating drawer (
min(820px, 94vw)wide, no scrim), in which case the body text shifts into the left-hand margin to get out of the way — again without being narrowed. - Find in file: search the contents of the file you're previewing right inside the drawer — matches are highlighted, the current position is shown as
index/total, Previous match / Next match step through them one by one, and Match case can be toggled on or off. When there are too many matches only the first few are marked, and you're told so. - Size: preview body is capped at 1 MiB (truncated with a marker beyond) — great for a quick look; for the full file use Save As.
- Save As button (in the drawer header) opens the system Save dialog and writes the source file out using a 64 MiB ceiling, preserving the entire file; cancel = no-op.
- Links inside Markdown documents: a Markdown document being previewed (
.md/.mdx/.markdown) is rendered as a document, and its relative links resolve against the directory that document lives in;#L10and#L10-L20in a link jump to the line(s), and?parametersand percent-encoding are handled correctly. - A lone file path inside a code block is previewable too when the file exists: existence is checked asynchronously on render and only then is the path upgraded to clickable, so you never click through to a missing file.
Pressing ↑ to walk back through input history shows a N/N position label at the top-left of the input box (newest = total, oldest = 1/N) so you don't lose track. Draft state, empty history and out-of-range don't show it.
Editing while in history → automatically becomes a new draft: editing a historical entry would previously look like "this history was edited"; this release makes the semantics explicit — edit means new draft; the original history is untouched. Pressing ↑ again still saves your current draft so you don't lose work.
5.9 Cross-device handoff
If you've bound a WeChat channel:
/s <short-id>on the phone resumes an in-progress desktop session.- The desktop can also take over a session that the phone started.
- Only one device "holds" a session at a time; the other side auto-syncs read-only.
See Chapter 19.
