binnacle 0.0.1-alpha.7

A CLI tool for AI agents and humans to track project graphs
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
<p align="center">
  <img src="binnaclebanner.png" alt="Binnacle Banner" width="100%">
</p>

# binnacle

Task tracker for AI agents. Stores data outside your repo so it doesn't pollute your codebase.

> [!WARNING]
> Early alpha. Things *will* break.

## Build Prerequisites

### Rust Toolchain

Install Rust via [rustup](https://rustup.rs/):

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

### System Dependencies

**Fedora/RHEL/Rocky Linux:**

```bash
sudo dnf install gcc make pkg-config openssl-devel
```

**Ubuntu/Debian:**

```bash
sudo apt-get update
sudo apt-get install build-essential pkg-config libssl-dev
```

**For WASM viewer builds** (optional):

```bash
rustup target add wasm32-unknown-unknown
cargo install wasm-pack
```

## Install

```bash
cargo install --path .
```

## Usage

```bash
bn system init                  # set up in your project
bn task create "Do the thing"   # create a task
bn ready                        # see what's actionable
bn task close bn-xxxx           # mark done
```

For AI agents:
```bash
bn orient                       # get up to speed on project state
bn goodbye "summary"            # graceful exit
```

## Copilot CLI Management

Binnacle can manage GitHub Copilot CLI binaries to provide version stability for agent workflows:

```bash
bn system copilot install --upstream   # Install binnacle-preferred version
bn system copilot install v0.0.396     # Install specific version
bn system copilot path                 # Show active binary location
bn system copilot version              # List installed versions
```

**Version Pinning:**
- Binnacle ships with a preferred Copilot version (embedded at build time)
- Agents use `--no-auto-update` flag to prevent runtime updates
- Containers pre-install the pinned version during image build
- Host agents resolve binaries via `bn system copilot path`

This prevents unexpected behavior from automatic Copilot updates mid-workflow.

## Running Agents

```bash
./agent.sh auto                 # pick highest priority task and work on it
./agent.sh --loop auto          # keep going until queue is empty
./agent.sh buddy                # helper for adding tasks interactively
```

**Note:** `agent.sh` automatically resolves the Copilot binary via `bn system copilot path` and runs it with `--no-auto-update` to prevent mid-workflow updates. Install a pinned version with `bn system copilot install --upstream` before running agents.

### Containerized Agents (Quick Start)

Run AI agents in isolated containers with full access to the binnacle task graph:

```bash
# 1. Install prerequisites (Fedora/RHEL)
sudo dnf install containerd buildah
sudo systemctl enable --now containerd

# 2. Create a worktree for the agent to work in
git worktree add ../agent-work -b agent-feature

# 3. Build the container image
bn container build

# 4. Run the container
bn container run ../agent-work
```

The container mounts your worktree and binnacle data, runs an AI agent (copilot or claude with pinned versions), and auto-merges completed work back to `main`.

**Copilot Version Management:**
- Containers use a pinned GitHub Copilot CLI version pre-installed during image build
- The pinned version is managed by `bn system copilot` commands
- Copilot runs with `--no-auto-update` to prevent runtime updates
- This ensures consistent agent behavior across container runs

See [container/README.md](container/README.md) for full documentation including resource limits, environment variables, and troubleshooting.

## What It Tracks

- **Tasks** (`bn-xxxx`) with priorities, dependencies, tags
- **Bugs** (`bn-xxxx`) with severity levels
- **Ideas** (`bn-xxxx`) that can be promoted to tasks
- **Milestones** (`bn-xxxx`) with progress tracking
- **Tests** (`bnt-xxxx`) linked to tasks, auto-reopen on regression
- **Docs** (`bn-xxxx`) for attached documentation
- **Queue** (`bnq-xxxx`) for agent prioritization

## Quick Reference

```bash
bn                              # status summary
bn ready                        # actionable tasks
bn blocked                      # what's waiting on dependencies
bn show <id>                    # details on any entity

bn task create/list/update/close
bn bug create/list/update/close
bn link add <src> <tgt> --type depends_on
bn queue show                   # see prioritized work

bn gui                          # web interface (needs --features gui)
bn mcp serve                    # MCP server for agents
```

Run `bn --help` for everything else.

## Agent Supervisor (`bn serve`)

Run a daemon that continuously manages containerized AI agents based on your scaling configuration:

```bash
sudo bn serve
```

**Why sudo?** The `bn serve` command needs to access the containerd socket at `/run/containerd/containerd.sock`, which requires root privileges. However, binnacle automatically detects when running under sudo and:

1. Opens the containerd socket while elevated
2. Drops privileges back to your user (via `SUDO_USER` detection)
3. Sets `HOME` to your user's home directory
4. Creates all files with your user's ownership

This means you run as sudo but **all files remain owned by you**, not root. The process only retains elevated privileges for the containerd socket connection.

If you see a warning like "Running as root without SUDO_USER", it means you're running directly as root (not via sudo), and files will be owned by root. To preserve user ownership, always run with `sudo bn serve`.

For rootless operation without sudo, see the [Rootless Setup](#rootless-setup) section in [container/README.md](container/README.md).

## GUI

### Building with GUI Support

The web interface requires the `gui` feature flag:

```bash
# Install to ~/.local/bin with GUI enabled (recommended)
just install

# Or build manually
cargo build --release --features gui
cargo install --path . --features gui
```

**How bundling works:**
- During `cargo build --features gui`, the build script (`build.rs`) automatically runs `scripts/bundle-web.sh`
- Web assets from `web/` are minified and compressed into `target/web-bundle.tar.zst`
- The bundle is embedded into the binary at compile time
- Bundle is cached using a hash of `web/` contents - only rebuilds when files change
- Development builds can skip bundling with `--dev` flag to serve directly from filesystem

### Launching the GUI

**Option 1: Using `bn gui` (direct command)**

```bash
bn gui                           # Start on default port (3030)
bn gui -p 8080                   # Start on custom port
bn gui --readonly                # Start in read-only mode
bn gui --tunnel                  # Create public URL via devtunnel (read-only)
bn gui --archive data.bng        # Load a .bng archive file (read-only snapshot)
```

The server will start and print the URL to access the interface. Open it in your browser:
```
http://localhost:3030
```

**Note**: The `--archive` flag must be specified **before** any subcommand (e.g., `bn gui --archive file.bng serve`). It appears in `bn gui --help` but not in `bn gui serve --help` because it's a top-level option.

**Option 2: Using `just gui` (with hot reload)**

For development, use the justfile recipe which provides hot restart:

```bash
just gui            # Build, install, and launch with hot restart
just gui nobuild    # Launch without rebuilding (uses existing binary)
```

The `just gui` recipe offers faster iteration during development:
- Starts immediately with the existing binary
- Rebuilds in the background
- Automatically restarts with the new build

**Option 3: Development mode (for frontend work)**

When working on JavaScript/CSS changes, use development mode for instant updates:

```bash
just dev-gui        # Serves from web/ directory, no bundle needed
```

Development mode (`--dev` flag):
- Serves assets directly from `web/` directory
- Edit files and refresh browser to see changes instantly
- No bundling/rebuilding required for frontend changes
- Uses `cargo run --features gui -- gui --dev` under the hood

**Environment Variables:**
- `BN_GUI_PORT`: Override default port (default: 3030)
- `BN_GUI_HOST`: Override bind address (default: 0.0.0.0)
- `BN_GUI_READONLY`: Start in read-only mode
- `BN_GUI_TUNNEL`: Enable tunnel mode (see below)

### Public URL via Dev Tunnels

Share your GUI publicly without port forwarding using Microsoft Dev Tunnels:

```bash
bn gui --tunnel              # Start with a public URL
```

This spawns a `devtunnel` process that creates a temporary public URL (e.g., `https://abc123-3030.use.devtunnels.ms`) proxying to your local GUI.

**Requirements:**
1. Install devtunnel: `just install-devtunnel`
2. Authenticate (one-time): `devtunnel user login`

The authentication step is required before first use and supports GitHub, Microsoft, or Azure AD accounts.

**Security:**
- Tunnel mode **automatically enables read-only mode** to prevent remote modifications
- The URL is randomly generated and not easily guessable
- Tunnel terminates when the GUI server stops

**Use cases:**
- Share project status with remote collaborators
- Demo your task graph without exposing your network
- Quick reviews without VPN setup

### GUI Management Commands

```bash
bn gui status       # Check if GUI is running
bn gui stop         # Gracefully stop the GUI (SIGTERM)
bn gui kill         # Force kill the GUI immediately
```

### Static Viewer Export (GitHub Pages Hosting)

You can create a static HTML bundle of your project's current state for hosting on GitHub Pages or any static site host:

```bash
# Export to default location (target/static-viewer/)
bn gui export

# Export to custom location
bn gui export -o docs/viewer

# Export with specific archive
bn gui export --archive path/to/snapshot.bng
```

The exported bundle includes:
- A standalone web viewer (all HTML, CSS, JS assets)
- A `.bng` archive snapshot of your project
- Auto-load script that opens the archive on page load

**Hosting on GitHub Pages:**

1. Export to a directory that will be committed:
   ```bash
   bn gui export -o docs/viewer
   ```

2. Commit the exported files:
   ```bash
   git add docs/viewer
   git commit -m "Add static project viewer"
   git push
   ```

3. Enable GitHub Pages in your repository settings:
   - Go to Settings → Pages
   - Set source to your branch (e.g., `main`)
   - Set folder to `/docs` (or root if you exported to root)

4. Visit your viewer at:
   ```
   https://<username>.github.io/<repo>/docs/viewer/
   ```

**Remote Archive URLs:**

The viewer can also load archives from remote URLs. Share a viewer URL with an archive parameter:
```
https://<username>.github.io/<repo>/viewer/?url=https://example.com/snapshot.bng
```

This allows you to:
- Host multiple snapshots and switch between them
- Share project state with collaborators
- Create time-based archives for project history

### Testing the GUI

1. **Launch the GUI:**
   ```bash
   just gui
   ```

2. **Open in browser:**
   ```
   http://localhost:3030
   ```

3. **Verify features:**
   - Graph visualization displays tasks and their relationships
   - Nodes are color-coded by status (pending, in_progress, done, blocked)
   - Click nodes to see details in the info panel
   - Use the search bar to filter nodes
   - Use filters to show/hide node and edge types
   - Live updates reflect changes made via CLI

4. **Test live updates:**
   ```bash
   # In another terminal, make changes
   bn task create "Test task"
   bn task update bn-xxxx --status in_progress
   ```
   
   The GUI should update automatically without refresh.

5. **Test connection recovery:**
   - Stop the server: `bn gui stop`
   - Restart it: `bn gui`
   - The viewer should automatically reconnect

### Troubleshooting

**Port already in use:**
```bash
# Use a different port
BN_GUI_PORT=8080 bn gui
```

**Can't connect from another machine:**
- Ensure the server is bound to 0.0.0.0 (default)
- Check firewall settings
- Use `bn gui --host 0.0.0.0` explicitly if needed

**GUI won't stop:**
```bash
# Force kill
bn gui kill
```

## Viewer (WASM)

Export your task graph and view it in any browser—no server needed:

```bash
just build-viewer                # build the standalone viewer
bn system store export data.bng  # export your project data
# open target/viewer/viewer.html, drop in data.bng
```

### Connection Modes

The viewer supports two modes via URL parameters:

- **Archive mode**: `viewer.html?archive=./data.bng` - Load exported `.bng` file (read-only)
- **Live mode**: `viewer.html?ws=localhost:3030` - Connect to running `bn gui` server

Add `#bn-xxxx` to focus on a specific entity: `viewer.html?archive=./data.bng#bn-a1b2`

### Local Hosting

Serve the viewer locally with a pre-loaded archive:

```bash
just serve-wasm                       # serve on port 8080
just serve-wasm 3000                  # serve on custom port
just serve-wasm 8080 path/to/data.bng # serve with pre-loaded archive
```

Then open `http://localhost:8080` in your browser. If you provided an archive path, it will be auto-loaded via URL parameter.

See [docs/embedding-viewer.md](docs/embedding-viewer.md) for embedding in web pages.

## Building

```bash
just install                    # recommended, includes GUI
cargo build --release           # without GUI
```

## License

MIT