docs: add README and CC BY-NC 4.0 license
README includes: - Non-technical user section (installation, quick start, tips) - Developer section (architecture, data flow, design decisions, build instructions, signed DMG workflow, dependencies) - License summary (free to use/modify/distribute, no monetization)
This commit is contained in:
parent
659dade82d
commit
e963b2edcd
49
LICENSE
Normal file
49
LICENSE
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
Creative Commons Attribution-NonCommercial 4.0 International
|
||||||
|
|
||||||
|
Copyright (c) 2026 Svrnty
|
||||||
|
|
||||||
|
This work is provided under the terms of the Creative Commons
|
||||||
|
Attribution-NonCommercial 4.0 International Public License
|
||||||
|
("CC BY-NC 4.0"). A summary of the license is below. The full
|
||||||
|
license text is available at:
|
||||||
|
|
||||||
|
https://creativecommons.org/licenses/by-nc/4.0/legalcode
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
You are free to:
|
||||||
|
|
||||||
|
Share — copy and redistribute the material in any medium or format
|
||||||
|
|
||||||
|
Adapt — remix, transform, and build upon the material
|
||||||
|
|
||||||
|
Under the following terms:
|
||||||
|
|
||||||
|
Attribution — You must give appropriate credit, provide a link to
|
||||||
|
the license, and indicate if changes were made. You may do so in
|
||||||
|
any reasonable manner, but not in any way that suggests the
|
||||||
|
licensor endorses you or your use.
|
||||||
|
|
||||||
|
NonCommercial — You may not use the material for commercial purposes.
|
||||||
|
This includes, but is not limited to, selling the software, using
|
||||||
|
it as part of a commercial product or service, or charging for
|
||||||
|
access to features built on top of it.
|
||||||
|
|
||||||
|
No additional restrictions — You may not apply legal terms or
|
||||||
|
technological measures that legally restrict others from doing anything
|
||||||
|
the license permits.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NOTICES:
|
||||||
|
|
||||||
|
"Claude Session Viewer" is not affiliated with, endorsed by, or
|
||||||
|
connected to Anthropic PBC. "Claude" is a trademark of Anthropic PBC.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
190
README.md
Normal file
190
README.md
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
# Claude Session Viewer
|
||||||
|
|
||||||
|
A macOS desktop app for browsing and analyzing your Claude AI conversation sessions. Explore your prompts, assistant responses, tool usage, token consumption, and subagent activity — all in a fast, searchable interface.
|
||||||
|
|
||||||
|
 
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## For Everyone
|
||||||
|
|
||||||
|
### What It Does
|
||||||
|
|
||||||
|
If you use [Claude](https://claude.ai) with the CLI (`claude`), every conversation is saved as a `.jsonl` file on your Mac. **Claude Session Viewer** lets you open those files and browse them with:
|
||||||
|
|
||||||
|
- **Timeline view** — See your conversation as a visual tree with user prompts, assistant responses, and tool calls all laid out chronologically
|
||||||
|
- **Search & filter** — Find specific messages, filter by type (user/assistant/system), or narrow down to a specific subagent
|
||||||
|
- **Tool usage analytics** — See which tools were used, how often, and with what arguments
|
||||||
|
- **Token tracking** — Break down token consumption by agent (input, output, cache hits)
|
||||||
|
- **Subagent inspection** — Drill into subagent conversations that were spawned during a session
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
1. Download the latest `Claude Session Viewer.dmg` from the [Releases](../../releases) page
|
||||||
|
2. Double-click the DMG
|
||||||
|
3. Drag **Claude Session Viewer** to your **Applications** folder
|
||||||
|
4. Launch it — no Gatekeeper warnings, the app is signed and notarized by Apple
|
||||||
|
|
||||||
|
### Quick Start
|
||||||
|
|
||||||
|
1. Open the app
|
||||||
|
2. It automatically scans `~/.claude/projects` for your session files
|
||||||
|
3. Pick a project → pick a session → browse the timeline
|
||||||
|
4. Or use **File → Open** to load any `.jsonl` file directly
|
||||||
|
|
||||||
|
### Tips
|
||||||
|
|
||||||
|
- Use the **search bar** in the timeline to find specific messages or tool calls
|
||||||
|
- Click the **type toggles** (User / Assistant / System) to filter what's shown
|
||||||
|
- Use the **agent dropdown** to focus on a specific subagent's activity
|
||||||
|
- Expand **tool use cards** to see arguments, results, and inline subagent conversations
|
||||||
|
- Expand **Thinking** blocks to see Claude's reasoning (when available)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## For Developers
|
||||||
|
|
||||||
|
### Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
lib/
|
||||||
|
├── main.dart # Entry point, Provider setup
|
||||||
|
├── models/
|
||||||
|
│ ├── agent_info.dart # AgentInfo + SessionLog aggregates
|
||||||
|
│ ├── content_block.dart # ContentBlock hierarchy (Text, Thinking, ToolUse, ToolResult)
|
||||||
|
│ ├── log_entry.dart # LogEntry hierarchy (User, Assistant, System, Progress, FileSnapshot)
|
||||||
|
│ └── token_usage.dart # TokenUsage value type
|
||||||
|
├── providers/
|
||||||
|
│ └── session_provider.dart # ChangeNotifier with cached filtering + debounced search
|
||||||
|
├── services/
|
||||||
|
│ └── jsonl_parser.dart # Isolate-based JSONL parser + session builder
|
||||||
|
├── screens/
|
||||||
|
│ ├── home/ # Project/session browser (scans ~/.claude/projects)
|
||||||
|
│ ├── timeline/ # Flat virtualized timeline with tree connectors
|
||||||
|
│ ├── agents/ # Agent analytics cards
|
||||||
|
│ ├── tokens/ # Token usage dashboard (pie chart + data table)
|
||||||
|
│ └── toolbelt/ # Tool usage bar chart + per-tool details
|
||||||
|
├── theme/
|
||||||
|
│ └── app_theme.dart # Dark theme + color constants
|
||||||
|
└── widgets/
|
||||||
|
├── common/ # ExpandableCard (lazy expand), JsonTreeView
|
||||||
|
└── navigation/ # AppShell (IndexedStack), Sidebar
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
FilePicker → SessionProvider.loadSession()
|
||||||
|
→ Isolate.run(JsonlParser._parseInIsolate) # CPU work off main thread
|
||||||
|
→ jsonDecode per line + LogEntry.fromJson
|
||||||
|
→ _linkToolResults() + _buildAgents()
|
||||||
|
→ ParseResult(SessionLog, List<ParseError>)
|
||||||
|
→ SessionProvider caches filteredEntries
|
||||||
|
→ Screens consume via context.select<SessionProvider, T>()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Design Decisions
|
||||||
|
|
||||||
|
| Decision | Rationale |
|
||||||
|
|----------|-----------|
|
||||||
|
| **Single ChangeNotifier** | App has one data source (a session file). No need for Riverpod/Bloc complexity. |
|
||||||
|
| **Isolate-based parsing** | 50K-line JSONL files parse in 2-4s — must not block the UI thread. |
|
||||||
|
| **Flat virtualized timeline** | Flattened turns into `List<_TimelineItem>` so `ListView.builder` recycles every card independently. |
|
||||||
|
| **Cached filter results** | `_FilterKey`-based invalidation avoids O(n) recomputation on every rebuild. |
|
||||||
|
| **Lazy ExpandableCard** | `AnimatedCrossFade` builds both children eagerly. Replaced with `SizeTransition` + `_hasBeenExpanded` guard. |
|
||||||
|
| **IndexedStack navigation** | Preserves scroll position and state across tab switches. |
|
||||||
|
| **No code generation** | 17 source files, single-user tool — hand-written `fromJson` is fine. |
|
||||||
|
|
||||||
|
### Building from Source
|
||||||
|
|
||||||
|
**Requirements:** Flutter 3.29+ / Dart 3.10+, macOS 13.0+, Xcode 16+
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone
|
||||||
|
git clone https://github.com/your-org/claude_session_viewer.git
|
||||||
|
cd claude_session_viewer
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
flutter pub get
|
||||||
|
|
||||||
|
# Run in debug mode
|
||||||
|
flutter run -d macos
|
||||||
|
|
||||||
|
# Build release
|
||||||
|
flutter build macos --release
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building a Signed & Notarized DMG
|
||||||
|
|
||||||
|
The project is pre-configured for Developer ID distribution. Set your team ID in `macos/Runner.xcodeproj/project.pbxproj` and `macos/Runner/Configs/AppInfo.xcconfig`, then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build
|
||||||
|
flutter build macos --release
|
||||||
|
|
||||||
|
# Re-sign with hardened runtime (inside-out)
|
||||||
|
APP="build/macos/Build/Products/Release/Claude Session Viewer.app"
|
||||||
|
SIGN_ID="Developer ID Application: Your Name (TEAMID)"
|
||||||
|
|
||||||
|
find "$APP/Contents/Frameworks" -name "*.framework" -maxdepth 1 | while read fw; do
|
||||||
|
codesign --force --deep --sign "$SIGN_ID" --timestamp --options runtime \
|
||||||
|
--entitlements macos/Runner/Release.entitlements "$fw"
|
||||||
|
done
|
||||||
|
|
||||||
|
codesign --force --deep --sign "$SIGN_ID" --timestamp --options runtime \
|
||||||
|
--entitlements macos/Runner/Release.entitlements "$APP"
|
||||||
|
|
||||||
|
# Create DMG
|
||||||
|
hdiutil create -volname "Claude Session Viewer" \
|
||||||
|
-srcfolder "$APP" -ov -format UDZO \
|
||||||
|
"build/Claude Session Viewer.dmg"
|
||||||
|
|
||||||
|
# Sign DMG
|
||||||
|
codesign --sign "$SIGN_ID" --timestamp "build/Claude Session Viewer.dmg"
|
||||||
|
|
||||||
|
# Notarize
|
||||||
|
xcrun notarytool submit "build/Claude Session Viewer.dmg" \
|
||||||
|
--keychain-profile "notarytool" --wait
|
||||||
|
|
||||||
|
# Staple ticket
|
||||||
|
xcrun stapler staple "build/Claude Session Viewer.dmg"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
| Package | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `provider` | State management (ChangeNotifier) |
|
||||||
|
| `file_picker` | Native file picker dialog |
|
||||||
|
| `flutter_markdown` | Markdown rendering in assistant messages |
|
||||||
|
| `fl_chart` | Pie chart (tokens) + bar chart (tool usage) |
|
||||||
|
| `google_fonts` | Inter font family |
|
||||||
|
| `intl` | Number/date formatting |
|
||||||
|
|
||||||
|
### Entitlements (macOS Sandbox)
|
||||||
|
|
||||||
|
The release build runs in the macOS **App Sandbox** with:
|
||||||
|
- `com.apple.security.app-sandbox` — enabled
|
||||||
|
- `com.apple.security.files.user-selected.read-only` — open files via dialog
|
||||||
|
- `com.apple.security.files.home-directory.read-only` — scan `~/.claude/projects`
|
||||||
|
|
||||||
|
### Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! Please:
|
||||||
|
|
||||||
|
1. Fork the repository
|
||||||
|
2. Create a feature branch (`git checkout -b feature/my-feature`)
|
||||||
|
3. Commit your changes
|
||||||
|
4. Open a pull request
|
||||||
|
|
||||||
|
Note: This project is **non-commercial** — contributions must respect the CC BY-NC 4.0 license.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under [Creative Commons Attribution-NonCommercial 4.0 International](./LICENSE).
|
||||||
|
|
||||||
|
You are free to use, modify, and distribute this software for personal and non-commercial purposes. Commercial use, resale, or monetization is not permitted without written permission.
|
||||||
|
|
||||||
|
© 2026 Svrnty. All rights reserved.
|
||||||
Loading…
Reference in New Issue
Block a user