@agentdeck/bridge 1.0.4 → 1.0.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/assets/fm-helper/agentdeck-fm-helper +0 -0
- package/dist/adapters/claude-code.d.ts.map +1 -1
- package/dist/adapters/claude-code.js +3 -0
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adb-reverse.d.ts.map +1 -1
- package/dist/adb-reverse.js +4 -2
- package/dist/adb-reverse.js.map +1 -1
- package/dist/apme/collector.js +2 -2
- package/dist/apme/collector.js.map +1 -1
- package/dist/apme/outcome.js +2 -2
- package/dist/apme/outcome.js.map +1 -1
- package/dist/apme/runner.js +3 -3
- package/dist/apme/runner.js.map +1 -1
- package/dist/ble-sync-spawn.js +1 -1
- package/dist/ble-sync-spawn.js.map +1 -1
- package/dist/calendar.d.ts +82 -0
- package/dist/calendar.d.ts.map +1 -0
- package/dist/calendar.js +324 -0
- package/dist/calendar.js.map +1 -0
- package/dist/card-feed.d.ts +63 -5
- package/dist/card-feed.d.ts.map +1 -1
- package/dist/card-feed.js +218 -14
- package/dist/card-feed.js.map +1 -1
- package/dist/card-modules.d.ts +4 -0
- package/dist/card-modules.d.ts.map +1 -1
- package/dist/card-modules.js +5 -3
- package/dist/card-modules.js.map +1 -1
- package/dist/check-deps.js +4 -4
- package/dist/check-deps.js.map +1 -1
- package/dist/cli.d.ts +35 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +269 -9
- package/dist/cli.js.map +1 -1
- package/dist/codex-otel.d.ts +89 -0
- package/dist/codex-otel.d.ts.map +1 -0
- package/dist/codex-otel.js +487 -0
- package/dist/codex-otel.js.map +1 -0
- package/dist/codex-rate-limits.d.ts.map +1 -1
- package/dist/codex-rate-limits.js +15 -3
- package/dist/codex-rate-limits.js.map +1 -1
- package/dist/daemon-server.d.ts +4 -0
- package/dist/daemon-server.d.ts.map +1 -1
- package/dist/daemon-server.js +797 -54
- package/dist/daemon-server.js.map +1 -1
- package/dist/daemon-ws-client.d.ts +108 -24
- package/dist/daemon-ws-client.d.ts.map +1 -1
- package/dist/daemon-ws-client.js +175 -39
- package/dist/daemon-ws-client.js.map +1 -1
- package/dist/daemon.js +1 -1
- package/dist/device-voice-reply.d.ts.map +1 -1
- package/dist/device-voice-reply.js +15 -3
- package/dist/device-voice-reply.js.map +1 -1
- package/dist/device-voice.d.ts +37 -0
- package/dist/device-voice.d.ts.map +1 -1
- package/dist/device-voice.js +130 -1
- package/dist/device-voice.js.map +1 -1
- package/dist/diag-analyzer.d.ts.map +1 -1
- package/dist/diag-analyzer.js +1 -0
- package/dist/diag-analyzer.js.map +1 -1
- package/dist/display-monitor.d.ts.map +1 -1
- package/dist/display-monitor.js +1 -0
- package/dist/display-monitor.js.map +1 -1
- package/dist/esp32-serial.d.ts +4 -0
- package/dist/esp32-serial.d.ts.map +1 -1
- package/dist/esp32-serial.js +6 -3
- package/dist/esp32-serial.js.map +1 -1
- package/dist/foundation-models-helper.d.ts +23 -0
- package/dist/foundation-models-helper.d.ts.map +1 -1
- package/dist/foundation-models-helper.js +32 -0
- package/dist/foundation-models-helper.js.map +1 -1
- package/dist/gateway-probe.js +1 -1
- package/dist/gateway-probe.js.map +1 -1
- package/dist/glance-frame.d.ts +64 -0
- package/dist/glance-frame.d.ts.map +1 -0
- package/dist/glance-frame.js +364 -0
- package/dist/glance-frame.js.map +1 -0
- package/dist/hook-codex-sessions.d.ts +40 -0
- package/dist/hook-codex-sessions.d.ts.map +1 -0
- package/dist/hook-codex-sessions.js +174 -0
- package/dist/hook-codex-sessions.js.map +1 -0
- package/dist/idotmatrix/idotmatrix-discover.d.ts.map +1 -1
- package/dist/idotmatrix/idotmatrix-discover.js +7 -4
- package/dist/idotmatrix/idotmatrix-discover.js.map +1 -1
- package/dist/idotmatrix/idotmatrix-settings.d.ts +15 -0
- package/dist/idotmatrix/idotmatrix-settings.d.ts.map +1 -1
- package/dist/idotmatrix/idotmatrix-settings.js +21 -0
- package/dist/idotmatrix/idotmatrix-settings.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +88 -7
- package/dist/index.js.map +1 -1
- package/dist/linux-service.d.ts +52 -0
- package/dist/linux-service.d.ts.map +1 -0
- package/dist/linux-service.js +206 -0
- package/dist/linux-service.js.map +1 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +15 -0
- package/dist/logger.js.map +1 -1
- package/dist/mdns-discover.d.ts +19 -0
- package/dist/mdns-discover.d.ts.map +1 -0
- package/dist/mdns-discover.js +109 -0
- package/dist/mdns-discover.js.map +1 -0
- package/dist/model-catalog.d.ts.map +1 -1
- package/dist/model-catalog.js +1 -0
- package/dist/model-catalog.js.map +1 -1
- package/dist/modules/adb-module.js +1 -1
- package/dist/modules/adb-module.js.map +1 -1
- package/dist/output-parser.d.ts +9 -0
- package/dist/output-parser.d.ts.map +1 -1
- package/dist/output-parser.js +67 -16
- package/dist/output-parser.js.map +1 -1
- package/dist/passive-observer.d.ts +57 -8
- package/dist/passive-observer.d.ts.map +1 -1
- package/dist/passive-observer.js +210 -74
- package/dist/passive-observer.js.map +1 -1
- package/dist/pixoo/pixoo-bridge.d.ts.map +1 -1
- package/dist/pixoo/pixoo-bridge.js +47 -6
- package/dist/pixoo/pixoo-bridge.js.map +1 -1
- package/dist/pixoo/pixoo-renderer.d.ts +2 -1
- package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
- package/dist/pixoo/pixoo-renderer.js +137 -8
- package/dist/pixoo/pixoo-renderer.js.map +1 -1
- package/dist/pocket-autonomy.d.ts +78 -0
- package/dist/pocket-autonomy.d.ts.map +1 -0
- package/dist/pocket-autonomy.js +529 -0
- package/dist/pocket-autonomy.js.map +1 -0
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-manager.js +3 -2
- package/dist/pty-manager.js.map +1 -1
- package/dist/python-ble-runtime.d.ts +2 -0
- package/dist/python-ble-runtime.d.ts.map +1 -1
- package/dist/python-ble-runtime.js +2 -1
- package/dist/python-ble-runtime.js.map +1 -1
- package/dist/remote-sessions.d.ts +64 -0
- package/dist/remote-sessions.d.ts.map +1 -0
- package/dist/remote-sessions.js +81 -0
- package/dist/remote-sessions.js.map +1 -0
- package/dist/review-runner.js +2 -2
- package/dist/review-runner.js.map +1 -1
- package/dist/session-aggregator.d.ts +2 -0
- package/dist/session-aggregator.d.ts.map +1 -1
- package/dist/session-aggregator.js +6 -1
- package/dist/session-aggregator.js.map +1 -1
- package/dist/session-focus-relay.d.ts +47 -1
- package/dist/session-focus-relay.d.ts.map +1 -1
- package/dist/session-focus-relay.js +130 -15
- package/dist/session-focus-relay.js.map +1 -1
- package/dist/session-push-channel.d.ts +31 -0
- package/dist/session-push-channel.d.ts.map +1 -0
- package/dist/session-push-channel.js +94 -0
- package/dist/session-push-channel.js.map +1 -0
- package/dist/session-registry.d.ts +126 -0
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/session-registry.js +180 -3
- package/dist/session-registry.js.map +1 -1
- package/dist/subagent-timeline.d.ts +34 -0
- package/dist/subagent-timeline.d.ts.map +1 -0
- package/dist/subagent-timeline.js +156 -0
- package/dist/subagent-timeline.js.map +1 -0
- package/dist/timebox/timebox-discover.js +1 -1
- package/dist/timebox/timebox-discover.js.map +1 -1
- package/dist/tui/gauge.d.ts +4 -2
- package/dist/tui/gauge.d.ts.map +1 -1
- package/dist/tui/gauge.js +8 -4
- package/dist/tui/gauge.js.map +1 -1
- package/dist/tui/renderer.d.ts.map +1 -1
- package/dist/tui/renderer.js +28 -0
- package/dist/tui/renderer.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/usage-api.d.ts +43 -0
- package/dist/usage-api.d.ts.map +1 -1
- package/dist/usage-api.js +114 -9
- package/dist/usage-api.js.map +1 -1
- package/dist/usage-event.d.ts +19 -0
- package/dist/usage-event.d.ts.map +1 -1
- package/dist/usage-event.js +35 -0
- package/dist/usage-event.js.map +1 -1
- package/dist/utils/project-name.d.ts.map +1 -1
- package/dist/utils/project-name.js +1 -0
- package/dist/utils/project-name.js.map +1 -1
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +3 -2
- package/dist/version-check.js.map +1 -1
- package/dist/voice-assistant.d.ts.map +1 -1
- package/dist/voice-assistant.js +2 -1
- package/dist/voice-assistant.js.map +1 -1
- package/dist/voice.d.ts.map +1 -1
- package/dist/voice.js +1 -0
- package/dist/voice.js.map +1 -1
- package/dist/weather.d.ts +72 -0
- package/dist/weather.d.ts.map +1 -0
- package/dist/weather.js +206 -0
- package/dist/weather.js.map +1 -0
- package/dist/windows-service.js +5 -5
- package/dist/windows-service.js.map +1 -1
- package/fm-helper/AgentDeckFMHelper.swift +200 -0
- package/package.json +15 -13
- package/src/idotmatrix/identity_generated.py +50 -0
- package/src/idotmatrix/scan.py +33 -13
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* 3. On state_changed, sends `session_push_state` with state + modelName
|
|
11
11
|
* 4. Reconnects with exponential backoff on disconnect
|
|
12
12
|
*/
|
|
13
|
+
import { type DaemonTarget } from './session-registry.js';
|
|
14
|
+
import type { PluginCommand, BridgeEvent } from './types.js';
|
|
13
15
|
export interface SessionPushState {
|
|
14
16
|
type: 'session_push_state';
|
|
15
17
|
sessionId: string;
|
|
@@ -26,57 +28,139 @@ export interface SessionPushRegister {
|
|
|
26
28
|
port: number;
|
|
27
29
|
agentType?: string;
|
|
28
30
|
projectName?: string;
|
|
31
|
+
/** This session's LAN host (display / diagnostics on the daemon side). */
|
|
32
|
+
host?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Explicit remote-attach intent. Sent only when the user opted in
|
|
35
|
+
* (`--remote-daemon`) AND the resolved daemon advertises `sameSocketControl`.
|
|
36
|
+
* The daemon must trust this flag over the socket's source IP: an
|
|
37
|
+
* `ssh -L`-forwarded worker arrives on loopback and is indistinguishable
|
|
38
|
+
* from a local session by IP alone.
|
|
39
|
+
*/
|
|
40
|
+
remoteAttach?: boolean;
|
|
41
|
+
/** Explicit deck/tab sort override. Always sent as a concrete integer
|
|
42
|
+
* (unweighted ⇒ 0, never omitted) — receivers merge retain-on-absent, so an
|
|
43
|
+
* only-sent-when-set field could be set but never reset. See shared
|
|
44
|
+
* sessionWeight / SESSION_WEIGHT_MIN..MAX. */
|
|
45
|
+
weight: number;
|
|
46
|
+
}
|
|
47
|
+
/** Daemon → worker: run a plugin command against this session (same-socket reverse control). */
|
|
48
|
+
export interface SessionCommandDown {
|
|
49
|
+
type: 'session_command_down';
|
|
50
|
+
sessionId: string;
|
|
51
|
+
command: PluginCommand;
|
|
52
|
+
}
|
|
53
|
+
/** Worker → daemon: a relayed session event, riding back up the push socket. */
|
|
54
|
+
export interface SessionEventUp {
|
|
55
|
+
type: 'session_event_up';
|
|
56
|
+
sessionId: string;
|
|
57
|
+
event: BridgeEvent;
|
|
58
|
+
}
|
|
59
|
+
/** Daemon → worker: (un)focus — the worker forwards events up only while focused. */
|
|
60
|
+
export interface SessionFocusDown {
|
|
61
|
+
type: 'session_focus_down' | 'session_unfocus_down';
|
|
62
|
+
sessionId: string;
|
|
29
63
|
}
|
|
30
64
|
export declare class DaemonWsClient {
|
|
31
65
|
private readonly sessionId;
|
|
32
66
|
private readonly sessionPort;
|
|
33
67
|
private readonly agentType?;
|
|
34
68
|
private readonly projectName?;
|
|
69
|
+
/** Deck/tab sort override; normalized via shared sessionWeight() at send time. */
|
|
70
|
+
private readonly weight?;
|
|
35
71
|
/**
|
|
36
|
-
* Resolves the
|
|
37
|
-
* client follow port drift (daemon restart
|
|
38
|
-
*
|
|
72
|
+
* Resolves the daemon target (host + port + optional token) on each
|
|
73
|
+
* (re)connect attempt. Lets the client follow port drift (daemon restart
|
|
74
|
+
* onto a fallback port), cover the daemon-not-up-yet case, and — when the
|
|
75
|
+
* remote-attach path is enabled — discover a daemon on another machine.
|
|
39
76
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* does exactly this to cover the App-Store-vs-CLI data-dir split.
|
|
44
|
-
*
|
|
45
|
-
* Return `null` to defer — the client will keep retrying on backoff.
|
|
77
|
+
* `resolveDaemonTarget` in `session-registry.ts` is the canonical provider
|
|
78
|
+
* (local → explicit host → mDNS). Return `null` to defer; the client keeps
|
|
79
|
+
* retrying on backoff.
|
|
46
80
|
*/
|
|
47
|
-
private readonly
|
|
81
|
+
private readonly targetProvider?;
|
|
82
|
+
/** This session's LAN host (display / diagnostics on the daemon side). */
|
|
83
|
+
private readonly sessionHost?;
|
|
84
|
+
/**
|
|
85
|
+
* User opted in to remote attach (`--remote-daemon` /
|
|
86
|
+
* `AGENTDECK_REMOTE_DAEMON=1`). Combined per-target with the daemon's
|
|
87
|
+
* advertised `sameSocketControl` capability to decide whether the
|
|
88
|
+
* registration carries `remoteAttach: true`, and to refuse dialing a
|
|
89
|
+
* capability-less target at all.
|
|
90
|
+
*/
|
|
91
|
+
private readonly remoteEnabled?;
|
|
48
92
|
private ws;
|
|
49
|
-
private
|
|
93
|
+
private target;
|
|
50
94
|
private reconnectTimer;
|
|
95
|
+
private readonly reconnectBase;
|
|
51
96
|
private reconnectDelay;
|
|
52
97
|
private closed;
|
|
53
98
|
private registered;
|
|
99
|
+
/** True while a remote daemon has focused this session (same-socket reverse). */
|
|
100
|
+
private focused;
|
|
101
|
+
/** Applies a command the daemon sent down the socket — same handler as the local WS server. */
|
|
102
|
+
private applyCommand;
|
|
103
|
+
/** Yields the initial events to emit up when the daemon focuses this session. */
|
|
104
|
+
private focusSnapshot;
|
|
54
105
|
constructor(sessionId: string, sessionPort: number, agentType?: string | undefined, projectName?: string | undefined,
|
|
106
|
+
/** Deck/tab sort override; normalized via shared sessionWeight() at send time. */
|
|
107
|
+
weight?: number | undefined,
|
|
55
108
|
/**
|
|
56
|
-
* Resolves the
|
|
57
|
-
* client follow port drift (daemon restart
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* May be sync (`number | null`) or async (`Promise<number | null>`). The
|
|
61
|
-
* async shape exists so callers can run a `/health` probe fallback when
|
|
62
|
-
* the registry is empty — `findDaemonPortAsync` in `session-registry.ts`
|
|
63
|
-
* does exactly this to cover the App-Store-vs-CLI data-dir split.
|
|
109
|
+
* Resolves the daemon target (host + port + optional token) on each
|
|
110
|
+
* (re)connect attempt. Lets the client follow port drift (daemon restart
|
|
111
|
+
* onto a fallback port), cover the daemon-not-up-yet case, and — when the
|
|
112
|
+
* remote-attach path is enabled — discover a daemon on another machine.
|
|
64
113
|
*
|
|
65
|
-
*
|
|
114
|
+
* `resolveDaemonTarget` in `session-registry.ts` is the canonical provider
|
|
115
|
+
* (local → explicit host → mDNS). Return `null` to defer; the client keeps
|
|
116
|
+
* retrying on backoff.
|
|
66
117
|
*/
|
|
67
|
-
|
|
118
|
+
targetProvider?: (() => DaemonTarget | null | Promise<DaemonTarget | null>) | undefined,
|
|
119
|
+
/** This session's LAN host (display / diagnostics on the daemon side). */
|
|
120
|
+
sessionHost?: string | undefined,
|
|
68
121
|
/**
|
|
69
|
-
*
|
|
122
|
+
* User opted in to remote attach (`--remote-daemon` /
|
|
123
|
+
* `AGENTDECK_REMOTE_DAEMON=1`). Combined per-target with the daemon's
|
|
124
|
+
* advertised `sameSocketControl` capability to decide whether the
|
|
125
|
+
* registration carries `remoteAttach: true`, and to refuse dialing a
|
|
126
|
+
* capability-less target at all.
|
|
127
|
+
*/
|
|
128
|
+
remoteEnabled?: boolean | undefined,
|
|
129
|
+
/** Reconnect backoff base in ms — injectable so tests don't wait out real 2s+ backoffs. */
|
|
130
|
+
reconnectBaseMs?: number);
|
|
131
|
+
/**
|
|
132
|
+
* Start the connection loop. If `target` is null and a `targetProvider`
|
|
70
133
|
* was supplied, the client waits on backoff until the provider yields a
|
|
71
|
-
*
|
|
134
|
+
* target (daemon catches up on a later launch).
|
|
135
|
+
*
|
|
136
|
+
* Note: when a `targetProvider` exists, its result — null included —
|
|
137
|
+
* replaces this seed on every (re)connect attempt; the seed only covers
|
|
138
|
+
* the very first dial in provider-less usage.
|
|
72
139
|
*/
|
|
73
|
-
connect(
|
|
140
|
+
connect(target: DaemonTarget | null): void;
|
|
141
|
+
/**
|
|
142
|
+
* Enable same-socket reverse control. When a remote daemon focuses this
|
|
143
|
+
* session it sends `session_command_down` frames back down the push socket
|
|
144
|
+
* (no inbound dial to our port — works for NAT'd / SSH-only workers).
|
|
145
|
+
* `applyCommand` feeds inner commands into the same handler the local WS
|
|
146
|
+
* server uses; `focusSnapshot` yields the initial events to emit up on focus.
|
|
147
|
+
*/
|
|
148
|
+
setReverseControl(applyCommand: (cmd: PluginCommand) => void, focusSnapshot: () => BridgeEvent[]): void;
|
|
149
|
+
/** Forward a broadcast event up the push socket while the daemon has us focused. */
|
|
150
|
+
forwardEvent(evt: BridgeEvent): void;
|
|
74
151
|
/** Push state update to daemon */
|
|
75
152
|
pushState(state: string, modelName?: string, effortLevel?: string, permissionMode?: string): void;
|
|
76
153
|
/** Clean shutdown */
|
|
77
154
|
close(): void;
|
|
78
155
|
get isConnected(): boolean;
|
|
79
156
|
private doConnect;
|
|
157
|
+
/**
|
|
158
|
+
* Build the register frame (exposed for tests). `weight` is always a
|
|
159
|
+
* concrete integer — the Swift daemon preserves an existing weight when the
|
|
160
|
+
* key is absent (legacy senders), so a current sender must send the explicit
|
|
161
|
+
* 0 to be able to reset one.
|
|
162
|
+
*/
|
|
163
|
+
buildRegisterFrame(): SessionPushRegister;
|
|
80
164
|
private sendRegister;
|
|
81
165
|
private scheduleReconnect;
|
|
82
166
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-ws-client.d.ts","sourceRoot":"","sources":["../src/daemon-ws-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"daemon-ws-client.d.ts","sourceRoot":"","sources":["../src/daemon-ws-client.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon-ws-client.js
CHANGED
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
* 4. Reconnects with exponential backoff on disconnect
|
|
12
12
|
*/
|
|
13
13
|
import WebSocket from 'ws';
|
|
14
|
+
import { sessionWeight } from '@agentdeck/shared';
|
|
14
15
|
import { debug } from './logger.js';
|
|
16
|
+
import { isLoopbackHost, formatHostForUrl } from './session-registry.js';
|
|
17
|
+
// Canonical relayed-event set — shared with the daemon side so the two ends of
|
|
18
|
+
// the push socket cannot drift on which events are worth forwarding.
|
|
19
|
+
import { RELAYED_EVENTS } from './session-focus-relay.js';
|
|
15
20
|
const TAG = 'DaemonWsClient';
|
|
16
21
|
const RECONNECT_BASE = 2000;
|
|
17
22
|
const RECONNECT_MAX = 30000;
|
|
@@ -20,49 +25,103 @@ export class DaemonWsClient {
|
|
|
20
25
|
sessionPort;
|
|
21
26
|
agentType;
|
|
22
27
|
projectName;
|
|
23
|
-
|
|
28
|
+
weight;
|
|
29
|
+
targetProvider;
|
|
30
|
+
sessionHost;
|
|
31
|
+
remoteEnabled;
|
|
24
32
|
ws = null;
|
|
25
|
-
|
|
33
|
+
target = null;
|
|
26
34
|
reconnectTimer = null;
|
|
27
|
-
|
|
35
|
+
reconnectBase;
|
|
36
|
+
reconnectDelay;
|
|
28
37
|
closed = false;
|
|
29
38
|
registered = false;
|
|
39
|
+
/** True while a remote daemon has focused this session (same-socket reverse). */
|
|
40
|
+
focused = false;
|
|
41
|
+
/** Applies a command the daemon sent down the socket — same handler as the local WS server. */
|
|
42
|
+
applyCommand = null;
|
|
43
|
+
/** Yields the initial events to emit up when the daemon focuses this session. */
|
|
44
|
+
focusSnapshot = null;
|
|
30
45
|
constructor(sessionId, sessionPort, agentType, projectName,
|
|
46
|
+
/** Deck/tab sort override; normalized via shared sessionWeight() at send time. */
|
|
47
|
+
weight,
|
|
31
48
|
/**
|
|
32
|
-
* Resolves the
|
|
33
|
-
* client follow port drift (daemon restart
|
|
34
|
-
*
|
|
49
|
+
* Resolves the daemon target (host + port + optional token) on each
|
|
50
|
+
* (re)connect attempt. Lets the client follow port drift (daemon restart
|
|
51
|
+
* onto a fallback port), cover the daemon-not-up-yet case, and — when the
|
|
52
|
+
* remote-attach path is enabled — discover a daemon on another machine.
|
|
35
53
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
54
|
+
* `resolveDaemonTarget` in `session-registry.ts` is the canonical provider
|
|
55
|
+
* (local → explicit host → mDNS). Return `null` to defer; the client keeps
|
|
56
|
+
* retrying on backoff.
|
|
57
|
+
*/
|
|
58
|
+
targetProvider,
|
|
59
|
+
/** This session's LAN host (display / diagnostics on the daemon side). */
|
|
60
|
+
sessionHost,
|
|
61
|
+
/**
|
|
62
|
+
* User opted in to remote attach (`--remote-daemon` /
|
|
63
|
+
* `AGENTDECK_REMOTE_DAEMON=1`). Combined per-target with the daemon's
|
|
64
|
+
* advertised `sameSocketControl` capability to decide whether the
|
|
65
|
+
* registration carries `remoteAttach: true`, and to refuse dialing a
|
|
66
|
+
* capability-less target at all.
|
|
42
67
|
*/
|
|
43
|
-
|
|
68
|
+
remoteEnabled,
|
|
69
|
+
/** Reconnect backoff base in ms — injectable so tests don't wait out real 2s+ backoffs. */
|
|
70
|
+
reconnectBaseMs) {
|
|
44
71
|
this.sessionId = sessionId;
|
|
45
72
|
this.sessionPort = sessionPort;
|
|
46
73
|
this.agentType = agentType;
|
|
47
74
|
this.projectName = projectName;
|
|
48
|
-
this.
|
|
75
|
+
this.weight = weight;
|
|
76
|
+
this.targetProvider = targetProvider;
|
|
77
|
+
this.sessionHost = sessionHost;
|
|
78
|
+
this.remoteEnabled = remoteEnabled;
|
|
79
|
+
this.reconnectBase = reconnectBaseMs ?? RECONNECT_BASE;
|
|
80
|
+
this.reconnectDelay = this.reconnectBase;
|
|
49
81
|
}
|
|
50
82
|
/**
|
|
51
|
-
* Start the connection loop. If `
|
|
83
|
+
* Start the connection loop. If `target` is null and a `targetProvider`
|
|
52
84
|
* was supplied, the client waits on backoff until the provider yields a
|
|
53
|
-
*
|
|
85
|
+
* target (daemon catches up on a later launch).
|
|
86
|
+
*
|
|
87
|
+
* Note: when a `targetProvider` exists, its result — null included —
|
|
88
|
+
* replaces this seed on every (re)connect attempt; the seed only covers
|
|
89
|
+
* the very first dial in provider-less usage.
|
|
54
90
|
*/
|
|
55
|
-
connect(
|
|
91
|
+
connect(target) {
|
|
56
92
|
if (this.closed)
|
|
57
93
|
return;
|
|
58
|
-
if (
|
|
59
|
-
this.
|
|
94
|
+
if (target != null) {
|
|
95
|
+
this.target = target;
|
|
60
96
|
void this.doConnect();
|
|
61
97
|
}
|
|
62
98
|
else {
|
|
63
99
|
this.scheduleReconnect();
|
|
64
100
|
}
|
|
65
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Enable same-socket reverse control. When a remote daemon focuses this
|
|
104
|
+
* session it sends `session_command_down` frames back down the push socket
|
|
105
|
+
* (no inbound dial to our port — works for NAT'd / SSH-only workers).
|
|
106
|
+
* `applyCommand` feeds inner commands into the same handler the local WS
|
|
107
|
+
* server uses; `focusSnapshot` yields the initial events to emit up on focus.
|
|
108
|
+
*/
|
|
109
|
+
setReverseControl(applyCommand, focusSnapshot) {
|
|
110
|
+
this.applyCommand = applyCommand;
|
|
111
|
+
this.focusSnapshot = focusSnapshot;
|
|
112
|
+
}
|
|
113
|
+
/** Forward a broadcast event up the push socket while the daemon has us focused. */
|
|
114
|
+
forwardEvent(evt) {
|
|
115
|
+
if (!this.focused || !this.ws || this.ws.readyState !== WebSocket.OPEN)
|
|
116
|
+
return;
|
|
117
|
+
if (!RELAYED_EVENTS.has(evt.type))
|
|
118
|
+
return;
|
|
119
|
+
const msg = { type: 'session_event_up', sessionId: this.sessionId, event: evt };
|
|
120
|
+
try {
|
|
121
|
+
this.ws.send(JSON.stringify(msg));
|
|
122
|
+
}
|
|
123
|
+
catch { /* socket closing */ }
|
|
124
|
+
}
|
|
66
125
|
/** Push state update to daemon */
|
|
67
126
|
pushState(state, modelName, effortLevel, permissionMode) {
|
|
68
127
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN)
|
|
@@ -88,10 +147,20 @@ export class DaemonWsClient {
|
|
|
88
147
|
}
|
|
89
148
|
if (this.ws) {
|
|
90
149
|
this.ws.removeAllListeners();
|
|
91
|
-
|
|
150
|
+
// ws throws if closed while still CONNECTING — terminate covers that case.
|
|
151
|
+
try {
|
|
152
|
+
this.ws.close();
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
try {
|
|
156
|
+
this.ws.terminate();
|
|
157
|
+
}
|
|
158
|
+
catch { /* ignore */ }
|
|
159
|
+
}
|
|
92
160
|
this.ws = null;
|
|
93
161
|
}
|
|
94
162
|
this.registered = false;
|
|
163
|
+
this.focused = false;
|
|
95
164
|
}
|
|
96
165
|
get isConnected() {
|
|
97
166
|
return this.ws?.readyState === WebSocket.OPEN && this.registered;
|
|
@@ -100,23 +169,37 @@ export class DaemonWsClient {
|
|
|
100
169
|
async doConnect() {
|
|
101
170
|
if (this.closed)
|
|
102
171
|
return;
|
|
103
|
-
if (this.
|
|
172
|
+
if (this.targetProvider) {
|
|
104
173
|
let resolved;
|
|
105
174
|
try {
|
|
106
|
-
resolved = await this.
|
|
175
|
+
resolved = await this.targetProvider();
|
|
107
176
|
}
|
|
108
177
|
catch (err) {
|
|
109
|
-
debug(TAG, `
|
|
178
|
+
debug(TAG, `targetProvider threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
110
179
|
resolved = null;
|
|
111
180
|
}
|
|
112
181
|
if (this.closed)
|
|
113
182
|
return;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
183
|
+
// Under remote intent the client itself refuses a capability-less target,
|
|
184
|
+
// independent of the resolver's own gate — a downgraded/replaced daemon
|
|
185
|
+
// must never be dialed just because a resolver variant let it through.
|
|
186
|
+
if (this.remoteEnabled && resolved && resolved.sameSocketControl !== true) {
|
|
187
|
+
debug(TAG, `Resolved daemon ${resolved.host}:${resolved.port} lacks sameSocketControl under remote intent — refusing`);
|
|
188
|
+
resolved = null;
|
|
189
|
+
}
|
|
190
|
+
// The provider result replaces the cached target on EVERY resolution,
|
|
191
|
+
// null included: after the daemon disappears or is replaced by an
|
|
192
|
+
// incapable one, redialing the stale target would bypass the capability
|
|
193
|
+
// refusal (and reuse a dead token). Null holds the reconnect loop until
|
|
194
|
+
// a valid target resolves again.
|
|
195
|
+
const prev = this.target ? `${this.target.host}:${this.target.port}` : 'null';
|
|
196
|
+
const next = resolved ? `${resolved.host}:${resolved.port}` : 'null';
|
|
197
|
+
if (prev !== next) {
|
|
198
|
+
debug(TAG, `Daemon target resolved ${prev} → ${next}${resolved ? '' : ' (resolution failed; holding reconnect)'}`);
|
|
117
199
|
}
|
|
200
|
+
this.target = resolved;
|
|
118
201
|
}
|
|
119
|
-
if (!this.
|
|
202
|
+
if (!this.target) {
|
|
120
203
|
this.scheduleReconnect();
|
|
121
204
|
return;
|
|
122
205
|
}
|
|
@@ -124,17 +207,24 @@ export class DaemonWsClient {
|
|
|
124
207
|
this.ws.removeAllListeners();
|
|
125
208
|
this.ws.close();
|
|
126
209
|
}
|
|
127
|
-
const
|
|
128
|
-
|
|
210
|
+
const { host, port, token } = this.target;
|
|
211
|
+
// Loopback needs no token (daemon treats same-machine as authenticated);
|
|
212
|
+
// a remote daemon requires its advertised pairing token on the query string.
|
|
213
|
+
const url = isLoopbackHost(host)
|
|
214
|
+
? `ws://127.0.0.1:${port}`
|
|
215
|
+
: `ws://${formatHostForUrl(host)}:${port}${token ? `?token=${encodeURIComponent(token)}` : ''}`;
|
|
216
|
+
// Never log the URL itself — it can carry the daemon's pairing token.
|
|
217
|
+
debug(TAG, `Connecting to daemon at ws://${formatHostForUrl(host)}:${port} (token: ${token ? 'yes' : 'no'})`);
|
|
129
218
|
this.ws = new WebSocket(url);
|
|
130
219
|
this.ws.on('open', () => {
|
|
131
|
-
debug(TAG, `Connected to daemon:${
|
|
132
|
-
this.reconnectDelay =
|
|
220
|
+
debug(TAG, `Connected to daemon ${host}:${port}`);
|
|
221
|
+
this.reconnectDelay = this.reconnectBase;
|
|
133
222
|
this.sendRegister();
|
|
134
223
|
});
|
|
135
224
|
this.ws.on('close', () => {
|
|
136
225
|
debug(TAG, 'Daemon WS closed');
|
|
137
226
|
this.registered = false;
|
|
227
|
+
this.focused = false;
|
|
138
228
|
this.scheduleReconnect();
|
|
139
229
|
});
|
|
140
230
|
this.ws.on('error', (err) => {
|
|
@@ -144,9 +234,41 @@ export class DaemonWsClient {
|
|
|
144
234
|
this.ws.on('message', (data) => {
|
|
145
235
|
try {
|
|
146
236
|
const msg = JSON.parse(data.toString());
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
237
|
+
switch (msg.type) {
|
|
238
|
+
case 'session_push_ack':
|
|
239
|
+
this.registered = true;
|
|
240
|
+
debug(TAG, 'Registration acknowledged');
|
|
241
|
+
break;
|
|
242
|
+
// ── Same-socket reverse control (daemon → this session) ──
|
|
243
|
+
// Down-frames addressed to another session are ignored outright: a
|
|
244
|
+
// daemon-side routing bug must not drive this session's PTY.
|
|
245
|
+
case 'session_command_down':
|
|
246
|
+
if (msg.sessionId !== this.sessionId) {
|
|
247
|
+
debug(TAG, `ignoring session_command_down for foreign session ${msg.sessionId}`);
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
if (msg.command && this.applyCommand) {
|
|
251
|
+
debug(TAG, `reverse cmd: ${msg.command.type}`);
|
|
252
|
+
this.applyCommand(msg.command);
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
case 'session_focus_down':
|
|
256
|
+
if (msg.sessionId !== this.sessionId)
|
|
257
|
+
break;
|
|
258
|
+
this.focused = true;
|
|
259
|
+
debug(TAG, 'Focused by daemon — forwarding events up');
|
|
260
|
+
// Emit an initial snapshot so the controlling deck shows state at once.
|
|
261
|
+
if (this.focusSnapshot) {
|
|
262
|
+
for (const evt of this.focusSnapshot())
|
|
263
|
+
this.forwardEvent(evt);
|
|
264
|
+
}
|
|
265
|
+
break;
|
|
266
|
+
case 'session_unfocus_down':
|
|
267
|
+
if (msg.sessionId !== this.sessionId)
|
|
268
|
+
break;
|
|
269
|
+
this.focused = false;
|
|
270
|
+
debug(TAG, 'Unfocused by daemon');
|
|
271
|
+
break;
|
|
150
272
|
}
|
|
151
273
|
}
|
|
152
274
|
catch {
|
|
@@ -154,17 +276,31 @@ export class DaemonWsClient {
|
|
|
154
276
|
}
|
|
155
277
|
});
|
|
156
278
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
279
|
+
/**
|
|
280
|
+
* Build the register frame (exposed for tests). `weight` is always a
|
|
281
|
+
* concrete integer — the Swift daemon preserves an existing weight when the
|
|
282
|
+
* key is absent (legacy senders), so a current sender must send the explicit
|
|
283
|
+
* 0 to be able to reset one.
|
|
284
|
+
*/
|
|
285
|
+
buildRegisterFrame() {
|
|
286
|
+
return {
|
|
161
287
|
type: 'session_push_register',
|
|
162
288
|
sessionId: this.sessionId,
|
|
163
289
|
port: this.sessionPort,
|
|
164
290
|
agentType: this.agentType,
|
|
165
291
|
projectName: this.projectName,
|
|
292
|
+
host: this.sessionHost,
|
|
293
|
+
// Per-target decision: intent (user opt-in) AND capability (daemon can
|
|
294
|
+
// actually drive us down this socket). A capability-less daemon (Swift
|
|
295
|
+
// App Store) gets a plain local-style registration instead.
|
|
296
|
+
remoteAttach: (this.remoteEnabled && this.target?.sameSocketControl === true) || undefined,
|
|
297
|
+
weight: sessionWeight(this.weight),
|
|
166
298
|
};
|
|
167
|
-
|
|
299
|
+
}
|
|
300
|
+
sendRegister() {
|
|
301
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN)
|
|
302
|
+
return;
|
|
303
|
+
this.ws.send(JSON.stringify(this.buildRegisterFrame()));
|
|
168
304
|
}
|
|
169
305
|
scheduleReconnect() {
|
|
170
306
|
if (this.closed || this.reconnectTimer)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-ws-client.js","sourceRoot":"","sources":["../src/daemon-ws-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon-ws-client.js","sourceRoot":"","sources":["../src/daemon-ws-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAqB,MAAM,uBAAuB,CAAC;AAC5F,+EAA+E;AAC/E,qEAAqE;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,MAAM,GAAG,GAAG,gBAAgB,CAAC;AAC7B,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,aAAa,GAAG,KAAK,CAAC;AAyD5B,MAAM,OAAO,cAAc;IAgBN;IACA;IACA;IACA;IAEA;IAWA;IAEA;IAQA;IAzCX,EAAE,GAAqB,IAAI,CAAC;IAC5B,MAAM,GAAwB,IAAI,CAAC;IACnC,cAAc,GAAyC,IAAI,CAAC;IACnD,aAAa,CAAS;IAC/B,cAAc,CAAS;IACvB,MAAM,GAAG,KAAK,CAAC;IACf,UAAU,GAAG,KAAK,CAAC;IAC3B,iFAAiF;IACzE,OAAO,GAAG,KAAK,CAAC;IACxB,+FAA+F;IACvF,YAAY,GAA0C,IAAI,CAAC;IACnE,iFAAiF;IACzE,aAAa,GAAiC,IAAI,CAAC;IAE3D,YACmB,SAAiB,EACjB,WAAmB,EACnB,SAAkB,EAClB,WAAoB;IACrC,kFAAkF;IACjE,MAAe;IAChC;;;;;;;;;OASG;IACc,cAAyE;IAC1F,0EAA0E;IACzD,WAAoB;IACrC;;;;;;OAMG;IACc,aAAuB;IACxC,2FAA2F;IAC3F,eAAwB;QA5BP,cAAS,GAAT,SAAS,CAAQ;QACjB,gBAAW,GAAX,WAAW,CAAQ;QACnB,cAAS,GAAT,SAAS,CAAS;QAClB,gBAAW,GAAX,WAAW,CAAS;QAEpB,WAAM,GAAN,MAAM,CAAS;QAWf,mBAAc,GAAd,cAAc,CAA2D;QAEzE,gBAAW,GAAX,WAAW,CAAS;QAQpB,kBAAa,GAAb,aAAa,CAAU;QAIxC,IAAI,CAAC,aAAa,GAAG,eAAe,IAAI,cAAc,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC;IAC3C,CAAC;IAED;;;;;;;;OAQG;IACH,OAAO,CAAC,MAA2B;QACjC,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,iBAAiB,CAAC,YAA0C,EAAE,aAAkC;QAC9F,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED,oFAAoF;IACpF,YAAY,CAAC,GAAgB;QAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI;YAAE,OAAO;QAC/E,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAC1C,MAAM,GAAG,GAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAChG,IAAI,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC3E,CAAC;IAED,kCAAkC;IAClC,SAAS,CAAC,KAAa,EAAE,SAAkB,EAAE,WAAoB,EAAE,cAAuB;QACxF,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI;YAAE,OAAO;QAC9D,MAAM,GAAG,GAAqB;YAC5B,IAAI,EAAE,oBAAoB;YAC1B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK;YACL,SAAS;YACT,WAAW;YACX,cAAc;YACd,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,qBAAqB;IACrB,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC;YAC7B,2EAA2E;YAC3E,IAAI,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,IAAI,CAAC;oBAAC,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YAAC,CAAC;YACtF,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,EAAE,EAAE,UAAU,KAAK,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC;IACnE,CAAC;IAED,sBAAsB;IAEd,KAAK,CAAC,SAAS;QACrB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,QAA6B,CAAC;YAClC,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YACzC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,KAAK,CAAC,GAAG,EAAE,yBAAyB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACxF,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;YACD,IAAI,IAAI,CAAC,MAAM;gBAAE,OAAO;YACxB,0EAA0E;YAC1E,wEAAwE;YACxE,uEAAuE;YACvE,IAAI,IAAI,CAAC,aAAa,IAAI,QAAQ,IAAI,QAAQ,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;gBAC1E,KAAK,CAAC,GAAG,EAAE,mBAAmB,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,yDAAyD,CAAC,CAAC;gBACvH,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;YACD,sEAAsE;YACtE,kEAAkE;YAClE,wEAAwE;YACxE,wEAAwE;YACxE,iCAAiC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YAC9E,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACrE,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,KAAK,CAAC,GAAG,EAAE,0BAA0B,IAAI,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,yCAAyC,EAAE,CAAC,CAAC;YACrH,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC;YAC7B,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1C,yEAAyE;QACzE,6EAA6E;QAC7E,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC;YAC9B,CAAC,CAAC,kBAAkB,IAAI,EAAE;YAC1B,CAAC,CAAC,QAAQ,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAClG,sEAAsE;QACtE,KAAK,CAAC,GAAG,EAAE,gCAAgC,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QAE9G,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YACtB,KAAK,CAAC,GAAG,EAAE,uBAAuB,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC;YACzC,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,KAAK,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC1B,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACvC,oCAAoC;QACtC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;YAC7B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACxC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;oBACjB,KAAK,kBAAkB;wBACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;wBACvB,KAAK,CAAC,GAAG,EAAE,2BAA2B,CAAC,CAAC;wBACxC,MAAM;oBACR,4DAA4D;oBAC5D,mEAAmE;oBACnE,6DAA6D;oBAC7D,KAAK,sBAAsB;wBACzB,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;4BACrC,KAAK,CAAC,GAAG,EAAE,qDAAqD,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;4BACjF,MAAM;wBACR,CAAC;wBACD,IAAI,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;4BACrC,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;4BAC/C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAwB,CAAC,CAAC;wBAClD,CAAC;wBACD,MAAM;oBACR,KAAK,oBAAoB;wBACvB,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS;4BAAE,MAAM;wBAC5C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;wBACpB,KAAK,CAAC,GAAG,EAAE,0CAA0C,CAAC,CAAC;wBACvD,wEAAwE;wBACxE,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;4BACvB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,EAAE;gCAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;wBACjE,CAAC;wBACD,MAAM;oBACR,KAAK,sBAAsB;wBACzB,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS;4BAAE,MAAM;wBAC5C,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;wBACrB,KAAK,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;wBAClC,MAAM;gBACV,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,oCAAoC;YACtC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,kBAAkB;QAChB,OAAO;YACL,IAAI,EAAE,uBAAuB;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,uEAAuE;YACvE,uEAAuE;YACvE,4DAA4D;YAC5D,YAAY,EAAE,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC,IAAI,SAAS;YAC1F,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;SACnC,CAAC;IACJ,CAAC;IAEO,YAAY;QAClB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI;YAAE,OAAO;QAC9D,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc;YAAE,OAAO;QAC/C,KAAK,CAAC,GAAG,EAAE,mBAAmB,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;QACxB,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,GAAG,GAAG,EAAE,aAAa,CAAC,CAAC;IAC3E,CAAC;CACF"}
|
package/dist/daemon.js
CHANGED
|
@@ -17,7 +17,7 @@ const program = new Command();
|
|
|
17
17
|
program
|
|
18
18
|
.name('agentdeck')
|
|
19
19
|
.description('AgentDeck daemon (legacy entry point — use `agentdeck daemon` instead)')
|
|
20
|
-
.version('1.0.
|
|
20
|
+
.version('1.0.5');
|
|
21
21
|
program
|
|
22
22
|
.command('start', { isDefault: true })
|
|
23
23
|
.description('Start monitoring daemon')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device-voice-reply.d.ts","sourceRoot":"","sources":["../src/device-voice-reply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,MAAM,WAAW,SAAS;IACxB,iCAAiC;IACjC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iCAAiC;IACjC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,MAAM,IAAI,OAAO,CAAC;IAClB,8DAA8D;IAC9D,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,IAAI,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,SAAS,IAAI,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;+EAC+E;AAC/E,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;kDACkD;AAClD,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAAiB,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAmB,GAAG,MAAM,CAwB/E;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqBlF;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,SAAkB,GAAG,MAAM,EAAE,CAM7E;AAED;;;GAGG;AACH,qBAAa,sBAAsB;IAK/B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,WAAW;IAR9B,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,SAAS,CAAwB;gBAGtB,GAAG,GAAE,MAAM,MAAyB,EACpC,KAAK,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CACL;IAC/C,0EAA0E;IACzD,WAAW,GAAE,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,GAAG,IAAiB;IAGpF;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;
|
|
1
|
+
{"version":3,"file":"device-voice-reply.d.ts","sourceRoot":"","sources":["../src/device-voice-reply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,MAAM,WAAW,SAAS;IACxB,iCAAiC;IACjC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iCAAiC;IACjC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,MAAM,IAAI,OAAO,CAAC;IAClB,8DAA8D;IAC9D,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,IAAI,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,SAAS,IAAI,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;+EAC+E;AAC/E,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;kDACkD;AAClD,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAAiB,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAmB,GAAG,MAAM,CAwB/E;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqBlF;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,SAAkB,GAAG,MAAM,EAAE,CAM7E;AAED;;;GAGG;AACH,qBAAa,sBAAsB;IAK/B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,WAAW;IAR9B,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,SAAS,CAAwB;gBAGtB,GAAG,GAAE,MAAM,MAAyB,EACpC,KAAK,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CACL;IAC/C,0EAA0E;IACzD,WAAW,GAAE,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,GAAG,IAAiB;IAGpF;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAchD,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAI7B;;;OAGG;IACH,OAAO,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IASlD;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI;IAOb,+DAA+D;IAC/D,UAAU,IAAI,MAAM;IAIpB,uEAAuE;IACvE,aAAa,IAAI,MAAM;IAKvB,wDAAwD;IACxD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE;IAU1C;;;;OAIG;IACG,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CA4CtF"}
|
|
@@ -126,7 +126,11 @@ export class DeviceVoiceReplyRouter {
|
|
|
126
126
|
arm(sink, sessionId) {
|
|
127
127
|
if (!sessionId)
|
|
128
128
|
return false;
|
|
129
|
-
|
|
129
|
+
// Either delivery mechanism counts: `audio_out` boards take the WS push
|
|
130
|
+
// stream, `audio_http_pull` boards fetch the staged reply themselves
|
|
131
|
+
// (the hosted-link boards whose RX path a push stream can crash).
|
|
132
|
+
const caps = sink.capabilities();
|
|
133
|
+
if (!caps.includes('audio_out') && !caps.includes('audio_http_pull'))
|
|
130
134
|
return false;
|
|
131
135
|
// Store the bare uuid: devices speak the prefixed `observed:<agent>:<uuid>`
|
|
132
136
|
// form while timeline rows are keyed by the uuid alone, so keying on what
|
|
@@ -194,10 +198,18 @@ export class DeviceVoiceReplyRouter {
|
|
|
194
198
|
this.armed.delete(armedSink);
|
|
195
199
|
// Follow the board, not the socket: a USB-attached board parks its WiFi and
|
|
196
200
|
// closes the WebSocket the dictation came in on, so by now the same device is
|
|
197
|
-
// very likely reachable over serial instead.
|
|
198
|
-
|
|
201
|
+
// very likely reachable over serial instead. And prefer a transport that
|
|
202
|
+
// can PLAY the audio: when the armed sink does not advertise audio_out
|
|
203
|
+
// (arm-time fallback while the board's WS was blinking), upgrade to the
|
|
204
|
+
// board's live audio-capable transport resolved now, at stream time.
|
|
205
|
+
let sink = armedSink.isOpen()
|
|
199
206
|
? armedSink
|
|
200
207
|
: this.resolveLive(armedSink.deviceKey()) ?? armedSink;
|
|
208
|
+
if (!sink.capabilities().includes('audio_out')) {
|
|
209
|
+
const live = this.resolveLive(armedSink.deviceKey());
|
|
210
|
+
if (live && live.capabilities().includes('audio_out'))
|
|
211
|
+
sink = live;
|
|
212
|
+
}
|
|
201
213
|
if (this.streaming.has(sink))
|
|
202
214
|
return false; // one utterance at a time per board
|
|
203
215
|
const parsed = pcmFromWav(wav);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device-voice-reply.js","sourceRoot":"","sources":["../src/device-voice-reply.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"device-voice-reply.js","sourceRoot":"","sources":["../src/device-voice-reply.ts"],"names":[],"mappings":"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"}
|