routstrd 0.4.7 → 0.4.9

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
@@ -19,16 +19,29 @@ For team-based routing, see [routstrd-auth](https://github.com/Routstr/routstrd-
19
19
 
20
20
  ## Requirements
21
21
 
22
- - [Bun](https://bun.sh) runtime
23
-
24
- ```sh
25
- curl -fsSL https://bun.com/install | bash
26
- ```
22
+ The standalone release does not require Bun, Node.js, or npm. Installing from
23
+ npm or running from source requires the [Bun](https://bun.sh) runtime.
27
24
 
28
25
  ## Installation
29
26
 
30
27
  ### Step 1: Install
31
28
 
29
+ **Standalone binary:**
30
+
31
+ Download the archive for your operating system and architecture from the
32
+ [latest GitHub Release](https://github.com/Routstr/routstrd/releases/latest).
33
+ Release archives are available for Linux and macOS on x64 and arm64.
34
+
35
+ ```sh
36
+ grep "routstrd-v0.4.9-linux-x64.tar.gz" SHA256SUMS | shasum -a 256 -c -
37
+ tar -xzf routstrd-v0.4.9-linux-x64.tar.gz
38
+ mkdir -p "$HOME/.local/bin"
39
+ install -m 755 routstrd "$HOME/.local/bin/routstrd"
40
+ ```
41
+
42
+ Substitute the version, platform, and architecture for the archive you
43
+ downloaded, and ensure `$HOME/.local/bin` is on `PATH`.
44
+
32
45
  **Global with bun:**
33
46
  ```sh
34
47
  bun i -g routstrd
@@ -103,6 +116,17 @@ Test connection:
103
116
  routstrd ping
104
117
  ```
105
118
 
119
+ Refresh models and client integrations on demand:
120
+ ```sh
121
+ routstrd clients --manual-refresh # same as `routstrd refresh`
122
+ ```
123
+
124
+ Turn the daemon's scheduled refresh on or off (no restart needed):
125
+ ```sh
126
+ routstrd clients --disable-automatic-refresh
127
+ routstrd clients --enable-automatic-refresh
128
+ ```
129
+
106
130
  Stop the daemon:
107
131
  ```sh
108
132
  routstrd stop
@@ -139,6 +163,20 @@ The daemon exposes an HTTP server (default port 8008) with the following endpoin
139
163
  GET /health
140
164
  ```
141
165
 
166
+ #### Automatic Refresh Settings
167
+ ```
168
+ POST /settings/auto-refresh
169
+ ```
170
+
171
+ Request body:
172
+ ```json
173
+ { "enabled": false }
174
+ ```
175
+
176
+ Enables or disables the scheduled refresh job. Persisted to the daemon's
177
+ `config.json` as `autoRefresh.enabled` and picked up on the next tick, so no
178
+ daemon restart is required.
179
+
142
180
  #### Route Request
143
181
  ```
144
182
  POST /
@@ -186,10 +224,18 @@ Configuration is stored in `~/.routstrd/config.json`:
186
224
  "port": 8008,
187
225
  "host": "127.0.0.1",
188
226
  "provider": null,
189
- "cocodPath": null
227
+ "cocodPath": null,
228
+ "autoRefresh": { "enabled": true }
190
229
  }
191
230
  ```
192
231
 
232
+ `autoRefresh.enabled` (default `true`) controls the daemon's scheduled refresh
233
+ job, which re-fetches Nostr events, routstr21 models, and client integrations
234
+ every 21 minutes. Set it to `false` (or run
235
+ `routstrd clients --disable-automatic-refresh`) to turn the schedule off and
236
+ refresh manually with `routstrd clients --manual-refresh`. `autoRefresh.intervalMs`
237
+ overrides the 21-minute interval.
238
+
193
239
  ### Environment Variables
194
240
 
195
241
  - `ROUTSTRD_DIR` - Config directory (default: `~/.routstrd`)
@@ -213,6 +259,33 @@ Run daemon:
213
259
  bun run start
214
260
  ```
215
261
 
262
+ Build a standalone executable for the current platform:
263
+
264
+ ```sh
265
+ bun run build:binary
266
+ ./dist/routstrd --version
267
+ ```
268
+
269
+ Standalone installations update directly from GitHub Releases with
270
+ `routstrd update`. npm installations continue to update through Bun. PM2 is an
271
+ optional external dependency used only by `routstrd service`; normal daemon
272
+ operation does not require it.
273
+
274
+ When an update finds a process on the configured daemon port, it only stops that
275
+ process if the wallet PID file confirms a live daemon owned by the same routstrd
276
+ configuration. Otherwise the update remains installed, but automatic restart is
277
+ refused so an unrelated daemon is not interrupted.
278
+
279
+ Existing PM2 registrations created by routstrd 0.4.x continue to work through a
280
+ compatibility daemon entrypoint. Recreate the registration to use the unified
281
+ CLI entrypoint and remove its legacy path dependency:
282
+
283
+ ```sh
284
+ routstrd service uninstall
285
+ routstrd service install
286
+ pm2 save
287
+ ```
288
+
216
289
  Typecheck:
217
290
  ```sh
218
291
  bun run lint
@@ -232,6 +305,23 @@ Set `ROUTSTRD_BASE_URL` to test a daemon at a different address. The script
232
305
  makes live provider requests that may spend wallet funds, so it is intentionally
233
306
  not part of `bun test`.
234
307
 
308
+ ### Publishing a standalone release
309
+
310
+ 1. Set a new `package.json` version and commit it. The release tag must be the
311
+ same version prefixed with `v`, and the tag must not already exist.
312
+ 2. Push the tag. The release workflow runs lint and tests, builds Linux and
313
+ macOS executables for x64 and arm64, smoke-tests them, and publishes the
314
+ archives with `SHA256SUMS`.
315
+ 3. Verify all four archives appear in the GitHub Release and validate each
316
+ checksum before announcing it.
317
+ 4. In disposable environments for each platform, test `--version`, `--help`,
318
+ foreground startup failure, and background `start`, `status`, and `stop`
319
+ without Bun on `PATH`.
320
+ 5. Test `routstrd service install` and restart behavior with PM2 in a disposable
321
+ environment. Never run release/update lifecycle tests against a production
322
+ daemon. When isolation is needed, use both a separate `ROUTSTRD_DIR` and a
323
+ non-production port in that configuration.
324
+
235
325
  ## Project Structure
236
326
 
237
327
  ```
package/SKILL.md ADDED
@@ -0,0 +1,341 @@
1
+ # routstrd CLI Reference
2
+
3
+ Routstr daemon — a Bun-based CLI tool that runs a background HTTP server for the Routstr protocol. It integrates with `cocod` for Cashu wallet management and routes LLM requests to available providers.
4
+
5
+ ## Quick Start
6
+
7
+ ```sh
8
+ routstrd onboard # Initialize (creates config, sets up cocod)
9
+ routstrd start # Start the daemon
10
+ routstrd stop # Stop the daemon
11
+ ```
12
+
13
+ After onboarding, the daemon listens at `http://localhost:8008` and exposes an OpenAI-compatible API.
14
+
15
+ ## Commands
16
+
17
+ ### `routstrd onboard`
18
+
19
+ Initialize routstrd for the first time:
20
+ - Creates `~/.routstrd/` config directory
21
+ - Creates `~/.routstrd/config.json` with defaults (port 8008, apikeys mode)
22
+ - Installs `cocod` globally via bun if not present
23
+ - Runs `cocod init` to set up the wallet
24
+ - Starts the daemon and configures integrations
25
+
26
+ ### `routstrd start`
27
+
28
+ Start the background daemon process.
29
+
30
+ | Option | Description |
31
+ |--------|-------------|
32
+ | `--port <port>` | Port to listen on (default: 8008) |
33
+ | `-p, --provider <provider>` | Default provider to use |
34
+
35
+ ### `routstrd stop`
36
+
37
+ Stop the background daemon.
38
+
39
+ ### `routstrd restart`
40
+
41
+ Restart the daemon (stops if running, then starts).
42
+
43
+ | Option | Description |
44
+ |--------|-------------|
45
+ | `--port <port>` | Port to listen on |
46
+ | `-p, --provider <provider>` | Default provider to use |
47
+
48
+ ### `routstrd status`
49
+
50
+ Check daemon and wallet status. Returns JSON with current state.
51
+
52
+ ### `routstrd balance`
53
+
54
+ Get wallet and API key balances. Shows per-mint wallet balances, per-key API balances, and a grand total (all in sats).
55
+
56
+ ### `routstrd models`
57
+
58
+ List available routstr21 models (discovered via Nostr).
59
+
60
+ | Option | Description |
61
+ |--------|-------------|
62
+ | `-r, --refresh` | Force refresh models from Nostr |
63
+
64
+ ### `routstrd usage`
65
+
66
+ Show recent usage logs and total sats cost.
67
+
68
+ | Option | Default | Description |
69
+ |--------|---------|-------------|
70
+ | `-n, --limit <number>` | 10 | Number of recent entries (max 1000) |
71
+
72
+ Shows timestamp, model, provider, sats cost, token counts, and request ID for each entry.
73
+
74
+ ### `routstrd providers`
75
+
76
+ List and manage providers (subcommand required).
77
+
78
+ #### `routstrd providers list`
79
+
80
+ List all providers with their enabled/disabled status. Shows index, status, and base URL.
81
+
82
+ ```
83
+ Providers (12 total, 2 disabled):
84
+
85
+ [0] enabled https://provider1.example.com
86
+ [1] enabled https://provider2.example.com
87
+ [2] DISABLED https://provider3.example.com
88
+ ```
89
+
90
+ #### `routstrd providers disable <indices...>`
91
+
92
+ Disable providers by their index numbers.
93
+
94
+ ```sh
95
+ routstrd providers disable 0 2 5
96
+ ```
97
+
98
+ #### `routstrd providers enable <indices...>`
99
+
100
+ Enable providers by their index numbers.
101
+
102
+ ```sh
103
+ routstrd providers enable 0 2 5
104
+ ```
105
+
106
+ ### `routstrd clients`
107
+
108
+ List and manage API clients (subcommand required).
109
+
110
+ | Option | Description |
111
+ |--------|-------------|
112
+ | `--manual-refresh` | Refresh routstr21 models and all client integrations now |
113
+ | `--disable-automatic-refresh` | Disable the daemon's scheduled refresh job |
114
+ | `--enable-automatic-refresh` | Re-enable the daemon's scheduled refresh job |
115
+
116
+ The daemon refreshes models and client integrations on a schedule (every 21 minutes by default). Use `--manual-refresh` to do it on demand, and `--disable-automatic-refresh` to stop the scheduled job — the setting is stored in the daemon's `config.json` (`autoRefresh.enabled`) and takes effect without a restart.
117
+
118
+ ```sh
119
+ routstrd clients --manual-refresh # refresh models + integrations now
120
+ routstrd clients --disable-automatic-refresh # no scheduled refresh
121
+ routstrd clients --enable-automatic-refresh # scheduled refresh back on
122
+ ```
123
+
124
+ #### `routstrd clients list`
125
+
126
+ List all registered clients with their ID, name, API key, and creation date.
127
+
128
+
129
+ #### `routstrd clients add`
130
+
131
+ Add a new client or set up a client integration.
132
+
133
+ | Option | Description |
134
+ |--------|-------------|
135
+ | `-n, --name <name>` | Client name (required when not using integration flags) |
136
+ | `--opencode` | Set up OpenCode integration |
137
+ | `--openclaw` | Set up OpenClaw integration |
138
+ | `--pi-agent` | Set up Pi Agent integration |
139
+ | `--claude-code` | Set up Claude Code integration |
140
+
141
+ ```sh
142
+ routstrd clients add --opencode --pi-agent --claude-code # multiple integrations
143
+ routstrd clients add -n "My App" # generic client
144
+ ```
145
+
146
+ Returns the client ID and API key for use with the OpenAI-compatible API.
147
+
148
+ #### `routstrd clients delete <id>`
149
+
150
+ Delete a registered client by its ID.
151
+
152
+ ### `routstrd npubs`
153
+
154
+ Manage registered npubs and their roles/names (subcommand required). Management commands route through the auth proxy (`--auth-url`) and use NIP-98 auth.
155
+
156
+ | Command | Description |
157
+ |---------|-------------|
158
+ | `routstrd npubs list` | List registered npubs with role and display name |
159
+ | `routstrd npubs register [--name <name>]` | Register yourself as the first admin (bootstrap only) |
160
+ | `routstrd npubs add <npub> [--role <role>] [--name <name>]` | Add an npub (accepts hex or npub1...) |
161
+ | `routstrd npubs update <npub> [--role <role>] [--name <name>]` | Update role and/or name (admin only) |
162
+ | `routstrd npubs delete <npub>` | Delete an npub |
163
+
164
+ ### `routstrd remote <url>`
165
+
166
+ Configure a remote daemon URL. Generates a Nostr identity (nsec/npub) for NIP-98 authentication automatically.
167
+
168
+ ```sh
169
+ routstrd remote https://your-remote-daemon.com
170
+ ```
171
+
172
+ ### `routstrd refresh`
173
+
174
+ Refresh routstr21 models from Nostr and re-run integrations for all registered clients. Equivalent to `routstrd clients --manual-refresh`.
175
+
176
+ | Field | Type | Default | Description |
177
+ |-------|------|---------|-------------|
178
+ | `port` | number | 8008 | Daemon HTTP port |
179
+ | `provider` | string\|null | null | Default provider URL |
180
+ | `daemonUrl` | string\|null | null | Remote daemon URL |
181
+ | `nsec` | string\|null | null | Nostr secret key for NIP-98 auth |
182
+ | `cocodPath` | string\|null | null | Custom path to cocod executable |
183
+ | `mode` | string | `"apikeys"` | Client mode (`apikeys` or `xcashu`) |
184
+ | `autoRefresh` | object | `{ enabled: true }` | Scheduled refresh job settings (`enabled`, `intervalMs`) |
185
+
186
+ | Variable | Default | Description |
187
+ |----------|---------|-------------|
188
+ | `ROUTSTRD_DIR` | `~/.routstrd` | Config directory |
189
+ | `ROUTSTRD_WALLET_DIR` | `~/.routstrd/wallet` | In-process Cashu wallet data directory |
190
+ | `ROUTSTRD_WALLET_PID` | `<wallet>/wallet.pid` | In-process wallet lock path |
191
+ | `COCOD_DIR` | `~/.cocod` | Legacy external cocod compatibility directory |
192
+
193
+ ### `routstrd mode`
194
+
195
+ Interactive prompt to set the client mode:
196
+ 1. **lazyrefund/apikeys** (default) — Pseudonymous accounts kept with Routstr nodes, refunded after 5 mins if unused.
197
+ 2. **xcashu** (coming soon) — Balances never kept with nodes, all refunded in response.
198
+
199
+ Changing mode restarts the daemon automatically.
200
+
201
+ ### `routstrd monitor`
202
+
203
+ Open an interactive TUI (htop-like) for usage monitoring.
204
+
205
+ ### `routstrd logs`
206
+
207
+ View daemon logs.
208
+
209
+ | Option | Default | Description |
210
+ |--------|---------|-------------|
211
+ | `-f, --follow` | false | Follow log output (like `tail -f`) |
212
+ | `-c, --coco` | false | Show Cashu wallet-engine (coco) logs instead of daemon logs |
213
+ | `-n, --lines <number>` | 50 | Number of lines to show |
214
+
215
+ Log files are stored at `~/.routstrd/logs/YYYY-MM-DD.log`. Wallet-engine (Cashu/coco) diagnostics go to a separate `~/.routstrd/coco-logs/YYYY-MM-DD.log` so they don't pollute the main daemon logs.
216
+
217
+ ## Wallet Commands
218
+
219
+ New wallets automatically trust `https://mint.cubabitcoin.org` as their default mint. The default is used when a wallet command does not include `--mint-url`.
220
+
221
+ ### `routstrd wallet status`
222
+
223
+ Check wallet status.
224
+
225
+ ### `routstrd wallet unlock <passphrase>`
226
+
227
+ Unlock the wallet with a passphrase.
228
+
229
+ ### `routstrd wallet balance`
230
+
231
+ Get wallet balance.
232
+
233
+ ### `routstrd wallet receive cashu <token>`
234
+
235
+ Receive funds via a Cashu token.
236
+
237
+ ### `routstrd wallet receive bolt11 <amount>`
238
+
239
+ Create a Lightning invoice to receive funds. Displays a QR code.
240
+
241
+ | Option | Description |
242
+ |--------|-------------|
243
+ | `--mint-url <url>` | Mint URL to use |
244
+
245
+ ### `routstrd wallet send cashu <amount>`
246
+
247
+ Create a Cashu token to send.
248
+
249
+ | Option | Description |
250
+ |--------|-------------|
251
+ | `--mint-url <url>` | Mint URL to use |
252
+
253
+ ### `routstrd wallet send bolt11 <invoice>`
254
+
255
+ Pay a Lightning invoice.
256
+
257
+ | Option | Description |
258
+ |--------|-------------|
259
+ | `--mint-url <url>` | Mint URL to use |
260
+
261
+ ### `routstrd wallet mints list`
262
+
263
+ List configured wallet mints.
264
+
265
+ ### `routstrd wallet mints add <url>`
266
+
267
+ Add a new mint by URL.
268
+
269
+ ### `routstrd wallet mints set-default <url>`
270
+
271
+ Set the persistent default mint. If necessary, the mint is added as trusted first.
272
+
273
+ ### `routstrd wallet mints info <url>`
274
+
275
+ Get info about a specific mint.
276
+
277
+ ## Daemon API
278
+
279
+ The daemon exposes an OpenAI-compatible HTTP API at `http://localhost:8008`:
280
+
281
+ ### `GET /health`
282
+
283
+ Health check endpoint.
284
+
285
+ ### `GET /v1/models`
286
+
287
+ List available models (OpenAI-compatible).
288
+
289
+ ### `POST /v1/chat/completions`
290
+
291
+ Route a chat completion request.
292
+
293
+ ```json
294
+ {
295
+ "model": "model-id",
296
+ "messages": [{ "role": "user", "content": "Hello" }],
297
+ "stream": false
298
+ }
299
+ ```
300
+
301
+ ## Configuration
302
+
303
+ Config file: `~/.routstrd/config.json`
304
+
305
+ | Field | Type | Default | Description |
306
+ |-------|------|---------|-------------|
307
+ | `port` | number | 8008 | Daemon HTTP port |
308
+ | `provider` | string\|null | null | Default provider URL |
309
+ | `cocodPath` | string\|null | null | Custom path to cocod executable |
310
+ | `mode` | string | `"apikeys"` | Client mode (`apikeys` or `xcashu`) |
311
+ | `autoRefresh` | object | `{ enabled: true }` | Scheduled refresh job settings (`enabled`, `intervalMs`) |
312
+
313
+ ### Environment Variables
314
+
315
+ | Variable | Default | Description |
316
+ |----------|---------|-------------|
317
+ | `ROUTSTRD_DIR` | `~/.routstrd` | Config directory |
318
+ | `ROUTSTRD_SOCKET` | `~/.routstrd/routstrd.sock` | IPC socket path |
319
+ | `ROUTSTRD_PID` | `~/.routstrd/routstrd.pid` | PID file path |
320
+
321
+ ## Remote Mode
322
+
323
+ When `daemonUrl` is configured, commands connect to a remote daemon instead of a local one:
324
+ - Client names are suffixed with the last 7 chars of your npub
325
+ - All requests are automatically NIP-98 signed using your local nsec
326
+ - Local-only commands (`onboard`, `start`, `restart`, `mode`, `logs`, `service`) are disabled
327
+
328
+ ## Pi Integration
329
+
330
+ When `routstrd onboard` runs, it automatically configures a `routstr` provider in `pi`'s `models.json` with an OpenAI-compatible base URL and API key. This allows pi (the AI coding agent) to use Routstr providers seamlessly.
331
+
332
+ ## File Locations
333
+
334
+ | Path | Description |
335
+ |------|-------------|
336
+ | `~/.routstrd/config.json` | Configuration |
337
+ | `~/.routstrd/routstr.db` | SQLite database |
338
+ | `~/.routstrd/routstrd.sock` | IPC socket |
339
+ | `~/.routstrd/routstrd.pid` | PID file |
340
+ | `~/.routstrd/logs/YYYY-MM-DD.log` | Daily daemon log files |
341
+ | `~/.routstrd/coco-logs/YYYY-MM-DD.log` | Daily Cashu wallet-engine (coco) log files |