@phnx-labs/agents-cli 1.22.40 → 1.22.42

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 (201) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +14 -3
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.js +0 -1
  5. package/dist/cli/command-registry.d.ts +2 -0
  6. package/dist/cli/command-registry.js +5 -2
  7. package/dist/commands/accounts.d.ts +29 -0
  8. package/dist/commands/accounts.js +220 -29
  9. package/dist/commands/alias.js +1 -1
  10. package/dist/commands/auth.d.ts +9 -0
  11. package/dist/commands/auth.js +104 -0
  12. package/dist/commands/browser-sessions-picker.js +42 -62
  13. package/dist/commands/browser.d.ts +15 -0
  14. package/dist/commands/browser.js +145 -78
  15. package/dist/commands/computer-actions.d.ts +1 -1
  16. package/dist/commands/computer-actions.js +1 -1
  17. package/dist/commands/computer-sessions-picker.js +32 -55
  18. package/dist/commands/computer.d.ts +1 -1
  19. package/dist/commands/computer.js +2 -2
  20. package/dist/commands/doctor.d.ts +1 -1
  21. package/dist/commands/doctor.js +3 -3
  22. package/dist/commands/feed.js +4 -12
  23. package/dist/commands/hooks.js +1 -1
  24. package/dist/commands/import.js +1 -1
  25. package/dist/commands/insights.js +163 -85
  26. package/dist/commands/inspect.js +2 -2
  27. package/dist/commands/mine.js +1 -1
  28. package/dist/commands/org.d.ts +6 -0
  29. package/dist/commands/org.js +174 -0
  30. package/dist/commands/packages.js +1 -1
  31. package/dist/commands/prune.js +1 -1
  32. package/dist/commands/routines.js +1 -1
  33. package/dist/commands/run-account-picker.d.ts +19 -0
  34. package/dist/commands/run-account-picker.js +81 -0
  35. package/dist/commands/secrets.js +87 -97
  36. package/dist/commands/sessions-picker-factory.d.ts +40 -0
  37. package/dist/commands/sessions-picker-factory.js +67 -0
  38. package/dist/commands/sessions-picker.d.ts +1 -0
  39. package/dist/commands/sessions-picker.js +27 -5
  40. package/dist/commands/sessions-share.d.ts +25 -0
  41. package/dist/commands/sessions-share.js +166 -0
  42. package/dist/commands/sessions.js +2 -0
  43. package/dist/commands/setup-browser.js +5 -5
  44. package/dist/commands/setup-mine.js +1 -1
  45. package/dist/commands/setup-preferences.js +4 -4
  46. package/dist/commands/setup.js +5 -3
  47. package/dist/commands/sync.js +1 -1
  48. package/dist/commands/versions.js +1 -1
  49. package/dist/commands/view.js +1 -1
  50. package/dist/commands/webhook.js +14 -9
  51. package/dist/lib/account-capabilities.d.ts +10 -0
  52. package/dist/lib/account-capabilities.js +34 -0
  53. package/dist/lib/agent-spec/agents.d.ts +584 -0
  54. package/dist/lib/agent-spec/agents.js +3127 -0
  55. package/dist/lib/agent-spec/provider.js +1 -1
  56. package/dist/lib/agents.d.ts +2 -584
  57. package/dist/lib/agents.js +2 -3127
  58. package/dist/lib/browser/cdp.js +4 -0
  59. package/dist/lib/browser/chrome.js +12 -1
  60. package/dist/lib/browser/drivers/local.d.ts +8 -2
  61. package/dist/lib/browser/drivers/local.js +8 -2
  62. package/dist/lib/browser/drivers/ssh.d.ts +8 -2
  63. package/dist/lib/browser/drivers/ssh.js +11 -4
  64. package/dist/lib/browser/hygiene.d.ts +1 -1
  65. package/dist/lib/browser/hygiene.js +5 -1
  66. package/dist/lib/browser/profiles.d.ts +77 -4
  67. package/dist/lib/browser/profiles.js +121 -12
  68. package/dist/lib/browser/runtime-state.d.ts +11 -5
  69. package/dist/lib/browser/runtime-state.js +13 -9
  70. package/dist/lib/browser/service.d.ts +91 -30
  71. package/dist/lib/browser/service.js +342 -207
  72. package/dist/lib/browser/types.d.ts +96 -4
  73. package/dist/lib/browser/types.js +51 -0
  74. package/dist/lib/catchup.js +1 -1
  75. package/dist/lib/computer/actions.d.ts +1 -1
  76. package/dist/lib/computer/actions.js +1 -1
  77. package/dist/lib/{computer-rpc.js → computer/computer-rpc.js} +5 -5
  78. package/dist/lib/computer/dispatch.d.ts +1 -1
  79. package/dist/lib/computer/download.d.ts +1 -1
  80. package/dist/lib/computer/download.js +3 -3
  81. package/dist/lib/{ssh-tunnel.d.ts → computer/ssh-tunnel.d.ts} +1 -1
  82. package/dist/lib/{ssh-tunnel.js → computer/ssh-tunnel.js} +12 -12
  83. package/dist/lib/daemon/daemon.js +1 -1
  84. package/dist/lib/{runner.d.ts → daemon/runner.d.ts} +10 -10
  85. package/dist/lib/{runner.js → daemon/runner.js} +59 -118
  86. package/dist/lib/daemon-webhooks.d.ts +3 -1
  87. package/dist/lib/daemon-webhooks.js +12 -7
  88. package/dist/lib/device-config.js +1 -1
  89. package/dist/lib/devices/doctor-findings.d.ts +1 -1
  90. package/dist/lib/devices/doctor-findings.js +3 -3
  91. package/dist/lib/devices/fleet-inventory.js +1 -1
  92. package/dist/lib/devices/harness-inventory.js +1 -1
  93. package/dist/lib/devices/registry.js +4 -22
  94. package/dist/lib/doctor-diff.d.ts +1 -1
  95. package/dist/lib/doctor-diff.js +1 -1
  96. package/dist/lib/drift.js +1 -1
  97. package/dist/lib/entitlement.d.ts +31 -0
  98. package/dist/lib/entitlement.js +137 -0
  99. package/dist/lib/exec.js +39 -202
  100. package/dist/lib/feed/feed.js +2 -8
  101. package/dist/lib/fs-atomic.d.ts +7 -0
  102. package/dist/lib/fs-atomic.js +9 -0
  103. package/dist/lib/harness/adapter.d.ts +160 -0
  104. package/dist/lib/harness/adapter.js +47 -0
  105. package/dist/lib/harness/adapters/claude.d.ts +2 -0
  106. package/dist/lib/harness/adapters/claude.js +110 -0
  107. package/dist/lib/harness/adapters/codex.d.ts +2 -0
  108. package/dist/lib/harness/adapters/codex.js +83 -0
  109. package/dist/lib/harness/adapters/copilot.d.ts +2 -0
  110. package/dist/lib/harness/adapters/copilot.js +23 -0
  111. package/dist/lib/harness/adapters/cursor.d.ts +2 -0
  112. package/dist/lib/harness/adapters/cursor.js +38 -0
  113. package/dist/lib/harness/adapters/droid.d.ts +2 -0
  114. package/dist/lib/harness/adapters/droid.js +17 -0
  115. package/dist/lib/harness/adapters/grok.d.ts +2 -0
  116. package/dist/lib/harness/adapters/grok.js +14 -0
  117. package/dist/lib/harness/adapters/kimi.d.ts +2 -0
  118. package/dist/lib/harness/adapters/kimi.js +49 -0
  119. package/dist/lib/harness/adapters/muse.d.ts +2 -0
  120. package/dist/lib/harness/adapters/muse.js +44 -0
  121. package/dist/lib/harness/adapters/opencode.d.ts +2 -0
  122. package/dist/lib/harness/adapters/opencode.js +14 -0
  123. package/dist/lib/harness/exec-config-version.d.ts +8 -0
  124. package/dist/lib/harness/exec-config-version.js +22 -0
  125. package/dist/lib/harness/index.d.ts +1 -0
  126. package/dist/lib/harness/index.js +34 -0
  127. package/dist/lib/{hooks.d.ts → hooks/install.d.ts} +1 -1
  128. package/dist/lib/{hooks.js → hooks/install.js} +11 -11
  129. package/dist/lib/import.js +1 -1
  130. package/dist/lib/installations/index.d.ts +4 -4
  131. package/dist/lib/installations/index.js +3 -4
  132. package/dist/lib/installations/migrate.js +6 -6
  133. package/dist/lib/{shims.d.ts → installations/shims.d.ts} +2 -2
  134. package/dist/lib/{shims.js → installations/shims.js} +12 -114
  135. package/dist/lib/installations/store.d.ts +141 -3
  136. package/dist/lib/installations/store.js +475 -5
  137. package/dist/lib/installations/versions.d.ts +1 -126
  138. package/dist/lib/installations/versions.js +5 -465
  139. package/dist/lib/isolation-boundary-report.d.ts +1 -1
  140. package/dist/lib/isolation-boundary-report.js +1 -1
  141. package/dist/lib/mailbox-gc.js +2 -3
  142. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  143. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  144. package/dist/lib/monitors/dispatch.d.ts +1 -1
  145. package/dist/lib/monitors/dispatch.js +2 -2
  146. package/dist/lib/monitors/state.d.ts +1 -1
  147. package/dist/lib/observe-aliases.d.ts +2 -2
  148. package/dist/lib/observe-aliases.js +2 -11
  149. package/dist/lib/plugins/plugins.js +1 -1
  150. package/dist/lib/plugins/skills.js +1 -1
  151. package/dist/lib/prix-account.d.ts +158 -0
  152. package/dist/lib/prix-account.js +214 -0
  153. package/dist/lib/project-key.js +7 -0
  154. package/dist/lib/project-launch.js +1 -1
  155. package/dist/lib/refresh.js +2 -2
  156. package/dist/lib/resource-inventory.d.ts +1 -1
  157. package/dist/lib/resource-inventory.js +1 -1
  158. package/dist/lib/rules/rules.js +1 -1
  159. package/dist/lib/scheduling/routines.js +1 -1
  160. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  161. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  162. package/dist/lib/secrets/bundles.d.ts +1 -1
  163. package/dist/lib/secrets/bundles.js +1 -1
  164. package/dist/lib/secrets/headless.d.ts +16 -0
  165. package/dist/lib/secrets/headless.js +21 -0
  166. package/dist/lib/secrets/remote.d.ts +9 -7
  167. package/dist/lib/secrets/remote.js +18 -9
  168. package/dist/lib/self-heal/checks/hook-runtime.js +1 -1
  169. package/dist/lib/self-heal/checks/path.js +1 -1
  170. package/dist/lib/self-heal/checks/shadowing.js +1 -1
  171. package/dist/lib/self-heal/checks/shims.js +1 -1
  172. package/dist/lib/session/discover.d.ts +39 -0
  173. package/dist/lib/session/discover.js +3 -3
  174. package/dist/lib/session/parse.js +24 -42
  175. package/dist/lib/session/recovery.js +1 -1
  176. package/dist/lib/session/share-html.d.ts +55 -0
  177. package/dist/lib/session/share-html.js +319 -0
  178. package/dist/lib/settings-manifest.d.ts +2 -0
  179. package/dist/lib/settings-manifest.js +81 -3
  180. package/dist/lib/share/publish.d.ts +38 -0
  181. package/dist/lib/share/publish.js +81 -8
  182. package/dist/lib/staleness/prune.d.ts +1 -1
  183. package/dist/lib/staleness/prune.js +1 -1
  184. package/dist/lib/staleness/writers/hooks.js +1 -1
  185. package/dist/lib/startup/command-registry.d.ts +2 -1
  186. package/dist/lib/startup/command-registry.js +5 -3
  187. package/dist/lib/teams/agents.js +2 -19
  188. package/dist/lib/teams/parsers.js +20 -26
  189. package/dist/lib/teams/registry.js +2 -21
  190. package/dist/lib/triggers/handlers.d.ts +37 -2
  191. package/dist/lib/triggers/handlers.js +57 -6
  192. package/dist/lib/triggers/webhook.d.ts +80 -6
  193. package/dist/lib/triggers/webhook.js +128 -4
  194. package/dist/lib/types.d.ts +1 -1
  195. package/dist/lib/uninstall.js +1 -1
  196. package/dist/lib/version.d.ts +9 -2
  197. package/dist/lib/version.js +11 -9
  198. package/dist/lib/wrap.d.ts +33 -0
  199. package/dist/lib/wrap.js +70 -0
  200. package/package.json +1 -1
  201. /package/dist/lib/{computer-rpc.d.ts → computer/computer-rpc.d.ts} +0 -0
@@ -227,6 +227,10 @@ export function verifyBrowserIdentity(reported, expected, port, host = 'localhos
227
227
  // doesn't override the Chromium branding. Accept chrome here so attaching
228
228
  // to a Comet instance doesn't trip a false "identity mismatch".
229
229
  comet: ['comet', 'chrome'],
230
+ // Arc reports itself as plain "Chrome/<version>" in /json/version (verified
231
+ // live: Arc 1.15x → "Chrome/151"), so accept chrome to avoid a false
232
+ // identity mismatch when attaching to a real Arc.
233
+ arc: ['arc', 'chrome'],
230
234
  brave: ['brave', 'brave-browser', 'chrome'],
231
235
  // Windows/Chromium Edge reports its /json/version "Browser" field as
232
236
  // "Edg/<version>" (the `Edg` token, not `Edge`), which normalizeBrowserName
@@ -23,6 +23,7 @@ const BROWSER_PATHS = {
23
23
  chromium: ['/Applications/Chromium.app/Contents/MacOS/Chromium'],
24
24
  brave: ['/Applications/Brave Browser.app/Contents/MacOS/Brave Browser'],
25
25
  edge: ['/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'],
26
+ arc: ['/Applications/Arc.app/Contents/MacOS/Arc'],
26
27
  custom: [],
27
28
  },
28
29
  linux: {
@@ -31,6 +32,8 @@ const BROWSER_PATHS = {
31
32
  chromium: ['/usr/bin/chromium', '/usr/bin/chromium-browser', '/snap/bin/chromium'],
32
33
  brave: ['/usr/bin/brave-browser', '/usr/bin/brave'],
33
34
  edge: ['/usr/bin/microsoft-edge'],
35
+ // Arc has no Linux build (macOS + Windows only).
36
+ arc: [],
34
37
  custom: [],
35
38
  },
36
39
  win32: {
@@ -57,6 +60,9 @@ const BROWSER_PATHS = {
57
60
  `${WIN_PROGRAMFILES_X86}\\Microsoft\\Edge\\Application\\msedge.exe`,
58
61
  `${WIN_LOCALAPPDATA}\\Microsoft\\Edge\\Application\\msedge.exe`,
59
62
  ],
63
+ // Arc ships a Windows build, but its install path is not yet verified here;
64
+ // leave unlisted (undetected) rather than guess a path that false-positives.
65
+ arc: [],
60
66
  custom: [],
61
67
  },
62
68
  };
@@ -162,6 +168,9 @@ export function findBrowserPath(browserType, customBinary) {
162
168
  if (browserType === 'comet' && platform === 'linux') {
163
169
  throw new Error('Browser "comet" is not available on Linux (Comet ships macOS and Windows builds only). Use chrome, chromium, brave, or edge on this platform.');
164
170
  }
171
+ if (browserType === 'arc' && platform === 'linux') {
172
+ throw new Error('Browser "arc" is not available on Linux (Arc ships macOS and Windows builds only). Use chrome, chromium, brave, or edge on this platform.');
173
+ }
165
174
  throw new Error(`Browser "${browserType}" not found. Install it first.`);
166
175
  }
167
176
  // Per-platform Chromium-family priority list for "no --profile" auto-pick.
@@ -170,7 +179,9 @@ export function findBrowserPath(browserType, customBinary) {
170
179
  // way cdp.ts expects, so they'd need separate drivers.
171
180
  const DEFAULT_BROWSER_PRIORITY = {
172
181
  // macOS: Chrome leads (>70% of dev machines), then the rest of the family.
173
- darwin: ['chrome', 'brave', 'edge', 'chromium', 'comet'],
182
+ // Arc is last: it's in maintenance mode and needs a blank tab to drive, so it
183
+ // shouldn't win auto-pick over a mainstream browser.
184
+ darwin: ['chrome', 'brave', 'edge', 'chromium', 'comet', 'arc'],
174
185
  // Linux: Chrome/Chromium first (apt/snap), then Brave/Edge if present.
175
186
  linux: ['chrome', 'chromium', 'brave', 'edge'],
176
187
  // Windows: Edge is preinstalled on every supported build, so it's the
@@ -1,8 +1,14 @@
1
1
  import { CDPClient } from '../cdp.js';
2
- import type { BrowserProfile } from '../types.js';
2
+ import type { BrowserProfile, ConnectionKey } from '../types.js';
3
3
  export interface LocalConnection {
4
4
  cdp: CDPClient;
5
5
  port: number;
6
6
  pid: number;
7
7
  }
8
- export declare function connectLocal(endpoint: string, profile: BrowserProfile): Promise<LocalConnection>;
8
+ export declare function connectLocal(endpoint: string, profile: BrowserProfile,
9
+ /**
10
+ * Runtime key (`<profile>@<endpoint>`) the launched browser's user-data-dir,
11
+ * pid, and port files are stored under. Separate from `profile.name`, which
12
+ * stays the bare user-facing name and appears only in messages (RUSH-2709).
13
+ */
14
+ key: ConnectionKey): Promise<LocalConnection>;
@@ -31,7 +31,13 @@ const TUNNEL_PROCESS_NAMES = new Set(['ssh', 'autossh', 'mosh-client', 'socat'])
31
31
  function isTunnelProcess(command) {
32
32
  return TUNNEL_PROCESS_NAMES.has(command.toLowerCase());
33
33
  }
34
- export async function connectLocal(endpoint, profile) {
34
+ export async function connectLocal(endpoint, profile,
35
+ /**
36
+ * Runtime key (`<profile>@<endpoint>`) the launched browser's user-data-dir,
37
+ * pid, and port files are stored under. Separate from `profile.name`, which
38
+ * stays the bare user-facing name and appears only in messages (RUSH-2709).
39
+ */
40
+ key) {
35
41
  const url = new URL(endpoint);
36
42
  if (url.protocol !== 'cdp:') {
37
43
  throw new Error(`Invalid local endpoint: ${endpoint}`);
@@ -91,7 +97,7 @@ export async function connectLocal(endpoint, profile) {
91
97
  const chromeOpts = { ...profile.chrome, viewport: profile.viewport };
92
98
  let launched;
93
99
  try {
94
- launched = await launchBrowser(profile.name, profile.browser, newPort, chromeOpts, profile.secrets, profile.binary, profile.electron === true);
100
+ launched = await launchBrowser(key, profile.browser, newPort, chromeOpts, profile.secrets, profile.binary, profile.electron === true);
95
101
  }
96
102
  catch (launchErr) {
97
103
  const reason = launchErr instanceof Error ? launchErr.message : String(launchErr);
@@ -1,5 +1,5 @@
1
1
  import { CDPClient } from '../cdp.js';
2
- import type { BrowserProfile } from '../types.js';
2
+ import type { BrowserProfile, ConnectionKey } from '../types.js';
3
3
  import { shellQuote } from '../../ssh-exec.js';
4
4
  export { shellQuote };
5
5
  export interface SSHConnection {
@@ -16,7 +16,13 @@ export interface SSHConnection {
16
16
  * strings differ (no `&` backgrounding, no `lsof`, `.exe` instead of `.app`).
17
17
  */
18
18
  export type RemoteOs = 'windows' | 'posix';
19
- export declare function connectSSH(endpoint: string, profile: BrowserProfile): Promise<SSHConnection>;
19
+ export declare function connectSSH(endpoint: string, profile: BrowserProfile,
20
+ /**
21
+ * Runtime key (`<profile>@<endpoint>`) this connection is stored under. It
22
+ * keys the tunnel's runtime record; `profile.name` is the bare, user-facing
23
+ * name and appears only in messages (RUSH-2709).
24
+ */
25
+ key: ConnectionKey): Promise<SSHConnection>;
20
26
  /**
21
27
  * Wrap a PowerShell script as a `-EncodedCommand` invocation. Base64 of the
22
28
  * UTF-16LE bytes is a single quote-free token, so it rides through Node spawn
@@ -11,9 +11,15 @@ export { shellQuote };
11
11
  // The `ssh -L` tunnel spawn is shared with `agents computer --device`; it lives in
12
12
  // the single ssh-tunnel helper. Calling it with no options preserves this
13
13
  // driver's original foreground, stderr-captured behavior exactly.
14
- import { startSSHTunnel } from '../../ssh-tunnel.js';
14
+ import { startSSHTunnel } from '../../computer/ssh-tunnel.js';
15
15
  import { encodePwshBase64 } from '../../pwsh.js';
16
- export async function connectSSH(endpoint, profile) {
16
+ export async function connectSSH(endpoint, profile,
17
+ /**
18
+ * Runtime key (`<profile>@<endpoint>`) this connection is stored under. It
19
+ * keys the tunnel's runtime record; `profile.name` is the bare, user-facing
20
+ * name and appears only in messages (RUSH-2709).
21
+ */
22
+ key) {
17
23
  const url = new URL(endpoint);
18
24
  if (url.protocol !== 'ssh:') {
19
25
  throw new Error(`Invalid SSH endpoint: ${endpoint}`);
@@ -88,7 +94,7 @@ export async function connectSSH(endpoint, profile) {
88
94
  // browser process.
89
95
  const tunnelPid = tunnel.pid ?? 0;
90
96
  if (tunnelPid > 0) {
91
- writeProfileRuntime(profile.name, {
97
+ writeProfileRuntime(key, {
92
98
  pid: 0,
93
99
  port: localPort,
94
100
  command: 'ssh',
@@ -108,7 +114,7 @@ export async function connectSSH(endpoint, profile) {
108
114
  // stays synchronous, and killRemoteBrowser never rejects.
109
115
  killRemoteBrowser(user, host, remoteOs, remotePort).catch(() => { });
110
116
  tunnel.kill();
111
- clearProfileRuntime(profile.name);
117
+ clearProfileRuntime(key);
112
118
  },
113
119
  };
114
120
  }
@@ -142,6 +148,7 @@ const POSIX_BROWSER_PATHS = {
142
148
  chromium: '/Applications/Chromium.app/Contents/MacOS/Chromium',
143
149
  brave: '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser',
144
150
  edge: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
151
+ arc: '/Applications/Arc.app/Contents/MacOS/Arc',
145
152
  };
146
153
  // Windows App Paths registry keys per browser. CreateProcess (used by WMI
147
154
  // Win32_Process.Create) does not honor App Paths the way ShellExecute/`start`
@@ -1,5 +1,5 @@
1
1
  import { type PidSessionEntry } from '../session/pid-registry.js';
2
- import type { ReapResult, Task } from './types.js';
2
+ import { type ReapResult, type Task } from './types.js';
3
3
  /** Default idle window before an untouched task is reaped. */
4
4
  export declare const DEFAULT_IDLE_MS: number;
5
5
  /**
@@ -28,6 +28,7 @@
28
28
  */
29
29
  import { isPidAlive, isSessionIdLiveOnProcessTable } from '../session/active.js';
30
30
  import { listPidSessionEntries, sessionIdFromLivePid } from '../session/pid-registry.js';
31
+ import { parseConnectionKey } from './types.js';
31
32
  /** Default idle window before an untouched task is reaped. */
32
33
  export const DEFAULT_IDLE_MS = 30 * 60_000;
33
34
  /**
@@ -131,7 +132,10 @@ export async function reapAbandonedTasks(service, opts = {}) {
131
132
  continue;
132
133
  }
133
134
  if (opts.dryRun) {
134
- closed.push({ task: task.name, profile, reason });
135
+ // Report the BARE profile, exactly as the real run does below — `profile`
136
+ // here is the runtime key from `listTasks()`, and printing the two shapes
137
+ // in one column made `gc --dry-run` and `gc` disagree (RUSH-2709).
138
+ closed.push({ task: task.name, profile: parseConnectionKey(profile).profile, reason });
135
139
  continue;
136
140
  }
137
141
  const result = await service.stop(task.name);
@@ -1,6 +1,30 @@
1
1
  import type { BrowserProfile } from './types.js';
2
2
  export type { BrowserProfile } from './types.js';
3
- export declare const DEFAULT_BROWSER_PROFILE_NAME = "default";
3
+ /**
4
+ * Name of the profile `ensureDefaultBrowserProfile` auto-detects and pins.
5
+ *
6
+ * It is `auto-chrome`, NOT `default`, since RUSH-2709: `default` used to be
7
+ * both this concrete profile AND the alias meaning "whatever profile the user
8
+ * configured", so `--profile default` landed on a literal auto-detected Chrome
9
+ * on one command and on the user's configured Comet on another. The alias now
10
+ * lives alone in {@link DEFAULT_PROFILE_ALIAS} and resolves in exactly one
11
+ * place ({@link resolveProfileRef}).
12
+ */
13
+ export declare const DEFAULT_BROWSER_PROFILE_NAME = "auto-chrome";
14
+ /**
15
+ * What older builds named the auto-detected profile. Still honored everywhere:
16
+ * a user whose machine already carries a `default` profile keeps using it (and
17
+ * its running browser + runtime dirs) rather than having a second one created
18
+ * beside it.
19
+ */
20
+ export declare const LEGACY_DEFAULT_BROWSER_PROFILE_NAME = "default";
21
+ /**
22
+ * The reserved ALIAS. `--profile default` (and a `browser.profile` config value
23
+ * of `default`) means "the configured default profile", not a profile called
24
+ * `default` — unless a profile literally named `default` exists, which still
25
+ * wins, so no existing config breaks.
26
+ */
27
+ export declare const DEFAULT_PROFILE_ALIAS = "default";
4
28
  /**
5
29
  * Where a profile is stored, and therefore who sees it:
6
30
  * - `local` — this machine's `devices/<machine>/agents.yaml` (`deviceBrowser`)
@@ -14,7 +38,7 @@ export interface ScopedBrowserProfile {
14
38
  }
15
39
  /**
16
40
  * The device-local configured default profile name (set via
17
- * `agents browser profiles set-default`), or undefined when unset. When set, it
41
+ * `agents browser use`), or undefined when unset. When set, it
18
42
  * is the profile `agents browser start` resolves to for BOTH the no-`--profile`
19
43
  * path and an explicit `--profile default`. Stored as this machine's
20
44
  * `browser.profile` device-config key (the per-device doc's `config:` block —
@@ -62,7 +86,7 @@ export declare function isProfileLaunchableHere(profile: BrowserProfile): boolea
62
86
  * set-default <name>`) when it names an existing profile that can launch here;
63
87
  * (2) an existing `default` profile that can launch here; (3) auto-pick the
64
88
  * first installed Chromium-family browser per the platform priority list in
65
- * chrome.ts (macOS: chrome > brave > edge > chromium > comet; Linux: chrome >
89
+ * chrome.ts (macOS: chrome > brave > edge > chromium > comet > arc; Linux: chrome >
66
90
  * chromium > brave > edge; Windows: edge > chrome > brave > comet) and pin a
67
91
  * `default` profile to it. Throws an actionable error if none of those binaries
68
92
  * are installed.
@@ -75,6 +99,55 @@ export declare function isProfileLaunchableHere(profile: BrowserProfile): boolea
75
99
  * that no longer exists, or can't launch here, warns and falls through — never a
76
100
  * hard fail.
77
101
  */
102
+ /**
103
+ * The auto-detected profile this machine already carries, under either name —
104
+ * the current `auto-chrome` or the `default` an older build wrote. Callers that
105
+ * ask "is a default profile set up here?" MUST use this rather than probing one
106
+ * name, or a machine that predates the RUSH-2709 rename grows a second one.
107
+ */
108
+ export declare function getAutoDetectedProfile(): Promise<BrowserProfile | null>;
109
+ /**
110
+ * Resolve what a caller typed after `--profile` to a real, BARE profile name.
111
+ * Every command — stop, status, navigate, tab, use, and (through
112
+ * {@link resolveProfileRefForStart}) start — routes through this one function,
113
+ * which is the whole point: before RUSH-2709 only `start` honored the reserved
114
+ * `default` alias, so `--profile default` meant three different profiles across
115
+ * three commands.
116
+ *
117
+ * Order:
118
+ * 1. A profile that literally bears the given name always wins — including
119
+ * one a user genuinely named `default`, which resolves to itself.
120
+ * 2. `default` (the alias) or no argument at all → the configured
121
+ * `browser.profile` for this machine, if it names a profile that exists.
122
+ * 3. → the auto-detected profile ({@link DEFAULT_BROWSER_PROFILE_NAME}), or
123
+ * its legacy `default`-named predecessor when that is what is on disk.
124
+ * 4. Otherwise the input is returned unchanged (so the caller reports its own
125
+ * `Profile "x" not found`), or `undefined` when nothing was passed.
126
+ *
127
+ * It never creates a profile, never warns, and never checks whether the profile
128
+ * can launch HERE. That is deliberate: for most callers `--profile` is a FILTER
129
+ * (`status`, `tasks`, `navigate --task`), where an absent flag means "no filter"
130
+ * and rewriting or warning about the user's config would be wrong. Note the
131
+ * corollary at those call sites — pass a ref only when the user gave one; do not
132
+ * resolve `undefined` into a concrete profile, or an unscoped listing silently
133
+ * becomes a scoped one.
134
+ */
135
+ export declare function resolveProfileRef(ref?: string): Promise<string | undefined>;
136
+ /**
137
+ * `start`'s resolver. Same order as {@link resolveProfileRef} for an explicit
138
+ * name, but the IMPLICIT path (no `--profile`, or the bare `default` alias with
139
+ * no profile of that name) goes through {@link ensureDefaultBrowserProfile} —
140
+ * which additionally verifies the resolved default can launch on THIS machine,
141
+ * warns and falls through when it can't, and regenerates or creates one.
142
+ *
143
+ * `start` is the only command that launches a browser, so it is the only one
144
+ * that may do those things; routing a filter-only command through this would
145
+ * warn about, and rewrite, config the user never asked it to touch.
146
+ *
147
+ * Throws when no profile exists and no supported browser is installed —
148
+ * `ensureDefaultBrowserProfile`'s actionable "install one of …" error.
149
+ */
150
+ export declare function resolveProfileRefForStart(ref?: string): Promise<string>;
78
151
  export declare function ensureDefaultBrowserProfile(): Promise<BrowserProfile>;
79
152
  /**
80
153
  * Compute the LOCAL port a profile will occupy at runtime:
@@ -133,7 +206,7 @@ export declare function padColumn(text: string, width: number): string;
133
206
  * Two things used to be called "default" in this listing with no way to tell
134
207
  * them apart (RUSH-2710): the profile literally NAMED `default` (the
135
208
  * auto-detected one), and whichever profile this machine resolves a bare
136
- * `agents browser start` to (`agents config set browser.profile <name>`). They
209
+ * `agents browser start` to (`agents browser use <name>`). They
137
210
  * are frequently different profiles. Now only the second is a marker — a `*` in
138
211
  * a leading column, explained by a legend line — so the name column carries just
139
212
  * the name and `default` in it always means the profile of that name.
@@ -3,7 +3,31 @@ import { getBrowserRuntimeDir as getBrowserRuntimeDirRoot, readMeta, updateMeta,
3
3
  import { getConfigValue } from '../device-config.js';
4
4
  import { findBrowserPath, findFirstInstalledBrowser, isPortInUse } from './chrome.js';
5
5
  import { DEFAULT_VIEWPORT } from './devices.js';
6
- export const DEFAULT_BROWSER_PROFILE_NAME = 'default';
6
+ /**
7
+ * Name of the profile `ensureDefaultBrowserProfile` auto-detects and pins.
8
+ *
9
+ * It is `auto-chrome`, NOT `default`, since RUSH-2709: `default` used to be
10
+ * both this concrete profile AND the alias meaning "whatever profile the user
11
+ * configured", so `--profile default` landed on a literal auto-detected Chrome
12
+ * on one command and on the user's configured Comet on another. The alias now
13
+ * lives alone in {@link DEFAULT_PROFILE_ALIAS} and resolves in exactly one
14
+ * place ({@link resolveProfileRef}).
15
+ */
16
+ export const DEFAULT_BROWSER_PROFILE_NAME = 'auto-chrome';
17
+ /**
18
+ * What older builds named the auto-detected profile. Still honored everywhere:
19
+ * a user whose machine already carries a `default` profile keeps using it (and
20
+ * its running browser + runtime dirs) rather than having a second one created
21
+ * beside it.
22
+ */
23
+ export const LEGACY_DEFAULT_BROWSER_PROFILE_NAME = 'default';
24
+ /**
25
+ * The reserved ALIAS. `--profile default` (and a `browser.profile` config value
26
+ * of `default`) means "the configured default profile", not a profile called
27
+ * `default` — unless a profile literally named `default` exists, which still
28
+ * wins, so no existing config breaks.
29
+ */
30
+ export const DEFAULT_PROFILE_ALIAS = 'default';
7
31
  /**
8
32
  * True for a profile whose contents only make sense on THIS machine, so it must
9
33
  * live in the per-machine doc rather than the fleet-synced agents.yaml.
@@ -21,11 +45,11 @@ export const DEFAULT_BROWSER_PROFILE_NAME = 'default';
21
45
  * into central from being written back there by {@link updateProfile}.
22
46
  */
23
47
  function isMachineLocalProfile(name) {
24
- return name === DEFAULT_BROWSER_PROFILE_NAME;
48
+ return name === DEFAULT_BROWSER_PROFILE_NAME || name === LEGACY_DEFAULT_BROWSER_PROFILE_NAME;
25
49
  }
26
50
  /**
27
51
  * The device-local configured default profile name (set via
28
- * `agents browser profiles set-default`), or undefined when unset. When set, it
52
+ * `agents browser use`), or undefined when unset. When set, it
29
53
  * is the profile `agents browser start` resolves to for BOTH the no-`--profile`
30
54
  * path and an explicit `--profile default`. Stored as this machine's
31
55
  * `browser.profile` device-config key (the per-device doc's `config:` block —
@@ -165,7 +189,7 @@ export function isProfileLaunchableHere(profile) {
165
189
  * set-default <name>`) when it names an existing profile that can launch here;
166
190
  * (2) an existing `default` profile that can launch here; (3) auto-pick the
167
191
  * first installed Chromium-family browser per the platform priority list in
168
- * chrome.ts (macOS: chrome > brave > edge > chromium > comet; Linux: chrome >
192
+ * chrome.ts (macOS: chrome > brave > edge > chromium > comet > arc; Linux: chrome >
169
193
  * chromium > brave > edge; Windows: edge > chrome > brave > comet) and pin a
170
194
  * `default` profile to it. Throws an actionable error if none of those binaries
171
195
  * are installed.
@@ -178,33 +202,118 @@ export function isProfileLaunchableHere(profile) {
178
202
  * that no longer exists, or can't launch here, warns and falls through — never a
179
203
  * hard fail.
180
204
  */
205
+ /**
206
+ * The auto-detected profile this machine already carries, under either name —
207
+ * the current `auto-chrome` or the `default` an older build wrote. Callers that
208
+ * ask "is a default profile set up here?" MUST use this rather than probing one
209
+ * name, or a machine that predates the RUSH-2709 rename grows a second one.
210
+ */
211
+ export async function getAutoDetectedProfile() {
212
+ return ((await getProfile(DEFAULT_BROWSER_PROFILE_NAME)) ??
213
+ (await getProfile(LEGACY_DEFAULT_BROWSER_PROFILE_NAME)));
214
+ }
215
+ /**
216
+ * Resolve what a caller typed after `--profile` to a real, BARE profile name.
217
+ * Every command — stop, status, navigate, tab, use, and (through
218
+ * {@link resolveProfileRefForStart}) start — routes through this one function,
219
+ * which is the whole point: before RUSH-2709 only `start` honored the reserved
220
+ * `default` alias, so `--profile default` meant three different profiles across
221
+ * three commands.
222
+ *
223
+ * Order:
224
+ * 1. A profile that literally bears the given name always wins — including
225
+ * one a user genuinely named `default`, which resolves to itself.
226
+ * 2. `default` (the alias) or no argument at all → the configured
227
+ * `browser.profile` for this machine, if it names a profile that exists.
228
+ * 3. → the auto-detected profile ({@link DEFAULT_BROWSER_PROFILE_NAME}), or
229
+ * its legacy `default`-named predecessor when that is what is on disk.
230
+ * 4. Otherwise the input is returned unchanged (so the caller reports its own
231
+ * `Profile "x" not found`), or `undefined` when nothing was passed.
232
+ *
233
+ * It never creates a profile, never warns, and never checks whether the profile
234
+ * can launch HERE. That is deliberate: for most callers `--profile` is a FILTER
235
+ * (`status`, `tasks`, `navigate --task`), where an absent flag means "no filter"
236
+ * and rewriting or warning about the user's config would be wrong. Note the
237
+ * corollary at those call sites — pass a ref only when the user gave one; do not
238
+ * resolve `undefined` into a concrete profile, or an unscoped listing silently
239
+ * becomes a scoped one.
240
+ */
241
+ export async function resolveProfileRef(ref) {
242
+ if (ref && ref !== DEFAULT_PROFILE_ALIAS) {
243
+ return ref;
244
+ }
245
+ if (ref === DEFAULT_PROFILE_ALIAS && (await getProfile(ref))) {
246
+ // A profile the user literally named `default` outranks the alias.
247
+ return ref;
248
+ }
249
+ const configured = getConfiguredDefaultProfileName();
250
+ if (configured && configured !== DEFAULT_PROFILE_ALIAS && (await getProfile(configured))) {
251
+ return configured;
252
+ }
253
+ if (await getProfile(DEFAULT_BROWSER_PROFILE_NAME))
254
+ return DEFAULT_BROWSER_PROFILE_NAME;
255
+ if (await getProfile(LEGACY_DEFAULT_BROWSER_PROFILE_NAME)) {
256
+ return LEGACY_DEFAULT_BROWSER_PROFILE_NAME;
257
+ }
258
+ return ref;
259
+ }
260
+ /**
261
+ * `start`'s resolver. Same order as {@link resolveProfileRef} for an explicit
262
+ * name, but the IMPLICIT path (no `--profile`, or the bare `default` alias with
263
+ * no profile of that name) goes through {@link ensureDefaultBrowserProfile} —
264
+ * which additionally verifies the resolved default can launch on THIS machine,
265
+ * warns and falls through when it can't, and regenerates or creates one.
266
+ *
267
+ * `start` is the only command that launches a browser, so it is the only one
268
+ * that may do those things; routing a filter-only command through this would
269
+ * warn about, and rewrite, config the user never asked it to touch.
270
+ *
271
+ * Throws when no profile exists and no supported browser is installed —
272
+ * `ensureDefaultBrowserProfile`'s actionable "install one of …" error.
273
+ */
274
+ export async function resolveProfileRefForStart(ref) {
275
+ if (ref && ref !== DEFAULT_PROFILE_ALIAS)
276
+ return ref;
277
+ // A profile the user literally named `default` still outranks the alias.
278
+ if (ref === DEFAULT_PROFILE_ALIAS && (await getProfile(ref)))
279
+ return ref;
280
+ return (await ensureDefaultBrowserProfile()).name;
281
+ }
181
282
  export async function ensureDefaultBrowserProfile() {
182
283
  const configured = getConfiguredDefaultProfileName();
183
- if (configured) {
284
+ if (configured && configured !== DEFAULT_PROFILE_ALIAS) {
184
285
  const chosen = await getProfile(configured);
185
286
  if (chosen && isProfileLaunchableHere(chosen))
186
287
  return chosen;
187
288
  console.warn(chosen
188
289
  ? `warning: configured default browser profile "${configured}" can't launch on this ` +
189
290
  `machine (its browser/binary isn't installed here); falling back to auto-detect. ` +
190
- `Fix with: agents browser profiles set-default <name> (or --unset)`
291
+ `Fix with: agents browser use <name> (or --unset)`
191
292
  : `warning: configured default browser profile "${configured}" no longer exists; ` +
192
- `falling back to auto-detect. Fix with: agents browser profiles set-default <name> (or --unset)`);
293
+ `falling back to auto-detect. Fix with: agents browser use <name> (or --unset)`);
193
294
  }
194
- const existing = await getProfile(DEFAULT_BROWSER_PROFILE_NAME);
295
+ // Prefer whichever auto-detected profile this machine already carries: the
296
+ // current `auto-chrome`, else the `default` an older build wrote. Reusing the
297
+ // legacy one is what keeps a currently-running browser (and its runtime dirs,
298
+ // keyed `default@endpoint-0`) attached after the rename.
299
+ const existing = (await getProfile(DEFAULT_BROWSER_PROFILE_NAME)) ??
300
+ (await getProfile(LEGACY_DEFAULT_BROWSER_PROFILE_NAME));
195
301
  if (existing && isProfileLaunchableHere(existing))
196
302
  return existing;
197
303
  const detected = findFirstInstalledBrowser();
198
304
  if (!detected) {
199
- throw new Error('No supported browser found. Install one of: Chrome, Brave, Edge, Chromium, or Comet, ' +
305
+ throw new Error('No supported browser found. Install one of: Chrome, Brave, Edge, Chromium, Comet, or Arc, ' +
200
306
  'then re-run `agents browser start`. Or create a profile explicitly with ' +
201
- '`agents browser profiles create <name> --browser <chrome|comet|chromium|brave|edge|custom>`. ' +
307
+ '`agents browser profiles create <name> --browser <chrome|comet|chromium|brave|edge|arc|custom>`. ' +
202
308
  'Note: Safari and Firefox are not supported — agents browser drives over the ' +
203
309
  'Chrome DevTools Protocol, which they don\'t implement.');
204
310
  }
205
311
  const freePort = await findFreeProfilePort();
206
312
  const profile = {
207
- name: DEFAULT_BROWSER_PROFILE_NAME,
313
+ // Regenerate under the name that is already on disk when there is one, so a
314
+ // stale legacy `default` is repaired in place instead of leaving the user
315
+ // with two auto-detected profiles.
316
+ name: existing?.name ?? DEFAULT_BROWSER_PROFILE_NAME,
208
317
  description: `Auto-detected ${detected.browserType} profile`,
209
318
  browser: detected.browserType,
210
319
  binary: detected.binary,
@@ -431,7 +540,7 @@ export function padColumn(text, width) {
431
540
  * Two things used to be called "default" in this listing with no way to tell
432
541
  * them apart (RUSH-2710): the profile literally NAMED `default` (the
433
542
  * auto-detected one), and whichever profile this machine resolves a bare
434
- * `agents browser start` to (`agents config set browser.profile <name>`). They
543
+ * `agents browser start` to (`agents browser use <name>`). They
435
544
  * are frequently different profiles. Now only the second is a marker — a `*` in
436
545
  * a leading column, explained by a legend line — so the name column carries just
437
546
  * the name and `default` in it always means the profile of that name.
@@ -1,4 +1,5 @@
1
1
  import { type ProfileScope } from './profiles.js';
2
+ import { type ProfileName } from './types.js';
2
3
  /**
3
4
  * Per-profile runtime files we persist under
4
5
  * `~/.agents/.cache/browser/<composite>/`:
@@ -55,12 +56,16 @@ export declare function clearProfileRuntime(profileName: string): void;
55
56
  */
56
57
  export declare function removeProfileCache(profileName: string): void;
57
58
  /**
58
- * Find every cache directory belonging to a given profile. The composite
59
- * naming (`<name>@<endpoint>`) means a single agents-cli profile can have
60
- * multiple runtime dirs side by side; this finds them all plus the legacy
59
+ * Find every cache directory belonging to a given profile. A runtime dir name
60
+ * IS a connection key (`<name>@<endpoint>[.<fork>]`), so a single agents-cli
61
+ * profile can have several side by side; this finds them all, plus the legacy
61
62
  * non-composite dir from older builds.
63
+ *
64
+ * Membership is decided by {@link keyBelongsToProfile} — the same single rule
65
+ * `status`, `stopProfile`, and `findTask` use (RUSH-2709), so a fork dir is no
66
+ * longer missed here while being matched there.
62
67
  */
63
- export declare function listProfileCacheDirs(profileName: string): string[];
68
+ export declare function listProfileCacheDirs(profileName: ProfileName): string[];
64
69
  /**
65
70
  * `process.kill(pid, 0)` answers "is a process with this id alive?" — but
66
71
  * pid reuse is real on long-uptime machines, and a stale cache pointing
@@ -162,7 +167,8 @@ export declare const PRUNE_REASON_TEXT: Record<PruneReason, string>;
162
167
  * - **in use** — a live browser, SSH tunnel, or open task on any of its dirs.
163
168
  * - **the configured default** — this machine resolves a bare
164
169
  * `agents browser start` to it; removing it breaks that command.
165
- * - **`default`** auto-regenerated by `ensureDefaultBrowserProfile`, so
170
+ * - **the auto-detected profile** (`auto-chrome`, or the `default` an older
171
+ * build wrote) — auto-regenerated by `ensureDefaultBrowserProfile`, so
166
172
  * pruning it is pure churn.
167
173
  * - **fleet-synced** — deleting one removes it from EVERY machine, so it takes
168
174
  * the explicit `includeFleet` opt-in.
@@ -1,7 +1,8 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { execFileSync } from 'child_process';
4
- import { getProfileRuntimeDir, getBrowserRuntimeDir, listProfilesWithScope, getConfiguredDefaultProfileName, isProfileLaunchableHere, deleteProfile, DEFAULT_BROWSER_PROFILE_NAME, } from './profiles.js';
4
+ import { getProfileRuntimeDir, getBrowserRuntimeDir, listProfilesWithScope, getConfiguredDefaultProfileName, isProfileLaunchableHere, deleteProfile, DEFAULT_BROWSER_PROFILE_NAME, LEGACY_DEFAULT_BROWSER_PROFILE_NAME, } from './profiles.js';
5
+ import { keyBelongsToProfile } from './types.js';
5
6
  const PID_FILE = 'pid';
6
7
  const PORT_FILE = 'port';
7
8
  const COMMAND_FILE = 'command';
@@ -106,10 +107,14 @@ export function removeProfileCache(profileName) {
106
107
  catch { /* gone */ }
107
108
  }
108
109
  /**
109
- * Find every cache directory belonging to a given profile. The composite
110
- * naming (`<name>@<endpoint>`) means a single agents-cli profile can have
111
- * multiple runtime dirs side by side; this finds them all plus the legacy
110
+ * Find every cache directory belonging to a given profile. A runtime dir name
111
+ * IS a connection key (`<name>@<endpoint>[.<fork>]`), so a single agents-cli
112
+ * profile can have several side by side; this finds them all, plus the legacy
112
113
  * non-composite dir from older builds.
114
+ *
115
+ * Membership is decided by {@link keyBelongsToProfile} — the same single rule
116
+ * `status`, `stopProfile`, and `findTask` use (RUSH-2709), so a fork dir is no
117
+ * longer missed here while being matched there.
113
118
  */
114
119
  export function listProfileCacheDirs(profileName) {
115
120
  const root = getBrowserRuntimeDir();
@@ -117,9 +122,7 @@ export function listProfileCacheDirs(profileName) {
117
122
  return [];
118
123
  const matches = [];
119
124
  for (const entry of fs.readdirSync(root)) {
120
- if (entry === profileName)
121
- matches.push(path.join(root, entry));
122
- else if (entry.startsWith(`${profileName}@`))
125
+ if (keyBelongsToProfile(entry, profileName))
123
126
  matches.push(path.join(root, entry));
124
127
  }
125
128
  return matches;
@@ -292,7 +295,8 @@ export const PRUNE_REASON_TEXT = {
292
295
  * - **in use** — a live browser, SSH tunnel, or open task on any of its dirs.
293
296
  * - **the configured default** — this machine resolves a bare
294
297
  * `agents browser start` to it; removing it breaks that command.
295
- * - **`default`** auto-regenerated by `ensureDefaultBrowserProfile`, so
298
+ * - **the auto-detected profile** (`auto-chrome`, or the `default` an older
299
+ * build wrote) — auto-regenerated by `ensureDefaultBrowserProfile`, so
296
300
  * pruning it is pure churn.
297
301
  * - **fleet-synced** — deleting one removes it from EVERY machine, so it takes
298
302
  * the explicit `includeFleet` opt-in.
@@ -310,7 +314,7 @@ export function planProfilePrune(profiles, opts = {}) {
310
314
  keep('fleet-synced (pass --fleet to include it)');
311
315
  continue;
312
316
  }
313
- if (name === DEFAULT_BROWSER_PROFILE_NAME) {
317
+ if (name === DEFAULT_BROWSER_PROFILE_NAME || name === LEGACY_DEFAULT_BROWSER_PROFILE_NAME) {
314
318
  keep('the auto-detected default profile');
315
319
  continue;
316
320
  }