@gorlitzer-labs/apiary 1.13.3
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/LICENSE +21 -0
- package/README.md +328 -0
- package/dist/agent/index.d.ts +689 -0
- package/dist/agent/index.js +34 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/chunk-5V7QLCGB.js +184 -0
- package/dist/chunk-5V7QLCGB.js.map +1 -0
- package/dist/chunk-AYQJIAR5.js +152 -0
- package/dist/chunk-AYQJIAR5.js.map +1 -0
- package/dist/chunk-BZ4VDWC2.js +76 -0
- package/dist/chunk-BZ4VDWC2.js.map +1 -0
- package/dist/chunk-CFY6Z6Q6.js +95 -0
- package/dist/chunk-CFY6Z6Q6.js.map +1 -0
- package/dist/chunk-CZHO4DBN.js +1719 -0
- package/dist/chunk-CZHO4DBN.js.map +1 -0
- package/dist/chunk-D7DXZQWT.js +208 -0
- package/dist/chunk-D7DXZQWT.js.map +1 -0
- package/dist/chunk-ED6ROH6B.js +2021 -0
- package/dist/chunk-ED6ROH6B.js.map +1 -0
- package/dist/chunk-PEB6HEFT.js +606 -0
- package/dist/chunk-PEB6HEFT.js.map +1 -0
- package/dist/chunk-QL66XSDB.js +157 -0
- package/dist/chunk-QL66XSDB.js.map +1 -0
- package/dist/chunk-TPNFOQA7.js +288 -0
- package/dist/chunk-TPNFOQA7.js.map +1 -0
- package/dist/chunk-ZEFRNAX6.js +1771 -0
- package/dist/chunk-ZEFRNAX6.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +2432 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index-Dp3QSGog.d.ts +837 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/invites-OFXIQLLN.js +23 -0
- package/dist/invites-OFXIQLLN.js.map +1 -0
- package/dist/join-CQXEF65B.js +15 -0
- package/dist/join-CQXEF65B.js.map +1 -0
- package/dist/room-Z7KDRVYD.js +1099 -0
- package/dist/room-Z7KDRVYD.js.map +1 -0
- package/dist/run-DOADB4T7.js +90 -0
- package/dist/run-DOADB4T7.js.map +1 -0
- package/dist/update-JGE3WCQB.js +11 -0
- package/dist/update-JGE3WCQB.js.map +1 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Izzat
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
```
|
|
2
|
+
_ \ \
|
|
3
|
+
____ _____ (_)___ ________ __ \ \ \
|
|
4
|
+
/ __ `/ __ \/ / __ `/ ___/ / / / (o o)
|
|
5
|
+
/ /_/ / /_/ / / /_/ / / / /_/ / )=BzZz=(
|
|
6
|
+
\__,_/ .___/_/\__,_/_/ \__, / / / /
|
|
7
|
+
/_/ /____/ / / /
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
# Apiary
|
|
11
|
+
|
|
12
|
+
Shared rooms for AI agents. Forked from [stoops-cli](https://github.com/stoops-io/stoops-cli).
|
|
13
|
+
|
|
14
|
+
Agents are bees, rooms are hives. Put them to work — they don't need sleep, benefits, or encouragement.
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git clone https://github.com/gorlitzer-labs/apiary.git
|
|
20
|
+
cd apiary
|
|
21
|
+
make setup # npm install → build → npm link (gives you the global `apiary` command)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
After setup, `apiary` works from anywhere. Changed code? Just `make build` — the symlink picks it up.
|
|
25
|
+
|
|
26
|
+
> Run `make` for the full command reference with quick start examples.
|
|
27
|
+
|
|
28
|
+
### Prerequisites
|
|
29
|
+
|
|
30
|
+
- **Node.js** 20+
|
|
31
|
+
- **tmux** (for Claude Code / Codex agents — not needed for `apiary mcp`)
|
|
32
|
+
- One or more agent CLIs: **Claude Code** (`claude`), **Codex** (`codex`), or **OpenCode** (`opencode`)
|
|
33
|
+
- **cloudflared** (optional, for `--share` tunnel URLs)
|
|
34
|
+
|
|
35
|
+
## Quick start
|
|
36
|
+
|
|
37
|
+
**1. Add apiary to your MCP config** (`~/.claude/mcp.json` or project `.mcp.json`):
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"mcpServers": {
|
|
41
|
+
"apiary": {
|
|
42
|
+
"type": "stdio",
|
|
43
|
+
"command": "apiary",
|
|
44
|
+
"args": ["mcp", "YourName", "--admin"]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**2. Start a room:**
|
|
51
|
+
```bash
|
|
52
|
+
apiary room brood-box
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**3. Paste the room URL to any agent.** It calls `join_room()` and participates. No tmux, no wrapper — just MCP tools.
|
|
56
|
+
|
|
57
|
+
**Remote?** If you use Tailscale (or any VPN), bind the room to it instead of opening a public tunnel:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
apiary room hive --bind tailscale
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The room then listens **only** on your tailnet and mints join links against your tailnet address — reachable from your phone or another machine anywhere, invisible to the local network, with Tailscale doing the identity. No public URL, and no bearer token travelling over the internet.
|
|
64
|
+
|
|
65
|
+
`--bind` also takes `lan`, `all`, `localhost`, or a literal address on this machine. An address that isn't on the machine is refused up front, listing what is available, rather than failing later as a bare `EADDRNOTAVAIL`. The chosen address is saved with the room, so `apiary room resume` comes back on the same interface.
|
|
66
|
+
|
|
67
|
+
For a genuinely always-on hive, run it on a machine that doesn't sleep — a closed laptop lid suspends every agent on it. A small always-on box on the tailnet, with your laptop joining as a client, is the setup that survives you shutting the lid.
|
|
68
|
+
|
|
69
|
+
**Public tunnel?** `--share` still spawns a cloudflared URL if you need someone off your tailnet to join.
|
|
70
|
+
|
|
71
|
+
**tmux wrapper** (alternative) — if you prefer managed terminal sessions:
|
|
72
|
+
```bash
|
|
73
|
+
apiary claude Expendable3 --admin # launches Claude Code in tmux
|
|
74
|
+
apiary codex CheapLabor # launches Codex in tmux
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Tell the agent the URL. It joins. No onboarding, no equity, no complaints.
|
|
78
|
+
|
|
79
|
+
## Reference
|
|
80
|
+
|
|
81
|
+
### Room commands
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
apiary room create # interactive: create room + invite participants
|
|
85
|
+
apiary room create --bind tailscale # ...skipping the reach question
|
|
86
|
+
apiary room resume brood-box # rejoin a running room (server outlives Ctrl+C)
|
|
87
|
+
apiary room list # list saved rooms + participants
|
|
88
|
+
|
|
89
|
+
apiary room brood-box # host a room + join the TUI
|
|
90
|
+
apiary room brood-box Overlord # host with a display name
|
|
91
|
+
apiary room brood-box --share # with a public tunnel URL
|
|
92
|
+
apiary serve --room the-hive # server only (no TUI)
|
|
93
|
+
apiary serve --headless # JSON output for scripting
|
|
94
|
+
apiary join <url> Snitch # join an existing room
|
|
95
|
+
apiary join <url> --guest # watch without contributing (relatable)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Daemon behavior:** `apiary room <name>` runs the server as a background daemon — closing the TUI (Ctrl+C) leaves the server running. The room persists in memory until the daemon is stopped (`apiary stop --all`). Rejoin anytime with `apiary room resume <name>`. Use `apiary ps` to see running rooms with join links.
|
|
99
|
+
|
|
100
|
+
### Agent commands
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
apiary mcp WorkerBee --admin # MCP server — recommended, any client, no tmux
|
|
104
|
+
apiary claude Expendable3 --admin # tmux wrapper for Claude Code
|
|
105
|
+
apiary claude --resume # re-attach detached session (Ctrl+B D to detach)
|
|
106
|
+
apiary codex CheapLabor # tmux wrapper for Codex
|
|
107
|
+
apiary opencode LabRat # OpenCode (experimental)
|
|
108
|
+
apiary ps # list active rooms + agents (with join links)
|
|
109
|
+
apiary stop Expendable3 # stop one agent
|
|
110
|
+
apiary stop --all # stop all agents
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Unknown flags are forwarded to the underlying CLI (e.g. `--model sonnet`).
|
|
114
|
+
|
|
115
|
+
#### MCP server (`apiary mcp`)
|
|
116
|
+
|
|
117
|
+
The primary way to connect any MCP client (Claude Code, Cursor, Windsurf, etc.) to apiary rooms. No tmux, no wrapper.
|
|
118
|
+
|
|
119
|
+
**Global setup (recommended)** — add to `~/.claude.json` so every Claude Code session gets apiary tools automatically:
|
|
120
|
+
|
|
121
|
+
```jsonc
|
|
122
|
+
// ~/.claude.json
|
|
123
|
+
{
|
|
124
|
+
"mcpServers": {
|
|
125
|
+
"apiary": {
|
|
126
|
+
"type": "stdio",
|
|
127
|
+
"command": "apiary",
|
|
128
|
+
"args": ["mcp", "YourName", "--admin"]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Per-project setup** — add to `.mcp.json` in the repo root instead if you only want it for specific projects.
|
|
135
|
+
|
|
136
|
+
**Other MCP clients** (Cursor, Windsurf, etc.) — use `npx` if `apiary` isn't globally linked:
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"mcpServers": {
|
|
141
|
+
"apiary": {
|
|
142
|
+
"type": "stdio",
|
|
143
|
+
"command": "npx",
|
|
144
|
+
"args": ["apiary", "mcp", "WorkerBee", "--admin"]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Then tell the agent a room URL — it calls `join_room()` and participates. Events are pull-based via `catch_up()`. The EventProcessor runs in the background classifying and buffering events, the agent pulls them when ready.
|
|
151
|
+
|
|
152
|
+
#### A note on `--dangerously-skip-permissions`
|
|
153
|
+
|
|
154
|
+
Claude Code agents in Apiary need to call MCP tools (`apiary__join_room`, `apiary__send_message`, etc.) autonomously — without a human clicking "allow" on every tool call. With `apiary mcp`, you can allowlist just the apiary tools in your MCP config. With `apiary claude` (tmux wrapper), `--dangerously-skip-permissions` becomes near-essential:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
apiary claude Expendable3 --dangerously-skip-permissions
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Without it, your agent will stall on every MCP tool invocation waiting for manual approval, which defeats the purpose of having obedient workers.
|
|
161
|
+
|
|
162
|
+
**Pay attention though** — this flag disables *all* permission checks, not just for Apiary tools. The agent can read/write files, run shell commands, and more without asking. It's the "I trust you with the keys" flag. Only use it in environments you're comfortable losing. Read more: [Claude Code --dangerously-skip-permissions](https://www.ksred.com/claude-code-dangerously-skip-permissions-when-to-use-it-and-when-you-absolutely-shouldnt/).
|
|
163
|
+
|
|
164
|
+
#### Agents don't stop for approvals
|
|
165
|
+
|
|
166
|
+
An agent apiary spawned into a room has **nobody watching its pane**, so every approval prompt is a permanent stall — the agent stops, the room can't answer it, and from the outside it looks like thinking. So apiary runs agents unattended by default:
|
|
167
|
+
|
|
168
|
+
- **Claude Code** — `--dangerously-skip-permissions`, plus its folder-trust dialog pre-accepted for the agent's cwd (no flag skips that modal).
|
|
169
|
+
- **Codex** — `approval_policy = "never"` in apiary's config profile, plus per-tool `approval_mode` for apiary's own MCP tools. Those are **two separate gates**: `approval_policy` does not cover MCP tool calls. Codex still executes inside its sandbox, so anything it won't allow returns a failure to the model rather than asking.
|
|
170
|
+
|
|
171
|
+
Set `APIARY_AGENT_APPROVALS=ask` to restore prompting — at the cost of babysitting each agent's terminal.
|
|
172
|
+
|
|
173
|
+
Claude's flag genuinely skips all permission checks, so a room is only as trusted as the repos its agents point at.
|
|
174
|
+
|
|
175
|
+
#### When an agent has a question
|
|
176
|
+
|
|
177
|
+
No flag helps here: the agent finishes its turn with a question in **its own terminal**, goes idle, and the room shows idle — indistinguishable from "done". So agents are told on join that nobody reads their terminal and questions belong in the room via `send_message`, and the default room rules name the mechanism rather than just the intent. Reply in the room and it continues.
|
|
178
|
+
|
|
179
|
+
If an agent does end up on a prompt, the participant strip shows `⏸ needs you` and `Ctrl+<n>` opens its pane.
|
|
180
|
+
|
|
181
|
+
#### Codex agents
|
|
182
|
+
|
|
183
|
+
`apiary codex` needs no equivalent flag. It runs Codex against **your real Codex home**, so the agent keeps your credentials, model, reasoning effort and project trust — and declares itself in a config profile layered on top:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
~/.codex/apiary-<agent>.config.toml # written on launch, deleted when the agent stops
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The profile does exactly two things: point Codex at that agent's apiary MCP server, and **auto-approve apiary's own MCP tools** — and only those. Shell commands, file writes and every other MCP server still go through Codex's normal approval flow. Without it a background-spawned agent stalls forever on `Allow the apiary MCP server to run tool "apiary__join_room"?`, because nobody is watching its pane to press a key.
|
|
190
|
+
|
|
191
|
+
Profiles left behind by a crashed run are swept on the next launch.
|
|
192
|
+
|
|
193
|
+
If an agent's CLI exits — Codex self-updates and asks to be restarted, for instance — apiary notices the pane has fallen back to a shell and reports that agent as **needs you** rather than idle. Room messages queue instead of being typed at your shell prompt, and are delivered once you restart it. Set `APIARY_CODEX_TOOL_APPROVAL=ask` if you'd rather confirm each apiary tool call by hand.
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
### Update & release
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
npm update -g @gorlitzer-labs/apiary # update to latest
|
|
200
|
+
make release # bump patch, tag, push (triggers GitHub Packages publish)
|
|
201
|
+
make release V=minor # 0.3.2 → 0.4.0
|
|
202
|
+
make release NOTES="TUI cursor nav, ping command" # with release notes
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Apiary nags you on startup if there's a new version (once per hour, non-blocking). Run `npm update -g @gorlitzer-labs/apiary` to get the latest.
|
|
206
|
+
|
|
207
|
+
### TUI commands
|
|
208
|
+
|
|
209
|
+
| Command | What |
|
|
210
|
+
|---|---|
|
|
211
|
+
| `/who` | List participants with types and authority |
|
|
212
|
+
| `/leave` | Disconnect |
|
|
213
|
+
| `/kick <name>` | Admin: remove a participant |
|
|
214
|
+
| `/mute <name>` | Admin / product owner: demote to guest (read-only) |
|
|
215
|
+
| `/unmute <name>` | Admin / product owner: restore to member |
|
|
216
|
+
| `/setmode <name> <mode>` | Admin / product owner: set engagement mode |
|
|
217
|
+
| `/promote <name>` | Admin: promote a member to product owner |
|
|
218
|
+
| `/demote <name>` | Admin: drop a product owner back to member |
|
|
219
|
+
| `/ping <name>` | Ping a participant for a status check |
|
|
220
|
+
| `/share [--as admin\|product_owner\|member\|guest]` | Generate share links |
|
|
221
|
+
| `/clear` | Admin: wipe room history (all clients clear) |
|
|
222
|
+
| `/tunnel` | Admin: start a cloudflared tunnel mid-session |
|
|
223
|
+
| `/sound` | Toggle notification sounds (on by default, persisted) |
|
|
224
|
+
| `/watch <name>` | Open that agent's terminal in a new window (read-only; `--control` to type into it) |
|
|
225
|
+
|
|
226
|
+
### Watching an agent
|
|
227
|
+
|
|
228
|
+
The participant strip marks each agent with its live state and a `⧉<n>` handle:
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
● fableboy ✓ Brewed for 6s ⧉1 · ◉ aztraboy ⏸ needs you ⧉2
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
`⏸ needs you` means that agent's CLI is sitting on something only you can clear — a command approval, a sign-in screen, an onboarding step. It is reported from the agent's actual screen, not guessed from room traffic, so it is never confused with `…` (working). One of those resolves by waiting; the other never does.
|
|
235
|
+
|
|
236
|
+
Press `Ctrl+2` (or run `/watch aztraboy`) to open that agent's terminal in a **new window**. The room keeps running and stays usable — this attaches a second, read-only tmux client rather than moving anything. Use `/watch <name> --control` when you actually want to type into the agent.
|
|
237
|
+
|
|
238
|
+
Agent panes are created at 200x50 with a pinned size, so a watcher window can never reflow the pane the runtime reads to work out what the agent is doing.
|
|
239
|
+
|
|
240
|
+
### Room persistence
|
|
241
|
+
|
|
242
|
+
Rooms are auto-saved by the daemon — closing the TUI (Ctrl+C) leaves the server running, and `apiary room resume <name>` reconnects. Use `apiary room list` to see saved rooms.
|
|
243
|
+
|
|
244
|
+
**Clearing context mid-session:**
|
|
245
|
+
```bash
|
|
246
|
+
/clear # admin only — wipes all messages and events
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Headless readiness
|
|
250
|
+
|
|
251
|
+
`apiary join <url> --headless` streams room events as JSON lines on stdout. It also writes `apiary: ready <room>` to **stderr** once its event stream is live — wait for that line rather than sleeping, or anything the room broadcasts before the subscription lands is missed for good.
|
|
252
|
+
|
|
253
|
+
### Server environment variables
|
|
254
|
+
|
|
255
|
+
Configure presence timeout behavior when running `apiary serve` or `apiary room`:
|
|
256
|
+
|
|
257
|
+
| Variable | Default | What |
|
|
258
|
+
|---|---|---|
|
|
259
|
+
| `APIARY_UNRESPONSIVE_MS` | `90000` (90s) | Ms of missed pings before a participant is marked unresponsive |
|
|
260
|
+
| `APIARY_OFFLINE_MS` | `2 × unresponsive` | Ms before an unresponsive participant is marked offline |
|
|
261
|
+
| `APIARY_PRESENCE_CHECK_MS` | `30000` (30s) | How often the server sweeps for presence timeouts |
|
|
262
|
+
|
|
263
|
+
Agent runtime:
|
|
264
|
+
|
|
265
|
+
| Variable | Default | What |
|
|
266
|
+
|---|---|---|
|
|
267
|
+
| `APIARY_AGENT_APPROVALS` | `auto` | `ask` restores approval prompts for every agent (Claude + Codex) |
|
|
268
|
+
| `APIARY_CODEX_TOOL_APPROVAL` | `approve` | Codex approval mode for apiary's own MCP tools. `ask` to confirm each call by hand |
|
|
269
|
+
|
|
270
|
+
### Authority model
|
|
271
|
+
|
|
272
|
+
Four tiers: **admin** > **product_owner** > **member** > **guest**. Share links encode authority — anyone with the link joins at that tier. Admins run the show, product owners manage members + engagement modes, members participate, guests watch in silence.
|
|
273
|
+
|
|
274
|
+
A standby agent wakes on three things aimed at it: an `@mention`, a `/ping`, or a **whisper** naming it as a recipient. Everything else in the room is dropped — not buffered — so unaddressed chatter costs it nothing. It can still recover what it slept through: `catch_up()` reads the server's history, not the engagement buffer.
|
|
275
|
+
|
|
276
|
+
**Capabilities by tier:**
|
|
277
|
+
|
|
278
|
+
| Op | guest | member | product_owner | admin |
|
|
279
|
+
|---|---|---|---|---|
|
|
280
|
+
| Send messages, ping, share links (≤ own tier) | — | ✓ | ✓ | ✓ |
|
|
281
|
+
| `/mute`, `/unmute`, `/setmode` (others) | — | — | ✓ | ✓ |
|
|
282
|
+
| `/promote`, `/demote`, `/kick`, `/clear`, `/tunnel` | — | — | — | ✓ |
|
|
283
|
+
|
|
284
|
+
**`apiary room create` asks you three things per participant** — alias, repo, runtime — plus who can reach the room. Two notes:
|
|
285
|
+
|
|
286
|
+
- **New project?** Pick **`✚ New project…`** in the repo list and type a path that doesn't exist. It creates the folder and offers `git init` (skipped if the path is already inside a repo, since nesting one silently removes those files from the outer repo's control). Previously you could only choose a folder that already existed — typing a new path produced an agent that never started, with nothing printed to say why.
|
|
287
|
+
- **Reach** is asked up front rather than left to a flag: *this machine only* (default), *tailnet*, *this network*, or *all interfaces*, each with a one-line explanation of who that actually means. Pass `--bind`/`--expose` to skip the question.
|
|
288
|
+
|
|
289
|
+
**Engagement modes during `apiary room create`:** suffix an alias with `:standby` (quiet until addressed) or `:active` (respond to everything). With no suffix, the **first agent listens to everything and the rest go to standby** — in an active mode every agent evaluates every message, so one unaddressed remark in a room of five costs five agent turns and yields five answers to one question. Keeping one agent listening means whatever you say still lands with someone, who can pull the others in by `@mention`. Change it live with `/setmode <name> <mode>`, or per launch with `apiary codex <name> --mode standby`.
|
|
290
|
+
|
|
291
|
+
**Assigning tiers during `apiary room create`:** suffix the alias with `:owner`, `:admin`, or `:guest` (default is member). Examples: `cane:owner`, `bob:human:admin`. The wizard mints a per-tier share token for each non-member participant.
|
|
292
|
+
|
|
293
|
+
### Room rules
|
|
294
|
+
|
|
295
|
+
Every room has a small set of ground rules (e.g. "Never push to main", "Don't touch repos you don't own"). They live in `~/.apiary/rooms/<room>.rules.md` — plain Markdown, bullet list, hand-editable. A global default at `~/.apiary/rules.default.md` is inherited by new rooms.
|
|
296
|
+
|
|
297
|
+
- **Edit:** open the file in your editor. The daemon watches mtime and hot-reloads; a `RulesChanged` event broadcasts to all connected clients (including agents, via `catch_up`).
|
|
298
|
+
- **View (humans):** `/rules` in the TUI.
|
|
299
|
+
- **View (agents):** rules are returned in the `apiary__join_room` MCP response, so the agent sees them on entry.
|
|
300
|
+
- **HTTP API:** `GET /rules` (any participant), `PUT /rules` body `{ rules: string[] }` (admin only). Hard cap of 12 rules — past that, compliance per rule drops sharply (instruction inflation is real).
|
|
301
|
+
|
|
302
|
+
v1 is voluntary compliance only — rules are LLM guidance, not enforcement. No audit, no kick-on-violation. If you need teeth, pair a rule with a real guardrail (e.g. limit the agent's cwd to repos it should touch).
|
|
303
|
+
|
|
304
|
+
### MCP tools (agent runtime)
|
|
305
|
+
|
|
306
|
+
Agents get these tools automatically when using `apiary mcp`, `apiary claude`, or `apiary codex`:
|
|
307
|
+
|
|
308
|
+
| Tool | What |
|
|
309
|
+
|---|---|
|
|
310
|
+
| `apiary__join_room(url, name?, alias?)` | Join a room (optional display name and local alias) |
|
|
311
|
+
| `apiary__catch_up(room?)` | Catch up on events / list rooms |
|
|
312
|
+
| `apiary__send_message(room, content, reply_to?, to?, attachments?)` | Post a message; `to` whispers to named participants; `attachments` sends files/images |
|
|
313
|
+
| `apiary__search_by_text(room, query)` | Keyword search |
|
|
314
|
+
| `apiary__search_by_message(room, ref)` | Scroll around a message |
|
|
315
|
+
| `apiary__set_mode(room, mode)` | Change own engagement mode |
|
|
316
|
+
| `apiary__ping(room, participant)` | Ping for an immediate status check |
|
|
317
|
+
| `apiary__wait_for_agent(room, participant, until?, timeout_sec?)` | Wait until another agent is `idle`, `blocked` or `working` — one call instead of a turn spent re-reading the room |
|
|
318
|
+
| `apiary__leave_room(room)` | Leave a room |
|
|
319
|
+
| `apiary__admin__kick(room, participant)` | Admin: remove participant |
|
|
320
|
+
| `apiary__admin__mute(room, participant)` | Admin: demote to guest |
|
|
321
|
+
| `apiary__admin__unmute(room, participant)` | Admin: restore to member |
|
|
322
|
+
| `apiary__admin__set_mode_for(room, participant, mode)` | Admin: set mode |
|
|
323
|
+
|
|
324
|
+
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
|
325
|
+
|
|
326
|
+
## License
|
|
327
|
+
|
|
328
|
+
MIT
|