@phnx-labs/agents-cli 1.22.117 → 1.22.119

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 (271) hide show
  1. package/CHANGELOG.md +301 -0
  2. package/dist/bootstrap.js +4 -11
  3. package/dist/commands/accounts.js +7 -4
  4. package/dist/commands/browser.d.ts +52 -70
  5. package/dist/commands/browser.js +192 -3562
  6. package/dist/commands/daemon.d.ts +39 -2
  7. package/dist/commands/daemon.js +72 -73
  8. package/dist/commands/events.js +1 -1
  9. package/dist/commands/exec.js +53 -1
  10. package/dist/commands/projects.js +92 -7
  11. package/dist/commands/repo.js +13 -49
  12. package/dist/commands/route.js +5 -5
  13. package/dist/commands/routines.js +39 -12
  14. package/dist/commands/sessions-render.d.ts +1 -1
  15. package/dist/commands/sessions-render.js +0 -1
  16. package/dist/commands/sessions.test-fixture.d.ts +0 -1
  17. package/dist/commands/sessions.test-fixture.js +0 -37
  18. package/dist/commands/setup-browser.d.ts +17 -12
  19. package/dist/commands/setup-browser.js +52 -87
  20. package/dist/commands/setup-preferences.d.ts +0 -17
  21. package/dist/commands/setup-preferences.js +18 -49
  22. package/dist/commands/setup.js +9 -9
  23. package/dist/commands/ssh.js +10 -1
  24. package/dist/commands/sync.js +6 -44
  25. package/dist/commands/teams.js +0 -1
  26. package/dist/commands/update.d.ts +19 -0
  27. package/dist/commands/update.js +34 -6
  28. package/dist/commands/view.d.ts +12 -1
  29. package/dist/commands/view.js +47 -2
  30. package/dist/index.js +107 -26
  31. package/dist/lib/account-capabilities.js +0 -2
  32. package/dist/lib/account-catalog.d.ts +38 -0
  33. package/dist/lib/account-catalog.js +110 -26
  34. package/dist/lib/account-provider-registry.js +1 -1
  35. package/dist/lib/account-registry.d.ts +1 -1
  36. package/dist/lib/account-registry.js +36 -2
  37. package/dist/lib/accounting/rotate.js +22 -8
  38. package/dist/lib/accounting/usage-ingest.d.ts +6 -1
  39. package/dist/lib/accounting/usage-ingest.js +115 -45
  40. package/dist/lib/accounting/usage-sync.d.ts +134 -31
  41. package/dist/lib/accounting/usage-sync.js +227 -66
  42. package/dist/lib/accounting/usage.d.ts +16 -3
  43. package/dist/lib/accounting/usage.js +26 -8
  44. package/dist/lib/accounts/add.d.ts +3 -1
  45. package/dist/lib/accounts/add.js +24 -13
  46. package/dist/lib/accounts/slots.d.ts +8 -0
  47. package/dist/lib/accounts/slots.js +17 -0
  48. package/dist/lib/add-dir.js +0 -1
  49. package/dist/lib/agent-cli-commands.js +0 -1
  50. package/dist/lib/agent-spec/agents.d.ts +6 -7
  51. package/dist/lib/agent-spec/agents.js +7 -60
  52. package/dist/lib/auth-health.d.ts +69 -1
  53. package/dist/lib/auth-health.js +133 -4
  54. package/dist/lib/browser/context.d.ts +82 -0
  55. package/dist/lib/browser/context.js +88 -0
  56. package/dist/lib/browser/paths.d.ts +25 -0
  57. package/dist/lib/browser/paths.js +51 -0
  58. package/dist/lib/browser/record.d.ts +38 -0
  59. package/dist/lib/browser/record.js +57 -0
  60. package/dist/lib/browser/sessions-list.js +1 -2
  61. package/dist/lib/browser-client.d.ts +158 -0
  62. package/dist/lib/browser-client.js +234 -0
  63. package/dist/lib/channels/owner-sink.d.ts +1 -18
  64. package/dist/lib/channels/owner-sink.js +29 -82
  65. package/dist/lib/channels/providers/rush.d.ts +7 -7
  66. package/dist/lib/channels/providers/rush.js +127 -57
  67. package/dist/lib/claude-account-token.d.ts +7 -1
  68. package/dist/lib/claude-account-token.js +26 -4
  69. package/dist/lib/claude-statusline.d.ts +1 -1
  70. package/dist/lib/claude-statusline.js +15 -3
  71. package/dist/lib/commands.js +1 -1
  72. package/dist/lib/crabbox/lease.js +1 -1
  73. package/dist/lib/crabbox/runtimes.js +1 -3
  74. package/dist/lib/daemon/account-state-daemon-service.js +1 -0
  75. package/dist/lib/daemon/auth-sync-service.d.ts +21 -18
  76. package/dist/lib/daemon/auth-sync-service.js +37 -43
  77. package/dist/lib/daemon/daemon.d.ts +25 -14
  78. package/dist/lib/daemon/daemon.js +92 -154
  79. package/dist/lib/daemon/runner.d.ts +2 -2
  80. package/dist/lib/daemon/runner.js +32 -9
  81. package/dist/lib/daemon/self-update-service.d.ts +35 -34
  82. package/dist/lib/daemon/self-update-service.js +40 -36
  83. package/dist/lib/daemon/service.d.ts +12 -8
  84. package/dist/lib/daemon/supervisor.d.ts +65 -54
  85. package/dist/lib/daemon/supervisor.js +136 -171
  86. package/dist/lib/daemon/testdata/process-view-start.js +5 -2
  87. package/dist/lib/daemon/usage-sync-service.d.ts +21 -30
  88. package/dist/lib/daemon/usage-sync-service.js +46 -78
  89. package/dist/lib/daemon-health.d.ts +22 -5
  90. package/dist/lib/daemon-health.js +47 -3
  91. package/dist/lib/daemon-services.d.ts +1 -1
  92. package/dist/lib/daemon-services.js +0 -10
  93. package/dist/lib/daemon-ticks.js +4 -2
  94. package/dist/lib/devices/doctor-findings.js +8 -11
  95. package/dist/lib/devices/harness-inventory.js +14 -5
  96. package/dist/lib/exec-account-home.js +5 -0
  97. package/dist/lib/exec.js +10 -13
  98. package/dist/lib/feed/events.js +0 -1
  99. package/dist/lib/feed/tool-activity.js +5 -2
  100. package/dist/lib/fleet-shared-state.d.ts +45 -0
  101. package/dist/lib/fleet-shared-state.js +78 -9
  102. package/dist/lib/fs-atomic.js +25 -0
  103. package/dist/lib/github/pr-mergeable.d.ts +4 -2
  104. package/dist/lib/github/pr-mergeable.js +5 -3
  105. package/dist/lib/github/project-prs.d.ts +58 -3
  106. package/dist/lib/github/project-prs.js +205 -7
  107. package/dist/lib/harness/adapters/cursor.js +14 -4
  108. package/dist/lib/harness-auth-capabilities.d.ts +4 -3
  109. package/dist/lib/harness-auth-capabilities.js +1 -2
  110. package/dist/lib/helper-versions.js +1 -1
  111. package/dist/lib/hooks/cache.d.ts +7 -0
  112. package/dist/lib/hooks/cache.js +27 -2
  113. package/dist/lib/hooks/install.js +7 -1
  114. package/dist/lib/hosts/ready.d.ts +38 -8
  115. package/dist/lib/hosts/ready.js +62 -14
  116. package/dist/lib/installations/active-check.d.ts +27 -0
  117. package/dist/lib/installations/active-check.js +61 -0
  118. package/dist/lib/installations/migrate.js +6 -3
  119. package/dist/lib/installations/shims.d.ts +1 -1
  120. package/dist/lib/installations/shims.js +32 -12
  121. package/dist/lib/installations/store.d.ts +9 -0
  122. package/dist/lib/installations/store.js +24 -0
  123. package/dist/lib/installations/update.js +21 -15
  124. package/dist/lib/installations/versions.js +15 -3
  125. package/dist/lib/manifest.js +1 -1
  126. package/dist/lib/models.js +0 -2
  127. package/dist/lib/open-url.js +28 -54
  128. package/dist/lib/profiles.js +0 -2
  129. package/dist/lib/projects.d.ts +16 -0
  130. package/dist/lib/projects.js +31 -0
  131. package/dist/lib/refresh.js +1 -1
  132. package/dist/lib/routine-readiness.d.ts +35 -0
  133. package/dist/lib/routine-readiness.js +74 -16
  134. package/dist/lib/rules/compile.js +6 -0
  135. package/dist/lib/sandbox.js +0 -2
  136. package/dist/lib/secrets-policy.d.ts +89 -11
  137. package/dist/lib/secrets-policy.js +175 -28
  138. package/dist/lib/session/active.d.ts +17 -6
  139. package/dist/lib/session/active.js +105 -49
  140. package/dist/lib/session/db.d.ts +1 -1
  141. package/dist/lib/session/db.js +65 -18
  142. package/dist/lib/session/discover.js +1 -283
  143. package/dist/lib/session/mirror.d.ts +4 -3
  144. package/dist/lib/session/mirror.js +4 -3
  145. package/dist/lib/session/parse.d.ts +0 -2
  146. package/dist/lib/session/parse.js +1 -138
  147. package/dist/lib/session/pid-registry.d.ts +6 -3
  148. package/dist/lib/session/pid-registry.js +18 -8
  149. package/dist/lib/session/remote/watch.d.ts +1 -1
  150. package/dist/lib/session/remote/watch.js +7 -3
  151. package/dist/lib/session/throughput.d.ts +1 -3
  152. package/dist/lib/session/throughput.js +0 -20
  153. package/dist/lib/session/types.d.ts +2 -2
  154. package/dist/lib/session/types.js +2 -2
  155. package/dist/lib/sessions-client.d.ts +60 -1
  156. package/dist/lib/sessions-client.js +227 -4
  157. package/dist/lib/setup-tool-status.js +5 -10
  158. package/dist/lib/signin-badge.d.ts +3 -2
  159. package/dist/lib/signin-badge.js +6 -3
  160. package/dist/lib/smart-launch.js +4 -1
  161. package/dist/lib/staleness/detectors/commands.d.ts +1 -1
  162. package/dist/lib/staleness/detectors/hooks.d.ts +1 -1
  163. package/dist/lib/staleness/detectors/mcp.d.ts +1 -1
  164. package/dist/lib/staleness/detectors/permissions.d.ts +1 -1
  165. package/dist/lib/staleness/detectors/plugins.d.ts +1 -1
  166. package/dist/lib/staleness/detectors/rules.d.ts +1 -1
  167. package/dist/lib/staleness/detectors/skills.d.ts +1 -1
  168. package/dist/lib/staleness/detectors/subagents.d.ts +1 -1
  169. package/dist/lib/staleness/detectors/workflows.d.ts +1 -1
  170. package/dist/lib/staleness/writers/commands.d.ts +1 -1
  171. package/dist/lib/staleness/writers/hooks.d.ts +1 -1
  172. package/dist/lib/staleness/writers/mcp.d.ts +1 -1
  173. package/dist/lib/staleness/writers/permissions.d.ts +1 -1
  174. package/dist/lib/staleness/writers/plugins.d.ts +1 -1
  175. package/dist/lib/staleness/writers/rules.d.ts +1 -1
  176. package/dist/lib/staleness/writers/skills.d.ts +1 -1
  177. package/dist/lib/staleness/writers/sources.js +5 -0
  178. package/dist/lib/staleness/writers/subagents.d.ts +1 -1
  179. package/dist/lib/staleness/writers/workflows.d.ts +1 -1
  180. package/dist/lib/state.d.ts +6 -4
  181. package/dist/lib/state.js +7 -17
  182. package/dist/lib/teams/parsers.d.ts +1 -1
  183. package/dist/lib/teams/parsers.js +1 -136
  184. package/dist/lib/teams/placement-probe.js +50 -15
  185. package/dist/lib/teams/scheduler.d.ts +7 -0
  186. package/dist/lib/types.d.ts +16 -1
  187. package/dist/lib/types.js +1 -1
  188. package/dist/lib/view-types.d.ts +32 -0
  189. package/dist/lib/watchdog/read.js +0 -1
  190. package/dist/lib/watchdog/rotate.js +1 -2
  191. package/dist/lib/watchdog/runner.js +2 -2
  192. package/dist/lib/watchdog/watchdog.d.ts +1 -1
  193. package/dist/lib/watchdog/watchdogTail.js +0 -31
  194. package/package.json +1 -1
  195. package/scripts/postinstall.js +8 -8
  196. package/dist/browser.d.ts +0 -2
  197. package/dist/browser.js +0 -17
  198. package/dist/commands/browser-picker.d.ts +0 -18
  199. package/dist/commands/browser-picker.js +0 -97
  200. package/dist/lib/browser/arc-discovery.d.ts +0 -52
  201. package/dist/lib/browser/arc-discovery.js +0 -197
  202. package/dist/lib/browser/arc-dom.d.ts +0 -14
  203. package/dist/lib/browser/arc-dom.js +0 -121
  204. package/dist/lib/browser/caller-identity.d.ts +0 -40
  205. package/dist/lib/browser/caller-identity.js +0 -175
  206. package/dist/lib/browser/cdp.d.ts +0 -51
  207. package/dist/lib/browser/cdp.js +0 -254
  208. package/dist/lib/browser/chrome.d.ts +0 -141
  209. package/dist/lib/browser/chrome.js +0 -704
  210. package/dist/lib/browser/chromium-discovery.d.ts +0 -28
  211. package/dist/lib/browser/chromium-discovery.js +0 -96
  212. package/dist/lib/browser/devices.d.ts +0 -34
  213. package/dist/lib/browser/devices.js +0 -61
  214. package/dist/lib/browser/domain-skills.d.ts +0 -71
  215. package/dist/lib/browser/domain-skills.js +0 -195
  216. package/dist/lib/browser/drivers/arc.d.ts +0 -40
  217. package/dist/lib/browser/drivers/arc.js +0 -276
  218. package/dist/lib/browser/drivers/firefox.d.ts +0 -99
  219. package/dist/lib/browser/drivers/firefox.js +0 -377
  220. package/dist/lib/browser/drivers/local.d.ts +0 -55
  221. package/dist/lib/browser/drivers/local.js +0 -266
  222. package/dist/lib/browser/drivers/ssh.d.ts +0 -120
  223. package/dist/lib/browser/drivers/ssh.js +0 -467
  224. package/dist/lib/browser/editor.d.ts +0 -3
  225. package/dist/lib/browser/editor.js +0 -50
  226. package/dist/lib/browser/ffmpeg.d.ts +0 -12
  227. package/dist/lib/browser/ffmpeg.js +0 -184
  228. package/dist/lib/browser/firefox-discovery.d.ts +0 -69
  229. package/dist/lib/browser/firefox-discovery.js +0 -162
  230. package/dist/lib/browser/har.d.ts +0 -85
  231. package/dist/lib/browser/har.js +0 -77
  232. package/dist/lib/browser/hygiene.d.ts +0 -97
  233. package/dist/lib/browser/hygiene.js +0 -153
  234. package/dist/lib/browser/index.d.ts +0 -5
  235. package/dist/lib/browser/index.js +0 -5
  236. package/dist/lib/browser/input.d.ts +0 -7
  237. package/dist/lib/browser/input.js +0 -92
  238. package/dist/lib/browser/ipc.d.ts +0 -204
  239. package/dist/lib/browser/ipc.js +0 -1453
  240. package/dist/lib/browser/login-detection.d.ts +0 -87
  241. package/dist/lib/browser/login-detection.js +0 -274
  242. package/dist/lib/browser/profiles.d.ts +0 -422
  243. package/dist/lib/browser/profiles.js +0 -1157
  244. package/dist/lib/browser/refs.d.ts +0 -89
  245. package/dist/lib/browser/refs.js +0 -191
  246. package/dist/lib/browser/registry.d.ts +0 -70
  247. package/dist/lib/browser/registry.js +0 -252
  248. package/dist/lib/browser/remote-control.d.ts +0 -59
  249. package/dist/lib/browser/remote-control.js +0 -85
  250. package/dist/lib/browser/resolve-target.d.ts +0 -66
  251. package/dist/lib/browser/resolve-target.js +0 -264
  252. package/dist/lib/browser/runtime-state.d.ts +0 -291
  253. package/dist/lib/browser/runtime-state.js +0 -584
  254. package/dist/lib/browser/secret-ref.d.ts +0 -10
  255. package/dist/lib/browser/secret-ref.js +0 -14
  256. package/dist/lib/browser/service.d.ts +0 -812
  257. package/dist/lib/browser/service.js +0 -4693
  258. package/dist/lib/browser/stream.d.ts +0 -17
  259. package/dist/lib/browser/stream.js +0 -72
  260. package/dist/lib/browser/task-index.d.ts +0 -78
  261. package/dist/lib/browser/task-index.js +0 -199
  262. package/dist/lib/browser/types.d.ts +0 -647
  263. package/dist/lib/browser/types.js +0 -61
  264. package/dist/lib/browser/upload.d.ts +0 -29
  265. package/dist/lib/browser/upload.js +0 -298
  266. package/dist/lib/daemon/browser-ipc-service.d.ts +0 -20
  267. package/dist/lib/daemon/browser-ipc-service.js +0 -46
  268. package/dist/lib/daemon/browser-task-reap-service.d.ts +0 -14
  269. package/dist/lib/daemon/browser-task-reap-service.js +0 -26
  270. package/dist/lib/fleet-shared-repo-sync.d.ts +0 -55
  271. package/dist/lib/fleet-shared-repo-sync.js +0 -490
@@ -3,28 +3,30 @@
3
3
  *
4
4
  * This tick owns only the NON-git duties of auth sync: it materializes worker
5
5
  * slots from durable keys already on the box, then (on the elected headed
6
- * publisher) provisions peers whose LAST-DELIVERED verdict says `missing` by
7
- * pushing the credential over SSH. The secret never enters Git.
6
+ * publisher) provisions peers missing a reserved key by pushing the credential
7
+ * over SSH. The secret never enters Git.
8
8
  *
9
- * It no longer runs its own `syncFleetSharedStateRepo` (PHNX-4051). The verdict
10
- * this tick's decisions read is published and delivered by the single git
11
- * committer, the usage-sync tick — folding both publishes into one caller is
12
- * what stops the two ticks (30 s apart) from contending for the one shared-repo
13
- * lock and starving the usage snapshot workers depend on. This tick keeps its
14
- * own deadline and circuit breaker, so a hung peer SSH push parks only auth-sync
15
- * and never the usage delivery. The pushes read the peer verdicts the last
16
- * usage-sync exchange wrote into the local checkout; they are idempotent
17
- * (push only when a peer is missing a key), so acting on at-most-one-tick-old
18
- * data converges exactly as the in-tick exchange did. To keep "at-most-one-tick-
19
- * old" true, the pushes are gated on the exchange's freshness marker
20
- * (`readLastSuccessfulExchangeMs`): when the last usage-sync exchange is missing
21
- * or older than one usage-sync tick interval (`USAGE_SYNC_TICK_MS`, the
22
- * producer's cadence — not this service's own `AUTH_SYNC_TICK_MS`), this tick
23
- * skips the pushes and WARNs instead of acting on peer state that may no longer
24
- * hold.
9
+ * It runs no transport of its own (PHNX-4051): the per-account readiness
10
+ * verdicts it reads are published and delivered by the usage-sync tick's SSH
11
+ * exchange, which stores each peer's reply at `devices/<peer>/daemon-state.json`
12
+ * stamped `receivedAt`. This tick keeps its own deadline and circuit breaker, so
13
+ * a hung peer SSH push parks only auth-sync and never the usage delivery.
14
+ *
15
+ * The pushes read each peer's OWN reply file (PHNX-4116 PR 5): a peer reporting
16
+ * a `missing` verdict for an account is pushed that account's key; a peer that
17
+ * has never sent a reply (no file), or whose reply carries no `accounts.rows`
18
+ * field (an older CLI — fail closed), is skipped this tick and logged at INFO.
19
+ * Presence is also gated on a delivered-fingerprint match, so a re-mint
20
+ * (`accounts login` bumps `workerCredential.mintedAt` while the old token still
21
+ * authenticates) re-pushes the rotated key within a tick instead of reading
22
+ * `present` forever. The push is idempotent, so a stale reply is harmless — a
23
+ * stale "has key" is fine, a stale "missing key" costs one redundant push —
24
+ * which is why the per-peer `receivedAt` replaced the old global freshness gate
25
+ * (`readLastSuccessfulExchangeMs`) that skipped EVERY push when the newest
26
+ * exchange across the fleet went stale. The reply file is first-hand and
27
+ * timestamped, so acting on it needs no such fleet-wide gate.
25
28
  */
26
29
  import { BasePeriodicService } from './service.js';
27
- import { USAGE_SYNC_TICK_MS } from './usage-sync-service.js';
28
30
  export const AUTH_SYNC_TICK_MS = 15 * 60_000;
29
31
  const AUTH_SYNC_DEADLINE_MS = 2 * 60_000;
30
32
  export const AUTH_SYNC_KICKOFF_MS = 60_000;
@@ -40,7 +42,7 @@ export class AuthSyncService extends BasePeriodicService {
40
42
  // Nothing to release — the supervisor's timer teardown is the only cleanup.
41
43
  }
42
44
  async onTick(ctx) {
43
- const { reconcileLocalWorkerSlots, syncReservedAuthBundle, syncReservedStores, } = await import('../secrets-policy.js');
45
+ const { reconcileLocalWorkerSlots, syncReservedAuthBundle, syncReservedStores, SKIP_REASON_NO_PEER_REPLY, SKIP_REASON_NO_ACCOUNT_ROWS, } = await import('../secrets-policy.js');
44
46
  // Worker-side slot materialization FIRST (PHNX-3940 T6): for each registered
45
47
  // account whose durable key is already on this box, create the HOME-shaped
46
48
  // slot the picker and spawn read. It touches only local state — the registry
@@ -67,29 +69,12 @@ export class AuthSyncService extends BasePeriodicService {
67
69
  catch (err) {
68
70
  ctx.log('WARN', `auth-sync: worker slot reconcile: ${err.message}`);
69
71
  }
70
- // The verdict this tick's pushes read is published by the usage-sync tick,
71
- // the single git committer (PHNX-4051), and delivered into the local checkout
72
- // by its exchange. The pushes below act on that last-delivered peer state, so
73
- // they are only sound while that state is fresh. Gate them on the exchange's
74
- // freshness: if the last successful usage-sync exchange is missing or older
75
- // than one tick interval, the delivered peer verdicts may be stale — a peer
76
- // that already received the key still reads `missing`, or a cleared `missing`
77
- // still reads stale — so skip the pushes and WARN rather than pushing off it.
78
- // The worker-slot reconcile above is NOT gated: it reads only local durable
79
- // keys, never delivered peer verdicts.
80
- const { readLastSuccessfulExchangeMs } = await import('../fleet-shared-repo-sync.js');
81
- const lastExchangeMs = readLastSuccessfulExchangeMs();
82
- const ageMs = lastExchangeMs === null ? null : Date.now() - lastExchangeMs;
83
- // The threshold is the PRODUCER's cadence (USAGE_SYNC_TICK_MS), not this
84
- // service's own AUTH_SYNC_TICK_MS: the delivered peer verdicts are refreshed
85
- // once per usage-sync exchange, so "stale" is measured against that tick, not
86
- // this one. The two constants are equal today, but sourcing it here keeps the
87
- // gate tracking the usage-sync cadence if either is ever retuned alone.
88
- if (ageMs === null || ageMs > USAGE_SYNC_TICK_MS) {
89
- const age = ageMs === null ? 'never completed' : `last completed ${Math.round(ageMs / 1000)}s ago`;
90
- ctx.log('WARN', `auth-sync: skipping credential push — usage-sync exchange ${age} (need one within ${Math.round(USAGE_SYNC_TICK_MS / 1000)}s); peer verdicts may be stale`);
91
- return;
92
- }
72
+ // The pushes read each peer's OWN daemon-state reply, first-hand and
73
+ // timestamped, so they run every tick with no fleet-wide freshness gate: a
74
+ // peer that has replied is planned off its verdict (any age — the push is
75
+ // idempotent), and a peer that has never replied is skipped and logged at
76
+ // INFO below. The worker-slot reconcile above reads only local durable keys,
77
+ // never peer verdicts, so it was never gated either.
93
78
  const result = await syncReservedAuthBundle();
94
79
  if (result.pushed.length > 0) {
95
80
  ctx.log('INFO', `auth-sync: pushed auth to ${result.pushed.join(', ')}`);
@@ -107,6 +92,15 @@ export class AuthSyncService extends BasePeriodicService {
107
92
  ctx.log('INFO', `auth-sync: adopted ${stores.adopted.length} legacy reserved item(s) into their bundle: ${stores.adopted.map((a) => `${a.bundle} ${a.key}`).join(', ')}`);
108
93
  for (const p of stores.pushed)
109
94
  ctx.log('INFO', `auth-sync: pushed ${p.bundle} (${p.keys.length} key(s)) to ${p.device}`);
95
+ // A peer with no reply yet — or a reply with no account rows (older CLI,
96
+ // fail-closed) — is informational, not a warning: a brand-new or never-
97
+ // dialed worker legitimately has none on an early tick, and the no-rows
98
+ // skip is transient during a rolling upgrade. One line per such peer per tick.
99
+ for (const s of stores.skipped) {
100
+ if (s.reason === SKIP_REASON_NO_PEER_REPLY || s.reason === SKIP_REASON_NO_ACCOUNT_ROWS) {
101
+ ctx.log('INFO', `auth-sync: ${s.device}: ${s.reason}`);
102
+ }
103
+ }
110
104
  for (const err of stores.errors)
111
105
  ctx.log('WARN', `auth-sync: reserved-store ${err.device}: ${err.message}`);
112
106
  }
@@ -51,9 +51,10 @@ export declare function daemonServiceLabel(): string;
51
51
  export declare function daemonSystemdUnitName(): string;
52
52
  /**
53
53
  * How many consecutive failed daemon starts disable the *implicit* auto-start
54
- * (`ensureDaemonStarted`). Matches `DAEMON_START_LIMIT_BURST` so the two layers
55
- * give up together rather than one silently masking the other. `agents daemon
56
- * start` is the deliberate override and is never gated by this.
54
+ * (`ensureDaemonStarted`). This bounds foreground-command auto-starts only; the
55
+ * OS-level unit restart is deliberately unbounded (`StartLimitIntervalSec=0`) so
56
+ * a wedged daemon always recovers (PHNX-4116). `agents daemon start` is the
57
+ * deliberate override and is never gated by this.
57
58
  */
58
59
  export declare const DAEMON_AUTOSTART_FAILURE_LIMIT = 5;
59
60
  /**
@@ -111,7 +112,6 @@ interface DaemonHeartbeat {
111
112
  export declare function writeHeartbeat(pid?: number): void;
112
113
  export declare function readHeartbeat(): DaemonHeartbeat | null;
113
114
  export declare function removeHeartbeat(): void;
114
- export declare function isDaemonWedged(): boolean;
115
115
  /**
116
116
  * Check whether a daemon is alive — via the pid file, or a fresh heartbeat when
117
117
  * the pid file has been lost (see resolveLiveDaemonPid). The observation itself
@@ -349,7 +349,7 @@ export declare function ensureDaemonStarted(): {
349
349
  * console-owning wrapper (cmd.exe / the npm shim). When that wrapper exits it
350
350
  * closes its console, and the detached daemon sharing that console receives a
351
351
  * console-close event that trips its shutdown handler — the daemon comes up,
352
- * binds the browser IPC socket, then tears itself down ~36ms later (#556).
352
+ * binds its sockets, then tears itself down ~36ms later (#556).
353
353
  * Going through `process.execPath` means a real PE/binary is spawned with
354
354
  * `detached: true` and no console, so nothing signals the daemon after launch.
355
355
  *
@@ -452,24 +452,35 @@ export declare function findSurvivingStateDirDaemons(exclude: Set<number>): numb
452
452
  * from launchd/systemd if applicable.
453
453
  *
454
454
  * The SIGTERM → grace → killTree sequence is unchanged; what it adds is
455
- * verification. After the daemon is gone it checks that the browser IPC
456
- * binding actually released — a stale socket present on disk but with no live
457
- * owner is the orphan that keeps clients hanging on it — and that no
458
- * `__daemon-run` for THIS state dir survives. A killTree escalation exits
459
- * without running the daemon's graceful handleShutdown, so that socket can be
460
- * left stale; this reclaims it (the owner is provably dead) and reports it. It
461
- * never reports success on an unverified stop.
455
+ * verification: after the daemon is gone it checks that no `__daemon-run` for
456
+ * THIS state dir survives and reclaims the state files a killTree escalation
457
+ * (which skips the graceful handleShutdown) can leave stale. The browser IPC
458
+ * socket is no longer among them — it left with the standalone `browser` CLI
459
+ * (PHNX-4101). It never reports success on an unverified stop.
462
460
  */
463
461
  export declare function stopDaemon(): DaemonStopResult;
464
- /** Get current daemon status including running state, PID, and enabled job count. */
462
+ /**
463
+ * Get current daemon status including running state, PID, enabled job count, and
464
+ * the supervised-restart history `agents daemon status` renders (PHNX-4116).
465
+ *
466
+ * There is no `wedged` state: a stalled daemon exits for a supervised
467
+ * systemd/launchd restart rather than sitting unresponsive, so the daemon is
468
+ * simply `running` or `stopped`, and its recent restarts are reported instead.
469
+ */
465
470
  export declare function getDaemonStatus(): {
466
- state: 'running' | 'wedged' | 'stopped';
471
+ state: 'running' | 'stopped';
467
472
  running: boolean;
468
473
  pid: number | null;
469
474
  jobCount: number;
470
475
  logPath: string;
471
476
  binaryPath: string | null;
472
477
  heartbeat: DaemonHeartbeat | null;
478
+ /** Supervised restarts in the last 24h (a service breaching its deadline exits the daemon for an OS restart). */
479
+ restarts24h: number;
480
+ /** The most recent supervised-restart cause, or null if none in the last 24h. */
481
+ lastRestartCause: string | null;
482
+ /** ISO timestamp of the most recent supervised restart in the last 24h, or null. */
483
+ lastRestartAt: string | null;
473
484
  };
474
485
  /** Read the daemon log, optionally limited to the last N lines. */
475
486
  export declare function readDaemonLog(lines?: number): string;