Add active path highlighting in html exports (#929)

* fix(coding-agent): HTML export sidebar click scrolls instead of truncating branch

Previously, clicking a message in the sidebar tree would set that message
as the new leaf, causing getPath() to only return messages up to that point
and hiding all messages below it.

Now handleTreeNodeClick() checks if the clicked entry is on the current path:
- If yes: just scrolls to it without re-rendering
- If no: finds the actual leaf of that branch and navigates to it, then
  scrolls to the clicked message

Added childrenMap for parent->children lookup and findBranchLeaf() to
traverse down to a branch's leaf.

* fix(coding-agent): HTML export sidebar click scrolls instead of truncating branch

Previously, clicking a message in the sidebar tree would set that message
as the new leaf, causing getPath() to only return messages up to that point
and hiding all messages below it.

Now handleTreeNodeClick() checks if the clicked entry is on the current path:
- If yes: scrolls to it and updates the active marker
- If no: finds the branch's leaf, navigates to it, then scrolls to clicked message

Adds currentTargetId to track the selected entry separately from currentLeafId
(which branch to display), so the active marker follows user selection.

* most recent path wins

* reuse method

* revert

* feat(coding-agent): highlight active path in HTML export sidebar

- Add subtle accent background tint to in-path nodes
- Dim off-path nodes to 50% opacity (restore on hover)
- Makes current branch visually distinct in tree navigation

* docs(coding-agent): move changelog entry to Unreleased and add attribution

* chore(coding-agent): remove dead code and fix changelog attribution

- Remove unused childrenMap, findBranchLeaf, handleTreeNodeClick, scrollToEntry
- Split changelog entry: navigation (#853 by @mitsuhiko), highlighting (#929 by @hewliyang)
This commit is contained in:
Li Yang 2026-01-26 02:25:44 +08:00 committed by GitHub
parent b1211261be
commit 1675824ed3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 19 additions and 9 deletions

View file

@ -28,18 +28,17 @@
- Custom provider support via `pi.registerProvider()` with `streamSimple` for custom API implementations
- Added `custom-provider.ts` example extension demonstrating custom Anthropic provider with OAuth
### Fixed
- Extension `setWorkingMessage()` calls in `agent_start` handlers now work correctly; previously the message was silently ignored because the loading animation didn't exist yet ([#935](https://github.com/badlogic/pi-mono/issues/935))
- Off-by-one error in bash output "earlier lines" count caused by counting spacing newline as hidden content ([#921](https://github.com/badlogic/pi-mono/issues/921))
### Changed
- HTML export: clicking a sidebar message now navigates to its newest leaf and scrolls to it, instead of truncating the branch ([#853](https://github.com/badlogic/pi-mono/pull/853) by [@mitsuhiko](https://github.com/mitsuhiko))
- HTML export: active path is now visually highlighted with dimmed off-path nodes ([#929](https://github.com/badlogic/pi-mono/pull/929) by [@hewliyang](https://github.com/hewliyang))
- `/reload` now re-renders the entire scrollback so updated extension components are visible immediately
- Skill, prompt template, and theme discovery now use settings and CLI path arrays instead of legacy filters ([#645](https://github.com/badlogic/pi-mono/issues/645))
### Fixed
- Extension `setWorkingMessage()` calls in `agent_start` handlers now work correctly; previously the message was silently ignored because the loading animation didn't exist yet ([#935](https://github.com/badlogic/pi-mono/issues/935))
- Off-by-one error in bash output "earlier lines" count caused by counting spacing newline as hidden content ([#921](https://github.com/badlogic/pi-mono/issues/921))
- User package filters now layer on top of manifest filters instead of replacing them ([#645](https://github.com/badlogic/pi-mono/issues/645))
- Auto-retry now handles "terminated" errors from Codex API mid-stream failures
- Follow-up queue (Alt+Enter) now sends full paste content instead of `[paste #N ...]` markers ([#912](https://github.com/badlogic/pi-mono/issues/912))

View file

@ -144,6 +144,15 @@
}
.tree-node.in-path {
background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.tree-node:not(.in-path) {
opacity: 0.5;
}
.tree-node:not(.in-path):hover {
opacity: 1;
}
.tree-prefix {

View file

@ -665,6 +665,7 @@
// ============================================================
let currentLeafId = leafId;
let currentTargetId = urlTargetId || leafId;
let treeRendered = false;
function renderTree() {
@ -681,12 +682,12 @@
for (const flatNode of filtered) {
const entry = flatNode.node.entry;
const isOnPath = activePathIds.has(entry.id);
const isLeaf = entry.id === currentLeafId;
const isTarget = entry.id === currentTargetId;
const div = document.createElement('div');
div.className = 'tree-node';
if (isOnPath) div.classList.add('in-path');
if (isLeaf) div.classList.add('active');
if (isTarget) div.classList.add('active');
div.dataset.id = entry.id;
const prefix = buildTreePrefix(flatNode);
@ -721,10 +722,10 @@
for (const node of nodes) {
const id = node.dataset.id;
const isOnPath = activePathIds.has(id);
const isLeaf = id === currentLeafId;
const isTarget = id === currentTargetId;
node.classList.toggle('in-path', isOnPath);
node.classList.toggle('active', isLeaf);
node.classList.toggle('active', isTarget);
const marker = node.querySelector('.tree-marker');
if (marker) {
@ -1351,6 +1352,7 @@
function navigateTo(targetId, scrollMode = 'target', scrollToEntryId = null) {
currentLeafId = targetId;
currentTargetId = scrollToEntryId || targetId;
const path = getPath(targetId);
renderTree();