T08-L01 · Write code · Level 1 User · 10-minute read, plus 40 minutes of doing
Almost what you need
A former colleague left you a small page. In the lab it's a reagent finder: you type part of a name, it lists where the bottle lives. It works for "tris". It says Nothing found for "buffer", although two buffers are on the list, because it only matches the start of a name. You've learned to live with it, and you still walk to the wrong shelf twice a month.
In a company it's a product finder for the stockroom. A customer asks for "the blue mug", you type "mug", and it shows only the mug lid. The coffee mug and the travel mug are in the list. Their names just don't start with "mug".
The fix is one line. You don't need to write code to make it, but you do need to know which line it is, what the change did and how to take it back. Those three things are what this book teaches. You are at Level 1 User: you work on your own copy, so if the change goes wrong, only you are affected.
After this you can
- Describe one code change as a before-and-after you can see on screen.
- Find, with the assistant's help, the line that decides the behaviour you want to change.
- Give OpenCode Desktop a narrow edit request and read exactly which lines it changed.
- Check that the old behaviour survived, then undo the change and bring it back.
Before you start
- Books: T01-L01 for the four-quadrant method. T06-L01 helps but isn't required.
- OpenCode Desktop with a working model. The course's starting point for apps is the AI Lab portal at https://ai.32dots.de/ (opens in a new tab). OpenCode Desktop itself downloads from opencode.ai/download.
- A text editor (Notepad, TextEdit in plain-text mode, or any code editor) and a web browser.
- About 50 minutes: 10 to read, 40 to do.
Last verified 23 September 2026. In OpenCode Desktop, the Review tab shows the files a session changed. It needs Git to do that: in a folder without Git it offers Create Git repository. Typing
/undoin the message box reverts the changes from your last message, and/redobrings them back. OpenCode Desktop downloads free from opencode.ai/download for macOS, Windows and Linux, with free models included. Zen's models are hosted in the US, and during their free period some free models may use your prompts to improve the model.
The idea in one page
You don't need to read a whole program to change it safely. You need three places in it:
- Where input comes in: the line that reads what you typed.
- Where the decision is made: usually an
if, deciding what happens to each item. - Where output goes out: the line that writes to the screen.
Most small, useful changes happen at the decision. Ask the assistant to point to these three places before it changes anything. That costs a minute, and you'll know whether the change it proposes is in the right place.
A narrow request has four parts: the file, the behaviour now, the behaviour you want (with one example input and its expected result), and what must stay the same. "Improve the search" invites a rewrite. "Find 'buffer' anywhere in the name; keep the list, the order and the Nothing-found message" invites one line.
A diff shows what really changed. It lists removed lines (marked -, usually red) and added lines (marked +, usually green). The assistant's summary tells you what it meant to change. The diff tells you what it did. If the diff touches ten lines for a one-line request, stop and ask why.
Always keep a way back. Before any change, make a copy of the file. OpenCode's /undo is quicker, but the copy works even if you've closed the session. A change you can't undo is a gamble. A change you can undo is an experiment.
Worked example: one line, checked and reversible
The method is the one from T01-L01. First the reagent finder, then the product finder.
Lab: the reagent finder
Structure it. "When I search 'buffer', I want Tris buffer and HEPES buffer, not 'Nothing found'. A good result: search finds a word anywhere in the name, and everything else works as before."
Understand it. She tries some searches and writes down what happens: "tris" finds R01, "buffer" finds nothing, "hepes" finds R04. So the page matches only the start of a name. Then she asks OpenCode to explain the code without changing it, and it points to the one line with startsWith. She also notices something she hadn't thought of: an empty search box shows every item. She wants to keep that. Back to Structure it: "Change the matching rule only. Keep the list, its order, show-all-when-empty and the Nothing-found message."
Choose tools. OpenCode Desktop to explain and edit, a backup copy and Git to see and reverse the change, and the browser to check the result. Honestly, once she knows the line, she could change one word in a text editor herself. The assistant earns its place by finding and explaining the line, and on a bigger file that's most of the work.
Build it.
-
Create the starting file. Make a new folder
reagent-finderin Documents. In your text editor, create a file there namedindex.html(notindex.html.txt) and paste:<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Reagent finder</title> </head> <body> <h1>Reagent finder</h1> <label>Search by name: <input id="search"></label> <ul id="results"></ul> <p id="none" hidden>Nothing found.</p> <script> const items = [ { id: "R01", name: "Tris buffer 1 M, pH 8.0", place: "Shelf A2" }, { id: "R02", name: "PBS 10x", place: "Shelf A3" }, { id: "R03", name: "Ethanol 70 %", place: "Flammables cabinet" }, { id: "R04", name: "HEPES buffer 1 M", place: "Fridge 2" }, ]; function show() { const query = document.getElementById("search").value.trim().toLowerCase(); const results = document.getElementById("results"); results.innerHTML = ""; for (const item of items) { if (item.name.toLowerCase().startsWith(query)) { const line = document.createElement("li"); line.textContent = item.id + " · " + item.name + " · " + item.place; results.appendChild(line); } } document.getElementById("none").hidden = results.children.length > 0; } document.getElementById("search").addEventListener("input", show); show(); </script> </body> </html>Double-click it to open it in your browser. Try "tris", "buffer" and an empty box, and write down what you see.
-
Make your way back. In the file manager, copy
index.htmltoindex-before.htmlin the same folder. Leave that copy alone from now on. In OpenCode Desktop, use Open project to open thereagent-finderfolder and start a New session. Open the Review tab. If it reports that no Git version control was detected, click Create Git repository. That lets OpenCode track, review and undo changes in this folder. -
Ask for an explanation first.
Read index.html. Don't change anything yet. Explain in plain English, pointing to the exact lines: 1. where the page reads what I type, 2. which line decides whether an item is shown, 3. where it writes the result. Then tell me why searching "buffer" finds nothing.Compare the answer with the file. The three places are the
const queryline, theifline and theline.textContentline.startsWithmeans "the name begins with what I typed". -
Ask for the narrow change.
Change index.html so the search finds the text anywhere in the name, not only at the start. "buffer" must find R01 and R04. Change only the line that decides whether an item is shown. Keep the item list, the order, the "Nothing found." message and the show-everything-when-empty behaviour exactly as they are. Don't touch index-before.html. Show me the changed line.If OpenCode asks for permission to edit the file, choose Allow once.
-
Read the diff. In the Review tab, open
index.html. You should see exactly one removed and one added line:- if (item.name.toLowerCase().startsWith(query)) { + if (item.name.toLowerCase().includes(query)) {includesmeans "the name contains what I typed, anywhere". If more lines changed, ask: "Why did you change these other lines? Revert everything except the matching rule." If the Review tab shows nothing, ask OpenCode to show the changed lines as a diff. -
Check before and after. Reload the page in your browser and fill in the last column:
You type Before After trisR01 R01 bufferNothing found R01, R04 BUFFERNothing found R01, R04 (empty box) all four, R01 to R04 all four, R01 to R04 R01Nothing found Nothing found The last row matters: the page searches names, not IDs, and the change mustn't quietly alter that.
-
Undo, then redo. Type
/undoin the OpenCode message box and reload the page: "buffer" should find nothing again. Type/redo, reload, and "buffer" finds both buffers. If the undo ever fails, the backup still works: copy the contents ofindex-before.htmloverindex.html.
What it taught her: reading three lines was enough to judge the change, and the empty-box row caught the behaviour she'd almost forgotten to protect. Next trip round the quadrants: searching the shelf as well as the name. That's another one-line change, with its own before-and-after table.
Company: the product finder
Structure it. "When a customer asks for 'the blue mug', typing 'mug' should show every mug. A good result: search anywhere in the name; everything else unchanged."
Understand it. He tries the page: "mug" shows only P02, "Mug lid, blue". He asks OpenCode for the same explanation and gets the same answer, because it's the same kind of page with a different list. He also learns that his colleague's page shows the stockroom aisle, which he'd never noticed was coming from the same list.
Choose tools. The same as the lab: OpenCode Desktop, a backup copy, Git in the Review tab, the browser.
Build it. He uses the same file with the title changed to Product finder and these four items instead of the reagents:
{ id: "P01", name: "Blue coffee mug 300 ml", place: "Aisle 3" },
{ id: "P02", name: "Mug lid, blue", place: "Aisle 3" },
{ id: "P03", name: "Travel mug 450 ml", place: "Aisle 4" },
{ id: "P04", name: "Tea towel, cotton", place: "Aisle 7" },
His table: "mug" goes from P02 alone to P01, P02 and P03, while "MUG" gives the same three and an empty box still shows all four. "P01" still finds nothing, because the page searches names only. He undoes and redoes once, so he knows he can. What it taught him: customers remember colours, not product names. His next change is to search "blue" across names, but first he'll ask whoever maintains the original page. Changing a tool other people rely on is a Level 2 job (T08-L02).
What goes wrong
Asking for "better". Symptom: "Improve the search" comes back as a rewritten page with new features and a changed layout. Fix: name the file, the example input, the expected result and what must stay the same. One behaviour per request.
Trusting the summary instead of the diff. Symptom: the assistant says "I changed the matching line", but the diff also changes the item list or the message. Fix: read the diff every time. Ask why each extra line changed, and have it revert anything you didn't ask for.
Checking only the new behaviour. Symptom: "buffer" works now, but the empty box shows nothing, and you notice a week later. Fix: write the before-and-after table before the change, including one case that should not change.
No way back. Symptom: the change broke something, the session is closed, and you can't remember the original line. Fix: copy the file before every change. Create the Git repository in the Review tab before the first edit, not after.
Checking the old page. Symptom: the change "didn't work", but the browser is still showing the page as it was before the edit. Fix: reload the page after every change, and check that the browser has the same file open that OpenCode edited.
Pasting real data into the chat. Symptom: you paste the institute's full reagent list or a customer list into OpenCode "for context". Fix: the chat goes to the model provider. The assistant needs the code, not your real records. Use four made-up rows (T12-L01).
Do it yourself (40 minutes)
Use a small program or page you already have that almost does what you want. If you have none, use the reagent or product finder and change something else: search the place as well as the name.
- Structure it (5 min). Write one sentence: "When I ___, I want ___ instead of ___."
- Understand it (10 min). Try the program with three or four inputs and note the results. Make a backup copy. Ask OpenCode to explain, without changing anything, where input comes in, where the decision is made and where output goes out. Rewrite your sentence if you learned something.
- Choose tools (5 min). Confirm the change fits in a few lines. Write your before-and-after table with five inputs, including one whose result must not change.
- Build it (20 min). Ask for the narrow change, read the diff, fill in the table, then undo and redo once.
Exit check
Delivered artifact: your before-and-after table of five inputs for the changed program, plus three lines: the changed line (before and after), why it causes the new behaviour, and how you undid it.
It passes when all five results match what you expected, including the one that must not change, and the undo brought the old behaviour back when you tried it.
Rule to remember
Know which line changed and how to change it back.
Further reading and tools
Next books
- T06-L01 · Build a small app you will use: building a new one-file tool from a description.
- T08-L02 · Code without being a developer: scripts for your own data, with the same read-check-undo habits.
- T08-L04 · OpenCode Desktop: from first launch to a useful project: the app in depth, including models and permissions.
- T12-L01 · Stop sensitive data before it reaches the agent: what may go into a chat with a coding assistant.
Tools
- OpenCode: Taught. The Desktop app is the approved interface for this course.
- Git: Taught, one button deep. OpenCode uses it to show and undo changes.
- Claude Code, Cursor: Catalogued. Other coding assistants with the same explain-edit-diff workflow.