Agent editing

Let a program edit your file

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.

camping.htmlclay Download

Trip list

  • Tent
  • Sleeping bag
  • Headlamp
  • Firewood
  • Rain jacket
  • Coffee and the little pot
  • Water filter

Terminal
[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.

Before you start

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.

1 A page with an ask box

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.

robot-notes.htmlclay
<!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.

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.

2 The robot

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.

  1. The request arrives on the program's standard input, and the file's location arrives in an environment variable called HTMLCLAY_WIRE_FILE.
  2. Every line the program prints shows up on the page as progress.
  3. When the program exits cleanly, the page is told the work is done. Any other exit code and the page shows an error.

Here is a whole working robot. Save it as robot.sh, next to the page file.

robot.sh
#!/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.

3 Connect them

Open Terminal and paste these three lines.

Terminal
alias htmlclay="/Applications/HTMLClay.app/Contents/MacOS/htmlclay"
cd ~/Desktop
htmlclay wire serve robot-notes.htmlclay -- bash robot.sh

The 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.

Terminal
[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.

4 Press Send

Go back to the tab, type anything into the box, and press Send. Watch the page. Within a second or two, in this order:

  1. The status under the box reads working on it. That is your robot's first line, arriving on the page as it runs.
  2. A new line appears in the list: The robot was here at 14:03:52. The robot edited the file on your disk, and the page picked the change up and showed it to you, with no reload.
  3. The status settles on done.

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.

Now make it think

The setup stays the same, with a different program.

This program reads what you typed.

banana-bread.htmlclay Download

Banana bread

Serves 4

  • 3 ripe bananas
  • 1 stick butter, melted
  • ¾ cup sugar
  • 2 eggs
  • 1½ cups flour
  • 1 tsp baking soda

Bake at 350°F for 55 minutes.

Terminal
[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.

agent.sh
#!/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.

Terminal
htmlclay wire serve robot-notes.htmlclay -- bash agent.sh

Try 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.

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.

What just happened

your page HTML Clay your program robot-notes.htmlclay, the file on disk asks runs it edits it and the page updates

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.

The rough edges

Known limitations.

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.

One program per file

A second attach to the same file is refused while the first is running. Stop the old one with Ctrl+C first.

A program gets two minutes without output

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.

Your next save after a robot edit warns you

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.

Give the parts a program rewrites an id

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.

Windows

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.

Where next

Try it on a file of your own.

The app is free to download.

Download HTML Clay