@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
@@ -1,291 +0,0 @@
1
- import { type BrowserProfileWithDeclarations } from './profiles.js';
2
- import { type ProfileName } from './types.js';
3
- /**
4
- * How many devices declare this profile — the shipped model's two kinds.
5
- *
6
- * NOT the deleted `scope: local | fleet`, which described where the config was
7
- * stored. `fungible` means several devices declare the name and each uses its
8
- * own browser; `identity` means exactly one does, so the name is a singular
9
- * browser. Prune only ever sees profiles THIS device declares, so `fungible`
10
- * here means "declared here and elsewhere too".
11
- */
12
- type PruneProfileClass = 'identity' | 'fungible';
13
- /**
14
- * Detect an identity-bearing profile whose stored endpoint is loopback, viewed
15
- * from a machine that is NOT the declaring device.
16
- *
17
- * That is the original `comet-local` bug: five real logins on the declaring
18
- * box, a bare logged-out chromium answering to the same name on a worker
19
- * because `cdp://localhost:N` is evaluated on the machine running the command.
20
- * The daemon now tunnels that shape (`resolve-target.ts`); doctor still flags
21
- * it so a worker does not report a green local binary/port for someone else's
22
- * browser. Kind comes from the registry (exactly one declaring device), never
23
- * from a stored field.
24
- */
25
- export declare function identityLoopbackMismatch(profile: BrowserProfileWithDeclarations): {
26
- misfiled: false;
27
- } | {
28
- misfiled: true;
29
- why: string;
30
- };
31
- /**
32
- * Per-profile runtime files we persist under
33
- * `~/.agents/.cache/browser/<composite>/`:
34
- *
35
- * - `pid` — child process ID we spawned (or 0 if attached to an
36
- * already-running browser)
37
- * - `command` — basename of the executable so we can defend against pid
38
- * reuse (`process.kill(pid, 0)` only proves *some* process
39
- * with that id exists; if the OS recycled it for an
40
- * unrelated daemon, we'd happily attach to garbage)
41
- * - `meta.json` — richer record: which daemon spawned us, when, the
42
- * user-data-dir we wrote into, optional tunnel PID. This
43
- * is the file the orphan reaper reads on daemon startup.
44
- * - `tasks.json` — open task state (managed elsewhere by service.ts)
45
- *
46
- * The one-value-per-file fields are kept for backward compat with older
47
- * builds; `meta.json` is additive and consulted preferentially.
48
- */
49
- interface ProfileRuntime {
50
- pid: number;
51
- port?: number;
52
- command?: string;
53
- /** Full path of the user-data-dir we passed to --user-data-dir, used by the reaper to confirm. */
54
- userDataDir?: string;
55
- /** PID of the daemon that spawned this. When the daemon dies, the next one reaps. */
56
- daemonPid?: number;
57
- /** Wall-clock time of spawn — useful for diagnostics and TTL-based cleanup. */
58
- spawnedAt?: number;
59
- /** What kind of process: 'browser' (Chrome-family), 'electron' (Notion etc.), or 'tunnel' (ssh -L). */
60
- kind?: 'browser' | 'electron' | 'tunnel';
61
- /** Local ssh -L PID, if this profile is SSH-backed. Distinct from `pid` (which is the remote browser, normally 0). */
62
- tunnelPid?: number;
63
- }
64
- /**
65
- * Save the runtime record atomically. We write the legacy one-value-per-
66
- * file fields plus a JSON meta blob so future code can read either.
67
- * The cache directory may not exist yet (first launch); we create it.
68
- */
69
- export declare function writeProfileRuntime(profileName: string, runtime: ProfileRuntime): void;
70
- /** Read just the JSON meta record. Returns null when absent or malformed. */
71
- export declare function readProfileRuntimeMeta(profileName: string): ProfileRuntime | null;
72
- /**
73
- * Read the runtime triple. Returns null when the files are missing OR when
74
- * the recorded pid no longer points at the same process we launched —
75
- * stale data is auto-cleaned to keep the next caller from acting on it.
76
- */
77
- export declare function readProfileRuntime(profileName: string): ProfileRuntime | null;
78
- /** Remove the pid/port/command/meta files. Leaves chrome-data + tasks.json intact. */
79
- export declare function clearProfileRuntime(profileName: string): void;
80
- /**
81
- * Recursively remove the whole profile cache (chrome-data, tasks.json,
82
- * everything). Used by `profiles remove` so an old profile name doesn't
83
- * leak its history into a freshly-recreated one.
84
- */
85
- export declare function removeProfileCache(profileName: string): void;
86
- /**
87
- * Find every cache directory belonging to a given profile. A runtime dir name
88
- * IS a connection key (`<name>@<endpoint>[.<fork>]`), so a single agents-cli
89
- * profile can have several side by side; this finds them all, plus the legacy
90
- * non-composite dir from older builds.
91
- *
92
- * Membership is decided by {@link keyBelongsToProfile} — the same single rule
93
- * `status`, `stopProfile`, and `findTask` use (RUSH-2709), so a fork dir is no
94
- * longer missed here while being matched there.
95
- */
96
- export declare function listProfileCacheDirs(profileName: ProfileName): string[];
97
- /**
98
- * `process.kill(pid, 0)` answers "is a process with this id alive?" — but
99
- * pid reuse is real on long-uptime machines, and a stale cache pointing
100
- * at a since-reassigned pid would happily call the imposter ours.
101
- *
102
- * Strategy: if we recorded the executable basename when we launched, ask
103
- * `ps` what command the live pid is running and compare. No command on
104
- * record means we fall back to the existence check (older cache entries
105
- * or `pid:0` for "attached to an externally-launched browser").
106
- */
107
- export declare function isProcessAlive(pid: number, expectedCommand?: string): boolean;
108
- /**
109
- * Snapshot of one tracked profile, suitable for `agents browser ps` output.
110
- * Combines the on-disk meta record with live-process probes so callers can
111
- * tell at a glance which entries are alive, stale, or have outright leaked.
112
- */
113
- interface ProfileSnapshot {
114
- /** Composite name as the cache dir is keyed: `<profile>` or `<profile>@<endpoint>`. */
115
- name: string;
116
- /** Absolute path of the cache dir. */
117
- dir: string;
118
- meta: ProfileRuntime | null;
119
- /** Live-process probe: does the recorded pid still exist + match command? */
120
- pidAlive: boolean;
121
- /** Live-process probe for the tunnel pid (SSH profiles). */
122
- tunnelAlive: boolean;
123
- /** True iff the daemon that started this is still alive. False == orphaned. */
124
- daemonAlive: boolean;
125
- /** Number of tasks recorded in tasks.json (open browser tabs). */
126
- taskCount: number;
127
- }
128
- /**
129
- * Read every profile cache directory and produce a structured snapshot.
130
- * Works without the daemon — `agents browser ps` uses this to render a
131
- * complete state view even when the IPC server is down. The caller can
132
- * post-process to detect conflicts (e.g. two profiles with the same port,
133
- * or a port someone else is listening on).
134
- */
135
- export declare function listAllProfileSnapshots(): ProfileSnapshot[];
136
- /**
137
- * Reap browser + tunnel processes spawned by daemons that no longer exist.
138
- * Call once on daemon startup. The idea: every process we spawn records
139
- * its daemonPid in meta.json. If that daemon is dead (crashed, SIGKILL),
140
- * its children were left rootless — kill them now so they don't hijack
141
- * the next session's local ports.
142
- *
143
- * We're conservative: a record with no daemonPid (older builds) is left
144
- * alone — we'd rather leak than wrongly kill a user-owned process that
145
- * happens to share metadata.
146
- */
147
- /**
148
- * Clean up what a DEAD daemon genuinely left behind — which is not the browser.
149
- *
150
- * A live local browser outliving its daemon is the NORMAL case, not an orphan.
151
- * `BrowserService.shutdown` deliberately closes only CDP and leaves the browser
152
- * running, and on macOS the spawn is detached so the daemon's own positive-pid
153
- * `killTree` reaches the daemon alone. This reaper used to read "the recorded
154
- * `daemonPid` has exited" as "everything it recorded is garbage" and SIGTERM the
155
- * browser — so replacing the daemon (a menubar activation, an upgrade, a crash
156
- * restart) killed a browser the user was looking at, and `clearProfileRuntime`
157
- * then removed the `port`/meta that {@link readProfileRuntime} needs, so even a
158
- * survivor could not be re-attached and a second browser would launch beside it.
159
- *
160
- * The three cases are now decided independently:
161
- *
162
- * - **A live local browser/electron is preserved untouched** — not signalled, not
163
- * cleared, and its `daemonPid` deliberately NOT rewritten. Ownership is adopted
164
- * only after an identity-checked attach succeeds (`adoptProfileRuntimeOwner`,
165
- * called from the reuse branch in `BrowserService.connectProfile`), so nothing
166
- * claims a browser it has not proven it can talk to. Re-running this is a no-op.
167
- * - **A dead browser record is cleared**, with no signal sent: there is nothing
168
- * alive to signal, and the stale pid/port would otherwise mislead the next
169
- * attach.
170
- * - **A stale tunnel IS reaped.** A local `ssh -L` cannot outlive its purpose, so
171
- * a dead owner does make it an orphan. This is the one thing the old code was
172
- * right about; it just shared a code path with the browser.
173
- *
174
- * The accepted trade: a genuinely leaked browser from a long-dead daemon is no
175
- * longer force-killed here. Idle/abandoned cleanup has its own owner in
176
- * `browser/hygiene.ts` (session-dead + idle), which the daemon's periodic tick and
177
- * `agents browser prune` both call — that is the right place for it, because it can
178
- * tell "idle and abandoned" from "in use right now" and this function cannot.
179
- */
180
- export declare function reapOrphanedProcesses(): {
181
- reaped: number;
182
- details: string[];
183
- };
184
- /**
185
- * Take ownership of a runtime record after an identity-checked attach succeeded.
186
- *
187
- * Called from the reuse branch in `BrowserService.connectProfile`, which has just
188
- * probed `/json/version` and run `verifyBrowserIdentity` against the profile's
189
- * expected browser family — so by this point the process on the recorded port is
190
- * proven to be ours. Only then may a new service claim it.
191
- *
192
- * Rewrites `daemonPid` ALONE. Every other field — `pid`, `port`, `command`,
193
- * `userDataDir`, `spawnedAt`, `kind`, `tunnelPid` — is the original launch's
194
- * metadata and stays exactly as recorded: this is an ownership handover, not a
195
- * re-registration, and rewriting the rest would lose the provenance the reaper and
196
- * the hygiene pass both read. A record that has since disappeared is left alone
197
- * rather than recreated from a partial view.
198
- */
199
- export declare function adoptProfileRuntimeOwner(profileName: string, daemonPid?: number): boolean;
200
- /**
201
- * True when ANY cache dir belonging to this profile still has a live browser or
202
- * SSH tunnel, or an open task. The composite naming (`<name>@<endpoint>`) means
203
- * one profile can own several runtime dirs, so checking only
204
- * `getProfileRuntimeDir(name)` would miss a running composite — and prune must
205
- * never remove a profile that is in use.
206
- *
207
- * A recorded `pid: 0` means "attached to a browser someone else launched", so it
208
- * is not our process to protect; an open task on that dir still counts as in use.
209
- */
210
- export declare function isProfileInUse(profileName: string): boolean;
211
- /** Why a profile is considered dead. */
212
- type PruneReason = 'binary-missing' | 'never-used';
213
- export interface PruneCandidate {
214
- name: string;
215
- scope: PruneProfileClass;
216
- reason: PruneReason;
217
- /** Cache dirs that would be removed along with the config entry. */
218
- cacheDirs: string[];
219
- }
220
- interface PrunePlan {
221
- /** Profiles that would be (or were) removed. */
222
- candidates: PruneCandidate[];
223
- /** Profiles deliberately left alone, with the guard that kept them. */
224
- kept: Array<{
225
- name: string;
226
- scope: PruneProfileClass;
227
- why: string;
228
- /**
229
- * True for an identity-bearing profile whose loopback endpoint only makes
230
- * sense on the declaring device. A structured flag, not a substring of
231
- * `why`: both the CLI's human output and `--json` consumers branch on it,
232
- * and sniffing the reason text would couple them to wording.
233
- */
234
- misfiled?: boolean;
235
- }>;
236
- }
237
- export declare const PRUNE_REASON_TEXT: Record<PruneReason, string>;
238
- /**
239
- * Decide which browser profiles are dead, WITHOUT touching anything.
240
- * `pruneProfiles` executes exactly this plan, so `--dry-run` and the real run
241
- * can never disagree.
242
- *
243
- * Dead means one of {@link PruneReason}: the configured browser cannot launch
244
- * here at all, or the profile has never been started so nothing on this disk
245
- * refers to it. That second reason is what actually reclaims agent-minted
246
- * throwaway profiles (RUSH-2716) — they are created for an installed browser, so
247
- * only "never started" identifies them.
248
- *
249
- * Four guards, and each exists because removing that profile would be wrong
250
- * rather than merely tidy:
251
- * - **in use** — a live browser, SSH tunnel, or open task on any of its dirs.
252
- * - **the configured default** — this machine resolves a bare
253
- * `agents browser start` to it; removing it breaks that command.
254
- * - **the auto-detected profile** (`auto-chrome`, or the `default` an older
255
- * build wrote) — still recognized and resolved by
256
- * `ensureDefaultBrowserProfile` as this machine's default; since PHNX-3296
257
- * it is no longer re-created on demand, so pruning it forces the user
258
- * back through `agents setup` to get a default browser again.
259
- *
260
- * Known limitation: `BrowserProfileConfig` records no creation time, so a
261
- * profile created seconds ago and not yet started is indistinguishable from an
262
- * abandoned one and is reported `never-used`. That is why the verb is explicit
263
- * and `--dry-run` exists.
264
- */
265
- export declare function planProfilePrune(profiles: Array<{
266
- name: string;
267
- scope: PruneProfileClass;
268
- launchableHere: boolean;
269
- /** Set when this identity-bearing profile's endpoint only makes sense on one machine. */
270
- misfiledWhy?: string;
271
- }>, opts?: {
272
- configuredDefault?: string;
273
- }): PrunePlan;
274
- /**
275
- * Build the prune plan from live config. Split from {@link planProfilePrune} so
276
- * the decision rules stay unit-testable without a configured machine.
277
- */
278
- export declare function buildProfilePrunePlan(): Promise<PrunePlan>;
279
- /**
280
- * Execute a prune plan: drop each candidate's config entry and wipe its cache
281
- * dirs. Returns the plan that was applied so the caller can report exactly what
282
- * went, matching what `--dry-run` printed.
283
- */
284
- export declare function pruneProfiles(plan: PrunePlan): Promise<PrunePlan>;
285
- /**
286
- * The executable/image name the live `pid` is running, or null if it can't be
287
- * determined. The process-listing API differs per OS: Windows has no `ps`, so
288
- * we query `tasklist` (CSV image name in column 1); POSIX uses `ps -o comm=`.
289
- */
290
- export declare function liveProcessCommand(pid: number): string | null;
291
- export {};