@agentdeck/bridge 1.0.19 → 1.0.21

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.
Files changed (192) hide show
  1. package/dist/adapters/openclaw.d.ts +55 -1
  2. package/dist/adapters/openclaw.d.ts.map +1 -1
  3. package/dist/adapters/openclaw.js +278 -45
  4. package/dist/adapters/openclaw.js.map +1 -1
  5. package/dist/adb-reverse.d.ts +26 -3
  6. package/dist/adb-reverse.d.ts.map +1 -1
  7. package/dist/adb-reverse.js +26 -5
  8. package/dist/adb-reverse.js.map +1 -1
  9. package/dist/apme/adapters/codex-turn-manager.js +6 -1
  10. package/dist/apme/adapters/codex-turn-manager.js.map +1 -1
  11. package/dist/apme/adapters/openclaw-hook.d.ts +45 -1
  12. package/dist/apme/adapters/openclaw-hook.d.ts.map +1 -1
  13. package/dist/apme/adapters/openclaw-hook.js +84 -4
  14. package/dist/apme/adapters/openclaw-hook.js.map +1 -1
  15. package/dist/apme/claude-transcript-reader.d.ts +76 -0
  16. package/dist/apme/claude-transcript-reader.d.ts.map +1 -1
  17. package/dist/apme/claude-transcript-reader.js +152 -1
  18. package/dist/apme/claude-transcript-reader.js.map +1 -1
  19. package/dist/apme/collector.d.ts +63 -5
  20. package/dist/apme/collector.d.ts.map +1 -1
  21. package/dist/apme/collector.js +147 -10
  22. package/dist/apme/collector.js.map +1 -1
  23. package/dist/apme/store.d.ts +23 -1
  24. package/dist/apme/store.d.ts.map +1 -1
  25. package/dist/apme/store.js +81 -2
  26. package/dist/apme/store.js.map +1 -1
  27. package/dist/apme/types.d.ts +1 -1
  28. package/dist/apme/types.d.ts.map +1 -1
  29. package/dist/apme/types.js.map +1 -1
  30. package/dist/auth.d.ts +37 -0
  31. package/dist/auth.d.ts.map +1 -1
  32. package/dist/auth.js +23 -0
  33. package/dist/auth.js.map +1 -1
  34. package/dist/bridge-core.d.ts.map +1 -1
  35. package/dist/bridge-core.js +6 -1
  36. package/dist/bridge-core.js.map +1 -1
  37. package/dist/claude-interrupt-marker.d.ts +31 -0
  38. package/dist/claude-interrupt-marker.d.ts.map +1 -0
  39. package/dist/claude-interrupt-marker.js +58 -0
  40. package/dist/claude-interrupt-marker.js.map +1 -0
  41. package/dist/claude-turn-watchdog.d.ts +93 -0
  42. package/dist/claude-turn-watchdog.d.ts.map +1 -0
  43. package/dist/claude-turn-watchdog.js +173 -0
  44. package/dist/claude-turn-watchdog.js.map +1 -0
  45. package/dist/cli.d.ts +6 -0
  46. package/dist/cli.d.ts.map +1 -1
  47. package/dist/cli.js +399 -115
  48. package/dist/cli.js.map +1 -1
  49. package/dist/codex-hook-silence.d.ts +52 -0
  50. package/dist/codex-hook-silence.d.ts.map +1 -0
  51. package/dist/codex-hook-silence.js +80 -0
  52. package/dist/codex-hook-silence.js.map +1 -0
  53. package/dist/daemon-port.d.ts +90 -0
  54. package/dist/daemon-port.d.ts.map +1 -0
  55. package/dist/daemon-port.js +119 -0
  56. package/dist/daemon-port.js.map +1 -0
  57. package/dist/daemon-server.d.ts +14 -1
  58. package/dist/daemon-server.d.ts.map +1 -1
  59. package/dist/daemon-server.js +297 -69
  60. package/dist/daemon-server.js.map +1 -1
  61. package/dist/daemon-settings.d.ts +46 -0
  62. package/dist/daemon-settings.d.ts.map +1 -0
  63. package/dist/daemon-settings.js +85 -0
  64. package/dist/daemon-settings.js.map +1 -0
  65. package/dist/daemon-takeover.d.ts +75 -0
  66. package/dist/daemon-takeover.d.ts.map +1 -0
  67. package/dist/daemon-takeover.js +137 -0
  68. package/dist/daemon-takeover.js.map +1 -0
  69. package/dist/daemon.js +1 -1
  70. package/dist/index.d.ts +4 -1
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +90 -12
  73. package/dist/index.js.map +1 -1
  74. package/dist/kiro-diagnostics.d.ts +90 -0
  75. package/dist/kiro-diagnostics.d.ts.map +1 -0
  76. package/dist/kiro-diagnostics.js +278 -0
  77. package/dist/kiro-diagnostics.js.map +1 -0
  78. package/dist/kiro-session.d.ts +113 -0
  79. package/dist/kiro-session.d.ts.map +1 -0
  80. package/dist/kiro-session.js +688 -0
  81. package/dist/kiro-session.js.map +1 -0
  82. package/dist/kiro-timeline-feed.d.ts +45 -0
  83. package/dist/kiro-timeline-feed.d.ts.map +1 -0
  84. package/dist/kiro-timeline-feed.js +116 -0
  85. package/dist/kiro-timeline-feed.js.map +1 -0
  86. package/dist/kiro-transcript-timeline.d.ts +57 -0
  87. package/dist/kiro-transcript-timeline.d.ts.map +1 -0
  88. package/dist/kiro-transcript-timeline.js +183 -0
  89. package/dist/kiro-transcript-timeline.js.map +1 -0
  90. package/dist/linux-service.d.ts +2 -1
  91. package/dist/linux-service.d.ts.map +1 -1
  92. package/dist/linux-service.js +8 -3
  93. package/dist/linux-service.js.map +1 -1
  94. package/dist/mdns-discover.d.ts +27 -0
  95. package/dist/mdns-discover.d.ts.map +1 -1
  96. package/dist/mdns-discover.js +60 -7
  97. package/dist/mdns-discover.js.map +1 -1
  98. package/dist/mdns.d.ts.map +1 -1
  99. package/dist/mdns.js +16 -3
  100. package/dist/mdns.js.map +1 -1
  101. package/dist/modules/adb-module.d.ts.map +1 -1
  102. package/dist/modules/adb-module.js +5 -2
  103. package/dist/modules/adb-module.js.map +1 -1
  104. package/dist/modules/index.d.ts +2 -1
  105. package/dist/modules/index.d.ts.map +1 -1
  106. package/dist/modules/index.js +1 -0
  107. package/dist/modules/index.js.map +1 -1
  108. package/dist/modules/types.d.ts +34 -9
  109. package/dist/modules/types.d.ts.map +1 -1
  110. package/dist/modules/types.js +34 -1
  111. package/dist/modules/types.js.map +1 -1
  112. package/dist/network-posture.d.ts +67 -0
  113. package/dist/network-posture.d.ts.map +1 -0
  114. package/dist/network-posture.js +100 -0
  115. package/dist/network-posture.js.map +1 -0
  116. package/dist/observed-steering.d.ts +14 -0
  117. package/dist/observed-steering.d.ts.map +1 -1
  118. package/dist/observed-steering.js +18 -0
  119. package/dist/observed-steering.js.map +1 -1
  120. package/dist/observed-turn-watchdogs.d.ts +84 -0
  121. package/dist/observed-turn-watchdogs.d.ts.map +1 -0
  122. package/dist/observed-turn-watchdogs.js +134 -0
  123. package/dist/observed-turn-watchdogs.js.map +1 -0
  124. package/dist/openclaw-session.d.ts +10 -0
  125. package/dist/openclaw-session.d.ts.map +1 -1
  126. package/dist/openclaw-session.js +12 -0
  127. package/dist/openclaw-session.js.map +1 -1
  128. package/dist/passive-observer.d.ts +19 -0
  129. package/dist/passive-observer.d.ts.map +1 -1
  130. package/dist/passive-observer.js +208 -24
  131. package/dist/passive-observer.js.map +1 -1
  132. package/dist/pixoo/micro-glyphs.d.ts +1 -1
  133. package/dist/pixoo/micro-glyphs.d.ts.map +1 -1
  134. package/dist/pixoo/micro-glyphs.js +2 -0
  135. package/dist/pixoo/micro-glyphs.js.map +1 -1
  136. package/dist/pixoo/official-dot-glyphs.generated.d.ts +1 -1
  137. package/dist/pixoo/official-dot-glyphs.generated.d.ts.map +1 -1
  138. package/dist/pixoo/official-dot-glyphs.generated.js +47 -0
  139. package/dist/pixoo/official-dot-glyphs.generated.js.map +1 -1
  140. package/dist/pixoo/pixoo-discover.d.ts +8 -1
  141. package/dist/pixoo/pixoo-discover.d.ts.map +1 -1
  142. package/dist/pixoo/pixoo-discover.js +15 -8
  143. package/dist/pixoo/pixoo-discover.js.map +1 -1
  144. package/dist/pixoo/pixoo-renderer.d.ts +4 -2
  145. package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
  146. package/dist/pixoo/pixoo-renderer.js +105 -36
  147. package/dist/pixoo/pixoo-renderer.js.map +1 -1
  148. package/dist/pixoo/pixoo-settings.d.ts +19 -2
  149. package/dist/pixoo/pixoo-settings.d.ts.map +1 -1
  150. package/dist/pixoo/pixoo-settings.js +22 -4
  151. package/dist/pixoo/pixoo-settings.js.map +1 -1
  152. package/dist/pixoo/pixoo-sprites.d.ts.map +1 -1
  153. package/dist/pixoo/pixoo-sprites.js +2 -0
  154. package/dist/pixoo/pixoo-sprites.js.map +1 -1
  155. package/dist/session-aggregator.d.ts +9 -1
  156. package/dist/session-aggregator.d.ts.map +1 -1
  157. package/dist/session-aggregator.js +1 -1
  158. package/dist/session-aggregator.js.map +1 -1
  159. package/dist/session-registry.d.ts +71 -3
  160. package/dist/session-registry.d.ts.map +1 -1
  161. package/dist/session-registry.js +126 -19
  162. package/dist/session-registry.js.map +1 -1
  163. package/dist/state-machine.d.ts +38 -1
  164. package/dist/state-machine.d.ts.map +1 -1
  165. package/dist/state-machine.js +112 -8
  166. package/dist/state-machine.js.map +1 -1
  167. package/dist/subagent-timeline.d.ts +38 -7
  168. package/dist/subagent-timeline.d.ts.map +1 -1
  169. package/dist/subagent-timeline.js +154 -23
  170. package/dist/subagent-timeline.js.map +1 -1
  171. package/dist/timeline-store.d.ts.map +1 -1
  172. package/dist/timeline-store.js +26 -1
  173. package/dist/timeline-store.js.map +1 -1
  174. package/dist/tui/renderer.d.ts.map +1 -1
  175. package/dist/tui/renderer.js +13 -1
  176. package/dist/tui/renderer.js.map +1 -1
  177. package/dist/tui/terrarium.d.ts.map +1 -1
  178. package/dist/tui/terrarium.js +10 -5
  179. package/dist/tui/terrarium.js.map +1 -1
  180. package/dist/utils/redact-secrets.d.ts +3 -0
  181. package/dist/utils/redact-secrets.d.ts.map +1 -0
  182. package/dist/utils/redact-secrets.js +29 -0
  183. package/dist/utils/redact-secrets.js.map +1 -0
  184. package/dist/version-check.d.ts +8 -0
  185. package/dist/version-check.d.ts.map +1 -1
  186. package/dist/version-check.js +27 -0
  187. package/dist/version-check.js.map +1 -1
  188. package/dist/windows-service.d.ts +2 -1
  189. package/dist/windows-service.d.ts.map +1 -1
  190. package/dist/windows-service.js +6 -3
  191. package/dist/windows-service.js.map +1 -1
  192. package/package.json +3 -3
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Codex hook-silence warning — detects the "lifecycle channel dead on
3
+ * arrival" failure with zero signal today.
4
+ *
5
+ * Codex lifecycle hooks AND the notify turn-complete fallback ride the same
6
+ * mechanism (a curl POST to this bridge's AGENTDECK_PORT, installed in
7
+ * ~/.codex/config.toml), so they share failure modes: a stale port in the
8
+ * config, a hooks.json/inline-[hooks] layer conflict, or a broken curl kills
9
+ * both at once. Since the PTY fallback state machine was removed (1.0.19), a
10
+ * managed Codex session in that condition is lifecycle-blind silently —
11
+ * no state changes, no timeline, no APME — while the terminal itself works.
12
+ *
13
+ * Detection is deliberately modest: if the PTY has produced real activity but
14
+ * NO codex_* hook or notify event has EVER arrived by the grace deadline, the
15
+ * install is broken — warn once (log + timeline row). The first hook event
16
+ * proves the channel and disarms permanently; mid-session hook death is out
17
+ * of scope (it cannot be distinguished from an idle session without parsing
18
+ * the screen, which lifecycle correctness must not do).
19
+ *
20
+ * `--no-codex-hooks` opted out of lifecycle monitoring explicitly; callers
21
+ * must not arm this warning in that case (cli.ts already prints the
22
+ * degradation notice at startup).
23
+ */
24
+ import { debug } from './logger.js';
25
+ /** How long after session start to expect the first codex_* event.
26
+ * codex_session_start fires immediately on launch, so one grace period
27
+ * covers slow starts without a turn ever being submitted. */
28
+ export const CODEX_HOOK_SILENCE_GRACE_MS = 120_000;
29
+ /** Minimum PTY activity events before silence is judged — a session that
30
+ * never rendered anything may simply not have started. */
31
+ export const CODEX_HOOK_SILENCE_MIN_ACTIVITY = 10;
32
+ export class CodexHookSilenceWarning {
33
+ onSilent;
34
+ minActivity;
35
+ timer = null;
36
+ activityCount = 0;
37
+ hookSeen = false;
38
+ deadlinePassed = false;
39
+ constructor(opts) {
40
+ this.onSilent = opts.onSilent;
41
+ this.minActivity = opts.minActivity ?? CODEX_HOOK_SILENCE_MIN_ACTIVITY;
42
+ this.timer = setTimeout(() => {
43
+ this.timer = null;
44
+ this.deadlinePassed = true;
45
+ this.judge();
46
+ }, opts.graceMs ?? CODEX_HOOK_SILENCE_GRACE_MS);
47
+ this.timer.unref?.();
48
+ }
49
+ /** Any codex_* hook or notify event proves the channel; disarms forever. */
50
+ noteHookEvent() {
51
+ if (this.hookSeen)
52
+ return;
53
+ this.hookSeen = true;
54
+ this.stop();
55
+ }
56
+ /** PTY activity — the terminal is being used. If the grace deadline already
57
+ * passed with too little activity, late activity re-judges once. */
58
+ noteActivity() {
59
+ this.activityCount++;
60
+ if (this.deadlinePassed)
61
+ this.judge();
62
+ }
63
+ stop() {
64
+ if (this.timer) {
65
+ clearTimeout(this.timer);
66
+ this.timer = null;
67
+ }
68
+ this.deadlinePassed = false;
69
+ }
70
+ judge() {
71
+ if (this.hookSeen)
72
+ return;
73
+ if (this.activityCount < this.minActivity)
74
+ return;
75
+ this.deadlinePassed = false; // fire once
76
+ debug('codex', `hook silence: ${this.activityCount} PTY activity events, zero codex_* hooks`);
77
+ this.onSilent();
78
+ }
79
+ }
80
+ //# sourceMappingURL=codex-hook-silence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-hook-silence.js","sourceRoot":"","sources":["../src/codex-hook-silence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC;;8DAE8D;AAC9D,MAAM,CAAC,MAAM,2BAA2B,GAAG,OAAO,CAAC;AACnD;2DAC2D;AAC3D,MAAM,CAAC,MAAM,+BAA+B,GAAG,EAAE,CAAC;AAQlD,MAAM,OAAO,uBAAuB;IACjB,QAAQ,CAAa;IACrB,WAAW,CAAS;IAC7B,KAAK,GAAyC,IAAI,CAAC;IACnD,aAAa,GAAG,CAAC,CAAC;IAClB,QAAQ,GAAG,KAAK,CAAC;IACjB,cAAc,GAAG,KAAK,CAAC;IAE/B,YAAY,IAA6B;QACvC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,+BAA+B,CAAC;QACvE,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,2BAA2B,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IACvB,CAAC;IAED,4EAA4E;IAC5E,aAAa;QACX,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED;yEACqE;IACrE,YAAY;QACV,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,cAAc;YAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IACxC,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;IAC9B,CAAC;IAEO,KAAK;QACX,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW;YAAE,OAAO;QAClD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,CAAC,YAAY;QACzC,KAAK,CAAC,OAAO,EAAE,iBAAiB,IAAI,CAAC,aAAa,0CAA0C,CAAC,CAAC;QAC9F,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;CACF"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The CLI daemon's **preferred port** — the port it intends to serve, as
3
+ * opposed to the port it ended up on.
4
+ *
5
+ * Roadmap item 11 (docs/ENTERPRISE-ROADMAP.md §1.5) asks for a persistent
6
+ * `daemonPort` for the CLI to match the macOS app's `AppPreferences.daemonPort`.
7
+ * The reason it matters is not configurability for its own sake — it is that
8
+ * without a recorded intent, a daemon that landed on a fallback port has no way
9
+ * to know it is on the wrong one.
10
+ *
11
+ * ## Intent is persisted; the outcome never is
12
+ *
13
+ * This is the rule the whole module exists to enforce. `daemon.json` records
14
+ * where the daemon *is*, and every client resolves through it. This setting
15
+ * records where the daemon *wants to be*. Persisting the outcome instead would
16
+ * be self-reinforcing: a daemon bumped to 9121 by a transient hold would write
17
+ * 9121 down and start there forever, turning a 14-second kernel reservation
18
+ * into a permanent move. So nothing in the daemon's startup path ever writes
19
+ * this value — only the user does, via `agentdeck daemon port <n>`.
20
+ *
21
+ * ## Sources
22
+ *
23
+ * `-p/--port` › `AGENTDECK_DAEMON_PORT` › `settings.json` `daemonPort` › 9120.
24
+ * All four are statements of intent; they differ only in precedence and in how
25
+ * long they last. The resolved `source` is carried alongside the number because
26
+ * one caller needs it: `daemon start` treats a port the user typed on THIS
27
+ * invocation differently from one it merely defaulted to (an explicit choice
28
+ * fails loudly rather than quietly binding a different port).
29
+ */
30
+ /** `settings.json` key. Same name as the macOS app's `prefs.daemonPort`. */
31
+ export declare const DAEMON_PORT_SETTING_KEY = "daemonPort";
32
+ /** Environment override, for a shell or MDM profile that cannot edit files. */
33
+ export declare const DAEMON_PORT_ENV_VAR = "AGENTDECK_DAEMON_PORT";
34
+ /**
35
+ * Accepted range, mirroring `AppPreferences.clampPort` (1024–65535). Below 1024
36
+ * needs root on every platform we support, which the daemon never has.
37
+ */
38
+ export declare const DAEMON_PORT_MIN = 1024;
39
+ export declare const DAEMON_PORT_MAX = 65535;
40
+ /**
41
+ * How long the daemon waits for its preferred port to come free before
42
+ * conceding to a fallback, when nothing answers `/health` on it.
43
+ *
44
+ * Sized from a measurement, not a guess: cancelling a listener on macOS leaves
45
+ * a NECP reservation on the port for ~14s (bindable at ~17s, measured
46
+ * 2026-08-06 — `lsof` shows zero sockets for the whole interval and `bind()`
47
+ * still returns EADDRINUSE). 20s clears that with margin.
48
+ *
49
+ * The wait polls, so it costs only as long as the port is actually held. The
50
+ * full budget is paid only when something outside AgentDeck really is
51
+ * listening there — once per daemon start, with a log line saying so.
52
+ */
53
+ export declare const PREFERRED_PORT_RECLAIM_MS = 20000;
54
+ export type DaemonPortSource = 'flag' | 'env' | 'settings' | 'default';
55
+ export interface ResolvedDaemonPort {
56
+ port: number;
57
+ source: DaemonPortSource;
58
+ }
59
+ /** True when `value` is a port this daemon may be asked to bind. */
60
+ export declare function isValidDaemonPort(value: unknown): value is number;
61
+ /**
62
+ * Parse a port written as text (a flag value, an env var). Returns null for
63
+ * anything that is not a valid port — including `"9120abc"`, which `parseInt`
64
+ * would happily read as 9120.
65
+ */
66
+ export declare function parseDaemonPort(raw: string | undefined | null): number | null;
67
+ /**
68
+ * The persisted preference, or null when absent or unusable.
69
+ *
70
+ * Lenient on purpose: a malformed `daemonPort` must fall through to the
71
+ * default rather than stop the daemon from starting. The *setter* is the strict
72
+ * half — it rejects out-of-range input with a message, so a typo is caught
73
+ * where the user can see it instead of silently reverting six weeks later.
74
+ */
75
+ export declare function preferredDaemonPortFrom(settings: Record<string, unknown>): number | null;
76
+ export interface ResolveDaemonPortInput {
77
+ /** `-p/--port` as typed on THIS invocation, or undefined when defaulted. */
78
+ flag?: string | number | null;
79
+ env?: NodeJS.ProcessEnv;
80
+ settings?: Record<string, unknown>;
81
+ }
82
+ /**
83
+ * Resolve the preferred port and where it came from. Pure — every input is
84
+ * injectable so the precedence order can be pinned without touching the real
85
+ * environment or the real settings file.
86
+ */
87
+ export declare function resolveDaemonPort(input?: ResolveDaemonPortInput): ResolvedDaemonPort;
88
+ /** Human-readable provenance, for `daemon port` and the startup log. */
89
+ export declare function describeDaemonPortSource(source: DaemonPortSource): string;
90
+ //# sourceMappingURL=daemon-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-port.d.ts","sourceRoot":"","sources":["../src/daemon-port.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAKH,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,eAAe,CAAC;AAEpD,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAKjE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAK7E;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAMxF;AAED,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,sBAA2B,GAAG,kBAAkB,CAYxF;AAED,wEAAwE;AACxE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAOzE"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * The CLI daemon's **preferred port** — the port it intends to serve, as
3
+ * opposed to the port it ended up on.
4
+ *
5
+ * Roadmap item 11 (docs/ENTERPRISE-ROADMAP.md §1.5) asks for a persistent
6
+ * `daemonPort` for the CLI to match the macOS app's `AppPreferences.daemonPort`.
7
+ * The reason it matters is not configurability for its own sake — it is that
8
+ * without a recorded intent, a daemon that landed on a fallback port has no way
9
+ * to know it is on the wrong one.
10
+ *
11
+ * ## Intent is persisted; the outcome never is
12
+ *
13
+ * This is the rule the whole module exists to enforce. `daemon.json` records
14
+ * where the daemon *is*, and every client resolves through it. This setting
15
+ * records where the daemon *wants to be*. Persisting the outcome instead would
16
+ * be self-reinforcing: a daemon bumped to 9121 by a transient hold would write
17
+ * 9121 down and start there forever, turning a 14-second kernel reservation
18
+ * into a permanent move. So nothing in the daemon's startup path ever writes
19
+ * this value — only the user does, via `agentdeck daemon port <n>`.
20
+ *
21
+ * ## Sources
22
+ *
23
+ * `-p/--port` › `AGENTDECK_DAEMON_PORT` › `settings.json` `daemonPort` › 9120.
24
+ * All four are statements of intent; they differ only in precedence and in how
25
+ * long they last. The resolved `source` is carried alongside the number because
26
+ * one caller needs it: `daemon start` treats a port the user typed on THIS
27
+ * invocation differently from one it merely defaulted to (an explicit choice
28
+ * fails loudly rather than quietly binding a different port).
29
+ */
30
+ import { loadDaemonSettings } from './daemon-settings.js';
31
+ import { DAEMON_DEFAULT_PORT } from './session-registry.js';
32
+ /** `settings.json` key. Same name as the macOS app's `prefs.daemonPort`. */
33
+ export const DAEMON_PORT_SETTING_KEY = 'daemonPort';
34
+ /** Environment override, for a shell or MDM profile that cannot edit files. */
35
+ export const DAEMON_PORT_ENV_VAR = 'AGENTDECK_DAEMON_PORT';
36
+ /**
37
+ * Accepted range, mirroring `AppPreferences.clampPort` (1024–65535). Below 1024
38
+ * needs root on every platform we support, which the daemon never has.
39
+ */
40
+ export const DAEMON_PORT_MIN = 1024;
41
+ export const DAEMON_PORT_MAX = 65535;
42
+ /**
43
+ * How long the daemon waits for its preferred port to come free before
44
+ * conceding to a fallback, when nothing answers `/health` on it.
45
+ *
46
+ * Sized from a measurement, not a guess: cancelling a listener on macOS leaves
47
+ * a NECP reservation on the port for ~14s (bindable at ~17s, measured
48
+ * 2026-08-06 — `lsof` shows zero sockets for the whole interval and `bind()`
49
+ * still returns EADDRINUSE). 20s clears that with margin.
50
+ *
51
+ * The wait polls, so it costs only as long as the port is actually held. The
52
+ * full budget is paid only when something outside AgentDeck really is
53
+ * listening there — once per daemon start, with a log line saying so.
54
+ */
55
+ export const PREFERRED_PORT_RECLAIM_MS = 20_000;
56
+ /** True when `value` is a port this daemon may be asked to bind. */
57
+ export function isValidDaemonPort(value) {
58
+ return typeof value === 'number'
59
+ && Number.isInteger(value)
60
+ && value >= DAEMON_PORT_MIN
61
+ && value <= DAEMON_PORT_MAX;
62
+ }
63
+ /**
64
+ * Parse a port written as text (a flag value, an env var). Returns null for
65
+ * anything that is not a valid port — including `"9120abc"`, which `parseInt`
66
+ * would happily read as 9120.
67
+ */
68
+ export function parseDaemonPort(raw) {
69
+ const text = raw?.trim();
70
+ if (!text || !/^\d+$/.test(text))
71
+ return null;
72
+ const value = Number(text);
73
+ return isValidDaemonPort(value) ? value : null;
74
+ }
75
+ /**
76
+ * The persisted preference, or null when absent or unusable.
77
+ *
78
+ * Lenient on purpose: a malformed `daemonPort` must fall through to the
79
+ * default rather than stop the daemon from starting. The *setter* is the strict
80
+ * half — it rejects out-of-range input with a message, so a typo is caught
81
+ * where the user can see it instead of silently reverting six weeks later.
82
+ */
83
+ export function preferredDaemonPortFrom(settings) {
84
+ const value = settings[DAEMON_PORT_SETTING_KEY];
85
+ if (isValidDaemonPort(value))
86
+ return value;
87
+ // A port stored as a string is a plausible hand-edit of settings.json.
88
+ if (typeof value === 'string')
89
+ return parseDaemonPort(value);
90
+ return null;
91
+ }
92
+ /**
93
+ * Resolve the preferred port and where it came from. Pure — every input is
94
+ * injectable so the precedence order can be pinned without touching the real
95
+ * environment or the real settings file.
96
+ */
97
+ export function resolveDaemonPort(input = {}) {
98
+ const flag = typeof input.flag === 'number' ? input.flag : parseDaemonPort(input.flag ?? undefined);
99
+ if (isValidDaemonPort(flag))
100
+ return { port: flag, source: 'flag' };
101
+ const env = input.env ?? process.env;
102
+ const fromEnv = parseDaemonPort(env[DAEMON_PORT_ENV_VAR]);
103
+ if (fromEnv !== null)
104
+ return { port: fromEnv, source: 'env' };
105
+ const fromSettings = preferredDaemonPortFrom(input.settings ?? loadDaemonSettings());
106
+ if (fromSettings !== null)
107
+ return { port: fromSettings, source: 'settings' };
108
+ return { port: DAEMON_DEFAULT_PORT, source: 'default' };
109
+ }
110
+ /** Human-readable provenance, for `daemon port` and the startup log. */
111
+ export function describeDaemonPortSource(source) {
112
+ switch (source) {
113
+ case 'flag': return '--port';
114
+ case 'env': return DAEMON_PORT_ENV_VAR;
115
+ case 'settings': return `settings.json ${DAEMON_PORT_SETTING_KEY}`;
116
+ case 'default': return 'built-in default';
117
+ }
118
+ }
119
+ //# sourceMappingURL=daemon-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-port.js","sourceRoot":"","sources":["../src/daemon-port.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@
12
12
  */
13
13
  import WebSocket from 'ws';
14
14
  import { BridgeCore } from './bridge-core.js';
15
+ import { type DaemonPortSource } from './daemon-port.js';
15
16
  import { type ApiUsageData } from './usage-api.js';
16
17
  /**
17
18
  * Single-path transport dedup. A physical ESP32 can be reachable over BOTH a
@@ -96,12 +97,24 @@ export declare function enrichGatewayTimelineEntry<T extends {
96
97
  */
97
98
  export declare function classifyObservedHookEvent(eventName: string, mapped: string): {
98
99
  boundary: string;
99
- agentType: 'claude-code' | 'codex-cli' | 'opencode' | 'antigravity';
100
+ agentType: 'claude-code' | 'codex-cli' | 'opencode' | 'antigravity' | 'kiro-cli' | 'kiro-ide';
100
101
  };
101
102
  export interface DaemonOptions {
103
+ /** The preferred port — already resolved by the caller when present. */
102
104
  port?: number;
105
+ /**
106
+ * Where `port` came from. Carried so the fallback log can name the real
107
+ * source: the CLI resolves the port itself (so the parent's singleton guard
108
+ * and the forked child cannot aim at different ports), which would otherwise
109
+ * make every port look like it was typed as `--port`.
110
+ */
111
+ portSource?: DaemonPortSource;
103
112
  debug?: boolean;
104
113
  wakeWord?: boolean;
114
+ /** `--local`: every device module off, USB serial included. */
115
+ local?: boolean;
116
+ /** `--loopback`: bind 127.0.0.1 and emit nothing onto the LAN. */
117
+ loopback?: boolean;
105
118
  }
106
119
  export declare function startDaemon(opts: DaemonOptions): Promise<void>;
107
120
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-server.d.ts","sourceRoot":"","sources":["../src/daemon-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,UAAU,EAA8B,MAAM,kBAAkB,CAAC;AAwH1E,OAAO,EAA8D,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAqQ/G;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,EAC5C,YAAY,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAClD,OAAO,CAST;AAkBD,iBAAS,iBAAiB,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CA+C1E;AAYD,iBAAS,yBAAyB,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAStD;AAED,iBAAS,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAsBlE;AA6ED,gBAAgB;AAChB,wBAAgB,uBAAuB,CAAC,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAKzH;AACD,gBAAgB;AAChB,wBAAgB,wBAAwB,IAAI,IAAI,CAS/C;AACD,gBAAgB;AAChB,eAAO,MAAM,gBAAgB;;;;;CAK5B,CAAC;AAEF,iBAAe,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA8F3H;AAoHD,iEAAiE;AACjE,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAsBtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EACnH,KAAK,EAAE,CAAC,GACP,CAAC,CAWH;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,CAAA;CAAE,CAa3F;AAID,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA+HD,wBAAsB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAqwIpE"}
1
+ {"version":3,"file":"daemon-server.d.ts","sourceRoot":"","sources":["../src/daemon-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,UAAU,EAA8B,MAAM,kBAAkB,CAAC;AAyH1E,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAA8D,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AA8Q/G;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,EAC5C,YAAY,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAClD,OAAO,CAST;AAkBD,iBAAS,iBAAiB,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CA+C1E;AAYD,iBAAS,yBAAyB,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAStD;AAED,iBAAS,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAsBlE;AA6ED,gBAAgB;AAChB,wBAAgB,uBAAuB,CAAC,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAKzH;AACD,gBAAgB;AAChB,wBAAgB,wBAAwB,IAAI,IAAI,CAS/C;AACD,gBAAgB;AAChB,eAAO,MAAM,gBAAgB;;;;;CAK5B,CAAC;AAEF,iBAAe,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA8F3H;AA6FD,iEAAiE;AACjE,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAsBtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EACnH,KAAK,EAAE,CAAC,GACP,CAAC,CAWH;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,CAAA;CAAE,CAiBrH;AAID,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA+HD,wBAAsB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAw/IpE"}