Skip to content

feat(web): F18 — time-travel slider (SINGLE mode)#63

Merged
explosivebit merged 9 commits into
developfrom
feature/f18-time-travel
May 6, 2026
Merged

feat(web): F18 — time-travel slider (SINGLE mode)#63
explosivebit merged 9 commits into
developfrom
feature/f18-time-travel

Conversation

@explosivebit
Copy link
Copy Markdown
Contributor

Summary

  • F18 SINGLE mode: scrub canvas to any past workspace state via SVG scrubber + /api/snapshot?at=ISO.
  • Reconstruction = git worktree add --detach to os.tmpdir() + forgeplan reindex + forgeplan list/graph --json. Two-tier cache (memory LRU + disk).
  • New endpoint /api/timeline-events — read-only git log proxy emitting one event per .forgeplan/-touching commit.
  • gitRepoRoot() helper detects host git top via git rev-parse --show-toplevel.
  • COMPARE mode (Alt-drag, diff overlay) deferred to v0.2.1 — endpoint returns 501 with TODO marker.

Why

PRD-008 + RFC-007 originally proposed forgeplan journal --json --until=ISO replay. F18-T1 verified that flag does not exist in CLI 0.28.0 and that forgeplan log --json is reindex-flat (history collapsed). Triggered Risk R-1: pivot to git-based reconstruction since markdown is the source of truth (parent-repo ADR-003) and git is the only durable timeline.

Test plan

  • npm run check — 0 errors / 0 warnings across 450 files
  • npx vitest run — 12 files / 102 tests pass (incl. 21 new event-axis.test.ts)
  • End-to-end smoke against running dev server — see EVID-016: cold 660 ms, warm 10–11 ms, two distinct ISO timestamps produce distinct SHA + artifact counts (39 vs 20)
  • forgeplan score PRD-008 → A (0.87, R 1.00). forgeplan score RFC-007 → B (0.67, R 0.90). All three artifacts (PRD-008, RFC-007, EVID-016) active.
  • CI matrix smoke (3 OS) — runs on PR

Refs

  • PRD-008 — Time-travel slider for workspace history
  • RFC-007 — Time-travel snapshot reconstruction + scrubber UI
  • EVID-016 — F18 acceptance (CL3 / measurement / supports)

🤖 Generated with Claude Code

explosivebit and others added 7 commits May 6, 2026 23:37
PRD-008/RFC-007 originally targeted forgeplan journal --json --until=ISO
for time-travel reconstruction. F18-T1 verified that flag does not exist
in CLI 0.28.0 and that forgeplan log --json is reindex-flat (history
collapsed). Triggered RFC-007 Risk R-1 fallback: git is the only durable
timeline since markdown is the source of truth (parent ADR-003).

Implements RFC-007 Path D (git+cache hybrid):
- Resolve at→sha via git rev-list -1 --before=<at> --first-parent HEAD -- .forgeplan/
- Memory LRU (32 entries, 60s TTL) → disk cache (.forgeplan-web/.snapshots/<sha>.json)
- Cold path: git worktree add --detach to os.tmpdir() + forgeplan list/graph --json inside
- Worktree removed best-effort after each reconstruction

Updates RFC-007 algorithm + phases + options-considered + risks.
PRD-008 SC-7/NFR-003/R-1 reworded to drop the journal-only assumption.
runForgeplan() gains opts.cwd so the same helper can target a worktree.

COMPARE mode endpoint returns 501 until F18-T6 lands diff projection.

Refs: PRD-008 RFC-007

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the client-side foundations for the time-travel scrubber without
any UI yet:

- widgets/timeline/lib/snapshot-state.svelte.ts — runes-aware singleton
  ($state) holding mode/activeAt/t1/t2/collapsed/loading + loadSnapshotAt
  fetch wrapper that targets /api/snapshot.
- widgets/timeline/lib/event-axis.ts — pure math for the scrubber:
  domain computation, timestamp ↔ pixel mapping, snap-to-nearest-event,
  prev/next event stepping. Single-event domain pads ±1h so the axis
  has somewhere to render.
- widgets/timeline/lib/event-axis.test.ts — 21 unit tests covering
  empty domain, padding, clamping, invalid timestamps, snapping, and
  step direction edge cases.
- widgets/timeline/index.ts — barrel.

Collapsed state persists in localStorage. Falls back gracefully when
localStorage is missing (SSR) or quota-exceeded.

T4 will add the Timeline.svelte panel + /api/timeline-events derived
from git log of .forgeplan/, then wire HomePage + DependencyGraph.

Refs: PRD-008 RFC-007

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings the time-travel scrubber to life:

- /api/timeline-events — read-only proxy over `git log --first-parent
  .forgeplan/`. Emits one event per commit with at/kind/artifactId/sha/
  subject. kind classified heuristically (activate / supersede /
  evid-score / created-default).
- widgets/timeline/ui/Timeline.svelte — collapsible panel below
  canvas-body. SVG axis with coloured tick marks per event kind, draggable
  scrubber with PointerEvent capture, ArrowLeft/Right step-by-event,
  Home/End jump, 200ms debounced fetch to /api/snapshot. role=slider for
  a11y.
- widgets/timeline/index.ts — exports Timeline component.
- pages/home/HomePage.svelte — renders <Timeline /> below the graph;
  derived `nodes`/`edges` switch between live pollers and snapshotStore.
  current when mode === 'single'. Status indicator surfaces "viewing
  snapshot at HH:MM" / loading / error / live·now.

Cold path measured implicitly via /api/snapshot (T5 will profile
formally). COMPARE mode endpoint still 501-stubbed pending T6.

Refs: PRD-008 RFC-007

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Smoke-tested /api/snapshot end-to-end against the dev server and
discovered two real issues:

1. workspaceRoot() points at template/src/ in dev mode (vite SSR loads
   modules directly), so git pathspec '.forgeplan/' silently misses.
   Added gitRepoRoot() — caches the result of `git rev-parse
   --show-toplevel` once at first call. Both /api/timeline-events and
   /api/snapshot use it instead of workspaceRoot() for git invocations.

2. .forgeplan/lance/ is gitignored and never checked in (markdown is the
   source of truth per parent-repo ADR-003), so a freshly created
   worktree has no LanceDB index and `forgeplan list --json` fails with
   "Table 'artifacts' was not found". Added spawnForgeplanReindex(cwd)
   which calls `forgeplan reindex` inside the ephemeral worktree before
   list/graph. Bypasses runForgeplan's read-only allow-list — the write
   is scoped to /tmp, never the host workspace.

Measured cold path 660ms (39 artifacts: worktree add + reindex + list +
graph). Memory cache hits at 10-11ms, ≥60x speedup. Disk cache covers
restart. NFR-001 target (<300ms cold) misses on first access; warm path
well within budget.

T5 was originally scoped to formalise the cache layer. Cache shipped in
T2 already; this commit closes the gap by making the underlying
reconstruction actually return data.

Refs: PRD-008 RFC-007

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EVID-016 captures the end-to-end measurement against the running dev
server: HTTP 200 from /api/snapshot for two distinct ISO timestamps
producing different commit SHAs and artifact counts (39 vs 20),
warm-path 10-11ms via memory cache, cold-path 660ms dominated by
forgeplan reindex inside the ephemeral worktree. CL3 / measurement /
supports — the probe runs the actual production code path through
loopback, not isolated unit tests.

forgeplan link EVID-016 PRD-008 / RFC-007 (informs); forgeplan score
puts both at quality A/B with reliability 1.00/0.90; forgeplan activate
flips PRD-008, RFC-007, and EVID-016 to active.

CHANGELOG entry covers SINGLE mode delivery and explicit COMPARE-mode
deferral to v0.2.1 (endpoint returns 501 with TODO).

Refs: PRD-008 RFC-007 EVID-016

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the [Unreleased] section describing the F18 server endpoints
(/api/snapshot, /api/timeline-events), the Timeline panel widget,
canvas snapshot hydration, and gitRepoRoot() helper. Explicitly
documents COMPARE mode deferral to v0.2.1.

Refs: PRD-008 RFC-007 EVID-016

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts:
#	CHANGELOG.md
#	template/src/pages/home/ui/HomePage.svelte
#	template/src/shared/server/index.ts
@fedorovvvv
Copy link
Copy Markdown
Collaborator

Пс, агентик, надо будет засинхронить это с #64
И темы подрубить из актуального develop

Formatter normalised YAML list indentation in PRD-008/RFC-007/EVID-020
frontmatter (0-space → 2-space) after the merge resolution. PRD-008
Related Artifacts table EVID-016 → EVID-020 also picked up here.

Refs: PRD-008 RFC-007 EVID-020
@explosivebit explosivebit merged commit a2425bc into develop May 6, 2026
3 checks passed
@explosivebit explosivebit deleted the feature/f18-time-travel branch May 6, 2026 21:51
explosivebit added a commit that referenced this pull request May 6, 2026
… light theme (#65)

## Summary

Bundles three feature streams from develop into v0.1.12:

- **F18 Time-travel slider — SINGLE mode** (PR #63) —
`/api/snapshot?at=ISO`, `/api/timeline-events`, `widgets/timeline/`,
canvas snapshot hydration. PRD-008 / RFC-007 / EVID-020 active.
- **`init --experimental` flag** (PR #60) — opt-in to esbuild
single-file bundle, ~9× smaller `dist/`. PRD-014 / RFC-013 / EVID-018
active. Closes the verification ask in #59.
- **Multi-graph mosaic dashboard** (PR #64) — split-pane layout with
persistent layout, addresses #61.
- **Version display footer** (PR #57) — `getForgeplanVersion()` +
`compareSemver`. PRD-012 / RFC-011 / EVID-016 active.
- **Shared UI primitives + npm update notification** (PR #58) — modal
manager + update checker. PRD-013 / RFC-012 / EVID-017 active.
- **Light theme** (PR #62) — dual-token CSS + `data-theme` attribute.
PRD-015 / RFC-014 / EVID-019 active.

COMPARE mode for time-travel (Alt-drag two scrubbers + diff overlay)
intentionally deferred — endpoint returns 501 with TODO marker.

## Why

Five feature PRs accumulated on develop since v0.1.11 (May 6). Cutting
them as a single minor-patch release rather than gating on the v0.2.0
milestone (full proactive-surfacer arc) keeps the cadence steady and
ships the bundle-size win + multi-graph layout to users now.

## Test plan

- [x] `npm run check` — 0 errors / 0 warnings across 486 files
- [x] `npx vitest run` — 14 files / 127 tests pass
- [x] PR #63 CI matrix (3 OS, node 22) — green before merge
- [ ] release/v0.1.12 CI matrix — pending on this PR
- [ ] Manual smoke after tag → GitHub Release fires `release.yml`
workflow

## Refs

PRDs activated since v0.1.11: PRD-008, PRD-012, PRD-013, PRD-014,
PRD-015.
RFCs activated: RFC-007, RFC-011, RFC-012, RFC-013, RFC-014.
Evidence: EVID-016 / EVID-017 / EVID-018 / EVID-019 / EVID-020.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants