@agentdeck/bridge 1.0.3 → 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.
Files changed (215) hide show
  1. package/assets/fm-helper/agentdeck-fm-helper +0 -0
  2. package/dist/adapters/claude-code.d.ts.map +1 -1
  3. package/dist/adapters/claude-code.js +3 -0
  4. package/dist/adapters/claude-code.js.map +1 -1
  5. package/dist/adb-reverse.d.ts.map +1 -1
  6. package/dist/adb-reverse.js +4 -2
  7. package/dist/adb-reverse.js.map +1 -1
  8. package/dist/apme/collector.js +2 -2
  9. package/dist/apme/collector.js.map +1 -1
  10. package/dist/apme/outcome.js +2 -2
  11. package/dist/apme/outcome.js.map +1 -1
  12. package/dist/apme/runner.js +3 -3
  13. package/dist/apme/runner.js.map +1 -1
  14. package/dist/ble-sync-spawn.js +1 -1
  15. package/dist/ble-sync-spawn.js.map +1 -1
  16. package/dist/calendar.d.ts +82 -0
  17. package/dist/calendar.d.ts.map +1 -0
  18. package/dist/calendar.js +324 -0
  19. package/dist/calendar.js.map +1 -0
  20. package/dist/card-feed.d.ts +63 -5
  21. package/dist/card-feed.d.ts.map +1 -1
  22. package/dist/card-feed.js +218 -14
  23. package/dist/card-feed.js.map +1 -1
  24. package/dist/card-modules.d.ts +4 -0
  25. package/dist/card-modules.d.ts.map +1 -1
  26. package/dist/card-modules.js +5 -3
  27. package/dist/card-modules.js.map +1 -1
  28. package/dist/check-deps.js +4 -4
  29. package/dist/check-deps.js.map +1 -1
  30. package/dist/cli.d.ts +35 -0
  31. package/dist/cli.d.ts.map +1 -1
  32. package/dist/cli.js +406 -76
  33. package/dist/cli.js.map +1 -1
  34. package/dist/codex-otel.d.ts +89 -0
  35. package/dist/codex-otel.d.ts.map +1 -0
  36. package/dist/codex-otel.js +487 -0
  37. package/dist/codex-otel.js.map +1 -0
  38. package/dist/codex-rate-limits.d.ts.map +1 -1
  39. package/dist/codex-rate-limits.js +15 -3
  40. package/dist/codex-rate-limits.js.map +1 -1
  41. package/dist/daemon-server.d.ts +4 -0
  42. package/dist/daemon-server.d.ts.map +1 -1
  43. package/dist/daemon-server.js +797 -54
  44. package/dist/daemon-server.js.map +1 -1
  45. package/dist/daemon-ws-client.d.ts +108 -24
  46. package/dist/daemon-ws-client.d.ts.map +1 -1
  47. package/dist/daemon-ws-client.js +175 -39
  48. package/dist/daemon-ws-client.js.map +1 -1
  49. package/dist/daemon.js +1 -1
  50. package/dist/device-voice-reply.d.ts.map +1 -1
  51. package/dist/device-voice-reply.js +15 -3
  52. package/dist/device-voice-reply.js.map +1 -1
  53. package/dist/device-voice.d.ts +37 -0
  54. package/dist/device-voice.d.ts.map +1 -1
  55. package/dist/device-voice.js +130 -1
  56. package/dist/device-voice.js.map +1 -1
  57. package/dist/diag-analyzer.d.ts.map +1 -1
  58. package/dist/diag-analyzer.js +1 -0
  59. package/dist/diag-analyzer.js.map +1 -1
  60. package/dist/display-monitor.d.ts.map +1 -1
  61. package/dist/display-monitor.js +1 -0
  62. package/dist/display-monitor.js.map +1 -1
  63. package/dist/esp32-serial.d.ts +4 -0
  64. package/dist/esp32-serial.d.ts.map +1 -1
  65. package/dist/esp32-serial.js +6 -3
  66. package/dist/esp32-serial.js.map +1 -1
  67. package/dist/foundation-models-helper.d.ts +23 -0
  68. package/dist/foundation-models-helper.d.ts.map +1 -1
  69. package/dist/foundation-models-helper.js +32 -0
  70. package/dist/foundation-models-helper.js.map +1 -1
  71. package/dist/gateway-probe.js +1 -1
  72. package/dist/gateway-probe.js.map +1 -1
  73. package/dist/glance-frame.d.ts +64 -0
  74. package/dist/glance-frame.d.ts.map +1 -0
  75. package/dist/glance-frame.js +364 -0
  76. package/dist/glance-frame.js.map +1 -0
  77. package/dist/hook-codex-sessions.d.ts +40 -0
  78. package/dist/hook-codex-sessions.d.ts.map +1 -0
  79. package/dist/hook-codex-sessions.js +174 -0
  80. package/dist/hook-codex-sessions.js.map +1 -0
  81. package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts.map +1 -1
  82. package/dist/idotmatrix/idotmatrix-daemon-sync.js +5 -18
  83. package/dist/idotmatrix/idotmatrix-daemon-sync.js.map +1 -1
  84. package/dist/idotmatrix/idotmatrix-discover.d.ts.map +1 -1
  85. package/dist/idotmatrix/idotmatrix-discover.js +12 -17
  86. package/dist/idotmatrix/idotmatrix-discover.js.map +1 -1
  87. package/dist/idotmatrix/idotmatrix-settings.d.ts +15 -0
  88. package/dist/idotmatrix/idotmatrix-settings.d.ts.map +1 -1
  89. package/dist/idotmatrix/idotmatrix-settings.js +21 -0
  90. package/dist/idotmatrix/idotmatrix-settings.js.map +1 -1
  91. package/dist/index.d.ts +7 -0
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +88 -7
  94. package/dist/index.js.map +1 -1
  95. package/dist/linux-service.d.ts +52 -0
  96. package/dist/linux-service.d.ts.map +1 -0
  97. package/dist/linux-service.js +206 -0
  98. package/dist/linux-service.js.map +1 -0
  99. package/dist/logger.d.ts +6 -0
  100. package/dist/logger.d.ts.map +1 -1
  101. package/dist/logger.js +15 -0
  102. package/dist/logger.js.map +1 -1
  103. package/dist/mdns-discover.d.ts +19 -0
  104. package/dist/mdns-discover.d.ts.map +1 -0
  105. package/dist/mdns-discover.js +109 -0
  106. package/dist/mdns-discover.js.map +1 -0
  107. package/dist/model-catalog.d.ts.map +1 -1
  108. package/dist/model-catalog.js +1 -0
  109. package/dist/model-catalog.js.map +1 -1
  110. package/dist/modules/adb-module.js +1 -1
  111. package/dist/modules/adb-module.js.map +1 -1
  112. package/dist/output-parser.d.ts +9 -0
  113. package/dist/output-parser.d.ts.map +1 -1
  114. package/dist/output-parser.js +67 -16
  115. package/dist/output-parser.js.map +1 -1
  116. package/dist/passive-observer.d.ts +57 -8
  117. package/dist/passive-observer.d.ts.map +1 -1
  118. package/dist/passive-observer.js +210 -74
  119. package/dist/passive-observer.js.map +1 -1
  120. package/dist/pixoo/pixoo-bridge.d.ts.map +1 -1
  121. package/dist/pixoo/pixoo-bridge.js +47 -6
  122. package/dist/pixoo/pixoo-bridge.js.map +1 -1
  123. package/dist/pixoo/pixoo-renderer.d.ts +2 -1
  124. package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
  125. package/dist/pixoo/pixoo-renderer.js +137 -8
  126. package/dist/pixoo/pixoo-renderer.js.map +1 -1
  127. package/dist/pocket-autonomy.d.ts +78 -0
  128. package/dist/pocket-autonomy.d.ts.map +1 -0
  129. package/dist/pocket-autonomy.js +529 -0
  130. package/dist/pocket-autonomy.js.map +1 -0
  131. package/dist/pty-manager.d.ts.map +1 -1
  132. package/dist/pty-manager.js +3 -2
  133. package/dist/pty-manager.js.map +1 -1
  134. package/dist/python-ble-runtime.d.ts +64 -0
  135. package/dist/python-ble-runtime.d.ts.map +1 -0
  136. package/dist/python-ble-runtime.js +216 -0
  137. package/dist/python-ble-runtime.js.map +1 -0
  138. package/dist/remote-sessions.d.ts +64 -0
  139. package/dist/remote-sessions.d.ts.map +1 -0
  140. package/dist/remote-sessions.js +81 -0
  141. package/dist/remote-sessions.js.map +1 -0
  142. package/dist/review-runner.js +2 -2
  143. package/dist/review-runner.js.map +1 -1
  144. package/dist/session-aggregator.d.ts +2 -0
  145. package/dist/session-aggregator.d.ts.map +1 -1
  146. package/dist/session-aggregator.js +6 -1
  147. package/dist/session-aggregator.js.map +1 -1
  148. package/dist/session-focus-relay.d.ts +47 -1
  149. package/dist/session-focus-relay.d.ts.map +1 -1
  150. package/dist/session-focus-relay.js +130 -15
  151. package/dist/session-focus-relay.js.map +1 -1
  152. package/dist/session-push-channel.d.ts +31 -0
  153. package/dist/session-push-channel.d.ts.map +1 -0
  154. package/dist/session-push-channel.js +94 -0
  155. package/dist/session-push-channel.js.map +1 -0
  156. package/dist/session-registry.d.ts +126 -0
  157. package/dist/session-registry.d.ts.map +1 -1
  158. package/dist/session-registry.js +180 -3
  159. package/dist/session-registry.js.map +1 -1
  160. package/dist/subagent-timeline.d.ts +34 -0
  161. package/dist/subagent-timeline.d.ts.map +1 -0
  162. package/dist/subagent-timeline.js +156 -0
  163. package/dist/subagent-timeline.js.map +1 -0
  164. package/dist/timebox/timebox-daemon-sync.d.ts.map +1 -1
  165. package/dist/timebox/timebox-daemon-sync.js +5 -20
  166. package/dist/timebox/timebox-daemon-sync.js.map +1 -1
  167. package/dist/timebox/timebox-discover.d.ts.map +1 -1
  168. package/dist/timebox/timebox-discover.js +7 -16
  169. package/dist/timebox/timebox-discover.js.map +1 -1
  170. package/dist/tui/gauge.d.ts +4 -2
  171. package/dist/tui/gauge.d.ts.map +1 -1
  172. package/dist/tui/gauge.js +8 -4
  173. package/dist/tui/gauge.js.map +1 -1
  174. package/dist/tui/renderer.d.ts.map +1 -1
  175. package/dist/tui/renderer.js +28 -0
  176. package/dist/tui/renderer.js.map +1 -1
  177. package/dist/types.d.ts +1 -1
  178. package/dist/types.d.ts.map +1 -1
  179. package/dist/types.js.map +1 -1
  180. package/dist/usage-api.d.ts +43 -0
  181. package/dist/usage-api.d.ts.map +1 -1
  182. package/dist/usage-api.js +114 -9
  183. package/dist/usage-api.js.map +1 -1
  184. package/dist/usage-event.d.ts +19 -0
  185. package/dist/usage-event.d.ts.map +1 -1
  186. package/dist/usage-event.js +35 -0
  187. package/dist/usage-event.js.map +1 -1
  188. package/dist/utils/project-name.d.ts.map +1 -1
  189. package/dist/utils/project-name.js +1 -0
  190. package/dist/utils/project-name.js.map +1 -1
  191. package/dist/version-check.d.ts.map +1 -1
  192. package/dist/version-check.js +3 -2
  193. package/dist/version-check.js.map +1 -1
  194. package/dist/voice-assistant.d.ts.map +1 -1
  195. package/dist/voice-assistant.js +2 -1
  196. package/dist/voice-assistant.js.map +1 -1
  197. package/dist/voice.d.ts.map +1 -1
  198. package/dist/voice.js +1 -0
  199. package/dist/voice.js.map +1 -1
  200. package/dist/weather.d.ts +72 -0
  201. package/dist/weather.d.ts.map +1 -0
  202. package/dist/weather.js +206 -0
  203. package/dist/weather.js.map +1 -0
  204. package/dist/windows-service.js +5 -5
  205. package/dist/windows-service.js.map +1 -1
  206. package/fm-helper/AgentDeckFMHelper.swift +200 -0
  207. package/package.json +20 -14
  208. package/python/requirements-ble.txt +5 -0
  209. package/src/idotmatrix/brightness.py +40 -0
  210. package/src/idotmatrix/identity_generated.py +50 -0
  211. package/src/idotmatrix/scan.py +55 -0
  212. package/src/idotmatrix/sync.py +400 -0
  213. package/src/pysync/matrix_sync_common.py +89 -0
  214. package/src/timebox/scan_ble.py +52 -0
  215. package/src/timebox/sync_ble.py +394 -0
@@ -15,11 +15,9 @@
15
15
  * App Store Swift build, so spawning a subprocess here does not touch the
16
16
  * Apple 2.5.2 sandbox invariants.
17
17
  */
18
- import { existsSync } from 'fs';
19
- import { join, dirname } from 'path';
20
- import { fileURLToPath } from 'url';
21
18
  import { loadIDotMatrixDevices } from './idotmatrix-settings.js';
22
19
  import { createSyncCycleSquelch, spawnPythonSync, terminateSyncChild } from '../ble-sync-spawn.js';
20
+ import { getBleRuntimeStatus } from '../python-ble-runtime.js';
23
21
  let child = null;
24
22
  let stopping = false;
25
23
  let respawnTimer = null;
@@ -42,16 +40,6 @@ function log(msg) {
42
40
  // Repeated identical respawn cycles (panel off/out of range) collapse into an
43
41
  // hourly summary instead of flooding the daemon log all night.
44
42
  const squelch = createSyncCycleSquelch(log);
45
- function resolvePaths() {
46
- // This file compiles to bridge/dist/idotmatrix/idotmatrix-daemon-sync.js, so
47
- // the repo root is three levels up.
48
- const here = dirname(fileURLToPath(import.meta.url));
49
- const projectRoot = join(here, '..', '..', '..');
50
- return {
51
- venvPython: join(projectRoot, '.venv', 'bin', 'python'),
52
- syncScript: join(projectRoot, 'bridge', 'src', 'idotmatrix', 'sync.py'),
53
- };
54
- }
55
43
  /**
56
44
  * Start (or no-op if already running) the managed BLE sync for the first
57
45
  * configured iDotMatrix device, fed by the daemon at `httpPort`.
@@ -75,13 +63,12 @@ export function startIDotMatrixSync(httpPort) {
75
63
  void stopIDotMatrixSync();
76
64
  stopping = false;
77
65
  }
78
- const { venvPython, syncScript } = resolvePaths();
79
- if (!existsSync(venvPython) || !existsSync(syncScript)) {
80
- log(`BLE sync unavailable (missing ${!existsSync(venvPython) ? 'Python venv (.venv)' : 'sync.py'}); ` +
81
- `iDotMatrix will not be driven by the daemon`);
66
+ const runtime = getBleRuntimeStatus();
67
+ if (!runtime.ready || !runtime.python) {
68
+ log(`BLE sync unavailable (${runtime.reason}); run \`agentdeck ble setup\``);
82
69
  return;
83
70
  }
84
- spawnSync(venvPython, syncScript, httpPort);
71
+ spawnSync(runtime.python, runtime.paths.scripts.idotmatrixSync, httpPort);
85
72
  }
86
73
  function spawnSync(venvPython, syncScript, httpPort) {
87
74
  if (stopping)
@@ -1 +1 @@
1
- {"version":3,"file":"idotmatrix-daemon-sync.js","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-daemon-sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"idotmatrix-daemon-sync.js","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-daemon-sync.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"idotmatrix-discover.d.ts","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAgEH;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAc9D"}
1
+ {"version":3,"file":"idotmatrix-discover.d.ts","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA8DH;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAsB9D"}
@@ -11,25 +11,18 @@
11
11
  * Swift build, which discovers over CoreBluetooth natively.
12
12
  */
13
13
  import { spawn } from 'child_process';
14
- import { existsSync } from 'fs';
15
- import { dirname, join } from 'path';
16
- import { fileURLToPath } from 'url';
17
- import { addIDotMatrixDevice, isIDotMatrixAutoDiscoverEnabled, loadIDotMatrixDevices, } from './idotmatrix-settings.js';
14
+ import { addIDotMatrixDevice, isIDotMatrixAutoDiscoverEnabled, loadIDotMatrixDevices, loadIDotMatrixNamePrefixes, } from './idotmatrix-settings.js';
15
+ import { getBleRuntimeStatus } from '../python-ble-runtime.js';
18
16
  function log(msg) {
19
17
  console.error(`[agentdeck] [idotmatrix] ${msg}`);
20
18
  }
21
- function resolvePaths() {
22
- const here = dirname(fileURLToPath(import.meta.url));
23
- const projectRoot = join(here, '..', '..', '..');
24
- return {
25
- venvPython: join(projectRoot, '.venv', 'bin', 'python'),
26
- scanScript: join(projectRoot, 'bridge', 'src', 'idotmatrix', 'scan.py'),
27
- };
28
- }
29
19
  /** Run scan.py and parse its JSON, with a hard outer timeout. */
30
- function runScan(venvPython, scanScript, timeoutMs) {
20
+ function runScan(venvPython, scanScript, timeoutMs, extraNamePrefixes = []) {
31
21
  return new Promise((resolve) => {
32
- const proc = spawn(venvPython, [scanScript], { stdio: ['ignore', 'pipe', 'ignore'] });
22
+ const proc = spawn(venvPython, [scanScript, ...extraNamePrefixes], {
23
+ stdio: ['ignore', 'pipe', 'ignore'],
24
+ windowsHide: true,
25
+ });
33
26
  let out = '';
34
27
  const timer = setTimeout(() => {
35
28
  try {
@@ -70,10 +63,12 @@ export async function autoDiscoverIDotMatrix() {
70
63
  return 0;
71
64
  if (loadIDotMatrixDevices().length > 0)
72
65
  return 0; // only when nothing configured
73
- const { venvPython, scanScript } = resolvePaths();
74
- if (!existsSync(venvPython) || !existsSync(scanScript))
66
+ const runtime = getBleRuntimeStatus();
67
+ if (!runtime.ready || !runtime.python) {
68
+ log(`auto-discovery unavailable (${runtime.reason}); run \`agentdeck ble setup\``);
75
69
  return 0;
76
- const results = await runScan(venvPython, scanScript, 8_000);
70
+ }
71
+ const results = await runScan(runtime.python, runtime.paths.scripts.idotmatrixScan, 8_000, loadIDotMatrixNamePrefixes());
77
72
  const match = results.find((r) => r.is_idotmatrix && r.address);
78
73
  if (!match)
79
74
  return 0;
@@ -1 +1 @@
1
- {"version":3,"file":"idotmatrix-discover.js","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EACL,mBAAmB,EACnB,+BAA+B,EAC/B,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAQlC,SAAS,GAAG,CAAC,GAAW;IACtB,OAAO,CAAC,KAAK,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;QACvD,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC;KACxE,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,SAAS,OAAO,CAAC,UAAkB,EAAE,UAAkB,EAAE,SAAiB;IACxE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtF,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,kBAAkB;YACpB,CAAC;YACD,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC,EAAE,SAAS,CAAC,CAAC;QACd,IAAI,KAAK,CAAC,KAAK;YAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE;YACpC,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACpB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACpB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC/B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAAuB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACjE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,EAAE,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,IAAI,CAAC,+BAA+B,EAAE;QAAE,OAAO,CAAC,CAAC;IACjD,IAAI,qBAAqB,EAAE,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC,+BAA+B;IAEjF,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,YAAY,EAAE,CAAC;IAClD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,CAAC,CAAC;IAEjE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;IAChE,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IAErB,MAAM,KAAK,GAAG,mBAAmB,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAChF,IAAI,KAAK;QAAE,GAAG,CAAC,8BAA8B,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;IAC9E,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"idotmatrix-discover.js","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-discover.ts"],"names":[],"mappings":"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"}
@@ -17,4 +17,19 @@ export declare function removeIDotMatrixDevice(address: string): boolean;
17
17
  * `idotmatrixAutoDiscover: false` in settings.json to opt out.
18
18
  */
19
19
  export declare function isIDotMatrixAutoDiscoverEnabled(): boolean;
20
+ /**
21
+ * Extra advertised-name prefixes to treat as iDotMatrix panels, on top of the
22
+ * families in the identity SSOT (`@agentdeck/shared` IDOTMATRIX_NAME_PREFIXES).
23
+ * The scan already matches the advertised service UUID brand-independently;
24
+ * this is the escape hatch for a rebranded panel that omits the service from
25
+ * its advertisement, so the next `iPixel` does not need a release.
26
+ */
27
+ export declare function loadIDotMatrixNamePrefixes(): string[];
28
+ /**
29
+ * Keep only non-blank strings. The values become argv for the scanner, so a
30
+ * hand-edited settings.json must not be able to feed it numbers, objects, or a
31
+ * blank prefix (the shared predicate ignores blanks, but they would still ride
32
+ * across the process boundary as empty arguments).
33
+ */
34
+ export declare function sanitizeNamePrefixes(value: unknown): string[];
20
35
  //# sourceMappingURL=idotmatrix-settings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"idotmatrix-settings.d.ts","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-settings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmBD,wBAAgB,qBAAqB,IAAI,gBAAgB,EAAE,CAG1D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAIvE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAMrE;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAM/D;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,OAAO,CAEzD"}
1
+ {"version":3,"file":"idotmatrix-settings.d.ts","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-settings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmBD,wBAAgB,qBAAqB,IAAI,gBAAgB,EAAE,CAG1D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAIvE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAMrE;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAM/D;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,OAAO,CAEzD;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,EAAE,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAG7D"}
@@ -54,4 +54,25 @@ export function removeIDotMatrixDevice(address) {
54
54
  export function isIDotMatrixAutoDiscoverEnabled() {
55
55
  return readSettings().idotmatrixAutoDiscover !== false;
56
56
  }
57
+ /**
58
+ * Extra advertised-name prefixes to treat as iDotMatrix panels, on top of the
59
+ * families in the identity SSOT (`@agentdeck/shared` IDOTMATRIX_NAME_PREFIXES).
60
+ * The scan already matches the advertised service UUID brand-independently;
61
+ * this is the escape hatch for a rebranded panel that omits the service from
62
+ * its advertisement, so the next `iPixel` does not need a release.
63
+ */
64
+ export function loadIDotMatrixNamePrefixes() {
65
+ return sanitizeNamePrefixes(readSettings().idotmatrixNamePrefixes);
66
+ }
67
+ /**
68
+ * Keep only non-blank strings. The values become argv for the scanner, so a
69
+ * hand-edited settings.json must not be able to feed it numbers, objects, or a
70
+ * blank prefix (the shared predicate ignores blanks, but they would still ride
71
+ * across the process boundary as empty arguments).
72
+ */
73
+ export function sanitizeNamePrefixes(value) {
74
+ if (!Array.isArray(value))
75
+ return [];
76
+ return value.filter((p) => typeof p === 'string' && p.trim().length > 0);
77
+ }
57
78
  //# sourceMappingURL=idotmatrix-settings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"idotmatrix-settings.js","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-settings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAQ7B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AACnD,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;AAE1D,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;YAAE,OAAO,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,QAAiC;IACtD,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAA2B;IAC/D,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,QAAQ,CAAC,iBAAiB,GAAG,OAAO,CAAC;IACrC,aAAa,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAwB;IAC1D,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;IACxC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9F,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrB,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACxF,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACrD,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,+BAA+B;IAC7C,OAAO,YAAY,EAAE,CAAC,sBAAsB,KAAK,KAAK,CAAC;AACzD,CAAC"}
1
+ {"version":3,"file":"idotmatrix-settings.js","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-settings.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -16,6 +16,13 @@ export interface SessionOptions {
16
16
  wakeWord?: boolean;
17
17
  postit?: boolean;
18
18
  modules?: ModuleConfigs;
19
+ /** Opt-in: discover a daemon on the LAN via mDNS when none is local. */
20
+ remoteDaemon?: boolean;
21
+ /** Explicit daemon endpoint (`host` or `host:port`) for cross-subnet / SSH. */
22
+ daemonHost?: string;
23
+ /** Explicit deck/tab sort override (default 0); lower sorts first. Lets a user
24
+ * pin terminal-tab order onto the Stream Deck via `--weight <n>`. */
25
+ weight?: number;
19
26
  }
20
27
  export declare function startSession(opts: SessionOptions): Promise<void>;
21
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwDH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAUxD,OAAO,EAOL,KAAK,SAAS,EAQf,MAAM,YAAY,CAAC;AAwDpB,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAID,wBAAsB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA6mCtE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4DH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAUxD,OAAO,EAOL,KAAK,SAAS,EAQf,MAAM,YAAY,CAAC;AAwDpB,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,wEAAwE;IACxE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;0EACsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,wBAAsB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA4rCtE"}
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ import { checkDependencies } from './check-deps.js';
22
22
  import { enableDebugLog, log, debug, setPtyMode } from './logger.js';
23
23
  import { EventJournal } from './event-journal.js';
24
24
  import { PtyRingBuffer } from './pty-ringbuffer.js';
25
+ import { isSubagentOnlyHook, SubagentTimelineTracker } from './subagent-timeline.js';
25
26
  import { createDiagDump } from './diag-analyzer.js';
26
27
  import { createAdapter, ClaudeCodeAdapter, CodexCliAdapter, OpenCodeAdapter } from './adapters/index.js';
27
28
  import { MonitorAdapter } from './adapters/monitor.js';
@@ -35,7 +36,7 @@ import { readFileSync } from 'fs';
35
36
  import { resolve, dirname } from 'path';
36
37
  import { fileURLToPath } from 'url';
37
38
  import { execSync } from 'child_process';
38
- import { listActive as listActiveSessions, findAvailablePort, detectTmuxSession, findDaemonPortAsync, } from './session-registry.js';
39
+ import { listActive as listActiveSessions, findAvailablePort, detectTmuxSession, resolveDaemonTarget, deriveRemoteAttachOpts, isLoopbackHost, } from './session-registry.js';
39
40
  import { resolveProjectName } from './utils/project-name.js';
40
41
  import { DaemonWsClient } from './daemon-ws-client.js';
41
42
  import { getLanIp } from '@agentdeck/shared';
@@ -418,6 +419,23 @@ export async function startSession(opts) {
418
419
  });
419
420
  // ===== Timeline wiring =====
420
421
  core.wireTimeline(bridgeLogStream ?? undefined);
422
+ // Child agents remain part of the parent session. Emit two concise,
423
+ // backward-compatible Timeline rows and never expose a controllable child
424
+ // SessionInfo or team configuration surface.
425
+ const subagentTimeline = new SubagentTimelineTracker((entry) => {
426
+ core.bridgeTimeline.addEntry(entry, { bypassSuppression: true });
427
+ });
428
+ adapter.on('event', (evt) => {
429
+ if (evt.source !== 'hook')
430
+ return;
431
+ subagentTimeline.handle({
432
+ eventName: evt.event,
433
+ payload: evt.data ?? {},
434
+ sessionId: core.sessionId,
435
+ agentType,
436
+ projectName: core.projectName,
437
+ });
438
+ });
421
439
  // Claude Code hook events → timeline entries
422
440
  if (agentType === 'claude-code') {
423
441
  wireClaudeCodeTimeline(adapter, core, journal, ptyRingBuffer);
@@ -438,6 +456,10 @@ export async function startSession(opts) {
438
456
  switch (evt.source) {
439
457
  case 'hook':
440
458
  journal.write('hook', 'hook', { event: evt.event, data: evt.data });
459
+ // Child hooks are telemetry-only. In particular, a child PreToolUse
460
+ // must not mutate the parent state or enter an approval/control path.
461
+ if (isSubagentOnlyHook(evt.event, evt.data ?? {}))
462
+ break;
441
463
  // APME ingestion via the shared TelemetrySpan envelope. Codex
442
464
  // CLI sessions go through codexHookToSpans (codex_* event prefix);
443
465
  // Claude Code goes through claudeHookToSpans. Both adapters detect
@@ -634,13 +656,23 @@ export async function startSession(opts) {
634
656
  // `~/.agentdeck` split). `findDaemonPortAsync` probes 9120-9139 /health
635
657
  // as a last resort so the session still attaches instead of staying
636
658
  // orphaned.
637
- const daemonPortProvider = async () => {
638
- const resolved = await findDaemonPortAsync();
659
+ // Remote attach is opt-in: `--remote-daemon` / `AGENTDECK_REMOTE_DAEMON=1`
660
+ // gates BOTH remote paths (explicit host and mDNS). Derivation is shared with
661
+ // the CLI's pre-PTY warning so the two can't drift.
662
+ const { remote: remoteEnabled, hostHint: daemonHost } = deriveRemoteAttachOpts({
663
+ remoteDaemon: opts.remoteDaemon,
664
+ daemonHost: opts.daemonHost,
665
+ });
666
+ const daemonTargetProvider = async () => {
667
+ const resolved = await resolveDaemonTarget({ remote: remoteEnabled, hostHint: daemonHost });
639
668
  if (!resolved)
640
669
  return null;
641
- return resolved.port !== core.port ? resolved.port : null;
670
+ // Never attach to our own port but only when the resolved target is
671
+ // actually this machine. A remote daemon legitimately shares the port
672
+ // number (9120 on both boxes); rejecting on port alone dropped it.
673
+ return isLoopbackHost(resolved.host) && resolved.port === core.port ? null : resolved;
642
674
  };
643
- const daemonWsClient = new DaemonWsClient(core.sessionId, core.port, agentType, core.projectName, daemonPortProvider);
675
+ const daemonWsClient = new DaemonWsClient(core.sessionId, core.port, agentType, core.projectName, opts.weight, daemonTargetProvider, getLanIp() ?? undefined, remoteEnabled);
644
676
  daemonWsClient.connect(null);
645
677
  core.onShutdown(() => { daemonWsClient.close(); });
646
678
  // ===== State changed → broadcast =====
@@ -718,7 +750,10 @@ export async function startSession(opts) {
718
750
  core.broadcast(btnEvt);
719
751
  });
720
752
  // ===== Commands from WS clients =====
721
- core.wsServer.onCommand((cmd) => {
753
+ // Named so the same handler serves both the local WS server AND same-socket
754
+ // reverse control (a remote daemon sends commands down the push socket) —
755
+ // one command-application path, no divergence between local and remote.
756
+ const applyPluginCommand = (cmd) => {
722
757
  debug('agentdeck', `pluginCmd: ${cmd.type}`);
723
758
  // Adapter-owned commands
724
759
  if (adapter.handleCommand(cmd)) {
@@ -799,7 +834,15 @@ export async function startSession(opts) {
799
834
  core.fetchAndUpdateUsage().catch(() => { });
800
835
  break;
801
836
  }
802
- });
837
+ };
838
+ core.wsServer.onCommand(applyPluginCommand);
839
+ // Same-socket reverse control: let a remote daemon drive this session down the
840
+ // push socket it already opened — no inbound dial to our port required, so
841
+ // NAT'd / SSH-only workers work with a single outbound connection. Commands go
842
+ // through the same `applyPluginCommand`; focused events ride back up via the
843
+ // broadcast hook (parity with what a dial-back WS client would receive).
844
+ daemonWsClient.setReverseControl(applyPluginCommand, buildFocusSnapshot);
845
+ core.wsServer.onBroadcast((evt) => daemonWsClient.forwardEvent(evt));
803
846
  // Deck slot map relay
804
847
  core.wsServer.onRawMessage((msg, sender) => {
805
848
  if (msg.type === 'device_info') {
@@ -831,6 +874,7 @@ export async function startSession(opts) {
831
874
  tmuxSession,
832
875
  parentTty,
833
876
  tty: adapter.getTtyPath(),
877
+ ...(opts.weight != null ? { weight: opts.weight } : {}),
834
878
  });
835
879
  // ===== Client connect =====
836
880
  core.wsServer.onClientConnect((ws) => {
@@ -906,6 +950,38 @@ export async function startSession(opts) {
906
950
  // OpenClaw session alive whenever anything held port 18789 open. Shared
907
951
  // injector with daemon-server.ts; mirror of Swift buildSessionsListEvent.
908
952
  core.setSessionsEnricher((sessions) => injectOpenClawSession(sessions, { gatewayConnected: core.cachedGatewayConnected }));
953
+ // Initial events emitted up the push socket when a remote daemon focuses this
954
+ // session (same-socket reverse control), so the controlling deck shows current
955
+ // state immediately — parity with the initial state a WS client gets on connect
956
+ // (`onClientConnect`). Only RELAYED_EVENTS-eligible types are worth sending; the
957
+ // daemon's focus relay forwards nothing else.
958
+ function buildFocusSnapshot() {
959
+ const snapshot = core.stateMachine.getSnapshot();
960
+ const events = [
961
+ core.buildStateEvent({
962
+ agentType: adapter.capabilities.type,
963
+ agentCapabilities: adapter.capabilities,
964
+ snapshot,
965
+ }),
966
+ ];
967
+ if (snapshot.options.length > 0) {
968
+ let promptType = 'multi_select';
969
+ if (snapshot.state === State.AWAITING_PERMISSION) {
970
+ promptType = snapshot.options.length > 2 ? 'yes_no_always' : 'yes_no';
971
+ }
972
+ else if (snapshot.state === State.AWAITING_DIFF) {
973
+ promptType = 'diff_review';
974
+ }
975
+ events.push({
976
+ type: 'prompt_options',
977
+ promptType,
978
+ question: snapshot.question ?? undefined,
979
+ options: snapshot.options,
980
+ });
981
+ }
982
+ events.push(core.buildUsage());
983
+ return events;
984
+ }
909
985
  // ===== Encoder state computation =====
910
986
  function computeEncoderState() {
911
987
  const snapshot = core.stateMachine.getSnapshot();
@@ -1195,6 +1271,9 @@ function wireAgentApme(adapter, agentType, apme, core, ptyRingBuffer) {
1195
1271
  ? new CodexTurnManager(core, apme, ptyRingBuffer, sid, agentType)
1196
1272
  : null;
1197
1273
  adapter.on('event', (evt) => {
1274
+ if (evt.source === 'hook' && isSubagentOnlyHook(evt.event, evt.data ?? {})) {
1275
+ return;
1276
+ }
1198
1277
  // ── Timeline events (OpenCode / OpenClaw) ──
1199
1278
  // Both adapters emit { source: 'timeline', entry: TimelineEntry }.
1200
1279
  // The timeline adapter normalizes them to AgentDeck telemetry spans.
@@ -1462,6 +1541,8 @@ function wireClaudeCodeTimeline(adapter, core, journal, ptyRingBuffer) {
1462
1541
  adapter.on('event', (evt) => {
1463
1542
  if (evt.source !== 'hook')
1464
1543
  return;
1544
+ if (isSubagentOnlyHook(evt.event, evt.data ?? {}))
1545
+ return;
1465
1546
  const now = Date.now();
1466
1547
  switch (evt.event) {
1467
1548
  case 'UserPromptSubmit': {