VCode home

Formatted answers and coloured code

Agents: claude, codex, opencode · On: phone, desktop

Replies render as markdown: headings, lists, tables, quotes and fenced code. Code is coloured the way VS Code colours it, in every language VS Code's grammars cover, and so are shell commands in a tool card's header and the lines of a diff.

Why you would use it

A phone screen is small. A wall of unrendered markdown with ** and backticks in it costs more to read than the answer is worth, and a 40-line file printed by Read is unusable without a gutter and colour.

How to use it

Nothing to switch on. It applies to every reply, every tool output and every patch.

  1. Read the reply.

    A reply rendered as markdown: a heading, a three-column table, a numbered list, a fenced JS block with its language label and copy button, a blockquote, and a bare URL turned into a link

  2. Tap the copy icon in a code block's header bar to copy just that block.

  3. Tap a link to open it in a new tab. A link to a file, such as [format.js:9](src/format.js:9) or the inline code src/format.js:9, opens the file in the viewer instead, scrolled to the line it names.

An edit renders the same way, as a patch:

An EDIT card opened: line numbers down the left, a + and a − column, and the JavaScript coloured on green and red rows

What you see

Rendered from an answer: headings (four levels), bullet and numbered lists including nested ones, tables (a wide one scrolls sideways inside the card), blockquotes, horizontal rules, **bold**, *italic*, ~~strike~~, inline code, and links. A bare URL becomes a link, and so does a bare host:port (the shape a dev server prints), and a web address written without https://, such as paddle.com/retain, in prose or in backticks. A link inside bold, italic or strikethrough is still a link.

A markdown link whose target is a path rather than a web address is a file link. So is inline code that holds only a path: one with a / in it, or a file name such as README.md, .env or Dockerfile, with or without a line. npm test or parseInline stays plain code. A long press on a file link selects its text. The path is read from the thread's folder; an absolute path outside it opens from /, and a path starting ~/ opens from your home folder on the tab's workstation. A line given as :42, :42:7 or #L42 scrolls the viewer to that line.

A fenced code block gets a header bar showing the language (or text) and a copy button. A fence with no language is guessed: shell when the content is commands, otherwise from the content.

Tool output is decided in this order: an MCP envelope is unwrapped, real escape bytes claim the terminal renderer, then structure (a numbered Read listing keeps its line-number gutter, grep hits keep theirs, fenced blocks are split out), and only then language, taken from the title's extension when the body could plausibly be that file.

A diff renders as three columns: line number, +/− marker, and the content coloured as the language of the file being changed. Line numbers appear only when the patch carries an @@ header; claude reports edits as old/new strings, so its synthesized patches have none.

Options and settings

Option Default What it changes
fence language guessed the label on the block and the colours used

Every language VS Code's grammars cover has colours, over 240. A fence takes the language's name or one of its short names, such as ts, py, sh or rs. A name no grammar knows renders as one plain block.

A block shows plain first and takes its colours a moment later. The first block in a language waits for that language's colours to download; after that they are kept on the device. Offline, a language you have never seen shows plain. JavaScript, TypeScript, JSX, TSX, shell, Python, JSON, CSS, HTML, YAML, SQL, Markdown, INI, TOML, .env and diffs come with the app and colour offline from the start. While an answer streams, its growing code block is coloured again at most every 300 ms.

Limits and known gaps