Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b5b0b52
feat: add @clens/web dashboard + monorepo restructure + security/stan…
silouone Mar 8, 2026
505fd59
perf: lightweight session listing — read first+last lines only
silouone Mar 8, 2026
6d66749
init clens web
silouone Mar 8, 2026
a64ec0c
web v0.1.0
silouone Mar 8, 2026
64463e7
clens web iteration
silouone Mar 13, 2026
eaedb3d
clens web UI/UX enahncement
silouone Mar 14, 2026
a23acf6
iteration on UI/UX session 2
silouone Mar 14, 2026
b877e08
work unit
silouone Mar 14, 2026
1423ebe
clens web final
silouone Mar 15, 2026
658e629
add settings page with app header navigation and wired preferences
silouone Mar 15, 2026
b23684e
move KPIs, Live indicator, and view toggle to sticky app header
silouone Mar 15, 2026
82777ce
refine header layout: move refresh to page, push nav right with separ…
silouone Mar 15, 2026
12c2a72
feat: add global multi-repo mode for cross-project session tracking
silouone Mar 15, 2026
2cdf397
add assets and fix stuff
silouone Mar 16, 2026
72eddcf
checkpoint before revival work
silouone Jun 11, 2026
bc53f9f
fix wave 1: exact event counts, duration semantics, active-duration, …
silouone Jun 11, 2026
79c48f0
fix wave 2: builder fleet fixes + orchestrator polish
silouone Jun 11, 2026
78642f9
fix wave 3: confirmed-findings fleet + orchestrator completion
silouone Jun 11, 2026
7893127
fix wave 4: gap closure — debugging-loop gate, team subject correlati…
silouone Jun 11, 2026
f2d40f7
phase 4: INSTRUMENT sweep — all 7 component groups restyled
silouone Jun 11, 2026
06cb93d
phase 4 polish: staleness banner layout, single-point area markers
silouone Jun 11, 2026
16c5cf6
fix: attach auth token to raw client fetches (prod-mode 401s found by…
silouone Jun 11, 2026
c34c5c0
phase 5: final validation — work-unit path disambiguation, dead font …
silouone Jun 11, 2026
c281824
checkpoint: overnight OSS-refactor planning + inherited clens-web WIP…
silouone Jun 27, 2026
a8e6ebf
build wave 0: repo hygiene & release foundation
silouone Jun 27, 2026
727e36f
fixup wave 0: strip stray tags leaked into SECURITY.md; add defensive…
silouone Jun 27, 2026
66aaf71
build wave 1: P0 backend correctness, packaging & clean safety
silouone Jun 27, 2026
3a003b8
build wave 2: backend distill/analytics/cost, CLI papercuts & publish
silouone Jun 27, 2026
25f443a
build wave 3: frontend numbers display
silouone Jun 27, 2026
58d5eba
build wave 4: FE design & responsive foundations + number tails
silouone Jun 27, 2026
b0b828a
build wave 5: FE filters, IA/live & design polish
silouone Jun 27, 2026
9e60156
build wave 6: session config/environment feature (ASK-01)
silouone Jun 27, 2026
63dc206
build wave 7: deprecation cuts (isolated, revertible)
silouone Jun 27, 2026
109f84c
build wave 8: tests & quality gates
silouone Jun 27, 2026
d26824c
build wave 9: documentation
silouone Jun 27, 2026
98881ef
assets: launch dashboard screenshots + fix README image links (DOCS-1…
silouone Jun 27, 2026
baa0999
build wave 10: clens.dev landing foundation
silouone Jun 27, 2026
f8191df
build wave 11: landing page build/polish
silouone Jun 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
64 changes: 64 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Bug report
description: Report something in clens that is broken or behaves incorrectly.
title: "[bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to file a bug. Please fill out the sections below so we can reproduce and fix it quickly.

clens is **local-first** — it never sends your session data anywhere. When sharing logs or output, please redact anything sensitive.
- type: textarea
id: what-happened
attributes:
label: What happened?
description: A clear and concise description of the bug.
placeholder: When I run `clens ...`, I see ...
validations:
required: true
- type: textarea
id: expected
attributes:
label: What did you expect to happen?
placeholder: I expected ...
validations:
required: true
- type: textarea
id: repro
attributes:
label: Steps to reproduce
description: The exact commands and actions that trigger the bug.
value: |
1. Run `clens ...`
2. ...
3. See error
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant output or logs
description: Paste the terminal output, error message, or stack trace. This will be rendered as code, so no backticks needed.
render: shell
- type: input
id: clens-version
attributes:
label: clens version
description: Output of `clens --version`.
placeholder: 0.3.0
validations:
required: true
- type: input
id: env
attributes:
label: Environment
description: OS, runtime (Bun/Node) version, and Claude Code version if relevant.
placeholder: macOS 14.5, Bun 1.1.20, Claude Code 1.x
validations:
required: true
- type: textarea
id: context
attributes:
label: Additional context
description: Anything else that might help — screenshots, related issues, etc.
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Questions & discussion
url: https://github.com/silouone/clens/discussions
about: Ask questions, share workflows, or discuss ideas with the community.
34 changes: 34 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Feature request
description: Suggest an idea or improvement for clens.
title: "[feature]: "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for the suggestion! clens is a precision instrument for Claude Code session observability — proposals that keep it focused, honest, and local-first are most likely to land.
- type: textarea
id: problem
attributes:
label: What problem are you trying to solve?
description: Describe the pain point or gap. What can't you do today?
placeholder: I'm always trying to ... but clens doesn't ...
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposed solution
description: What would you like clens to do?
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: Other approaches, workarounds, or existing commands you have tried.
- type: textarea
id: context
attributes:
label: Additional context
description: Mockups, examples from other tools, or anything else that helps.
32 changes: 32 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!--
Thanks for contributing to clens! Please fill out the sections below.
Keep changes focused — one logical change per PR is easiest to review.
-->

## Summary

<!-- What does this PR do, and why? -->

## Related issue

<!-- e.g. Closes #123. If there's no issue, briefly explain the motivation. -->

## Type of change

- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that changes existing behavior)
- [ ] Documentation
- [ ] Refactor / chore (no functional change)

## Checklist

- [ ] `bun run typecheck` passes
- [ ] `bun test` passes
- [ ] I added or updated tests where it makes sense
- [ ] I updated the docs / README / CHANGELOG where relevant
- [ ] My changes preserve the locked metric semantics (status, wall-clock duration, exact event counts, read-time pricing, honesty caveats)

## Notes for reviewers

<!-- Anything you want a reviewer to look at closely, trade-offs made, or follow-ups deferred. -->
Binary file added .github/assets/dashboard-detail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/assets/dashboard-insights.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/assets/dashboard-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/assets/dashboard-sessions-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/assets/dashboard-sessions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/assets/dashboard-usage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 15 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
check:
runs-on: ubuntu-latest
# TEST-10: pin the timezone so time-relative analytics window tests are deterministic
# across runners. ubuntu-latest already defaults to UTC; this makes it explicit.
env:
TZ: UTC
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
Expand All @@ -17,7 +20,16 @@ jobs:
- run: bun install
- name: Typecheck
run: bun run typecheck
- name: Test
run: bun test --coverage
# TEST-5: run BOTH package suites explicitly so the web suite can never be
# silently dropped (root `bun test` recursion is incidental). Per D5-RESOLVED
# there is no vitest harness — the web tests are bun:test and run here.
- name: Test CLI
run: bun run test:cli
- name: Test web
run: bun run test:web
- name: Lint
run: bun run lint
- name: Build
run: bun run build
- name: Verify pack contents (web bundle + types)
run: node scripts/verify-pack.mjs packages/cli
20 changes: 18 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
# OIDC token for npm publish provenance (--provenance). An explicit
# permissions block replaces the default set, so id-token must be listed
# alongside contents or provenance is silently disabled.
id-token: write
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
Expand All @@ -20,6 +24,15 @@ jobs:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- run: bun install
- name: Verify tag matches package version
run: |
TAG="${GITHUB_REF_NAME#v}"
PKG="$(node -p "require('./packages/cli/package.json').version")"
if [ "$TAG" != "$PKG" ]; then
echo "::error::Tag '$GITHUB_REF_NAME' does not match packages/cli version '$PKG'"
exit 1
fi
echo "Tag and version agree: $PKG"
- name: Typecheck
run: bun run typecheck
- name: Test
Expand All @@ -28,7 +41,10 @@ jobs:
run: bun run lint
- name: Build
run: bun run build
- name: Publish
run: npm publish
- name: Verify pack contents (web bundle + types)
run: node scripts/verify-pack.mjs packages/cli
- name: Publish (packages/cli only — root is private)
working-directory: packages/cli
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ ai_docs/
docs/
cli-review/

# Internal deliberation / self-criticism (not part of the open source project)
deliberation/

# cLens local capture data
.clens/

Expand All @@ -51,3 +54,14 @@ specs/
# Internal analytics
scripts/
report_kpi_33_sessions.md

# Test artifacts
.playwright-cli/
screenshots/
ai_review/
.verify.json

# Generated/placeholder image assets (not real product assets)
**/Gemini_Generated_Image*
# Stray root-level asset dump (real product assets live in packages/web/src/client/assets)
/assets/
116 changes: 116 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,116 @@

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.3.0] - 2026-03-08

### Breaking Changes

#### Monorepo Migration
- Project restructured into Bun workspaces: `packages/cli` + `packages/web`
- All existing source moved to `packages/cli/src/`, tests to `packages/cli/test/`
- CLI package remains **zero runtime dependencies**
- Web package is a new `@clens/web` workspace with its own dependency tree

### Added

#### `clens web` — Browser-Based Session Explorer
- New CLI command: `clens web [--port <n>] [--no-open]`
- Opens a full-featured browser UI at `http://127.0.0.1:3700`
- Dynamic import of `@clens/web/server` avoids circular workspace dependency

#### Hono API Server (9 endpoints)
- `GET /api/sessions` — paginated session list with filtering and sorting
- `GET /api/sessions/:id` — distilled session detail (404/202 for missing/undistilled)
- `GET /api/sessions/:id/events` — raw events with LRU cache (10 sessions, ~17MB max)
- `GET /api/sessions/:id/conversation` — merged ConversationEntry timeline (paginated)
- `GET /api/sessions/:id/agents/:agentId/conversation` — agent-scoped conversation
- `GET /api/sessions/:id/diff/:filePath` — unified diff via diffLinesToUnified()
- `POST /api/sessions/:id/distill` — async distill trigger with SSE notification
- `GET /api/events/stream` — SSE with ring buffer replay (1000 events), 30s heartbeat
- `GET /` — SPA static assets with immutable cache headers (production mode)

#### Security
- Random 256-bit auth token per server session (query param or Bearer header)
- Bound to `127.0.0.1` only — no network exposure
- UUID regex validation on session IDs (path traversal protection)
- CORS: `localhost:5173` in dev, same-origin in production

#### SolidJS SPA
- **Session list**: table with status badges, duration, cost, branch; search, filters, pagination
- **Split-screen hero view**: ConversationPanel (left) + DiffPanel (right) with resizable SplitPane
- **ConversationPanel**: 6 entry types (user prompts, thinking blocks, tool calls, tool results, backtracks, phase boundaries); collapsible thinking with intent badges; consecutive tool call collapse; jump-to navigation; minimap scrollbar; virtual scrolling for 500+ entries
- **DiffPanel**: diff2html rendering, A/M/D/R badges, +N/-M line counts, expandable file cards, per-file lazy loading, abandoned edit markers
- **Bidirectional linking**: click tool call → scroll to diff, click file → scroll to tool call (flash highlight animation)
- **SessionHeader**: metadata bar with phase timeline visualization (click phase → scroll to boundary)
- **Bottom panel tabs**: Backtracks (click to scroll), Timeline (13 type filters), Edits (chain visualization), Communication (multi-agent)

#### Multi-Agent Views
- Agent tree sidebar for team sessions (collapsible, color-coded by agent type)
- Agent-scoped conversation view with stats sidebar (tools, cost, duration, files)
- Communication timeline: swim-lane visualization of inter-agent messages
- Solo session detection — no agent UI clutter

#### Risk Scoring
- `computeFileRiskScores()` — per-file risk based on backtracks, abandoned edits, failure rate
- Risk badges (green/amber/red) on DiffPanel file list with tooltips
- Risk levels: low (clean), medium (1-2 backtracks), high (3+ backtracks or >50% abandoned)

#### Plan Drift View
- Expected vs actual files side-by-side with match/missing/unexpected badges
- Drift score percentage with color coding

#### Live Updates
- `fs.watch` on `.clens/sessions/` and `.clens/distilled/` with 100ms debounce
- Per-file byte offset tracking for incremental JSONL reads
- SSE ring buffer (1000 events) with `Last-Event-ID` reconnect replay
- Polling fallback via `CLENS_POLL=1` env var
- Session list auto-updates with connection status indicator

#### Dark/Light Theme
- System preference detection as default, toggle in header
- Persisted in localStorage, flash-of-wrong-theme prevention
- All components support `dark:` variants

#### Keyboard Navigation
- `j`/`k` — scroll entries / session rows
- `Enter` — drill into session or agent
- `Escape` — go back
- `[`/`]` — switch panel focus
- `?` — keyboard shortcut help overlay

#### Responsive Layout
- Below 1024px: stacked layout (conversation above diffs)
- Above 1024px: side-by-side split (default)
- Error boundaries on every major panel with retry fallback

#### New CLI Modules
- `ConversationEntry` discriminated union type (6 variants)
- `buildConversation(distilled, events)` — pure function merging distilled data + raw events into sorted timeline
- `diffLinesToUnified(filePath, lines)` — converts DiffLine[] to standard unified diff format
- `computeFileRiskScores(distilled)` — per-file risk scoring (pure function, no I/O)
- `FileRiskScore` and `RiskLevel` types

#### Production Build
- Vite with SolidJS plugin, Tailwind CSS purging
- Asset fingerprinting with immutable cache headers (1 year)
- Output: 150KB JS (47KB gzip), 31KB CSS (6KB gzip)

### Changed
- `package.json` now uses Bun workspaces (`"workspaces": ["packages/*"]`)
- Root scripts: `build:cli`, `build:web`, `build`, `test:cli`, `test:web`, `test`, `dev:api`, `dev:web`
- `tsconfig.json` uses project references with shared `tsconfig.base.json`
- Hook tests updated with absolute paths for monorepo compatibility
- 1,373 CLI tests + 72 web tests = 1,445 total (0 regressions)

### Dependencies (web package only)
- Runtime: hono, solid-js, @solidjs/router, @kobalte/core, diff2html
- Dev: vite, vite-plugin-solid, tailwindcss, postcss, autoprefixer, vitest, @solidjs/testing-library

## [0.2.1] - 2026-02-25

### Added
Expand Down Expand Up @@ -170,3 +280,9 @@ All notable changes to this project will be documented in this file.
- Cost estimation (token heuristic + model pricing)
- Zero-dependency, local-first architecture
- Compiled binary support via `bun build --compile`

[Unreleased]: https://github.com/silouone/clens/compare/v0.3.0...HEAD
[0.3.0]: https://github.com/silouone/clens/compare/v0.2.1...v0.3.0
[0.2.1]: https://github.com/silouone/clens/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/silouone/clens/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/silouone/clens/releases/tag/v0.1.0
Loading
Loading