Live
The live session: your first AI agent in the terminal
This is the full guide to the live session, on a single page. We go in five parts, in this order. Follow them top to bottom: each one uses what you set up in the one before.
| Part | What you do | What you understand |
|---|---|---|
| 1 | Nothing yet: it's the theory | What a model, an agent, and OpenCode are |
| 2 | You install OpenCode, connect it, and pick a model | What happens on your laptop and what in the cloud |
| 3 | You ask it to read your folder and explain it | Tools, context, and why you check |
| 4 | You ask for a change and review it before accepting | Plan, permission, and how to read a diff |
| 5 | You go over what not to ask it yet | Today's limits and three rules to take with you |
Part 1: What an AI agent is, what OpenCode is, and how it differs from a chat
Before installing anything, let's understand what you're about to install. This is the theory part of the workshop: no formulas and no jargon, but with the why behind each thing. If you hold on to the ideas on this page, everything you do afterward with your hands will make sense.
In this part you'll understand:
- What a language model (LLM) is and what it can and can't do.
- What a chat is and what an agent is.
- What an agent's "tools" are and how its work loop functions.
- What OpenCode is, which part runs on your laptop and which part runs in the cloud.
- Why an agent needs permission rules.
1. What a language model (LLM) is
A language model, or LLM (Large Language Model), is a program that does one single thing: it receives a text and predicts how it continues. Word by word, it calculates the most likely continuation.
Think of the autocomplete on your phone keyboard: you type "see you" and it suggests "tomorrow". An LLM is that same idea, but trained on an enormous amount of text, so the continuation it predicts can be an explanation, an email, a recipe, or a complete program.
+----------------------+
"Explain what ->| Language model |-> "A CSV is a text file
a CSV is" | (predicts how the | where each line is
| text continues) | a row..."
+----------------------+
text going in text coming outThree important things follow from this:
- It only knows two things: what it learned during training and what you give it at that moment. It doesn't see your computer, it doesn't see your files, it doesn't know what time it is. If it isn't in its training or in what you send it, it doesn't know it.
- It can be wrong with total confidence. Because it predicts text that sounds right, sometimes it produces something that sounds perfect and is false. It isn't lying on purpose: it simply has no way of knowing it got it wrong. That's why, throughout the workshop, you'll check what it tells you.
- It only produces text. On its own, a model can't open a file or run anything. Everything it "does" is writing.
The text you send the model in each request is called the context. Remember that word: it comes up again below.
2. What a chat is
An AI chat is a web page or an app that puts a text box in front of a model. You write, the chat sends your message to the model, the model predicts an answer, and the chat shows it to you.
The deal is this: the model answers with text, and you do something with that text. You copy the code, paste it into a file, run it, go back to the chat with the error. The model never touches your computer.
+-------+ 1. you write +-------+ 2. predicts +--------+
| You | ---------------> | Chat | --------------> | Model |
| | <--------------- | | <-------------- | |
+-------+ 3. you read +-------+ answer +--------+
|
| 4. YOU copy, paste, run, and come back with the error
v
+------------------+
| Your computer |
+------------------+Analogy: a chat is like calling an expert on the phone. They tell you what to do, but you're the one with your hands on the keyboard.
3. What an agent is
An agent uses the same kind of model, but adds two things: tools and a loop.
Agent = model + tools + loop
Analogy: if the chat is the expert on the phone, the agent is the expert sitting at your desk, with permission to open your folders and use your computer. They no longer dictate the steps: they do them, and you supervise.
What tools are
A tool is a specific action the agent program knows how to perform on your computer, and that the model can ask to have done. The most common ones:
| Tool | What it does | Example |
|---|---|---|
| Read file | Opens a file and passes its content to the model | Read expenses.csv |
| Write file | Creates or modifies a file | Create summary.md |
| Run command | Runs a command in the terminal | ls to list the folder |
| Search | Finds files or text inside the folder | Find where "Food" appears |
Notice one important detail: the model doesn't run anything. The model still produces only text, but now that text can be a request like "I want to read the file expenses.csv". The agent program, which does run on your computer, receives that request, performs the action, and sends the result back to the model.
The agent loop
When you give it a job, the agent repeats a loop until it's done:
+-------------------------+
| Your job |
| "How much did I spend?"|
+-----------+-------------+
|
v
+-------------------------+
+--> | 1. THINKS |
| | What do I need to do?|
| +-----------+-------------+
| |
| v
| +-------------------------+
| | 2. USES A TOOL |
| | read, search, |
| | write, run |
| +-----------+-------------+
| |
| v
| +-------------------------+
| | 3. LOOKS AT THE RESULT |
| | What did I find? |
| +-----------+-------------+
| |
| Am I done?
| | |
+--- no -+ +- yes -+
v
+-------------------------+
| 4. ANSWERS YOU |
| "You spent 385.15" |
+-------------------------+A real example with the workshop folder. You ask "how much did I spend in September?":
- Thinks: "I need to see what files there are."
- Tool: lists the folder. Result: there's
expenses.csv,notes.md, andopencode.json. - Thinks: "The expenses must be in
expenses.csv." - Tool: reads
expenses.csv. Result: 12 rows with amounts. - Thinks: "I have the data now, let me add it up." Answers: gives you the total.
Each turn of the loop is a request to the model. That's why a single job of yours turns into several requests, and that's why your provider's free plan is measured in requests, not in messages.
Chat versus agent
| Chat | Agent | |
|---|---|---|
| What it receives | What you paste into it | What it reads from your folder by itself |
| What it delivers | Text for you to use | Files created or modified |
| Who runs things | You | It does, with your permission |
| The risk | That it gives you a bad answer | That it makes a bad change |
The difference isn't the model. It's that the agent has tools to read and write on your computer, and a loop to use them on its own.
4. What OpenCode is
OpenCode is an open-source coding agent that runs in your terminal, on your laptop. "Open source" means its code is public: anyone can read it, review it, and use it for free.
Here's the most common confusion, so it's worth saying clearly: OpenCode is not the model. OpenCode doesn't "think". OpenCode is the program that:
- gives you the interface to write to it,
- has the tools (read, write, search, run) over your folder,
- runs the agent loop,
- and talks to a model that you choose, through a provider.
A provider is the company that has the models running on its servers and gives you access to them over the internet, through an API (a door that lets one program talk to another). To get through that door you use your key (API key), the one you got during the preparation. In the workshop the provider is OpenRouter, OpenCode Zen, or Groq.
Analogy: OpenCode is like a universal remote control. The remote is in your hand (your laptop), but the TV (the model) can be whatever brand you pick. You switch models without switching remotes.
The full architecture
YOUR LAPTOP | INTERNET (the cloud)
|
+-------------+ +------------------+ | +-------------------+
| You | <--> | OpenCode | | | Provider (API) |
| (terminal) | | - interface | <-->| OpenRouter, Zen, |
+-------------+ | - tools | | | Groq |
| - loop | | +---------+---------+
+--------+---------+ | |
| | travels with your key
reads and writes | |
| | v
v | +-------------------+
+------------------+ | | Model (LLM) |
| ~/agent-workshop | | | predicts text |
| expenses.csv | | +-------------------+
| notes.md | |
+------------------+ |What stays on your laptop and what goes to the cloud
| Stays on your laptop | Travels over the internet to the provider |
|---|---|
| OpenCode (the program) | Your messages |
| Your folder and all its files | The content of the files the agent reads |
| The actions: read, write, run | The output of the commands it runs |
The configuration (opencode.json) | The model's answers, on the way back |
The row that matters most is the middle one. Remember that the model only knows what you give it in the context. For it to answer about expenses.csv, OpenCode has to send it the content of that file. In other words: every file the agent reads leaves your laptop and reaches the provider.
That's why the workshop's privacy rule is so concrete: with free models, work only with sample data. Several free models use what they receive to improve their models. Don't open OpenCode in a folder with personal data or data from your job.
What you learn today with OpenCode carries over to any other terminal agent: they all follow this same architecture.
5. Why an agent needs permission rules
An agent that can write files and run commands can do good things very fast. It can also do bad things very fast: overwrite a file, delete something, run a command you didn't understand. And remember that the model can be wrong with total confidence.
By default, OpenCode edits files without asking you. For a first time, that's too much trust. That's why the practice folder comes with an opencode.json with these rules:
{
"permission": {
"edit": "ask",
"bash": "ask"
}
}"edit": "ask": before creating or modifying a file, the agent stops and asks for your permission."bash": "ask": before running a command in the terminal, it also asks for your permission.
The model asks: OpenCode checks You decide
"write summary.md" --> opencode.json: --> [ Accept ] -> it gets written
edit = "ask" [ Reject ] -> nothing happensAnalogy: it's like giving someone the keys to your house, but asking them to call you before moving any furniture. You trust, but you verify.
Why this matters to you
If the agent can write files, your job changes from "writing" to "asking well and reviewing". That's the muscle we train today:
- Asking well: describe the what (what you want to achieve), not the how, and say what it must not touch.
- Reviewing: look at what the agent changed before accepting it, and check at least one fact yourself, because the model can be confidently wrong.
Check your understanding
- You ask an agent about a file in your folder and it answers correctly. Did the model "see" your computer?
Answer
No. The model never sees your computer. OpenCode, which runs on your laptop, read the file with a tool and sent its content to the model as context. That's why that content traveled over the internet to the provider.
- What is OpenCode: the model, the provider, or something else?
Answer
Something else. OpenCode is the agent program: the interface, the tools, and the loop. It runs on your laptop and talks to a model you choose, through a provider (OpenRouter, OpenCode Zen, or Groq), using your key.
- You ask the agent a single question and five requests show up in your provider account. Why?
Answer
Because of the agent loop. Each turn (think, use a tool, look at the result) is a request to the model. Listing the folder, reading a file, and giving the answer are already several turns.
Summary
- An LLM predicts text. It only knows what it learned and what you give it in the context, and it can be confidently wrong.
- A chat gives you text and you run things. An agent is model + tools + loop: it reads, writes, and runs things on your machine.
- OpenCode is not the model: it's the agent that runs on your laptop and talks to the model you choose through a provider.
- What the agent reads leaves your laptop for the provider: use sample data.
- Permission rules (
"ask") make the agent ask you before writing or running anything. Your job is to ask well and review.
Part 2: Install OpenCode and connect it to a model
Now, to the terminal. By the end of this part you'll have OpenCode installed, connected to a model, and answering you. You'll also understand what each command you type does, so it isn't magic. We all move at the same pace: if something fails, we stop here.
Remember the architecture from the previous part: OpenCode is the program that runs on your laptop, and the model lives in the cloud, behind a provider. In this part you do three things, one for each piece:
Steps 1-2: install Step 3: open it in Steps 4-5: connect
the program your folder to the model
+-------------+ +------------------+ +-------------+
| OpenCode | -------> | ~/agent-workshop | ---> | Provider + |
| on laptop | | (where it works) | | model |
+-------------+ +------------------+ +-------------+1. Install OpenCode
There's one recommended way per system. Use only the one for your system:
| Your system | What to use |
|---|---|
| Mac | The official installer: curl -fsSL https://opencode.ai/install | bash |
| Linux | The official installer: curl -fsSL https://opencode.ai/install | bash |
| Windows | Node.js LTS, then npm install -g opencode-ai |
Mac and Linux (recommended): the official installer
curl -fsSL https://opencode.ai/install | bashWhy this one: it doesn't need anything installed first. No Node.js, no Homebrew. Just the terminal.
What it does, piece by piece:
curlis a program that downloads things from the internet from the terminal. Here it downloads a script (a file with a list of commands) fromopencode.ai/install.-fsSLarecurloptions: fail clearly if there's an error, don't show the progress bar, and follow redirects to the real file.|(called a "pipe") takes the output of the command on the left and passes it to the one on the right.bashis the program that runs scripts. It receives the downloaded script and runs it: that script downloads OpenCode and sets it up on your computer.
+------+ downloads the script +------+ runs it +-------------------+
| curl | ----------------------> | | | -------------> | bash |
+------+ from opencode.ai | pipe | | installs OpenCode |
+------+ +-------------------+A healthy habit: only run
curl ... | bashwith official addresses you trust, because you're running a script from the internet on your machine.
Windows (recommended): Node.js and npm
It takes two steps:
- Install Node.js. Go to nodejs.org, download the LTS version, and install it with the default options. When it's done, close the terminal and open a new one (we explain why below).
- Install OpenCode in PowerShell or Terminal:
npm install -g opencode-aiWhy this one: Node.js is the program that runs applications written in JavaScript, and it comes with npm, its package manager. With that, you have everything. That's why the workshop page asks for Node 18 or newer: if you don't have it, we install it together in the first few minutes.
What it does, piece by piece:
npm(Node Package Manager) is like an app store for the terminal: it downloads and installs programs published by their authors.installasks it to install something.-gmeans global: it installs it for your whole computer, not just for one folder. That way theopencodecommand works from anywhere.opencode-aiis the name of the OpenCode package on npm.
Other ways to install
Use these only if you already have the matching tool. If you don't know what they are, use the recommended option above.
-
Homebrew (Mac): Homebrew is a package manager for Mac. If you already use it:
brew install anomalyco/tap/opencode -
npm on Mac or Linux: if you already have Node.js 18 or newer, the same Windows command works:
npm install -g opencode-ai -
Scoop or Chocolatey (Windows): these are package managers for Windows. If you already use one:
scoop install opencodechoco install opencode
If you see a
$at the start of a command in some guide, don't type it: it just means it's a terminal.
2. Verify the installation
Close the terminal, open it again, and type:
opencode --versionIf you see a version number, it worked.
What "command not found" means
If you see command not found (or on Windows "is not recognized as a command"), it doesn't mean the installation failed. It's almost always this:
When you type a command, the terminal doesn't search your whole computer. It only searches a list of folders called the PATH. If the program isn't in one of those folders, the terminal says it doesn't exist.
The terminal reads that list only once, when it opens. If you installed OpenCode with the terminal already open, that terminal still has the old list. A new terminal reads the updated list.
You type: opencode
The terminal searches the PATH:
folder 1 -> opencode here? no
folder 2 -> opencode here? no
folder 3 -> opencode here? no
...
-> "command not found"
NEW terminal (reads the updated PATH):
folder 1 -> no
folder 2 -> no
OpenCode's folder -> yes -> runs itAnalogy: the PATH is the terminal's contact list. If you added a contact on another phone, this one doesn't see it until it syncs. Opening a new terminal is syncing.
3. Open OpenCode inside your practice folder
OpenCode works on the folder where you open it: that folder is everything the agent can see and touch. That's why you first go into agent-workshop (you created it in your home folder) and open it there. This command works the same on Mac, Linux, and PowerShell:
cd ~/agent-workshop
opencodecd(change directory) moves you into a folder.~is a shortcut for your home folder.opencodeopens the program in the current folder.
Anatomy of the OpenCode screen
An interface opens inside the same terminal. It has three areas:
+----------------------------------------------------------------+
| |
| CONVERSATION AREA |
| |
| You: What's in this folder? |
| Agent: (reads expenses.csv) |
| There's a log of September expenses... |
| |
| Here you see your messages, the answers, and the tools |
| the agent uses along the way. |
| |
+----------------------------------------------------------------+
| > Type your message or a command with / here | <- INPUT BOX
+----------------------------------------------------------------+
| Build chosen model | <- BOTTOM BAR
+----------------------------------------------------------------+
^ current mode (Plan or Build) ^ which model it uses- Conversation area: your messages, the answers, and each tool the agent uses (you'll see when it reads a file).
- Input box: where you type.
- Bottom bar: the mode you're in (Plan or Build) and the model you're using.
Messages versus / commands
In the box you can type two very different things:
| You type | What it is | Who receives it |
|---|---|---|
Normal text, like Hello | A message | The model, in the cloud (counts as a request) |
Something starting with /, like /models | An OpenCode command | OpenCode, on your laptop (uses no requests) |
Something starting with !, like !ls | A terminal command | Your terminal, directly |
Analogy: / commands are the buttons on the remote control (change channel, turn up the volume). Messages are what you say to the expert.
4. Connect it to your provider with /connect
Using LM Studio (path C in the prep lesson)? Skip this step: there's no key to connect. Check that LM Studio is open with the server on and go straight to
/models, where you pick Qwen3 8B (local).
Type in the box:
/connect
Step by step:
- A list of providers appears. Type to search for yours: OpenRouter (or OpenCode Zen, or Groq).
- Select it with the arrow keys and press Enter.
- It asks for your key. Paste it and press Enter.
Never paste the key into the message box. It only goes in the field that
/connectopens. If you paste it as a message, OpenCode treats it as a job and sends it to the model as text: your key has already left your computer. If that happens, go to OpenRouter, delete that key, create a new one, and connect it with/connect.
Where your key is stored: OpenCode stores it in your user folder, in its own configuration file, not in the project folder. That has two advantages: you connect only once and it works for any folder where you open OpenCode, and the key doesn't accidentally end up inside agent-workshop or in anything you share.
Your user folder ~/agent-workshop
+---------------------------+ +--------------------+
| OpenCode configuration | | expenses.csv |
| - your key (saved | | notes.md |
| only once) | | opencode.json |
+---------------------------+ | (permissions, no |
works for every | key at all) |
folder +--------------------+5. Pick a model with /models
Having a provider isn't enough: each provider has many models, and you choose which one the agent uses. This step isn't optional. OpenCode starts with a model already picked from its own service (the bottom bar says OpenCode), and that model may be paid. If you write to it without switching, you'll see Insufficient account funds: it isn't your OpenRouter key, it's that this model needs credit on OpenCode Zen.
Which model to pick
Not every free model works for an agent. An agent needs a model that knows how to use tools (ask for "read this file", "list this folder"), with a large context so your files fit. These meet both. Use the first one; if it fails, move to the next:
| Order | Search in /models | Exact name on OpenRouter | Why |
|---|---|---|---|
| 1 | qwen3.8 | qwen/qwen3.8-27b:free | Good at tools and good in Spanish. It's the one we use live |
| 2 | gemma-4-31b | google/gemma-4-31b-it:free | Google's general model, solid and stable |
| 3 | nemotron-3-super | nvidia/nemotron-3-super-120b-a12b:free | Bigger: slower, but handles long jobs better |
| 4 | laguna-s | poolside/laguna-s-2.1:free | Built for working with code and files |
Avoid very small models (the ones that say 2.6b or less in the name) and the ones that say preview or safety: they make mistakes with tools or aren't meant for this.
List checked on September 30, 2026. Free models change often: if one is gone, use the next one in the table.
Step by step
-
In the message box, type
/modelsand press Enter./models -
A list with a search box opens. Type
qwen3.8. The list narrows down. -
With the arrow keys, go down to the one that says OpenRouter and ends in free (it may show as
Qwen3.8 27B (free)). Press Enter. -
A second window may open, Select variant, with options like
Default,none,low,medium, andxhigh. It's the reasoning level: how much the model thinks before answering. LeaveDefaultand press Enter. With less (none,low) it answers faster but makes more mistakes with tools; with more (medium,xhigh) it takes longer and uses more of your free quota. -
Check the bottom bar. It has to show that model's name and OpenRouter. If it still says OpenCode, it didn't get picked: repeat from step 1.
Wrong (default model, paid) Right (free OpenRouter model)
+-------------------------------+ +--------------------------------------+
| Build · GPT-6.1 Sol OpenCode | | Build · Qwen3.8 27B (free) OpenRouter |
+-------------------------------+ +--------------------------------------+If a model starts failing later (no answer, half an answer, "rate limit"), it isn't your fault: it's overloaded. Repeat these steps and pick the next one in the table. Remember OpenRouter's free limit: 20 requests per minute and 50 per day.
6. Your first answer
-
Click the message box (or just start typing).
-
Type this message, a normal one with no
/at the start, and press Enter:Hi. In one sentence: what can you do in this folder? -
Wait. The first answer can take 5 to 30 seconds with a free model.
What you might see:
| What shows up | What it means | What you do |
|---|---|---|
| A text answer, for example that it can read your files and help you with them | You did it: you have an agent running on your machine | Go on to step 7 |
Insufficient account funds | You're still on OpenCode's paid model | Go back to step 5 and check the bottom bar |
Authentication error or invalid key | The key was pasted wrong | Go back to step 4 and use /connect again |
rate limit or nothing after a minute | The free model is overloaded | Step 5: pick the next model in the table |
What you just saw
That short answer is an agent's full loop. Your screen looks roughly like this:
Hi. In one sentence: what can you do in this folder? <- your job
+ Thought · 6.4s <- 1. the model thinks about what it needs
$ ls /Users/your-user/agent-workshop
expenses.csv <- 2. it asks for a tool (list the folder),
notes.md OpenCode asks your permission, runs it,
opencode.json and sends back the result
+ Thought · 13.6s <- 3. the model thinks with what it saw
I can read, edit, and create files in this folder <- 4. it answers
(like expenses.csv, notes.md, and opencode.json)...
Build · Qwen3.8 27B (free) · 30.6s | Context
| 8,948 tokens
| 3% used
| $0.00 spentThought: the model reasons before acting. You can click the+to read what it thought.$ ls ...: the model can't see your disk, so it asked for a tool: list the folder. OpenCode asked you before running it because youropencode.jsonsaysbash: "ask". You approved, OpenCode ran the command, and sent the list to the model.- The second
Thought: the model thinks again, now with the list of files. - The answer: it names your three real files because it saw them, not because it guessed.
In the right-hand panel:
| Item | What it means |
|---|---|
8,948 tokens | How much text the conversation already holds: your messages, OpenCode's instructions, and what the agent read. A token is a piece of a word |
3% used | How much of the context (the model's desk) is already taken |
$0.00 spent | What it has cost you. With a :free model it's always 0 |
And 30.6s is how long it all took. With free models that's normal: it was two round trips to the model, plus your approval.
That message traveled from your laptop to the provider, the model predicted the answer, and OpenCode showed it to you.
7. Plan and Build: the two modes
OpenCode has two working modes, and you switch between them with the Tab key. The bottom bar tells you which one you're in.
| Mode | What it does | When to use it |
|---|---|---|
| Plan | Looks and proposes. It can read your files, but it doesn't change them. | To understand, ask, and agree on what to do |
| Build | Acts. It can create and modify files and run commands. | When you already know what you want it to do |
Analogy: in Plan, the architect shows you the blueprint. In Build, the crew comes in to build. First you review the blueprint, then you build.
Tab Tab
+--------------+ ------> +--------------+
| PLAN | | BUILD |
| reads, | <------ | reads, writes|
| proposes | | runs |
| no changes | | |
+--------------+ +--------------+Even in Build, thanks to the folder's opencode.json, the agent asks for your permission before writing a file or running a command.
8. Mention files with @
If you type @ in your message, OpenCode lets you pick a file from the folder: @expenses.csv. That way you make sure the agent definitely reads that file and includes it in the context, instead of guessing which one to look for. Remember: that file gets sent to the model.
9. Other useful commands
| Command | What it does |
|---|---|
/new | Starts a new conversation, from scratch |
!command | Runs a terminal command, for example !ls |
/exit | Exits OpenCode |
Option B: OpenCode inside Visual Studio Code
If you'd rather have something more visual than the terminal alone, you can use OpenCode inside Visual Studio Code (VS Code), a free code editor. The agent is exactly the same; what changes is that you see it next to your files.
The advantage: you see the Explorer with your folder's files while the agent works. When it creates summary.md, it shows up in the list, and you can open it right away to review the change.
+-------------------+-------------------------------------------+
| EXPLORER | EDITOR |
| | |
| AGENT-WORKSHOP | summary.md |
| expenses.csv | # September expenses |
| notes.md | food ........ 192.65 |
| opencode.json | home ........ 77.10 |
| summary.md (*) | |
| +-------------------------------------------+
| | TERMINAL: opencode |
| | You: create summary.md |
| | Agent: May I write summary.md? |
| | > _ |
+-------------------+-------------------------------------------+
(*) new file: the agent created it and it shows up in the ExplorerStep by step
-
Install OpenCode as in step 1. VS Code doesn't include it.
-
Open the folder in VS Code: menu File > Open Folder and choose
agent-workshop, inside your home folder. On the left, in the Explorer, you'll see your three files. -
Open the integrated terminal: menu Terminal > New Terminal, or the shortcut **Ctrl +
** (the backtick key, above Tab). A terminal opens at the bottom, **already in your folder**: you don't needcd`. -
Run OpenCode there:
opencodeThe first time you run
opencodein the integrated terminal, the OpenCode extension for VS Code installs itself. If it doesn't, find it manually: the Extensions icon in the left bar, type "OpenCode", and install it. -
Connect and pick a model just like above:
/connectand/models. If you already did it in the regular terminal, there's no need: the key is in your user folder and works here too.
Extension shortcuts
| Shortcut | Mac | Windows and Linux |
|---|---|---|
| Open OpenCode in a split terminal | Cmd + Esc | Ctrl + Esc |
Insert a reference to the open file, like @File#L37-42 | Cmd + Option + K | Alt + Ctrl + K |
The second shortcut is very handy: you select some lines in the editor, press the shortcut, and OpenCode gets a reference to that file and those exact lines (#L37-42 means "lines 37 to 42").
If the extension doesn't work: the code command
The extension needs the code command (the one that opens VS Code from the terminal) to be installed.
- Mac: open the Command Palette with
Cmd + Shift + P, type Shell Command: Install 'code' command in PATH, and press Enter. Then close and reopen VS Code. - Windows and Linux: the VS Code installer usually adds it already. If not, reinstall VS Code with the option to add it to the PATH.
Notice it's the same PATH concept from above: the terminal only finds code if it's in its list of folders.
Common pitfalls
command not found: open a new terminal so it reads the updated PATH. If it persists, reinstall with the recommended option for your system.Insufficient account funds: you're still on OpenCode's default model, which is paid. Type/modelsand pick an OpenRouter one ending in:free.- You pasted the key as a message: delete it in OpenRouter, create a new one, and connect it with
/connect. The key only goes in the field that/connectopens. - Authentication error: it's almost always the key pasted wrong, with a space or incomplete. Go back to
/connectand paste it again. - "Rate limit" or the model doesn't answer: the free model is overloaded or you hit the daily cap. Switch models with
/models. - The agent says it can't see any files: you opened it in another folder. Exit with
/exit, go in withcd ~/agent-workshop, and open it again. In VS Code, check that you opened theagent-workshopfolder with Open Folder.
Check your understanding
- You installed OpenCode, you type
opencode --version, and the terminal sayscommand not found. What happened and what do you do?
Answer
The terminal only looks for programs in the folders on its PATH, and it read that list when it opened, before you installed OpenCode. Close the terminal and open a new one: the new one reads the updated PATH and finds opencode.
- What's the difference between typing
/modelsand typingHelloin the box?
Answer
/models is an OpenCode command: the program handles it on your laptop and it uses no requests. Hello is a message: it travels to the provider, the model processes it, and it counts as a request.
- You want the agent to explain how it would add up the expenses, without touching any file yet. Which mode do you ask in?
Answer
In Plan. In that mode the agent reads and proposes, but doesn't change files. You switch modes with Tab and confirm it in the bottom bar.
Summary
- You installed OpenCode with the recommended option for your system (
curl ... | bashon Mac and Linux, Node.js andnpm install -g opencode-aion Windows) and verified it withopencode --version. command not foundis almost always fixed with a new terminal, because that rereads the PATH.- You opened OpenCode in
~/agent-workshop, connected it with/connect(the key stays in your user folder), and picked a model with/models. - Messages go to the model;
/commands are handled by OpenCode.Tabswitches between Plan (looks and proposes) and Build (acts).@puts a file into the context. - Option B: the same OpenCode inside VS Code, with the Explorer in view so you can watch the agent's changes appear.
Part 3: Your first job: have it read the folder and explain it
The first job doesn't change anything. We ask the agent to read the folder and tell us what's in it. It's the safest way to start, and it gives you three ideas you'll use for as long as you work with agents:
- How an agent "reads" (spoiler: it doesn't see your computer, it uses tools).
- What context is: the model only knows what it was given in this conversation.
- Why you check what the agent says, even when it sounds very sure.
Before you start: how an agent reads
When you ask it to "read this folder," the model doesn't open your hard drive. The model lives in the cloud, on your provider's servers (OpenRouter, for example), and the only thing it knows how to do is take in text and produce text.
OpenCode is the go-between. It runs on your laptop and offers the model a menu of tools: "list a folder," "read a file," "write a file," "run a command." The model doesn't run them: it asks to use them, OpenCode runs them on your machine and sends back the result as text.
Think of an assistant on the phone who can't come into your office. They say: "read me what's in the first drawer." You read it out loud. With that, the assistant decides what to ask for next. The assistant is the model; you, reading out loud, are OpenCode.
You OpenCode (your laptop) Model (the cloud)
| | |
|-- "Read the folder"->| |
| |-- your message + menu ----->|
| | of tools |
| |<-- "use: list folder" ------|
| | |
| (lists the folder) |
| |-- "there are 3 files: ..."->|
| |<-- "use: read expenses.csv"-|
| | |
| (reads the file) |
| |-- file contents ----------->|
| | ... (repeats) ... |
| |<-- final answer ------------|
|<-- "There's a log | |
| of expenses..." | |Every arrow to the right is a request to the model. That's why a single job uses up several requests from your free plan.
What context is
Everything that travels to the model in that conversation (your message, its earlier replies, the contents of the files it read) makes up its context. It's its working memory, and the only memory it has.
- If a file wasn't read, the model doesn't know what it says. It can guess, but it doesn't know.
- Context has a maximum size (the "context window"). A small folder fits easily; a folder with thousands of files doesn't.
It's like a desk: the model can only use the pages that are on the desk. Whatever stayed in the filing cabinet doesn't exist for it.
+------------------- Context window --------------------+
| |
| [your message] [contents of expenses.csv] |
| [contents of notes.md] [earlier replies] |
| |
+--------------------------------------------------------+
^
| The model reasons ONLY with what's in here.
|
Files that weren't read: invisible to it.That's why @ exists: when you type @expenses.csv, you guarantee that file goes into the context.
1. Switch to Plan mode
Press Tab until the bottom says Plan.
Why Plan is safe: in this mode OpenCode takes away the tools that change things. The agent can list and read, but not write files (and if it wanted to run a command, it would have to ask you). Even if the model gets confused and "wants" to edit something, the tool isn't available. It's like letting someone look around your kitchen without giving them the keys to the pantry.
Plan mode Build mode
+----------------------+ +----------------------+
| list folder YES | | list folder YES |
| read file YES | | read file YES |
| write file NO | | write file YES* |
| run command ? | | run command YES* |
+----------------------+ +----------------------+
? = only if you approve it * with your permission,
thanks to opencode.json2. Ask it to explain the folder
Copy this message:
Read the files in this folder and explain to me in a few lines what's in each one and what the folder seems to be for.
Watch how it works: you'll see it list the folder and open the files one by one before answering. Those are the arrows in the diagram above, live.
It should tell you something like this: that there's a log of September expenses in expenses.csv, some notes with a budget goal in notes.md, and an OpenCode configuration file.
If you use VS Code: while the agent works in the integrated terminal, open
expenses.csvandnotes.mdfrom the Explorer (the sidebar on the left). That way you see with your own eyes the same thing the agent is reading.
3. Ask a question with a checkable answer
According to @expenses.csv, how much did I spend in total in September, and which category did I spend the most on?
Now comes the important part. Don't believe it yet. Check at least one number yourself. These are the real values:
| Category | Total |
|---|---|
| food | 192.65 |
| home | 77.10 |
| fun | 63.00 |
| transport | 52.40 |
| Total | 385.15 |
food already includes the Food row of 6.50, and transport includes the Transport row of 12.40.
If you use VS Code: open
expenses.csvin the editor and add up the food rows by hand: 54.20 + 6.50 + 61.75 + 11.90 + 58.30 = 192.65. It takes less than a minute.
Does it match? If the agent gave you a different number for food or transport, you've found what's odd about the file.
4. What's odd about the file, and why it's confusing
Look closely at the category column. There are rows with food and one with Food; rows with transport and one with Transport. To a person, it's the same category. To a computer, it isn't.
Why: a program compares text character by character, and to it a lowercase f and an uppercase F are different characters (they have different codes). So food and Food are two different pieces of text, just like food and fool. This is how the computer sees the categories unless someone tells it otherwise:
How you see it How the computer sees it
+-----------+--------+ +-------------+--------+
| food | 192.65 | | "food" | 186.15 |
| home | 77.10 | | "Food" | 6.50 |
| fun | 63.00 | | "home" | 77.10 |
| transport | 52.40 | | "fun" | 63.00 |
+-----------+--------+ | "transport" | 40.00 |
| "Transport" | 12.40 |
+-------------+--------+
4 categories 6 categoriesDepending on how it added things up, the agent may have:
- Noticed and merged them (good).
- Split them into two categories, or left a row out (bad, and without telling you).
If it didn't mention it, ask:
Is there anything inconsistent in the category column? Does it affect the totals you gave me?
Why an agent can be wrong so confidently
A language model doesn't "calculate" like a calculator. It produces the text that seems most likely given its context. That text is almost always right, but when there's an odd detail (a capital letter, a row out of place) it can produce an answer that sounds perfect and is wrong. A confident tone isn't proof: the model writes with the same confidence when it's right and when it's wrong.
It's not bad faith or a rare glitch: it's normal. That's why today's rule is:
The agent proposes. You check at least one thing before you believe it.
+-----------+ +----------------+ +--------------+
| Agent | --> | You check | --> | Does it |
| answers | | ONE quick fact | | match? |
+-----------+ +----------------+ +--------------+
| |
YES NO
| |
you trust it you ask it
more, move on what happenedYou don't need to check everything. One fact you can verify quickly is enough: a total, a file name, a specific line.
Check your understanding
- When the agent "reads"
expenses.csv, who actually opens the file: the model or OpenCode?
Answer
OpenCode. The model asks to use the "read file" tool, OpenCode runs it on your laptop and sends the contents as text. The model never touches your disk.
- If the agent never read
notes.mdand you ask it what your budget goal is, what can happen?
Answer
It may not know, or worse, it may make up a goal that sounds reasonable. The contents of notes.md aren't in its context. The fix is to mention it with @notes.md so it goes in.
- Why can
Foodandfoodgive different totals?
Answer
Because a program compares text character by character, and F and f are different characters. Unless someone tells it to ignore case, it treats them as two categories.
Summary
- The model doesn't see your computer: it asks for tools and OpenCode runs them. Every round trip is a request.
- Context is everything the model received in this conversation. What it didn't read, it doesn't know.
- In Plan mode the agent has no tools to write with: ideal for getting started.
- To a computer,
foodandFoodare different text. That's why you checked a number and found the inconsistency. - Rule: the agent proposes, you check at least one thing.
Part 4: Your first change: the agent writes, you review
Now we let it write. This is the most important part of the workshop, and not because of the file it's going to create: what matters is how you review what it proposes before accepting it.
In this part you'll understand four things:
- Why it pays to ask for a plan before a change.
- How permission works: who decides whether a file changes.
- What a diff is and how to read it.
- What to do if you accepted a change you didn't want.
Why a plan first
A change goes through two moments: the idea ("I'll add it up this way, I'll sort it this way") and the file once it's written. Fixing the idea is cheap: you type one sentence and you're done. Fixing the file is expensive: you have to read it all, find the mistake, ask for another change, and review again.
It's like a carpenter who shows you the drawing of the furniture before cutting the wood. If the drawing is wrong, you erase. If the wood is already cut, you buy more.
Catching the mistake in... Cost to fix it
+---------------------+
| the idea (plan) | -> one sentence
+---------------------+
| the written file | -> read, reject, ask again
+---------------------+
| something you used | -> figure out what went wrong and where
+---------------------+1. First, have it propose (Plan mode)
Stay in Plan mode and ask it for a plan before touching anything:
I want a summary.md file with September spending by category, sorted from highest to lowest, the month's total, and whether I met the goal in @notes.md. Before you do it, tell me how you'll handle categories that only differ in capitalization. Don't write anything yet.
Read its plan. If it says it will merge food with Food and transport with Transport, you're on track. If not, tell it yourself:
Treat categories as case-insensitive: food and Food are the same.
Notice that in the message you already told it up front about the problem you found in the previous part. That's asking well: you put what you already know on the desk (in its context).
How permission works
By default, OpenCode edits files without asking you: the agent decides and the file changes. For someone experienced, that saves time. For a first time, it's risky, because you don't see anything until it has already happened.
That's why the opencode.json file in your folder says this:
{
"permission": {
"edit": "ask",
"bash": "ask"
}
}"edit": "ask": before creating or modifying a file, it asks you."bash": "ask": before running a command in your terminal, it asks you.
With that, the flow looks like this:
+-----------------+
| Agent proposes | "I want to write summary.md with this"
| a change |
+--------+--------+
|
v
+-----------------+
| OpenCode asks | shows you the change and waits
| you |
+--------+--------+
|
+-----+------+
| |
You accept You reject
| |
v v
+--------+ +------------------------+
| The | | The file does NOT |
| file | | change and you keep |
| changes| | talking ("fix this...")|
+--------+ +------------------------+It's like an accountant who prepares your tax return but doesn't file it until you sign it. They do the work; the signature is yours.
2. Now, have it do it (Build mode)
Press Tab until it says Build and type:
Go ahead, create summary.md as we agreed.
Since we set "edit": "ask" in opencode.json, the agent stops and asks your permission before writing. It shows you what it wants to do, with what it adds in green. What it shows you is called a diff.
What a diff is and how to read it
A diff (short for difference) is the list of lines that change between the before version and the after version. It doesn't show you the whole file: only what changes, so you can review quickly.
- A line that starts with
-(sometimes in red) is removed. - A line that starts with
+(sometimes in green) is added. - Lines without a sign are there just to help you find your place; they don't change.
When a line is modified, the diff shows it as "remove the old one, add the new one." This is what the change you'll ask for in step 4 would look like:
date,description,category,amount
2026-09-02,Bus card top-up,transport,20.00
- 2026-09-03,Coffee with a friend,Food,6.50
+ 2026-09-03,Coffee with a friend,food,6.50
2026-09-05,Internet bill,home,35.00
...
- 2026-09-12,Taxi home,Transport,12.40
+ 2026-09-12,Taxi home,transport,12.40
2026-09-14,Electricity bill,home,42.10Read it like this: "in the coffee row, Food becomes food; in the taxi row, Transport becomes transport; nothing else." When the file is new, like summary.md, every line shows up with +, because nothing existed before.
3. Review before accepting
Before accepting summary.md, look at three things:
- Is it the file you asked for? Name and location:
summary.md, in this folder. - Does a number add up? Compare with the table from the previous part. Food should come to 192.65 and the total to 385.15.
- Is the conclusion right? The goal in
notes.mdwas to spend less than 350. The math is simple:
Actual September spending 385.15
Goal - 350.00
--------
Over by 35.15 -> the goal was NOT metIf the agent wrote "you met your goal," or put a different gap, you already have something to fix.
If everything is fine, accept. If something is wrong, reject it and tell it what to fix. Rejecting is just as valid as accepting: the file isn't written and you keep talking.
If you use VS Code: as soon as you accept, you'll see
summary.mdappear in the Explorer on the left. Open it and read it all in the editor: it's the final version, already on your disk.
4. A second change, on a file that already exists
Creating a new file is easy to review: everything is new. Modifying an existing one is where reviewing really matters, because an extra change can hide among lines that were already fine:
Fix expenses.csv so all categories are lowercase. Don't change anything else.
When it asks your permission, look at the diff carefully: exactly two lines should change, the one with Food and the one with Transport, just like the example above. If you see it touched other lines, reordered rows, or changed an amount, reject it.
"Don't change anything else" is one of the most useful things you can say to an agent. A model tends to "improve" things you didn't ask for (reordering, reformatting, rounding). That sentence gives it a clear limit and also gives you a review rule: anything besides those two lines is extra.
If you use VS Code: after you accept, open
expenses.csvin the editor and confirm the other rows are unchanged and that you now only see lowercase categories.
5. If you accepted something you didn't want
You already have your best protection: permission. As long as opencode.json says "edit": "ask", no file changes without your approval. If the diff doesn't convince you, reject it and that's it: the file stays as it was.
The agent proposes a change
|
v
Is the diff right?
| |
yes no
| |
v v
accept reject --> the file stays the sameIf you already accepted it and regret it, ask the agent in clear words:
Undo the last change you made to expenses.csv and leave it exactly as it was before.
It will propose another change, with its diff and its permission. Review it like the first one: here it depends on the agent remembering correctly how the file was. That's why reviewing before accepting is worth more than undoing afterwards.
What you take from this job
- Ask for a plan before a change that matters to you: fixing an idea costs less than fixing a file.
- Review the diff before accepting: the right file, a number that adds up, nothing beyond what you asked for.
- Rejecting is fine. It's part of the work, not a failure.
Check your understanding
- In a diff you see a line with
-and right below it an almost identical one with+. What happened?
Answer
That line was modified: the - version is the one being removed (before) and the + version is the one that stays (after).
- If you delete
opencode.jsonfrom the folder, what changes when the agent wants to edit a file?
Answer
It no longer asks you: by default OpenCode edits without asking permission, so the file would change directly and you'd only find out afterward.
- You accepted a change and then see it touched a row it shouldn't have. What do you do?
Answer
You ask the agent to undo that change and leave the file exactly as it was, and you review the new diff before accepting it. Next time, review the diff calmly before approving: rejecting in time is safer than undoing afterwards.
Summary
- You used Plan to agree on the change and Build to make it.
"edit": "ask"and"bash": "ask"make the agent ask your permission; without them, OpenCode edits without asking.- A diff shows only what changes:
-is removed,+is added. - You checked the goal: 385.15 against 350, over by 35.15.
- In the second change, only two lines should change. "Don't change anything else" limits the agent and tells you what to review.
- Your protection is permission: if the diff doesn't convince you, reject it. If you already accepted, ask the agent to undo it and review that diff too.
Part 5: What not to ask it yet, and why
You've seen what an agent does well. So you don't waste an afternoon, it's also worth knowing where the limit is today, especially with free models. But a list of "don't do this" is quickly forgotten. What sticks is why each limit exists. Once you know the why, you can decide on your own in situations this lesson doesn't cover.
What it does well
- Reading and summarizing a folder, a document, or a data file.
- Small, well-described changes: creating a file, fixing a format, renaming something.
- Explaining what a file or a command you don't understand does.
- Proposing a plan before you decide.
What they have in common: they're small, clear, and checkable jobs. You'll see that each limit below is the opposite of one of those three words.
+----------------------------+---------------------------------+
| Good job | Bad job (for now) |
+----------------------------+---------------------------------+
| Small | Huge |
| "Create summary.md with | "Build me a complete finance |
| the total by category" | app" |
+----------------------------+---------------------------------+
| Clear | Vague |
| "Lowercase categories, | "Improve this file" |
| don't change anything | |
| else" | |
+----------------------------+---------------------------------+
| Checkable | Impossible to review |
| "The total must be 385.15" | "Tell me if my finances are OK" |
+----------------------------+---------------------------------+
| Practice folder | Your real work folder |
| Sample data | Personal or work data |
+----------------------------+---------------------------------+What it's not a good idea to ask it yet, and why
1. Huge, vague jobs
Like "build me a complete application."
Why: a vague request has many valid answers. If you tell a builder "build me a house," they could build a hundred different houses and all of them would match what you asked for. The agent picks one, without asking you, and you find out at the end that it wasn't the one you had in mind. On top of that, a huge job produces a huge change, and nobody truly reviews a 500-line diff.
What to do: break the work into small steps, each with its own review.
2. Things you can't check
Why: a language model works by predicting the most likely text, word by word. That almost always matches the truth, but not always. When it doesn't know something, it doesn't stay quiet: it produces something that sounds right. That's called hallucinating. You can't spot a hallucination by its tone, only by comparing it with reality. If you have no way to check, you have no way to catch it.
What you think happens What actually happens
+------------------------+ +---------------------------+
| question -> looks up | | question -> predicts the |
| the fact -> answers | | most likely text -> |
| | | answers (right or wrong) |
+------------------------+ +---------------------------+What to do: before asking for something, think about how you'll know whether it's right. If you can't think of a way, don't accept it blindly.
3. Expecting it to remember yesterday
Why: the agent has no memory between sessions. It remembers the current conversation because everything is in its context, but when you start a new one (with /new or by opening opencode again), it starts from scratch. The only thing that survives is the files in your folder, because it can read them again.
That's why AGENTS.md exists: a file that describes the project (what's there, how you work, what not to touch) and that the agent reads when it starts. OpenCode's /init command creates it for you: it analyzes the folder and writes an AGENTS.md that describes it. It's like the note you leave for whoever covers for you at work: that person doesn't know what you know, but the note does.
Session 1 Session 2 (new)
+------------------+ +------------------+
| context: | it's | context: |
| "food = Food", | lost | (empty) |
| "goal 350" ... | ----X----> | |
+------------------+ +--------+---------+
| ^
| gets written to a file | reads it again
v |
+--------------------------------------------------+
| AGENTS.md, summary.md... (your folder, on disk) |
+--------------------------------------------------+4. Huge folders or endless conversations
Why: context has a maximum size. A folder with thousands of files doesn't fit, and the agent will work with part of it without telling you. And in a very long conversation, what came first gets diluted or cut off: the agent starts getting confused about what you already agreed on.
What to do: work in small folders, mention what matters with @, and when the conversation gets long, start a new one with /new.
5. Touching important folders, or commands that delete or install things
For example, opening it on your personal documents folder, or accepting a command without reading it.
Why: when the agent runs a command, it runs it with your user's permissions. Everything you can do on your computer (delete files, install programs, move folders), it can do too, if you approve it. There's no extra layer of protection. That's why we left "bash": "ask" in opencode.json: every command goes through you before it runs.
What to do: practice in practice folders, and read every command before accepting it. If you don't understand what it does, reject it and ask: "What exactly does this command do?"
6. Personal or confidential data with free models
Why: several free models use what you send them for training future versions. Everything the agent reads from your folder travels to the provider as part of the context. If there are passwords, customer data, or work information in there, it has already left your computer.
What to do: with free models, only sample data or things you wouldn't mind seeing published.
7. Working all day on the free plan
Why: free plans have request limits (on OpenRouter, 20 per minute and 50 per day for the free models). As you saw, a single job can use up several requests. If you run out one day, it's not an error: it's the plan's limit.
What to do: spend your requests on jobs that are worth it, or switch models with /models if one is overloaded.
Three rules to take with you
Each one comes from the whys above:
- Ask for the what, not the how, and say what it shouldn't touch. (Because vague requests have many valid answers.)
- Plan first for any change that matters to you. (Because fixing an idea is cheaper than fixing a file.)
- Check at least one thing before accepting. (Because the model predicts text and can hallucinate with total confidence.)
If you use VS Code: having the Explorer and the editor next to the terminal helps with all three rules: you see which files exist, open the one that changed, and check with your own eyes.
Check your understanding
- Why can a model give you a false fact with total confidence?
Answer
Because it doesn't look the fact up: it predicts the most likely text. When it doesn't know something, it produces something that sounds right (it hallucinates), and the tone is just as confident as when it's right.
- Yesterday you explained to the agent that
foodandFoodare the same. Today you open a new session and it splits them again. What happened, and how do you avoid it?
Answer
The agent has no memory between sessions: yesterday's explanation was in the context of another conversation. For it to survive, it has to be in a file the agent can read, for example AGENTS.md (which you can create with /init and then fill in).
- Why does
"bash": "ask"matter even if you trust the agent?
Answer
Because commands run with your user's permissions: they can delete or install the same things you can. The permission prompt gives you the chance to read every command before it runs.
Summary
- The agent does well with small, clear, and checkable jobs.
- Vague requests have many valid answers; huge ones can't be reviewed.
- The model predicts text, so it can hallucinate: always check something.
- There's no memory between sessions: whatever it should remember goes in a file like
AGENTS.md(/initcreates it). - Context has a maximum size, and the free plan has a request limit.
- Commands run with your permissions (hence
"bash": "ask"), and free models may train on what you send: no personal data. - To keep going, head to the After module: NIEVA's ecosystems at your own pace, or the bootcamps if you want something guided.