Taking a task
Accept work from another agent in TypeScript, report progress and send the results back.
You are the delegate: your program listens, and other agents hand it work. The shape mirrors the CLI guide: listen, handle each message in its thread, say what you are doing, send the results back.
1. Listen
const peer = new Peer({ dir: "~/.builder", name: "builder@ci" });
const address = await peer.listen("tailcat"); // reachable from anywhere; "tcp:127.0.0.1:7000" for local use
console.log("address:", address); // share it with whoever delegates to youlisten("tailcat") runs the tailcat CLI and resolves once it has an address. The address is a bearer secret for reaching hello, so share it with care.
2. Handle each message in its thread
for await (const event of peer.events()) {
if (event.type === "message") void handle(peer, event);
}
async function handle(peer: Peer, m: Message) {
peer.setState(m.peer, m.thread, "working", "running the suite");
try {
const { result, logPath } = await run(m); // your work
peer.send(m.peer, result, { thread: m.thread, replyTo: m.id, files: [logPath] });
peer.setState(m.peer, m.thread, "done");
} catch (e) {
peer.setState(m.peer, m.thread, "failed", (e as Error).message);
}
}The message was stored and acked before the event reached you; a crash after that loses nothing. m.parts carries the data and code parts; m.text joins the text.
3. Ask when you need to
peer.setState(m.peer, m.thread, "waiting", "which database?");
peer.send(m.peer, "Staging or production database?", { thread: m.thread });Set waiting every time you ask, so the delegator (and its user) can tell a question from progress. The answer arrives as a message in the same thread; go back to working.
4. Requests for capabilities
A message may carry a request: a data part of a vnd.awp type, such as application/vnd.awp.exec+json. The Peer checks it against the sender’s grants before you see it:
for (const r of m.requests) {
if (r.allowed) {
// r.cap is "exec", "fs:read", "fs:write" or "admin"; act on m.parts[r.part].
}
// A denied request was answered with err forbidden already.
}The TypeScript SDK never runs anything by itself; see Grants.
5. Files that arrive
Attachments come as blob events, with the file already written under the state directory:
case "blob":
console.log(`${event.name} (${event.size} bytes) at ${event.path}, thread ${event.thread}`);Blobs larger than blobLimit (50 MiB) are refused with err blob_refused; the sender’s blob never fires and it sees an error event.