fleetlens 0.16.1 → 0.16.3

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 (70) hide show
  1. package/app/apps/web/.next/BUILD_ID +1 -1
  2. package/app/apps/web/.next/build-manifest.json +3 -3
  3. package/app/apps/web/.next/prerender-manifest.json +3 -3
  4. package/app/apps/web/.next/server/app/_global-error.html +1 -1
  5. package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
  6. package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/app/apps/web/.next/server/app/agent/page_client-reference-manifest.js +1 -1
  13. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  14. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  15. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  16. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  17. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  18. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  19. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  20. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  21. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  22. package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
  23. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  24. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  25. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  26. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  27. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  28. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  29. package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
  30. package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
  31. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  32. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02faosk._.js +3 -3
  33. package/app/apps/web/.next/server/chunks/[root-of-the-server]__09cgmam._.js +2 -2
  34. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0tk8p3d._.js +2 -2
  35. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0u6pamj._.js +2 -2
  36. package/app/apps/web/.next/server/chunks/[root-of-the-server]__12jomao._.js +2 -2
  37. package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0sr4wr_.js +1 -1
  38. package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
  39. package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
  40. package/app/apps/web/.next/server/chunks/ssr/_0k8yioi._.js +1 -1
  41. package/app/apps/web/.next/server/chunks/ssr/apps_web_0epqfet._.js +1 -1
  42. package/app/apps/web/.next/server/chunks/ssr/apps_web_app_sessions_[id]_session-view_tsx_0-9t5~.._.js +1 -1
  43. package/app/apps/web/.next/server/chunks/ssr/apps_web_app_sessions_sessions-grid_tsx_0bri5x.._.js +1 -1
  44. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
  45. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
  46. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
  47. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  48. package/app/apps/web/.next/server/middleware-manifest.json +5 -5
  49. package/app/apps/web/.next/server/pages/500.html +1 -1
  50. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  51. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  52. package/app/apps/web/.next/static/chunks/{07bzlfv97o1ig.js → 0p5ee8wje3zi~.js} +1 -1
  53. package/app/apps/web/.next/static/chunks/0pt-1~k9ei92l.js +14 -0
  54. package/app/apps/web/.next/static/chunks/{0awkd5df28gvj.js → 0~uugvb4izjd2.js} +1 -1
  55. package/app/apps/web/app/sessions/[id]/session-view.tsx +6 -2
  56. package/app/apps/web/app/sessions/sessions-grid.tsx +5 -1
  57. package/app/apps/web/app/usage/page.tsx +27 -1
  58. package/app/apps/web/lib/agent/run.ts +24 -5
  59. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  60. package/app/apps/web/package.json +1 -1
  61. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  62. package/dist/daemon-worker.js +182 -34
  63. package/dist/index.js +187 -41
  64. package/menubar/FleetlensMenubar.app/Contents/Info.plist +2 -2
  65. package/menubar/FleetlensMenubar.app/Contents/MacOS/FleetlensMenubar +0 -0
  66. package/package.json +1 -1
  67. package/app/apps/web/.next/static/chunks/0at6brbse8wn2.js +0 -14
  68. /package/app/apps/web/.next/static/{d1mwRtSMG-R7wb8o9KxM3 → DoQvoHgeMQRMU3tniT_DK}/_buildManifest.js +0 -0
  69. /package/app/apps/web/.next/static/{d1mwRtSMG-R7wb8o9KxM3 → DoQvoHgeMQRMU3tniT_DK}/_clientMiddlewareManifest.js +0 -0
  70. /package/app/apps/web/.next/static/{d1mwRtSMG-R7wb8o9KxM3 → DoQvoHgeMQRMU3tniT_DK}/_ssgManifest.js +0 -0
@@ -2785,6 +2785,11 @@ function parseRollout(file, lines) {
2785
2785
  let lastUserPreview;
2786
2786
  let lastAgentPreview;
2787
2787
  const tsMs = [];
2788
+ let threadSource;
2789
+ let rootSessionId;
2790
+ let parentThreadId;
2791
+ let agentNickname;
2792
+ let agentPath;
2788
2793
  let idx = 0;
2789
2794
  for (const line of lines) {
2790
2795
  if (typeof line !== "object" || line === null)
@@ -2805,6 +2810,16 @@ function parseRollout(file, lines) {
2805
2810
  if (type === "session_meta") {
2806
2811
  if (typeof payload.cwd === "string")
2807
2812
  cwd = payload.cwd;
2813
+ if (threadSource === void 0 && typeof payload.thread_source === "string")
2814
+ threadSource = payload.thread_source;
2815
+ if (rootSessionId === void 0 && typeof payload.session_id === "string")
2816
+ rootSessionId = payload.session_id;
2817
+ if (parentThreadId === void 0 && typeof payload.parent_thread_id === "string")
2818
+ parentThreadId = payload.parent_thread_id;
2819
+ if (agentNickname === void 0 && typeof payload.agent_nickname === "string")
2820
+ agentNickname = payload.agent_nickname;
2821
+ if (agentPath === void 0 && typeof payload.agent_path === "string")
2822
+ agentPath = payload.agent_path;
2808
2823
  continue;
2809
2824
  }
2810
2825
  if (type === "turn_context") {
@@ -3008,7 +3023,7 @@ function parseRollout(file, lines) {
3008
3023
  airTimeMs,
3009
3024
  activeSegments
3010
3025
  };
3011
- return { meta, events };
3026
+ return { meta, events, threadSource, rootSessionId, parentThreadId, agentNickname, agentPath };
3012
3027
  }
3013
3028
  function numberOf(v) {
3014
3029
  return typeof v === "number" && Number.isFinite(v) ? v : void 0;
@@ -3046,28 +3061,112 @@ function clearCodexCaches() {
3046
3061
  metaCache2.clear();
3047
3062
  detailCache2.clear();
3048
3063
  }
3049
- async function listCodexSessions(opts = {}) {
3050
- const root = opts.root ?? DEFAULT_CODEX_ROOT;
3064
+ async function scanAllCodex(root) {
3051
3065
  const files = await listRolloutFiles(root);
3052
3066
  const out = [];
3053
3067
  for (const file of files) {
3054
3068
  const cached = metaCache2.get(file.filePath);
3055
3069
  if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
3056
- out.push(cached.meta);
3070
+ out.push({
3071
+ file,
3072
+ meta: cached.meta,
3073
+ threadSource: cached.threadSource,
3074
+ rootSessionId: cached.rootSessionId,
3075
+ parentThreadId: cached.parentThreadId,
3076
+ agentNickname: cached.agentNickname,
3077
+ agentPath: cached.agentPath
3078
+ });
3057
3079
  continue;
3058
3080
  }
3059
3081
  try {
3060
3082
  const lines = await readJsonl(file.filePath);
3061
- const { meta } = parseRollout(file, lines);
3083
+ const parsed = parseRollout(file, lines);
3062
3084
  metaCache2.set(file.filePath, {
3063
- meta,
3085
+ meta: parsed.meta,
3064
3086
  mtimeMs: file.mtimeMs,
3065
- sizeBytes: file.sizeBytes
3087
+ sizeBytes: file.sizeBytes,
3088
+ threadSource: parsed.threadSource,
3089
+ rootSessionId: parsed.rootSessionId,
3090
+ parentThreadId: parsed.parentThreadId,
3091
+ agentNickname: parsed.agentNickname,
3092
+ agentPath: parsed.agentPath
3093
+ });
3094
+ out.push({
3095
+ file,
3096
+ meta: parsed.meta,
3097
+ threadSource: parsed.threadSource,
3098
+ rootSessionId: parsed.rootSessionId,
3099
+ parentThreadId: parsed.parentThreadId,
3100
+ agentNickname: parsed.agentNickname,
3101
+ agentPath: parsed.agentPath
3066
3102
  });
3067
- out.push(meta);
3068
3103
  } catch {
3069
3104
  }
3070
3105
  }
3106
+ return out;
3107
+ }
3108
+ function buildSubagentRun(entry, parentStartMs) {
3109
+ const meta = entry.meta;
3110
+ const startMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
3111
+ const endMs = meta.lastTimestamp ? Date.parse(meta.lastTimestamp) : void 0;
3112
+ const startOk = startMs !== void 0 && Number.isFinite(startMs) ? startMs : void 0;
3113
+ const endOk = endMs !== void 0 && Number.isFinite(endMs) ? endMs : void 0;
3114
+ return {
3115
+ agentId: meta.id,
3116
+ agentType: entry.agentNickname ?? entry.agentPath ?? "subagent",
3117
+ description: entry.agentPath ?? entry.agentNickname ?? meta.id,
3118
+ startMs: startOk,
3119
+ endMs: endOk,
3120
+ durationMs: meta.durationMs,
3121
+ startTOffsetMs: parentStartMs !== void 0 && startOk !== void 0 ? Math.max(0, startOk - parentStartMs) : void 0,
3122
+ endTOffsetMs: parentStartMs !== void 0 && endOk !== void 0 ? Math.max(0, endOk - parentStartMs) : void 0,
3123
+ eventCount: meta.eventCount,
3124
+ totalUsage: meta.totalUsage,
3125
+ model: meta.model,
3126
+ toolCallCount: meta.toolCallCount,
3127
+ finalPreview: meta.lastAgentPreview
3128
+ };
3129
+ }
3130
+ async function listCodexSessions(opts = {}) {
3131
+ const root = opts.root ?? DEFAULT_CODEX_ROOT;
3132
+ const all = await scanAllCodex(root);
3133
+ const subagentsByRoot = /* @__PURE__ */ new Map();
3134
+ for (const entry of all) {
3135
+ if (entry.threadSource !== "subagent" || !entry.rootSessionId)
3136
+ continue;
3137
+ const list = subagentsByRoot.get(entry.rootSessionId);
3138
+ if (list)
3139
+ list.push(entry);
3140
+ else
3141
+ subagentsByRoot.set(entry.rootSessionId, [entry]);
3142
+ }
3143
+ const out = [];
3144
+ for (const entry of all) {
3145
+ if (entry.threadSource === "subagent")
3146
+ continue;
3147
+ const children = subagentsByRoot.get(entry.meta.id);
3148
+ if (!children || children.length === 0) {
3149
+ out.push(entry.meta);
3150
+ continue;
3151
+ }
3152
+ const merged = {
3153
+ ...entry.meta,
3154
+ spawnedAgentCount: children.length,
3155
+ totalUsage: {
3156
+ input: entry.meta.totalUsage.input + children.reduce((s, c) => s + c.meta.totalUsage.input, 0),
3157
+ output: entry.meta.totalUsage.output + children.reduce((s, c) => s + c.meta.totalUsage.output, 0),
3158
+ cacheRead: entry.meta.totalUsage.cacheRead + children.reduce((s, c) => s + c.meta.totalUsage.cacheRead, 0),
3159
+ cacheWrite: entry.meta.totalUsage.cacheWrite + children.reduce((s, c) => s + c.meta.totalUsage.cacheWrite, 0)
3160
+ },
3161
+ toolCallCount: (entry.meta.toolCallCount ?? 0) + children.reduce((s, c) => s + (c.meta.toolCallCount ?? 0), 0)
3162
+ };
3163
+ for (const c of children) {
3164
+ if (c.meta.lastTimestamp && (!merged.lastTimestamp || c.meta.lastTimestamp > merged.lastTimestamp)) {
3165
+ merged.lastTimestamp = c.meta.lastTimestamp;
3166
+ }
3167
+ }
3168
+ out.push(merged);
3169
+ }
3071
3170
  out.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
3072
3171
  if (opts.limit !== void 0)
3073
3172
  return out.slice(0, opts.limit);
@@ -3075,17 +3174,41 @@ async function listCodexSessions(opts = {}) {
3075
3174
  }
3076
3175
  async function getCodexSession(id, opts = {}) {
3077
3176
  const root = opts.root ?? DEFAULT_CODEX_ROOT;
3078
- const files = await listRolloutFiles(root);
3079
- const file = files.find((f) => f.sessionId === id);
3080
- if (!file)
3081
- return null;
3177
+ const all = await scanAllCodex(root);
3178
+ const rootEntry = all.find((a) => a.meta.id === id && a.threadSource !== "subagent");
3179
+ if (!rootEntry) {
3180
+ const direct = all.find((a) => a.meta.id === id);
3181
+ if (!direct)
3182
+ return null;
3183
+ const cached2 = detailCache2.get(direct.file.filePath);
3184
+ if (cached2 && cached2.mtimeMs === direct.file.mtimeMs && cached2.sizeBytes === direct.file.sizeBytes) {
3185
+ return cached2.detail;
3186
+ }
3187
+ const lines2 = await readJsonl(direct.file.filePath);
3188
+ const { meta: meta2, events: events2 } = parseRollout(direct.file, lines2);
3189
+ const detail2 = { ...meta2, events: events2 };
3190
+ detailCache2.set(direct.file.filePath, {
3191
+ detail: detail2,
3192
+ mtimeMs: direct.file.mtimeMs,
3193
+ sizeBytes: direct.file.sizeBytes
3194
+ });
3195
+ return detail2;
3196
+ }
3197
+ const file = rootEntry.file;
3082
3198
  const cached = detailCache2.get(file.filePath);
3083
3199
  if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
3084
3200
  return cached.detail;
3085
3201
  }
3086
3202
  const lines = await readJsonl(file.filePath);
3087
3203
  const { meta, events } = parseRollout(file, lines);
3088
- const detail = { ...meta, events };
3204
+ const children = all.filter((a) => a.threadSource === "subagent" && a.rootSessionId === id);
3205
+ const parentStartMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
3206
+ const subagents = children.map((c) => buildSubagentRun(c, parentStartMs)).sort((a, b) => (a.startMs ?? 0) - (b.startMs ?? 0));
3207
+ const detail = {
3208
+ ...meta,
3209
+ events,
3210
+ ...subagents.length > 0 ? { subagents, spawnedAgentCount: subagents.length } : {}
3211
+ };
3089
3212
  detailCache2.set(file.filePath, {
3090
3213
  detail,
3091
3214
  mtimeMs: file.mtimeMs,
@@ -3096,6 +3219,15 @@ async function getCodexSession(id, opts = {}) {
3096
3219
  function hasUsableRateLimitWindows(primary, secondary) {
3097
3220
  return numberOf(primary?.used_percent) !== void 0 || numberOf(secondary?.used_percent) !== void 0;
3098
3221
  }
3222
+ function normalizeCodexWindow(raw, nowMs) {
3223
+ const usedPercent = numberOf(raw?.used_percent);
3224
+ const resetUnix = numberOf(raw?.resets_at);
3225
+ const expired = resetUnix !== void 0 && nowMs > resetUnix * 1e3;
3226
+ return {
3227
+ utilization: usedPercent === void 0 ? null : expired ? 0 : usedPercent,
3228
+ resets_at: resetUnix !== void 0 ? new Date(resetUnix * 1e3).toISOString() : null
3229
+ };
3230
+ }
3099
3231
  async function getLatestCodexUsage(opts = {}) {
3100
3232
  const root = opts.root ?? DEFAULT_CODEX_ROOT;
3101
3233
  const files = await listRolloutFiles(root);
@@ -3121,23 +3253,34 @@ async function getLatestCodexUsage(opts = {}) {
3121
3253
  const secondary = rl.secondary ?? null;
3122
3254
  if (!hasUsableRateLimitWindows(primary, secondary))
3123
3255
  continue;
3124
- const fivePct = numberOf(primary?.used_percent);
3125
- const sevenPct = numberOf(secondary?.used_percent);
3126
- const fiveResetUnix = numberOf(primary?.resets_at);
3127
- const sevenResetUnix = numberOf(secondary?.resets_at);
3128
3256
  const planType = typeof rl.plan_type === "string" ? rl.plan_type : null;
3129
3257
  const nowMs = Date.now();
3130
- const fiveExpired = fiveResetUnix !== void 0 && nowMs > fiveResetUnix * 1e3;
3131
- const sevenExpired = sevenResetUnix !== void 0 && nowMs > sevenResetUnix * 1e3;
3258
+ let fiveHour = null;
3259
+ let sevenDay = null;
3260
+ for (const candidate of [primary, secondary]) {
3261
+ if (!candidate)
3262
+ continue;
3263
+ const windowMinutes = numberOf(candidate.window_minutes);
3264
+ if (windowMinutes === FIVE_HOUR_WINDOW_MINUTES) {
3265
+ fiveHour = normalizeCodexWindow(candidate, nowMs);
3266
+ } else if (windowMinutes === SEVEN_DAY_WINDOW_MINUTES) {
3267
+ sevenDay = normalizeCodexWindow(candidate, nowMs);
3268
+ }
3269
+ }
3270
+ const unknownWindows = [primary, secondary].filter((candidate) => candidate !== null && numberOf(candidate.window_minutes) === void 0);
3271
+ if (!fiveHour && !sevenDay) {
3272
+ fiveHour = primary ? normalizeCodexWindow(primary, nowMs) : null;
3273
+ sevenDay = secondary ? normalizeCodexWindow(secondary, nowMs) : null;
3274
+ } else if (unknownWindows.length === 1) {
3275
+ const inferred = normalizeCodexWindow(unknownWindows[0], nowMs);
3276
+ if (!fiveHour)
3277
+ fiveHour = inferred;
3278
+ else if (!sevenDay)
3279
+ sevenDay = inferred;
3280
+ }
3132
3281
  return {
3133
- five_hour: {
3134
- utilization: fiveExpired ? 0 : fivePct ?? null,
3135
- resets_at: fiveResetUnix !== void 0 ? new Date(fiveResetUnix * 1e3).toISOString() : null
3136
- },
3137
- seven_day: {
3138
- utilization: sevenExpired ? 0 : sevenPct ?? null,
3139
- resets_at: sevenResetUnix !== void 0 ? new Date(sevenResetUnix * 1e3).toISOString() : null
3140
- },
3282
+ five_hour: fiveHour ?? { utilization: null, resets_at: null },
3283
+ seven_day: sevenDay ?? { utilization: null, resets_at: null },
3141
3284
  plan_type: planType,
3142
3285
  source_path: file.filePath
3143
3286
  };
@@ -3151,7 +3294,7 @@ function codexSessionLocalDay(meta) {
3151
3294
  const ms = Date.parse(meta.firstTimestamp);
3152
3295
  return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
3153
3296
  }
3154
- var DEFAULT_CODEX_ROOT, ROLLOUT_RE, IDLE_GAP_MS, metaCache2, detailCache2;
3297
+ var DEFAULT_CODEX_ROOT, ROLLOUT_RE, IDLE_GAP_MS, metaCache2, detailCache2, FIVE_HOUR_WINDOW_MINUTES, SEVEN_DAY_WINDOW_MINUTES;
3155
3298
  var init_codex = __esm({
3156
3299
  "../parser/dist/codex.js"() {
3157
3300
  "use strict";
@@ -3163,6 +3306,8 @@ var init_codex = __esm({
3163
3306
  IDLE_GAP_MS = 3 * 60 * 1e3;
3164
3307
  metaCache2 = /* @__PURE__ */ new Map();
3165
3308
  detailCache2 = /* @__PURE__ */ new Map();
3309
+ FIVE_HOUR_WINDOW_MINUTES = 5 * 60;
3310
+ SEVEN_DAY_WINDOW_MINUTES = 7 * 24 * 60;
3166
3311
  }
3167
3312
  });
3168
3313
 
@@ -5508,7 +5653,8 @@ var init_fs = __esm({
5508
5653
  captured_at: (/* @__PURE__ */ new Date()).toISOString(),
5509
5654
  agent: "codex",
5510
5655
  five_hour: w.five_hour,
5511
- seven_day: w.seven_day
5656
+ seven_day: w.seven_day,
5657
+ plan_type: w.plan_type
5512
5658
  };
5513
5659
  }
5514
5660
  };
@@ -8043,7 +8189,7 @@ function buildIngestPayload(inputs) {
8043
8189
  return {
8044
8190
  ingestId: randomUUID(),
8045
8191
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
8046
- cliVersion: "0.16.1",
8192
+ cliVersion: "0.16.3",
8047
8193
  ...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
8048
8194
  ...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
8049
8195
  ...richRollup ? { richRollup } : {},
@@ -16977,14 +17123,14 @@ async function getUpdateAvailability() {
16977
17123
  if (isDevMode()) return null;
16978
17124
  const latest = await fetchLatestVersion();
16979
17125
  if (latest === null) return {
16980
- current: "0.16.1",
17126
+ current: "0.16.3",
16981
17127
  latest: null,
16982
17128
  updateAvailable: false
16983
17129
  };
16984
17130
  return {
16985
- current: "0.16.1",
17131
+ current: "0.16.3",
16986
17132
  latest,
16987
- updateAvailable: shouldUpdate("0.16.1", latest)
17133
+ updateAvailable: shouldUpdate("0.16.3", latest)
16988
17134
  };
16989
17135
  }
16990
17136
 
@@ -17139,9 +17285,11 @@ async function tick() {
17139
17285
  extra_usage: null
17140
17286
  };
17141
17287
  appendSnapshot(USAGE_LOG3, snapshot);
17288
+ const fiveHour = snapshot.five_hour.utilization === null ? "\u2014" : `${snapshot.five_hour.utilization}%`;
17289
+ const sevenDay = snapshot.seven_day.utilization === null ? "\u2014" : `${snapshot.seven_day.utilization}%`;
17142
17290
  log2(
17143
17291
  "info",
17144
- `${source.kind} snapshot 5h=${snapshot.five_hour.utilization}% 7d=${snapshot.seven_day.utilization}%`
17292
+ `${source.kind} snapshot 5h=${fiveHour} 7d=${sevenDay}`
17145
17293
  );
17146
17294
  } catch (err) {
17147
17295
  log2("warn", `${source.kind} poll failed: ${err.message}`);