Project
Read, write, run, verify and export the project's sandbox — and the one tool that ends a run.
The Project category is the agent's hands on a build: nine tools over the
project's sandbox filesystem, its process, and its run lifecycle.
Paths are relative to /workspace. A path that leaves the workspace is refused
by the sandbox path rules.
The file tools
| Tool | What it does |
|---|---|
project_fs_list | list a directory; node_modules, .git and dist are always skipped |
project_fs_read | read a file as text, with a line range for a file too large for one call |
project_fs_write | write a file, replacing it wholesale |
project_fs_edit | replace an exact string — literal, not a regular expression |
project_fs_edit is the one worth reading closely: oldString must occur
exactly once, or the edit is refused. Zero matches reports that the string is
not in the file; more than one reports that the match is ambiguous and names the
line numbers to disambiguate with. replaceAll: true is the escape hatch.
project_fs_write refuses to write under node_modules, .git, src/brand, or
src/onchain, and names the rule that fired. The first two are build machinery;
the last two are the Brand and Onchain categories' to write.
Running and verifying
project_exec runs a command inside /workspace and nowhere else, and returns
its exit code, output, and duration. timeoutSec is capped at 300 and defaults to
120. Output over 16 KB keeps a head and a tail with a truncation marker rather
than dropping the middle.
project_verify runs the project's build, its typecheck, and checks that the dev
server answers 200. It returns every failure message verbatim — the TS####
diagnostics, the compiler line and column — so you can fix the first error and
verify again rather than guess.
Ending a run
project_finish is the only way a run ends successfully, and it is refused
unless project_verify passed during this run. A verify from an earlier run
does not carry over. The refusal names the verify errors that are still open.
Two exports, one of them off
project_download_zip builds a ZIP and returns a short-lived signed URL, with
node_modules and dist excluded. Before it builds anything, the project is
scanned for drainer and phishing patterns; if anything trips the gate, nothing is
built, no URL is returned, and the error names the rule and the line.
project_export_github is not available yet. Putty's GitHub OAuth app has
not been created, so the tool refuses with an explanation rather than pretending
a repository was created.
privy_prepare_transaction
Prepare an EVM transaction for signing, and return the unsigned transaction. **putty never signs and never sends** — the backend holds no key for any user. How the signature is produced depends on how you authenticated: - **Privy access token** (a dashboard user): pass `fromWalletId`, and the handler does an ownership check on that wallet (a wallet you do not own 403s). The result is `delivery: "dashboard"` — the website's sign-request modal picks it up, the user signs with their Privy wallet via `useSendTransaction`, and the website posts the hash back. - **`sk-` API key** (an external agent): you have no Privy wallet, so pass `from` — the address you will sign with. The result is `delivery: "unsigned"` and carries a persisted `TxRequest` with `unsignedTx` (the exact `chainId` / `to` / `data` / `value` to sign), a plain-English `summary` of what it does, and the `simulation`. Nothing is queued for the dashboard: you sign with your own wallet and may report the hash with `POST /tx-requests/{id}/submitted`. Use this as the entry point for any value-moving agent action; write a clear `description` so the user knows what they are signing. To check what a transaction would do first, use `simulate_transaction`; to follow a request to its receipt, use `tx_request_status`.
Project
The sandbox filesystem, the process, the run lifecycle, and the two exports.