Open the file before you attach
The command finds files through the app, so attaching to a file that is not open answers no HTML Clay site is serving this file; open it first. Double-click the file, then run the command.
Agent editing
Your file is open in a tab. You type "add everything I need for a beach trip" into a box on the page and press Send. A program in your own terminal wakes up, edits the file, and the new lines appear in front of you, already saved.
Trip list
saved into the file
[wire] attached as handler to http://127.0.0.1:52341 (/Users/you/Desktop/camping.htmlclay)
This demonstration uses the file you can download from the corner. The rest of the page shows how to attach a program to it.
The program runs on your computer, as you. Nothing gets copied out of a chat window or sent through a service. The page and the program share only the file on your disk.
Usually that program is an AI agent. It could instead be a formatter, a script you wrote, or five lines of shell. This page starts with a script that only adds a line, then shows how to connect an AI.
The commands below are written for a Mac and use nothing beyond what macOS already ships with. On Linux everything is identical except one line you get to skip, noted where it appears. Windows is covered at the bottom.
Save this as robot-notes.htmlclay, the same way you saved your first file: any plain text editor, plain text mode, keep the .htmlclay ending. Put it on your Desktop.
<!DOCTYPE html>
<html lang="en" autosave>
<head>
<meta charset="utf-8">
<title>Robot notes</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 30rem;
margin: 3rem auto;
padding: 0 1rem;
}
form { display: flex; gap: 0.5rem; }
input { flex: 1; font: inherit; padding: 0.4rem 0.6rem; }
button { font: inherit; padding: 0.4rem 0.9rem; }
</style>
</head>
<body>
<h1 editable>Robot notes</h1>
<form id="ask">
<input id="said" placeholder="Ask for a change" autocomplete="off">
<button>Send</button>
</form>
<ul id="log">
<li>Lines the robot adds will show up here.</li>
</ul>
<div id="notes" editable>
<p>This part is yours. Click and type.</p>
</div>
<script src="https://clayjs.com/v1/clay.js?plugins=sync,wire"></script>
<script>
clay.ready.then(function () {
var ask = document.getElementById("ask");
var box = document.getElementById("said");
// Built here, never typed into the file: everything you can see
// in the page is what gets saved.
var status = document.createElement("p");
status.setAttribute("clay", "no-save no-snapshot no-watch");
ask.after(status);
clay.wire.on(function (request) {
status.textContent = request.error
|| request.text
|| request.state;
});
ask.addEventListener("submit", function (event) {
event.preventDefault();
var words = box.value.trim();
if (!words) return;
box.value = "";
status.textContent = "sent";
clay.wire.send({ said: words }, { text: words });
});
});
</script>
</body>
</html>Three lines do the work.
wire gives the page a way to ask for something. sync makes the answer appear in the open tab without a reload.clay.wire.send sends the request. You hand it what the person typed. Everything else on the page is an ordinary form.clay attribute makes the line visible without saving it. Build parts like that in code. If you type one into the file by hand, the first save deletes it.Double-click the file so it is open in a tab, then press Send. A moment later the status reports that nothing is attached instead of hanging.
A robot here is any program. HTML Clay runs it once each time the page asks for something, and three plain rules connect the two.
HTMLCLAY_WIRE_FILE.Here is a whole working robot. Save it as robot.sh, next to the page file.
#!/bin/bash
echo "working on it"
NOW=$(date "+%H:%M:%S")
LINE="<li>The robot was here at $NOW.</li>"
perl -pi -e "s|</ul>|$LINE\n </ul>|" "$HTMLCLAY_WIRE_FILE"
echo "added a line at $NOW"It prints a progress line, adds one line to the list in the file stamped with the current time, and prints that it finished. It ignores what you typed. This first script lets you watch the connection work. The next script reads what you typed.
Open Terminal and paste these three lines.
alias htmlclay="/Applications/HTMLClay.app/Contents/MacOS/htmlclay"
cd ~/Desktop
htmlclay wire serve robot-notes.htmlclay -- bash robot.shThe first line teaches this terminal window the htmlclay command, because on a Mac the command lives inside the app rather than on your path. It lasts until you close the window, and putting the same line in your ~/.zshrc keeps it. On Linux, skip it: htmlclay is already a command. On Windows it is htmlclay.exe, in the folder you unzipped.
The last line sends requests from this file to this program. The terminal answers with one line and then waits.
[wire] attached as handler to http://127.0.0.1:52341 (/Users/you/Desktop/robot-notes.htmlclay)Your port number and your username will differ. Leave it running. The robot is attached to your file while this command runs.
If it says no HTML Clay site is serving this file; open it first, the file has not been opened since HTML Clay last started. Double-click it and run the command again.
Go back to the tab, type anything into the box, and press Send. Watch the page. Within a second or two, in this order:
Press Send a few more times. Each press adds one line.
The page saved itself before asking, so the robot read what you were looking at. The robot edited robot-notes.htmlclay itself, so its lines stay after you close and reopen the tab. HTML Clay put a complete copy of the file from before the edit in Backups, as it does before any other save, so you can go back.
The setup stays the same, with a different program.
This program reads what you typed.
Banana bread
Serves 4
Bake at 350°F for 55 minutes.
saved into the file
[wire] attached as handler to http://127.0.0.1:52341 (/Users/you/Desktop/banana-bread.htmlclay)
The oven temperature should not double, and the program left it alone. This demonstration is shortened for the page. An AI request takes fifteen seconds to a minute.
For this step, you need an AI you can run from the terminal. The example uses Claude Code. If typing claude --version prints a version number, you are ready. If it prints command not found, you can stop here. The robot above uses the same connection without an AI.
Save this as agent.sh, next to the others.
#!/bin/bash
REQUEST=$(cat)
claude --permission-mode acceptEdits -p "The file at
$HTMLCLAY_WIRE_FILE is an HTML page I have open on my screen.
This request came from inside the page: $REQUEST. Make the change
it asks for by editing that file directly. Leave everything else in
the file exactly as it is, and do not create any other files." 1>&2 &
agent=$!
while kill -0 "$agent" 2>/dev/null; do
echo "thinking"
sleep 5
done
wait "$agent"Stop the robot with Ctrl+C, because one file has one program attached at a time, and start this one instead.
htmlclay wire serve robot-notes.htmlclay -- bash agent.shTry one of these requests. "Add everything I need for a beach trip to the list." "Rewrite my notes so they are half as long." "Turn my notes into a haiku."
The status says thinking while the agent works. When it finishes, the page shows new list items or rewrites your notes in place. A small ask usually takes somewhere between fifteen seconds and a minute.
Two lines in that script need explaining.
1>&2 sends the agent's own chatter to your terminal rather than the page. The page only needs to know that something is happening.Where your file goes. An AI agent reads your file and sends what it reads to its own provider, under your own account with them. HTML Clay does not send the file anywhere. It starts the program you named.
The agent also runs with your permissions, in the folder you started it from. acceptEdits is what lets it write without stopping to ask about every change. If you would rather approve each one, use your agent's stricter setting instead.
The document stays in the file on disk.
The page does not connect directly to your program, and it sends no page content to it. It sends a short message through HTML Clay. Your program edits the file with whatever tools it already has, and HTML Clay updates the page as it does after any file change. HTML Clay calls this channel the wire. Four rules apply.
The program runs only while your command runs. Ctrl+C detaches it.
A page cannot pretend to be your program. Browsers announce themselves in ways they cannot suppress, so a web page can ask, but only a program you started yourself can answer.
A page can only reach its own file. It cannot send requests about some other file on your disk, even one open in the next tab.
Every edit is versioned. A program's change is backed up exactly like yours, even when no tab is open at the time.
Known limitations.
The command finds files through the app, so attaching to a file that is not open answers no HTML Clay site is serving this file; open it first. Double-click the file, then run the command.
A second attach to the same file is refused while the first is running. Stop the old one with Ctrl+C first.
Each line resets the timer, which is why both example scripts print while they work. A large request can time out if the agent prints nothing for two minutes. Small requests are fine.
The first time you edit the page yourself after a program has changed the file, the page reports that the file changed outside this tab. Nothing is lost, both versions are in Backups, and your save carries the program's edit forward.
Changes arrive in the open page by matching elements up, so a program should edit inside elements with a stable id or data-id, like log and notes in the example file. A change inside an anonymous element may not appear until the next reload.
The app and the wire both work, but the example robots are bash scripts. Write the same three rules in PowerShell or any language you like: read standard input, print progress, edit the file named by HTMLCLAY_WIRE_FILE, exit 0. The command is the same, with the path to your htmlclay.exe in place of the alias.