@phnx-labs/agents-cli 1.22.22 → 1.22.23

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 (91) hide show
  1. package/CHANGELOG.md +209 -0
  2. package/README.md +8 -2
  3. package/dist/commands/doctor.js +15 -7
  4. package/dist/commands/exec.js +20 -6
  5. package/dist/commands/focus.d.ts +76 -4
  6. package/dist/commands/focus.js +219 -40
  7. package/dist/commands/fork.d.ts +20 -2
  8. package/dist/commands/fork.js +91 -64
  9. package/dist/commands/go.d.ts +25 -0
  10. package/dist/commands/go.js +63 -2
  11. package/dist/commands/harness-wizard.d.ts +206 -0
  12. package/dist/commands/harness-wizard.js +403 -0
  13. package/dist/commands/harness.d.ts +12 -0
  14. package/dist/commands/harness.js +97 -101
  15. package/dist/commands/resume.js +10 -3
  16. package/dist/commands/secrets.js +25 -30
  17. package/dist/commands/sessions-resume.d.ts +21 -3
  18. package/dist/commands/sessions-resume.js +50 -11
  19. package/dist/commands/sessions.d.ts +81 -5
  20. package/dist/commands/sessions.js +325 -66
  21. package/dist/commands/watchdog.js +13 -2
  22. package/dist/lib/agents.d.ts +1 -1
  23. package/dist/lib/agents.js +132 -0
  24. package/dist/lib/codex-policy.d.ts +17 -0
  25. package/dist/lib/codex-policy.js +48 -0
  26. package/dist/lib/crabbox/lease.d.ts +25 -0
  27. package/dist/lib/crabbox/lease.js +62 -0
  28. package/dist/lib/daemon.js +70 -0
  29. package/dist/lib/exec.d.ts +4 -0
  30. package/dist/lib/exec.js +88 -54
  31. package/dist/lib/feed-broadcast.d.ts +1 -20
  32. package/dist/lib/feed-broadcast.js +31 -1
  33. package/dist/lib/hooks.js +12 -2
  34. package/dist/lib/mcp.js +44 -0
  35. package/dist/lib/menubar/MenubarHelper.app/Contents/Info.plist +1 -5
  36. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  37. package/dist/lib/menubar/MenubarHelper.app/Contents/_CodeSignature/CodeResources +2 -15
  38. package/dist/lib/models.d.ts +0 -5
  39. package/dist/lib/models.js +48 -0
  40. package/dist/lib/plugin-marketplace.js +9 -0
  41. package/dist/lib/pricing/prices.json +119 -92
  42. package/dist/lib/pricing/table.js +13 -0
  43. package/dist/lib/remote-agents-json.d.ts +29 -1
  44. package/dist/lib/remote-agents-json.js +47 -10
  45. package/dist/lib/resources/mcp.js +2 -0
  46. package/dist/lib/resources/permissions.js +3 -0
  47. package/dist/lib/resources/types.d.ts +2 -1
  48. package/dist/lib/runner.js +28 -19
  49. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  50. package/dist/lib/secrets/Agents CLI.app/Contents/Info.plist +0 -2
  51. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  52. package/dist/lib/secrets/Agents CLI.app/Contents/_CodeSignature/CodeResources +1 -13
  53. package/dist/lib/secrets/index.d.ts +15 -1
  54. package/dist/lib/secrets/index.js +118 -49
  55. package/dist/lib/secrets/reaper.d.ts +87 -0
  56. package/dist/lib/secrets/reaper.js +184 -0
  57. package/dist/lib/secrets/remote.d.ts +29 -0
  58. package/dist/lib/secrets/remote.js +37 -1
  59. package/dist/lib/session/active.d.ts +36 -1
  60. package/dist/lib/session/active.js +60 -19
  61. package/dist/lib/session/actor-sidecar.d.ts +14 -0
  62. package/dist/lib/session/actor-sidecar.js +67 -4
  63. package/dist/lib/session/db.d.ts +1 -1
  64. package/dist/lib/session/db.js +32 -1
  65. package/dist/lib/session/discover.js +168 -0
  66. package/dist/lib/session/parse.d.ts +10 -0
  67. package/dist/lib/session/parse.js +98 -0
  68. package/dist/lib/session/remote-list.d.ts +10 -1
  69. package/dist/lib/session/remote-list.js +2 -8
  70. package/dist/lib/session/remote.d.ts +57 -3
  71. package/dist/lib/session/remote.js +90 -26
  72. package/dist/lib/session/resume-command.d.ts +6 -0
  73. package/dist/lib/session/resume-command.js +8 -0
  74. package/dist/lib/session/session-cache.d.ts +173 -0
  75. package/dist/lib/session/session-cache.js +399 -0
  76. package/dist/lib/session/types.d.ts +1 -1
  77. package/dist/lib/session/types.js +1 -1
  78. package/dist/lib/session/width.d.ts +1 -1
  79. package/dist/lib/session/width.js +12 -2
  80. package/dist/lib/shims.d.ts +2 -2
  81. package/dist/lib/shims.js +40 -5
  82. package/dist/lib/staleness/writers/hooks.js +1 -1
  83. package/dist/lib/types.d.ts +1 -1
  84. package/dist/lib/usage.d.ts +13 -0
  85. package/dist/lib/usage.js +215 -0
  86. package/dist/lib/versions.js +13 -2
  87. package/package.json +1 -1
  88. package/dist/bin/agents +0 -0
  89. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  90. package/dist/lib/menubar/MenubarHelper.app/Contents/Resources/AppIcon.icns +0 -0
  91. package/dist/lib/secrets/Agents CLI.app/Contents/Resources/AppIcon.icns +0 -0
@@ -66,6 +66,9 @@ interface SessionsOptions extends SessionFilterOptions {
66
66
  local?: boolean;
67
67
  /** --device <target...> — alias for --host; resolves against the device registry. */
68
68
  device?: string[];
69
+ /** --devices <target...> — plural alias for --device; a bare `all`/`fleet` value
70
+ * means "search the whole fleet" (already the default), so it never errors. */
71
+ devices?: string[];
69
72
  /** Query every registered online compute device and merge tool evidence. */
70
73
  fleet?: boolean;
71
74
  /** Aggregate static program sites instead of returning matching call evidence. */
@@ -127,6 +130,17 @@ export declare function formatActiveRowDescription(s: ActiveSession): string;
127
130
  * can't be correlated back to a transcript on disk.
128
131
  */
129
132
  export declare function indexActiveBySessionId(active: ActiveSession[]): Map<string, ActiveSession>;
133
+ /** The SessionMeta fields the live-row backfill reads — the enrichment a running process cannot report. */
134
+ type BackfillMeta = Pick<SessionMeta, 'version' | 'timestamp' | 'label' | 'ticketId' | 'prUrl' | 'prNumber'>;
135
+ /**
136
+ * Backfill display-only fields onto live rows from the indexed SessionMeta, by
137
+ * full session id (RUSH-2205). A running process reports no agent version, and a
138
+ * live orphan row usually carries no ticket/PR/label/start-time; the historical
139
+ * index does. Only a field the live row LACKS is filled — the live signal always
140
+ * wins when present. Pure (no I/O) so the join is unit-tested against fixtures;
141
+ * the DB read that builds `metaById` is the caller's concern.
142
+ */
143
+ export declare function backfillActiveRowsFromMeta(sessions: ActiveSession[], metaById: Map<string, BackfillMeta>): void;
130
144
  /**
131
145
  * The live decoration for a listing row: a status glyph and the latest-turn
132
146
  * preview, when the session is still running. `●` running / `◐` waiting on the
@@ -198,6 +212,22 @@ export declare function serializeActiveSessionsForJson(sessions: ActiveSession[]
198
212
  prLink: string | null;
199
213
  viewingIn: string | null;
200
214
  }>;
215
+ /**
216
+ * Build the (one or two) rendered lines for a single active-session row.
217
+ * Indent is the leading whitespace (2 spaces for flat groups, 4 inside a window
218
+ * sub-group). Sized to `termW` so no line ever wraps under tmux/SSH (RUSH-2205):
219
+ *
220
+ * line 1: id · agent version · status · owner · created X · idle Y · ticket/PR
221
+ * line 2: └ label/topic (+ checklist) · jump locator (ssh/tmux/detached)
222
+ *
223
+ * The label/topic gets its own line so it is no longer buried in a truncated grey
224
+ * snippet, and the actionable ticket/PR badges ride line 1. Version and the
225
+ * ticket/PR/label are backfilled onto the {@link ActiveSession} from the indexed
226
+ * SessionMeta before this renders (a live process reports none of them). Pure +
227
+ * exported so the row layout is unit-tested for content and width without a
228
+ * captured stdout.
229
+ */
230
+ export declare function renderActiveRowLines(s: ActiveSession, indent: string, termW: number): string[];
201
231
  /**
202
232
  * Compact owner display for the `--active` owner column: the local-part of a
203
233
  * resolved actor email/login (`muqsit@getrush.ai` -> `muqsit`), the id as-is
@@ -313,10 +343,17 @@ export declare function remoteHostsToDial(hosts: string[] | undefined, self: str
313
343
  * call it, so the browser can never disagree with `--active --json` about which
314
344
  * sessions are live (it used to call the local-only `getActiveSessions()` directly
315
345
  * and silently hid every remote session).
346
+ *
347
+ * RUSH-2062: default path is cache-first against the daemon-warmed shared
348
+ * snapshot (`session-cache.ts`). Menubar / Factory / watchdog / CLI share one
349
+ * warm result instead of each re-running the full SSH fan-out. `forceRefresh`
350
+ * (or `AGENTS_SESSIONS_FORCE_REFRESH=1`) re-gathers live; scoped `--host` lists
351
+ * always gather live so a filter never returns a wrong unscoped snapshot.
316
352
  */
317
353
  export declare function gatherActiveSessions(opts?: {
318
354
  local?: boolean;
319
355
  hosts?: string[];
356
+ forceRefresh?: boolean;
320
357
  }): Promise<{
321
358
  sessions: ActiveSession[];
322
359
  remoteDeviceCount: number;
@@ -582,6 +619,10 @@ export interface SessionQueryResolution {
582
619
  export declare function resolveSessionQuery(pool: SessionMeta[], query: string, options?: {
583
620
  indexFallback?: boolean;
584
621
  }): SessionQueryResolution;
622
+ /** Honest result of a fleet sweep that found nothing: it says what the sweep
623
+ * actually did — how many peers answered, which were unreachable — instead of
624
+ * dead-ending on "search with --device <host>" after the search already ran. */
625
+ export declare function fleetNotFoundMessage(query: string, deviceCount: number, unreachable: string[]): string[];
585
626
  /** Filter and rank sessions by a multi-term search query across metadata and content. */
586
627
  export declare function filterSessionsByQuery(sessions: SessionMeta[], query: string | undefined): SessionMeta[];
587
628
  /**
@@ -626,11 +667,32 @@ export type MetadataResolveOutcome = {
626
667
  kind: 'partial';
627
668
  failedPeers: string[];
628
669
  };
670
+ /**
671
+ * A match unique enough to resolve on the FIRST peer that returns it and cancel
672
+ * the rest of the fleet sweep: a full session UUID, which is globally unique.
673
+ *
674
+ * Only a full UUID qualifies. A session **label** is deliberately NOT definitive
675
+ * here even on an exact match: labels are free-form and can collide, so a
676
+ * distinct session may carry the same label on a peer that has not answered yet
677
+ * — early-exiting on the first would silently, and nondeterministically, resume
678
+ * the wrong session (whichever peer replied first). Labels therefore stay
679
+ * all-settle so a cross-machine label conflict surfaces as an ambiguity, and a
680
+ * short-id PREFIX stays all-settle for the same reason (RUSH-2203).
681
+ */
682
+ export declare function isDefinitiveMatch(session: SessionMeta, selector: string): boolean;
683
+ /**
684
+ * Whether a selector may enable early-exit on the cancellable fan-out — only a
685
+ * full UUID, which is globally unique so the first hit is the only hit. Labels,
686
+ * keywords, and short-id prefixes stay all-settle: their uniqueness (or
687
+ * conflict) is only knowable once every peer has answered. See
688
+ * {@link isDefinitiveMatch}.
689
+ */
690
+ export declare function selectorAllowsEarlyExit(selector: string): boolean;
629
691
  /** Resolve a fleet sweep through the same canonical full-id / prefix resolver as
630
692
  * local lookups, then group copies by logical session id. Synced mirrors of one
631
693
  * session therefore stay one candidate even when several machines report them;
632
694
  * distinct ids sharing a prefix remain distinct ambiguity candidates. */
633
- export declare function fleetCandidatesByQuery(rows: SessionMeta[], query: string): FleetSessionCandidate[];
695
+ export declare function fleetCandidatesByQuery(rows: SessionMeta[], query: string, trustResolvedRows?: boolean): FleetSessionCandidate[];
634
696
  /** Fixed peer argv for the metadata resolver. Scope flags compose identically on
635
697
  * every host; `--all` removes the SSH login cwd/time window, not agent/project filters. */
636
698
  export declare function metadataResolveForwardedArgs(selector: string, scope: Pick<SessionFilterOptions, 'agent' | 'project'>): string[];
@@ -661,14 +723,28 @@ export declare function resolveSessionMetadataValue(selector: string, scope?: {
661
723
  * (its transcript and agent binary live there — a local `--host` hop would
662
724
  * re-discover locally and dead-end), returning `'rendered'`.
663
725
  * - more than one logical session → print every full-id candidate with its
664
- * machine labels, returning `'conflict'`.
665
- * - none → `'not-found'`, letting the caller print the local
666
- * "no session on this machine" message.
726
+ * machine labels, returning `{ kind: 'conflict' }`.
727
+ * - none → `{ kind: 'not-found', deviceCount, unreachable }`,
728
+ * letting the caller print an honest sweep-aware message.
729
+ *
730
+ * A full-UUID query opts into early-exit: the first peer holding it resolves the
731
+ * sweep and cancels the rest, so a fast peer is not bounded by the slowest one.
732
+ * A short-id prefix stays all-settle — its ambiguity is only known once every
733
+ * peer has answered, so it must wait to surface a conflict.
667
734
  *
668
735
  * No fuzzy/content fallback: the sweep forwards the id selector and every result
669
736
  * is resolved through `resolveSessionQuery`, the same id-only resolver used locally.
670
737
  */
671
- export declare function resolveSessionAcrossFleet(query: string, mode: ViewMode, hosts?: string[], deps?: FleetResolveDeps): Promise<'rendered' | 'conflict' | 'not-found'>;
738
+ export type FleetResolveResult = {
739
+ kind: 'rendered';
740
+ } | {
741
+ kind: 'conflict';
742
+ } | {
743
+ kind: 'not-found';
744
+ deviceCount: number;
745
+ unreachable: string[];
746
+ };
747
+ export declare function resolveSessionAcrossFleet(query: string, mode: ViewMode, hosts?: string[], deps?: FleetResolveDeps): Promise<FleetResolveResult>;
672
748
  /** Register the `agents sessions` command with all its options and help text. */
673
749
  export declare function registerSessionsCommands(program: Command): void;
674
750
  export {};