@dinglebear/labby 1.13.3 → 1.19.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/README.md CHANGED
@@ -52,13 +52,11 @@ Labby is centered on the current gateway/operator surface:
52
52
  feature-matrix artifacts under
53
53
  [docs/generated](./docs/generated/README.md).
54
54
 
55
- The registered services on this branch are exactly `doctor`, `fs`, `gateway`,
56
- `lab_admin`, `server_logs`, `setup`, and `snippets`. The older
57
- `marketplace`/`stash`/`acp`/`nodes`/`deploy`/`logs`/`device` product services
58
- were removed by the "Slim labby gateway host" pass; their domain types survive
59
- in `labby-runtime`/`labby-apis` but are no longer registered services and have
60
- no CLI commands. Use the generated catalogs below for the current surface
61
- instead of copying command or action lists by hand.
55
+ Use the generated service, action, and CLI catalogs below for the complete
56
+ current product surface instead of copying inventories into hand-written
57
+ documentation. Standalone ACP chat, Marketplace/MCP Registry browser, Fleet,
58
+ Deploy, and Stash products remain retired; bounded provider-backed discovery
59
+ through the `artifacts` control-plane service does not restore those products.
62
60
 
63
61
  ## Quick Start
64
62
 
@@ -92,7 +90,17 @@ the [stdio MCP proxy guide](./docs/guides/STDIO_MCP_PROXY.md).
92
90
  Linux/macOS:
93
91
 
94
92
  ```bash
95
- curl -fsSL https://raw.githubusercontent.com/dinglebear-ai/labby/main/scripts/install.sh | sh
93
+ version=vX.Y.Z
94
+ base="https://github.com/dinglebear-ai/labby/releases/download/$version"
95
+ curl -fSLO "$base/labby-install.sh"
96
+ curl -fSLO "$base/labby-install.sh.sha256"
97
+ gh attestation verify labby-install.sh \
98
+ --repo dinglebear-ai/labby \
99
+ --signer-workflow dinglebear-ai/labby/.github/workflows/release.yml \
100
+ --source-ref "refs/tags/$version" \
101
+ --deny-self-hosted-runners
102
+ shasum -a 256 -c labby-install.sh.sha256
103
+ LABBY_INSTALL_VERSION="$version" sh ./labby-install.sh
96
104
  labby setup
97
105
  labby serve --host 127.0.0.1 --port 8765
98
106
  ```
@@ -106,19 +114,94 @@ npx -y @dinglebear/labby mcp
106
114
  Windows PowerShell:
107
115
 
108
116
  ```powershell
109
- irm https://raw.githubusercontent.com/dinglebear-ai/labby/main/scripts/install.ps1 | iex
117
+ $Version = "vX.Y.Z"
118
+ $Base = "https://github.com/dinglebear-ai/labby/releases/download/$Version"
119
+ Invoke-WebRequest "$Base/labby-install.ps1" -OutFile labby-install.ps1
120
+ Invoke-WebRequest "$Base/labby-install.ps1.sha256" -OutFile labby-install.ps1.sha256
121
+ gh attestation verify labby-install.ps1 `
122
+ --repo dinglebear-ai/labby `
123
+ --signer-workflow dinglebear-ai/labby/.github/workflows/release.yml `
124
+ --source-ref "refs/tags/$Version" `
125
+ --deny-self-hosted-runners
126
+ $Expected = ((Get-Content labby-install.ps1.sha256) -split '\s+')[0]
127
+ if ((Get-FileHash labby-install.ps1 -Algorithm SHA256).Hash.ToLower() -ne $Expected) { throw "installer digest mismatch" }
128
+ $env:LABBY_INSTALL_VERSION = $Version
129
+ & ./labby-install.ps1
110
130
  labby setup
111
131
  labby serve --host 127.0.0.1 --port 8765
112
132
  ```
113
133
 
114
- The install scripts download the requested GitHub Release asset, verify its
115
- checksum, and install `labby` onto the user PATH. They do **not** perform
134
+ The separately downloaded and attested install scripts resolve an immutable GitHub Release containing the current
135
+ platform asset, require `gh`, verify the archive's attestation against the
136
+ Labby repository, `release.yml`, exact tag, and hosted-runner policy, verify its checksum, and install `labby` onto the
137
+ user PATH. They do **not** perform
116
138
  operator provisioning or environment setup. The scripts only install the binary
117
139
  (from a release or fallback source build); all first-run provisioning is handled
118
140
  inside `labby` via `labby serve` bootstrap and `labby setup`.
119
141
 
120
142
  Override install behavior with `LABBY_INSTALL_DIR`, `LABBY_INSTALL_VERSION`, or
121
- `LABBY_INSTALL_REPO`.
143
+ `LABBY_INSTALL_REPO`. Source fallback is off by default. Opt in with
144
+ `LABBY_ALLOW_SOURCE_FALLBACK=1`; a pinned `LABBY_INSTALL_VERSION` is passed to
145
+ Cargo as the exact tag instead of silently building the default branch.
146
+
147
+ Each successful install retains the verified binary by SHA-256 plus an
148
+ owner-only receipt beneath `<install-dir>/.labby-install/`. At least the prior
149
+ verified artifact remains available when distribution is unavailable. Restore
150
+ it without downloading or changing `$LABBY_HOME`:
151
+
152
+ ```bash
153
+ LABBY_INSTALL_ROLLBACK=1 sh ./labby-install.sh
154
+ ```
155
+
156
+ ```powershell
157
+ $env:LABBY_INSTALL_ROLLBACK = '1'
158
+ & .\labby-install.ps1
159
+ ```
160
+
161
+ Rollback switches only the installed executable and receipt. It does not
162
+ downgrade or delete configuration, credentials, databases, or other durable
163
+ state. Inspect the receipt at `<install-dir>/.labby-install/receipt` on Unix or
164
+ `receipt.json` on Windows.
165
+
166
+ Release qualification can install an already-downloaded candidate without
167
+ network or source fallback by setting `LABBY_INSTALL_LOCAL_BINARY` and its exact
168
+ lowercase `LABBY_INSTALL_LOCAL_SHA256`. The installer copies that input once to
169
+ private staging, verifies the staged bytes, and activates those same bytes. It
170
+ also rehashes every existing cached artifact before reuse. Before changing the
171
+ binary or either receipt, the installer writes a recovery journal beneath
172
+ `.labby-install/`; a later invocation restores the complete pre-install
173
+ snapshot when it finds an interrupted activation. If restoration fails, the
174
+ installer stops and retains the journal for diagnosis.
175
+ All Unix installer entry points share a process-level transaction lock and
176
+ flush journal boundaries before advancing them. Successful activation retains
177
+ only the current artifact and the immediately previous artifact required for
178
+ offline rollback.
179
+
180
+ ### Automatic updates on macOS
181
+
182
+ For a persistent macOS server, enable daily updates in the existing server job:
183
+
184
+ ```bash
185
+ LABBY_SERVICE_AUTO_UPDATE=1 bash scripts/install-macos-service.sh install
186
+ ```
187
+
188
+ This runs `labby serve --auto-update` under launchd and removes the separate
189
+ updater job after the server passes its health check. See the
190
+ [macOS setup instructions](docs/services/SETUP.md#macos-server-and-automatic-updates).
191
+
192
+ For an installation without a persistent server, use the standalone daily job:
193
+
194
+ ```bash
195
+ labby update --auto-update enable
196
+ labby update --auto-update status
197
+ labby update --auto-update disable
198
+ ```
199
+
200
+ Both modes require Apple Silicon and GitHub CLI (`gh`) for release attestation
201
+ verification. They skip drafts, prereleases, missing platform assets, and versions
202
+ equal to or older than the installed binary. The installer verifies attestations
203
+ and checksums before atomic replacement. No separate language runtime is required.
204
+ Use `labby update --automatic --dry-run` to check without installing.
122
205
 
123
206
  ### Build From Source
124
207
 
@@ -152,14 +235,21 @@ just macos-service-status
152
235
  ```
153
236
 
154
237
  This installs a `launchd` LaunchAgent that keeps Labby listening on
155
- `127.0.0.1:8765`, restarts it after login or exit, and writes logs under
156
- `~/.labby/`. Use `just macos-service-restart` after changing service settings
238
+ `127.0.0.1:8765`, restarts it after login or exit, and uses the stable absolute
239
+ `LABBY_HOME` (default `~/.labby`) as both working directory and durable
240
+ configuration root. It never persists the directory from which installation
241
+ was invoked. Logs default to the same root. Use `just macos-service-restart`
242
+ after changing service settings
157
243
  or `just macos-service-uninstall` to remove it. The cross-platform
158
244
  `just service-install`, `just service-status`, `just service-restart`, and
159
245
  `just service-uninstall` bindings select launchd on macOS and systemd on
160
246
  Linux. This is suitable for a Tailscale Serve/Funnel route whose OAuth
161
247
  callback targets the local gateway.
162
248
 
249
+ When overriding the launchd paths, `LABBY_SERVICE_BIN`, `LABBY_STATE_DIR`, and
250
+ `LABBY_HOME` must all be absolute; relative paths fail before the plist or
251
+ service is changed.
252
+
163
253
  ### First Run
164
254
 
165
255
  For loopback development, `labby serve` can bootstrap a missing bearer token for
@@ -176,7 +266,7 @@ Bootstrap writes these required `setup` keys if no env exists yet:
176
266
  - `LABBY_MCP_HTTP_PORT=8765`
177
267
  - `LABBY_AUTH_MODE=bearer`
178
268
 
179
- It also enforces secure file creation via Lab's `env_merge` path (`0600` perms on
269
+ It also enforces secure file creation via Labby's `env_merge` path (`0600` perms on
180
270
  Unix) and then skips creating anything else until the web wizard runs.
181
271
 
182
272
  For explicit setup:
@@ -223,7 +313,13 @@ labby mcp
223
313
  `labby serve` starts the hosted HTTP runtime: `/v1` product APIs, `/mcp`
224
314
  streamable HTTP MCP, auth routes, OAuth relay endpoints, and static Labby web
225
315
  assets when an export is available. `labby mcp` is the stdio MCP entrypoint for
226
- local MCP clients.
316
+ local MCP clients. A client configured to launch `labby mcp` does not need an
317
+ HTTP URL: when a `labby serve` daemon is reachable, the stdio process becomes a
318
+ transparent bridge to that daemon and uses its gateway configuration, upstream
319
+ connections, and OAuth state. If no daemon is found and no explicit target is
320
+ set, it starts a standalone local gateway instead. See the
321
+ [local bridge guide](./docs/surfaces/TRANSPORT.md#local-bridge-to-the-running-daemon)
322
+ for client configuration and `LABBY_SERVER_URL` fail-closed behavior.
227
323
 
228
324
  ### Manage Upstream MCP Gateways
229
325
 
@@ -284,7 +380,7 @@ labby snippets test my-snippet
284
380
  ```
285
381
 
286
382
  Snippets are stored per-user under `$LABBY_HOME` and executed through the
287
- gateway Code Mode runner, so they can reach exposed upstream tools but not Lab
383
+ gateway Code Mode runner, so they can reach exposed upstream tools but not Labby
288
384
  actions. The `snippets` service is gateway-gated: it is unavailable in builds
289
385
  without the `gateway` feature.
290
386
 
@@ -311,7 +407,7 @@ severity found.
311
407
  > from source, manifests, packaging, and CI — not merely feature-gated.
312
408
  > `scripts/check-retired-features.sh` guards against reintroduction, and the
313
409
  > historical designs are archived under
314
- > [docs/references/retired-labby](./docs/references/retired-labby/). Plugin
410
+ > [docs/archive/retired-labby](./docs/archive/retired-labby/). Plugin
315
411
  > marketplace assets now live in the separate
316
412
  > [dendrite](https://github.com/dinglebear-ai/dendrite) repo.
317
413
 
@@ -362,17 +458,13 @@ Configuration is split deliberately:
362
458
 
363
459
  | Data | Location | Examples |
364
460
  | --- | --- | --- |
365
- | Secrets and endpoint values | `~/.labby/.env` | `LABBY_MCP_HTTP_TOKEN`, `LABBY_GOOGLE_CLIENT_SECRET`, upstream bearer token env values |
366
- | Preferences | `config.toml` | transport, CORS, auth mode, workspace root, gateway spawn guard, and upstream behavior |
367
-
368
- `config.toml` is searched in this order:
369
-
370
- 1. `./config.toml`
371
- 2. `~/.labby/config.toml`
372
- 3. `~/.config/labby/config.toml`
461
+ | Secrets and endpoint values | `$LABBY_HOME/.env` | `LABBY_MCP_HTTP_TOKEN`, `LABBY_GOOGLE_CLIENT_SECRET`, upstream bearer token env values |
462
+ | Preferences | `$LABBY_HOME/config.toml` | transport, CORS, auth mode, workspace root, gateway spawn guard, and upstream behavior |
373
463
 
374
- Startup loads the first `config.toml`, initializes tracing, then loads
375
- `~/.labby/.env` and a CWD `.env` if present. Runtime precedence is:
464
+ `LABBY_HOME` selects the one authoritative configuration and durable-state
465
+ root and must be absolute. It defaults to `~/.labby`; Labby does not implicitly
466
+ read CWD or XDG fallback files. Existing process environment values win over
467
+ values loaded from the selected `.env`. Runtime precedence is:
376
468
 
377
469
  1. CLI flags
378
470
  2. Environment variables
@@ -386,7 +478,9 @@ Useful environment variables:
386
478
  | `LABBY_MCP_HTTP_TOKEN` | Static bearer token for protected admin/API/MCP routes. |
387
479
  | `LABBY_AUTH_MODE` | `bearer` or `oauth`. |
388
480
  | `LABBY_PUBLIC_URL` | Public base URL for OAuth metadata, issuer/audience, callbacks, and allowed-host derivation. |
389
- | `LABBY_GOOGLE_CLIENT_ID` / `LABBY_GOOGLE_CLIENT_SECRET` | Google OAuth credentials for OAuth mode. |
481
+ | `LABBY_AUTH_PROVIDER` | Inbound OAuth identity provider: `google` (stable) or `authelia` (open beta). |
482
+ | `LABBY_GOOGLE_CLIENT_ID` / `LABBY_GOOGLE_CLIENT_SECRET` | Google credentials when Google is selected. |
483
+ | `LABBY_AUTHELIA_ISSUER_URL` / `LABBY_AUTHELIA_CLIENT_ID` / `LABBY_AUTHELIA_CLIENT_SECRET` | Authelia OIDC configuration; see the pinned registration contract in the OAuth guide. |
390
484
  | `LABBY_AUTH_ADMIN_EMAIL` | Bootstrap admin email; required in OAuth mode. |
391
485
  | `LABBY_OAUTH_ENCRYPTION_KEY` | Base64 32-byte key required for encrypted upstream OAuth credentials. Rotation requires reauthorizing affected upstreams. |
392
486
  | `LABBY_WEB_ASSETS_DIR` | Override static Labby export directory. |
@@ -396,8 +490,8 @@ Useful environment variables:
396
490
  | `LABBY_ACTOR_KEY_SECRET` | Stable secret for redacted actor correlation in logs. |
397
491
  | `LABBY_ADMIN_ENABLED` | Runtime opt-in for the `lab_admin` tool. |
398
492
 
399
- Bearer auth is an operator/admin shortcut for Lab routes. Public protected MCP
400
- routes validate route-scoped Lab OAuth JWTs; do not treat `LABBY_MCP_HTTP_TOKEN` as
493
+ Bearer auth is an operator/admin shortcut for Labby routes. Public protected MCP
494
+ routes validate route-scoped Labby OAuth JWTs; do not treat `LABBY_MCP_HTTP_TOKEN` as
401
495
  a public resource credential.
402
496
 
403
497
  When driving the web UI with automation while OAuth is enabled, pass the bearer
@@ -533,20 +627,28 @@ recommended agent gateway runtime.
533
627
 
534
628
  ### Dev Container
535
629
 
536
- The Compose stack is a trusted local operator environment, not a hardened
537
- generic deployment. It bind-mounts Labby state, the repository, and built web
538
- assets; secrets are loaded from the mounted `/home/labby/.labby/.env`. The image
539
- installs pinned Claude, Codex, and Gemini CLIs for stdio upstreams that invoke
540
- provider tools. It does not install ACP adapters or mount ACP-specific state.
630
+ The development Compose stack mirrors the production process controls: a
631
+ read-only root filesystem, dropped capabilities, `no-new-privileges`, loopback
632
+ port binding, bounded logs, and named volumes for durable state and data. It
633
+ also bind-mounts the source repository read-only so locally built web assets are
634
+ visible without rebuilding the image. The clean-checkout defaults mount the
635
+ tracked, non-secret `config/config.example.toml` and `config/.env.example`.
636
+ Set `LABBY_CONFIG_FILE` and `LABBY_ENV_FILE` to select local runtime files;
637
+ Compose mounts both read-only at their canonical paths beneath `$LABBY_HOME`. Labby-owned runtime
638
+ state remains writable in the surrounding `labby-home` named volume. Startup logs and the
639
+ setup settings state report `/home/labby/.labby/config.toml` as the effective
640
+ source. The image installs pinned Claude,
641
+ Codex, and Gemini CLIs for stdio upstreams that invoke provider tools.
541
642
 
542
643
  ### Releases
543
644
 
544
645
  Release Please maintains the version/changelog pull request and creates the
545
- stable tag plus draft GitHub release when that pull request merges. Publishing
546
- the release triggers the heavy GitHub-hosted x86_64 workflows. They build Linux
547
- and Windows archives with checksums, build and scan the GHCR image, build and
548
- smoke the Incus image, publish the npm launcher, and publish Labby's
549
- `server.json` metadata to the official MCP Registry.
646
+ stable tag plus draft GitHub release when that pull request merges. The stable
647
+ tag triggers the heavy GitHub-hosted candidate workflow. It builds Linux,
648
+ macOS, and Windows archives with checksums, builds and smokes the Incus image,
649
+ publishes the npm launcher, and publishes Labby's
650
+ `server.json` metadata to the official MCP Registry. Only after qualification
651
+ and publication succeed does the workflow promote the draft GitHub release.
550
652
 
551
653
  ### Plugin Setup
552
654
 
package/lib/platform.js CHANGED
@@ -23,7 +23,17 @@ function targetFor(platform = process.platform, arch = process.arch) {
23
23
  };
24
24
  }
25
25
 
26
- throw new Error(`Unsupported platform ${platform}/${arch}. Supported targets: linux/x64, win32/x64.`);
26
+ if (platform === "darwin" && arch === "arm64") {
27
+ return {
28
+ asset: "lab-aarch64-apple-darwin.tar.gz",
29
+ binary: "labby",
30
+ archiveType: "tar.gz",
31
+ };
32
+ }
33
+
34
+ throw new Error(
35
+ `Unsupported platform ${platform}/${arch}. Supported targets: linux/x64, darwin/arm64, win32/x64.`,
36
+ );
27
37
  }
28
38
 
29
39
  function releaseVersion(env = process.env) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dinglebear/labby",
3
- "version": "1.13.3",
3
+ "version": "1.19.0",
4
4
  "license": "AGPL-3.0-only",
5
5
  "description": "Rust MCP gateway with Code Mode, authentication, setup, logs, CLI, HTTP API, and operator web UI.",
6
6
  "homepage": "https://github.com/dinglebear-ai/labby#readme",
@@ -318,7 +318,7 @@ function supportedTargets(platform) {
318
318
  const tuples = [
319
319
  ["linux", "x64"],
320
320
  ["win32", "x64"],
321
- ["darwin", "x64"],
321
+ ["darwin", "arm64"],
322
322
  ["linux", "ppc64"],
323
323
  ];
324
324
  const targets = [];