Install, First Session, First Task
Get Pi running and give it something real to do: installation, the working folder, authentication, a first task, and what to do when the result is not what you wanted.
Before you can write for an agent, you have to run one — and running one is really two activities that are easy to blur together. The first is setup: install the tool, point it at a folder, prove it can authenticate. The second is use: give it a task and judge the result. They fail differently. A broken install fails loudly and immediately; a badly specified task fails quietly, as output that looks plausible and is wrong. This chapter does the setup quickly, because setup is short and verifiable, then spends most of its length on the part that is actually hard: giving the agent a first task it can finish.
By the end you should be able to state, for any task you hand an agent, what material it names and what finished output it asks for — and to say that before you judge whether the result was good.
Install
Installation looks like a one-line chore, but it is also the moment you decide how much of the rest of this book will describe the program you are actually running. Every behavioural claim here is tied to a release, so the install path is a version decision before it is a convenience decision.
On macOS or Linux, Pi has an installer:
curl -fsSL https://pi.dev/install.sh | sh
Or install from npm, which requires Node.js 22.19 or newer:
# The book's path: the release every claim here was checked against.
npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.0.4
# The unpinned npm path: whatever version is current when you run it.
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
Pi does not require dependency lifecycle scripts for a normal npm installation, which is why --ignore-scripts is there.
Use the pinned form if you intend to follow this book’s claims literally, and say so when you see a difference. Everything here is written against 1.0.4: the managed installer moves to the current release, and where the two disagree, this book is describing the older one. Confirm with pi --version before trusting a behavioural claim.
Be precise about what the pin does and does not do, because it is easy to read a version number as a stronger guarantee than it is. @1.0.4 fixes the version of pi-coding-agent itself. It does not pin what it depends on, and npm will resolve those transitives to satisfying versions — which is exactly the distinction quickstart.md draws between this installer and the one that “pins all dependencies”. If you need a fully reproducible tree, that is the installer’s job or a lockfile’s, not a version range’s. A pinned package is not a pinned tree.
Since 1.0.1 there is a third path on macOS and Linux, and the difference between the three is not cosmetic:
nix profile add github:earendil-works/pi/stable
The installer from the first line “pins all dependencies and updates Pi with pi update”. The npm path, as quickstart.md now puts it, “does not pin transitive dependencies”. Nix builds Pi from source, updates with nix profile upgrade pi, and cannot be updated by pi update at all — package and model catalogue updates still work, but the binary is the package manager’s to move.
For a reader following along, the installation choice matters mainly because this book checks behaviour against version 1.0.4. The managed installer and Nix track releases differently, so neither guarantees the version used by the examples without an explicit check or pin. For a reader deploying Pi to a team or a CI image, dependency resolution matters too: two machines using an unpinned npm command can resolve different dependency graphs. Pi recommends the managed installer over a global npm installation when reproducibility matters. Chapter 22 returns to dependencies inside a package you ship.
Verify it:
pi --version
Do this before trusting anything behavioural the rest of this chapter says about your machine, and before reporting a difference as a bug.
Native Windows and Android under Termux have separate setup instructions. If you are on either, consult the corresponding platform document for installation and shell differences before continuing. The agent loop is the same; the examples and shell commands in this section are not a complete platform-specific setup guide.
The working folder is not a detail
This is the step people skip, and it changes more than you would expect — because the folder is an input to three separate mechanisms, not a formality you set and forget.
cd /path/to/folder
pi
The working folder does three things. It helps Pi discover relevant files, instructions and configuration. It is where Pi looks for context files that apply to what you are working on. And it is how Pi groups saved sessions, which is what makes pi --continue resume the right conversation.
Notice what kind of problem each of those is. “Pi cannot see my instructions”, “Pi ignored my project setup”, “Pi resumed the wrong conversation” are all discovery stories, not intelligence stories: in every case the agent is doing exactly what it was told, in the place it was told to look. Start Pi in the right directory. A session started in your home directory and a session started in the repository you are working on are not the same session, and they do not see the same instructions.
Authenticate
Authenticate before you judge anything else, because every later symptom is hard to read through an authentication problem. Inside Pi:
/login
Choose a provider and follow the prompts — use a subscription, or store an API key. Then:
/model
searches available models and shows the ones whose providers have usable authentication. Press Ctrl+S on a model to save it as the default for new sessions.
If you would rather not have Pi write credentials at all, set the provider’s environment variable instead. That is the right choice in CI. It is also the lowest-priority source: when several credential sources are configured, the one you just exported is often shadowed by a stored one.
The principle underneath that sentence is worth taking with you: authentication is resolved by precedence, not by presence or recency. When a credential seems to be ignored, the question is not “is a credential configured?” but “which source won?” An apparently broken environment variable is usually a stored credential outranking it — and the variable never entered the decision at all. Chapter 3 gives the exact order.
There is a second failure that looks identical and is worth separating now. An environment variable must be present in the process that starts Pi. If you export it in one shell and launch Pi from another — or from a desktop launcher that did not inherit your shell’s environment — the variable is not shadowed, it is simply absent. That is why authentication can succeed in one terminal and fail in another on the same machine: the two terminals are not running the same process environment.
Connect to OpenAI, ChatGPT or OpenCode
Choose the connection you actually have before choosing a model, because the order is not free. A provider is the service Pi connects to; a model is what you select from that service. Pi’s ordinary model picker filters for models with usable provider authentication, so setting up credentials first is the simplest route. Custom endpoints and model configuration are covered in chapter 3. Pi’s pinned models.md and providers.md describe the built-in setup: /login first, /model second.
OpenAI with an API key
If you have an OpenAI API key, run this inside Pi:
/login openai
Follow the API-key prompt, then run /model and choose a model from the openai provider. You can instead supply OPENAI_API_KEY before starting Pi. On macOS or Linux, enter your own key in place of the quoted value:
export OPENAI_API_KEY='your-openai-api-key'
pi
In PowerShell:
$env:OPENAI_API_KEY = 'your-openai-api-key'
pi
Choose one credential route to start with. As models.md explains, a stored credential takes precedence over an environment variable. Keep keys out of your repository; providers.md also says to keep Pi’s auth.json private.
ChatGPT through the subscription login
For the ChatGPT subscription route, use:
/login openai
The built-in openai provider supports two authentication methods: an API key, and a ChatGPT subscription sign-in, which the 1.0.4 provider labels Sign in with ChatGPT. Choose the ChatGPT option, complete the sign-in prompts, then run /model and choose a model under openai.
A separate provider, openai-codex, also exists (/login openai-codex). The pinned provider declaration names it OpenAI Codex (legacy), so treat it as a legacy alternative rather than the starting point. You do not need it to use a ChatGPT subscription with openai.
These are documented setup paths, not a live authentication test: the book’s examples have not signed into your account or run these models.
OpenCode and the optional bridge
Pi 1.0.4’s providers.md lists OpenCode Zen and Go with the environment variable OPENCODE_API_KEY. Start with the built-in connection: run /login, select the OpenCode provider and follow its API-key prompt, then choose a model with /model. Alternatively, set OPENCODE_API_KEY before starting Pi, using the same shell syntax as the OpenAI example above. This is also documented, not run against the service for this book.
The pi-opencode-bridge package you may encounter is a third-party provider extension. A reasonable first approach is to try the built-in connection and consider the bridge only if you need its integration. Pi’s custom-provider.md documents provider extensions as a way to add custom authentication or model discovery; it does not guarantee this particular package’s behaviour.
For the bridge specifically, its published 0.2.1 instructions give this installation route. Review its source before installing, as Pi’s packages.md requires for third-party packages:
pi install npm:pi-opencode-bridge@0.2.1
Restart Pi, then follow the package’s interactive Go-key setup:
/opencode-go-key
/opencode-status
/model
Those two /opencode-... commands belong to the extension. Its README says it discovers models from OpenCode’s cached registry and writes credentials to both OpenCode’s and Pi’s authentication files. This optional integration is documented by the package author, not run or verified for compatibility with Pi 1.0.4 by this book. Treat it as a proposed setup route. If its models do not appear, check the package’s registry and authentication prerequisites; installing the package alone is not evidence of a working connection.
Whichever route you choose, finish in /model. Select an authenticated model and press Ctrl+S if you want it to be the default for new sessions. You are then ready to give Pi the first task below.
Notice that every route in this section is described here but not proved here: the built-in OpenAI, ChatGPT and OpenCode paths are documented setup instructions, not a live sign-in this book performed, and the bridge is the package author’s claim rather than Pi’s.
Give it a task
Before the task itself, one fact about how Pi behaves while it works, because it shapes how you should write that task. Pi shows each file read, each search, each command and each edit it performs. It does not ask before every tool call. This matters on a real machine: by default there is no per-edit confirmation between “Pi decided to edit this file” and “the file is edited.” The visible tool log records actions, rather than asking you to approve each one. If you need pre-execution restrictions, use an appropriate tool guard or external isolation instead of treating the log as an approval mechanism.
That single fact is what makes task framing matter. Some tasks that work well:
Summarize @meeting-notes.md and save the action items to action-items.md.
Explain how this repository is structured and how to run its checks.
Compare @previous.csv with @current.csv and summarize the important changes.
Type @ in the editor to search for a file instead of typing its path.
Then, when Pi finishes, review its response and any changed files. Use version control or backups for important work. For untrusted or unattended work, use a container or another sandbox.
Review afterward catches mistakes and makes the work auditable, but it cannot prevent an action that has already happened. For tasks where that distinction matters, constrain what the agent can reach before it runs; chapter 42 explains the authority boundary. A task with a named output is easier to review, but review and prevention are different controls.
A first session you can build on
The whole path, in order. Each step is a place to stop if something goes wrong, which is the point of doing setup as a sequence rather than as one long script:
flowchart TD
I["install pi<br/>managed installer, npm, or nix"] --> V["pi --version<br/>expect 1.0.4 for this book"]
V --> F["choose a project folder<br/>something disposable"]
F --> A["authenticate<br/>/login or provider environment variable"]
A --> T["project trust<br/>review resources before granting"]
T --> C["pi config<br/>check what was discovered"]
C --> P["first real task"]
The version check is second on purpose, and it is the step most people skip. This book is written against 1.0.4; if pi --version reports something else, the behavioural claims ahead are describing a different program. Say so and read the drift notes rather than quietly reconciling the difference as you go.
The next chapters build extensions, skills and packages, and Part II is where that starts in earnest. You want a project to build them in — something disposable, with one small thing in it. The smallest useful example is a directory with a .pi/ in it:
my-agent/
├── AGENTS.md context file: instructions, applies to this dir and below
└── .pi/ project configuration
├── APPEND_SYSTEM.md appended to the system prompt
├── settings.json project settings: tools and resources
└── prompts/
└── review.md a reusable prompt, available as /review
The .pi/ is the part that trips people up, so say it plainly: project configuration lives under .pi/. settings.json, APPEND_SYSTEM.md, SYSTEM.md, mcp.json and the resource directories all belong there. An APPEND_SYSTEM.md sitting directly in my-agent/ is a file in the repository that Pi does not read as configuration, and it fails silently.
The exception, and the rule that generates it: a context file is found by location, and everything else is found by convention under .pi/.
| You want | Put it | Found by | Needs project trust? |
|---|---|---|---|
| Instructions for this folder and below | AGENTS.md at the folder root |
Walking up from the working directory | No |
| Instructions replacing the base system prompt | .pi/SYSTEM.md |
Convention under .pi/ |
Yes |
| Instructions appended to the system prompt | .pi/APPEND_SYSTEM.md |
Convention under .pi/ |
Yes |
| Tools, resources and mode defaults | .pi/settings.json |
Convention under .pi/ |
Yes |
Reusable prompts, as /name |
.pi/prompts/*.md |
Convention under .pi/ |
Yes |
| MCP servers | .pi/mcp.json |
Convention under .pi/ |
Yes |
| Skills | .pi/skills/<name>/SKILL.md |
Recursive search for SKILL.md |
Yes |
That last column is worth understanding before chapter 8: a stranger’s repository can contribute AGENTS.md instructions even if you decline project trust. Declining trust blocks the listed project resources, but it does not prevent ordinary enabled tools from running or stop untrusted file content from influencing the model. Chapter 28 gives the discovery rules; chapter 8 explains the trust boundary.
If Pi finds protected project resources and no trust decision already applies, interactive mode asks whether to trust the project. Review those resources before granting trust: trusted project extensions can run code in the Pi process, while context files such as AGENTS.md can influence the model even without project trust. SYSTEM.md and APPEND_SYSTEM.md under .pi/ are protected resources. Chapter 8 explains the trust decision and its limits.
While you are in there, run this once:
pi config
It shows the discovered resources and Pi’s built-in extensions and lets you enable or disable them. When something does not appear, this is the first command to run — far more often than it should be necessary to read the source.
Continue later
Sessions save automatically. To resume the most recent session for the same working folder:
pi --continue
Use /resume to choose another saved session.
Because sessions are keyed to the working folder, resuming is the same decision as starting: pi --continue in the right directory brings back the right conversation, and in the wrong directory it brings back a different one.
Why the first task matters so much
Look at the three examples again, and read them for what they have in common rather than for what they ask. None prescribes how to do the job. The first and third name input files; the second names the repository as the material to examine. Each asks for a recognisable result, even when that result is an answer rather than a saved file. That shape — identifiable material, a bounded request, and a reviewable output — is what the most common first prompt is missing:
Fix the bug.
There is nothing wrong with that prompt. It is simply a different request: it delegates the definition of the task as well as the execution, and it does so in a context where the agent has just started and knows nothing about this repository, this codebase’s conventions, or what “fixed” means here.
The diagnosis is not that the agent is weak. It is that the prompt asked the agent to supply the definition of done — which of the several bugs, in which file, up to what standard — when the only participant who knows the answer is you, and the session has not yet learned enough to guess well. A vague task is not a shorter version of a clear one. It is a request for a different job, and it hands the specification to someone who has to invent it.
Three habits worth forming now, each aimed at one part of that specification:
Name the material. @file, a directory, a test suite. The agent can find things, but you know which things are relevant. Naming the material is how you supply the context the session does not have yet.
Say what the output should be. A file, a diff, a table, a single number in the editor. “Summarise” leaves the format open; “save the action items to action-items.md” does not. A recognisable output also makes the result easier to review, which is what the operating contract above asks of you.
Let it look first. Asking for an explanation of the repository before asking for a change in it is cheap, and it puts the agent’s understanding in front of you while any misunderstanding is still easy to correct. This is an inexpensive review before execution, not just afterward.
Chapter 10 makes this argument at length, because it is the highest-leverage skill in the book and the one with the shortest feedback loop. You can practise it today, before writing a line of extension code.
These habits are not specific to Pi. They are what makes a request testable anywhere: the same “name the material and the output” check is what lets you tell, later, whether a run succeeded or merely finished.
What just happened
You started a process, authenticated it, gave it a folder to work in, ran a task, and found it again later. Notice what you did not need: none of it required understanding the extension runtime, the skill router, or the settings precedence chain. That is the setup/use split doing its job — a short, verifiable setup in front of a flexible, unverified use.
Everything the rest of this book describes — the extension runtime, the skill router, the settings precedence chain, the session file — operates inside that process, on that conversation, in that folder. You now have a place for all of it to land.
The three setup decisions you just made — which release, which folder, which credential — are the same three you face on every machine you run this on, a CI image included. Making them visible — with pi --version, pi config, and a known credential source — is what keeps them from becoming silent differences between machines.
Next
You have a loop that runs and something running inside it. What you do not yet know is what the loop is running on. Model, provider, credential, thinking level and cache state sit underneath every mechanism in this book and produce symptoms that look exactly like bugs in the layer above, so they are the next thing to get right.
Chapter 3: models, providers and thinking level.