Simon Willison’s Weblog

Subscribe

Video: Building a tool to copy-paste share terminal sessions using Claude Code for web

23rd October 2025

This afternoon I was manually converting a terminal session into a shared HTML file for the umpteenth time when I decided to reduce the friction by building a custom tool for it—and on the spur of the moment I fired up Descript to record the process. The result is this new 11 minute YouTube video showing my workflow for vibe-coding simple tools from start to finish.

The initial problem

The problem I wanted to solve involves sharing my Claude Code CLI sessions—and the more general problem of sharing interesting things that happen in my terminal.

A while back I discovered (using my vibe-coded clipboard inspector) that copying and pasting from the macOS terminal populates a rich text clipboard format which preserves the colors and general formatting of the terminal output.

The problem is that format looks like this:

{\rtf1\ansi\ansicpg1252\cocoartf2859
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 Monaco;}
{\colortbl;\red255\green255\blue255;\red242\green242\blue242;\red0\green0\blue0;\red204\green98\blue70;
\red0\green0\blue0;\red97\green97\blue97;\red102\green102\blue102;\red255\

This struck me as the kind of thing an LLM might be able to write code to parse, so I had ChatGPT take a crack at it and then later rewrote it from scratch with Claude Sonnet 4.5. The result was this rtf-to-html tool which lets you paste in rich formatted text and gives you reasonably solid HTML that you can share elsewhere.

To share that HTML I’ve started habitually pasting it into a GitHub Gist and then taking advantage of gitpreview.github.io, a neat little unofficial tool that accepts ?GIST_ID and displays the gist content as a standalone HTML page... which means you can link to rendered HTML that’s stored in a gist.

So my process was:

  1. Copy terminal output
  2. Paste into rtf-to-html
  3. Copy resulting HTML
  4. Paste that int a new GitHub Gist
  5. Grab that Gist’s ID
  6. Share the link to gitpreview.github.io?GIST_ID

Not too much hassle, but frustratingly manual if you’re doing it several times a day.

The desired solution

Ideally I want a tool where I can do this:

  1. Copy terminal output
  2. Paste into a new tool
  3. Click a button and get a gistpreview link to share

I decided to get Claude Code for web to build the entire thing.

The prompt

Here’s the full prompt I used on claude.ai/code, pointed at my simonw/tools repo, to build the tool:

Build a new tool called terminal-to-html which lets the user copy RTF directly from their terminal and paste it into a paste area, it then produces the HTML version of that in a textarea with a copy button, below is a button that says "Save this to a Gist", and below that is a full preview. It will be very similar to the existing rtf-to-html.html tool but it doesn't show the raw RTF and it has that Save this to a Gist button

That button should do the same trick that openai-audio-output.html does, with the same use of localStorage and the same flow to get users signed in with a token if they are not already

So click the button, it asks the user to sign in if necessary, then it saves that HTML to a Gist in a file called index.html, gets back the Gist ID and shows the user the URL https://gistpreview.github.io/?6d778a8f9c4c2c005a189ff308c3bc47 - but with their gist ID in it

They can see the URL, they can click it (do not use target="_blank") and there is also a "Copy URL" button to copy it to their clipboard

Make the UI mobile friendly but also have it be courier green-text-on-black themed to reflect what it does

If the user pastes and the pasted data is available as HTML but not as RTF skip the RTF step and process the HTML directly

If the user pastes and it's only available as plain text then generate HTML that is just an open <pre> tag and their text and a closing </pre> tag

It’s quite a long prompt—it took me several minutes to type! But it covered the functionality I wanted in enough detail that I was pretty confident Claude would be able to build it.

I’m using one key technique in this prompt: I’m referencing existing tools in the same repo and telling Claude to imitate their functionality.

I first wrote about this trick last March in Running OCR against PDFs and images directly in your browser, where I described how a snippet of code that used PDF.js and another snippet that used Tesseract.js was enough for Claude 3 Opus to build me this working PDF OCR tool. That was actually the tool that kicked off my tools.simonwillison.net collection in the first place, which has since grown to 139 and counting.

Here I’m telling Claude that I want the RTF to HTML functionality of rtf-to-html.html combined with the Gist saving functionality of openai-audio-output.html.

That one has quite a bit going on. It uses the OpenAI audio API to generate audio output from a text prompt, which is returned by that API as base64-encoded data in JSON.

Then it offers the user a button to save that JSON to a Gist, which gives the snippet a URL.

Another tool I wrote, gpt-4o-audio-player.html, can then accept that Gist ID in the URL and will fetch the JSON data and make the audio playable in the browser. Here’s an example.

The trickiest part of this is API tokens. I’ve built tools in the past that require users to paste in a GitHub Personal Access Token (PAT) (which I then store in localStorage in their browser—I don’t want other people’s authentication credentials anywhere near my own servers). But that’s a bit fiddly.

Instead, I figured out the minimal Cloudflare worker necessary to implement the server-side portion of GitHub’s authentication flow. That code lives here and means that any of the HTML+JavaScript tools in my collection can implement a GitHub authentication flow if they need to save Gists.

But I don’t have to tell the model any of that! I can just say “do the same trick that openai-audio-output.html does” and Claude Code will work the rest out for itself.

The result

Here’s what the resulting app looks like after I’ve pasted in some terminal output from Claude Code CLI:

Terminal to HTML app. Green glowing text on black. Instructions: Paste terminal output below. Supports RTF, HTML or plain text. There's an HTML Code area with a Copy HTML button, Save this to a Gist and a bunch of HTML. Below is the result of save to a gist showing a URL and a Copy URL button. Below that a preview with the Claude Code heading in ASCII art.

It’s exactly what I asked for, and the green-on-black terminal aesthetic is spot on too.

Other notes from the video

There are a bunch of other things that I touch on in the video. Here’s a quick summary:

This is Video: Building a tool to copy-paste share terminal sessions using Claude Code for web by Simon Willison, posted on 23rd October 2025.

Part of series How I use LLMs and ChatGPT

  1. Vibe engineering - Oct. 7, 2025, 2:32 p.m.
  2. Claude can write complete Datasette plugins now - Oct. 8, 2025, 11:43 p.m.
  3. Getting DeepSeek-OCR working on an NVIDIA Spark via brute force using Claude Code - Oct. 20, 2025, 5:21 p.m.
  4. Video: Building a tool to copy-paste share terminal sessions using Claude Code for web - Oct. 23, 2025, 4:14 a.m.

Previous: Dane Stuckey (OpenAI CISO) on prompt injection risks for ChatGPT Atlas

Monthly briefing

Sponsor me for $10/month and get a curated email digest of the month's most important LLM developments.

Pay me to send you less!

Sponsor & subscribe