fleetlens 0.1.0 → 0.1.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.
Files changed (67) 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.js.nft.json +1 -1
  12. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  13. package/app/apps/web/.next/server/app/page.js +2 -2
  14. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  15. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  16. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  17. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  18. package/app/apps/web/.next/server/app/projects/[slug]/page.js +2 -2
  19. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  20. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  21. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  22. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  23. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  24. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  25. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  26. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  27. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  28. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  29. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0pm~ki3._.js +3 -3
  30. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0e53.km._.js +3 -0
  31. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0g56txz._.js +3 -0
  32. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0xh83kj._.js +8 -0
  33. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__100em.n._.js +3 -0
  34. package/app/apps/web/.next/server/chunks/ssr/_0mer501._.js +12 -0
  35. package/app/apps/web/.next/server/chunks/ssr/_0mkq9uv._.js +12 -0
  36. package/app/apps/web/.next/server/chunks/ssr/_0yyvgac._.js +1 -1
  37. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_06j3c.0._.js +1 -1
  38. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0b-4-4j._.js +8 -0
  39. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0-jvt~a._.js +1 -1
  40. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  41. package/app/apps/web/.next/server/pages/500.html +1 -1
  42. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  43. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  44. package/app/apps/web/.next/static/chunks/0ewidc3d80nvk.js +6 -0
  45. package/app/apps/web/.next/static/chunks/0ipd1ph4bgubq.js +6 -0
  46. package/app/apps/web/.next/static/chunks/0r_2tya645h45.js +6 -0
  47. package/app/apps/web/app/api/ask/route.ts +1 -1
  48. package/app/apps/web/app/layout.tsx +2 -2
  49. package/app/apps/web/app/projects/[slug]/page.tsx +87 -112
  50. package/app/apps/web/components/sidebar.tsx +1 -1
  51. package/app/apps/web/package.json +1 -1
  52. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  53. package/dist/index.js +14 -14
  54. package/package.json +1 -1
  55. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__07uf5k8._.js +0 -8
  56. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0bb9l_d._.js +0 -3
  57. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0yhkpq.._.js +0 -3
  58. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__10tl2-f._.js +0 -3
  59. package/app/apps/web/.next/server/chunks/ssr/_0c4zmjt._.js +0 -12
  60. package/app/apps/web/.next/server/chunks/ssr/_0ev.8gk._.js +0 -12
  61. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_033k_mm._.js +0 -3
  62. package/app/apps/web/.next/static/chunks/01zgbvaped3rv.js +0 -6
  63. package/app/apps/web/.next/static/chunks/0fn-74bl9-qvi.js +0 -1
  64. package/app/apps/web/.next/static/chunks/0wmzqi~uv60lw.js +0 -6
  65. /package/app/apps/web/.next/static/{prUnSo8A-GShFCDI6P0cA → 2kdRQ_Qfdyey-Xt31t7FV}/_buildManifest.js +0 -0
  66. /package/app/apps/web/.next/static/{prUnSo8A-GShFCDI6P0cA → 2kdRQ_Qfdyey-Xt31t7FV}/_clientMiddlewareManifest.js +0 -0
  67. /package/app/apps/web/.next/static/{prUnSo8A-GShFCDI6P0cA → 2kdRQ_Qfdyey-Xt31t7FV}/_ssgManifest.js +0 -0
@@ -3,20 +3,13 @@ import Link from "next/link";
3
3
  import { listSessions, getSession } from "@/lib/data";
4
4
  import {
5
5
  canonicalProjectName,
6
- detectParallelRuns,
7
6
  detectPrMarkers,
8
7
  sessionAirTimeMs,
9
8
  } from "@claude-lens/parser";
10
9
  import { DashboardView } from "@/components/dashboard-view";
11
- import { MetricCard } from "@/components/metric-card";
12
- import { ParallelRunsStrip } from "@/components/parallel-runs-strip";
13
- import {
14
- formatDuration,
15
- formatRelative,
16
- prettyProjectName,
17
- shortId,
18
- } from "@/lib/format";
19
- import { ArrowLeft, GitPullRequest } from "lucide-react";
10
+ import { LiveBadge } from "@/components/live-badge";
11
+ import { formatDuration, formatRelative, prettyProjectName } from "@/lib/format";
12
+ import { ArrowLeft } from "lucide-react";
20
13
 
21
14
  export const dynamic = "force-dynamic";
22
15
 
@@ -36,7 +29,6 @@ export default async function ProjectDetail({ params }: { params: Promise<{ slug
36
29
 
37
30
  // Use the canonical name for display (no `.worktrees/<name>` suffix).
38
31
  const projectName = decodedCanonical;
39
- const parallelRuns = detectParallelRuns(projectSessions, 2);
40
32
 
41
33
  // PR detection is per-session — it needs the event stream, so load the
42
34
  // detail for each session and scan. Cap at first 50 sessions so a project
@@ -53,6 +45,9 @@ export default async function ProjectDetail({ params }: { params: Promise<{ slug
53
45
  .filter((d): d is NonNullable<typeof d> => !!d)
54
46
  .reduce((a, d) => a + sessionAirTimeMs(d.events), 0);
55
47
 
48
+ const recentSessions = projectSessions.slice(0, 12);
49
+ const hasPrs = prMarkers.length > 0;
50
+
56
51
  return (
57
52
  <div
58
53
  style={{
@@ -97,53 +92,36 @@ export default async function ProjectDetail({ params }: { params: Promise<{ slug
97
92
 
98
93
  <DashboardView
99
94
  sessions={projectSessions}
100
- override={{
101
- activeTimeMs: refinedAirMs || undefined,
102
- extraCards: (
103
- <MetricCard
104
- label="PRs shipped"
105
- value={String(prMarkers.length)}
106
- sub={
107
- prMarkers.length > 0
108
- ? `${sliced.length} sessions scanned`
109
- : "scanned recent 50"
110
- }
111
- icon={<GitPullRequest size={13} />}
112
- tooltip="PRs detected by scanning for `gh pr create` Bash commands in session transcripts. Only the most recent 50 sessions are scanned."
113
- />
114
- ),
115
- }}
95
+ override={{ activeTimeMs: refinedAirMs || undefined }}
116
96
  />
117
97
 
118
- {/* PR timeline + Parallel runs — two-column */}
98
+ {/* Pull requests shipped + Recent sessions — two columns (or one if no PRs) */}
119
99
  <section
120
100
  style={{
121
101
  display: "grid",
122
- gridTemplateColumns: prMarkers.length > 0 && parallelRuns.length > 0 ? "1fr 1fr" : "1fr",
102
+ gridTemplateColumns: hasPrs ? "1fr 1fr" : "1fr",
123
103
  gap: 16,
124
104
  }}
125
105
  >
126
- {prMarkers.length > 0 && (
106
+ {hasPrs && (
127
107
  <div className="af-panel">
128
108
  <div className="af-panel-header">
129
109
  <span>Pull requests shipped</span>
130
- <span
131
- style={{ fontSize: 11, color: "var(--af-text-tertiary)", fontWeight: 400 }}
132
- >
110
+ <span style={{ fontSize: 11, color: "var(--af-text-tertiary)", fontWeight: 400 }}>
133
111
  detected from `gh pr create` calls
134
112
  </span>
135
113
  </div>
136
114
  <div style={{ padding: 14, display: "flex", flexDirection: "column", gap: 6 }}>
137
115
  {prMarkers
138
116
  .sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp))
139
- .slice(0, 25)
117
+ .slice(0, 12)
140
118
  .map((m, i) => (
141
119
  <Link
142
120
  key={i}
143
121
  href={`/sessions/${m.sessionId}`}
144
122
  style={{
145
123
  display: "grid",
146
- gridTemplateColumns: "100px 1fr 70px",
124
+ gridTemplateColumns: "90px 1fr 60px",
147
125
  gap: 10,
148
126
  padding: "10px 14px",
149
127
  border: "1px solid var(--af-border-subtle)",
@@ -159,6 +137,7 @@ export default async function ProjectDetail({ params }: { params: Promise<{ slug
159
137
  color: "var(--af-text-secondary)",
160
138
  fontFamily: "var(--font-mono)",
161
139
  }}
140
+ suppressHydrationWarning
162
141
  >
163
142
  {formatRelative(m.timestamp)}
164
143
  </div>
@@ -191,89 +170,85 @@ export default async function ProjectDetail({ params }: { params: Promise<{ slug
191
170
  </div>
192
171
  )}
193
172
 
194
- {parallelRuns.length > 0 && (
195
- <div className="af-panel">
196
- <div className="af-panel-header">
197
- <span>Parallel runs</span>
198
- <span style={{ fontSize: 11, color: "var(--af-text-tertiary)", fontWeight: 400 }}>
199
- ≥ 2 concurrent sessions
200
- </span>
201
- </div>
202
- <div style={{ padding: 14 }}>
203
- <ParallelRunsStrip runs={parallelRuns} sessions={projectSessions} />
204
- </div>
205
- </div>
206
- )}
207
- </section>
208
-
209
- {/* Session list */}
210
- <div className="af-panel">
211
- <div className="af-panel-header">
212
- <span>Sessions</span>
213
- <span style={{ fontSize: 11, color: "var(--af-text-tertiary)", fontWeight: 400 }}>
214
- newest first
215
- </span>
216
- </div>
217
- <div>
218
- {projectSessions.map((s) => (
173
+ <div className="af-panel">
174
+ <div className="af-panel-header">
175
+ <span>Recent sessions</span>
219
176
  <Link
220
- key={`${s.projectDir}/${s.id}`}
221
- href={`/sessions/${s.id}`}
222
- style={{
223
- display: "grid",
224
- gridTemplateColumns: "100px 1fr 90px 90px",
225
- gap: 14,
226
- padding: "12px 18px",
227
- fontSize: 12,
228
- borderBottom: "1px solid var(--af-border-subtle)",
229
- alignItems: "center",
230
- }}
177
+ href="/sessions"
178
+ style={{ fontSize: 11, color: "var(--af-accent)", marginLeft: "auto" }}
231
179
  >
232
- <div
233
- style={{
234
- fontFamily: "var(--font-mono)",
235
- fontSize: 11,
236
- color: "var(--af-text-tertiary)",
237
- }}
238
- >
239
- sesn_{shortId(s.id)}
240
- </div>
241
- <div
242
- style={{
243
- overflow: "hidden",
244
- textOverflow: "ellipsis",
245
- whiteSpace: "nowrap",
246
- color: "var(--af-text)",
247
- }}
248
- >
249
- {s.firstUserPreview || (
250
- <em style={{ color: "var(--af-text-tertiary)" }}>(no user message)</em>
251
- )}
252
- </div>
253
- <div
254
- style={{
255
- fontSize: 11,
256
- color: "var(--af-text-tertiary)",
257
- fontFamily: "var(--font-mono)",
258
- textAlign: "right",
259
- }}
260
- title="Agent time (filters out idle gaps)"
261
- >
262
- {formatDuration(s.airTimeMs ?? s.durationMs)}
263
- </div>
264
- <div
180
+ View all →
181
+ </Link>
182
+ </div>
183
+ <div>
184
+ {recentSessions.map((s) => (
185
+ <Link
186
+ key={`${s.projectDir}/${s.id}`}
187
+ href={`/sessions/${s.id}`}
265
188
  style={{
266
- fontSize: 10,
267
- color: "var(--af-text-tertiary)",
268
- textAlign: "right",
189
+ display: "grid",
190
+ gridTemplateColumns: "1fr auto auto",
191
+ gap: 12,
192
+ padding: "10px 18px",
193
+ fontSize: 12,
194
+ borderBottom: "1px solid var(--af-border-subtle)",
195
+ alignItems: "center",
269
196
  }}
270
197
  >
271
- {s.firstTimestamp ? formatRelative(s.firstTimestamp) : "—"}
272
- </div>
273
- </Link>
274
- ))}
198
+ <div style={{ minWidth: 0 }}>
199
+ <div
200
+ style={{
201
+ overflow: "hidden",
202
+ textOverflow: "ellipsis",
203
+ whiteSpace: "nowrap",
204
+ color: "var(--af-text)",
205
+ display: "flex",
206
+ alignItems: "center",
207
+ gap: 6,
208
+ }}
209
+ >
210
+ <LiveBadge mtimeIso={s.lastTimestamp} />
211
+ <span
212
+ style={{
213
+ overflow: "hidden",
214
+ textOverflow: "ellipsis",
215
+ whiteSpace: "nowrap",
216
+ }}
217
+ >
218
+ {s.firstUserPreview || (
219
+ <em style={{ color: "var(--af-text-tertiary)" }}>(no user message)</em>
220
+ )}
221
+ </span>
222
+ </div>
223
+ </div>
224
+ <div
225
+ style={{
226
+ fontSize: 10,
227
+ color: "var(--af-text-tertiary)",
228
+ fontFamily: "var(--font-mono)",
229
+ textAlign: "right",
230
+ minWidth: 54,
231
+ }}
232
+ title="Agent time (filters out idle gaps)"
233
+ >
234
+ {formatDuration(s.airTimeMs ?? s.durationMs)}
235
+ </div>
236
+ <div
237
+ style={{
238
+ fontSize: 10,
239
+ color: "var(--af-text-tertiary)",
240
+ textAlign: "right",
241
+ minWidth: 54,
242
+ }}
243
+ suppressHydrationWarning
244
+ >
245
+ {s.firstTimestamp ? formatRelative(s.firstTimestamp) : "—"}
246
+ </div>
247
+ </Link>
248
+ ))}
249
+ </div>
275
250
  </div>
276
- </div>
251
+ </section>
277
252
  </div>
278
253
  );
279
254
  }
@@ -126,7 +126,7 @@ export function Sidebar({
126
126
  </div>
127
127
  <div>
128
128
  <div style={{ fontSize: 14, fontWeight: 700, letterSpacing: "-0.01em" }}>
129
- Claude Lens
129
+ fleetlens
130
130
  </div>
131
131
  <div style={{ fontSize: 11, color: "var(--af-text-tertiary)" }}>local dashboard</div>
132
132
  </div>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-lens/web",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "private": true,
5
5
  "description": "Local-only dashboard for Claude Code sessions. Reads ~/.claude/projects/*.jsonl and visualizes agent activity.",
6
6
  "license": "MIT",