piu-piu-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +406 -0
- package/bin/piu-piu.mjs +428 -0
- package/dist/channel.mjs +145 -0
- package/dist/daemon.mjs +1975 -0
- package/dist/office/assets/index-77PZXJ_x.js +5529 -0
- package/dist/office/assets/index-CB3kPPFD.css +1 -0
- package/dist/office/index.html +17 -0
- package/dist/public/debug.html +81 -0
- package/docs/banner.svg +72 -0
- package/package.json +54 -0
- package/scripts/postinstall.mjs +16 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to piu-piu. Versions follow [semver](https://semver.org).
|
|
4
|
+
|
|
5
|
+
## 0.1.0 (2026-10-05)
|
|
6
|
+
|
|
7
|
+
First release.
|
|
8
|
+
|
|
9
|
+
- **The office:** every Claude Code session on your machine is a person in a 3D isometric building with day, sunset and night lighting. People type while tools run, raise a hand when they need you, and take breaks in the lounge, at ping-pong or at baby-foot.
|
|
10
|
+
- **Chat with any agent** through a live Claude Code process, with:
|
|
11
|
+
- permission approvals, Claude-Code-style question cards and plan approval;
|
|
12
|
+
- slash commands;
|
|
13
|
+
- modes (Ask first, Auto-edit, Plan, Allow all).
|
|
14
|
+
- **The real Claude Code in the page:** a node-pty terminal with xterm.js. Expand it to full screen, collapse it while the agent works, or choose it as the default view in settings.
|
|
15
|
+
- **Resume conversations** under the same names as Claude Code's `/resume`, or open Claude Code's own resume picker in the terminal.
|
|
16
|
+
- **Specialists:** your Claude Code agents (user, project, plugin, built-in) have desks, work when called, link to their caller, and bring in colleagues for parallel calls. Each call opens read-only in the sidebar.
|
|
17
|
+
- **Skills** show as a badge on the session using them.
|
|
18
|
+
- **Channel:** talk to an open terminal session from the office, and approve its permission prompts there.
|
|
19
|
+
- **The `piu-piu` command:** `setup`, `status`, `start`/`stop`/`restart` (refuses while agents work), `run`, `logs`, `doctor`, `uninstall`.
|
|
20
|
+
- **Background service** (launchd or systemd user unit). Your data lives in `~/.piu-piu`.
|
package/README.md
ADDED
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://unpkg.com/piu-piu-cli@0.1.0/docs/banner.svg" alt="piu-piu: a 3D office for your Claude Code agents" width="100%">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img alt="Claude Code" src="https://img.shields.io/badge/Claude_Code-D97757?style=for-the-badge&logo=claude&logoColor=white">
|
|
7
|
+
<img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white">
|
|
8
|
+
<img alt="React" src="https://img.shields.io/badge/React_19-20232A?style=for-the-badge&logo=react&logoColor=61DAFB">
|
|
9
|
+
<img alt="Three.js" src="https://img.shields.io/badge/Three.js-000000?style=for-the-badge&logo=threedotjs&logoColor=white">
|
|
10
|
+
<img alt="Node.js" src="https://img.shields.io/badge/Node.js_24+-5FA04E?style=for-the-badge&logo=nodedotjs&logoColor=white">
|
|
11
|
+
<img alt="Fastify" src="https://img.shields.io/badge/Fastify-000000?style=for-the-badge&logo=fastify&logoColor=white">
|
|
12
|
+
<img alt="SQLite" src="https://img.shields.io/badge/SQLite-003B57?style=for-the-badge&logo=sqlite&logoColor=white">
|
|
13
|
+
<img alt="Vite" src="https://img.shields.io/badge/Vite-646CFF?style=for-the-badge&logo=vite&logoColor=white">
|
|
14
|
+
<img alt="pnpm" src="https://img.shields.io/badge/pnpm-F69220?style=for-the-badge&logo=pnpm&logoColor=white">
|
|
15
|
+
<img alt="macOS" src="https://img.shields.io/badge/macOS-000000?style=for-the-badge&logo=apple&logoColor=white">
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
# piu-piu
|
|
19
|
+
|
|
20
|
+
piu-piu shows every Claude Code session on your machine as a person in a 3D isometric office.
|
|
21
|
+
|
|
22
|
+
- **People:** each session sits at a desk and types while it works. It raises a hand when it needs you, and takes a break in the lounge when it's idle.
|
|
23
|
+
- **Specialists:** your Claude Code agents (`~/.claude/agents`, plugins, built-ins) are people with their own desks. They get to work whenever a session calls them.
|
|
24
|
+
- **Control:** you talk to any agent from the office. From there you can approve or deny its tool calls, answer its questions, run slash commands and switch modes. You can also resume old conversations, or open the **real Claude Code** in a terminal inside the page.
|
|
25
|
+
|
|
26
|
+
It runs locally. One daemon on `127.0.0.1:7777` watches `~/.claude` and serves the office web app. Nothing leaves your machine.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm i -g piu-piu
|
|
30
|
+
piu-piu setup
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Contents
|
|
36
|
+
|
|
37
|
+
- [What it does](#what-it-does)
|
|
38
|
+
- [Requirements](#requirements)
|
|
39
|
+
- [Install](#install)
|
|
40
|
+
- [Commands](#commands)
|
|
41
|
+
- [Connect your terminal sessions](#connect-your-terminal-sessions)
|
|
42
|
+
- [Using the office](#using-the-office)
|
|
43
|
+
- [Agents, specialists and skills](#agents-specialists-and-skills)
|
|
44
|
+
- [Configuration](#configuration)
|
|
45
|
+
- [Running Claude in a VM, office on the host](#running-claude-in-a-vm-office-on-the-host)
|
|
46
|
+
- [How it works](#how-it-works)
|
|
47
|
+
- [HTTP and WebSocket API](#http-and-websocket-api)
|
|
48
|
+
- [Security model](#security-model)
|
|
49
|
+
- [Troubleshooting](#troubleshooting)
|
|
50
|
+
- [Development](#development)
|
|
51
|
+
- [Releases](#releases)
|
|
52
|
+
- [Uninstall](#uninstall)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## What it does
|
|
57
|
+
|
|
58
|
+
### See
|
|
59
|
+
| In the office | What it means |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Typing at the desk | A tool is running (the label shows which one: `Bash: npm test`, `Edit: src/app.ts`) |
|
|
62
|
+
| Hands on the keyboard, still | Thinking or generating |
|
|
63
|
+
| Raised hand and amber light | Waiting for you: a permission prompt or a question |
|
|
64
|
+
| Head in hands | The session hit an error |
|
|
65
|
+
| Lounge, ping-pong, baby-foot | Idle for 5+ minutes. Games need at least 2 people on a break; anyone alone gets the sofa and a coffee |
|
|
66
|
+
| Dashed coloured line between two people | A specialist (subagent) working for the session it's linked to |
|
|
67
|
+
| `using devops-mz` badge | The session is running that skill this turn |
|
|
68
|
+
|
|
69
|
+
### Talk and control
|
|
70
|
+
- **Chat with any agent.** Office messages go to a live Claude Code process for that agent, in its folder, with its full conversation.
|
|
71
|
+
- **Approvals and questions.** Permission prompts become Allow/Deny cards. `AskUserQuestion` questions become choice cards, like in Claude Code, and plan approval (`ExitPlanMode`) shows the plan.
|
|
72
|
+
- **Modes**, from one dropdown: Ask first, Auto-edit, Plan, or Allow all (`--dangerously-skip-permissions`). A change applies straight away, even mid-task.
|
|
73
|
+
- **Slash commands.** Type `/` for the agent's real command list, including your custom commands and skills.
|
|
74
|
+
- **Full history.** A terminal session's own conversation is mirrored into the chat. Use "Show earlier messages" to page back through it.
|
|
75
|
+
- **Real terminal.** Toggle any conversation to Terminal and you get the real `claude` CLI running in a pseudo-terminal, drawn with xterm.js: pickers, Shift+Tab, everything. You can expand it to full screen and collapse it while the agent keeps working.
|
|
76
|
+
- **Resume, rename, create.**
|
|
77
|
+
- Start a new agent on any folder, or resume one of its earlier conversations. The names match Claude Code's `/resume`.
|
|
78
|
+
- Or open Claude Code's own resume picker in the terminal.
|
|
79
|
+
- **Take over closed terminals.** Close a terminal session and your next office message continues the same conversation through the Agent SDK.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Requirements
|
|
84
|
+
|
|
85
|
+
- **macOS** (tested on macOS 26) or **Linux** (background service via systemd user units)
|
|
86
|
+
- **Node.js 24+** (uses the built-in `node:sqlite`)
|
|
87
|
+
- **Claude Code**, installed and logged in (`claude` on your PATH, or at `~/.local/bin/claude`)
|
|
88
|
+
- Linux only: `build-essential`, `python3` (node-pty compiles there) and `lsof`
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Install
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npm i -g piu-piu
|
|
96
|
+
piu-piu setup
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
On **Linux**, node-pty compiles during install, and npm 11 blocks install scripts for global packages. Allow it:
|
|
100
|
+
`npm i -g piu-piu-cli --allow-scripts=node-pty`
|
|
101
|
+
|
|
102
|
+
`piu-piu setup` does the following, and is safe to run again after an upgrade:
|
|
103
|
+
1. Installs the Claude Code hooks for real-time status, in `~/.claude/settings.json` (a backup is written first).
|
|
104
|
+
2. Registers the channel, so the office can talk to open terminal sessions.
|
|
105
|
+
3. Installs the background service, which starts at login and restarts if it stops: launchd on macOS, systemd `--user` on Linux.
|
|
106
|
+
4. Opens **http://127.0.0.1:7777**.
|
|
107
|
+
|
|
108
|
+
Your data lives in `~/.piu-piu`, so upgrades never touch it.
|
|
109
|
+
|
|
110
|
+
**Upgrade:** `npm i -g piu-piu-cli@latest && piu-piu restart`
|
|
111
|
+
|
|
112
|
+
**From source:**
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
git clone https://github.com/T4ruxx/piu-piu.git && cd piu-piu
|
|
116
|
+
pnpm install && pnpm build
|
|
117
|
+
pnpm piu-piu setup # same CLI, running from the checkout
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Commands
|
|
123
|
+
|
|
124
|
+
| Command | What it does |
|
|
125
|
+
|---|---|
|
|
126
|
+
| `piu-piu setup` | Hooks, channel and background service, then opens the office |
|
|
127
|
+
| `piu-piu open` | Opens the office in your browser |
|
|
128
|
+
| `piu-piu status` | Sessions open, working and waiting; specialists at work; approvals; terminals |
|
|
129
|
+
| `piu-piu start` · `stop` · `restart` | The background service. `stop` and `restart` refuse while an agent is working in the office; add `--force` to go ahead anyway |
|
|
130
|
+
| `piu-piu run` | Runs in the foreground instead of as a service |
|
|
131
|
+
| `piu-piu logs [-f]` | Shows or follows the log |
|
|
132
|
+
| `piu-piu hooks install` · `uninstall` | Claude Code hooks only |
|
|
133
|
+
| `piu-piu channel install` · `uninstall` | The channel only |
|
|
134
|
+
| `piu-piu service install` · `uninstall` | Start at login only |
|
|
135
|
+
| `piu-piu doctor` | Checks Node, Claude Code, terminal support, hooks, channel, service and port |
|
|
136
|
+
| `piu-piu uninstall` | Removes the service, hooks and channel. Keeps `~/.piu-piu` |
|
|
137
|
+
| `piu-piu --version` | Prints the installed version |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Connect your terminal sessions
|
|
142
|
+
|
|
143
|
+
piu-piu sees every session through its transcript files with no setup at all. Two optional additions make it real-time and two-way.
|
|
144
|
+
|
|
145
|
+
### 1. Hooks: instant status
|
|
146
|
+
|
|
147
|
+
Installed by `piu-piu setup`, or on their own with `piu-piu hooks install` (`piu-piu hooks uninstall` removes them).
|
|
148
|
+
|
|
149
|
+
The hooks cover SessionStart, UserPromptSubmit, Pre/PostToolUse, Notification, Stop, SubagentStart, SubagentStop and SessionEnd.
|
|
150
|
+
|
|
151
|
+
- Each one is a `curl` to the daemon with a 1-second timeout, so a stopped daemon never slows Claude Code down.
|
|
152
|
+
- Without hooks, the office still works from transcripts. "Waiting for you" is the main signal that only hooks give in real time.
|
|
153
|
+
|
|
154
|
+
### 2. Channel: talk to an open terminal session from the office
|
|
155
|
+
|
|
156
|
+
Registered by `piu-piu setup` (or `piu-piu channel install`). Start the sessions you want to reach from the office with:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
claude --dangerously-load-development-channels server:piu-piu
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Messages you send from the office arrive in that terminal session, and Claude answers back into the office chat. Its permission prompts are relayed to the office too. Without the channel, an open terminal session is read-only in the office until you close it. After that, the office takes the conversation over.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Using the office
|
|
167
|
+
|
|
168
|
+
### Navigation
|
|
169
|
+
| Action | How |
|
|
170
|
+
|---|---|
|
|
171
|
+
| Open someone's conversation | Click their figure, or pick them in **Team** |
|
|
172
|
+
| Jump to any agent | `⌘K` / `Ctrl+K` |
|
|
173
|
+
| Rotate / pan / zoom | Drag / right-drag / scroll |
|
|
174
|
+
| Dock the sidebar beside the office | Dock button in the sidebar header |
|
|
175
|
+
| Close the switcher, collapse full screen, close the sidebar | `Esc` (in that order) |
|
|
176
|
+
| Lighting | Auto (follows your clock), day, sunset, night |
|
|
177
|
+
|
|
178
|
+
### Sidebar
|
|
179
|
+
- **Team:** everyone, grouped by team, with filters for Working, Waiting and On a break. Specialists are listed at the bottom.
|
|
180
|
+
- **Inbox:** every approval and question waiting for you, across all agents.
|
|
181
|
+
- **Activity:** a live feed of prompts, tools, turns, and specialists being called.
|
|
182
|
+
- **Conversation:**
|
|
183
|
+
- The project bar shows the folder, git branch and path.
|
|
184
|
+
- The status strip shows the context window and session cost.
|
|
185
|
+
- The ⋯ menu has: rename, star, stop, new conversation, resume, close the terminal, remove agent, copy the session id.
|
|
186
|
+
|
|
187
|
+
### Chat or terminal
|
|
188
|
+
- Each conversation has a **Chat / Terminal** toggle.
|
|
189
|
+
- **Settings (gear) → Conversations open in** sets the default.
|
|
190
|
+
- When a terminal is closed, the Terminal view offers three choices:
|
|
191
|
+
- **Continue "<title>"** runs `claude --resume <session>`.
|
|
192
|
+
- **Pick a conversation to resume…** runs `claude --resume`, Claude Code's own picker.
|
|
193
|
+
- **New conversation** starts fresh.
|
|
194
|
+
- While an agent's terminal is running, chat is paused for it, so two writers never share one session. The terminal keeps running when you switch away, and its output is replayed when you come back.
|
|
195
|
+
|
|
196
|
+
### Creating agents
|
|
197
|
+
- **Team → New agent:** choose a name, folder, role and room. You can start fresh or continue a past conversation in that folder, optionally with Allow all.
|
|
198
|
+
- Renaming a "freelancer" (a session in a folder no agent owns) turns it into a named agent and keeps its chat.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Agents, specialists and skills
|
|
203
|
+
|
|
204
|
+
| Kind | What it is | How it shows |
|
|
205
|
+
|---|---|---|
|
|
206
|
+
| **Agent** | A folder you work in: from `agents.yaml`, created in the office, or a "freelancer" for any other folder with a session | A person at a desk. One figure per agent; a second figure only for a parallel busy terminal |
|
|
207
|
+
| **Specialist** | A Claude Code agent definition: `~/.claude/agents/*.md`, `<project>/.claude/agents/*.md`, enabled plugin agents, and built-ins (Explore, Plan, general-purpose, claude-code-guide, statusline-setup, fork) | A person with a home desk, wearing the agent's `color`. Gets a desk once called in the last 30 days; the rest are listed "on call" |
|
|
208
|
+
| **Skill** | `~/.claude/skills/<name>` or a project skill. It runs **inside** the calling session | A `using <skill>` badge on that session |
|
|
209
|
+
|
|
210
|
+
**Specialists in practice**
|
|
211
|
+
- **When a session calls one** (`Task` / `Agent` tool), the specialist works at their own desk. A dashed line in their colour runs to the caller, and their label reads `For Lamine · Read: src/app.ts`.
|
|
212
|
+
- **Parallel calls** of the same agent bring in colleagues ("Explore · 2") at free desks.
|
|
213
|
+
- **Each call opens read-only in the sidebar:** the caller's brief, the tools it used and the answer it handed back. A caller's chat shows a **Helping now** strip, and its `Agent:` tool rows link to the call.
|
|
214
|
+
- **Home rooms** come from the agent's name and description:
|
|
215
|
+
- docs, wiki, explore, plan → library
|
|
216
|
+
- devops, infra, deploy, security → server room
|
|
217
|
+
- seo, content, design, film → Studio B
|
|
218
|
+
- anything else → dev floor
|
|
219
|
+
- **Desks:** a full room spills over to the next one. Override the room in `agents.yaml` (see below).
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Configuration
|
|
224
|
+
|
|
225
|
+
### `agents.yaml`
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
agents:
|
|
229
|
+
- id: budget # stable id (chat history is keyed by it)
|
|
230
|
+
name: Léa # shown in the office
|
|
231
|
+
role: dev # dev | lead | devops | web | design | docs | qa | product
|
|
232
|
+
room: dev-floor # dev-floor | server-room | library | studio-b
|
|
233
|
+
cwd: ~/workspace/budget # sessions in this folder (and subfolders) sit at this desk
|
|
234
|
+
instructions: | # optional, appended to Claude Code's system prompt for office chats
|
|
235
|
+
Prefer small PRs.
|
|
236
|
+
permissionMode: default # optional starting mode: default | acceptEdits | plan
|
|
237
|
+
|
|
238
|
+
# optional: seat specialists in a specific room
|
|
239
|
+
specialists:
|
|
240
|
+
mazestudio-docs: library
|
|
241
|
+
devops-agent: server-room
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
- The **longest matching folder** wins, so a session in `~/workspace/budget/api` goes to `budget`.
|
|
245
|
+
- This file lives at `~/.piu-piu/agents.yaml` and is created on first run. Agents created in the office live in `~/.piu-piu/agents.json`. They own their **exact** folder only, and can be removed from the office.
|
|
246
|
+
|
|
247
|
+
### Environment
|
|
248
|
+
|
|
249
|
+
| Variable | Default | Purpose |
|
|
250
|
+
|---|---|---|
|
|
251
|
+
| `PIU_PIU_HOST` | `127.0.0.1` | Address the daemon listens on |
|
|
252
|
+
| `PIU_PIU_PORT` | `7777` | Port for the office, API, hooks and channel |
|
|
253
|
+
| `PIU_PIU_HOME` | `~/.piu-piu` | Where your data lives |
|
|
254
|
+
| `PIU_PIU_URL` | `ws://127.0.0.1:7777/channel` | Where the channel server connects (set in the MCP server's env) |
|
|
255
|
+
|
|
256
|
+
Set these when running `piu-piu setup` or `piu-piu service install`, and the service keeps them.
|
|
257
|
+
|
|
258
|
+
### Files
|
|
259
|
+
|
|
260
|
+
| Path | Contents |
|
|
261
|
+
|---|---|
|
|
262
|
+
| `~/.piu-piu/agents.yaml` | Your roster (see above) |
|
|
263
|
+
| `~/.piu-piu/office.db` | SQLite: sessions, events, office chats, agent modes, agent ↔ session links |
|
|
264
|
+
| `~/.piu-piu/agents.json` | Agents created in the office |
|
|
265
|
+
| `~/.piu-piu/channel-token` | Secret the channel must present (mode 600) |
|
|
266
|
+
| `~/Library/Logs/piu-piu.log` (macOS) · `~/.piu-piu/piu-piu.log` (Linux) | Service log (`piu-piu logs`) |
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Running Claude in a VM, office on the host
|
|
271
|
+
|
|
272
|
+
The daemon has to run **where Claude Code runs**: it reads `~/.claude`, receives hooks and starts `claude`. The browser is only a client. With VirtualBox NAT port forwarding:
|
|
273
|
+
|
|
274
|
+
1. In the VM, run `PIU_PIU_HOST=0.0.0.0 piu-piu setup` (keep port 7777). NAT forwarding targets the VM's own address, not its loopback.
|
|
275
|
+
2. Forward **host 127.0.0.1:7777 → guest 7777**. Binding the host side to 127.0.0.1 keeps it off your network.
|
|
276
|
+
3. On the host, open `http://localhost:7777`. The port must stay 7777: the daemon only accepts pages served from `localhost`/`127.0.0.1` on its own port.
|
|
277
|
+
4. On a Linux guest:
|
|
278
|
+
- `apt install lsof build-essential python3`. `lsof` is used to verify that hook and channel connections really come from your Claude processes.
|
|
279
|
+
- The service is a systemd user unit. On a server without a login session, run `loginctl enable-linger $USER` so it keeps running.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## How it works
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
~/.claude/projects/**.jsonl ──┐ ┌── office (React + three.js) ── you
|
|
287
|
+
~/.claude/…/subagents/*.jsonl ┤ │ WebSocket /ws, /terminal/:id
|
|
288
|
+
Claude Code hooks (curl) ─────┼─► daemon ◄─┤
|
|
289
|
+
channel MCP server (per tty) ─┘ :7777 └── Agent SDK / node-pty ── claude
|
|
290
|
+
SQLite
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
- **apps/daemon** (Fastify, `node:sqlite`, chokidar)
|
|
294
|
+
- **Watching:** tails every transcript and the subagent transcripts, and receives hooks. It keeps one state per session and broadcasts every change over `/ws`.
|
|
295
|
+
- **Agent runtime:** runs one live Claude Code process per agent through `@anthropic-ai/claude-agent-sdk` (streaming input). It handles `canUseTool` approvals, modes and slash commands, and closes idle processes after 20 minutes.
|
|
296
|
+
- **Terminals:** starts the real `claude` in a node-pty pseudo-terminal per agent and keeps 2 MB of scrollback.
|
|
297
|
+
- **Specialists:** reads agent definitions and follows each run from `subagents/agent-*.meta.json` and `.jsonl`.
|
|
298
|
+
- **apps/office** (Vite, React 19, @react-three/fiber, drei, zustand, xterm.js)
|
|
299
|
+
- The scene is a pure function of daemon state (`computeFigures`): desks, the lounge, games, specialists and links.
|
|
300
|
+
- People are procedural, with IK arms on keyboards, paddles and rods.
|
|
301
|
+
- **apps/channel:** an MCP server using Claude Code's channels preview. It links one terminal session to the office in both directions and relays its permission prompts.
|
|
302
|
+
- **packages/shared:** the types used on both sides of the wire.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## HTTP and WebSocket API
|
|
307
|
+
|
|
308
|
+
Local only. Browser requests must come from the office's own origin (see [Security model](#security-model)).
|
|
309
|
+
|
|
310
|
+
| Method & path | Purpose |
|
|
311
|
+
|---|---|
|
|
312
|
+
| `GET /api/state` | Snapshot: roster, sessions, events, approvals, running agents, terminals, specialists, recent subagent runs |
|
|
313
|
+
| `GET /api/sessions/:id/transcript?before=<offset>` | A session's own conversation, paged by byte offset |
|
|
314
|
+
| `GET /api/subagents/:id/transcript` | A specialist call's own conversation |
|
|
315
|
+
| `GET /api/specialists/:type/runs` | Recent calls of one specialist |
|
|
316
|
+
| `GET /api/agents/:id/chat` | Office chat history |
|
|
317
|
+
| `POST /api/agents/:id/messages` `{text}` | Send a message (or `/command`) to an agent |
|
|
318
|
+
| `POST /api/agents/:id/stop` · `/reset` | Stop the current task · start a new conversation |
|
|
319
|
+
| `POST /api/agents/:id/mode` `{mode}` | `default` · `acceptEdits` · `plan` · `bypassPermissions` |
|
|
320
|
+
| `GET /api/agents/:id/commands` | Slash commands and the current mode |
|
|
321
|
+
| `POST /api/agents/:id/resume` `{sessionId}` | Continue an earlier conversation |
|
|
322
|
+
| `POST /api/agents/:id/terminal` `{cols,rows,how}` | Open the real Claude Code. `how`: `continue` · `pick` · `new` |
|
|
323
|
+
| `DELETE /api/agents/:id/terminal` | Close it |
|
|
324
|
+
| `POST /api/agents` · `PATCH /api/agents/:id` · `DELETE /api/agents/:id` | Create (optionally adopting a freelancer) · rename · remove |
|
|
325
|
+
| `GET /api/folders?q=` · `GET /api/folders/sessions?cwd=` | Folder suggestions · past conversations in a folder |
|
|
326
|
+
| `POST /api/approvals/:id` `{behavior, answers?, message?}` | Answer a permission prompt or question |
|
|
327
|
+
| `POST /hooks/:event` | Claude Code hooks |
|
|
328
|
+
| `WS /ws` | Live state: `snapshot`, `session`, `event`, `chat`, `transcript`, `approval`, `running`, `roster`, `terminals`, `specialists`, `subagent` |
|
|
329
|
+
| `WS /terminal/:id` | Terminal I/O: `{type:'input'\|'resize'}` in, `{type:'data'\|'exit'}` out |
|
|
330
|
+
| `WS /channel` | Channel servers (token-authenticated) |
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Security model
|
|
335
|
+
|
|
336
|
+
- **Network:** the daemon binds to `127.0.0.1` only.
|
|
337
|
+
- **Origin check:** `/api`, `/ws`, `/terminal` and `/channel` reject browser requests from any origin other than the office itself. Without it, any website you visit could drive your agents through localhost.
|
|
338
|
+
- **Hook links:** a hook's `X-Claude-Pid` link to a session is accepted only after checking, with `lsof`/`ps`, that the request really comes from a child of that Claude process.
|
|
339
|
+
- **Channel:** a channel must present the secret in `data/channel-token` (readable only by your user) and pass the same ancestry check.
|
|
340
|
+
- **Allow all** is opt-in per agent, starts Claude Code with `--dangerously-skip-permissions`, and is forgotten if an agent id is reused.
|
|
341
|
+
- **Office terminals** run `claude` as your user, in the agent's folder: the same as typing it yourself.
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Troubleshooting
|
|
346
|
+
|
|
347
|
+
| Problem | Fix |
|
|
348
|
+
|---|---|
|
|
349
|
+
| Anything | Start with `piu-piu doctor` |
|
|
350
|
+
| Office is empty | `piu-piu status`. Sessions idle for 30+ minutes are hidden |
|
|
351
|
+
| Nobody raises a hand on prompts | `piu-piu hooks install` |
|
|
352
|
+
| "Forbidden origin" | Open the office at `http://127.0.0.1:7777` or `http://localhost:7777` (same port) |
|
|
353
|
+
| Can't type to an open terminal session | Start it with `--dangerously-load-development-channels server:piu-piu`, or close it and continue from the office |
|
|
354
|
+
| Terminal shows "Do you trust this folder?" | That's Claude Code's first-run prompt for that folder. Answer it once |
|
|
355
|
+
| `posix_spawnp failed` when opening a terminal | Reinstall (`npm i -g piu-piu-cli`): the install step fixes node-pty's spawn-helper permissions |
|
|
356
|
+
| A specialist stays "working" | Runs end on handback, on SubagentStop, or after 10 minutes without activity. Install hooks for instant updates |
|
|
357
|
+
| Logs | `piu-piu logs -f` |
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Development
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
pnpm daemon # daemon with reload (tsx watch) on :7777
|
|
365
|
+
pnpm office # Vite dev server on :5173, proxies /api, /ws and /terminal to the daemon
|
|
366
|
+
pnpm typecheck # all packages
|
|
367
|
+
pnpm check # scene checks: hands on keyboards, ping-pong rally, baby-foot rods, specialist desks
|
|
368
|
+
pnpm build # the npm package: office + bundled daemon + channel in packages/piu-piu/dist
|
|
369
|
+
pnpm piu-piu <cmd> # the CLI, from the checkout
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
```
|
|
373
|
+
apps/daemon/src
|
|
374
|
+
observe/ transcripts.ts · hooks.ts · mirror.ts · subagents.ts · specialists.ts · skills.ts
|
|
375
|
+
runtime/ agents.ts (Agent SDK) · terminals.ts (node-pty) · peer.ts (process ancestry)
|
|
376
|
+
server.ts · state.ts · store.ts · roster.ts · folders.ts
|
|
377
|
+
apps/office/src
|
|
378
|
+
layout.ts who sits where (pure)
|
|
379
|
+
scene/ Building · Furniture · Decor · Person · poses (IK) · FigureView · HelpLink
|
|
380
|
+
ui/ Sidebar · Conversation · TerminalView · Specialists · AgentForms
|
|
381
|
+
apps/channel/channel.mjs
|
|
382
|
+
packages/shared/src/index.ts
|
|
383
|
+
packages/piu-piu the published package: bin/piu-piu.mjs (CLI), scripts/build.mjs
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## Releases
|
|
389
|
+
|
|
390
|
+
Versions follow [semver](https://semver.org). Each release has a section in [CHANGELOG.md](CHANGELOG.md).
|
|
391
|
+
|
|
392
|
+
1. On a branch, run `pnpm release patch` (or `minor` / `major`). This bumps `packages/piu-piu/package.json`, adds a CHANGELOG section listing the commits since the last release, and commits it.
|
|
393
|
+
2. Open a pull request. CI typechecks, runs the scene checks and builds the package.
|
|
394
|
+
3. Merge to `main`. The **Release** workflow publishes the new version to npm with trusted publishing (no npm token), tags it `vX.Y.Z` and creates a GitHub release.
|
|
395
|
+
|
|
396
|
+
Merges that don't change the version publish nothing. Only `main` publishes.
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## Uninstall
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
piu-piu uninstall # service, hooks and channel
|
|
404
|
+
npm rm -g piu-piu
|
|
405
|
+
rm -rf ~/.piu-piu # your data, if you want it gone too
|
|
406
|
+
```
|