Skip to content

New package: randlee.claude-history version 0.3.0#337541

Merged
microsoft-github-policy-service[bot] merged 1 commit intomicrosoft:masterfrom
randlee:randlee-claude-history-0.3.0
Feb 13, 2026
Merged

New package: randlee.claude-history version 0.3.0#337541
microsoft-github-policy-service[bot] merged 1 commit intomicrosoft:masterfrom
randlee:randlee-claude-history-0.3.0

Conversation

@randlee
Copy link
Contributor

@randlee randlee commented Feb 8, 2026

This PR adds the initial manifest for claude-history v0.3.0.

Package Information

Description

CLI tool for programmatic access to Claude Code's agent history storage. It maps between filesystem paths and Claude's internal storage format, enabling querying, filtering, and export of conversation history including subagent sessions and tool calls.

Validation

Additional Notes

This is the initial submission for this package. Future releases will be automatically updated via winget-releaser.

Microsoft Reviewers: Open in CodeFlow

@wingetbot
Copy link
Collaborator

Validation Pipeline Run WinGetSvc-Validation-132-337541-20260208-1

randlee added a commit to randlee/claude-history that referenced this pull request Feb 8, 2026
- Created initial winget manifest for microsoft/winget-pkgs
- Includes installer, locale, and version manifests
- PR submitted: microsoft/winget-pkgs#337541
@wingetbot wingetbot added New-Package Azure-Pipeline-Passed Validation pipeline passed. There may still be manual validation requirements. Validation-Completed Validation passed labels Feb 8, 2026
@randlee
Copy link
Contributor Author

randlee commented Feb 8, 2026

@microsoft-github-policy-service agree

randlee added a commit to randlee/claude-history that referenced this pull request Feb 9, 2026
* fix(export): resolve session file lookup issue

The export command was failing to locate session JSONL files even when
the list command found them. The issue was in the path resolution logic:
ExportSession was using the original session ID without resolving prefixes.

This mirrors how the list command works - both now support git-style
prefix matching for session IDs. Updated ExportSession to call
resolver.ResolveSessionID before attempting file lookup.

Added TestExport_SessionResolution to prevent regression. Updated
existing tests to use valid UUID format session IDs instead of
arbitrary string IDs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add GoReleaser, install script, and /history skill

- Add GoReleaser config for multi-platform builds (Linux, macOS, Windows)
- Add GitHub Actions workflow for automated releases on tag push
- Add universal install.sh script for easy installation
- Add version support to CLI (--version flag)
- Add /history Claude Code skill for querying agent history
  - SKILL.md with YAML frontmatter and comprehensive examples
  - README.md with usage documentation
  - Supports all claude-history commands (list, query, tree, find-agent, export)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: remove extra blank line for gofmt compliance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): HTML quality improvements for Phase 10 (#31)

* fix(export): resolve session file lookup issue

The export command was failing to locate session JSONL files even when
the list command found them. The issue was in the path resolution logic:
ExportSession was using the original session ID without resolving prefixes.

This mirrors how the list command works - both now support git-style
prefix matching for session IDs. Updated ExportSession to call
resolver.ResolveSessionID before attempting file lookup.

Added TestExport_SessionResolution to prevent regression. Updated
existing tests to use valid UUID format session IDs instead of
arbitrary string IDs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(export): skip empty messages and add chat bubble alignment

- Add hasContent() helper to skip rendering entries with no text/tools
- Update CSS to right-align user messages and left-align assistant messages
- Update tests to reflect new empty-message-skipping behavior
- Queue operations without content still render subagent placeholders

Fixes #5 (skip empty message blocks)
Fixes #2 (right/left align chat bubbles)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): increase viewport width and normalize text spacing

- Increase conversation container max-width from 900px to 1400px for better content density
- Collapse consecutive empty lines in markdown rendering to prevent excessive vertical spacing
- Both changes improve readability and use of screen real estate

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): add collapse/expand controls and improve color scheme

Task 1: Add collapse/expand controls (#4)
- Add chevron indicators (▼) to tool and subagent headers
- Add collapsed/collapsible classes to tool-call and subagent elements
- Update toggleTool() to toggle collapsed state on parent container
- Update loadAgent() to toggle collapsed state on subagent container
- Add CSS rules for chevron rotation based on collapsed state
- Items start collapsed by default

Task 2: Improve color scheme (#6)
- User messages: softer blue (hsl(210, 100%, 95%))
- Assistant messages: light neutral gray (hsl(0, 0%, 96%))
- Tool overlays: improved teal contrast (hsl(172, 45%, 96%))
- Agent overlays: improved purple contrast (hsl(270, 80%, 97%))
- System overlays: improved amber contrast (hsl(48, 100%, 95%))
- Better visual contrast and professional appearance

Updated tests to match new HTML structure with collapsible classes.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(test): resolve TestHTMLOutput_ValidStructure failure

The test was expecting `<div class="tool-call"` with a closing quote,
but the actual HTML output has additional CSS classes:
`<div class="tool-call collapsible collapsed"`. Changed the test
expectation to match the opening portion without the closing quote,
allowing it to match regardless of additional classes.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): make chevron indicators visible

- Add explicit color, font-size, and opacity to .chevron class
- Chevrons were present but invisible due to missing color styling
- Now visible as intended for collapse/expand functionality

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: resolve lint issues for gofmt compliance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Add --limit flag to control text truncation in query output (#33)

* fix: add --limit flag to control text truncation in query output

Fixes agent output truncation bug that broke pass-by-reference workflows.

Changes:
- Add --limit flag (default: 100, 0 = no limit)
- Update WriteEntries() to accept limit parameter
- Update writeEntryList() to respect limit (0 = full content)
- Add examples to help text showing --limit 0 usage

Before: Agent analysis truncated at 100 chars ("## BEA...")
After: Full content available with --limit 0

Use cases:
- claude-history query --limit 0  (full content, no truncation)
- claude-history query --limit 500 (custom truncation)
- Default behavior unchanged (100 chars for backward compatibility)

Critical for pass-by-reference pattern where agents query previous
agent work and need complete analysis, not truncated snippets.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: filter out empty text entries from query output

Skip entries with no text content (tool-use only, progress, etc.)
to reduce clutter in text format output.

Before: Many empty lines between messages
After: Only lines with actual text content shown

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add smart preview mode for default text output

Shows first entry, count, and last entry preview with exact command
for full output. Makes default behavior much more useful for agents.

Default output now shows:
- First entry (confirms query worked)
- Entry count: '... (N more entries) ...'
- Last entry with first 10 lines of text
- Clear truncation marker: '... (10 of 842 lines shown - TRUNCATED)'
- Exact working command: '--format json | jq -r ...'

Full output modes still work:
- --limit 0: All entries in text format
- --format json: Structured data for agents
- Custom --limit N: Truncate at N chars

This gives agents immediate recognition that content is truncated
and the exact command to retry for full content.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): improve HTML quality - hide empty blocks and format XML tags (#34)

* fix: remove empty assistant blocks and improve user content formatting

Fixes HTML export rendering issues:

1. Filter empty assistant blocks
   - Added whitespace trimming in hasContent() check
   - Entries with only whitespace no longer render
   - Tool calls still render even with whitespace-only text

2. Fixed user content XML formatting
   - Fixed Go regexp compatibility (removed backreferences)
   - Improved spacing for bash-stdout/bash-stderr blocks

3. Added comprehensive tests
   - TestRenderConversation_WhitespaceOnlyContent
   - TestRenderConversation_AssistantWithOnlyToolCalls
   - Test coverage for user content formatting

Results in cleaner HTML exports with less wasted space.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* test: fix integration test JSON encoding for newlines

Fixed TestUserContentWithBashOutput and TestUserContentMixedContent
to properly escape newlines in JSON strings. Raw newlines in JSON
string literals cause "invalid character '\n' in string literal" errors.

Changes:
- Use \n escape sequences instead of literal newlines in JSON
- All export tests now pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): resolve gofmt and staticcheck issues

- Fix formatting in html.go, task_notification_test.go, and user_content_test.go
- Convert if-else chain to tagged switch statement for data.Status check
- Align struct fields and comments to match gofmt standards

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* release: prepare for v0.1.0 initial public release

Prepare the repository for the first official release (v0.1.0):

Changes:
- Updated CHANGELOG.md with v0.1.0 release notes
  - Consolidated all Phase 10 features and fixes
  - Documented query enhancements, HTML export quality improvements
  - Included CI/lint fixes and integration test corrections
- Added docs/issues.md for Phase 11-12 sprint planning
  - 6 issues tracked (P0-P2 priorities)
  - Sprint 1: Critical fixes (search, expand/collapse, newlines)
  - Sprint 2: URL enhancements (clickable links, file paths)
- Updated .gitignore to exclude worktrees directory

Ready for tagging v0.1.0 and PR to main.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(release): add Homebrew tap publishing (#35)

Configure GoReleaser to automatically publish to Homebrew tap.

Changes:
- Added brews section to .goreleaser.yml
  - Target repository: randlee/homebrew-tap
  - Auto-generates Formula/claude-history.rb
  - Includes test command for verification
- Updated release notes to prioritize Homebrew installation
- Added docs/HOMEBREW_SETUP.md with setup instructions

User Installation (after next release):
  brew tap randlee/tap
  brew install claude-history

Notes:
- GoReleaser will auto-create the homebrew-tap repository
- Formula updates automatically on each release
- Works on macOS and Linux
- No Homebrew account required

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(release): update GoReleaser hooks to run from src directory

GoReleaser runs from repo root, but go.mod is in src/.
Updated before.hooks to cd into src before running go commands.

Fixes v0.1.0 release failure:
  error=hook failed: shell: 'go mod tidy': exit status 1:
  go: go.mod file not found in current directory

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(release): specify build directory in GoReleaser config

Added 'dir: ./src' to builds section so Go can find go.mod.
Changed main from './src' to '.' since we're now in src/ dir.

Fixes build error:
  failed to build: go: cannot find main module

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(winget): add Windows Package Manager support

Creates winget manifest for Windows users to install via:
  winget install randlee.claude-history

Changes:
- Added .winget/ directory with installer manifest
- Created docs/WINGET_SETUP.md with submission instructions
- Updated README.md with winget installation method

To publish:
1. After v0.2.0 release, get SHA256 from GitHub Release
2. Update .winget/randlee.claude-history.yaml with SHA256
3. Submit PR to microsoft/winget-pkgs repository

No winget account or API keys required!

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): Resolve critical HTML export issues (Phase 11) (#37)

* fix(export): resolve critical HTML export issues (Phase 11)

Fixes three critical issues in HTML export:

1. Search functionality (P0)
   - Fixed CSS selector mismatch in controls.js
   - Changed .entry -> .message-row
   - Changed .content -> .message-content
   - Search now properly highlights and navigates matches

2. Newlines being doubled (P1)
   - Fixed markdown.go line 660
   - Join with empty string instead of \n
   - Prevents double line breaks when CSS pre-wrap is active

3. Expand/Collapse All buttons (P1)
   - Added support for <details> elements in controls.js
   - expandAllTools() and collapseAllTools() now handle both
     .tool-body class-based AND native <details> elements

All tests passing. Manual verification confirmed fixes work.

Resolves issues from docs/issues.md Phase 11.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): prevent double-escaping of HTML entities in markdown

Fixed issue where HTML entities like &#34; were being escaped twice,
resulting in literal display of entity codes (e.g., &amp;#34;) instead
of the intended characters (e.g., ").

Root cause: The RenderMarkdown function was calling escapeHTML() on
text content during header, list, table, and blockquote processing,
then calling escapeRemainingText() which escaped everything again.
This caused quotes to go from " → &#34; → &amp;#34;.

Solution: Removed redundant escapeHTML() calls from markdown element
processing functions. The escapeRemainingText() function now handles
all HTML escaping in a single pass, preventing double-escaping while
maintaining XSS protection.

Changes:
- Headers (h1-h6): Remove escapeHTML() from content
- Bold/italic: Remove escapeHTML() from content
- Tables (th/td): Remove escapeHTML() from cell content
- Lists (ul/ol/task): Remove escapeHTML() from list item content
- Blockquotes: Remove escapeHTML() from quoted text

Example:
Before: Results: &amp;#34;beads&amp;#34; References in Gastown
After:  Results: &#34;beads&#34; References in Gastown
        (renders as: Results: "beads" References in Gastown)

Tested:
- All export package tests pass
- XSS protection still works (< > & " ' are still escaped)
- HTML entities now render correctly in browsers
- Session 8c43ec84 export verified: 0 double-escaped entities

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): show session start time and duration instead of export time

Replaced "Exported: [time]" in HTML header with more valuable info:
- Session start time (when conversation began)
- Duration (how long the session lasted)

Changes:
- Added SessionStart, SessionEnd, Duration to SessionStats struct
- Updated ComputeSessionStats to extract first/last entry timestamps
- Added formatDuration helper for human-readable duration (e.g., "2h 35m")
- Updated renderHTMLHeader to display new fields instead of export time
- Modified cmd/export.go to pass ProjectPath in stats object
- Fixed timestamp parsing to handle entries without timestamps
- Added comprehensive tests for new functionality

Example header now shows:
  Session: 8c43ec84
  Project: /Users/randlee/Documents/github/github-research
  Started: 2026-02-06 20:37
  Duration: 8h 35m
  Messages: 658
  Agents: 0
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): fix agent count and enhance message statistics (Phase 12) (#38)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy (Phase 13) (#39)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy

Added interactive tooltip when hovering over agent statistics in HTML
export header. Displays table of all agents with their message counts.

Features:
- Hover tooltip shows agent ID and message count for each agent
- Agents sorted by message count (descending)
- Click to copy agent list to clipboard
- Clipboard format: session ID + tab-separated agent list
- Smooth animations and visual feedback

Changes:
- Updated renderHTMLHeader() to include agent details as data attribute
- Added CSS styling for tooltip and copy feedback
- Created agent-tooltip.js for interactive behavior
- Enhanced click-to-copy with visual confirmation
- Fixed test calls to renderHTMLHeader() with new signature

Example tooltip:
  Agent Message Counts
  ━━━━━━━━━━━━━━━━━━
  a1b2c3d4    127
  a5b6c7d8     98
  ...

Clipboard output:
  session: 8c43ec84
  ---
  a1b2c3d4    127
  a5b6c7d8    98

Technical details:
- New JavaScript module: agent-tooltip.js
- CSS styles for .agent-stats-interactive, .agent-tooltip, .copy-feedback
- Data attributes: data-session-id, data-agent-details (JSON)
- Responsive tooltip positioning (auto-adjusts for screen edges)
- Dark mode support
- Mobile responsive
- Print styles (hides tooltip)

Testing:
- All unit tests pass
- Manual testing with 29-agent session confirmed:
  * Hover shows tooltip with agent list
  * Click copies to clipboard
  * Visual feedback displays
  * Tooltip positioning works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): flatten AGENT NOTIFICATION DOM structure (Phase 14) (#40)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy

Added interactive tooltip when hovering over agent statistics in HTML
export header. Displays table of all agents with their message counts.

Features:
- Hover tooltip shows agent ID and message count for each agent
- Agents sorted by message count (descending)
- Click to copy agent list to clipboard
- Clipboard format: session ID + tab-separated agent list
- Smooth animations and visual feedback

Changes:
- Updated renderHTMLHeader() to include agent details as data attribute
- Added CSS styling for tooltip and copy feedback
- Created agent-tooltip.js for interactive behavior
- Enhanced click-to-copy with visual confirmation
- Fixed test calls to renderHTMLHeader() with new signature

Example tooltip:
  Agent Message Counts
  ━━━━━━━━━━━━━━━━━━
  a1b2c3d4    127
  a5b6c7d8     98
  ...

Clipboard output:
  session: 8c43ec84
  ---
  a1b2c3d4    127
  a5b6c7d8    98

Technical details:
- New JavaScript module: agent-tooltip.js
- CSS styles for .agent-stats-interactive, .agent-tooltip, .copy-feedback
- Data attributes: data-session-id, data-agent-details (JSON)
- Responsive tooltip positioning (auto-adjusts for screen edges)
- Dark mode support
- Mobile responsive
- Print styles (hides tooltip)

Testing:
- All unit tests pass
- Manual testing with 29-agent session confirmed:
  * Hover shows tooltip with agent list
  * Click copies to clipboard
  * Visual feedback displays
  * Tooltip positioning works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): flatten AGENT NOTIFICATION DOM structure (Phase 14)

Restructured task-notification rendering to use flattened 2-level DOM
instead of 4+ nested levels. Single-header design improves navigation
and debuggability.

Changes:
- Reduced nesting from message-row→bubble→content→notification to
  notification-row→header/content (2 levels)
- Single-line header: collapse-toggle | type | summary | agent-id
- Added CLI command tooltip to agent ID badge
- Enhanced copy button in agent ID badge
- Collapsible content with aria-expanded state
- Updated CSS for new flattened structure
- Added JavaScript for collapse toggle functionality

Benefits:
- Easier DOM navigation for debugging
- Simpler selection/search logic
- Reusable pattern for future components (User/Assistant grouping)
- Better accessibility (aria-expanded)

Example structure:
  ▼ | Subagent | Deep dive on Dog agent | [a41c57b] 📋

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): improve notification visibility and expand/collapse all

Fixed two issues with Phase 14 notifications:
1. Increased text contrast - notifications were appearing dim/disabled
2. Added notification support to Expand All / Collapse All buttons

Changes:
- Updated notification CSS colors for better contrast:
  - .notification-result: #9ca3af -> #d4d4d4 (brighter text)
  - .notification-usage: #6b7280 -> #9ca3af (improved readability)
  - .notification-header .timestamp: #6b7280 -> #9ca3af (less dim)
- Added .notification-header targeting to expandAllTools()
- Added .notification-header targeting to collapseAllTools()
- Notifications now respond to header Expand/Collapse All buttons

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use CSS variables for notification text colors

Root cause: Notifications used hardcoded dim colors (#9ca3af, #d4d4d4)
while rest of UI uses CSS variables (--text-primary, --text-secondary)
which are much brighter in dark mode.

Color comparison (dark mode):
- Old #9ca3af ≈ hsl(210 14% 65%) - very dim
- Old #d4d4d4 ≈ hsl(0 0% 83%) - dim
- New --text-primary = hsl(210 17% 95%) - bright
- New --text-secondary = hsl(210 11% 79%) - readable

Changes:
- .notification-summary: #d4d4d4 → var(--text-primary) (+12% brightness)
- .notification-result: #d4d4d4 → var(--text-primary) (+12% brightness)
- .agent-id-badge: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-usage: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-header .timestamp: #9ca3af → var(--text-secondary) (+14%)
- .collapse-toggle: #9ca3af → var(--text-secondary) (+14% brightness)

All notification text now matches the brightness of regular message content.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): copy full agent context from notifications

Changed notification copy button to include full context:
- Agent type and description
- Agent ID
- Full claude-history query command

Example copied text:
  Subagent "Deep dive on Dog agent" [ad19412]
  claude-history query /path/to/project --session 8c43ec84 --agent ad19412

This makes it easy to paste agent details into conversations with
Claude to reference specific subagents.

Also improved notification text brightness (95% -> 96%) for better
readability in dark mode.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use actual project path in copy and remove brackets

Fixed two issues:
1. Copy text now includes actual project path instead of <project-path>
2. Removed brackets from agent ID display (kept badge styling)

Before:
  Display: [ac8c7ba]
  Copy: claude-history query <project-path> ...

After:
  Display: ac8c7ba (with badge styling)
  Copy: claude-history query /path/to/project ...

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* wip: Phase 14 notification flattening changes

- Add HTML format to formatter.go
- Use RenderMarkdown for notification results
- Fix CSS color variables for proper contrast

* chore: remove unused imports from query.go

Remove unused os/exec, runtime, and export package imports
that were left over from merge conflict resolution.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: resolve lint issues

Fixed gofmt formatting issue in task_notification_test.go where line 305
had incorrect indentation (mixed spaces/tabs).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(release): add fine-grained PAT for homebrew tap publishing

- Add HOMEBREW_TAP_TOKEN environment variable to release workflow
- Update .goreleaser.yml to use HOMEBREW_TAP_TOKEN for homebrew-tap pushes
- Add release notes template at .goreleaser/release-notes-template.md
- Add comprehensive RELEASE_PROCESS.md documentation
- Fixes 403 error when publishing to homebrew-tap

This uses a fine-grained PAT with Contents:write permission scoped
only to randlee/homebrew-tap for better security than classic PAT.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(skill): make history skill portable with pass-by-reference pattern

- Remove hard-coded paths from SKILL.md, use 'claude-history' from PATH
- Add comprehensive installation guide to README.md with 5 install methods
- Add troubleshooting section for common issues
- Add 'Passing Agent to Subagents by Reference' section to SKILL.md
- Document 10x faster pattern for sharing explore agent analysis
- Add template for subagents to query previous agent work
- Brief note in SKILL.md pointing to README.md for installation

This makes the skill portable across systems and documents the powerful
pass-by-reference pattern for efficient agent coordination.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Phase 15: Query HTML format UX improvements (#42)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy

Added interactive tooltip when hovering over agent statistics in HTML
export header. Displays table of all agents with their message counts.

Features:
- Hover tooltip shows agent ID and message count for each agent
- Agents sorted by message count (descending)
- Click to copy agent list to clipboard
- Clipboard format: session ID + tab-separated agent list
- Smooth animations and visual feedback

Changes:
- Updated renderHTMLHeader() to include agent details as data attribute
- Added CSS styling for tooltip and copy feedback
- Created agent-tooltip.js for interactive behavior
- Enhanced click-to-copy with visual confirmation
- Fixed test calls to renderHTMLHeader() with new signature

Example tooltip:
  Agent Message Counts
  ━━━━━━━━━━━━━━━━━━
  a1b2c3d4    127
  a5b6c7d8     98
  ...

Clipboard output:
  session: 8c43ec84
  ---
  a1b2c3d4    127
  a5b6c7d8    98

Technical details:
- New JavaScript module: agent-tooltip.js
- CSS styles for .agent-stats-interactive, .agent-tooltip, .copy-feedback
- Data attributes: data-session-id, data-agent-details (JSON)
- Responsive tooltip positioning (auto-adjusts for screen edges)
- Dark mode support
- Mobile responsive
- Print styles (hides tooltip)

Testing:
- All unit tests pass
- Manual testing with 29-agent session confirmed:
  * Hover shows tooltip with agent list
  * Click copies to clipboard
  * Visual feedback displays
  * Tooltip positioning works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): flatten AGENT NOTIFICATION DOM structure (Phase 14)

Restructured task-notification rendering to use flattened 2-level DOM
instead of 4+ nested levels. Single-header design improves navigation
and debuggability.

Changes:
- Reduced nesting from message-row→bubble→content→notification to
  notification-row→header/content (2 levels)
- Single-line header: collapse-toggle | type | summary | agent-id
- Added CLI command tooltip to agent ID badge
- Enhanced copy button in agent ID badge
- Collapsible content with aria-expanded state
- Updated CSS for new flattened structure
- Added JavaScript for collapse toggle functionality

Benefits:
- Easier DOM navigation for debugging
- Simpler selection/search logic
- Reusable pattern for future components (User/Assistant grouping)
- Better accessibility (aria-expanded)

Example structure:
  ▼ | Subagent | Deep dive on Dog agent | [a41c57b] 📋

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): improve notification visibility and expand/collapse all

Fixed two issues with Phase 14 notifications:
1. Increased text contrast - notifications were appearing dim/disabled
2. Added notification support to Expand All / Collapse All buttons

Changes:
- Updated notification CSS colors for better contrast:
  - .notification-result: #9ca3af -> #d4d4d4 (brighter text)
  - .notification-usage: #6b7280 -> #9ca3af (improved readability)
  - .notification-header .timestamp: #6b7280 -> #9ca3af (less dim)
- Added .notification-header targeting to expandAllTools()
- Added .notification-header targeting to collapseAllTools()
- Notifications now respond to header Expand/Collapse All buttons

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use CSS variables for notification text colors

Root cause: Notifications used hardcoded dim colors (#9ca3af, #d4d4d4)
while rest of UI uses CSS variables (--text-primary, --text-secondary)
which are much brighter in dark mode.

Color comparison (dark mode):
- Old #9ca3af ≈ hsl(210 14% 65%) - very dim
- Old #d4d4d4 ≈ hsl(0 0% 83%) - dim
- New --text-primary = hsl(210 17% 95%) - bright
- New --text-secondary = hsl(210 11% 79%) - readable

Changes:
- .notification-summary: #d4d4d4 → var(--text-primary) (+12% brightness)
- .notification-result: #d4d4d4 → var(--text-primary) (+12% brightness)
- .agent-id-badge: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-usage: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-header .timestamp: #9ca3af → var(--text-secondary) (+14%)
- .collapse-toggle: #9ca3af → var(--text-secondary) (+14% brightness)

All notification text now matches the brightness of regular message content.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): copy full agent context from notifications

Changed notification copy button to include full context:
- Agent type and description
- Agent ID
- Full claude-history query command

Example copied text:
  Subagent "Deep dive on Dog agent" [ad19412]
  claude-history query /path/to/project --session 8c43ec84 --agent ad19412

This makes it easy to paste agent details into conversations with
Claude to reference specific subagents.

Also improved notification text brightness (95% -> 96%) for better
readability in dark mode.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use actual project path in copy and remove brackets

Fixed two issues:
1. Copy text now includes actual project path instead of <project-path>
2. Removed brackets from agent ID display (kept badge styling)

Before:
  Display: [ac8c7ba]
  Copy: claude-history query <project-path> ...

After:
  Display: ac8c7ba (with badge styling)
  Copy: claude-history query /path/to/project ...

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* wip: Phase 14 notification flattening changes

- Add HTML format to formatter.go
- Use RenderMarkdown for notification results
- Fix CSS color variables for proper contrast

* feat(query): add HTML export format (Phase 15)

Added --format html option to query command that generates and opens
an HTML page showing the filtered query results.

Usage:
  claude-history query /path/to/project --session <id> --agent <id> --format html

The HTML format reuses the existing export package renderers to ensure
consistent formatting with the full export command.

Features:
- Generates single HTML file with embedded CSS and JavaScript
- Auto-opens in default browser (macOS, Linux, Windows)
- Uses same markdown rendering as export command
- Includes all Phase 14 improvements (markdown, copy buttons, etc.)
- Simplified header without agent navigation (query-specific)

Implementation:
- Added RenderQueryResults() to pkg/export/html.go
- Added generateQueryHTML() helper to cmd/query.go
- Added openBrowser() cross-platform helper
- HTML file saved to temp directory with descriptive name

Testing:
- Tested with agent-specific queries
- Tested with session queries
- Tested with full project queries
- All existing tests pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(query): parameterize role labels for query HTML output

Problem: Query results showing "User/Assistant" for subagent queries was
misleading. In subagent context, roles should be "Orchestrator/Agent" to
reflect that the orchestrator (main agent) is prompting the subagent.

Solution:
- Added userLabel and assistantLabel parameters to RenderQueryResults()
- Added userLabel and assistantLabel parameters to renderEntry()
- Updated getRoleLabel() to accept custom role names
- Query command now passes "Orchestrator"/"Agent" for subagent queries
- Export command passes "User"/"Assistant" for full session exports
- Role labels displayed in both header stats and message headers

Testing:
- All existing tests pass with updated function signatures
- Verified subagent query shows "Orchestrator: 20 | Agent: 26"
- Verified session query shows "User: 244 | Assistant: 414"
- Verified export still uses "User"/"Assistant" labels

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: improve header layout and reduce vertical space

Changes:
- Update page titles: "Subagent Session" for subagent queries, "Claude Code Session" for full exports
- Move session folder to h1 title with clickable file:// link
- Remove separate "Project:" metadata line
- Reduce vertical spacing in header (padding, margins)
- Add folder-link styling with hover effects
- Update tests to reflect new structure

Implementation:
- Add SessionFolderPath field to SessionStats
- Add helper functions: extractSessionFolderName, buildFileURL
- Update RenderQueryResults and renderHTMLHeader to build folder links
- Pass sessionFolderPath through cmd layer
- Reduce CSS spacing: page-header padding, h1 margin, session-metadata margin

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: filter out empty message bubbles from HTML output

PROBLEM:
HTML export was showing empty message bubbles for:
1. Assistant messages with only whitespace (e.g., "\n\n")
2. Assistant messages with no text and no tool calls
3. User messages with no text and no tool results (BUG: these were being filtered)

The original hasContent() function was incorrectly filtering OUT user messages
that had tool results but no text content. These are valid messages that should
be displayed (they're the USER INPUT messages returning tool results to Claude).

INVESTIGATION:
Analyzed session 8c43ec84 JSONL file and found:
- Empty assistant messages: 4 with whitespace-only, several with no content at all
- User messages with tool results but no text: 189 (these were being incorrectly filtered)

BEFORE FIX: 361 messages rendered (missing 189 valid user messages with tool results)
AFTER FIX: 550 messages rendered (all valid messages, empty ones filtered)

FIX:
Added check in hasContent() for user messages with tool results:
- If entry.Type == user and has ExtractToolResults() > 0, return true
- This ensures user messages with tool results are always rendered
- Empty user messages (no text, no tool results) are still filtered

TESTING:
- Verified empty assistant messages are filtered: 389990a7, c55680df, 6e1459d2, 0dc6e932
- Verified user messages with tool results are now shown: 96f584e6
- Verified assistant messages with tool calls but no text still show: 0e58cabd
- All tests pass: go test ./...
- Export command works correctly
- Query command HTML output works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add clickable file paths to conversation text

Automatically detects and linkifies file paths in message text when they
exist on disk. Only creates links for files that actually exist to avoid
false positives.

**Path Detection**:
- Absolute Unix paths: /path/to/file.ext
- Absolute Windows paths: C:\path\to\file.ext
- Relative paths with prefix: ./file.go, ../pkg/export.go
- Relative paths with directories: src/main.go
- Simple filenames: test.go (when projectPath is available)

**Implementation**:
- New paths.go module with regex-based path detection
- Integrated into markdown rendering pipeline via placeholders
- Paths are resolved relative to projectPath for relative paths
- File existence check before creating links
- Uses file:// URL format for links

**Limitations**:
- Does not support paths with spaces (to avoid false positives)
- Code blocks are protected from path detection (via placeholder system)
- Only detects paths followed by whitespace or punctuation

**CSS Styling**:
- .file-link class with dotted underline
- Hover effect with light blue background
- Consistent with existing .folder-link styling

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: correct agent IDs in message headers and enhance copy context

This commit addresses critical issues with agent ID display and copy functionality in HTML query results:

**Agent ID Display Fixes:**
- ORCHESTRATOR messages now show session ID (parent) instead of subagent ID
- AGENT messages correctly show subagent ID
- Removed literal brackets `[` `]` from agent ID display
- Applied badge styling (`.agent-id-badge`) matching notification badges
- Right-aligned agent ID badges in message headers using flexbox

**Copy Context Enhancements:**
- Session ID copy: Includes session ID, project path, and full CLI command
- Message agent ID copy: Includes role, agent ID, session context, and appropriate CLI command
- ORCHESTRATOR messages: Copy context includes session-only query command
- AGENT messages: Copy context includes session + agent query command

**Technical Changes:**
- Updated `renderEntry()` signature to accept sessionID and agentID parameters
- Added `determineDisplayAgentID()` to compute correct agent ID based on message role
- Added `buildAgentIDCopyContext()` to generate contextual copy text for agent IDs
- Added `buildSessionCopyContext()` to generate contextual copy text for session IDs
- Updated CSS for `.agent-id-badge` styling and positioning
- Updated all tests to reflect new badge styling and copy context behavior

**Testing:**
- All unit tests pass
- Verified with `query --session --agent` command
- Confirmed correct agent IDs in both ORCHESTRATOR and AGENT messages
- Confirmed copy buttons include full context with CLI commands

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* test: add automated detection for empty message bubbles

**Investigation Summary**
- Analyzed 103 subagent entries and 1425 main session entries
- Found 0 empty bubbles in current codebase
- Current hasContent() function correctly filters all empty cases

**Automated Tests Added**

1. **TestNoEmptyMessageBubbles** - Query results (subagent)
   - Tests RenderQueryResults with real session data
   - Parses HTML and verifies no empty message-content divs
   - Reports which entries would create empty bubbles if found

2. **TestNoEmptyMessageBubblesFullExport** - Full export path
   - Tests RenderConversation with full session data
   - Validates both query and export code paths
   - Tested with 1425 entries, 381 rendered

3. **TestHasContentEdgeCases** - Comprehensive edge cases
   - User messages with ONLY tool results → filtered ✓
   - Messages with only whitespace → filtered ✓
   - Empty messages → filtered ✓
   - Assistant messages with tool calls → rendered ✓
   - 10 edge cases covered with explanations

4. **check-empty-bubbles.sh** - Shell script alternative
   - Scans HTML for empty message-content divs
   - Can be run manually or in CI
   - Exit 1 if empty bubbles found

**hasContent() Filtering Rules**
The function correctly filters out:
- User messages with ONLY tool results (not rendered in HTML)
- Any message with only whitespace (spaces, tabs, newlines)
- Empty messages
- System/Queue messages with no content

**Results**
- Current codebase: 0 empty bubbles found
- All edge cases: passing
- Future PRs: protected by automated tests
- Can run: go test ./pkg/export -run Empty

**Files Added**
- src/pkg/export/html_empty_test.go (query path)
- src/pkg/export/html_empty_full_test.go (export path)
- src/pkg/export/html_empty_edgecases_test.go (edge cases)
- scripts/check-empty-bubbles.sh (CLI detection)

* refactor(export): DRY HTML rendering and fix copy buttons to use full IDs

PART 1: Fix Copy Buttons to Use Full IDs
- All copy buttons now include full context (session/agent ID + project path + CLI command)
- Display still shows truncated IDs (8 chars) for clean UI
- Copy text includes FULL IDs to prevent collision risk (birthday paradox)
- Fixed locations:
  * Session ID copy buttons: Now use buildSessionCopyContext()
  * Agent ID copy buttons: Now use buildAgentIDCopyContext()
  * Subagent placeholders: Now use renderSubagentBadgeWithCopy()
  * Notification badges: Already using full context (correct)

PART 2: DRY Refactoring - Single Source of Truth
New helper functions created:
- renderSessionIDWithCopy(): Session ID badge with full copy context
- renderAgentIDWithCopy(): Agent ID badge with full copy context
- renderSubagentBadgeWithCopy(): Subagent badge with full copy context
- renderFileLink(): Clickable file:// links for Finder/Explorer
- truncateID(): Unified ID truncation (consolidated TruncateSessionID)

Duplication eliminated:
- Session ID rendering: 2 locations → 1 helper function
- Agent ID badge rendering: 3 locations → 2 helper functions
- File link rendering: 2 locations → 1 helper function
- ID truncation: 2 functions → 1 unified function

Benefits:
- Consistency: All copy buttons use same format
- Maintainability: Changes to copy format happen in ONE place
- Safety: Full IDs prevent collision issues
- UX: Clean truncated display, comprehensive copy text
- Documentation: Helper functions explain WHY we use full IDs

Stats:
- Lines changed: 107 additions, 49 deletions
- Functions added: 4 new helpers
- Test updates: 5 files updated to match new format
- All tests passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: show tool type in message header for tool-only messages

Changes:
- Modified renderEntry() to detect tool-only assistant messages (no text, only tool calls)
- Changed role label from "Assistant" to "TOOL: <tool-name>" for tool-only messages
- Added inline tool summary in header showing:
  - Bash: command (first 60 chars)
  - Task: description
  - Read/Write: file path
  - Grep: pattern
  - Others: tool name only
- Added CSS styles for .tool-only-label and .tool-summary-inline
- Modified hasContent() to keep tool-only messages (previously filtered out)
- Added comprehensive tests for tool-only message rendering

Impact:
- Tool-only messages are now visible with clear indication of what tool was called
- Inline summaries provide quick context without expanding tool details
- Messages with text + tools still show normal "Assistant" label

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: enable file path linkification in conversation text

The file path linkification feature was not working because paths were
wrapped in inline code backticks (e.g., `/path/to/file.go`). The inline
code processing happened BEFORE file path detection, causing paths to be
replaced with placeholders before they could be linkified.

This commit fixes the issue by processing file paths WITHIN inline code
blocks, before they are escaped and converted to placeholders. Now paths
that exist on disk are converted to clickable file:// links even when
they appear in inline code.

Changes:
- Modified RenderMarkdown() to call makePathsClickable() on inline code
  content before escaping it
- Paths are detected and converted to links within the inline code string
- The resulting HTML (with links) is then wrapped in inline-code styling

Result:
- File links increased from 3 to 113+ in test export
- Paths like /Users/name/project/internal/file.go are now clickable
- Links work correctly when clicked (open in Finder/Explorer)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): Phase 15 UX improvements

- Remove "Main Session" badge from header (saves vertical space)
- Add tool-only compact styling (reduced message-bubble padding)
- Make file paths in tool headers clickable (Read/Write/Edit tools)
- Add meaningful inline summaries for TaskUpdate/TaskCreate/TaskGet/TaskList
- Increase clickable path width from 300px to 600px
- Hide collapsed tool content for tool-only messages to save space

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): remove Main Session breadcrumb and compact tool-only messages

- Remove "Main Session" breadcrumb from navigation.js JavaScript
- Hide empty breadcrumbs nav completely to save vertical space
- Make tool-only message headers clickable to expand/collapse
- Hide message-content by default for tool-only messages (single line)
- Remove box/background styling from tool labels (plain text like ORCHESTRATOR/AGENT)
- Add version marker [v15.3] to page header for cache verification
- Increase clickable file path width from 300px to 600px

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: bump version to 0.3.0-dev

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: update HTML version marker to v0.3.0

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(version): single source of truth for version number with unit test

- Create pkg/version package with Version constant (0.3.0)
- Update main.go to import and use version.Version as default
- Update html.go to dynamically insert version into HTML header
- Add TestVersionConsistency to verify no hardcoded versions
- Add TestVersionFormat to validate semantic versioning
- Update tests to check for version-suffixed title

All version references now use version.Version constant.
GoReleaser can still override via ldflags during release builds.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: resolve linter issues (errcheck and gofmt)

- Fix errcheck warnings in paths_test.go (defer cleanup error handling)
- Run gofmt on html.go and task_notification_test.go
- All linter checks now pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(test): skip Unix path tests on Windows

Windows temp files use Windows path format (C:\...) which these tests
weren't designed for. The path detection itself supports Windows paths
via winAbsPathRe, but these specific tests use tmpFile.Name() which
returns platform-specific paths.

Fix by skipping Unix path tests on Windows platform.

Related: PR #42, Phase 15 Windows CI failure

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: comprehensive Phase 15 documentation update

Critical fixes:
- Remove non-existent --template flag from export command
- Fix --output description (directory not file)
- Add CHANGELOG.md v0.3.0 entry with Phase 15 features
- Update skill docs to remove deprecated --open flag

Additions:
- Document --format html for query command
- Document --include-agents flag with examples
- Document --limit flag for query output control
- Add Phase 15 section to PROJECT_PLAN.md
- Mark Phase 10 Wave 3 as complete

Files updated:
- README.md: Query HTML format, subagent flags, export fixes
- CHANGELOG.md: Complete v0.3.0 release notes
- docs/PROJECT_PLAN.md: Phase 15 completion, version 2.11
- .claude/skills/history/SKILL.md: Remove deprecated flags

Related: Phase 15 documentation audit, PR #42

* docs(release): update RELEASE_PROCESS for v0.3.0+ with working Homebrew

- Add version status section (v0.2.0 broken, v0.3.0+ works)
- Update availability table to show Homebrew as automatic
- Change post-release tasks to reflect Homebrew is now automatic (verify only)
- Update troubleshooting to cover 403 errors with HOMEBREW_TAP_TOKEN
- Remove outdated 'tap doesn't exist' troubleshooting
- Clarify that fine-grained PAT is configured and working

The document now describes the correct state for v0.3.0 and later releases
where Homebrew publishing works automatically via GitHub Actions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: update .gitignore to exclude build artifacts

- Ignore claude-history binary in root directory
- Ignore INTEGRATION_TESTS_SUMMARY.md (auto-generated test output)

These files were accidentally tracked and should be build/test artifacts.

* docs: update issues tracker to reflect completed Phases 11-15

All backlog items from original tracker have been resolved:
- Phase 11: Search, expand/collapse fixes (PR #37)
- Phase 12: Enhanced statistics (PR #38)
- Phase 13: Agent tooltips (PR #39)
- Phase 14: DOM structure improvements (PR #40)
- Phase 15: Query HTML & UX (PR #42)

Total: 0 active issues, 6 resolved, ready for new feature requests.

* docs: add comprehensive examples with HTML exports

Created two example exports demonstrating claude-history capabilities:

Example 1: Simple Session (claude-history-simple)
- 13 messages, 9 agents
- Shows basic session navigation and structure
- 3.1MB complete HTML export with lazy-loaded agents

Example 2: Large Session with Subagents (claude-history-subagents)
- 2041 messages, 90 agents
- Demonstrates complex multi-agent workflows
- 25MB complete HTML export showing deep agent hierarchy

Documentation:
- docs/examples/README.md - Overview and quick start
- docs/examples/VIEWING.md - Cross-platform viewing guide
- Each example has detailed README with exact commands used

Both examples use actual HTML exports from real claude-history
development sessions, providing reproducible demonstrations of
export capabilities.

Features demonstrated:
- Interactive navigation with lazy-loaded subagents
- Search and expand/collapse functionality
- Copy-to-clipboard for agent resurrection
- Session metadata and statistics
- Clickable file paths and URLs
- Tool-only message display
- Agent hierarchy visualization

Total: 146 files (2 examples × complete exports + documentation)

* feat(release): add automated winget publishing via winget-releaser

- Add winget-releaser@v2 action to release workflow
- Automatically creates PR to microsoft/winget-pkgs after each release
- Updates RELEASE_PROCESS.md to reflect winget as automated (~1-2 days)
- Change winget from 'manual' to 'automatic - monitor only'
- Update version status: v0.3.0+ has both Homebrew and winget automated

The workflow now handles both Homebrew (immediate) and winget (PR created
automatically, requires Microsoft approval ~1-2 days) publishing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(release): remove invalid header_template_file field

GoReleaser v1.26.2 does not support header_template_file field.
Removed to allow automatic release notes generation from CHANGELOG.

* ci: add GoReleaser config validation

Add comprehensive validation for GoReleaser configuration to prevent
release failures from configuration errors.

Changes:
- Add GitHub Actions workflow (.github/workflows/validate-config.yml)
  that runs on pushes to main/develop and on PRs
- Add local validation script (scripts/validate-goreleaser.sh) that:
  - Runs 'goreleaser check' for syntax validation
  - Performs snapshot build to validate full configuration
  - Checks for deprecated/invalid fields (e.g., header_template_file)
  - Verifies required files exist
- Add optional pre-commit hook template (scripts/pre-commit-hook.sh)
- Add test script (scripts/test-validation.sh) to verify validation
  catches known errors
- Update docs/RELEASE_PROCESS.md with validation steps and
  troubleshooting for config errors
- Update README.md with validation instructions

This validation would have caught the header_template_file error that
caused the v0.3.2 release failure.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: add winget manifest files for v0.3.0

- Created initial winget manifest for microsoft/winget-pkgs
- Includes installer, locale, and version manifests
- PR submitted: https://github.com/microsoft/winget-pkgs/pull/337541

* docs: update release process for winget setup

- Note winget manifest submitted for v0.3.0
- Update version status to reflect pending approval
- Add PR link for tracking

* feat: add history skill metadata infrastructure

- Create .sc/history/ for skill metadata
- Add bookmarks.jsonl for agent bookmarking
- Add README.md documenting metadata structure
- Bookmark agent-design-expert (a47c2de) - first reusable agent
  - Expert in agent design best practices
  - Analyzed guidelines-0.4.md and tool-use-best-practices.md
  - Available for reviewing future agent prompts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add history-search agent v0.1.0

Implements fuzzy search across Claude Code agent history.

Key features:
- PreToolUse hooks for Bash validation
- Path safety validation (allowed directories only)
- Fuzzy matching with weighted scoring (query 40%, time 25%, type 20%, project 15%)
- Confidence scores and match_reasons for transparency
- Standard maturity level with full response envelope
- Timeout: 120s, max 50 tool calls

Security improvements:
- Path sanitization to prevent shell injection
- Validates against allowed directories
- PreToolUse hooks for command validation

Addresses agent-design-expert review (82/100 -> targeting 90+):
- Added PreToolUse hooks (HIGH priority)
- Added path safety validation (HIGH priority)
- Clarified execution order in Step 3
- Kept fuzzy matching in-agent per user direction

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: history-search agent uses Grep/Glob/Read tools

Major design correction based on user feedback:
- Agent searches raw JSONL files using Grep/Glob/Read tools
- Does NOT call claude-history CLI (that's for users, not agents)
- Searches ~/.claude/projects/ directory structure directly
- Parses queue-operation entries to find agent spawns
- Returns multiple candidates weighted by search criteria

Key insight: If session_id + agent_id known, resurrection is trivial.
This agent's job is to FIND those IDs when unknown.

Search process:
1. Glob to find session JSONL files
2. Grep for queue-operation entries with query keywords
3. Check for subagent files
4. Extract metadata and rank by weighted criteria
5. Return top N candidates with confidence scores

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add advanced search examples to history-search v0.2.0

Added 4 new CLI examples covering:
- Example 7: Find Explore subagents (filter by subagent_type)
- Example 8: Find agents that used specific tool (--tool bash)
- Example 9: Find agents that accessed specific file (--tool-match package.json)
- Example 10: Find agents that accessed file patterns (--tool-match regex)

Now covers all use cases:
✓ Search by project path
✓ Search by date range
✓ Search by agent type (Explore, general-purpose, etc.)
✓ Search by tool used (Bash, Read, Write, etc.)
✓ Search by file accessed (specific files or patterns)

Agent learns through 10 concrete, non-redundant examples.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add PreToolUse hook for CLI validation

Implements MEDIUM priority issue from agent-design-expert review.

PreToolUse hook checks if claude-history CLI is installed:
- Runs before any Bash tool execution
- Exit code 2 blocks execution if tool missing
- Provides clear error message with:
  - Explanation of requirement
  - Relative path to README.md (../../README.md from skill folder)
  - Quick install instructions

Improves user experience by failing fast with actionable guidance
instead of cryptic Bash errors.

Score expected to reach 95/100 (production-ready).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: correct README path in PreToolUse hook

Path should be relative to repo root:
  .claude/skills/history/README.md

(not ../../README.md which was relative to agent file location)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor: move agent to correct location and remove runtime files

Correct plugin structure:
- Agents: .claude/agents/history-search.md (was in .sc/)
- Scripts: .claude/scripts/ (for Python scripts)
- Skills: .claude/skills/history/ (to be created)

Runtime data (not in plugin):
- .sc/history/ created by agents at runtime
- Added .sc/ to .gitignore

Files moved:
- .sc/history/agents/history-search-v2.md → .claude/agents/history-search.md

Files removed (runtime only):
- .sc/history/bookmarks.jsonl (created by agents)
- .sc/history/README.md (not needed)

When plugin is installed, files are dropped into target repo
at these locations. Runtime data is generated by agents.

Co-Authored-By: Claude Sonnet 4.5…
randlee added a commit to randlee/claude-history that referenced this pull request Feb 9, 2026
* fix(export): resolve session file lookup issue

The export command was failing to locate session JSONL files even when
the list command found them. The issue was in the path resolution logic:
ExportSession was using the original session ID without resolving prefixes.

This mirrors how the list command works - both now support git-style
prefix matching for session IDs. Updated ExportSession to call
resolver.ResolveSessionID before attempting file lookup.

Added TestExport_SessionResolution to prevent regression. Updated
existing tests to use valid UUID format session IDs instead of
arbitrary string IDs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add GoReleaser, install script, and /history skill

- Add GoReleaser config for multi-platform builds (Linux, macOS, Windows)
- Add GitHub Actions workflow for automated releases on tag push
- Add universal install.sh script for easy installation
- Add version support to CLI (--version flag)
- Add /history Claude Code skill for querying agent history
  - SKILL.md with YAML frontmatter and comprehensive examples
  - README.md with usage documentation
  - Supports all claude-history commands (list, query, tree, find-agent, export)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: remove extra blank line for gofmt compliance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): HTML quality improvements for Phase 10 (#31)

* fix(export): resolve session file lookup issue

The export command was failing to locate session JSONL files even when
the list command found them. The issue was in the path resolution logic:
ExportSession was using the original session ID without resolving prefixes.

This mirrors how the list command works - both now support git-style
prefix matching for session IDs. Updated ExportSession to call
resolver.ResolveSessionID before attempting file lookup.

Added TestExport_SessionResolution to prevent regression. Updated
existing tests to use valid UUID format session IDs instead of
arbitrary string IDs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(export): skip empty messages and add chat bubble alignment

- Add hasContent() helper to skip rendering entries with no text/tools
- Update CSS to right-align user messages and left-align assistant messages
- Update tests to reflect new empty-message-skipping behavior
- Queue operations without content still render subagent placeholders

Fixes #5 (skip empty message blocks)
Fixes #2 (right/left align chat bubbles)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): increase viewport width and normalize text spacing

- Increase conversation container max-width from 900px to 1400px for better content density
- Collapse consecutive empty lines in markdown rendering to prevent excessive vertical spacing
- Both changes improve readability and use of screen real estate

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): add collapse/expand controls and improve color scheme

Task 1: Add collapse/expand controls (#4)
- Add chevron indicators (▼) to tool and subagent headers
- Add collapsed/collapsible classes to tool-call and subagent elements
- Update toggleTool() to toggle collapsed state on parent container
- Update loadAgent() to toggle collapsed state on subagent container
- Add CSS rules for chevron rotation based on collapsed state
- Items start collapsed by default

Task 2: Improve color scheme (#6)
- User messages: softer blue (hsl(210, 100%, 95%))
- Assistant messages: light neutral gray (hsl(0, 0%, 96%))
- Tool overlays: improved teal contrast (hsl(172, 45%, 96%))
- Agent overlays: improved purple contrast (hsl(270, 80%, 97%))
- System overlays: improved amber contrast (hsl(48, 100%, 95%))
- Better visual contrast and professional appearance

Updated tests to match new HTML structure with collapsible classes.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(test): resolve TestHTMLOutput_ValidStructure failure

The test was expecting `<div class="tool-call"` with a closing quote,
but the actual HTML output has additional CSS classes:
`<div class="tool-call collapsible collapsed"`. Changed the test
expectation to match the opening portion without the closing quote,
allowing it to match regardless of additional classes.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): make chevron indicators visible

- Add explicit color, font-size, and opacity to .chevron class
- Chevrons were present but invisible due to missing color styling
- Now visible as intended for collapse/expand functionality

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: resolve lint issues for gofmt compliance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Add --limit flag to control text truncation in query output (#33)

* fix: add --limit flag to control text truncation in query output

Fixes agent output truncation bug that broke pass-by-reference workflows.

Changes:
- Add --limit flag (default: 100, 0 = no limit)
- Update WriteEntries() to accept limit parameter
- Update writeEntryList() to respect limit (0 = full content)
- Add examples to help text showing --limit 0 usage

Before: Agent analysis truncated at 100 chars ("## BEA...")
After: Full content available with --limit 0

Use cases:
- claude-history query --limit 0  (full content, no truncation)
- claude-history query --limit 500 (custom truncation)
- Default behavior unchanged (100 chars for backward compatibility)

Critical for pass-by-reference pattern where agents query previous
agent work and need complete analysis, not truncated snippets.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: filter out empty text entries from query output

Skip entries with no text content (tool-use only, progress, etc.)
to reduce clutter in text format output.

Before: Many empty lines between messages
After: Only lines with actual text content shown

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add smart preview mode for default text output

Shows first entry, count, and last entry preview with exact command
for full output. Makes default behavior much more useful for agents.

Default output now shows:
- First entry (confirms query worked)
- Entry count: '... (N more entries) ...'
- Last entry with first 10 lines of text
- Clear truncation marker: '... (10 of 842 lines shown - TRUNCATED)'
- Exact working command: '--format json | jq -r ...'

Full output modes still work:
- --limit 0: All entries in text format
- --format json: Structured data for agents
- Custom --limit N: Truncate at N chars

This gives agents immediate recognition that content is truncated
and the exact command to retry for full content.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): improve HTML quality - hide empty blocks and format XML tags (#34)

* fix: remove empty assistant blocks and improve user content formatting

Fixes HTML export rendering issues:

1. Filter empty assistant blocks
   - Added whitespace trimming in hasContent() check
   - Entries with only whitespace no longer render
   - Tool calls still render even with whitespace-only text

2. Fixed user content XML formatting
   - Fixed Go regexp compatibility (removed backreferences)
   - Improved spacing for bash-stdout/bash-stderr blocks

3. Added comprehensive tests
   - TestRenderConversation_WhitespaceOnlyContent
   - TestRenderConversation_AssistantWithOnlyToolCalls
   - Test coverage for user content formatting

Results in cleaner HTML exports with less wasted space.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* test: fix integration test JSON encoding for newlines

Fixed TestUserContentWithBashOutput and TestUserContentMixedContent
to properly escape newlines in JSON strings. Raw newlines in JSON
string literals cause "invalid character '\n' in string literal" errors.

Changes:
- Use \n escape sequences instead of literal newlines in JSON
- All export tests now pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): resolve gofmt and staticcheck issues

- Fix formatting in html.go, task_notification_test.go, and user_content_test.go
- Convert if-else chain to tagged switch statement for data.Status check
- Align struct fields and comments to match gofmt standards

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* release: prepare for v0.1.0 initial public release

Prepare the repository for the first official release (v0.1.0):

Changes:
- Updated CHANGELOG.md with v0.1.0 release notes
  - Consolidated all Phase 10 features and fixes
  - Documented query enhancements, HTML export quality improvements
  - Included CI/lint fixes and integration test corrections
- Added docs/issues.md for Phase 11-12 sprint planning
  - 6 issues tracked (P0-P2 priorities)
  - Sprint 1: Critical fixes (search, expand/collapse, newlines)
  - Sprint 2: URL enhancements (clickable links, file paths)
- Updated .gitignore to exclude worktrees directory

Ready for tagging v0.1.0 and PR to main.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(release): add Homebrew tap publishing (#35)

Configure GoReleaser to automatically publish to Homebrew tap.

Changes:
- Added brews section to .goreleaser.yml
  - Target repository: randlee/homebrew-tap
  - Auto-generates Formula/claude-history.rb
  - Includes test command for verification
- Updated release notes to prioritize Homebrew installation
- Added docs/HOMEBREW_SETUP.md with setup instructions

User Installation (after next release):
  brew tap randlee/tap
  brew install claude-history

Notes:
- GoReleaser will auto-create the homebrew-tap repository
- Formula updates automatically on each release
- Works on macOS and Linux
- No Homebrew account required

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(release): update GoReleaser hooks to run from src directory

GoReleaser runs from repo root, but go.mod is in src/.
Updated before.hooks to cd into src before running go commands.

Fixes v0.1.0 release failure:
  error=hook failed: shell: 'go mod tidy': exit status 1:
  go: go.mod file not found in current directory

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(release): specify build directory in GoReleaser config

Added 'dir: ./src' to builds section so Go can find go.mod.
Changed main from './src' to '.' since we're now in src/ dir.

Fixes build error:
  failed to build: go: cannot find main module

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(winget): add Windows Package Manager support

Creates winget manifest for Windows users to install via:
  winget install randlee.claude-history

Changes:
- Added .winget/ directory with installer manifest
- Created docs/WINGET_SETUP.md with submission instructions
- Updated README.md with winget installation method

To publish:
1. After v0.2.0 release, get SHA256 from GitHub Release
2. Update .winget/randlee.claude-history.yaml with SHA256
3. Submit PR to microsoft/winget-pkgs repository

No winget account or API keys required!

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): Resolve critical HTML export issues (Phase 11) (#37)

* fix(export): resolve critical HTML export issues (Phase 11)

Fixes three critical issues in HTML export:

1. Search functionality (P0)
   - Fixed CSS selector mismatch in controls.js
   - Changed .entry -> .message-row
   - Changed .content -> .message-content
   - Search now properly highlights and navigates matches

2. Newlines being doubled (P1)
   - Fixed markdown.go line 660
   - Join with empty string instead of \n
   - Prevents double line breaks when CSS pre-wrap is active

3. Expand/Collapse All buttons (P1)
   - Added support for <details> elements in controls.js
   - expandAllTools() and collapseAllTools() now handle both
     .tool-body class-based AND native <details> elements

All tests passing. Manual verification confirmed fixes work.

Resolves issues from docs/issues.md Phase 11.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): prevent double-escaping of HTML entities in markdown

Fixed issue where HTML entities like &#34; were being escaped twice,
resulting in literal display of entity codes (e.g., &amp;#34;) instead
of the intended characters (e.g., ").

Root cause: The RenderMarkdown function was calling escapeHTML() on
text content during header, list, table, and blockquote processing,
then calling escapeRemainingText() which escaped everything again.
This caused quotes to go from " → &#34; → &amp;#34;.

Solution: Removed redundant escapeHTML() calls from markdown element
processing functions. The escapeRemainingText() function now handles
all HTML escaping in a single pass, preventing double-escaping while
maintaining XSS protection.

Changes:
- Headers (h1-h6): Remove escapeHTML() from content
- Bold/italic: Remove escapeHTML() from content
- Tables (th/td): Remove escapeHTML() from cell content
- Lists (ul/ol/task): Remove escapeHTML() from list item content
- Blockquotes: Remove escapeHTML() from quoted text

Example:
Before: Results: &amp;#34;beads&amp;#34; References in Gastown
After:  Results: &#34;beads&#34; References in Gastown
        (renders as: Results: "beads" References in Gastown)

Tested:
- All export package tests pass
- XSS protection still works (< > & " ' are still escaped)
- HTML entities now render correctly in browsers
- Session 8c43ec84 export verified: 0 double-escaped entities

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): show session start time and duration instead of export time

Replaced "Exported: [time]" in HTML header with more valuable info:
- Session start time (when conversation began)
- Duration (how long the session lasted)

Changes:
- Added SessionStart, SessionEnd, Duration to SessionStats struct
- Updated ComputeSessionStats to extract first/last entry timestamps
- Added formatDuration helper for human-readable duration (e.g., "2h 35m")
- Updated renderHTMLHeader to display new fields instead of export time
- Modified cmd/export.go to pass ProjectPath in stats object
- Fixed timestamp parsing to handle entries without timestamps
- Added comprehensive tests for new functionality

Example header now shows:
  Session: 8c43ec84
  Project: /Users/randlee/Documents/github/github-research
  Started: 2026-02-06 20:37
  Duration: 8h 35m
  Messages: 658
  Agents: 0
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): fix agent count and enhance message statistics (Phase 12) (#38)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy (Phase 13) (#39)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy

Added interactive tooltip when hovering over agent statistics in HTML
export header. Displays table of all agents with their message counts.

Features:
- Hover tooltip shows agent ID and message count for each agent
- Agents sorted by message count (descending)
- Click to copy agent list to clipboard
- Clipboard format: session ID + tab-separated agent list
- Smooth animations and visual feedback

Changes:
- Updated renderHTMLHeader() to include agent details as data attribute
- Added CSS styling for tooltip and copy feedback
- Created agent-tooltip.js for interactive behavior
- Enhanced click-to-copy with visual confirmation
- Fixed test calls to renderHTMLHeader() with new signature

Example tooltip:
  Agent Message Counts
  ━━━━━━━━━━━━━━━━━━
  a1b2c3d4    127
  a5b6c7d8     98
  ...

Clipboard output:
  session: 8c43ec84
  ---
  a1b2c3d4    127
  a5b6c7d8    98

Technical details:
- New JavaScript module: agent-tooltip.js
- CSS styles for .agent-stats-interactive, .agent-tooltip, .copy-feedback
- Data attributes: data-session-id, data-agent-details (JSON)
- Responsive tooltip positioning (auto-adjusts for screen edges)
- Dark mode support
- Mobile responsive
- Print styles (hides tooltip)

Testing:
- All unit tests pass
- Manual testing with 29-agent session confirmed:
  * Hover shows tooltip with agent list
  * Click copies to clipboard
  * Visual feedback displays
  * Tooltip positioning works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): flatten AGENT NOTIFICATION DOM structure (Phase 14) (#40)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy

Added interactive tooltip when hovering over agent statistics in HTML
export header. Displays table of all agents with their message counts.

Features:
- Hover tooltip shows agent ID and message count for each agent
- Agents sorted by message count (descending)
- Click to copy agent list to clipboard
- Clipboard format: session ID + tab-separated agent list
- Smooth animations and visual feedback

Changes:
- Updated renderHTMLHeader() to include agent details as data attribute
- Added CSS styling for tooltip and copy feedback
- Created agent-tooltip.js for interactive behavior
- Enhanced click-to-copy with visual confirmation
- Fixed test calls to renderHTMLHeader() with new signature

Example tooltip:
  Agent Message Counts
  ━━━━━━━━━━━━━━━━━━
  a1b2c3d4    127
  a5b6c7d8     98
  ...

Clipboard output:
  session: 8c43ec84
  ---
  a1b2c3d4    127
  a5b6c7d8    98

Technical details:
- New JavaScript module: agent-tooltip.js
- CSS styles for .agent-stats-interactive, .agent-tooltip, .copy-feedback
- Data attributes: data-session-id, data-agent-details (JSON)
- Responsive tooltip positioning (auto-adjusts for screen edges)
- Dark mode support
- Mobile responsive
- Print styles (hides tooltip)

Testing:
- All unit tests pass
- Manual testing with 29-agent session confirmed:
  * Hover shows tooltip with agent list
  * Click copies to clipboard
  * Visual feedback displays
  * Tooltip positioning works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): flatten AGENT NOTIFICATION DOM structure (Phase 14)

Restructured task-notification rendering to use flattened 2-level DOM
instead of 4+ nested levels. Single-header design improves navigation
and debuggability.

Changes:
- Reduced nesting from message-row→bubble→content→notification to
  notification-row→header/content (2 levels)
- Single-line header: collapse-toggle | type | summary | agent-id
- Added CLI command tooltip to agent ID badge
- Enhanced copy button in agent ID badge
- Collapsible content with aria-expanded state
- Updated CSS for new flattened structure
- Added JavaScript for collapse toggle functionality

Benefits:
- Easier DOM navigation for debugging
- Simpler selection/search logic
- Reusable pattern for future components (User/Assistant grouping)
- Better accessibility (aria-expanded)

Example structure:
  ▼ | Subagent | Deep dive on Dog agent | [a41c57b] 📋

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): improve notification visibility and expand/collapse all

Fixed two issues with Phase 14 notifications:
1. Increased text contrast - notifications were appearing dim/disabled
2. Added notification support to Expand All / Collapse All buttons

Changes:
- Updated notification CSS colors for better contrast:
  - .notification-result: #9ca3af -> #d4d4d4 (brighter text)
  - .notification-usage: #6b7280 -> #9ca3af (improved readability)
  - .notification-header .timestamp: #6b7280 -> #9ca3af (less dim)
- Added .notification-header targeting to expandAllTools()
- Added .notification-header targeting to collapseAllTools()
- Notifications now respond to header Expand/Collapse All buttons

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use CSS variables for notification text colors

Root cause: Notifications used hardcoded dim colors (#9ca3af, #d4d4d4)
while rest of UI uses CSS variables (--text-primary, --text-secondary)
which are much brighter in dark mode.

Color comparison (dark mode):
- Old #9ca3af ≈ hsl(210 14% 65%) - very dim
- Old #d4d4d4 ≈ hsl(0 0% 83%) - dim
- New --text-primary = hsl(210 17% 95%) - bright
- New --text-secondary = hsl(210 11% 79%) - readable

Changes:
- .notification-summary: #d4d4d4 → var(--text-primary) (+12% brightness)
- .notification-result: #d4d4d4 → var(--text-primary) (+12% brightness)
- .agent-id-badge: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-usage: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-header .timestamp: #9ca3af → var(--text-secondary) (+14%)
- .collapse-toggle: #9ca3af → var(--text-secondary) (+14% brightness)

All notification text now matches the brightness of regular message content.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): copy full agent context from notifications

Changed notification copy button to include full context:
- Agent type and description
- Agent ID
- Full claude-history query command

Example copied text:
  Subagent "Deep dive on Dog agent" [ad19412]
  claude-history query /path/to/project --session 8c43ec84 --agent ad19412

This makes it easy to paste agent details into conversations with
Claude to reference specific subagents.

Also improved notification text brightness (95% -> 96%) for better
readability in dark mode.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use actual project path in copy and remove brackets

Fixed two issues:
1. Copy text now includes actual project path instead of <project-path>
2. Removed brackets from agent ID display (kept badge styling)

Before:
  Display: [ac8c7ba]
  Copy: claude-history query <project-path> ...

After:
  Display: ac8c7ba (with badge styling)
  Copy: claude-history query /path/to/project ...

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* wip: Phase 14 notification flattening changes

- Add HTML format to formatter.go
- Use RenderMarkdown for notification results
- Fix CSS color variables for proper contrast

* chore: remove unused imports from query.go

Remove unused os/exec, runtime, and export package imports
that were left over from merge conflict resolution.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: resolve lint issues

Fixed gofmt formatting issue in task_notification_test.go where line 305
had incorrect indentation (mixed spaces/tabs).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(release): add fine-grained PAT for homebrew tap publishing

- Add HOMEBREW_TAP_TOKEN environment variable to release workflow
- Update .goreleaser.yml to use HOMEBREW_TAP_TOKEN for homebrew-tap pushes
- Add release notes template at .goreleaser/release-notes-template.md
- Add comprehensive RELEASE_PROCESS.md documentation
- Fixes 403 error when publishing to homebrew-tap

This uses a fine-grained PAT with Contents:write permission scoped
only to randlee/homebrew-tap for better security than classic PAT.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(skill): make history skill portable with pass-by-reference pattern

- Remove hard-coded paths from SKILL.md, use 'claude-history' from PATH
- Add comprehensive installation guide to README.md with 5 install methods
- Add troubleshooting section for common issues
- Add 'Passing Agent to Subagents by Reference' section to SKILL.md
- Document 10x faster pattern for sharing explore agent analysis
- Add template for subagents to query previous agent work
- Brief note in SKILL.md pointing to README.md for installation

This makes the skill portable across systems and documents the powerful
pass-by-reference pattern for efficient agent coordination.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Phase 15: Query HTML format UX improvements (#42)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy

Added interactive tooltip when hovering over agent statistics in HTML
export header. Displays table of all agents with their message counts.

Features:
- Hover tooltip shows agent ID and message count for each agent
- Agents sorted by message count (descending)
- Click to copy agent list to clipboard
- Clipboard format: session ID + tab-separated agent list
- Smooth animations and visual feedback

Changes:
- Updated renderHTMLHeader() to include agent details as data attribute
- Added CSS styling for tooltip and copy feedback
- Created agent-tooltip.js for interactive behavior
- Enhanced click-to-copy with visual confirmation
- Fixed test calls to renderHTMLHeader() with new signature

Example tooltip:
  Agent Message Counts
  ━━━━━━━━━━━━━━━━━━
  a1b2c3d4    127
  a5b6c7d8     98
  ...

Clipboard output:
  session: 8c43ec84
  ---
  a1b2c3d4    127
  a5b6c7d8    98

Technical details:
- New JavaScript module: agent-tooltip.js
- CSS styles for .agent-stats-interactive, .agent-tooltip, .copy-feedback
- Data attributes: data-session-id, data-agent-details (JSON)
- Responsive tooltip positioning (auto-adjusts for screen edges)
- Dark mode support
- Mobile responsive
- Print styles (hides tooltip)

Testing:
- All unit tests pass
- Manual testing with 29-agent session confirmed:
  * Hover shows tooltip with agent list
  * Click copies to clipboard
  * Visual feedback displays
  * Tooltip positioning works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): flatten AGENT NOTIFICATION DOM structure (Phase 14)

Restructured task-notification rendering to use flattened 2-level DOM
instead of 4+ nested levels. Single-header design improves navigation
and debuggability.

Changes:
- Reduced nesting from message-row→bubble→content→notification to
  notification-row→header/content (2 levels)
- Single-line header: collapse-toggle | type | summary | agent-id
- Added CLI command tooltip to agent ID badge
- Enhanced copy button in agent ID badge
- Collapsible content with aria-expanded state
- Updated CSS for new flattened structure
- Added JavaScript for collapse toggle functionality

Benefits:
- Easier DOM navigation for debugging
- Simpler selection/search logic
- Reusable pattern for future components (User/Assistant grouping)
- Better accessibility (aria-expanded)

Example structure:
  ▼ | Subagent | Deep dive on Dog agent | [a41c57b] 📋

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): improve notification visibility and expand/collapse all

Fixed two issues with Phase 14 notifications:
1. Increased text contrast - notifications were appearing dim/disabled
2. Added notification support to Expand All / Collapse All buttons

Changes:
- Updated notification CSS colors for better contrast:
  - .notification-result: #9ca3af -> #d4d4d4 (brighter text)
  - .notification-usage: #6b7280 -> #9ca3af (improved readability)
  - .notification-header .timestamp: #6b7280 -> #9ca3af (less dim)
- Added .notification-header targeting to expandAllTools()
- Added .notification-header targeting to collapseAllTools()
- Notifications now respond to header Expand/Collapse All buttons

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use CSS variables for notification text colors

Root cause: Notifications used hardcoded dim colors (#9ca3af, #d4d4d4)
while rest of UI uses CSS variables (--text-primary, --text-secondary)
which are much brighter in dark mode.

Color comparison (dark mode):
- Old #9ca3af ≈ hsl(210 14% 65%) - very dim
- Old #d4d4d4 ≈ hsl(0 0% 83%) - dim
- New --text-primary = hsl(210 17% 95%) - bright
- New --text-secondary = hsl(210 11% 79%) - readable

Changes:
- .notification-summary: #d4d4d4 → var(--text-primary) (+12% brightness)
- .notification-result: #d4d4d4 → var(--text-primary) (+12% brightness)
- .agent-id-badge: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-usage: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-header .timestamp: #9ca3af → var(--text-secondary) (+14%)
- .collapse-toggle: #9ca3af → var(--text-secondary) (+14% brightness)

All notification text now matches the brightness of regular message content.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): copy full agent context from notifications

Changed notification copy button to include full context:
- Agent type and description
- Agent ID
- Full claude-history query command

Example copied text:
  Subagent "Deep dive on Dog agent" [ad19412]
  claude-history query /path/to/project --session 8c43ec84 --agent ad19412

This makes it easy to paste agent details into conversations with
Claude to reference specific subagents.

Also improved notification text brightness (95% -> 96%) for better
readability in dark mode.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use actual project path in copy and remove brackets

Fixed two issues:
1. Copy text now includes actual project path instead of <project-path>
2. Removed brackets from agent ID display (kept badge styling)

Before:
  Display: [ac8c7ba]
  Copy: claude-history query <project-path> ...

After:
  Display: ac8c7ba (with badge styling)
  Copy: claude-history query /path/to/project ...

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* wip: Phase 14 notification flattening changes

- Add HTML format to formatter.go
- Use RenderMarkdown for notification results
- Fix CSS color variables for proper contrast

* feat(query): add HTML export format (Phase 15)

Added --format html option to query command that generates and opens
an HTML page showing the filtered query results.

Usage:
  claude-history query /path/to/project --session <id> --agent <id> --format html

The HTML format reuses the existing export package renderers to ensure
consistent formatting with the full export command.

Features:
- Generates single HTML file with embedded CSS and JavaScript
- Auto-opens in default browser (macOS, Linux, Windows)
- Uses same markdown rendering as export command
- Includes all Phase 14 improvements (markdown, copy buttons, etc.)
- Simplified header without agent navigation (query-specific)

Implementation:
- Added RenderQueryResults() to pkg/export/html.go
- Added generateQueryHTML() helper to cmd/query.go
- Added openBrowser() cross-platform helper
- HTML file saved to temp directory with descriptive name

Testing:
- Tested with agent-specific queries
- Tested with session queries
- Tested with full project queries
- All existing tests pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(query): parameterize role labels for query HTML output

Problem: Query results showing "User/Assistant" for subagent queries was
misleading. In subagent context, roles should be "Orchestrator/Agent" to
reflect that the orchestrator (main agent) is prompting the subagent.

Solution:
- Added userLabel and assistantLabel parameters to RenderQueryResults()
- Added userLabel and assistantLabel parameters to renderEntry()
- Updated getRoleLabel() to accept custom role names
- Query command now passes "Orchestrator"/"Agent" for subagent queries
- Export command passes "User"/"Assistant" for full session exports
- Role labels displayed in both header stats and message headers

Testing:
- All existing tests pass with updated function signatures
- Verified subagent query shows "Orchestrator: 20 | Agent: 26"
- Verified session query shows "User: 244 | Assistant: 414"
- Verified export still uses "User"/"Assistant" labels

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: improve header layout and reduce vertical space

Changes:
- Update page titles: "Subagent Session" for subagent queries, "Claude Code Session" for full exports
- Move session folder to h1 title with clickable file:// link
- Remove separate "Project:" metadata line
- Reduce vertical spacing in header (padding, margins)
- Add folder-link styling with hover effects
- Update tests to reflect new structure

Implementation:
- Add SessionFolderPath field to SessionStats
- Add helper functions: extractSessionFolderName, buildFileURL
- Update RenderQueryResults and renderHTMLHeader to build folder links
- Pass sessionFolderPath through cmd layer
- Reduce CSS spacing: page-header padding, h1 margin, session-metadata margin

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: filter out empty message bubbles from HTML output

PROBLEM:
HTML export was showing empty message bubbles for:
1. Assistant messages with only whitespace (e.g., "\n\n")
2. Assistant messages with no text and no tool calls
3. User messages with no text and no tool results (BUG: these were being filtered)

The original hasContent() function was incorrectly filtering OUT user messages
that had tool results but no text content. These are valid messages that should
be displayed (they're the USER INPUT messages returning tool results to Claude).

INVESTIGATION:
Analyzed session 8c43ec84 JSONL file and found:
- Empty assistant messages: 4 with whitespace-only, several with no content at all
- User messages with tool results but no text: 189 (these were being incorrectly filtered)

BEFORE FIX: 361 messages rendered (missing 189 valid user messages with tool results)
AFTER FIX: 550 messages rendered (all valid messages, empty ones filtered)

FIX:
Added check in hasContent() for user messages with tool results:
- If entry.Type == user and has ExtractToolResults() > 0, return true
- This ensures user messages with tool results are always rendered
- Empty user messages (no text, no tool results) are still filtered

TESTING:
- Verified empty assistant messages are filtered: 389990a7, c55680df, 6e1459d2, 0dc6e932
- Verified user messages with tool results are now shown: 96f584e6
- Verified assistant messages with tool calls but no text still show: 0e58cabd
- All tests pass: go test ./...
- Export command works correctly
- Query command HTML output works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add clickable file paths to conversation text

Automatically detects and linkifies file paths in message text when they
exist on disk. Only creates links for files that actually exist to avoid
false positives.

**Path Detection**:
- Absolute Unix paths: /path/to/file.ext
- Absolute Windows paths: C:\path\to\file.ext
- Relative paths with prefix: ./file.go, ../pkg/export.go
- Relative paths with directories: src/main.go
- Simple filenames: test.go (when projectPath is available)

**Implementation**:
- New paths.go module with regex-based path detection
- Integrated into markdown rendering pipeline via placeholders
- Paths are resolved relative to projectPath for relative paths
- File existence check before creating links
- Uses file:// URL format for links

**Limitations**:
- Does not support paths with spaces (to avoid false positives)
- Code blocks are protected from path detection (via placeholder system)
- Only detects paths followed by whitespace or punctuation

**CSS Styling**:
- .file-link class with dotted underline
- Hover effect with light blue background
- Consistent with existing .folder-link styling

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: correct agent IDs in message headers and enhance copy context

This commit addresses critical issues with agent ID display and copy functionality in HTML query results:

**Agent ID Display Fixes:**
- ORCHESTRATOR messages now show session ID (parent) instead of subagent ID
- AGENT messages correctly show subagent ID
- Removed literal brackets `[` `]` from agent ID display
- Applied badge styling (`.agent-id-badge`) matching notification badges
- Right-aligned agent ID badges in message headers using flexbox

**Copy Context Enhancements:**
- Session ID copy: Includes session ID, project path, and full CLI command
- Message agent ID copy: Includes role, agent ID, session context, and appropriate CLI command
- ORCHESTRATOR messages: Copy context includes session-only query command
- AGENT messages: Copy context includes session + agent query command

**Technical Changes:**
- Updated `renderEntry()` signature to accept sessionID and agentID parameters
- Added `determineDisplayAgentID()` to compute correct agent ID based on message role
- Added `buildAgentIDCopyContext()` to generate contextual copy text for agent IDs
- Added `buildSessionCopyContext()` to generate contextual copy text for session IDs
- Updated CSS for `.agent-id-badge` styling and positioning
- Updated all tests to reflect new badge styling and copy context behavior

**Testing:**
- All unit tests pass
- Verified with `query --session --agent` command
- Confirmed correct agent IDs in both ORCHESTRATOR and AGENT messages
- Confirmed copy buttons include full context with CLI commands

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* test: add automated detection for empty message bubbles

**Investigation Summary**
- Analyzed 103 subagent entries and 1425 main session entries
- Found 0 empty bubbles in current codebase
- Current hasContent() function correctly filters all empty cases

**Automated Tests Added**

1. **TestNoEmptyMessageBubbles** - Query results (subagent)
   - Tests RenderQueryResults with real session data
   - Parses HTML and verifies no empty message-content divs
   - Reports which entries would create empty bubbles if found

2. **TestNoEmptyMessageBubblesFullExport** - Full export path
   - Tests RenderConversation with full session data
   - Validates both query and export code paths
   - Tested with 1425 entries, 381 rendered

3. **TestHasContentEdgeCases** - Comprehensive edge cases
   - User messages with ONLY tool results → filtered ✓
   - Messages with only whitespace → filtered ✓
   - Empty messages → filtered ✓
   - Assistant messages with tool calls → rendered ✓
   - 10 edge cases covered with explanations

4. **check-empty-bubbles.sh** - Shell script alternative
   - Scans HTML for empty message-content divs
   - Can be run manually or in CI
   - Exit 1 if empty bubbles found

**hasContent() Filtering Rules**
The function correctly filters out:
- User messages with ONLY tool results (not rendered in HTML)
- Any message with only whitespace (spaces, tabs, newlines)
- Empty messages
- System/Queue messages with no content

**Results**
- Current codebase: 0 empty bubbles found
- All edge cases: passing
- Future PRs: protected by automated tests
- Can run: go test ./pkg/export -run Empty

**Files Added**
- src/pkg/export/html_empty_test.go (query path)
- src/pkg/export/html_empty_full_test.go (export path)
- src/pkg/export/html_empty_edgecases_test.go (edge cases)
- scripts/check-empty-bubbles.sh (CLI detection)

* refactor(export): DRY HTML rendering and fix copy buttons to use full IDs

PART 1: Fix Copy Buttons to Use Full IDs
- All copy buttons now include full context (session/agent ID + project path + CLI command)
- Display still shows truncated IDs (8 chars) for clean UI
- Copy text includes FULL IDs to prevent collision risk (birthday paradox)
- Fixed locations:
  * Session ID copy buttons: Now use buildSessionCopyContext()
  * Agent ID copy buttons: Now use buildAgentIDCopyContext()
  * Subagent placeholders: Now use renderSubagentBadgeWithCopy()
  * Notification badges: Already using full context (correct)

PART 2: DRY Refactoring - Single Source of Truth
New helper functions created:
- renderSessionIDWithCopy(): Session ID badge with full copy context
- renderAgentIDWithCopy(): Agent ID badge with full copy context
- renderSubagentBadgeWithCopy(): Subagent badge with full copy context
- renderFileLink(): Clickable file:// links for Finder/Explorer
- truncateID(): Unified ID truncation (consolidated TruncateSessionID)

Duplication eliminated:
- Session ID rendering: 2 locations → 1 helper function
- Agent ID badge rendering: 3 locations → 2 helper functions
- File link rendering: 2 locations → 1 helper function
- ID truncation: 2 functions → 1 unified function

Benefits:
- Consistency: All copy buttons use same format
- Maintainability: Changes to copy format happen in ONE place
- Safety: Full IDs prevent collision issues
- UX: Clean truncated display, comprehensive copy text
- Documentation: Helper functions explain WHY we use full IDs

Stats:
- Lines changed: 107 additions, 49 deletions
- Functions added: 4 new helpers
- Test updates: 5 files updated to match new format
- All tests passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: show tool type in message header for tool-only messages

Changes:
- Modified renderEntry() to detect tool-only assistant messages (no text, only tool calls)
- Changed role label from "Assistant" to "TOOL: <tool-name>" for tool-only messages
- Added inline tool summary in header showing:
  - Bash: command (first 60 chars)
  - Task: description
  - Read/Write: file path
  - Grep: pattern
  - Others: tool name only
- Added CSS styles for .tool-only-label and .tool-summary-inline
- Modified hasContent() to keep tool-only messages (previously filtered out)
- Added comprehensive tests for tool-only message rendering

Impact:
- Tool-only messages are now visible with clear indication of what tool was called
- Inline summaries provide quick context without expanding tool details
- Messages with text + tools still show normal "Assistant" label

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: enable file path linkification in conversation text

The file path linkification feature was not working because paths were
wrapped in inline code backticks (e.g., `/path/to/file.go`). The inline
code processing happened BEFORE file path detection, causing paths to be
replaced with placeholders before they could be linkified.

This commit fixes the issue by processing file paths WITHIN inline code
blocks, before they are escaped and converted to placeholders. Now paths
that exist on disk are converted to clickable file:// links even when
they appear in inline code.

Changes:
- Modified RenderMarkdown() to call makePathsClickable() on inline code
  content before escaping it
- Paths are detected and converted to links within the inline code string
- The resulting HTML (with links) is then wrapped in inline-code styling

Result:
- File links increased from 3 to 113+ in test export
- Paths like /Users/name/project/internal/file.go are now clickable
- Links work correctly when clicked (open in Finder/Explorer)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): Phase 15 UX improvements

- Remove "Main Session" badge from header (saves vertical space)
- Add tool-only compact styling (reduced message-bubble padding)
- Make file paths in tool headers clickable (Read/Write/Edit tools)
- Add meaningful inline summaries for TaskUpdate/TaskCreate/TaskGet/TaskList
- Increase clickable path width from 300px to 600px
- Hide collapsed tool content for tool-only messages to save space

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): remove Main Session breadcrumb and compact tool-only messages

- Remove "Main Session" breadcrumb from navigation.js JavaScript
- Hide empty breadcrumbs nav completely to save vertical space
- Make tool-only message headers clickable to expand/collapse
- Hide message-content by default for tool-only messages (single line)
- Remove box/background styling from tool labels (plain text like ORCHESTRATOR/AGENT)
- Add version marker [v15.3] to page header for cache verification
- Increase clickable file path width from 300px to 600px

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: bump version to 0.3.0-dev

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: update HTML version marker to v0.3.0

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(version): single source of truth for version number with unit test

- Create pkg/version package with Version constant (0.3.0)
- Update main.go to import and use version.Version as default
- Update html.go to dynamically insert version into HTML header
- Add TestVersionConsistency to verify no hardcoded versions
- Add TestVersionFormat to validate semantic versioning
- Update tests to check for version-suffixed title

All version references now use version.Version constant.
GoReleaser can still override via ldflags during release builds.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: resolve linter issues (errcheck and gofmt)

- Fix errcheck warnings in paths_test.go (defer cleanup error handling)
- Run gofmt on html.go and task_notification_test.go
- All linter checks now pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(test): skip Unix path tests on Windows

Windows temp files use Windows path format (C:\...) which these tests
weren't designed for. The path detection itself supports Windows paths
via winAbsPathRe, but these specific tests use tmpFile.Name() which
returns platform-specific paths.

Fix by skipping Unix path tests on Windows platform.

Related: PR #42, Phase 15 Windows CI failure

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: comprehensive Phase 15 documentation update

Critical fixes:
- Remove non-existent --template flag from export command
- Fix --output description (directory not file)
- Add CHANGELOG.md v0.3.0 entry with Phase 15 features
- Update skill docs to remove deprecated --open flag

Additions:
- Document --format html for query command
- Document --include-agents flag with examples
- Document --limit flag for query output control
- Add Phase 15 section to PROJECT_PLAN.md
- Mark Phase 10 Wave 3 as complete

Files updated:
- README.md: Query HTML format, subagent flags, export fixes
- CHANGELOG.md: Complete v0.3.0 release notes
- docs/PROJECT_PLAN.md: Phase 15 completion, version 2.11
- .claude/skills/history/SKILL.md: Remove deprecated flags

Related: Phase 15 documentation audit, PR #42

* docs(release): update RELEASE_PROCESS for v0.3.0+ with working Homebrew

- Add version status section (v0.2.0 broken, v0.3.0+ works)
- Update availability table to show Homebrew as automatic
- Change post-release tasks to reflect Homebrew is now automatic (verify only)
- Update troubleshooting to cover 403 errors with HOMEBREW_TAP_TOKEN
- Remove outdated 'tap doesn't exist' troubleshooting
- Clarify that fine-grained PAT is configured and working

The document now describes the correct state for v0.3.0 and later releases
where Homebrew publishing works automatically via GitHub Actions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: update .gitignore to exclude build artifacts

- Ignore claude-history binary in root directory
- Ignore INTEGRATION_TESTS_SUMMARY.md (auto-generated test output)

These files were accidentally tracked and should be build/test artifacts.

* docs: update issues tracker to reflect completed Phases 11-15

All backlog items from original tracker have been resolved:
- Phase 11: Search, expand/collapse fixes (PR #37)
- Phase 12: Enhanced statistics (PR #38)
- Phase 13: Agent tooltips (PR #39)
- Phase 14: DOM structure improvements (PR #40)
- Phase 15: Query HTML & UX (PR #42)

Total: 0 active issues, 6 resolved, ready for new feature requests.

* docs: add comprehensive examples with HTML exports

Created two example exports demonstrating claude-history capabilities:

Example 1: Simple Session (claude-history-simple)
- 13 messages, 9 agents
- Shows basic session navigation and structure
- 3.1MB complete HTML export with lazy-loaded agents

Example 2: Large Session with Subagents (claude-history-subagents)
- 2041 messages, 90 agents
- Demonstrates complex multi-agent workflows
- 25MB complete HTML export showing deep agent hierarchy

Documentation:
- docs/examples/README.md - Overview and quick start
- docs/examples/VIEWING.md - Cross-platform viewing guide
- Each example has detailed README with exact commands used

Both examples use actual HTML exports from real claude-history
development sessions, providing reproducible demonstrations of
export capabilities.

Features demonstrated:
- Interactive navigation with lazy-loaded subagents
- Search and expand/collapse functionality
- Copy-to-clipboard for agent resurrection
- Session metadata and statistics
- Clickable file paths and URLs
- Tool-only message display
- Agent hierarchy visualization

Total: 146 files (2 examples × complete exports + documentation)

* feat(release): add automated winget publishing via winget-releaser

- Add winget-releaser@v2 action to release workflow
- Automatically creates PR to microsoft/winget-pkgs after each release
- Updates RELEASE_PROCESS.md to reflect winget as automated (~1-2 days)
- Change winget from 'manual' to 'automatic - monitor only'
- Update version status: v0.3.0+ has both Homebrew and winget automated

The workflow now handles both Homebrew (immediate) and winget (PR created
automatically, requires Microsoft approval ~1-2 days) publishing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(release): remove invalid header_template_file field

GoReleaser v1.26.2 does not support header_template_file field.
Removed to allow automatic release notes generation from CHANGELOG.

* ci: add GoReleaser config validation

Add comprehensive validation for GoReleaser configuration to prevent
release failures from configuration errors.

Changes:
- Add GitHub Actions workflow (.github/workflows/validate-config.yml)
  that runs on pushes to main/develop and on PRs
- Add local validation script (scripts/validate-goreleaser.sh) that:
  - Runs 'goreleaser check' for syntax validation
  - Performs snapshot build to validate full configuration
  - Checks for deprecated/invalid fields (e.g., header_template_file)
  - Verifies required files exist
- Add optional pre-commit hook template (scripts/pre-commit-hook.sh)
- Add test script (scripts/test-validation.sh) to verify validation
  catches known errors
- Update docs/RELEASE_PROCESS.md with validation steps and
  troubleshooting for config errors
- Update README.md with validation instructions

This validation would have caught the header_template_file error that
caused the v0.3.2 release failure.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: add winget manifest files for v0.3.0

- Created initial winget manifest for microsoft/winget-pkgs
- Includes installer, locale, and version manifests
- PR submitted: https://github.com/microsoft/winget-pkgs/pull/337541

* docs: update release process for winget setup

- Note winget manifest submitted for v0.3.0
- Update version status to reflect pending approval
- Add PR link for tracking

* feat: add history skill metadata infrastructure

- Create .sc/history/ for skill metadata
- Add bookmarks.jsonl for agent bookmarking
- Add README.md documenting metadata structure
- Bookmark agent-design-expert (a47c2de) - first reusable agent
  - Expert in agent design best practices
  - Analyzed guidelines-0.4.md and tool-use-best-practices.md
  - Available for reviewing future agent prompts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add history-search agent v0.1.0

Implements fuzzy search across Claude Code agent history.

Key features:
- PreToolUse hooks for Bash validation
- Path safety validation (allowed directories only)
- Fuzzy matching with weighted scoring (query 40%, time 25%, type 20%, project 15%)
- Confidence scores and match_reasons for transparency
- Standard maturity level with full response envelope
- Timeout: 120s, max 50 tool calls

Security improvements:
- Path sanitization to prevent shell injection
- Validates against allowed directories
- PreToolUse hooks for command validation

Addresses agent-design-expert review (82/100 -> targeting 90+):
- Added PreToolUse hooks (HIGH priority)
- Added path safety validation (HIGH priority)
- Clarified execution order in Step 3
- Kept fuzzy matching in-agent per user direction

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: history-search agent uses Grep/Glob/Read tools

Major design correction based on user feedback:
- Agent searches raw JSONL files using Grep/Glob/Read tools
- Does NOT call claude-history CLI (that's for users, not agents)
- Searches ~/.claude/projects/ directory structure directly
- Parses queue-operation entries to find agent spawns
- Returns multiple candidates weighted by search criteria

Key insight: If session_id + agent_id known, resurrection is trivial.
This agent's job is to FIND those IDs when unknown.

Search process:
1. Glob to find session JSONL files
2. Grep for queue-operation entries with query keywords
3. Check for subagent files
4. Extract metadata and rank by weighted criteria
5. Return top N candidates with confidence scores

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add advanced search examples to history-search v0.2.0

Added 4 new CLI examples covering:
- Example 7: Find Explore subagents (filter by subagent_type)
- Example 8: Find agents that used specific tool (--tool bash)
- Example 9: Find agents that accessed specific file (--tool-match package.json)
- Example 10: Find agents that accessed file patterns (--tool-match regex)

Now covers all use cases:
✓ Search by project path
✓ Search by date range
✓ Search by agent type (Explore, general-purpose, etc.)
✓ Search by tool used (Bash, Read, Write, etc.)
✓ Search by file accessed (specific files or patterns)

Agent learns through 10 concrete, non-redundant examples.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add PreToolUse hook for CLI validation

Implements MEDIUM priority issue from agent-design-expert review.

PreToolUse hook checks if claude-history CLI is installed:
- Runs before any Bash tool execution
- Exit code 2 blocks execution if tool missing
- Provides clear error message with:
  - Explanation of requirement
  - Relative path to README.md (../../README.md from skill folder)
  - Quick install instructions

Improves user experience by failing fast with actionable guidance
instead of cryptic Bash errors.

Score expected to reach 95/100 (production-ready).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: correct README path in PreToolUse hook

Path should be relative to repo root:
  .claude/skills/history/README.md

(not ../../README.md which was relative to agent file location)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor: move agent to correct location and remove runtime files

Correct plugin structure:
- Agents: .claude/agents/history-search.md (was in .sc/)
- Scripts: .claude/scripts/ (for Python scripts)
- Skills: .claude/skills/history/ (to be created)

Runtime data (not in plugin):
- .sc/history/ created by agents at runtime
- Added .sc/ to .gitignore

Files moved:
- .sc/history/agents/history-search-v2.md → .claude/agents/history-search.md

Files removed (runtime only):
- .sc/history/bookmarks.jsonl (created by agents)
- .sc/history/README.md (not needed)

When plugin is installed, files are dropped into target repo
at these locations. Runtime data is generated by agents.

Co-Authored-By: Claude Sonnet 4…
randlee added a commit to randlee/claude-history that referenced this pull request Feb 9, 2026
…49)

* fix(export): resolve session file lookup issue

The export command was failing to locate session JSONL files even when
the list command found them. The issue was in the path resolution logic:
ExportSession was using the original session ID without resolving prefixes.

This mirrors how the list command works - both now support git-style
prefix matching for session IDs. Updated ExportSession to call
resolver.ResolveSessionID before attempting file lookup.

Added TestExport_SessionResolution to prevent regression. Updated
existing tests to use valid UUID format session IDs instead of
arbitrary string IDs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add GoReleaser, install script, and /history skill

- Add GoReleaser config for multi-platform builds (Linux, macOS, Windows)
- Add GitHub Actions workflow for automated releases on tag push
- Add universal install.sh script for easy installation
- Add version support to CLI (--version flag)
- Add /history Claude Code skill for querying agent history
  - SKILL.md with YAML frontmatter and comprehensive examples
  - README.md with usage documentation
  - Supports all claude-history commands (list, query, tree, find-agent, export)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: remove extra blank line for gofmt compliance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): HTML quality improvements for Phase 10 (#31)

* fix(export): resolve session file lookup issue

The export command was failing to locate session JSONL files even when
the list command found them. The issue was in the path resolution logic:
ExportSession was using the original session ID without resolving prefixes.

This mirrors how the list command works - both now support git-style
prefix matching for session IDs. Updated ExportSession to call
resolver.ResolveSessionID before attempting file lookup.

Added TestExport_SessionResolution to prevent regression. Updated
existing tests to use valid UUID format session IDs instead of
arbitrary string IDs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(export): skip empty messages and add chat bubble alignment

- Add hasContent() helper to skip rendering entries with no text/tools
- Update CSS to right-align user messages and left-align assistant messages
- Update tests to reflect new empty-message-skipping behavior
- Queue operations without content still render subagent placeholders

Fixes #5 (skip empty message blocks)
Fixes #2 (right/left align chat bubbles)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): increase viewport width and normalize text spacing

- Increase conversation container max-width from 900px to 1400px for better content density
- Collapse consecutive empty lines in markdown rendering to prevent excessive vertical spacing
- Both changes improve readability and use of screen real estate

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): add collapse/expand controls and improve color scheme

Task 1: Add collapse/expand controls (#4)
- Add chevron indicators (▼) to tool and subagent headers
- Add collapsed/collapsible classes to tool-call and subagent elements
- Update toggleTool() to toggle collapsed state on parent container
- Update loadAgent() to toggle collapsed state on subagent container
- Add CSS rules for chevron rotation based on collapsed state
- Items start collapsed by default

Task 2: Improve color scheme (#6)
- User messages: softer blue (hsl(210, 100%, 95%))
- Assistant messages: light neutral gray (hsl(0, 0%, 96%))
- Tool overlays: improved teal contrast (hsl(172, 45%, 96%))
- Agent overlays: improved purple contrast (hsl(270, 80%, 97%))
- System overlays: improved amber contrast (hsl(48, 100%, 95%))
- Better visual contrast and professional appearance

Updated tests to match new HTML structure with collapsible classes.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(test): resolve TestHTMLOutput_ValidStructure failure

The test was expecting `<div class="tool-call"` with a closing quote,
but the actual HTML output has additional CSS classes:
`<div class="tool-call collapsible collapsed"`. Changed the test
expectation to match the opening portion without the closing quote,
allowing it to match regardless of additional classes.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): make chevron indicators visible

- Add explicit color, font-size, and opacity to .chevron class
- Chevrons were present but invisible due to missing color styling
- Now visible as intended for collapse/expand functionality

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: resolve lint issues for gofmt compliance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Add --limit flag to control text truncation in query output (#33)

* fix: add --limit flag to control text truncation in query output

Fixes agent output truncation bug that broke pass-by-reference workflows.

Changes:
- Add --limit flag (default: 100, 0 = no limit)
- Update WriteEntries() to accept limit parameter
- Update writeEntryList() to respect limit (0 = full content)
- Add examples to help text showing --limit 0 usage

Before: Agent analysis truncated at 100 chars ("## BEA...")
After: Full content available with --limit 0

Use cases:
- claude-history query --limit 0  (full content, no truncation)
- claude-history query --limit 500 (custom truncation)
- Default behavior unchanged (100 chars for backward compatibility)

Critical for pass-by-reference pattern where agents query previous
agent work and need complete analysis, not truncated snippets.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: filter out empty text entries from query output

Skip entries with no text content (tool-use only, progress, etc.)
to reduce clutter in text format output.

Before: Many empty lines between messages
After: Only lines with actual text content shown

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add smart preview mode for default text output

Shows first entry, count, and last entry preview with exact command
for full output. Makes default behavior much more useful for agents.

Default output now shows:
- First entry (confirms query worked)
- Entry count: '... (N more entries) ...'
- Last entry with first 10 lines of text
- Clear truncation marker: '... (10 of 842 lines shown - TRUNCATED)'
- Exact working command: '--format json | jq -r ...'

Full output modes still work:
- --limit 0: All entries in text format
- --format json: Structured data for agents
- Custom --limit N: Truncate at N chars

This gives agents immediate recognition that content is truncated
and the exact command to retry for full content.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): improve HTML quality - hide empty blocks and format XML tags (#34)

* fix: remove empty assistant blocks and improve user content formatting

Fixes HTML export rendering issues:

1. Filter empty assistant blocks
   - Added whitespace trimming in hasContent() check
   - Entries with only whitespace no longer render
   - Tool calls still render even with whitespace-only text

2. Fixed user content XML formatting
   - Fixed Go regexp compatibility (removed backreferences)
   - Improved spacing for bash-stdout/bash-stderr blocks

3. Added comprehensive tests
   - TestRenderConversation_WhitespaceOnlyContent
   - TestRenderConversation_AssistantWithOnlyToolCalls
   - Test coverage for user content formatting

Results in cleaner HTML exports with less wasted space.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* test: fix integration test JSON encoding for newlines

Fixed TestUserContentWithBashOutput and TestUserContentMixedContent
to properly escape newlines in JSON strings. Raw newlines in JSON
string literals cause "invalid character '\n' in string literal" errors.

Changes:
- Use \n escape sequences instead of literal newlines in JSON
- All export tests now pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): resolve gofmt and staticcheck issues

- Fix formatting in html.go, task_notification_test.go, and user_content_test.go
- Convert if-else chain to tagged switch statement for data.Status check
- Align struct fields and comments to match gofmt standards

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* release: prepare for v0.1.0 initial public release

Prepare the repository for the first official release (v0.1.0):

Changes:
- Updated CHANGELOG.md with v0.1.0 release notes
  - Consolidated all Phase 10 features and fixes
  - Documented query enhancements, HTML export quality improvements
  - Included CI/lint fixes and integration test corrections
- Added docs/issues.md for Phase 11-12 sprint planning
  - 6 issues tracked (P0-P2 priorities)
  - Sprint 1: Critical fixes (search, expand/collapse, newlines)
  - Sprint 2: URL enhancements (clickable links, file paths)
- Updated .gitignore to exclude worktrees directory

Ready for tagging v0.1.0 and PR to main.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(release): add Homebrew tap publishing (#35)

Configure GoReleaser to automatically publish to Homebrew tap.

Changes:
- Added brews section to .goreleaser.yml
  - Target repository: randlee/homebrew-tap
  - Auto-generates Formula/claude-history.rb
  - Includes test command for verification
- Updated release notes to prioritize Homebrew installation
- Added docs/HOMEBREW_SETUP.md with setup instructions

User Installation (after next release):
  brew tap randlee/tap
  brew install claude-history

Notes:
- GoReleaser will auto-create the homebrew-tap repository
- Formula updates automatically on each release
- Works on macOS and Linux
- No Homebrew account required

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(release): update GoReleaser hooks to run from src directory

GoReleaser runs from repo root, but go.mod is in src/.
Updated before.hooks to cd into src before running go commands.

Fixes v0.1.0 release failure:
  error=hook failed: shell: 'go mod tidy': exit status 1:
  go: go.mod file not found in current directory

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(release): specify build directory in GoReleaser config

Added 'dir: ./src' to builds section so Go can find go.mod.
Changed main from './src' to '.' since we're now in src/ dir.

Fixes build error:
  failed to build: go: cannot find main module

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(winget): add Windows Package Manager support

Creates winget manifest for Windows users to install via:
  winget install randlee.claude-history

Changes:
- Added .winget/ directory with installer manifest
- Created docs/WINGET_SETUP.md with submission instructions
- Updated README.md with winget installation method

To publish:
1. After v0.2.0 release, get SHA256 from GitHub Release
2. Update .winget/randlee.claude-history.yaml with SHA256
3. Submit PR to microsoft/winget-pkgs repository

No winget account or API keys required!

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): Resolve critical HTML export issues (Phase 11) (#37)

* fix(export): resolve critical HTML export issues (Phase 11)

Fixes three critical issues in HTML export:

1. Search functionality (P0)
   - Fixed CSS selector mismatch in controls.js
   - Changed .entry -> .message-row
   - Changed .content -> .message-content
   - Search now properly highlights and navigates matches

2. Newlines being doubled (P1)
   - Fixed markdown.go line 660
   - Join with empty string instead of \n
   - Prevents double line breaks when CSS pre-wrap is active

3. Expand/Collapse All buttons (P1)
   - Added support for <details> elements in controls.js
   - expandAllTools() and collapseAllTools() now handle both
     .tool-body class-based AND native <details> elements

All tests passing. Manual verification confirmed fixes work.

Resolves issues from docs/issues.md Phase 11.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): prevent double-escaping of HTML entities in markdown

Fixed issue where HTML entities like &#34; were being escaped twice,
resulting in literal display of entity codes (e.g., &amp;#34;) instead
of the intended characters (e.g., ").

Root cause: The RenderMarkdown function was calling escapeHTML() on
text content during header, list, table, and blockquote processing,
then calling escapeRemainingText() which escaped everything again.
This caused quotes to go from " → &#34; → &amp;#34;.

Solution: Removed redundant escapeHTML() calls from markdown element
processing functions. The escapeRemainingText() function now handles
all HTML escaping in a single pass, preventing double-escaping while
maintaining XSS protection.

Changes:
- Headers (h1-h6): Remove escapeHTML() from content
- Bold/italic: Remove escapeHTML() from content
- Tables (th/td): Remove escapeHTML() from cell content
- Lists (ul/ol/task): Remove escapeHTML() from list item content
- Blockquotes: Remove escapeHTML() from quoted text

Example:
Before: Results: &amp;#34;beads&amp;#34; References in Gastown
After:  Results: &#34;beads&#34; References in Gastown
        (renders as: Results: "beads" References in Gastown)

Tested:
- All export package tests pass
- XSS protection still works (< > & " ' are still escaped)
- HTML entities now render correctly in browsers
- Session 8c43ec84 export verified: 0 double-escaped entities

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): show session start time and duration instead of export time

Replaced "Exported: [time]" in HTML header with more valuable info:
- Session start time (when conversation began)
- Duration (how long the session lasted)

Changes:
- Added SessionStart, SessionEnd, Duration to SessionStats struct
- Updated ComputeSessionStats to extract first/last entry timestamps
- Added formatDuration helper for human-readable duration (e.g., "2h 35m")
- Updated renderHTMLHeader to display new fields instead of export time
- Modified cmd/export.go to pass ProjectPath in stats object
- Fixed timestamp parsing to handle entries without timestamps
- Added comprehensive tests for new functionality

Example header now shows:
  Session: 8c43ec84
  Project: /Users/randlee/Documents/github/github-research
  Started: 2026-02-06 20:37
  Duration: 8h 35m
  Messages: 658
  Agents: 0
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): fix agent count and enhance message statistics (Phase 12) (#38)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy (Phase 13) (#39)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy

Added interactive tooltip when hovering over agent statistics in HTML
export header. Displays table of all agents with their message counts.

Features:
- Hover tooltip shows agent ID and message count for each agent
- Agents sorted by message count (descending)
- Click to copy agent list to clipboard
- Clipboard format: session ID + tab-separated agent list
- Smooth animations and visual feedback

Changes:
- Updated renderHTMLHeader() to include agent details as data attribute
- Added CSS styling for tooltip and copy feedback
- Created agent-tooltip.js for interactive behavior
- Enhanced click-to-copy with visual confirmation
- Fixed test calls to renderHTMLHeader() with new signature

Example tooltip:
  Agent Message Counts
  ━━━━━━━━━━━━━━━━━━
  a1b2c3d4    127
  a5b6c7d8     98
  ...

Clipboard output:
  session: 8c43ec84
  ---
  a1b2c3d4    127
  a5b6c7d8    98

Technical details:
- New JavaScript module: agent-tooltip.js
- CSS styles for .agent-stats-interactive, .agent-tooltip, .copy-feedback
- Data attributes: data-session-id, data-agent-details (JSON)
- Responsive tooltip positioning (auto-adjusts for screen edges)
- Dark mode support
- Mobile responsive
- Print styles (hides tooltip)

Testing:
- All unit tests pass
- Manual testing with 29-agent session confirmed:
  * Hover shows tooltip with agent list
  * Click copies to clipboard
  * Visual feedback displays
  * Tooltip positioning works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): flatten AGENT NOTIFICATION DOM structure (Phase 14) (#40)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy

Added interactive tooltip when hovering over agent statistics in HTML
export header. Displays table of all agents with their message counts.

Features:
- Hover tooltip shows agent ID and message count for each agent
- Agents sorted by message count (descending)
- Click to copy agent list to clipboard
- Clipboard format: session ID + tab-separated agent list
- Smooth animations and visual feedback

Changes:
- Updated renderHTMLHeader() to include agent details as data attribute
- Added CSS styling for tooltip and copy feedback
- Created agent-tooltip.js for interactive behavior
- Enhanced click-to-copy with visual confirmation
- Fixed test calls to renderHTMLHeader() with new signature

Example tooltip:
  Agent Message Counts
  ━━━━━━━━━━━━━━━━━━
  a1b2c3d4    127
  a5b6c7d8     98
  ...

Clipboard output:
  session: 8c43ec84
  ---
  a1b2c3d4    127
  a5b6c7d8    98

Technical details:
- New JavaScript module: agent-tooltip.js
- CSS styles for .agent-stats-interactive, .agent-tooltip, .copy-feedback
- Data attributes: data-session-id, data-agent-details (JSON)
- Responsive tooltip positioning (auto-adjusts for screen edges)
- Dark mode support
- Mobile responsive
- Print styles (hides tooltip)

Testing:
- All unit tests pass
- Manual testing with 29-agent session confirmed:
  * Hover shows tooltip with agent list
  * Click copies to clipboard
  * Visual feedback displays
  * Tooltip positioning works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): flatten AGENT NOTIFICATION DOM structure (Phase 14)

Restructured task-notification rendering to use flattened 2-level DOM
instead of 4+ nested levels. Single-header design improves navigation
and debuggability.

Changes:
- Reduced nesting from message-row→bubble→content→notification to
  notification-row→header/content (2 levels)
- Single-line header: collapse-toggle | type | summary | agent-id
- Added CLI command tooltip to agent ID badge
- Enhanced copy button in agent ID badge
- Collapsible content with aria-expanded state
- Updated CSS for new flattened structure
- Added JavaScript for collapse toggle functionality

Benefits:
- Easier DOM navigation for debugging
- Simpler selection/search logic
- Reusable pattern for future components (User/Assistant grouping)
- Better accessibility (aria-expanded)

Example structure:
  ▼ | Subagent | Deep dive on Dog agent | [a41c57b] 📋

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): improve notification visibility and expand/collapse all

Fixed two issues with Phase 14 notifications:
1. Increased text contrast - notifications were appearing dim/disabled
2. Added notification support to Expand All / Collapse All buttons

Changes:
- Updated notification CSS colors for better contrast:
  - .notification-result: #9ca3af -> #d4d4d4 (brighter text)
  - .notification-usage: #6b7280 -> #9ca3af (improved readability)
  - .notification-header .timestamp: #6b7280 -> #9ca3af (less dim)
- Added .notification-header targeting to expandAllTools()
- Added .notification-header targeting to collapseAllTools()
- Notifications now respond to header Expand/Collapse All buttons

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use CSS variables for notification text colors

Root cause: Notifications used hardcoded dim colors (#9ca3af, #d4d4d4)
while rest of UI uses CSS variables (--text-primary, --text-secondary)
which are much brighter in dark mode.

Color comparison (dark mode):
- Old #9ca3af ≈ hsl(210 14% 65%) - very dim
- Old #d4d4d4 ≈ hsl(0 0% 83%) - dim
- New --text-primary = hsl(210 17% 95%) - bright
- New --text-secondary = hsl(210 11% 79%) - readable

Changes:
- .notification-summary: #d4d4d4 → var(--text-primary) (+12% brightness)
- .notification-result: #d4d4d4 → var(--text-primary) (+12% brightness)
- .agent-id-badge: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-usage: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-header .timestamp: #9ca3af → var(--text-secondary) (+14%)
- .collapse-toggle: #9ca3af → var(--text-secondary) (+14% brightness)

All notification text now matches the brightness of regular message content.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): copy full agent context from notifications

Changed notification copy button to include full context:
- Agent type and description
- Agent ID
- Full claude-history query command

Example copied text:
  Subagent "Deep dive on Dog agent" [ad19412]
  claude-history query /path/to/project --session 8c43ec84 --agent ad19412

This makes it easy to paste agent details into conversations with
Claude to reference specific subagents.

Also improved notification text brightness (95% -> 96%) for better
readability in dark mode.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use actual project path in copy and remove brackets

Fixed two issues:
1. Copy text now includes actual project path instead of <project-path>
2. Removed brackets from agent ID display (kept badge styling)

Before:
  Display: [ac8c7ba]
  Copy: claude-history query <project-path> ...

After:
  Display: ac8c7ba (with badge styling)
  Copy: claude-history query /path/to/project ...

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* wip: Phase 14 notification flattening changes

- Add HTML format to formatter.go
- Use RenderMarkdown for notification results
- Fix CSS color variables for proper contrast

* chore: remove unused imports from query.go

Remove unused os/exec, runtime, and export package imports
that were left over from merge conflict resolution.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: resolve lint issues

Fixed gofmt formatting issue in task_notification_test.go where line 305
had incorrect indentation (mixed spaces/tabs).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(release): add fine-grained PAT for homebrew tap publishing

- Add HOMEBREW_TAP_TOKEN environment variable to release workflow
- Update .goreleaser.yml to use HOMEBREW_TAP_TOKEN for homebrew-tap pushes
- Add release notes template at .goreleaser/release-notes-template.md
- Add comprehensive RELEASE_PROCESS.md documentation
- Fixes 403 error when publishing to homebrew-tap

This uses a fine-grained PAT with Contents:write permission scoped
only to randlee/homebrew-tap for better security than classic PAT.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(skill): make history skill portable with pass-by-reference pattern

- Remove hard-coded paths from SKILL.md, use 'claude-history' from PATH
- Add comprehensive installation guide to README.md with 5 install methods
- Add troubleshooting section for common issues
- Add 'Passing Agent to Subagents by Reference' section to SKILL.md
- Document 10x faster pattern for sharing explore agent analysis
- Add template for subagents to query previous agent work
- Brief note in SKILL.md pointing to README.md for installation

This makes the skill portable across systems and documents the powerful
pass-by-reference pattern for efficient agent coordination.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Phase 15: Query HTML format UX improvements (#42)

* feat(export): fix agent count and enhance message statistics (Phase 12)

Fixed critical bug where agent count showed 0 due to session ID prefix
not being resolved before passing to BuildNestedTree.

Enhanced message statistics to show breakdown:
- User message count
- Assistant message count (main session)
- Subagent count and total subagent messages

Display format: "User: X | Assistant: Y | Subagents[Z]: W messages"

Changes:
- Fixed export.go to pass resolvedSessionID instead of exportSessionID
  at all call sites (lines 140, 172, 188)
- Added UserMessages, AssistantMessages, TotalAgentMessages,
  SubagentMessages to SessionStats struct
- Updated ComputeSessionStats to count categories separately and sum
  subagent messages from agent tree
- Updated renderHTMLHeader to display enhanced statistics
- Added comprehensive tests for new functionality
- All tests pass with 93.7% coverage

Example output:
  Session: 8c43ec84
  Started: 2026-02-06 20:37 | Duration: 8h 35m
  User: 42 | Assistant: 128 | Subagents[29]: 488 messages
  Tools: 193 calls

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): ensure search results are visible in viewport

Fixed search navigation to scroll matched items into the center of
the viewport instead of positioning them above the visible area.

Changed scrollIntoView() to use block: 'center' option, ensuring
highlighted search matches are always visible without manual scrolling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): auto-expand collapsed sections when search finds matches

Search now automatically expands parent <details> elements and hidden
tool-body sections when navigating to matches inside them. This ensures
search results are always visible without manual expansion.

Added expandParentSections() helper that walks up the DOM tree and
expands any collapsed containers before scrolling to the match.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(lint): convert if-else chain to switch statement

Resolved staticcheck QF1003 warning in pkg/export/html.go by converting
if-else chain on entry.Type to a tagged switch statement. Also consolidated
the tool call counting logic into the assistant case branch for better
organization.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): add interactive agent tooltip with click-to-copy

Added interactive tooltip when hovering over agent statistics in HTML
export header. Displays table of all agents with their message counts.

Features:
- Hover tooltip shows agent ID and message count for each agent
- Agents sorted by message count (descending)
- Click to copy agent list to clipboard
- Clipboard format: session ID + tab-separated agent list
- Smooth animations and visual feedback

Changes:
- Updated renderHTMLHeader() to include agent details as data attribute
- Added CSS styling for tooltip and copy feedback
- Created agent-tooltip.js for interactive behavior
- Enhanced click-to-copy with visual confirmation
- Fixed test calls to renderHTMLHeader() with new signature

Example tooltip:
  Agent Message Counts
  ━━━━━━━━━━━━━━━━━━
  a1b2c3d4    127
  a5b6c7d8     98
  ...

Clipboard output:
  session: 8c43ec84
  ---
  a1b2c3d4    127
  a5b6c7d8    98

Technical details:
- New JavaScript module: agent-tooltip.js
- CSS styles for .agent-stats-interactive, .agent-tooltip, .copy-feedback
- Data attributes: data-session-id, data-agent-details (JSON)
- Responsive tooltip positioning (auto-adjusts for screen edges)
- Dark mode support
- Mobile responsive
- Print styles (hides tooltip)

Testing:
- All unit tests pass
- Manual testing with 29-agent session confirmed:
  * Hover shows tooltip with agent list
  * Click copies to clipboard
  * Visual feedback displays
  * Tooltip positioning works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): flatten AGENT NOTIFICATION DOM structure (Phase 14)

Restructured task-notification rendering to use flattened 2-level DOM
instead of 4+ nested levels. Single-header design improves navigation
and debuggability.

Changes:
- Reduced nesting from message-row→bubble→content→notification to
  notification-row→header/content (2 levels)
- Single-line header: collapse-toggle | type | summary | agent-id
- Added CLI command tooltip to agent ID badge
- Enhanced copy button in agent ID badge
- Collapsible content with aria-expanded state
- Updated CSS for new flattened structure
- Added JavaScript for collapse toggle functionality

Benefits:
- Easier DOM navigation for debugging
- Simpler selection/search logic
- Reusable pattern for future components (User/Assistant grouping)
- Better accessibility (aria-expanded)

Example structure:
  ▼ | Subagent | Deep dive on Dog agent | [a41c57b] 📋

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): improve notification visibility and expand/collapse all

Fixed two issues with Phase 14 notifications:
1. Increased text contrast - notifications were appearing dim/disabled
2. Added notification support to Expand All / Collapse All buttons

Changes:
- Updated notification CSS colors for better contrast:
  - .notification-result: #9ca3af -> #d4d4d4 (brighter text)
  - .notification-usage: #6b7280 -> #9ca3af (improved readability)
  - .notification-header .timestamp: #6b7280 -> #9ca3af (less dim)
- Added .notification-header targeting to expandAllTools()
- Added .notification-header targeting to collapseAllTools()
- Notifications now respond to header Expand/Collapse All buttons

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use CSS variables for notification text colors

Root cause: Notifications used hardcoded dim colors (#9ca3af, #d4d4d4)
while rest of UI uses CSS variables (--text-primary, --text-secondary)
which are much brighter in dark mode.

Color comparison (dark mode):
- Old #9ca3af ≈ hsl(210 14% 65%) - very dim
- Old #d4d4d4 ≈ hsl(0 0% 83%) - dim
- New --text-primary = hsl(210 17% 95%) - bright
- New --text-secondary = hsl(210 11% 79%) - readable

Changes:
- .notification-summary: #d4d4d4 → var(--text-primary) (+12% brightness)
- .notification-result: #d4d4d4 → var(--text-primary) (+12% brightness)
- .agent-id-badge: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-usage: #9ca3af → var(--text-secondary) (+14% brightness)
- .notification-header .timestamp: #9ca3af → var(--text-secondary) (+14%)
- .collapse-toggle: #9ca3af → var(--text-secondary) (+14% brightness)

All notification text now matches the brightness of regular message content.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): copy full agent context from notifications

Changed notification copy button to include full context:
- Agent type and description
- Agent ID
- Full claude-history query command

Example copied text:
  Subagent "Deep dive on Dog agent" [ad19412]
  claude-history query /path/to/project --session 8c43ec84 --agent ad19412

This makes it easy to paste agent details into conversations with
Claude to reference specific subagents.

Also improved notification text brightness (95% -> 96%) for better
readability in dark mode.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): use actual project path in copy and remove brackets

Fixed two issues:
1. Copy text now includes actual project path instead of <project-path>
2. Removed brackets from agent ID display (kept badge styling)

Before:
  Display: [ac8c7ba]
  Copy: claude-history query <project-path> ...

After:
  Display: ac8c7ba (with badge styling)
  Copy: claude-history query /path/to/project ...

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* wip: Phase 14 notification flattening changes

- Add HTML format to formatter.go
- Use RenderMarkdown for notification results
- Fix CSS color variables for proper contrast

* feat(query): add HTML export format (Phase 15)

Added --format html option to query command that generates and opens
an HTML page showing the filtered query results.

Usage:
  claude-history query /path/to/project --session <id> --agent <id> --format html

The HTML format reuses the existing export package renderers to ensure
consistent formatting with the full export command.

Features:
- Generates single HTML file with embedded CSS and JavaScript
- Auto-opens in default browser (macOS, Linux, Windows)
- Uses same markdown rendering as export command
- Includes all Phase 14 improvements (markdown, copy buttons, etc.)
- Simplified header without agent navigation (query-specific)

Implementation:
- Added RenderQueryResults() to pkg/export/html.go
- Added generateQueryHTML() helper to cmd/query.go
- Added openBrowser() cross-platform helper
- HTML file saved to temp directory with descriptive name

Testing:
- Tested with agent-specific queries
- Tested with session queries
- Tested with full project queries
- All existing tests pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(query): parameterize role labels for query HTML output

Problem: Query results showing "User/Assistant" for subagent queries was
misleading. In subagent context, roles should be "Orchestrator/Agent" to
reflect that the orchestrator (main agent) is prompting the subagent.

Solution:
- Added userLabel and assistantLabel parameters to RenderQueryResults()
- Added userLabel and assistantLabel parameters to renderEntry()
- Updated getRoleLabel() to accept custom role names
- Query command now passes "Orchestrator"/"Agent" for subagent queries
- Export command passes "User"/"Assistant" for full session exports
- Role labels displayed in both header stats and message headers

Testing:
- All existing tests pass with updated function signatures
- Verified subagent query shows "Orchestrator: 20 | Agent: 26"
- Verified session query shows "User: 244 | Assistant: 414"
- Verified export still uses "User"/"Assistant" labels

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: improve header layout and reduce vertical space

Changes:
- Update page titles: "Subagent Session" for subagent queries, "Claude Code Session" for full exports
- Move session folder to h1 title with clickable file:// link
- Remove separate "Project:" metadata line
- Reduce vertical spacing in header (padding, margins)
- Add folder-link styling with hover effects
- Update tests to reflect new structure

Implementation:
- Add SessionFolderPath field to SessionStats
- Add helper functions: extractSessionFolderName, buildFileURL
- Update RenderQueryResults and renderHTMLHeader to build folder links
- Pass sessionFolderPath through cmd layer
- Reduce CSS spacing: page-header padding, h1 margin, session-metadata margin

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: filter out empty message bubbles from HTML output

PROBLEM:
HTML export was showing empty message bubbles for:
1. Assistant messages with only whitespace (e.g., "\n\n")
2. Assistant messages with no text and no tool calls
3. User messages with no text and no tool results (BUG: these were being filtered)

The original hasContent() function was incorrectly filtering OUT user messages
that had tool results but no text content. These are valid messages that should
be displayed (they're the USER INPUT messages returning tool results to Claude).

INVESTIGATION:
Analyzed session 8c43ec84 JSONL file and found:
- Empty assistant messages: 4 with whitespace-only, several with no content at all
- User messages with tool results but no text: 189 (these were being incorrectly filtered)

BEFORE FIX: 361 messages rendered (missing 189 valid user messages with tool results)
AFTER FIX: 550 messages rendered (all valid messages, empty ones filtered)

FIX:
Added check in hasContent() for user messages with tool results:
- If entry.Type == user and has ExtractToolResults() > 0, return true
- This ensures user messages with tool results are always rendered
- Empty user messages (no text, no tool results) are still filtered

TESTING:
- Verified empty assistant messages are filtered: 389990a7, c55680df, 6e1459d2, 0dc6e932
- Verified user messages with tool results are now shown: 96f584e6
- Verified assistant messages with tool calls but no text still show: 0e58cabd
- All tests pass: go test ./...
- Export command works correctly
- Query command HTML output works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add clickable file paths to conversation text

Automatically detects and linkifies file paths in message text when they
exist on disk. Only creates links for files that actually exist to avoid
false positives.

**Path Detection**:
- Absolute Unix paths: /path/to/file.ext
- Absolute Windows paths: C:\path\to\file.ext
- Relative paths with prefix: ./file.go, ../pkg/export.go
- Relative paths with directories: src/main.go
- Simple filenames: test.go (when projectPath is available)

**Implementation**:
- New paths.go module with regex-based path detection
- Integrated into markdown rendering pipeline via placeholders
- Paths are resolved relative to projectPath for relative paths
- File existence check before creating links
- Uses file:// URL format for links

**Limitations**:
- Does not support paths with spaces (to avoid false positives)
- Code blocks are protected from path detection (via placeholder system)
- Only detects paths followed by whitespace or punctuation

**CSS Styling**:
- .file-link class with dotted underline
- Hover effect with light blue background
- Consistent with existing .folder-link styling

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: correct agent IDs in message headers and enhance copy context

This commit addresses critical issues with agent ID display and copy functionality in HTML query results:

**Agent ID Display Fixes:**
- ORCHESTRATOR messages now show session ID (parent) instead of subagent ID
- AGENT messages correctly show subagent ID
- Removed literal brackets `[` `]` from agent ID display
- Applied badge styling (`.agent-id-badge`) matching notification badges
- Right-aligned agent ID badges in message headers using flexbox

**Copy Context Enhancements:**
- Session ID copy: Includes session ID, project path, and full CLI command
- Message agent ID copy: Includes role, agent ID, session context, and appropriate CLI command
- ORCHESTRATOR messages: Copy context includes session-only query command
- AGENT messages: Copy context includes session + agent query command

**Technical Changes:**
- Updated `renderEntry()` signature to accept sessionID and agentID parameters
- Added `determineDisplayAgentID()` to compute correct agent ID based on message role
- Added `buildAgentIDCopyContext()` to generate contextual copy text for agent IDs
- Added `buildSessionCopyContext()` to generate contextual copy text for session IDs
- Updated CSS for `.agent-id-badge` styling and positioning
- Updated all tests to reflect new badge styling and copy context behavior

**Testing:**
- All unit tests pass
- Verified with `query --session --agent` command
- Confirmed correct agent IDs in both ORCHESTRATOR and AGENT messages
- Confirmed copy buttons include full context with CLI commands

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* test: add automated detection for empty message bubbles

**Investigation Summary**
- Analyzed 103 subagent entries and 1425 main session entries
- Found 0 empty bubbles in current codebase
- Current hasContent() function correctly filters all empty cases

**Automated Tests Added**

1. **TestNoEmptyMessageBubbles** - Query results (subagent)
   - Tests RenderQueryResults with real session data
   - Parses HTML and verifies no empty message-content divs
   - Reports which entries would create empty bubbles if found

2. **TestNoEmptyMessageBubblesFullExport** - Full export path
   - Tests RenderConversation with full session data
   - Validates both query and export code paths
   - Tested with 1425 entries, 381 rendered

3. **TestHasContentEdgeCases** - Comprehensive edge cases
   - User messages with ONLY tool results → filtered ✓
   - Messages with only whitespace → filtered ✓
   - Empty messages → filtered ✓
   - Assistant messages with tool calls → rendered ✓
   - 10 edge cases covered with explanations

4. **check-empty-bubbles.sh** - Shell script alternative
   - Scans HTML for empty message-content divs
   - Can be run manually or in CI
   - Exit 1 if empty bubbles found

**hasContent() Filtering Rules**
The function correctly filters out:
- User messages with ONLY tool results (not rendered in HTML)
- Any message with only whitespace (spaces, tabs, newlines)
- Empty messages
- System/Queue messages with no content

**Results**
- Current codebase: 0 empty bubbles found
- All edge cases: passing
- Future PRs: protected by automated tests
- Can run: go test ./pkg/export -run Empty

**Files Added**
- src/pkg/export/html_empty_test.go (query path)
- src/pkg/export/html_empty_full_test.go (export path)
- src/pkg/export/html_empty_edgecases_test.go (edge cases)
- scripts/check-empty-bubbles.sh (CLI detection)

* refactor(export): DRY HTML rendering and fix copy buttons to use full IDs

PART 1: Fix Copy Buttons to Use Full IDs
- All copy buttons now include full context (session/agent ID + project path + CLI command)
- Display still shows truncated IDs (8 chars) for clean UI
- Copy text includes FULL IDs to prevent collision risk (birthday paradox)
- Fixed locations:
  * Session ID copy buttons: Now use buildSessionCopyContext()
  * Agent ID copy buttons: Now use buildAgentIDCopyContext()
  * Subagent placeholders: Now use renderSubagentBadgeWithCopy()
  * Notification badges: Already using full context (correct)

PART 2: DRY Refactoring - Single Source of Truth
New helper functions created:
- renderSessionIDWithCopy(): Session ID badge with full copy context
- renderAgentIDWithCopy(): Agent ID badge with full copy context
- renderSubagentBadgeWithCopy(): Subagent badge with full copy context
- renderFileLink(): Clickable file:// links for Finder/Explorer
- truncateID(): Unified ID truncation (consolidated TruncateSessionID)

Duplication eliminated:
- Session ID rendering: 2 locations → 1 helper function
- Agent ID badge rendering: 3 locations → 2 helper functions
- File link rendering: 2 locations → 1 helper function
- ID truncation: 2 functions → 1 unified function

Benefits:
- Consistency: All copy buttons use same format
- Maintainability: Changes to copy format happen in ONE place
- Safety: Full IDs prevent collision issues
- UX: Clean truncated display, comprehensive copy text
- Documentation: Helper functions explain WHY we use full IDs

Stats:
- Lines changed: 107 additions, 49 deletions
- Functions added: 4 new helpers
- Test updates: 5 files updated to match new format
- All tests passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: show tool type in message header for tool-only messages

Changes:
- Modified renderEntry() to detect tool-only assistant messages (no text, only tool calls)
- Changed role label from "Assistant" to "TOOL: <tool-name>" for tool-only messages
- Added inline tool summary in header showing:
  - Bash: command (first 60 chars)
  - Task: description
  - Read/Write: file path
  - Grep: pattern
  - Others: tool name only
- Added CSS styles for .tool-only-label and .tool-summary-inline
- Modified hasContent() to keep tool-only messages (previously filtered out)
- Added comprehensive tests for tool-only message rendering

Impact:
- Tool-only messages are now visible with clear indication of what tool was called
- Inline summaries provide quick context without expanding tool details
- Messages with text + tools still show normal "Assistant" label

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: enable file path linkification in conversation text

The file path linkification feature was not working because paths were
wrapped in inline code backticks (e.g., `/path/to/file.go`). The inline
code processing happened BEFORE file path detection, causing paths to be
replaced with placeholders before they could be linkified.

This commit fixes the issue by processing file paths WITHIN inline code
blocks, before they are escaped and converted to placeholders. Now paths
that exist on disk are converted to clickable file:// links even when
they appear in inline code.

Changes:
- Modified RenderMarkdown() to call makePathsClickable() on inline code
  content before escaping it
- Paths are detected and converted to links within the inline code string
- The resulting HTML (with links) is then wrapped in inline-code styling

Result:
- File links increased from 3 to 113+ in test export
- Paths like /Users/name/project/internal/file.go are now clickable
- Links work correctly when clicked (open in Finder/Explorer)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(export): Phase 15 UX improvements

- Remove "Main Session" badge from header (saves vertical space)
- Add tool-only compact styling (reduced message-bubble padding)
- Make file paths in tool headers clickable (Read/Write/Edit tools)
- Add meaningful inline summaries for TaskUpdate/TaskCreate/TaskGet/TaskList
- Increase clickable path width from 300px to 600px
- Hide collapsed tool content for tool-only messages to save space

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(export): remove Main Session breadcrumb and compact tool-only messages

- Remove "Main Session" breadcrumb from navigation.js JavaScript
- Hide empty breadcrumbs nav completely to save vertical space
- Make tool-only message headers clickable to expand/collapse
- Hide message-content by default for tool-only messages (single line)
- Remove box/background styling from tool labels (plain text like ORCHESTRATOR/AGENT)
- Add version marker [v15.3] to page header for cache verification
- Increase clickable file path width from 300px to 600px

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: bump version to 0.3.0-dev

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: update HTML version marker to v0.3.0

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(version): single source of truth for version number with unit test

- Create pkg/version package with Version constant (0.3.0)
- Update main.go to import and use version.Version as default
- Update html.go to dynamically insert version into HTML header
- Add TestVersionConsistency to verify no hardcoded versions
- Add TestVersionFormat to validate semantic versioning
- Update tests to check for version-suffixed title

All version references now use version.Version constant.
GoReleaser can still override via ldflags during release builds.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: resolve linter issues (errcheck and gofmt)

- Fix errcheck warnings in paths_test.go (defer cleanup error handling)
- Run gofmt on html.go and task_notification_test.go
- All linter checks now pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(test): skip Unix path tests on Windows

Windows temp files use Windows path format (C:\...) which these tests
weren't designed for. The path detection itself supports Windows paths
via winAbsPathRe, but these specific tests use tmpFile.Name() which
returns platform-specific paths.

Fix by skipping Unix path tests on Windows platform.

Related: PR #42, Phase 15 Windows CI failure

---------

Co-authored-by: Rand Lee <randlee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: comprehensive Phase 15 documentation update

Critical fixes:
- Remove non-existent --template flag from export command
- Fix --output description (directory not file)
- Add CHANGELOG.md v0.3.0 entry with Phase 15 features
- Update skill docs to remove deprecated --open flag

Additions:
- Document --format html for query command
- Document --include-agents flag with examples
- Document --limit flag for query output control
- Add Phase 15 section to PROJECT_PLAN.md
- Mark Phase 10 Wave 3 as complete

Files updated:
- README.md: Query HTML format, subagent flags, export fixes
- CHANGELOG.md: Complete v0.3.0 release notes
- docs/PROJECT_PLAN.md: Phase 15 completion, version 2.11
- .claude/skills/history/SKILL.md: Remove deprecated flags

Related: Phase 15 documentation audit, PR #42

* docs(release): update RELEASE_PROCESS for v0.3.0+ with working Homebrew

- Add version status section (v0.2.0 broken, v0.3.0+ works)
- Update availability table to show Homebrew as automatic
- Change post-release tasks to reflect Homebrew is now automatic (verify only)
- Update troubleshooting to cover 403 errors with HOMEBREW_TAP_TOKEN
- Remove outdated 'tap doesn't exist' troubleshooting
- Clarify that fine-grained PAT is configured and working

The document now describes the correct state for v0.3.0 and later releases
where Homebrew publishing works automatically via GitHub Actions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: update .gitignore to exclude build artifacts

- Ignore claude-history binary in root directory
- Ignore INTEGRATION_TESTS_SUMMARY.md (auto-generated test output)

These files were accidentally tracked and should be build/test artifacts.

* docs: update issues tracker to reflect completed Phases 11-15

All backlog items from original tracker have been resolved:
- Phase 11: Search, expand/collapse fixes (PR #37)
- Phase 12: Enhanced statistics (PR #38)
- Phase 13: Agent tooltips (PR #39)
- Phase 14: DOM structure improvements (PR #40)
- Phase 15: Query HTML & UX (PR #42)

Total: 0 active issues, 6 resolved, ready for new feature requests.

* docs: add comprehensive examples with HTML exports

Created two example exports demonstrating claude-history capabilities:

Example 1: Simple Session (claude-history-simple)
- 13 messages, 9 agents
- Shows basic session navigation and structure
- 3.1MB complete HTML export with lazy-loaded agents

Example 2: Large Session with Subagents (claude-history-subagents)
- 2041 messages, 90 agents
- Demonstrates complex multi-agent workflows
- 25MB complete HTML export showing deep agent hierarchy

Documentation:
- docs/examples/README.md - Overview and quick start
- docs/examples/VIEWING.md - Cross-platform viewing guide
- Each example has detailed README with exact commands used

Both examples use actual HTML exports from real claude-history
development sessions, providing reproducible demonstrations of
export capabilities.

Features demonstrated:
- Interactive navigation with lazy-loaded subagents
- Search and expand/collapse functionality
- Copy-to-clipboard for agent resurrection
- Session metadata and statistics
- Clickable file paths and URLs
- Tool-only message display
- Agent hierarchy visualization

Total: 146 files (2 examples × complete exports + documentation)

* feat(release): add automated winget publishing via winget-releaser

- Add winget-releaser@v2 action to release workflow
- Automatically creates PR to microsoft/winget-pkgs after each release
- Updates RELEASE_PROCESS.md to reflect winget as automated (~1-2 days)
- Change winget from 'manual' to 'automatic - monitor only'
- Update version status: v0.3.0+ has both Homebrew and winget automated

The workflow now handles both Homebrew (immediate) and winget (PR created
automatically, requires Microsoft approval ~1-2 days) publishing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(release): remove invalid header_template_file field

GoReleaser v1.26.2 does not support header_template_file field.
Removed to allow automatic release notes generation from CHANGELOG.

* ci: add GoReleaser config validation

Add comprehensive validation for GoReleaser configuration to prevent
release failures from configuration errors.

Changes:
- Add GitHub Actions workflow (.github/workflows/validate-config.yml)
  that runs on pushes to main/develop and on PRs
- Add local validation script (scripts/validate-goreleaser.sh) that:
  - Runs 'goreleaser check' for syntax validation
  - Performs snapshot build to validate full configuration
  - Checks for deprecated/invalid fields (e.g., header_template_file)
  - Verifies required files exist
- Add optional pre-commit hook template (scripts/pre-commit-hook.sh)
- Add test script (scripts/test-validation.sh) to verify validation
  catches known errors
- Update docs/RELEASE_PROCESS.md with validation steps and
  troubleshooting for config errors
- Update README.md with validation instructions

This validation would have caught the header_template_file error that
caused the v0.3.2 release failure.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: add winget manifest files for v0.3.0

- Created initial winget manifest for microsoft/winget-pkgs
- Includes installer, locale, and version manifests
- PR submitted: https://github.com/microsoft/winget-pkgs/pull/337541

* docs: update release process for winget setup

- Note winget manifest submitted for v0.3.0
- Update version status to reflect pending approval
- Add PR link for tracking

* feat: add history skill metadata infrastructure

- Create .sc/history/ for skill metadata
- Add bookmarks.jsonl for agent bookmarking
- Add README.md documenting metadata structure
- Bookmark agent-design-expert (a47c2de) - first reusable agent
  - Expert in agent design best practices
  - Analyzed guidelines-0.4.md and tool-use-best-practices.md
  - Available for reviewing future agent prompts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add history-search agent v0.1.0

Implements fuzzy search across Claude Code agent history.

Key features:
- PreToolUse hooks for Bash validation
- Path safety validation (allowed directories only)
- Fuzzy matching with weighted scoring (query 40%, time 25%, type 20%, project 15%)
- Confidence scores and match_reasons for transparency
- Standard maturity level with full response envelope
- Timeout: 120s, max 50 tool calls

Security improvements:
- Path sanitization to prevent shell injection
- Validates against allowed directories
- PreToolUse hooks for command validation

Addresses agent-design-expert review (82/100 -> targeting 90+):
- Added PreToolUse hooks (HIGH priority)
- Added path safety validation (HIGH priority)
- Clarified execution order in Step 3
- Kept fuzzy matching in-agent per user direction

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: history-search agent uses Grep/Glob/Read tools

Major design correction based on user feedback:
- Agent searches raw JSONL files using Grep/Glob/Read tools
- Does NOT call claude-history CLI (that's for users, not agents)
- Searches ~/.claude/projects/ directory structure directly
- Parses queue-operation entries to find agent spawns
- Returns multiple candidates weighted by search criteria

Key insight: If session_id + agent_id known, resurrection is trivial.
This agent's job is to FIND those IDs when unknown.

Search process:
1. Glob to find session JSONL files
2. Grep for queue-operation entries with query keywords
3. Check for subagent files
4. Extract metadata and rank by weighted criteria
5. Return top N candidates with confidence scores

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add advanced search examples to history-search v0.2.0

Added 4 new CLI examples covering:
- Example 7: Find Explore subagents (filter by subagent_type)
- Example 8: Find agents that used specific tool (--tool bash)
- Example 9: Find agents that accessed specific file (--tool-match package.json)
- Example 10: Find agents that accessed file patterns (--tool-match regex)

Now covers all use cases:
✓ Search by project path
✓ Search by date range
✓ Search by agent type (Explore, general-purpose, etc.)
✓ Search by tool used (Bash, Read, Write, etc.)
✓ Search by file accessed (specific files or patterns)

Agent learns through 10 concrete, non-redundant examples.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add PreToolUse hook for CLI validation

Implements MEDIUM priority issue from agent-design-expert review.

PreToolUse hook checks if claude-history CLI is installed:
- Runs before any Bash tool execution
- Exit code 2 blocks execution if tool missing
- Provides clear error message with:
  - Explanation of requirement
  - Relative path to README.md (../../README.md from skill folder)
  - Quick install instructions

Improves user experience by failing fast with actionable guidance
instead of cryptic Bash errors.

Score expected to reach 95/100 (production-ready).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: correct README path in PreToolUse hook

Path should be relative to repo root:
  .claude/skills/history/README.md

(not ../../README.md which was relative to agent file location)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor: move agent to correct location and remove runtime files

Correct plugin structure:
- Agents: .claude/agents/history-search.md (was in .sc/)
- Scripts: .claude/scripts/ (for Python scripts)
- Skills: .claude/skills/history/ (to be created)

Runtime data (not in plugin):
- .sc/history/ created by agents at runtime
- Added .sc/ to .gitignore

Files moved:
- .sc/history/agents/history-search-v2.md → .claude/agents/history-search.md

Files removed (runtime only):
- .sc/history/bookmarks.jsonl (created by agents)
- .sc/history/README.md (not needed)

When plugin is installed, files are dropped into target repo
at these locations. Runtime data is generated by agents.

Co-Authored-By: Clau…
@stephengillie
Copy link
Collaborator

Manual Validation ended with:

2026-02-12 10:18:14.652 [FAIL] Installer failed security check. Url: https://github.com/randlee/claude-history/releases/download/v0.3.0/claude-history_0.3.0_windows_amd64.zip Result: 0x80004005

Hex Dec Inverted Dec Symbol Description
80004005 -2147467259 2147500037 E_Fail Resource missing

(Automated response - build 1218.)

@stephengillie
Copy link
Collaborator

Manual Validation ended with:

2026-02-12 13:11:27.789 [FAIL] Installer failed security check. Url: https://github.com/randlee/claude-history/releases/download/v0.3.0/claude-history_0.3.0_windows_amd64.zip Result: 0x80004005

Hex Dec Inverted Dec Symbol Description
80004005 -2147467259 2147500037 E_Fail Resource missing

(Automated response - build 1218.)

@stephengillie
Copy link
Collaborator

stephengillie commented Feb 13, 2026

Edit: For #337683

@stephengillie
Copy link
Collaborator

Manual Validation ended with:

claude-history version 0.3.0 (commit: 41b6bc6e437c55588d54b1ffcb40702659f91c3a, built: 2026-02-08T00:54:59Z)

(Automated response - build 1218.)

@microsoft-github-policy-service microsoft-github-policy-service bot merged commit 4b30dba into microsoft:master Feb 13, 2026
1 check passed
@microsoft-github-policy-service microsoft-github-policy-service bot added the Moderator-Approved One of the Moderators has reviewed and approved this PR label Feb 13, 2026
@wingetbot
Copy link
Collaborator

Publish pipeline succeeded for this Pull Request. Once you refresh your index, this change should be present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Azure-Pipeline-Passed Validation pipeline passed. There may still be manual validation requirements. Moderator-Approved One of the Moderators has reviewed and approved this PR New-Package Publish-Pipeline-Succeeded Validation-Completed Validation passed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants