@huynle/hub 0.10.1 → 0.11.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/CHANGELOG.md +54 -0
- package/README.md +17 -3
- package/package.json +1 -1
- package/packages/claude-code/package.json +1 -1
- package/packages/cli/dist/hub-cli.js +622 -394
- package/packages/cli/package.json +1 -1
- package/packages/cli/src/grants-mcp.ts +65 -0
- package/packages/cli/src/mcp-operations.ts +49 -0
- package/packages/cli/src/mcp.ts +6 -0
- package/packages/cli/src/subscriptions-mcp.ts +76 -0
- package/packages/cli/src/teams-mcp.ts +5 -3
- package/packages/codex/package.json +1 -1
- package/packages/node/package.json +1 -1
- package/packages/preset/package.json +1 -1
- package/packages/protocol/package.json +1 -1
- package/packages/protocol/src/teams.ts +4 -0
- package/packages/protocol/src/voice-recording.ts +39 -2
- package/packages/runtime-openshell/image/entry.sh +3 -1
- package/packages/runtime-openshell/image/start.sh +3 -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/sdk/src/client.ts +13 -0
- package/packages/sdk/src/teams.ts +2 -0
- package/packages/spoke-sdk/package.json +1 -1
- package/src/central/agent/decisions.ts +7 -1
- package/src/central/agent/delivery.ts +39 -9
- package/src/central/agent/grant-routes.ts +14 -1
- package/src/central/agent/grants.ts +23 -0
- package/src/central/agent/launch-engine.ts +3 -3
- package/src/central/agent/message-limits.ts +3 -0
- package/src/central/agent/routes.ts +11 -0
- package/src/central/agent/subscriptions.ts +3 -1
- package/src/central/config.ts +9 -2
- package/src/central/http.ts +102 -20
- package/src/central/recording/export.ts +57 -3
- package/src/central/recording/index.ts +234 -16
- package/src/central/recording/ingest.ts +11 -2
- package/src/central/recording/routes.ts +61 -7
- package/src/central/recording/schema.ts +66 -2
- package/src/central/recording/settings.ts +19 -5
- package/src/central/recording/store.ts +19 -0
- package/src/central/recording/taps.ts +45 -1
- package/src/central/speech/openai.ts +4 -4
- package/src/central/speech/openrouter.ts +4 -4
- package/src/central/speech/provider.ts +32 -1
- package/src/central/speech/service.ts +6 -5
- package/src/central/teams/hop-stalls.ts +72 -0
- package/src/central/teams/policy.ts +10 -0
- package/src/central/teams/routes.ts +2 -0
- package/src/central/teams/seats.ts +3 -3
- package/src/central/teams/staffing.ts +5 -0
- package/src/central/teams/store.ts +5 -2
- package/src/central/teams/validation.ts +8 -5
- package/web/dist/assets/{ArtifactPage-CsPjam8D.js → ArtifactPage-C5MMqXLN.js} +1 -1
- package/web/dist/assets/{ArtifactPane-B9weO8L6.js → ArtifactPane-CXSCmhyJ.js} +1 -1
- package/web/dist/assets/{ArtifactWorkbench-DzKhMs3l.js → ArtifactWorkbench-S0RxNGWy.js} +1 -1
- package/web/dist/assets/{Diagram-CuRIffka.js → Diagram-BGmyRb-R.js} +1 -1
- package/web/dist/assets/{Library-rv5DGtrm.js → Library-CFmMbXEa.js} +2 -2
- package/web/dist/assets/{ProfilesDestination-DUuQ9jmd.js → ProfilesDestination-7jpOc2HM.js} +1 -1
- package/web/dist/assets/{TeamsPage-D_17MkvN.js → TeamsPage-C1NGrUR-.js} +1 -1
- package/web/dist/assets/{Watchtower-DlrNOJ7X.js → Watchtower-DnvlJaU0.js} +2 -2
- package/web/dist/assets/{artifacts-But87Jfo.js → artifacts-DlQEYmDl.js} +1 -1
- package/web/dist/assets/index-Da8SKXMw.js +33 -0
- package/web/dist/assets/{index-rW6LKQj1.css → index-Dyq-jBeE.css} +1 -1
- package/web/dist/assets/live-BmqLASSo.js +5 -0
- package/web/dist/assets/{pane-layout-BW0RdX5a.js → pane-layout-BAuu_pA3.js} +1 -1
- package/web/dist/assets/{renderer2d-DyANQ1WS.js → renderer2d-B2Nh39UN.js} +1 -1
- package/web/dist/assets/{renderer3d-vYYKFAJq.js → renderer3d-CTYbljHH.js} +1 -1
- package/web/dist/assets/{safe-area-B2Bk__FK.js → safe-area-CkhEclGo.js} +1 -1
- package/web/dist/assets/{silero-worker-e802lB5T.js → silero-worker-CC2etKS3.js} +1 -1
- package/web/dist/assets/{source-C-De8L3s.js → source-GYayxUxS.js} +1 -1
- package/web/dist/assets/{toast-CXTwTvDw.js → toast-q818mjUF.js} +1 -1
- package/web/dist/index.html +5 -5
- package/web/dist/assets/index-bX8B6NLo.js +0 -33
- package/web/dist/assets/live-BGLA-peO.js +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
Voice recording's Developer mode and the richer `capture.v2` recording events (below), plus the fixes and team
|
|
6
|
+
tools merged since 0.10.1: a launch's `end.cleanup: keep` is honoured when an ended host launch is reconciled, and
|
|
7
|
+
the applied cleanup policy is stored before a launch ends, so kept, `needs_user` and lost workspaces are no longer
|
|
8
|
+
deleted later; a per-team agent message hop limit with a user-only Renew Decision when a team chain stalls (and
|
|
9
|
+
orphaned stall claims expire); team member names show without graph interactions; holder-scoped grant tools and
|
|
10
|
+
read-only subscription, session-model and machine/node tools over MCP; the console's Launch new member form sets
|
|
11
|
+
the model, end policy and timeout; the sandbox entry publishes its PID atomically, so a second start no longer
|
|
12
|
+
starts a duplicate harness. CI cancels superseded test runs without interrupting an image release and can reuse a
|
|
13
|
+
PR's passing result for the same tree.
|
|
14
|
+
|
|
15
|
+
### Voice recording (developer)
|
|
16
|
+
- **Developer mode** (Settings → Voice, per user, off by default; user request, 2026-11-10). One more field of the
|
|
17
|
+
recording settings record (`developer`, the same revision and `PUT /api/settings/recording {developer}`): on turns
|
|
18
|
+
recording on, recording off turns it off, older consoles' `{enabled}` keep it. While a developer recording runs it
|
|
19
|
+
also keeps, behind the new hub feature `dev.v1` (start answer `developer: true`):
|
|
20
|
+
- **raw microphone audio clips** (3 s before to 2 s after) around near-misses and marks, from a ring buffer of the
|
|
21
|
+
detector's input (`audio.clip`, `PUT/GET /api/recordings/:id/clips/:n`, ≤ 200 per recording);
|
|
22
|
+
- the detector's **frame traces** around speech starts, ends and near-misses (`vad.trace`);
|
|
23
|
+
- **device and network facts** on start and on change (`device.info`: audio devices, mic track processing,
|
|
24
|
+
Network Information, visibility, wake lock, battery), **Resource Timing** of the voice routes
|
|
25
|
+
(`resource.timing`) and **console errors and warnings** (`console.log`, scrubbed, rate-limited);
|
|
26
|
+
- hub side: per turn the **model, provider, agent and context token counts** and each tool call's start and end
|
|
27
|
+
(`turn.detail`; never prompt text), **request lines** of the voice routes (`request`), and the **reply audio**
|
|
28
|
+
kept from `/api/speak` as it streams (`reply.audio`, `GET /api/recordings/:id/replies/:n`).
|
|
29
|
+
The extras count against the same caps; their audio stops first (50 MiB below the user's cap, 15 MiB below the
|
|
30
|
+
recording's; `cap.reached {what: "extras"}`), segments and events go on. Exports add `clips/` and `replies/`,
|
|
31
|
+
listed in the manifest. Turning Developer mode off stops the extras at once. The indicator says
|
|
32
|
+
"● Recording · developer"; `scripts/voice-eval.ts` reports models per turn, devices, routes, clips and errors.
|
|
33
|
+
- **More of what happens is recorded**, so "I talked and nothing happened" and lost words leave a trace. New console
|
|
34
|
+
events, sent only to a hub whose recording start lists the new feature `capture.v2` (an older hub refuses a whole
|
|
35
|
+
batch with an unknown kind, value or field, so toward it the console drops them before they take a `seq`):
|
|
36
|
+
- `vad.near`: what the speech detector almost took for speech: an onset abandoned before it started
|
|
37
|
+
(`short-onset`, `voiced-ratio`) or ≥ 150 ms just under the start threshold (`below-threshold`), with its peak, the
|
|
38
|
+
threshold that applied and whether the echo guard was up (the agent speaking). At most one per 500 ms of audio
|
|
39
|
+
and 20 per minute (the rest are counted in the next summary).
|
|
40
|
+
- `vad.summary`: every 10 s of listening, the detector's frames, max and p90 speech probability, loudest frame,
|
|
41
|
+
noise floor, frames over the start and echo-guard thresholds, time under the echo guard, mode and sensitivity
|
|
42
|
+
(quiet windows after a quiet summary are skipped).
|
|
43
|
+
- `stt.received` adds `junkReason` (why a transcript was dropped as noise), `held` (the text held at that moment)
|
|
44
|
+
and `speechMs`.
|
|
45
|
+
- `stt.slow`: a transcription still unanswered after 2 s (once per segment).
|
|
46
|
+
- `mark`: a bookmark. Say **"mark"**, **"mark that"** or **"bookmark"** alone (not sent to the agent; the held
|
|
47
|
+
text waits on), or press the Voice bar's new **Mark** button (shown only while recording on such a hub). The
|
|
48
|
+
Voice bar notes "Marked".
|
|
49
|
+
- The hub's `stt.result` adds the provider's `httpStatus`, `responseBytes` and `headersMs` (time to the response's
|
|
50
|
+
headers; `providerMs` stays the total).
|
|
51
|
+
- **`scripts/voice-eval.ts`** reads a recording export (zip or folder) and reports, across all its recordings,
|
|
52
|
+
per-turn latency by stage (median / p90 / max, by recording kind and device), dropped segments with their reason
|
|
53
|
+
and held text, early sends, STT stalls over 3 s with the provider's share, near-misses with the echo-guard share
|
|
54
|
+
and marks with ±15 s of context (`--json`, `--no-text`). Older exports work: what they lack is reported as not
|
|
55
|
+
recorded.
|
|
56
|
+
|
|
3
57
|
## 0.10.1
|
|
4
58
|
|
|
5
59
|
Clicking the composer's Model chip changes the session's model. No migration is needed. Machines need the new
|
package/README.md
CHANGED
|
@@ -312,7 +312,7 @@ The hub serves the web app, pairs devices, enrolls machines, and does push and (
|
|
|
312
312
|
|---|---|---|
|
|
313
313
|
| **`/hub` → On this computer** | Local use; nothing to install (plugin from npm) | started by the plugin with OpenCode's own runtime (`BUN_BE_BUN=1 opencode bin/hub.ts`), or `bun` when installed |
|
|
314
314
|
| **Standalone binary** | Any server or laptop, no runtime needed | `hub-<os>-<arch>` from the [releases](https://github.com/huynle/hub-releases/releases) (the source repository is private; releases are mirrored to the public `huynle/hub-releases`) |
|
|
315
|
-
| **Docker** | Servers | `ghcr.io/huynle/hub` (linux/amd64, linux/arm64) |
|
|
315
|
+
| **Docker** | Servers | `ghcr.io/huynle/hub` (linux/amd64, linux/arm64 for `v*` releases and `latest`; per-commit `git-…` tags from `main` are linux/amd64 only) |
|
|
316
316
|
| **bunx / from source** | Bun users, development | `bunx --package @huynle/hub hub-server` · `bun bin/hub.ts` |
|
|
317
317
|
| **Kubernetes (cluster mode)** | Several pods on Postgres + Valkey, rolling updates | [docs/cluster.md](docs/cluster.md), manifests in [`deploy/k8s/`](deploy/k8s/) |
|
|
318
318
|
|
|
@@ -819,6 +819,13 @@ the requester and may only be the requester itself or a reserved role it holds.
|
|
|
819
819
|
the grant; approving creates it as yours, and the requester is told the grant id in a reply. One open request per
|
|
820
820
|
requester, 5 an hour.
|
|
821
821
|
|
|
822
|
+
`hub mcp` exposes `grant_request` (the same request route and limits), `grant_list`, `grant_show` and
|
|
823
|
+
`grant_revoke` (grants held by the calling session or app; apps need `messages:read` to list/show and
|
|
824
|
+
`messages:send` to revoke), and
|
|
825
|
+
`grant_create` (user device credential only; an agent must request and wait for your tap). A user credential on
|
|
826
|
+
the holder-scoped tools has no holder; manage all grants in the console or with `hub grant` instead. Pinning a
|
|
827
|
+
profile as an app also requires a `prompt` grant on the target session, not only `profiles:assign`.
|
|
828
|
+
|
|
822
829
|
**Prompts.** An agent's prompt reaches the session as the hub's, never as yours: the spoke wraps it in a provenance
|
|
823
830
|
envelope (`[hub] prompt from @lead · grant g_… · msg_…`, the body between boundary lines) and admits it as a hub
|
|
824
831
|
message, so it never resets the loop protection's hop chain the way your own typing does. Agents may prompt root
|
|
@@ -1102,7 +1109,12 @@ required and absolute; `mode`, `branch`, `base`, `remote`, `key`, `name`, `roles
|
|
|
1102
1109
|
`cleanup`), `launches` (`state`, `label`), `launch_show` and `launch_stop` (`id`); the profile tools (`profiles`,
|
|
1103
1110
|
`profile_show`, `profile_create`, `profile_version_create`, `profile_skill_set`, `profile_command_set`,
|
|
1104
1111
|
`profile_assign`, …; [docs/profiles.md](docs/profiles.md#sdk-and-mcp)), the workspace, artifact and team tools
|
|
1105
|
-
([docs/teams.md](docs/teams.md#mcp-tools); `team_staff` takes the nested launch spec),
|
|
1112
|
+
([docs/teams.md](docs/teams.md#mcp-tools); `team_staff` takes the nested launch spec), subscription tools
|
|
1113
|
+
(`subscribe`, `subscriptions`, `unsubscribe`; [docs/subscriptions.md](docs/subscriptions.md#surfaces)),
|
|
1114
|
+
the grant tools (`grant_request`, `grant_list`, `grant_show`, `grant_revoke`, `grant_create`;
|
|
1115
|
+
[docs/multi-user.md](docs/multi-user.md#grants-tenancy)), `session_model_set` (user device credential only, same
|
|
1116
|
+
catalog checks as the console), and read-only `machines` and `launch_nodes` (user device credential only; connected
|
|
1117
|
+
node roots, slots, runtimes and labels; [docs/mcp-operations.md](docs/mcp-operations.md)), with the same arguments
|
|
1106
1118
|
(`to`, `text`, `addr`, `id`, `requestID`, `formID`, `why`, `n`, `wake`, `urgent`, `all`, `project`, `role`, …). The act
|
|
1107
1119
|
tools need an app token with scope `sessions:act` and a grant, the launch tools scope `sessions:launch` and a
|
|
1108
1120
|
launch grant; `needs_user` results include the evaluation. `ask` takes `wait` of at
|
|
@@ -1904,7 +1916,9 @@ The loop is the package `packages/voice-client` (a `VoiceTransport` over the con
|
|
|
1904
1916
|
`voiceTurn.fallback`, `voiceTurn.slow` as URL query parameters (one visit) or localStorage keys. The recording
|
|
1905
1917
|
mode records each score as `turn.predict` ([docs/voice-recording.md](docs/voice-recording.md)).
|
|
1906
1918
|
- **Commands**: an utterance that is only "stop", "cancel", "never mind", "stop that" or "hold on"
|
|
1907
|
-
calls `POST …/interrupt` and stops speech. "Pause listening" turns the mode off.
|
|
1919
|
+
calls `POST …/interrupt` and stops speech. "Pause listening" turns the mode off. While the recording mode records
|
|
1920
|
+
(on a hub with its `capture.v2` feature), "mark", "mark that" or "bookmark" alone bookmarks the recording instead
|
|
1921
|
+
of reaching the agent ([docs/voice-recording.md](docs/voice-recording.md)).
|
|
1908
1922
|
- **Speech out**: root replies arrive one sentence at a time while they are written (`say` with `seq`);
|
|
1909
1923
|
the phone plays them in `seq` order per text part and drops duplicates (`SayAssembler`). A `say` without
|
|
1910
1924
|
`seq` (a subagent's result) is split into sentences. Abbreviations, decimals, file names and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huynle/hub",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
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.
|
|
3
|
+
"version": "0.11.0",
|
|
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",
|