fleetlens 0.13.0 → 0.13.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/app/apps/web/.next/BUILD_ID +1 -1
- package/app/apps/web/.next/build-manifest.json +8 -8
- package/app/apps/web/.next/prerender-manifest.json +3 -3
- package/app/apps/web/.next/server/app/_global-error/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/_global-error.html +1 -1
- package/app/apps/web/.next/server/app/_global-error.rsc +7 -7
- package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_not-found/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/_not-found/page.js +1 -1
- package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js +1 -1
- package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js +1 -1
- package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js +1 -1
- package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/events/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/pdf/[key]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/team-config/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/workflow-agent/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/changelog/page.js +1 -1
- package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/day/[date]/page.js +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/day/page.js +1 -1
- package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/digest/[date]/page.js +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/digest/page.js +1 -1
- package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/insights/[key]/page.js +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/insights/page.js +3 -2
- package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/page.js +1 -1
- package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/parallelism/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/parallelism/page.js +1 -1
- package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/print/[key]/page.js +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/projects/[slug]/page.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/projects/page.js +1 -1
- package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/runs/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/runs/page.js +1 -1
- package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/sessions/[id]/page.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/sessions/page.js +1 -1
- package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/settings/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/settings/page.js +1 -1
- package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/team/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/team/page.js +1 -1
- package/app/apps/web/.next/server/app/team/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page/build-manifest.json +5 -5
- package/app/apps/web/.next/server/app/usage/page.js +1 -1
- package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0gril0u._.js +9 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0n79hpm._.js +9 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0~utv~v._.js +9 -0
- package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
- package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0exckd4._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0-1_njm._.js → [root-of-the-server]__0k1x-c9._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0lhwp-k._.js +8 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0n-ax-5._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0~.f_3z._.js +3 -3
- package/app/apps/web/.next/server/chunks/ssr/_0kajk31._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/_0s3n5mz._.js +8 -0
- package/app/apps/web/.next/server/chunks/ssr/_0xu2pvc._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/{_0jw2sm7._.js → _12mbgs5._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/apps_web_app_day_[date]_day-view_tsx_0wjoe1u._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_app_insights_page_tsx_071kwyw._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web_app_sessions_sessions-grid_tsx_0bri5x.._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0l6hsch._.js +6 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0cepfi8._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
- package/app/apps/web/.next/server/middleware-build-manifest.js +8 -8
- package/app/apps/web/.next/server/middleware-manifest.json +5 -5
- package/app/apps/web/.next/server/pages/500.html +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/app/apps/web/.next/static/chunks/02xxpexzk3rf-.js +1 -0
- package/app/apps/web/.next/static/chunks/{07lbm-sdh9c2j.js → 0389wb_f0j78j.js} +1 -1
- package/app/apps/web/.next/static/chunks/03gy1evbn94qu.js +6 -0
- package/app/apps/web/.next/static/chunks/03rd.3cc_t~yf.js +4 -0
- package/app/apps/web/.next/static/chunks/{0l4e3as18eexy.js → 0g223u9amib0q.js} +1 -1
- package/app/apps/web/.next/static/chunks/{0h3.-_s-k0mj3.js → 0i.hc~2bj0_3d.js} +1 -1
- package/app/apps/web/.next/static/chunks/0m7dd-2zd9vl2.js +4 -0
- package/app/apps/web/.next/static/chunks/0nqklmbs5s3ax.js +6 -0
- package/app/apps/web/.next/static/chunks/{073081qv4uyn8.js → 0p--hzrway8~3.js} +1 -1
- package/app/apps/web/.next/static/chunks/{0gblp_v.kiu-..js → 0qv-gw888_5nu.js} +1 -1
- package/app/apps/web/.next/static/chunks/{14bjditmmrn7l.js → 0tirv_vo6q8uc.js} +1 -1
- package/app/apps/web/.next/static/chunks/0uyctl-m8iydb.js +1 -0
- package/app/apps/web/.next/static/chunks/0~qdw1b2uz._5.js +10 -0
- package/app/apps/web/.next/static/chunks/{0n0n.0279ot6c.js → 14vx702c32kn6.js} +1 -1
- package/app/apps/web/.next/static/chunks/{turbopack-0lb9w090w5ezx.js → turbopack-0mxu3~9vk.brh.js} +1 -1
- package/app/apps/web/app/api/digest/_shared/digest-route-helpers.ts +178 -0
- package/app/apps/web/app/api/digest/day/[date]/route.ts +34 -128
- package/app/apps/web/app/api/digest/month/[yearMonth]/route.ts +36 -121
- package/app/apps/web/app/api/digest/week/[startDate]/route.ts +36 -123
- package/app/apps/web/app/insights/page.tsx +20 -5
- package/app/apps/web/app/parallelism/burst-detail-modal.tsx +637 -0
- package/app/apps/web/app/parallelism/concurrency-info-modal.tsx +228 -0
- package/app/apps/web/app/parallelism/gantt-chart-utils.ts +49 -0
- package/app/apps/web/app/parallelism/gantt-chart.tsx +24 -903
- package/app/apps/web/app/sessions/[id]/session-view/colors.ts +31 -0
- package/app/apps/web/app/sessions/[id]/session-view/debug-list.tsx +78 -0
- package/app/apps/web/app/sessions/[id]/session-view/drawer.tsx +414 -0
- package/app/apps/web/app/sessions/[id]/session-view/entry-day-strip.tsx +124 -0
- package/app/apps/web/app/sessions/[id]/session-view/header-stats.tsx +217 -0
- package/app/apps/web/app/sessions/[id]/session-view/helpers.ts +135 -0
- package/app/apps/web/app/sessions/[id]/session-view/minimap.tsx +1587 -0
- package/app/apps/web/app/sessions/[id]/session-view/subagent-drawer.tsx +339 -0
- package/app/apps/web/app/sessions/[id]/session-view/token-stats.tsx +111 -0
- package/app/apps/web/app/sessions/[id]/session-view/tooltip.tsx +63 -0
- package/app/apps/web/app/sessions/[id]/session-view/types.ts +46 -0
- package/app/apps/web/app/sessions/[id]/session-view/workflows-panel.tsx +944 -0
- package/app/apps/web/app/sessions/[id]/session-view/workflows-shared.tsx +104 -0
- package/app/apps/web/app/sessions/[id]/session-view.tsx +1513 -5018
- package/app/apps/web/app/sessions/[id]/team-tab/minimap-hover-card.tsx +201 -0
- package/app/apps/web/app/sessions/[id]/team-tab/minimap-idle-band.tsx +53 -0
- package/app/apps/web/app/sessions/[id]/team-tab/minimap-shared.ts +20 -0
- package/app/apps/web/app/sessions/[id]/team-tab/team-minimap.tsx +10 -265
- package/app/apps/web/app/sessions/sessions-grid.tsx +10 -10
- package/app/apps/web/components/digest-actions.tsx +103 -0
- package/app/apps/web/components/job-queue-widget.tsx +1 -1
- package/app/apps/web/components/month-digest-view.tsx +19 -64
- package/app/apps/web/components/searchable-select.tsx +215 -0
- package/app/apps/web/components/tail-mode.tsx +46 -9
- package/app/apps/web/components/week-digest-view.tsx +16 -71
- package/app/apps/web/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/lib/entries-index.ts +7 -8
- package/app/apps/web/lib/entries.ts +0 -9
- package/app/apps/web/lib/format.test.ts +221 -0
- package/app/apps/web/lib/format.ts +17 -0
- package/app/apps/web/lib/utilization-tone.test.ts +56 -0
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +35 -43
- package/dist/index.js +37 -49
- package/package.json +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__04j3tng._.js +0 -9
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0cnh3k4._.js +0 -9
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__132eosx._.js +0 -9
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__136-0me._.js +0 -8
- package/app/apps/web/.next/server/chunks/ssr/_0w.cv64._.js +0 -8
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_01d-iwx._.js +0 -6
- package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0-lmm4p._.js +0 -3
- package/app/apps/web/.next/static/chunks/05k84gif3ucxm.js +0 -6
- package/app/apps/web/.next/static/chunks/0nnjldasalwdu.js +0 -4
- package/app/apps/web/.next/static/chunks/0okg13phslr1..js +0 -4
- package/app/apps/web/.next/static/chunks/0pzt9vemtzct8.js +0 -10
- package/app/apps/web/.next/static/chunks/0qmh5da6gfm56.js +0 -1
- package/app/apps/web/.next/static/chunks/0rnay-a.-jr8-.js +0 -1
- package/app/apps/web/.next/static/chunks/0snv3-2ux2xvv.js +0 -6
- /package/app/apps/web/.next/static/{rbp9x3iPbzrz-wxS-DAU5 → bZs5UyzsYBqC6MFY5n-M_}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{rbp9x3iPbzrz-wxS-DAU5 → bZs5UyzsYBqC6MFY5n-M_}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{rbp9x3iPbzrz-wxS-DAU5 → bZs5UyzsYBqC6MFY5n-M_}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
|
|
5
|
+
export function ConcurrencyInfoModal({ onClose }: { onClose: () => void }) {
|
|
6
|
+
// Close on ESC.
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
const onKey = (e: KeyboardEvent) => {
|
|
9
|
+
if (e.key === "Escape") onClose();
|
|
10
|
+
};
|
|
11
|
+
window.addEventListener("keydown", onKey);
|
|
12
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
13
|
+
}, [onClose]);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div
|
|
17
|
+
role="dialog"
|
|
18
|
+
aria-modal="true"
|
|
19
|
+
aria-labelledby="concurrency-modal-title"
|
|
20
|
+
onClick={onClose}
|
|
21
|
+
style={{
|
|
22
|
+
position: "fixed",
|
|
23
|
+
inset: 0,
|
|
24
|
+
zIndex: 200,
|
|
25
|
+
background: "rgba(0, 0, 0, 0.5)",
|
|
26
|
+
backdropFilter: "blur(4px)",
|
|
27
|
+
WebkitBackdropFilter: "blur(4px)",
|
|
28
|
+
display: "flex",
|
|
29
|
+
alignItems: "center",
|
|
30
|
+
justifyContent: "center",
|
|
31
|
+
padding: 20,
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
<div
|
|
35
|
+
onClick={(e) => e.stopPropagation()}
|
|
36
|
+
style={{
|
|
37
|
+
background: "var(--af-surface-elevated)",
|
|
38
|
+
border: "1px solid var(--af-border-subtle)",
|
|
39
|
+
borderRadius: 12,
|
|
40
|
+
maxWidth: 560,
|
|
41
|
+
width: "100%",
|
|
42
|
+
maxHeight: "85vh",
|
|
43
|
+
overflow: "auto",
|
|
44
|
+
boxShadow: "0 16px 48px rgba(0, 0, 0, 0.3)",
|
|
45
|
+
}}
|
|
46
|
+
>
|
|
47
|
+
<div
|
|
48
|
+
style={{
|
|
49
|
+
display: "flex",
|
|
50
|
+
alignItems: "center",
|
|
51
|
+
justifyContent: "space-between",
|
|
52
|
+
padding: "18px 22px",
|
|
53
|
+
borderBottom: "1px solid var(--af-border-subtle)",
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
<h2
|
|
57
|
+
id="concurrency-modal-title"
|
|
58
|
+
style={{
|
|
59
|
+
margin: 0,
|
|
60
|
+
fontSize: 16,
|
|
61
|
+
fontWeight: 700,
|
|
62
|
+
letterSpacing: "-0.01em",
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
How concurrency is measured
|
|
66
|
+
</h2>
|
|
67
|
+
<button
|
|
68
|
+
type="button"
|
|
69
|
+
onClick={onClose}
|
|
70
|
+
aria-label="Close"
|
|
71
|
+
style={{
|
|
72
|
+
background: "transparent",
|
|
73
|
+
border: "none",
|
|
74
|
+
color: "var(--af-text-tertiary)",
|
|
75
|
+
fontSize: 22,
|
|
76
|
+
lineHeight: 1,
|
|
77
|
+
cursor: "pointer",
|
|
78
|
+
padding: 0,
|
|
79
|
+
width: 28,
|
|
80
|
+
height: 28,
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
×
|
|
84
|
+
</button>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<div
|
|
88
|
+
style={{
|
|
89
|
+
padding: "18px 22px",
|
|
90
|
+
fontSize: 13,
|
|
91
|
+
color: "var(--af-text-secondary)",
|
|
92
|
+
lineHeight: 1.55,
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
<p style={{ margin: "0 0 14px" }}>
|
|
96
|
+
A <strong style={{ color: "var(--af-text)" }}>concurrency burst</strong>{" "}
|
|
97
|
+
is a window of time when two or more Claude Code sessions were
|
|
98
|
+
actively working in parallel. The goal is to surface moments
|
|
99
|
+
when you were running a multi-agent fleet — not every accidental
|
|
100
|
+
tab overlap.
|
|
101
|
+
</p>
|
|
102
|
+
|
|
103
|
+
<h3
|
|
104
|
+
style={{
|
|
105
|
+
margin: "18px 0 8px",
|
|
106
|
+
fontSize: 12,
|
|
107
|
+
fontWeight: 700,
|
|
108
|
+
color: "var(--af-text)",
|
|
109
|
+
textTransform: "uppercase",
|
|
110
|
+
letterSpacing: "0.04em",
|
|
111
|
+
}}
|
|
112
|
+
>
|
|
113
|
+
1. What counts as "active"
|
|
114
|
+
</h3>
|
|
115
|
+
<p style={{ margin: "0 0 6px" }}>
|
|
116
|
+
Each session's events are split into{" "}
|
|
117
|
+
<strong style={{ color: "var(--af-text)" }}>active segments</strong> —
|
|
118
|
+
stretches of time where no gap between consecutive events exceeds{" "}
|
|
119
|
+
<strong style={{ color: "var(--af-text)" }}>3 minutes</strong>. Any longer
|
|
120
|
+
gap (walked away, laptop closed, thinking) splits the session
|
|
121
|
+
into separate segments.
|
|
122
|
+
</p>
|
|
123
|
+
<p style={{ margin: "0 0 6px", fontSize: 12, color: "var(--af-text-tertiary)" }}>
|
|
124
|
+
This is the same definition used for the "active time" metric on
|
|
125
|
+
the dashboard, so numbers stay consistent.
|
|
126
|
+
</p>
|
|
127
|
+
|
|
128
|
+
<h3
|
|
129
|
+
style={{
|
|
130
|
+
margin: "18px 0 8px",
|
|
131
|
+
fontSize: 12,
|
|
132
|
+
fontWeight: 700,
|
|
133
|
+
color: "var(--af-text)",
|
|
134
|
+
textTransform: "uppercase",
|
|
135
|
+
letterSpacing: "0.04em",
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
2. Detecting overlap
|
|
139
|
+
</h3>
|
|
140
|
+
<p style={{ margin: "0 0 6px" }}>
|
|
141
|
+
A sweep-line walks every segment start/end across all sessions.
|
|
142
|
+
Whenever the active count is ≥2, that stretch becomes a raw
|
|
143
|
+
overlap. The <strong style={{ color: "var(--af-text)" }}>peak</strong>{" "}
|
|
144
|
+
reported on each burst is the maximum active count reached
|
|
145
|
+
anywhere inside it.
|
|
146
|
+
</p>
|
|
147
|
+
|
|
148
|
+
<h3
|
|
149
|
+
style={{
|
|
150
|
+
margin: "18px 0 8px",
|
|
151
|
+
fontSize: 12,
|
|
152
|
+
fontWeight: 700,
|
|
153
|
+
color: "var(--af-text)",
|
|
154
|
+
textTransform: "uppercase",
|
|
155
|
+
letterSpacing: "0.04em",
|
|
156
|
+
}}
|
|
157
|
+
>
|
|
158
|
+
3. Cleaning up noise
|
|
159
|
+
</h3>
|
|
160
|
+
<p style={{ margin: "0 0 6px" }}>
|
|
161
|
+
Raw overlaps are noisy — a typical day produces dozens of
|
|
162
|
+
sub-minute artifacts from switching between sessions. Two rules
|
|
163
|
+
collapse them into human-readable bursts:
|
|
164
|
+
</p>
|
|
165
|
+
<ul style={{ margin: "6px 0 0 0", paddingLeft: 22 }}>
|
|
166
|
+
<li style={{ marginBottom: 4 }}>
|
|
167
|
+
<strong style={{ color: "var(--af-text)" }}>Drop under 1 minute</strong> —
|
|
168
|
+
overlaps shorter than that are almost always tab-switch
|
|
169
|
+
artifacts, not real parallel work.
|
|
170
|
+
</li>
|
|
171
|
+
<li>
|
|
172
|
+
<strong style={{ color: "var(--af-text)" }}>Merge within 10 minutes</strong> —
|
|
173
|
+
two overlaps separated by less than 10 minutes of idle time
|
|
174
|
+
fuse into a single burst. A morning of back-and-forth agent
|
|
175
|
+
work becomes one burst, not forty.
|
|
176
|
+
</li>
|
|
177
|
+
</ul>
|
|
178
|
+
|
|
179
|
+
<h3
|
|
180
|
+
style={{
|
|
181
|
+
margin: "18px 0 8px",
|
|
182
|
+
fontSize: 12,
|
|
183
|
+
fontWeight: 700,
|
|
184
|
+
color: "var(--af-text)",
|
|
185
|
+
textTransform: "uppercase",
|
|
186
|
+
letterSpacing: "0.04em",
|
|
187
|
+
}}
|
|
188
|
+
>
|
|
189
|
+
4. Same-project vs cross-project
|
|
190
|
+
</h3>
|
|
191
|
+
<p style={{ margin: "0 0 6px" }}>
|
|
192
|
+
Bursts are colored by whether the involved sessions span more
|
|
193
|
+
than one project directory.{" "}
|
|
194
|
+
<span style={{ color: "rgba(167, 139, 250, 1)", fontWeight: 600 }}>
|
|
195
|
+
Purple = cross-project
|
|
196
|
+
</span>{" "}
|
|
197
|
+
— different repos running at once, usually genuine fleet work.{" "}
|
|
198
|
+
<span style={{ color: "rgba(45, 212, 191, 1)", fontWeight: 600 }}>
|
|
199
|
+
Teal = same-project
|
|
200
|
+
</span>{" "}
|
|
201
|
+
— multiple sessions in one repo, usually context-switching
|
|
202
|
+
inside a single task.
|
|
203
|
+
</p>
|
|
204
|
+
|
|
205
|
+
<h3
|
|
206
|
+
style={{
|
|
207
|
+
margin: "18px 0 8px",
|
|
208
|
+
fontSize: 12,
|
|
209
|
+
fontWeight: 700,
|
|
210
|
+
color: "var(--af-text)",
|
|
211
|
+
textTransform: "uppercase",
|
|
212
|
+
letterSpacing: "0.04em",
|
|
213
|
+
}}
|
|
214
|
+
>
|
|
215
|
+
Why bursts, not runs
|
|
216
|
+
</h3>
|
|
217
|
+
<p style={{ margin: "0 0 6px" }}>
|
|
218
|
+
An earlier version reported every raw overlap as a separate
|
|
219
|
+
"parallel run". On a busy day that produced 40–80 entries,
|
|
220
|
+
most of them seconds long, most of them meaningless. Bursts are
|
|
221
|
+
the unit humans actually think in: "this morning I was
|
|
222
|
+
running 3 agents at once for about 20 minutes."
|
|
223
|
+
</p>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { canonicalProjectName } from "@claude-lens/parser";
|
|
2
|
+
|
|
3
|
+
export const ROW_HEIGHT = 30;
|
|
4
|
+
export const ROW_GAP = 3;
|
|
5
|
+
export const LABEL_WIDTH = 220;
|
|
6
|
+
export const HEADER_HEIGHT = 26;
|
|
7
|
+
export const BURST_RIBBON_HEIGHT = 24;
|
|
8
|
+
export const MIN_CHART_WIDTH = 700;
|
|
9
|
+
export const PAD_MS = 30 * 60 * 1000; // 30-min padding on each side
|
|
10
|
+
|
|
11
|
+
export const PROJECT_COLORS = [
|
|
12
|
+
"rgba(45, 212, 191, 0.75)",
|
|
13
|
+
"rgba(167, 139, 250, 0.75)",
|
|
14
|
+
"rgba(248, 113, 113, 0.75)",
|
|
15
|
+
"rgba(52, 211, 153, 0.75)",
|
|
16
|
+
"rgba(251, 191, 36, 0.75)",
|
|
17
|
+
"rgba(236, 72, 153, 0.75)",
|
|
18
|
+
"rgba(34, 211, 238, 0.75)",
|
|
19
|
+
"rgba(168, 85, 247, 0.75)",
|
|
20
|
+
"rgba(244, 114, 82, 0.75)",
|
|
21
|
+
"rgba(96, 165, 250, 0.75)",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Hash a project key to a stable color. The key should be a canonical
|
|
26
|
+
* project identity (not a raw projectDir) so all worktrees of the same
|
|
27
|
+
* repo share one color — visually grouping "this repo's parallel work".
|
|
28
|
+
*/
|
|
29
|
+
export function projectColor(projectKey: string): string {
|
|
30
|
+
let hash = 0;
|
|
31
|
+
for (let i = 0; i < projectKey.length; i++) {
|
|
32
|
+
hash = ((hash << 5) - hash + projectKey.charCodeAt(i)) | 0;
|
|
33
|
+
}
|
|
34
|
+
return PROJECT_COLORS[Math.abs(hash) % PROJECT_COLORS.length]!;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Color for a Gantt session, keyed by canonical project name. */
|
|
38
|
+
export function sessionColor(s: { projectName: string }): string {
|
|
39
|
+
return projectColor(canonicalProjectName(s.projectName));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function stripXml(s: string): string {
|
|
43
|
+
return s.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function fmtTime(ms: number): string {
|
|
47
|
+
const d = new Date(ms);
|
|
48
|
+
return `${d.getHours().toString().padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}`;
|
|
49
|
+
}
|