feat(session): artifacts panel and inline annotations#42
Merged
Conversation
Surface a session's substantial outputs and a review loop in the right sidebar (Scratchpad / Artifacts / Annotations tabs): - Artifacts: path-keyed, edit-aware registry that reconstructs each file's latest state from write/edit and simple mv/git mv/rm; sandboxed HTML/SVG and inline Markdown preview; copy/download; a help (?) modal explaining the bash staleness limitation. - Annotations: offset-anchored highlights on transcript messages and artifact source, persisted in SQLite (/api/annotations) and synced across tabs via an `annotations` SSE snapshot; a mobile-friendly selection → note-modal flow; and "send notes to pi" that formats notes (file path + line numbers) into the composer. Serialize SQLite writes (SetMaxOpenConns(1)) and disable e2e auto-title noise.
Add artifacts and annotations sequence-flow docs; update architecture docs (backend handler map + SQLite tables + SSE events, frontend module list, system overview) and AGENTS.md to reflect the new /api/annotations endpoint, the `annotations` SSE event, and the new web/src/session/ modules.
Surface two server-backed settings (artifacts:enabled, artifacts:include, default *.md, *.html) so users can hide the Artifacts tab or scope it to specific paths. Filtering is a pure frontend pass over the unchanged registry: matching file artifacts are kept, chat snippets are dropped when any filter is active, and the panel's empty state links to Settings when artifacts are hidden. Disabling hides the tab entirely (falling back to Scratchpad).
The .right-sidebar-tab { display: inline-flex } rule overrode the [hidden]
attribute, so disabling "Show Artifacts panel" set tab.hidden but the tab stayed
visible. Add a .right-sidebar-tab[hidden] { display: none } rule. Reorder the
tabs to Scratchpad / Annotations / Artifacts. Strengthen the disabled-tab E2E to
assert real visibility (not just the property) so it catches this class of CSS bug.
Listen for the storage event in the session page and re-run the artifact filter when artifacts:enabled/include changes in another tab, so toggling on /settings takes effect without reloading the open session. E2E drives a second tab.
# Conflicts: # internal/ui/live_templates/styles/settings.css
…e is saved Saving a note now fires an onCreate callback that opens the right sidebar if it's collapsed and switches to the Annotations tab, so the just-created note is always visible where it lands.
…ile send On mobile the right sidebar is a full-screen overlay, so "Send N notes to pi" now fires an onSend callback that collapses the sidebar (mobile only) before the just-filled composer is focused, leaving it visible and ready to type into.
Contributor
Author
Annotation panel UX: reveal on save + mobile sendTwo follow-up commits improving how the right sidebar behaves around annotations:
Tests
|
Resolve import-block conflict in web/src/session/session.js by keeping both the artifacts/annotations imports (this branch) and the load-earlier banner import (origin/main).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an in-browser review surface to the session viewer via the right sidebar (Scratchpad / Artifacts / Annotations tabs). The motivation: a long agent session produces files and decisions buried in a linear transcript — this makes the outputs easy to find, preview, and review, and lets you push structured feedback straight back to the agent.
write/edit, plus a conservativemv/git mv/rmrecognizer; arbitrary shell is intentionally left alone). Source view with copy/download, sandboxed HTML/SVG preview and inline Markdown preview, and a help (?) modal that explains the bash-staleness limitation in plain language.artifacts:enabled,artifacts:include, default*.md, *.html) let users hide the Artifacts tab entirely or scope it to specific paths. Filtering is a pure frontend pass over the unchanged registry (artifact-filter.js): matching file artifacts are kept; loose chat snippets are dropped whenever a filter is active; the empty state links to Settings when artifacts are hidden. Disabling hides the tab and falls back to Scratchpad./api/annotations, GET/POST/DELETE) and synced across tabs via anannotationsSSE snapshot. Mobile-friendly selection → note-modal flow (selectionchangetrigger for touch). "Send notes to pi" groups notes by file with line numbers and fills the composer with a directive framing.annotationstable + handlers; SQLite pool capped to one connection (SetMaxOpenConns(1)) so concurrent writers queue instead of hitting "database is locked".artifacts.md/annotations.mdsequence-flow deep-dives (artifacts.md now covers the filtering model); architecture docs and AGENTS.md updated for the new endpoint, SSE event, and frontend modules.Related issue
Closes #
Type of change
feat— new featurefix— bug fixdocs— documentation onlyrefactor— code change that neither fixes a bug nor adds a featurestyle— formatting / UI styling, no behavior changetest— adding or updating testschore— build, tooling, or maintenanceLive vs. Export
internal/ui/live_templates/in sync withweb/src/session/changesIsLive, so the layers are no-ops in exported Gist snapshotsTesting
make checkpasses (test + build + vet)vitest) cover the change — registry/panel/filter, annotation range/api/layer, tab controller (445 tests)go test ./...) cover the change —annotations_test.go(create/list/upsert/delete/validation/scoping)artifacts.spec.tsincl. include-filter / empty-state / disabled-tab cases,annotations.spec.ts) across desktop, mobile, and iPad projects