@huynle/hub 0.8.4 → 0.8.5
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/CHANGELOG.md +42 -0
- package/README.md +40 -3
- package/package.json +1 -1
- package/packages/claude-code/package.json +1 -1
- package/packages/cli/dist/hub-cli.js +5288 -4415
- package/packages/cli/package.json +1 -1
- package/packages/cli/src/bootstrap/PHASE2-CONTRACT.md +87 -0
- package/packages/cli/src/bootstrap/adapters/claude/node.ts +11 -43
- package/packages/cli/src/bootstrap/adapters/codex/verify.ts +19 -12
- package/packages/cli/src/bootstrap/adapters/opencode/README.md +42 -6
- package/packages/cli/src/bootstrap/adapters/opencode/apply.ts +18 -7
- package/packages/cli/src/bootstrap/adapters/opencode/archive.ts +36 -19
- package/packages/cli/src/bootstrap/adapters/opencode/config.ts +19 -3
- package/packages/cli/src/bootstrap/adapters/opencode/index.ts +2 -5
- package/packages/cli/src/bootstrap/adapters/opencode/plan.ts +37 -6
- package/packages/cli/src/bootstrap/adapters/opencode/verify.ts +49 -26
- package/packages/cli/src/bootstrap/adapters/process-tree.ts +263 -0
- package/packages/cli/src/bootstrap/contracts/paths.ts +7 -4
- package/packages/cli/src/bootstrap/contracts/platform.ts +9 -5
- package/packages/cli/src/bootstrap/contracts/validate.ts +20 -4
- package/packages/cli/src/bootstrap/discovery/discover.ts +3 -1
- package/packages/cli/src/bootstrap/discovery/executables.ts +49 -14
- package/packages/cli/src/bootstrap/discovery/host.ts +16 -8
- package/packages/cli/src/bootstrap/discovery/node-probe.ts +41 -5
- package/packages/cli/src/bootstrap/discovery/probe.ts +7 -3
- package/packages/cli/src/bootstrap/discovery/util.ts +42 -5
- package/packages/cli/src/bootstrap/enrollment/store.ts +13 -6
- package/packages/cli/src/bootstrap/preview/plan.ts +3 -0
- package/packages/cli/src/bootstrap/profiles/desired.ts +10 -3
- package/packages/cli/src/bootstrap/release/README.md +63 -9
- package/packages/cli/src/bootstrap/release/cli.ts +94 -16
- package/packages/cli/src/bootstrap/release/harness-pins.pending.json +24 -0
- package/packages/cli/src/bootstrap/release/manifest.ts +3 -0
- package/packages/cli/src/bootstrap/release/pins.ts +60 -9
- package/packages/cli/src/bootstrap/transaction/builtin.ts +18 -6
- package/packages/cli/src/bootstrap/transaction/engine.ts +166 -12
- package/packages/cli/src/bootstrap/transaction/executor.ts +5 -0
- package/packages/cli/src/bootstrap/transaction/fs.ts +142 -3
- package/packages/cli/src/bootstrap/transaction/shim.ts +31 -0
- package/packages/cli/src/bootstrap/transaction/state.ts +11 -6
- package/packages/cli/src/credentials.ts +5 -2
- package/packages/cli/src/main.ts +3 -2
- package/packages/cli/src/setup/commands.ts +96 -18
- package/packages/cli/src/setup/contributors.ts +45 -10
- package/packages/cli/src/setup/runtime.ts +25 -6
- package/packages/cli/src/setup/self-aside.ts +130 -0
- package/packages/codex/package.json +1 -1
- package/packages/node/package.json +1 -1
- package/packages/node/src/opencode-warm.ts +12 -4
- package/packages/preset/package.json +1 -1
- package/packages/protocol/package.json +1 -1
- package/packages/runtime-openshell/package.json +1 -1
- package/packages/runtime-sdk/package.json +1 -1
- package/packages/sdk/package.json +1 -1
- package/packages/spoke-sdk/package.json +1 -1
- package/src/central/config.ts +12 -0
- package/src/central/http.ts +10 -0
- package/src/central/install/CONTRACT.md +66 -0
- package/src/central/install/install.ps1 +349 -0
- package/src/central/install/install.sh +266 -0
- package/src/central/install/render.ts +146 -0
- package/src/central/install/templates.ts +6 -0
- package/src/central/install/text-assets.d.ts +9 -0
- package/src/config.ts +12 -7
- package/src/spoke/env-inject.ts +17 -2
- package/src/spoke/launchers.ts +145 -9
- package/src/win-acl.ts +154 -0
- package/web/dist/assets/ArtifactPage-Dq7VW-bU.js +1 -0
- package/web/dist/assets/{ArtifactPane-XTnwXl-Y.js → ArtifactPane-DKwbMTX9.js} +1 -1
- package/web/dist/assets/ArtifactWorkbench-vrgIfncX.js +6 -0
- package/web/dist/assets/Library-D6-Go6Cu.js +2 -0
- package/web/dist/assets/{ProfilesDestination-dZa3vioh.js → ProfilesDestination-BOML2Dgf.js} +1 -1
- package/web/dist/assets/{TeamsPage-DJt-Kk84.js → TeamsPage-CNBTE8gB.js} +1 -1
- package/web/dist/assets/Watchtower-Dor1Ubjy.js +2 -0
- package/web/dist/assets/Watchtower-RphjcL0_.css +1 -0
- package/web/dist/assets/hub-CrbItiwP.js +13 -0
- package/web/dist/assets/index-82Ce0IAf.css +1 -0
- package/web/dist/assets/index-D9SP3_0z.js +22 -0
- package/web/dist/assets/{live-D-RZbeUi.js → live-BNJgy0vg.js} +3 -3
- package/web/dist/assets/{pane-layout-Csk-vPNe.js → pane-layout-EdR1kRrG.js} +1 -1
- package/web/dist/assets/preload-helper-DqrJTq0t.js +1 -0
- package/web/dist/assets/{renderer2d-DILxLFEq.js → renderer2d-CYag1CnR.js} +1 -1
- package/web/dist/assets/{renderer3d-PvN9Qbt2.js → renderer3d-BRB6rgDJ.js} +1 -1
- package/web/dist/assets/{safe-area-BS6ii3M7.js → safe-area-fOy0AOuG.js} +1 -1
- package/web/dist/assets/{source-BFLJQ43_.js → source-Wbq35qGp.js} +1 -1
- package/web/dist/assets/{ui-Qo2Pd9-O.js → ui-j5FFk90B.js} +1 -1
- package/web/dist/index.html +6 -4
- package/web/dist/assets/ArtifactPage-Cb1DcrQf.js +0 -1
- package/web/dist/assets/ArtifactWorkbench-C37tZZ3e.js +0 -6
- package/web/dist/assets/Library-CZSSHvOJ.js +0 -2
- package/web/dist/assets/Watchtower-BXaUaXO1.js +0 -2
- package/web/dist/assets/Watchtower-CTgqHk5g.css +0 -1
- package/web/dist/assets/index-DVSkeAvn.css +0 -1
- package/web/dist/assets/index-DifgVuKS.js +0 -34
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.5
|
|
4
|
+
|
|
5
|
+
Set up Hub on a machine in one line. The console's new **Set up Hub on a machine** (avatar menu, Settings → Machines
|
|
6
|
+
& devices, Watchtower) builds a `curl … | sh` (macOS, Linux) or `irm … | iex` (Windows) command that the hub serves
|
|
7
|
+
with its own URL and version: it installs and checks hubctl, enrolls the machine (you approve it in the console) and
|
|
8
|
+
sets it up. hubctl now runs natively on Windows x64 for the OpenCode-only profile. No migration is needed.
|
|
9
|
+
|
|
10
|
+
### Machine setup
|
|
11
|
+
- **The hub serves one-line install scripts**: public `GET /install.sh` (macOS, Linux: `curl -fsSL '<hub>/install.sh?…' | sh`)
|
|
12
|
+
and `GET /install.ps1` (Windows: `irm '<hub>/install.ps1?…' | iex`), rendered from fixed templates with only the
|
|
13
|
+
hub's public URL, its version and the validated choices (`profile`, `root`, `activate`; anything else answers 400
|
|
14
|
+
with the reason; never a token). They pin this hub's hubctl release; the new `HUB_RELEASE_BASE` points them
|
|
15
|
+
elsewhere (https, or http on loopback or a private-network IP), and a development version without it answers 503.
|
|
16
|
+
A plain-http hub is served only on loopback or a private-network IP (with `--allow-insecure-http`), else 400.
|
|
17
|
+
Leave both paths reachable behind an authenticating proxy, like `/.well-known/hub`.
|
|
18
|
+
- **`install.ps1` installs hubctl on Windows** (x64; arm64 and 32-bit are refused with the reason): it downloads
|
|
19
|
+
`hubctl-windows-x64.exe`, checks its sha256 against `HUBCTL_SHA256SUMS` (`Get-FileHash`), then runs the same
|
|
20
|
+
`machine status` / `machine enroll` / `setup preview` / `setup apply` / `setup verify` sequence as `install.sh`
|
|
21
|
+
(session-only), and adds `%USERPROFILE%\.local\bin` to the user PATH once (`%VARS%` in it are kept). It no longer adds
|
|
22
|
+
the OpenCode plugin or writes the spoke config itself; it still never closes the PowerShell window.
|
|
23
|
+
- Console: **Set up Hub on a machine**, one dialog opened from the avatar's new menu, Settings → Machines & devices
|
|
24
|
+
(**Set up a machine**, also in the settings search) and Watchtower's **Connect a machine**: pick the OS (detected),
|
|
25
|
+
the profile (OpenCode only, + launch node with its workspace folder, All harnesses; Windows: OpenCode only for
|
|
26
|
+
now) and Start services now, then copy the `curl … | sh` or `irm … | iex` one-liner built from the hub's public URL.
|
|
27
|
+
|
|
28
|
+
### hubctl on Windows (x64, OpenCode only)
|
|
29
|
+
- **`hubctl-windows-x64.exe`** is built, signed into the release manifest and smoke-tested on Windows. Windows paths
|
|
30
|
+
(`C:/…`) are first-class in plans and journals; discovery reads `%USERPROFILE%`, PATHEXT, `.cmd` shims and the
|
|
31
|
+
machine's `MachineGuid`. `hub` and `opencode` on PATH are `.cmd` shims, the harness's current version is a junction,
|
|
32
|
+
files in use are replaced rename-aside, and the machine credential gets an owner-only ACL. `+ launch node` and
|
|
33
|
+
`All harnesses` need user services and are refused on Windows for now. This release pins no OpenCode for Windows
|
|
34
|
+
yet: a Windows machine without OpenCode is asked to install it first.
|
|
35
|
+
- **The OpenCode plugin writes `.cmd` launchers on Windows** instead of `#!/bin/sh` scripts and a symlink, and never
|
|
36
|
+
overwrites hubctl's `hub.cmd`.
|
|
37
|
+
- **Rollback**: a rollback that removes the running `hubctl.exe` deletes it once it exits and lists what it undid; a
|
|
38
|
+
path in use undoes everything else, names the path and is finished by `hubctl setup recover`.
|
|
39
|
+
- **Verify probes leave nothing running** (all harnesses, every OS): `opencode models --standalone`, and the probe's
|
|
40
|
+
whole process tree ends with it.
|
|
41
|
+
|
|
42
|
+
### Fixes
|
|
43
|
+
- `HEAD /install.sh` and `/install.ps1` answer like GET without a body.
|
|
44
|
+
|
|
3
45
|
## 0.8.4
|
|
4
46
|
|
|
5
47
|
A fix release. A question or permission a session is waiting on no longer disappears from the console while
|
package/README.md
CHANGED
|
@@ -179,6 +179,41 @@ Optional: put the voice agent on a fast model in `~/.config/hub/config.json`:
|
|
|
179
179
|
`"voiceModel": "anthropic/claude-haiku-4-5"` (any `provider/model` you have). Subagents keep the
|
|
180
180
|
session's model.
|
|
181
181
|
|
|
182
|
+
## Set up a machine (one line)
|
|
183
|
+
|
|
184
|
+
The hub serves an install script for its own version, so a machine needs only one command. In the console use
|
|
185
|
+
**Set up Hub on a machine** (avatar menu, Settings → Machines, or Watchtower's **Connect a machine**) and copy the
|
|
186
|
+
line it shows, or write it yourself:
|
|
187
|
+
|
|
188
|
+
```sh
|
|
189
|
+
# macOS / Linux (POSIX sh): downloads and checks hubctl, enrolls (approve the code in the console), previews, applies
|
|
190
|
+
curl -fsSL 'https://hub.example.com/install.sh' | sh
|
|
191
|
+
curl -fsSL 'https://hub.example.com/install.sh?profile=launch-node&root=~/projects&activate=1' | sh
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```powershell
|
|
195
|
+
# Windows x64 (PowerShell 5.1 or 7): the same steps with hubctl-windows-x64.exe; OpenCode only for now
|
|
196
|
+
irm 'https://hub.example.com/install.ps1' | iex
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Query options (each optional, at most once; anything else answers 400 with the reason):
|
|
200
|
+
|
|
201
|
+
| Key | Values | Default |
|
|
202
|
+
|---|---|---|
|
|
203
|
+
| `profile` | `session-only` (OpenCode only), `launch-node` (+ a launch node), `full-harness` (all harnesses) | `session-only` |
|
|
204
|
+
| `root` | the launch node's workspace root, only with `launch-node`: up to 200 characters of `A-Z a-z 0-9 . _ / ~ -`, starting with `/` or `~/`, no `..` or `//` | `~/projects` |
|
|
205
|
+
| `activate` | `1` starts the services now (`--confirm-activation`), `0` leaves them stopped | `0` |
|
|
206
|
+
|
|
207
|
+
`install.ps1` takes only `profile=session-only` and `activate=0` for now (hubctl does not install user services on
|
|
208
|
+
Windows yet) and runs on x64 Windows only (no arm64 build yet). It never closes your PowerShell window: a failure is
|
|
209
|
+
one red `hub setup:` line. After a successful apply it adds `%USERPROFILE%\.local\bin` to your user PATH (once; open a
|
|
210
|
+
new terminal for other windows). The scripts carry
|
|
211
|
+
the hub's public URL, version and the validated choices; never a token. They download hubctl from this version's
|
|
212
|
+
release on [hub-releases](https://github.com/huynle/hub-releases/releases) (`v<version>`); `HUB_RELEASE_BASE` on
|
|
213
|
+
the hub points them at another location (a mirror, or a development build, which otherwise answers 503). A
|
|
214
|
+
plain-`http` hub is served only on loopback or a private-network IP address (the script then passes
|
|
215
|
+
`--allow-insecure-http`); on a host name or a public address the routes answer 400: use https.
|
|
216
|
+
|
|
182
217
|
## Quick start (hubctl, before any harness)
|
|
183
218
|
|
|
184
219
|
`hubctl` is a standalone, signed program (Bun and the CLI compiled into one file; no bun, node or harness needed)
|
|
@@ -317,8 +352,9 @@ foreground with `hub.json`; `scripts/io.github.huynle.hub.plist` is a launchd te
|
|
|
317
352
|
**Security:** the hub can drive your OpenCode sessions, which can run tools. Every API call needs a
|
|
318
353
|
paired device or a signed-in user; spokes need machine tokens; nothing trusts the client IP. For a public
|
|
319
354
|
hostname, consider [sign-in with Google](#multi-user-sign-in-with-google) or an authenticating proxy in
|
|
320
|
-
front of the web app, and leave `/spoke/*`, `/auth/*`, `/healthz`, `/.well-known/hub`,
|
|
321
|
-
icons reachable for spokes, sign-in, app discovery
|
|
355
|
+
front of the web app, and leave `/spoke/*`, `/auth/*`, `/healthz`, `/.well-known/hub`, `/install.sh`,
|
|
356
|
+
`/install.ps1`, the manifest and icons reachable for spokes, sign-in, app discovery, [machine
|
|
357
|
+
setup](#set-up-a-machine-one-line) and the PWA (and `/mcp`, bearer-authenticated, if MCP clients
|
|
322
358
|
or gateways use [MCP over HTTP](#over-http-mcp)).
|
|
323
359
|
|
|
324
360
|
**Behind a reverse proxy**, set a request-body limit of about 26 MiB (artifact blobs are up to 25 MiB) and keep
|
|
@@ -328,7 +364,7 @@ including `blobs/` (artifact bytes).
|
|
|
328
364
|
|
|
329
365
|
## Configuration
|
|
330
366
|
|
|
331
|
-
- **Hub**: env vars (`HUB_HOST`, `HUB_PORT`, `HUB_PUBLIC_URL`, `HUB_STATE_DIR`, `OPENROUTER_API_KEY`, …)
|
|
367
|
+
- **Hub**: env vars (`HUB_HOST`, `HUB_PORT`, `HUB_PUBLIC_URL`, `HUB_STATE_DIR`, `HUB_RELEASE_BASE`, `OPENROUTER_API_KEY`, …)
|
|
332
368
|
over `~/.config/hub/hub.json` (`$HUB_CONFIG`); see [Central server](#central-server) and
|
|
333
369
|
[hub.json](#hubjson). Speech providers and keys are easiest to set in the app (Settings → Speech).
|
|
334
370
|
- **Plugin** (OpenCode spoke): `~/.config/hub/config.json` (`$HUB_SPOKE_CONFIG`; server, mode, machine
|
|
@@ -1218,6 +1254,7 @@ holds the startup (`bin/hub.ts` serves `web/` from disk; the compiled binaries e
|
|
|
1218
1254
|
| `HUB_DATABASE_STATEMENT_TIMEOUT_MS` | `30000` | cluster mode: Postgres `statement_timeout` of the hub's pools (`0` turns it off) |
|
|
1219
1255
|
| `HUB_TURN_TIMEOUT_MS` | `600000` | the hub waits this + 15 s so the spoke's own timeout result arrives first |
|
|
1220
1256
|
| `HUB_VAPID_SUBJECT` | the https public URL, else `mailto:hub@localhost` | contact sent to push services |
|
|
1257
|
+
| `HUB_RELEASE_BASE` | `https://github.com/huynle/hub-releases/releases/download/v<version>` | where `/install.sh` and `/install.ps1` download hubctl ([Set up a machine](#set-up-a-machine-one-line)): https, or plain http on loopback or a private-network IP address; the hub refuses to start with any other value. Without it a development version (not a plain `x.y.z`) answers 503 |
|
|
1221
1258
|
| `HUB_CSP` | `enforce` | `report-only` sends the console's Content-Security-Policy as `Content-Security-Policy-Report-Only` (violations are only logged in the browser console); see [Content-Security-Policy](#content-security-policy) |
|
|
1222
1259
|
| `OPENROUTER_API_KEY` | | default key for the `openrouter` speech provider (never sent to other providers) |
|
|
1223
1260
|
| `HUB_STT_MODEL`, `HUB_TTS_MODEL`, `HUB_VOICE`, `HUB_MAX_*` | see `src/central/config.ts` | speech defaults; the phone's speech settings override them |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huynle/hub",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"description": "Hub: a harness-agnostic central hub your AI agent harnesses connect to (OpenCode first). Follow, steer and stop sessions from your phone or browser, with notifications, optional hands-free Voice and a self-hostable server.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Huy Le",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huynle/hub-claude-code",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "The Claude Code hooks spoke: per-user daemon, hook bridge, plugin dir, `hub claude` wrapper and daemon-backed MCP server (internal; shipped inside @huynle/hub, not published on its own).",
|
|
6
6
|
"license": "MIT",
|