@phnx-labs/agents-cli 1.22.94 → 1.22.96

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.
@@ -1,16 +1,19 @@
1
1
  import type { ArcNativeTabRef } from './drivers/arc.js';
2
2
  export type { ArcNativeTabRef } from './drivers/arc.js';
3
- export type BrowserType = 'chrome' | 'comet' | 'chromium' | 'brave' | 'edge' | 'arc' | 'custom';
3
+ export type BrowserType = 'chrome' | 'comet' | 'chromium' | 'brave' | 'edge' | 'arc' | 'firefox' | 'custom';
4
4
  /**
5
5
  * The transport backend a live browser connection uses (PHNX-2399).
6
6
  * - `cdp` — Chrome DevTools Protocol (the existing path for all Chromium-family browsers).
7
7
  * - `arc-native` — Apple Events via `osascript` (the native Arc path, no CDP port required).
8
+ * - `bidi` — WebDriver BiDi over a WebSocket (Firefox, PHNX-4043; Firefox 129+
9
+ * ships no CDP at all).
8
10
  *
9
11
  * Load-bearing: every action method on `BrowserService` that calls `conn.cdp.send()`
10
12
  * must check `conn.backend` and route to the native driver instead when it is
11
- * `arc-native`. Unsupported native verbs throw `ArcNativeCapabilityError`.
13
+ * `arc-native` or `bidi`. Unsupported verbs throw `ArcNativeCapabilityError` /
14
+ * `FirefoxCapabilityError`.
12
15
  */
13
- export type BackendKind = 'cdp' | 'arc-native';
16
+ export type BackendKind = 'cdp' | 'arc-native' | 'bidi';
14
17
  /**
15
18
  * Stable native identity carried by an Arc profile declaration (PHNX-2399).
16
19
  * One agents-cli profile is one Arc Space: the Space already carries its Arc
@@ -176,6 +179,8 @@ export interface BrowserProfile {
176
179
  * `resolveProfileDataDir(profile)` rather than reading directly.
177
180
  */
178
181
  userDataDir?: string;
182
+ /** Chromium profile directory inside `userDataDir` for a discovered native profile (PHNX-4042). */
183
+ profileDirectory?: string;
179
184
  chrome?: ChromeOptions;
180
185
  secrets?: string;
181
186
  viewport?: {
@@ -190,6 +195,26 @@ export interface BrowserProfile {
190
195
  logHost?: string;
191
196
  /** Native Arc identity. Present only for an `arc-native:` profile. */
192
197
  arc?: ArcNativeProfileIdentity;
198
+ /**
199
+ * The Firefox profile this agents-cli profile is pinned to (PHNX-4043).
200
+ * Present only for a `bidi:` profile discovered from `profiles.ini`; the
201
+ * directory itself is {@link userDataDir}, which is what Firefox is launched
202
+ * with (`--profile <dir>`).
203
+ */
204
+ firefox?: FirefoxProfileIdentity;
205
+ }
206
+ /**
207
+ * Stable identity of a Firefox profile discovered from `profiles.ini` (PHNX-4043).
208
+ * One agents-cli profile is one Firefox profile: it already carries the cookies
209
+ * and logins, so agents never learn a second concept.
210
+ */
211
+ export interface FirefoxProfileIdentity {
212
+ /** The `Name=` of the `[ProfileN]` section. Display + slug source only. */
213
+ profileName: string;
214
+ /** The `profiles.ini` the entry was read from. Display only. */
215
+ iniPath: string;
216
+ /** Whether `profiles.ini` marks the entry `Default=1`. Display only. */
217
+ isDefault: boolean;
193
218
  }
194
219
  /** Parsed form of `BrowserProfile.targetFilter`. */
195
220
  export interface TargetFilter {
@@ -205,6 +230,10 @@ export interface ChromeOptions {
205
230
  x?: number;
206
231
  y?: number;
207
232
  };
233
+ /** The browser's own user-data dir; set only for a discovered native profile (PHNX-4042). */
234
+ userDataDir?: string;
235
+ /** Chromium profile directory inside `userDataDir` (`Default`, `Profile 1`, ...). */
236
+ profileDirectory?: string;
208
237
  }
209
238
  export interface Task {
210
239
  id: string;
@@ -298,6 +327,20 @@ export interface TabInfo {
298
327
  /** Whether this is the task's current tab (the one URL-less verbs act on). */
299
328
  current?: boolean;
300
329
  }
330
+ /**
331
+ * One row of `agents browser tabs --all`: a top-level tab open in the profile's
332
+ * browser. Owned by an agents-cli task → `task` names it and `id` is that
333
+ * task's short tab id; otherwise (the owner's own tab, or a tab from another
334
+ * tool) `task` is absent and `id` is the browser's own tab id.
335
+ */
336
+ export interface ProfileTabInfo {
337
+ id: string;
338
+ url: string;
339
+ title: string;
340
+ task?: string;
341
+ /** The queried task's current tab. */
342
+ current?: boolean;
343
+ }
301
344
  export interface ProfileStatus {
302
345
  /**
303
346
  * The BARE profile name — what the user passed to `--profile` and what
@@ -331,6 +374,7 @@ export interface TaskStatus {
331
374
  url: string;
332
375
  title?: string;
333
376
  current?: boolean;
377
+ task?: string;
334
378
  }>;
335
379
  }
336
380
  export interface HistoricalTask {
@@ -366,6 +410,8 @@ export interface IPCRequest {
366
410
  action: IPCAction;
367
411
  task?: string;
368
412
  taskName?: string;
413
+ /** tab-list: every tab open in the profile browser, not only the task's own. */
414
+ all?: boolean;
369
415
  profile?: string;
370
416
  url?: string;
371
417
  tabId?: string;
@@ -514,7 +560,8 @@ export interface IPCResponse {
514
560
  */
515
561
  reused?: boolean;
516
562
  windowTargetId?: string;
517
- tabs?: TabInfo[];
563
+ /** `tab-list` rows; `task` is absent for a tab no agents-cli task owns (`--all`). */
564
+ tabs?: ProfileTabInfo[];
518
565
  profiles?: ProfileStatus[];
519
566
  history?: HistoricalTask[];
520
567
  /** `gc`: what the abandoned-task reaper closed (or would close under dryRun). */
@@ -32,6 +32,18 @@ export class UsageSyncService extends BasePeriodicService {
32
32
  const { consumeUsageSnapshotsFromSharedStore, publishUsageSnapshotToSharedStore } = await import('../accounting/usage-sync.js');
33
33
  const { consumeSessionMirrorFromSharedStore, publishSessionMirrorToSharedStore } = await import('../session/mirror.js');
34
34
  // Publish every owned field BEFORE the single git exchange so they ride one commit.
35
+ // Discovered native browser profiles (Arc Spaces, Comet profiles) go into this
36
+ // device's declaration first, so every other box lists them with WHERE=<here>
37
+ // and routes a `--profile` for one of them to this machine (PHNX-4042).
38
+ const { publishDiscoveredProfiles } = await import('../browser/profiles.js');
39
+ const profiles = await publishDiscoveredProfiles().catch((error) => ({
40
+ published: [],
41
+ errors: { publish: error instanceof Error ? error.message : String(error) },
42
+ }));
43
+ if (profiles.published.length > 0)
44
+ ctx.log('INFO', `browser-profiles: published ${profiles.published.join(', ')} to this device's declaration`);
45
+ for (const [browser, message] of Object.entries(profiles.errors))
46
+ ctx.log('WARN', `browser-profiles: ${browser}: ${message}`);
35
47
  const published = await publishUsageSnapshotToSharedStore();
36
48
  if (published.changed)
37
49
  ctx.log('INFO', `usage-sync: published usage snapshot to ${published.path}`);
@@ -135,6 +135,12 @@ export async function resolveViewer(opts = {}) {
135
135
  console.error(`[viewer] "${resolved}" is Arc, which cannot open a new viewer tab — using the OS browser.`);
136
136
  return 'os';
137
137
  }
138
+ if (profile.browser === 'firefox') {
139
+ // agents drives Firefox headless over BiDi for its own read-back; a page a
140
+ // human is meant to read goes to the visible OS browser, not the headless one.
141
+ console.error(`[viewer] "${resolved}" is a headless-automation Firefox profile — using the OS browser.`);
142
+ return 'os';
143
+ }
138
144
  if (!isProfileLaunchableHere(profile)) {
139
145
  console.error(`[viewer] "${resolved}" cannot launch on this machine — using the OS browser.`);
140
146
  return 'os';
@@ -1245,7 +1245,7 @@ export interface HostEntry {
1245
1245
  /** Browser profile definition stored in agents.yaml. */
1246
1246
  export interface BrowserProfileConfig {
1247
1247
  description?: string;
1248
- browser: 'chrome' | 'comet' | 'chromium' | 'brave' | 'edge' | 'arc' | 'custom';
1248
+ browser: 'chrome' | 'comet' | 'chromium' | 'brave' | 'edge' | 'arc' | 'firefox' | 'custom';
1249
1249
  binary?: string;
1250
1250
  electron?: boolean;
1251
1251
  /**
@@ -1290,6 +1290,12 @@ export interface BrowserProfileConfig {
1290
1290
  * ownership guard compares a running instance against to reject a port-squatter.
1291
1291
  */
1292
1292
  userDataDir?: string;
1293
+ /**
1294
+ * Chromium profile directory inside {@link userDataDir} (`Default`,
1295
+ * `Profile 1`, ...) for a profile discovered from the browser's own store
1296
+ * (PHNX-4042). Launch passes it as `--profile-directory`.
1297
+ */
1298
+ profileDirectory?: string;
1293
1299
  chrome?: {
1294
1300
  headless?: boolean;
1295
1301
  args?: string[];
@@ -1310,6 +1316,12 @@ export interface BrowserProfileConfig {
1310
1316
  spaceId: string;
1311
1317
  spaceTitle: string;
1312
1318
  };
1319
+ /** The `profiles.ini` entry a discovered Firefox profile is pinned to (PHNX-4043); the dir is `userDataDir`. */
1320
+ firefox?: {
1321
+ profileName: string;
1322
+ iniPath: string;
1323
+ isDefault: boolean;
1324
+ };
1313
1325
  }
1314
1326
  /** Options controlling which agents and resources are synced during `agents sync` / `agents use`. */
1315
1327
  export interface SyncOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phnx-labs/agents-cli",
3
- "version": "1.22.94",
3
+ "version": "1.22.96",
4
4
  "description": "One CLI for all your AI coding agents - versions, config, cloud dispatch, sessions, and teams (now with first-class Grok Build CLI support)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",