@huynle/hub 0.6.1 → 0.7.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/CHANGELOG.md +800 -0
- package/Dockerfile +30 -0
- package/README.md +870 -66
- package/package.json +45 -2
- package/packages/claude-code/package.json +12 -0
- package/packages/claude-code/src/bridge.ts +79 -0
- package/packages/claude-code/src/daemon.ts +339 -0
- package/packages/claude-code/src/hook-input.ts +44 -0
- package/packages/claude-code/src/ids.ts +27 -0
- package/packages/claude-code/src/index.ts +18 -0
- package/packages/claude-code/src/launcher.ts +265 -0
- package/packages/claude-code/src/main.ts +127 -0
- package/packages/claude-code/src/mcp.ts +109 -0
- package/packages/claude-code/src/paths.ts +34 -0
- package/packages/claude-code/src/plugin.ts +99 -0
- package/packages/claude-code/src/references.ts +51 -0
- package/packages/claude-code/src/sessions.ts +600 -0
- package/packages/claude-code/src/tools.ts +66 -0
- package/packages/claude-code/src/wire.ts +71 -0
- package/packages/claude-code/src/wrapper.ts +155 -0
- package/packages/cli/dist/hub-cli.js +10162 -0
- package/packages/codex/package.json +12 -0
- package/packages/codex/src/app-server.ts +44 -0
- package/packages/codex/src/ids.ts +28 -0
- package/packages/codex/src/index.ts +11 -0
- package/packages/codex/src/jsonrpc.ts +168 -0
- package/packages/codex/src/main.ts +122 -0
- package/packages/codex/src/paths.ts +65 -0
- package/packages/codex/src/sessions.ts +578 -0
- package/packages/codex/src/spoke.ts +249 -0
- package/packages/codex/src/stdio.ts +101 -0
- package/packages/codex/src/websocket.ts +206 -0
- package/packages/codex/src/wrapper.ts +100 -0
- package/packages/node/package.json +12 -0
- package/packages/node/src/config.ts +184 -0
- package/packages/node/src/connection.ts +283 -0
- package/packages/node/src/daemon.ts +281 -0
- package/packages/node/src/git.ts +107 -0
- package/packages/node/src/harnesses.ts +60 -0
- package/packages/node/src/host.ts +319 -0
- package/packages/node/src/index.ts +17 -0
- package/packages/node/src/main.ts +11 -0
- package/packages/node/src/openshell.ts +73 -0
- package/packages/node/src/run.ts +106 -0
- package/packages/preset/package.json +12 -0
- package/packages/preset/presets/aider.json +8 -0
- package/packages/preset/presets/goose.json +8 -0
- package/packages/preset/src/index.ts +2 -0
- package/packages/preset/src/main.ts +195 -0
- package/packages/preset/src/presets.ts +87 -0
- package/packages/preset/src/spoke.ts +251 -0
- package/packages/preset/src/tmux.ts +160 -0
- package/packages/protocol/package.json +12 -0
- package/packages/protocol/src/harness-events.ts +207 -0
- package/packages/protocol/src/index.ts +1215 -0
- package/packages/protocol/src/launch.ts +172 -0
- package/packages/protocol/src/node.ts +409 -0
- package/packages/protocol/src/preset.ts +144 -0
- package/packages/protocol/src/webhook.ts +62 -0
- package/packages/protocol/src/wire.ts +54 -0
- package/packages/runtime-openshell/image/Dockerfile +36 -0
- package/packages/runtime-openshell/image/README.md +78 -0
- package/packages/runtime-openshell/image/build.ts +203 -0
- package/packages/runtime-openshell/image/entry.sh +163 -0
- package/packages/runtime-openshell/image/image.ts +119 -0
- package/packages/runtime-openshell/image/start.sh +24 -0
- package/packages/runtime-openshell/package.json +12 -0
- package/packages/runtime-openshell/src/cli.ts +584 -0
- package/packages/runtime-openshell/src/index.ts +6 -0
- package/packages/runtime-openshell/src/policy.ts +155 -0
- package/packages/runtime-openshell/src/profiles.ts +181 -0
- package/packages/runtime-openshell/src/runtime.ts +475 -0
- package/packages/runtime-sdk/package.json +12 -0
- package/packages/runtime-sdk/src/index.ts +87 -0
- package/packages/sdk/package.json +12 -0
- package/packages/sdk/src/address.ts +25 -0
- package/packages/sdk/src/client.ts +502 -0
- package/packages/sdk/src/envelope.ts +108 -0
- package/packages/sdk/src/errors.ts +106 -0
- package/packages/sdk/src/index.ts +10 -0
- package/packages/sdk/src/sse.ts +67 -0
- package/packages/sdk/src/types.ts +458 -0
- package/packages/sdk/src/webhook.ts +102 -0
- package/packages/spoke-sdk/package.json +12 -0
- package/packages/spoke-sdk/src/activity.ts +3 -0
- package/packages/spoke-sdk/src/connection.ts +295 -0
- package/packages/spoke-sdk/src/delivery.ts +119 -0
- package/packages/spoke-sdk/src/enroll.ts +79 -0
- package/packages/spoke-sdk/src/harness-hello.ts +79 -0
- package/packages/spoke-sdk/src/harness-spoke.ts +263 -0
- package/packages/spoke-sdk/src/index.ts +12 -0
- package/packages/spoke-sdk/src/prompt-refs.ts +154 -0
- package/packages/spoke-sdk/src/prompt-source.ts +8 -0
- package/packages/spoke-sdk/src/session-ids.ts +49 -0
- package/packages/spoke-sdk/src/session-tokens.ts +78 -0
- package/scripts/hub-claude-code.service +34 -0
- package/scripts/hub-codex-spoke.service +34 -0
- package/scripts/hub-node.service +35 -0
- package/scripts/io.github.huynle.hub-claude-code.plist +53 -0
- package/scripts/io.github.huynle.hub-codex-spoke.plist +53 -0
- package/scripts/io.github.huynle.hub-node.plist +52 -0
- package/src/central/actions.ts +233 -0
- package/src/central/agent/acting-routes.ts +133 -0
- package/src/central/agent/acting-switch.ts +93 -0
- package/src/central/agent/acting.ts +599 -0
- package/src/central/agent/actor.ts +193 -0
- package/src/central/agent/app-tokens.ts +142 -0
- package/src/central/agent/audit.ts +185 -0
- package/src/central/agent/decisions.ts +530 -0
- package/src/central/agent/delivery.ts +678 -0
- package/src/central/agent/directory-routes.ts +185 -0
- package/src/central/agent/directory.ts +473 -0
- package/src/central/agent/envelope.ts +51 -0
- package/src/central/agent/errors.ts +72 -0
- package/src/central/agent/escalation.ts +219 -0
- package/src/central/agent/grant-requests.ts +221 -0
- package/src/central/agent/grant-routes.ts +70 -0
- package/src/central/agent/grants.ts +235 -0
- package/src/central/agent/launch-engine.ts +1025 -0
- package/src/central/agent/launch-routes.ts +252 -0
- package/src/central/agent/launch-spec.ts +289 -0
- package/src/central/agent/launch-store.ts +264 -0
- package/src/central/agent/launch-tokens.ts +206 -0
- package/src/central/agent/message-limits.ts +123 -0
- package/src/central/agent/message-routes.ts +385 -0
- package/src/central/agent/messages.ts +442 -0
- package/src/central/agent/names.ts +86 -0
- package/src/central/agent/placement.ts +419 -0
- package/src/central/agent/policy.ts +378 -0
- package/src/central/agent/read-routes.ts +389 -0
- package/src/central/agent/routes.ts +278 -0
- package/src/central/agent/session-tokens.ts +227 -0
- package/src/central/agent/versioned.ts +26 -0
- package/src/central/agent/watch.ts +221 -0
- package/src/central/agent/webhook-routes.ts +78 -0
- package/src/central/agent/webhooks.ts +449 -0
- package/src/central/agent-data.ts +177 -0
- package/src/central/auth.ts +224 -121
- package/src/central/backend/file-state.ts +240 -0
- package/src/central/backend/index.ts +113 -0
- package/src/central/backend/memory-bus.ts +93 -0
- package/src/central/backend/memory-catalog.ts +90 -0
- package/src/central/backend/memory-counters.ts +102 -0
- package/src/central/backend/memory-events.ts +45 -0
- package/src/central/backend/memory-kv.ts +38 -0
- package/src/central/backend/memory-state.ts +77 -0
- package/src/central/backend/postgres-migrate.ts +100 -0
- package/src/central/backend/postgres-state.ts +197 -0
- package/src/central/backend/types.ts +244 -0
- package/src/central/backend/valkey-bus.ts +425 -0
- package/src/central/backend/valkey-catalog.ts +190 -0
- package/src/central/backend/valkey-client.ts +36 -0
- package/src/central/backend/valkey-counters.ts +38 -0
- package/src/central/backend/valkey-events.ts +168 -0
- package/src/central/backend/valkey-kv.ts +54 -0
- package/src/central/backend/valkey-locks.ts +92 -0
- package/src/central/cluster/directory.ts +141 -0
- package/src/central/cluster/feed.ts +84 -0
- package/src/central/cluster/leader.ts +232 -0
- package/src/central/cluster/live.ts +151 -0
- package/src/central/cluster/recommend.ts +59 -0
- package/src/central/cluster/rpc.ts +150 -0
- package/src/central/cluster/view.ts +232 -0
- package/src/central/config.ts +197 -3
- package/src/central/done.ts +96 -0
- package/src/central/events-log.ts +100 -0
- package/src/central/http.ts +1067 -171
- package/src/central/import.ts +318 -0
- package/src/central/main.ts +211 -12
- package/src/central/nodes.ts +314 -0
- package/src/central/oidc.ts +34 -14
- package/src/central/push-target.ts +118 -18
- package/src/central/push.ts +256 -82
- package/src/central/registry.ts +902 -92
- package/src/central/say-stream.ts +128 -0
- package/src/central/session-token-push.ts +233 -0
- package/src/central/speech/openai.ts +21 -14
- package/src/central/speech/openrouter.ts +27 -10
- package/src/central/speech/provider.ts +54 -0
- package/src/central/speech/service.ts +22 -7
- package/src/central/spoke-ws.ts +522 -44
- package/src/central/store-shared.ts +518 -0
- package/src/central/store.ts +572 -189
- package/src/central/token-keys.ts +165 -0
- package/src/config.ts +49 -1
- package/src/index.ts +165 -12
- package/src/protocol.ts +3 -650
- package/src/rpc.ts +27 -2
- package/src/spoke/client.ts +3 -272
- package/src/spoke/conversation.ts +16 -12
- package/src/spoke/deliver.ts +75 -0
- package/src/spoke/enroll.ts +2 -79
- package/src/spoke/env-inject.ts +160 -0
- package/src/spoke/hub-rpc.ts +115 -0
- package/src/spoke/hub-tool.ts +409 -0
- package/src/spoke/launch-source.ts +22 -0
- package/src/spoke/launchers.ts +68 -0
- package/src/spoke/locations.ts +3 -2
- package/src/spoke/node-roots.ts +61 -0
- package/src/spoke/prompt-refs.ts +116 -0
- package/src/spoke/session-tokens.ts +2 -0
- package/src/spoke/spoke.ts +465 -28
- package/src/spoke/taskboard.ts +243 -0
- package/src/spoke/timeline.ts +184 -6
- package/src/spoke/tracker.ts +79 -4
- package/src/status.ts +203 -10
- package/src/tui-commands.ts +13 -6
- package/src/tui-messaging.ts +93 -0
- package/src/tui.ts +15 -0
- package/web/dist/assets/highlight-y4rJE6Tt.js +5 -0
- package/web/dist/assets/index-D9zMbxSg.css +1 -0
- package/web/dist/assets/index-db1z4duA.js +20 -0
- package/web/dist/assets/ort-wasm-simd-threaded-CxTQ5xH-.wasm +0 -0
- package/web/dist/assets/silero-worker-C8-8vLVS.js +11 -0
- package/web/dist/assets/silero_vad-Dt9-bTDn.onnx +0 -0
- package/web/dist/index.html +9 -2
- package/web/dist/sw.js +79 -15
- package/web/dist/assets/index-DClBvfLL.css +0 -1
- package/web/dist/assets/index-Djo_yF0a.js +0 -12
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Recent live-stream messages per user, so a console that reconnects (phone unlocked, tab back in view, network
|
|
2
|
+
// blip) gets what it missed (EventSource's Last-Event-ID) instead of a full reload. Ids are `<epoch>.<n>`: n
|
|
3
|
+
// counts per user from 1; the epoch changes with every hub start, so an id from before a restart is never
|
|
4
|
+
// mistaken for a current one. Bounded by count and age per user.
|
|
5
|
+
|
|
6
|
+
export type LoggedMessage = { type: string; [key: string]: unknown }
|
|
7
|
+
|
|
8
|
+
export interface Logged {
|
|
9
|
+
readonly id: string
|
|
10
|
+
readonly message: LoggedMessage
|
|
11
|
+
/** Not for this device (the one that made the change). */
|
|
12
|
+
readonly exceptDevice?: string
|
|
13
|
+
readonly at: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Events kept per user. */
|
|
17
|
+
export const EVENT_LOG_MAX = 2000
|
|
18
|
+
/** Events older than this are dropped. */
|
|
19
|
+
export const EVENT_LOG_AGE_MS = 5 * 60_000
|
|
20
|
+
|
|
21
|
+
interface UserLog {
|
|
22
|
+
/** n of the last appended event (0: none yet). */
|
|
23
|
+
last: number
|
|
24
|
+
events: Logged[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class EventLog {
|
|
28
|
+
readonly epoch: string
|
|
29
|
+
private readonly max: number
|
|
30
|
+
private readonly maxAgeMs: number
|
|
31
|
+
private readonly now: () => number
|
|
32
|
+
private readonly logs = new Map<string, UserLog>()
|
|
33
|
+
|
|
34
|
+
constructor(options: { max?: number; maxAgeMs?: number; now?: () => number; epoch?: string } = {}) {
|
|
35
|
+
this.max = options.max ?? EVENT_LOG_MAX
|
|
36
|
+
this.maxAgeMs = options.maxAgeMs ?? EVENT_LOG_AGE_MS
|
|
37
|
+
this.now = options.now ?? Date.now
|
|
38
|
+
this.epoch = options.epoch ?? `${Date.now().toString(36)}${Math.floor(Math.random() * 1296).toString(36)}`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Records a message for a user; returns its id. */
|
|
42
|
+
append(userID: string, message: LoggedMessage, exceptDevice?: string): string {
|
|
43
|
+
const log = this.log(userID)
|
|
44
|
+
const id = `${this.epoch}.${++log.last}`
|
|
45
|
+
log.events.push({ id, message, at: this.now(), ...(exceptDevice ? { exceptDevice } : {}) })
|
|
46
|
+
if (log.events.length > this.max) log.events.splice(0, log.events.length - this.max)
|
|
47
|
+
this.prune(log)
|
|
48
|
+
return id
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** The id of the user's latest event (`<epoch>.0` before the first). */
|
|
52
|
+
latest(userID: string): string {
|
|
53
|
+
return `${this.epoch}.${this.logs.get(userID)?.last ?? 0}`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The user's events after `lastID`, oldest first; undefined when the log cannot cover the gap (another hub
|
|
58
|
+
* start, an id it never gave out, a user it does not know, or events since dropped).
|
|
59
|
+
*/
|
|
60
|
+
since(userID: string, lastID: string): Logged[] | undefined {
|
|
61
|
+
const log = this.logs.get(userID)
|
|
62
|
+
const match = /^([a-z0-9]+)\.(\d+)$/.exec(lastID)
|
|
63
|
+
if (!log || !match || match[1] !== this.epoch) return undefined
|
|
64
|
+
const n = Number(match[2])
|
|
65
|
+
if (!Number.isSafeInteger(n) || n > log.last) return undefined
|
|
66
|
+
this.prune(log)
|
|
67
|
+
if (n === log.last) return []
|
|
68
|
+
const first = log.events[0]
|
|
69
|
+
// The next event the client needs (n + 1) must still be here.
|
|
70
|
+
if (!first || this.number(first.id) > n + 1) return undefined
|
|
71
|
+
return log.events.filter((event) => this.number(event.id) > n)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Users with a log (they connected or were sent something since the hub started). */
|
|
75
|
+
users(): string[] {
|
|
76
|
+
return [...this.logs.keys()]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Starts a user's log (so a reconnect after their first message can be replayed). */
|
|
80
|
+
open(userID: string): void {
|
|
81
|
+
this.log(userID)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private log(userID: string): UserLog {
|
|
85
|
+
let log = this.logs.get(userID)
|
|
86
|
+
if (!log) this.logs.set(userID, (log = { last: 0, events: [] }))
|
|
87
|
+
return log
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private prune(log: UserLog): void {
|
|
91
|
+
const oldest = this.now() - this.maxAgeMs
|
|
92
|
+
let drop = 0
|
|
93
|
+
while (drop < log.events.length && log.events[drop]!.at < oldest) drop++
|
|
94
|
+
if (drop) log.events.splice(0, drop)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private number(id: string): number {
|
|
98
|
+
return Number(id.slice(id.lastIndexOf(".") + 1))
|
|
99
|
+
}
|
|
100
|
+
}
|