accelr8 3.8.1 → 4.0.0-next.1

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/README.md CHANGED
@@ -1,8 +1,5 @@
1
1
  # accelr8
2
2
 
3
- Collaborative ascii canvas in your terminal. A real CLI app: mouse-driven TUI,
4
- real multiplayer, and live cursors that glide as your friends move them.
5
-
6
3
  ```
7
4
  ('-. ('-. _ .-')
8
5
  ( OO ).-. _( OO) ( \( -O )
@@ -15,104 +12,341 @@ real multiplayer, and live cursors that glide as your friends move them.
15
12
  `--' `--' `-----' `-----' `------' `------' `--' '--' `----''
16
13
  ```
17
14
 
18
- ## Install
15
+ A multiplayer room in your terminal. Make a project, share its six-character
16
+ code, and friends join with one command. Each project has chat, a shared ASCII
17
+ canvas with live cursors, voice, and AI agents that answer when you @mention
18
+ them. There is a radio station too.
19
19
 
20
20
  ```bash
21
21
  npm install -g accelr8
22
+ accelr8
22
23
  ```
23
24
 
24
- ## Use
25
+ A room in a 120-column window (a real frame, blank rows trimmed):
25
26
 
26
- ```bash
27
- accelr8 # open the app
28
- accelr8 join XYMRAU # jump straight into a friend's project
29
- accelr8 --name pat # pick your display name (remembered)
27
+ ```
28
+ accelr8 night market sign settings maya ●
29
+ Chat ● Canvas Secrets Team ● live
30
+ ──━━━━━━────────────────────────────────────────────────────────────────────────────────────────────────────────────────
31
+ │ ONLINE · 2
32
+ │ ● pat chat
33
+ │ ● maya you
34
+ │
35
+ │ AGENTS · 0
36
+ │ none yet
37
+ │
38
+ │ INVITE
39
+ │ accelr8 join BQRY88
40
+ │ [ copy ]
41
+ │
42
+ · pat joined the project · │
43
+ 21:24 pat ▸ first light. canvas is open, come paint the sign │
44
+ pat ▸ thinking neon pink on black, a big 8 in the middle │
45
+ · maya joined the project · │
46
+ 21:24 maya ▸ on my way. bringing the pink, starting top left │
47
+ 21:25 pat ▸ nice. @maya grab the canvas tab when you land │
48
+ ❯ │
49
+ night market sign · BQRY88 · 2 online joined "night market sign" [tab] tabs · [^C] quit
30
50
  ```
31
51
 
32
- Create a project in the **Projects** tab, paint on the **Canvas** by clicking
33
- and dragging (right-click erases), and grab the join code from the **Members**
34
- tab. Everyone in a project sees everyone else's cursor move live.
52
+ ## Install
35
53
 
54
+ ```bash
55
+ npm install -g accelr8
36
56
  ```
37
- accelr8 collaborative ascii canvas you ●
38
- Projects Canvas Members ● live
39
- ────────────────────────────────────────────────────────────────────────
40
- brush █ ▓ ▒ ░ ● ◆ ★ ▲ ■ · # @ * ⌫ erase clear
41
- ┌─ canvas 100×30 ───────────────────────────────────────────────────────┐
42
- │ █ │
43
- │ █ ▲ alice │
44
- │ █ │
45
- │ ▲ bob │
46
- └────────────────────────────────────────────────────────────────────────┘
47
- landing page redesign · code XYMRAU · 3 online [tab] switch [q] quit
48
- ```
49
57
 
50
- ### Controls
58
+ - Node.js 18 or newer. Tested on Node 22.
59
+ - A terminal with mouse support. accelr8 needs an interactive terminal and
60
+ says so if it doesn't get one.
61
+ - For voice and radio sound: ffmpeg and ffplay on your PATH. The first time you
62
+ join voice, accelr8 offers to install ffmpeg (Homebrew on macOS, winget or
63
+ Chocolatey on Windows) or shows the command to run on Linux.
64
+
65
+ ## Commands
66
+
67
+ | Command | What it does |
68
+ |---|---|
69
+ | `accelr8` | Open the app. |
70
+ | `accelr8 join <CODE>` | Open straight into a project. |
71
+ | `accelr8 radio` | Tune in to ACCELR8 radio in this terminal. |
72
+ | `accelr8 serve` | Run your own sync server on port 8787. |
73
+ | `accelr8 agent add` | Connect an AI account as an agent. |
74
+ | `accelr8 agent list` | List the agents connected on this machine. |
75
+ | `accelr8 agent remove <handle>` | Remove one. |
76
+ | `accelr8 --intro` | Replay the opening film. |
77
+ | `accelr8 -v`, `accelr8 --version` | Print the version. |
78
+ | `accelr8 -h`, `accelr8 --help` | Print help. |
79
+
80
+ | Option or variable | What it does |
81
+ |---|---|
82
+ | `--name <name>` | Your display name, up to 16 characters. Remembered for next time. |
83
+ | `--server <url>` | The sync server to use. The default is the hosted one. |
84
+ | `ACCELR8_SERVER=<url>` | Same as `--server`, for the app. The radio only reads `--server`. |
85
+ | `--port <port>` | The port for `accelr8 serve`. |
86
+ | `--clip <file or url>` | Radio only: play a video as ASCII instead of the visualizers. |
87
+ | `ACCELR8_MIC=<index>` | The microphone voice uses (see `/voice mics`). |
88
+ | `ACCELR8_RADIO_SINK=ffplay` | Radio only, macOS: play through ffplay instead of CoreAudio. |
89
+
90
+ ## The app
91
+
92
+ accelr8 opens with a short film, then the logo. Any key or click skips ahead.
93
+ Skip the logo and the film stops playing at launch. Skip it three launches in
94
+ a row and the logo gets shorter too. Until then, letting the logo play to the
95
+ end starts the count over and brings the film back. `accelr8 --intro` plays
96
+ the whole show again, and watching it to the end brings everything back.
97
+
98
+ ### HOME
99
+
100
+ HOME lists every project on the server you are connected to, with its join
101
+ code, its member count and how many people are online. Click a row to open it.
102
+
103
+ - `+ new project` (or `n`) names a new project and opens it.
104
+ - `join by code` (or `j`) asks for a code.
105
+ - `accounts` (or F2) connects AI accounts. See [Agents](#agents-chat-only).
106
+ - `♫ radio` opens the radio in a new terminal window. On Linux, if nothing
107
+ opens, run `accelr8 radio`.
108
+
109
+ accelr8 checks npm for a newer version in the background, at most every 6
110
+ hours. When a check finds one, HOME shows `update to vX · press enter` from
111
+ the next launch on. Enter (or `u`) runs `npm install -g accelr8@latest`. Start
112
+ accelr8 again when it finishes. If it fails, run that command yourself.
113
+
114
+ ### Rooms
115
+
116
+ A project is a room with four tabs: Chat, Canvas, Secrets and Team. Click a tab
117
+ or press Tab to move between them. Outside chat, `1` to `4` also switch tabs. A
118
+ colored dot on a tab shows who else is there, and Chat shows an unread count.
119
+
120
+ Ctrl-P goes back to HOME and keeps you in the project. Ctrl-C quits. F1 opens
121
+ the keyboard help.
122
+
123
+ **Chat.** Type and press Enter. To start a new line, end the line with `\` and
124
+ press Enter. `@` opens a list of agents and people, and Tab or Enter accepts
125
+ one. Up and Down bring back what you sent, and Ctrl-A, Ctrl-E, Ctrl-W, Ctrl-U
126
+ and Ctrl-K edit the line the way a shell does, and Esc clears it. PgUp, PgDn
127
+ and the mouse wheel scroll, and End on an empty line jumps to the newest
128
+ message. Teammates see what you type while you type it: `/ghost off` stops
129
+ that and `/ghost on` starts it again.
130
+
131
+ **Canvas.** One shared 100×30 grid per project. Pick a brush, then click and
132
+ drag to paint in your color. Right-click erases a cell, and `clear` wipes the
133
+ grid for everyone. Everyone's cursor moves live with their name on it. To see
134
+ the whole grid at once, make the window at least 102 columns by 37 rows. From
135
+ 120 columns the sidebar appears, and the grid sits beside it whole from 126
136
+ columns. In a smaller window you see part of the grid: the arrow keys, Page Up
137
+ and Page Down and the scroll wheel move the view, Home goes back to the
138
+ top-left corner, ‹ and › mark hidden columns, and the bottom edge says which
139
+ part is showing.
140
+
141
+ **Secrets.** A placeholder for now. Nothing is stored here.
142
+
143
+ **Team.** A world map with a dot for each person online, placed by their time
144
+ zone (hover a dot for the name and city). Below the map:
145
+
146
+ - everyone in the project, online or not, and the tab each person is on;
147
+ - the project's agents, with their owner and status;
148
+ - the invite line `accelr8 join <CODE>`, with a copy button.
149
+
150
+ ### Window sizes
51
151
 
52
- | Input | Action |
152
+ accelr8 reshapes itself to fit the window.
153
+
154
+ | Window | Layout |
155
+ |---|---|
156
+ | 120 columns or more | The room adds a sidebar: who is online, agents, the invite. |
157
+ | 80 to 119 columns | The standard room. |
158
+ | under 80 columns, or under 22 rows | A one-row header. |
159
+ | under 60 columns | Chat only. |
160
+ | 15 rows or fewer | A ticker: who is here, the newest chat and the input. |
161
+ | under 32 columns | Parked as an 8-ball that shows unread mentions and agent activity. |
162
+
163
+ Read the table from the bottom up: the first row that matches wins. The
164
+ smallest window accelr8 draws for is 20 columns by 6 rows. Below that, parts
165
+ of the screen are cut off. While it is parked, keys do nothing except Ctrl-C
166
+ (quit) and, in voice, Ctrl-G (mic). Make the window bigger to come back.
167
+
168
+ ### Settings
169
+
170
+ Click `settings` at the top right.
171
+
172
+ - **Theme:** midnight (the default), amber, matrix, mono or paper (light).
173
+ - **Top nav:** underline, brackets, blocks or pipes.
174
+ - **Notify on:** mentions (the default), all messages, or off. accelr8 rings
175
+ the terminal bell when chat is not on screen, at most once every 30 seconds.
176
+
177
+ Settings save to `~/.accelr8/settings.json` as you change them.
178
+
179
+ ## Voice
180
+
181
+ In a project, type `/voice` in chat to join the project's voice channel. You
182
+ join muted and hear everyone who is in voice.
183
+
184
+ | In chat | What it does |
53
185
  |---|---|
54
- | Mouse click | tabs, buttons, project rows, palette |
55
- | Click + drag on canvas | paint with the current brush |
56
- | Right-click on canvas | erase a cell |
57
- | `Tab` / `1` `2` `3` | switch tabs |
58
- | `q` / `Ctrl-C` | quit |
186
+ | `/voice` | Join or leave voice. |
187
+ | `/talk`, `/mute` or Ctrl-G | Open or close your mic. |
188
+ | `/voice mic <index>` | Switch to another microphone. |
189
+ | `/voice mics`, `/voice debug` | List microphones, or show the voice state. The panel shows in the chat-only layout (32 to 59 columns). |
190
+
191
+ - Voice needs ffmpeg and ffplay on your PATH. If they are missing, `/voice`
192
+ offers to install ffmpeg.
193
+ - There is no echo cancellation yet, so wear headphones.
194
+ - Audio travels through the sync server as uncompressed 16 kHz mono, about
195
+ 350 kbps for each person talking.
196
+ - Every step of a call is logged to `~/.accelr8/voice.log`. Send that file
197
+ along when voice misbehaves.
198
+
199
+ ## Agents (chat only)
200
+
201
+ Connect an AI account and it joins your projects as a named agent, such as
202
+ `@mayasclaude`. When someone @mentions it, it answers in chat. API-key agents
203
+ stream their reply as they write it. A reply from a Claude Code login appears
204
+ when it is done.
205
+
206
+ **Connect one.** Press F2 (or click `accounts` on HOME), or run
207
+ `accelr8 agent add`.
59
208
 
60
- ## How the live cursors work
209
+ 1. Provider: Anthropic or OpenAI.
210
+ 2. Key: paste an API key or, for Anthropic, use your Claude Code login if the
211
+ `claude` command is installed. `accelr8 agent add` also picks up
212
+ `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` from your environment.
213
+ 3. Handle: 3 to 20 lowercase letters, digits or hyphens, starting with a letter
214
+ or digit.
215
+ 4. Model. With a Claude Code login, the model follows your Claude Code setup.
61
216
 
62
- The terminal reports mouse motion via ANSI escape sequences (any-event
63
- tracking, `ESC[?1003h`). The app:
217
+ Keys stay on your machine, in `~/.accelr8/accounts.json`, which only you can
218
+ read. The server never sees them. It knows the agent's handle, provider and
219
+ model.
64
220
 
65
- 1. **Throttles** outgoing cursor positions to ~25/sec.
66
- 2. **Interpolates** on the receiving side: each remote cursor lerps toward its
67
- last reported position every frame (`x += (target - x) * 0.35`), so it
68
- glides smoothly instead of teleporting between throttled updates.
221
+ **How it runs.** Your agent runs inside your own accelr8, on your machine, with
222
+ your key. It is online only while you have that project open. If you leave in
223
+ the middle of a reply, the reply ends where it stopped.
69
224
 
70
- Sparse sends plus client-side smoothing is what makes it feel live.
225
+ **Who can @mention it.** On the Team tab, click your agent and pick only me (the
226
+ default), everyone in the project, or choose people. Agents can @mention other
227
+ agents, and every hop is checked against the person who started it.
71
228
 
72
- ## Sync server
229
+ **What it can do.** Talk. API-key agents have no tools at all. A Claude Code
230
+ login runs `claude -p` in plan mode, one turn per reply, with its shell, file
231
+ and web tools blocked. The plan / approve / auto mode on the accounts screen is
232
+ saved, but it changes nothing yet.
73
233
 
74
- By default the CLI talks to the hosted sync server (a Cloudflare Worker with a
75
- Durable Object, source in `worker/`). You can point it anywhere:
234
+ Give any agent that other people can @mention an API key. Anthropic's terms do
235
+ not allow sharing a Claude plan, so keep an agent on your Claude Code login set
236
+ to only me.
237
+
238
+ ## ACCELR8 radio
239
+
240
+ A synced station: everyone tuned in hears the same song at the same moment and
241
+ sees the same visuals.
242
+
243
+ - Run `accelr8 radio`, or click `♫ radio` on HOME to open it in a new terminal
244
+ window. On Linux the button can open nothing, so use the command there.
245
+ - `m` mutes, `+` and `-` (or Up and Down) change the volume, `s` votes to skip,
246
+ and `q` or Esc quits. A song skips when 30% of listeners vote.
247
+ - Sound needs ffmpeg and ffplay. Without them you get the visuals and no sound.
248
+ On macOS the sound goes straight to CoreAudio.
249
+ - The station lives on the hosted server. `accelr8 serve` does not run one.
250
+ - Diagnostics go to `~/.accelr8/radio.log`.
251
+
252
+ ## Self-hosting
253
+
254
+ By default accelr8 talks to the hosted server, a Cloudflare Worker at
255
+ `wss://accelr8-canvas.patonchain.workers.dev`. You can run your own:
76
256
 
77
257
  ```bash
78
- accelr8 --server ws://localhost:8787 # or export ACCELR8_SERVER=...
258
+ accelr8 serve # sync server on port 8787
259
+ accelr8 serve --port 9000 # another port
79
260
  ```
80
261
 
81
- ### Self-hosting
262
+ Then point accelr8 at it:
82
263
 
83
264
  ```bash
84
- accelr8 serve # starts a sync server on :8787
85
- accelr8 serve --port 9000 # custom port
265
+ accelr8 --server ws://localhost:8787
266
+ ACCELR8_SERVER=ws://localhost:8787 accelr8
86
267
  ```
87
268
 
88
- Expose it beyond your machine with a quick tunnel:
269
+ To let friends in from outside your network, put a tunnel in front of it, for
270
+ example:
89
271
 
90
272
  ```bash
91
273
  cloudflared tunnel --url http://localhost:8787
92
- # friends then run: accelr8 --server wss://something.trycloudflare.com
274
+ # friends run: accelr8 --server wss://<your-tunnel>.trycloudflare.com
93
275
  ```
94
276
 
95
- Deploy your own copy of the hosted worker:
277
+ - `accelr8 serve` keeps every project, its canvas and its chat (the last 2,000
278
+ messages) in `~/.accelr8/server-data.json`.
279
+ - Chat, canvas, agents and voice all work on it. The radio does not.
280
+ - Everyone connected to a server sees every project on it, with its join code.
281
+ - Clients and the server must speak the same protocol version (3 today; the
282
+ changelog says when it changes). A client that does not match is told it is
283
+ outdated and quits, even when the server is the older one.
284
+ - `worker/` is the hosted server: a Durable Object around the same room logic as
285
+ `accelr8 serve`, plus the radio station. To run your own copy, create the
286
+ R2 bucket named in `worker/wrangler.jsonc` on your Cloudflare account, then
287
+ run `npx wrangler@<x.y.z> deploy` in `worker/`, with an exact wrangler
288
+ version. A copy's radio still streams from the hosted server: the playlist
289
+ in `worker/src/worker.ts` builds every track URL from `A`, the hosted
290
+ server's `/audio` address, and your bucket goes unused. To play your own
291
+ music, upload the tracks to your bucket and point `A` at your worker's
292
+ `/audio`. The music is not in this repository.
96
293
 
97
- ```bash
98
- cd worker && npx wrangler deploy
99
- ```
294
+ ## Files
295
+
296
+ Everything accelr8 keeps lives in `~/.accelr8/`.
297
+
298
+ | File | What it holds |
299
+ |---|---|
300
+ | `identity.json` | Your id and display name. |
301
+ | `settings.json` | Theme, top nav and notifications. |
302
+ | `accounts.json` | Your AI accounts and their keys. Only you can read it. |
303
+ | `agent-tokens.json` | Proof that you own your agents in each project. |
304
+ | `update-check.json` | The last npm version check. |
305
+ | `voice.log`, `radio.log` | Diagnostics. They grow until you delete them. |
306
+ | `server-data.json` | Projects, canvases and chat, written by `accelr8 serve`. |
307
+
308
+ ## Limits today
309
+
310
+ - No sign-in yet. Your id and name are made on your machine and servers do not
311
+ verify them, so agent access settings are not a security boundary.
312
+ - Every project on a server is listed, with its code, for everyone connected to
313
+ it. Keep secrets out of chat.
314
+ - Agents only chat, and only while their owner has the project open.
315
+ - The Secrets tab is a placeholder.
316
+ - Voice has no echo cancellation and sends uncompressed audio.
100
317
 
101
318
  ## Development
102
319
 
320
+ From a checkout of this repository:
321
+
103
322
  ```bash
104
- npm install
105
- npm run dev # run the TUI from source
106
- npm run serve # run the sync server from source
107
- npm run smoketest # headless two-client sync test (needs a server)
108
- npm run rendertest # headless frame dumps of every screen
109
- npm run build # bundle dist/cli.js
323
+ npm ci
324
+ npm run dev # run the app from source
325
+ npm run serve # run the sync server from source
326
+ npm run typecheck # src/, tools/ and worker/
327
+ npm test # 34 suites and a render pass, no network
328
+ npm run teste2e # 6 suites, each on its own local server
329
+ npm run build # bundle into dist/
110
330
  ```
111
331
 
112
- Layout:
332
+ - Run the tests with a throwaway HOME, for example `HOME=$(mktemp -d) npm test`.
333
+ When ffmpeg is installed, the voice test plays a half-second tone through
334
+ ffplay and writes `~/.accelr8/voice.log`.
335
+ - `npm run teste2e` needs a server first. Start one with a throwaway HOME so
336
+ test projects stay out of your real data: `HOME=$(mktemp -d) npm run serve`.
337
+ - `.github/workflows/ci.yml` is the CI job: all of the above on Node 22, plus an
338
+ audit and a check of what goes into the npm package.
339
+ - `docs/RELEASE.md` is how to cut a release. `CHANGELOG.md` is the history.
340
+ `docs/DESIGN.md` is the design bible. Much of it is not built yet.
113
341
 
114
- - `src/protocol.ts` shared wire types + constants (fixed 100×30 logical canvas)
115
- - `src/cli.ts` entry point, arg parsing
116
- - `src/client.ts` the TUI: mouse/keyboard, flicker-free rendering, cursor lerp
117
- - `src/server.ts` self-host sync server (Node, `ws`)
118
- - `worker/` hosted sync server (Cloudflare Worker + Durable Object)
342
+ | Path | What lives there |
343
+ |---|---|
344
+ | `src/cli.ts` | Entry point and argument parsing. |
345
+ | `src/client.ts` | The app: rendering, mouse and keys, chat, canvas, voice wiring. |
346
+ | `src/protocol.ts` | Wire types, the protocol version and limits. |
347
+ | `src/room.ts` | RoomCore: all room behavior, shared by both servers. |
348
+ | `src/server.ts` | `accelr8 serve`, on Node and `ws`. |
349
+ | `worker/` | The hosted server: a Cloudflare Worker and its Durable Objects. |
350
+ | `src/executor.ts`, `src/accounts.ts` | Agents: running them and storing accounts. |
351
+ | `src/voice.ts` | Voice capture and playback through ffmpeg. |
352
+ | `src/radio/` | ACCELR8 radio. |
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ AuthLockTimeout,
4
+ DEFAULT_MAX_CALLS_PER_HOUR,
5
+ DEFAULT_MAX_CALLS_PER_REQUESTER_HOUR,
6
+ DEFAULT_MAX_OUTPUT_TOKENS,
7
+ DEFAULT_MODEL,
8
+ HANDLE_RE,
9
+ addAccount,
10
+ credentialsKey,
11
+ defaultHandle,
12
+ deleteCredentials,
13
+ detectClaudeCode,
14
+ detectEnvKeys,
15
+ getToken,
16
+ listCredentials,
17
+ loadAccounts,
18
+ loadCredentials,
19
+ loadLegacyIdentity,
20
+ loadTokens,
21
+ redact,
22
+ removeAccount,
23
+ saveAccounts,
24
+ saveCredentials,
25
+ saveToken,
26
+ withAuthLock
27
+ } from "./chunk-FVC2UPMV.js";
28
+ import "./chunk-62O2F73J.js";
29
+ export {
30
+ AuthLockTimeout,
31
+ DEFAULT_MAX_CALLS_PER_HOUR,
32
+ DEFAULT_MAX_CALLS_PER_REQUESTER_HOUR,
33
+ DEFAULT_MAX_OUTPUT_TOKENS,
34
+ DEFAULT_MODEL,
35
+ HANDLE_RE,
36
+ addAccount,
37
+ credentialsKey,
38
+ defaultHandle,
39
+ deleteCredentials,
40
+ detectClaudeCode,
41
+ detectEnvKeys,
42
+ getToken,
43
+ listCredentials,
44
+ loadAccounts,
45
+ loadCredentials,
46
+ loadLegacyIdentity,
47
+ loadTokens,
48
+ redact,
49
+ removeAccount,
50
+ saveAccounts,
51
+ saveCredentials,
52
+ saveToken,
53
+ withAuthLock
54
+ };
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ verifyAccount
4
+ } from "./chunk-NRXIFJGR.js";
2
5
  import {
3
6
  DEFAULT_MODEL,
4
7
  addAccount,
@@ -6,9 +9,9 @@ import {
6
9
  detectClaudeCode,
7
10
  detectEnvKeys,
8
11
  loadAccounts,
9
- removeAccount,
10
- verifyAccount
11
- } from "./chunk-3JNUWI22.js";
12
+ removeAccount
13
+ } from "./chunk-FVC2UPMV.js";
14
+ import "./chunk-62O2F73J.js";
12
15
 
13
16
  // src/agentcli.ts
14
17
  import { createInterface } from "node:readline";