@phnx-labs/agents-cli 1.21.0 → 1.21.2
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.
- package/CHANGELOG.md +198 -0
- package/README.md +2 -1
- package/dist/bin/agents +0 -0
- package/dist/commands/doctor.js +5 -2
- package/dist/commands/feed.js +63 -40
- package/dist/commands/hooks.js +9 -45
- package/dist/commands/menubar.js +24 -24
- package/dist/commands/message.js +23 -3
- package/dist/commands/monitors.js +8 -6
- package/dist/commands/perf.d.ts +13 -0
- package/dist/commands/perf.js +80 -23
- package/dist/commands/projects.d.ts +11 -0
- package/dist/commands/projects.js +153 -21
- package/dist/commands/routines.js +46 -1
- package/dist/commands/ssh.js +69 -0
- package/dist/commands/trends.d.ts +2 -0
- package/dist/commands/trends.js +158 -0
- package/dist/commands/usage.d.ts +4 -4
- package/dist/commands/view.d.ts +6 -0
- package/dist/commands/view.js +90 -45
- package/dist/index.js +14 -1
- package/dist/lib/activity.d.ts +6 -0
- package/dist/lib/activity.js +3 -0
- package/dist/lib/agents.js +2 -2
- package/dist/lib/analytics/dashboard.d.ts +11 -0
- package/dist/lib/analytics/dashboard.js +31 -0
- package/dist/lib/analytics/recipes.d.ts +32 -0
- package/dist/lib/analytics/recipes.js +316 -0
- package/dist/lib/analytics/usage-db.d.ts +84 -0
- package/dist/lib/analytics/usage-db.js +301 -0
- package/dist/lib/browser/service.js +18 -0
- package/dist/lib/channels/providers/openclaw-telegram.js +1 -1
- package/dist/lib/channels/resolve.d.ts +18 -1
- package/dist/lib/channels/resolve.js +15 -5
- package/dist/lib/cli-resources.d.ts +20 -0
- package/dist/lib/cli-resources.js +48 -1
- package/dist/lib/daemon.js +51 -14
- package/dist/lib/devices/health-report.d.ts +5 -0
- package/dist/lib/devices/health-report.js +3 -0
- package/dist/lib/feed-broadcast.d.ts +93 -12
- package/dist/lib/feed-broadcast.js +235 -30
- package/dist/lib/feed-post.d.ts +16 -2
- package/dist/lib/feed-post.js +35 -7
- package/dist/lib/feed.js +1 -1
- package/dist/lib/fleet-cache.d.ts +37 -0
- package/dist/lib/fleet-cache.js +40 -0
- package/dist/lib/fleet-status.d.ts +53 -0
- package/dist/lib/fleet-status.js +120 -0
- package/dist/lib/friction-heuristics.d.ts +32 -0
- package/dist/lib/friction-heuristics.js +47 -0
- package/dist/lib/hooks/cache.js +28 -6
- package/dist/lib/hooks/profile.d.ts +8 -0
- package/dist/lib/hooks/profile.js +14 -4
- package/dist/lib/hooks.d.ts +16 -1
- package/dist/lib/hooks.js +133 -18
- package/dist/lib/linear-cache.d.ts +63 -0
- package/dist/lib/linear-cache.js +146 -0
- package/dist/lib/linear-project-counts.d.ts +35 -5
- package/dist/lib/linear-project-counts.js +61 -16
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/Info.plist +3 -1
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.d.ts +7 -0
- package/dist/lib/menubar/install-menubar.js +36 -6
- package/dist/lib/monitors/config.d.ts +1 -1
- package/dist/lib/monitors/dispatch.d.ts +6 -2
- package/dist/lib/monitors/dispatch.js +10 -15
- package/dist/lib/notify.d.ts +42 -6
- package/dist/lib/notify.js +41 -32
- package/dist/lib/perf/db.d.ts +6 -1
- package/dist/lib/perf/db.js +35 -5
- package/dist/lib/perf/types.d.ts +10 -0
- package/dist/lib/project-doctor.d.ts +36 -0
- package/dist/lib/project-doctor.js +45 -0
- package/dist/lib/project-import.d.ts +11 -1
- package/dist/lib/project-import.js +17 -3
- package/dist/lib/project-status.d.ts +25 -5
- package/dist/lib/project-status.js +48 -6
- package/dist/lib/rotate.d.ts +27 -0
- package/dist/lib/rotate.js +44 -17
- package/dist/lib/routines.d.ts +16 -0
- package/dist/lib/routines.js +39 -0
- package/dist/lib/runner.js +34 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/usage-db.d.ts +3 -63
- package/dist/lib/secrets/usage-db.js +46 -186
- package/dist/lib/session/db.d.ts +2 -1
- package/dist/lib/session/db.js +14 -3
- package/dist/lib/session/discover.d.ts +3 -0
- package/dist/lib/session/discover.js +8 -0
- package/dist/lib/session/types.d.ts +1 -0
- package/dist/lib/startup/command-registry.d.ts +1 -0
- package/dist/lib/startup/command-registry.js +2 -0
- package/dist/lib/state.d.ts +31 -3
- package/dist/lib/state.js +53 -10
- package/dist/lib/types.d.ts +14 -4
- package/dist/lib/usage-refresh.d.ts +106 -0
- package/dist/lib/usage-refresh.js +238 -0
- package/dist/lib/usage.d.ts +152 -17
- package/dist/lib/usage.js +393 -79
- package/package.json +1 -1
package/dist/lib/usage.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ export declare function usageUnreachableError(agent: string, cause?: unknown): s
|
|
|
49
49
|
* fresh" (never force a refresh on a token with no known expiry).
|
|
50
50
|
*/
|
|
51
51
|
export declare function claudeAccessTokenNeedsRefresh(expiresAt: number | null | undefined, nowMs?: number): boolean;
|
|
52
|
+
export declare function setClaudeUsageCachePathForTest(cachePath: string | null): string | null;
|
|
52
53
|
/** Discriminator for usage window types. */
|
|
53
54
|
export type UsageWindowKey = 'session' | 'week' | 'sonnet_week' | 'month';
|
|
54
55
|
/** A single rate-limit window with utilization percentage and reset time. */
|
|
@@ -155,10 +156,37 @@ export declare function buildCanonicalUsageContext(inputs: UsageIdentityInput[])
|
|
|
155
156
|
* Claude account with no data) versus simply not applicable (OpenCode).
|
|
156
157
|
*/
|
|
157
158
|
export declare function agentReportsUsage(agentId: AgentId): boolean;
|
|
158
|
-
/**
|
|
159
|
+
/**
|
|
160
|
+
* Whether an agent's usage source makes a live NETWORK call (Claude/Kimi/Droid/
|
|
161
|
+
* Cursor/Antigravity) versus reading local session logs (Codex/Grok). Only the
|
|
162
|
+
* networked ones go through the on-disk cache, and only they need the daemon's
|
|
163
|
+
* background refresher to keep that cache warm for the routing hot path.
|
|
164
|
+
*/
|
|
165
|
+
export declare function agentUsesNetworkUsage(agentId: AgentId): boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Concurrent live usage fetches for a single `agents view` / rotation pass.
|
|
168
|
+
* High enough to finish a multi-account refresh in one round-trip window; low
|
|
169
|
+
* enough that a cold cache of 10+ accounts cannot open 10+ HTTP calls at once
|
|
170
|
+
* (and cannot stack behind delayed responses until the process is pegged).
|
|
171
|
+
*/
|
|
172
|
+
export declare const USAGE_FETCH_CONCURRENCY = 3;
|
|
173
|
+
/**
|
|
174
|
+
* How long a cached snapshot is treated as fresh enough that we skip the network
|
|
175
|
+
* entirely. Five minutes balances "still accurate enough to glance at" against
|
|
176
|
+
* "don't re-hit every account on every `agents view` in a tight loop". Was 2
|
|
177
|
+
* minutes; that re-fired too often when delayed responses stacked.
|
|
178
|
+
*/
|
|
179
|
+
export declare const USAGE_CACHE_FRESH_MS: number;
|
|
180
|
+
/**
|
|
181
|
+
* Unified entry for every multi-account usage lookup (`agents view`, rotation,
|
|
182
|
+
* JSON export). Deduplicates by usage identity, then fans out through the
|
|
183
|
+
* shared SWR + timeout path with a hard concurrency cap so delayed calls
|
|
184
|
+
* cannot pile up.
|
|
185
|
+
*/
|
|
159
186
|
export declare function getUsageInfoByIdentity(inputs: UsageIdentityInput[], opts?: {
|
|
160
187
|
forceRefresh?: boolean;
|
|
161
188
|
maxAgeMs?: number;
|
|
189
|
+
readOnly?: boolean;
|
|
162
190
|
}): Promise<{
|
|
163
191
|
canonicalByUsageKey: Map<string, AccountInfo>;
|
|
164
192
|
usageByKey: Map<string, UsageInfo>;
|
|
@@ -174,24 +202,46 @@ export declare function swrWindowMsFor(maxAgeMs?: number): number;
|
|
|
174
202
|
/**
|
|
175
203
|
* Fetch usage for a single identity using stale-while-revalidate.
|
|
176
204
|
*
|
|
177
|
-
* - Cache fresh (<
|
|
178
|
-
* - Cache stale but < 24h: return cached snapshot instantly,
|
|
179
|
-
*
|
|
205
|
+
* - Cache fresh (< 5 min): return cached snapshot, NO network.
|
|
206
|
+
* - Cache stale but < 24h: return cached snapshot instantly, enqueue a
|
|
207
|
+
* concurrency-capped background refresh.
|
|
208
|
+
* - Cache too stale or absent: block on live fetch (shared in-flight promise),
|
|
209
|
+
* fall back to cache on error.
|
|
180
210
|
*
|
|
181
|
-
* This keeps `agents run`
|
|
182
|
-
* invocation after a cold install or 24h gap still blocks once to seed
|
|
183
|
-
* cache; every run after that returns instantly while the cache silently
|
|
184
|
-
* refreshes in the background
|
|
211
|
+
* This keeps `agents run` / `agents view` off the network on the hot path. The
|
|
212
|
+
* first invocation after a cold install or 24h gap still blocks once to seed
|
|
213
|
+
* the cache; every run after that returns instantly while the cache silently
|
|
214
|
+
* refreshes in the background — never more than {@link USAGE_BG_REFRESH_CONCURRENCY}
|
|
215
|
+
* at a time.
|
|
185
216
|
*/
|
|
186
217
|
export declare function getUsageInfoForIdentity(input: UsageIdentityInput, opts?: {
|
|
187
218
|
forceRefresh?: boolean;
|
|
188
219
|
maxAgeMs?: number;
|
|
220
|
+
readOnly?: boolean;
|
|
189
221
|
}): Promise<UsageInfo>;
|
|
190
|
-
/**
|
|
191
|
-
|
|
222
|
+
/**
|
|
223
|
+
* Pick which usage windows to render in a compact one-line summary.
|
|
224
|
+
*
|
|
225
|
+
* Overview rows (`agents view` all agents) must stay narrow enough that one
|
|
226
|
+
* multi-window agent (Antigravity's four model quotas, Droid's three buckets)
|
|
227
|
+
* does not force every other row to pad to ~200 columns and wrap. Prefer the
|
|
228
|
+
* canonical session + week windows when present; otherwise take the highest
|
|
229
|
+
* utilization remaining. Returns the full set when `maxWindows` is unset.
|
|
230
|
+
*/
|
|
231
|
+
export declare function pickCompactUsageWindows(windows: UsageWindow[], maxWindows?: number): UsageWindow[];
|
|
232
|
+
/** Options for {@link formatUsageSummary}. */
|
|
233
|
+
export interface FormatUsageSummaryOpts {
|
|
192
234
|
unavailable?: boolean;
|
|
193
235
|
unverified?: boolean;
|
|
194
|
-
|
|
236
|
+
/**
|
|
237
|
+
* Cap how many usage windows render on one line. Overview (`agents view`
|
|
238
|
+
* with no agent filter) passes 2 so multi-window agents cannot blow out
|
|
239
|
+
* column width; single-agent and detail views leave this unset.
|
|
240
|
+
*/
|
|
241
|
+
maxWindows?: number;
|
|
242
|
+
}
|
|
243
|
+
/** Format a one-line usage summary with compact bars for inline display. */
|
|
244
|
+
export declare function formatUsageSummary(plan: string | null, snapshot: UsageSnapshot | null, planWidth?: number, opts?: FormatUsageSummaryOpts): string;
|
|
195
245
|
/**
|
|
196
246
|
* Derive an account's real throttle state from its live usage windows — the
|
|
197
247
|
* single signal both the `agents view` badge and run-rotation eligibility share
|
|
@@ -212,6 +262,39 @@ export declare function formatUsageSummary(plan: string | null, snapshot: UsageS
|
|
|
212
262
|
* one model, not the account, so it shouldn't flip the whole row to throttled.
|
|
213
263
|
*/
|
|
214
264
|
export declare function deriveUsageStatusFromSnapshot(snapshot: UsageSnapshot | null | undefined): 'available' | 'rate_limited' | null;
|
|
265
|
+
/** A prior sample of one window's utilization, for burn-rate projection. */
|
|
266
|
+
export interface UsagePriorSample {
|
|
267
|
+
/** Epoch ms the prior snapshot was captured. */
|
|
268
|
+
capturedAt: number;
|
|
269
|
+
/** The session window's `usedPercent` in that prior snapshot. */
|
|
270
|
+
usedPercent: number;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* An account's throttle state PLUS how long until it caps, projected from the
|
|
274
|
+
* burn rate on its 5-hour `session` window — the window that throttles the next
|
|
275
|
+
* request soonest. `deriveUsageStatusFromSnapshot` answers only "maxed right
|
|
276
|
+
* now (100%)?"; this answers "and how close is it getting?", so routing can
|
|
277
|
+
* deprioritize an account burning toward its cap before it actually hits it,
|
|
278
|
+
* instead of treating 85%-and-climbing the same as 85%-and-idle.
|
|
279
|
+
*
|
|
280
|
+
* `minutesToLimit`:
|
|
281
|
+
* - `0` — already rate-limited (a blocking window at 100%).
|
|
282
|
+
* - `n > 0` — projected minutes until the session window reaches 100%, from
|
|
283
|
+
* `(100 - used) / burnRatePerMinute`, where the burn rate is
|
|
284
|
+
* measured between `prev` and this snapshot.
|
|
285
|
+
* - `null` — unknown: no snapshot, no session window, no prior sample, or
|
|
286
|
+
* usage flat/falling since `prev` (a reset or an idle account is
|
|
287
|
+
* not "projected to cap", so it is NOT deprioritized).
|
|
288
|
+
*
|
|
289
|
+
* Pure: the daemon's refresher supplies `prev` from the last snapshot it stored
|
|
290
|
+
* (`usage-refresh.ts`); the routing hot path reads the daemon-computed result
|
|
291
|
+
* from the headroom cache rather than recomputing (it has no `prev`).
|
|
292
|
+
*/
|
|
293
|
+
export interface UsageHeadroom {
|
|
294
|
+
status: 'available' | 'rate_limited' | null;
|
|
295
|
+
minutesToLimit: number | null;
|
|
296
|
+
}
|
|
297
|
+
export declare function deriveUsageHeadroom(snapshot: UsageSnapshot | null | undefined, prev?: UsagePriorSample | null): UsageHeadroom;
|
|
215
298
|
/**
|
|
216
299
|
* Compact colored badge for the account's overall usage status. Renders only
|
|
217
300
|
* when the account is throttled — `available` and `null` return ''.
|
|
@@ -433,13 +516,65 @@ export interface CursorUsageResponse {
|
|
|
433
516
|
* bar to draw here and return no windows rather than a misleading empty gauge.
|
|
434
517
|
*/
|
|
435
518
|
export declare function normalizeCursorUsage(data: CursorUsageResponse): UsageWindow[];
|
|
519
|
+
/** Per-window plan usage percentages Cursor's dashboard breaks usage into (Auto+Composer / API / Total). */
|
|
520
|
+
interface CursorPlanUsage {
|
|
521
|
+
autoPercentUsed?: number | null;
|
|
522
|
+
apiPercentUsed?: number | null;
|
|
523
|
+
totalPercentUsed?: number | null;
|
|
524
|
+
}
|
|
525
|
+
/** Response shape from Cursor's dashboard current-period-usage endpoint (subset we render). */
|
|
526
|
+
export interface CursorPeriodUsageResponse {
|
|
527
|
+
planUsage?: CursorPlanUsage | null;
|
|
528
|
+
/** ISO timestamp, or a unix-ms string, marking the end of the current billing cycle. */
|
|
529
|
+
billingCycleEnd?: string | number | null;
|
|
530
|
+
}
|
|
531
|
+
/** Response shape from Cursor's usage-summary endpoint (subset we render). */
|
|
532
|
+
export interface CursorUsageSummaryResponse {
|
|
533
|
+
/** True on a plan with no consumption cap; only tiered self-serve plans populate the percent fields. */
|
|
534
|
+
isUnlimited?: boolean | null;
|
|
535
|
+
individualUsage?: {
|
|
536
|
+
plan?: CursorPlanUsage | null;
|
|
537
|
+
} | null;
|
|
538
|
+
billingCycleEnd?: string | number | null;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Normalize Cursor's dashboard `get-current-period-usage` payload — the
|
|
542
|
+
* primary usage source, giving the same Auto+Composer / API / Total breakdown
|
|
543
|
+
* the web dashboard shows.
|
|
544
|
+
*/
|
|
545
|
+
export declare function normalizeCursorPeriodUsage(data: CursorPeriodUsageResponse): UsageWindow[];
|
|
546
|
+
/**
|
|
547
|
+
* Normalize Cursor's `usage-summary` fallback payload — the same Auto/API/Total
|
|
548
|
+
* breakdown nested under `individualUsage.plan`, used when the primary
|
|
549
|
+
* dashboard endpoint returns no usable `planUsage` (seen on some
|
|
550
|
+
* enterprise/team accounts). An unlimited plan (`isUnlimited: true`) with no
|
|
551
|
+
* usable percent has nothing to draw and returns no windows, rather than a
|
|
552
|
+
* misleading empty gauge.
|
|
553
|
+
*/
|
|
554
|
+
export declare function normalizeCursorUsageSummary(data: CursorUsageSummaryResponse): UsageWindow[];
|
|
436
555
|
/**
|
|
437
|
-
* Fetch Cursor usage
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
556
|
+
* Fetch Cursor usage. Cursor authenticates every one of these requests with a
|
|
557
|
+
* `WorkosCursorSessionToken` cookie of the form `<oauth-subject>::<access-token>`
|
|
558
|
+
* (the same pair the web dashboard sends), not a bearer header, so all three
|
|
559
|
+
* sources below share one resolved cookie.
|
|
560
|
+
*
|
|
561
|
+
* Three sources, tried in order, because no single endpoint carries usable data
|
|
562
|
+
* for every plan shape:
|
|
563
|
+
*
|
|
564
|
+
* 1. `get-current-period-usage` — the primary source, and the richest: the
|
|
565
|
+
* Auto+Composer / API / Total percent breakdown the dashboard itself shows.
|
|
566
|
+
* 2. `usage-summary` — some enterprise/team accounts return no usable
|
|
567
|
+
* `planUsage` from (1); this nests the same three percentages under
|
|
568
|
+
* `individualUsage.plan` instead.
|
|
569
|
+
* 3. The legacy `/api/usage` request-cap endpoint — the original source,
|
|
570
|
+
* kept as the final fallback for free/legacy plans that predate the
|
|
571
|
+
* percent-based breakdown above and only ever exposed a monthly request cap.
|
|
572
|
+
*
|
|
573
|
+
* The first source to yield a non-empty window list wins; a source that errors
|
|
574
|
+
* or returns no usable numbers falls through to the next rather than surfacing
|
|
575
|
+
* an error — only the last resort's own response/error is surfaced when every
|
|
576
|
+
* source comes up empty, so a plan enrolled in exactly one billing model still
|
|
577
|
+
* renders instead of reporting three swallowed failures.
|
|
443
578
|
*/
|
|
444
579
|
declare function getCursorUsageInfo(options?: UsageOptions): Promise<UsageInfo>;
|
|
445
580
|
/** The OAuth token `agy` stores (inside `{ token: … }`) in the OS keyring or file. */
|