Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ on:
description: "GitHub-verified signed release tag"
type: string
required: true
default: v0.0.2
confirmation:
description: "Enter STAGE-<tag>, for example STAGE-v0.0.2"
type: string
Expand Down Expand Up @@ -93,7 +92,7 @@ jobs:
assert.equal(pkg.homepage, "https://docs.0xbuff.com/docs/throughline");
assert.equal(pkg.repository?.url, "git+https://github.com/0xbuffdev/throughline.git");
assert.deepEqual(Object.keys(pkg.exports).sort(),
[".", "./react", "./examples", "./styles/throughline.css"].sort());
[".", "./remark", "./react", "./examples", "./styles/throughline.css"].sort());
NODE

- name: Install frozen dependencies
Expand All @@ -102,6 +101,10 @@ jobs:
run: pnpm audit:source
- name: Typecheck
run: pnpm typecheck
- name: Typecheck and bundle local playground
run: |
pnpm preview:typecheck
pnpm preview:build
- name: Compiler tests
run: pnpm test:run
- name: Install Chromium
Expand All @@ -117,6 +120,11 @@ jobs:
- name: Verify packed Vite/React browser hydration
run: pnpm audit:browser

- name: Verify framework integration consumers
run: pnpm audit:frameworks
- name: Verify Markdown host consumers
run: pnpm audit:markdown-hosts

- name: Pack reviewed tarball and checksum
shell: bash
run: |
Expand Down
52 changes: 12 additions & 40 deletions AGENTS.md
Comment thread
christophersesugh marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,10 @@ documentation before changing observable behavior. The source and

## Development and verification

Use Node.js 24+, pnpm **11.2.2**, and the committed `pnpm-lock.yaml`.
This is a **single package**, not a workspace. Do not introduce workspace
filters or application-specific build steps.

```sh
pnpm install --frozen-lockfile
pnpm audit:source
pnpm typecheck
pnpm test:run
pnpm exec playwright install chromium
pnpm test:browser:run
pnpm build
pnpm audit:licenses
pnpm audit:pack
pnpm audit:browser
pnpm audit:frameworks
pnpm audit:markdown-hosts
```

Run the checks relevant to each change and the full sequence before
submitting a release-related PR. `audit:licenses` requires a build;
`audit:pack` and `audit:browser` exercise the packed package in
independent Node, TypeScript, React SSR, and Vite/browser consumers.
The framework and Markdown-host audits install the freshly packed package in disposable projects using committed npm lockfiles and `npm ci`. Registry access is required. Refresh intentional host-version updates with `node scripts/fixtures/update-integration-locks.mjs` and review the four generated lockfiles.
Some consumer checks install public dependencies. Report any skipped or
failed checks accurately; do not suppress failures with focused or
skipped tests.
Use Node.js 24+, pnpm 11.2.2 and the committed lockfile in this
single-package repository. Run the relevant tests for each change and
follow [verification and release procedures](docs/releasing.md) for a
full release candidate. Never misrepresent skipped or failed checks.

## Repository map

Expand All @@ -63,9 +40,9 @@ skipped tests.
- `src/examples.ts`: public examples and acceptance fixtures.
- `src/**/__tests__/`, `scripts/`: regression, browser, packaging,
source-boundary, and license checks.
- `docs/`: grammar, authoring, domain, and architecture documentation.
- `docs/`: grammar, authoring, integration and architecture documentation.
- `.github/workflows/ci.yml`: read-only quality checks.
- `.github/workflows/publish.yml`, `RELEASING.md`: manual npm
- `.github/workflows/publish.yml`, `docs/releasing.md`: manual npm
staging, provenance, and maintainer approval procedures.

## Public API and compatibility
Expand Down Expand Up @@ -111,21 +88,16 @@ Preserve deterministic compilation and stable seeking through frames.
Document purpose, compatibility impact, implementation, and checks
actually run. Keep `README.md`, relevant `docs/`, tests, and
`CHANGELOG.md` in sync with user-visible changes.
- This project has one maintainer. Final review, required signing,
merges, Git tags, and npm release approvals are maintainer actions;
never invent other reviewers or claim those actions happened.
- Final review, any required signing, merges, Git tags and npm release
approvals require maintainer authorization. Never invent approvals or
claim unperformed actions are complete.
- Do not publish, stage, approve, move release tags, change repository
visibility, or rewrite Git history without explicit authorization.
- Publication uses an immutable, GitHub-verified signed tag and the
manually dispatched `publish.yml` workflow. Only its protected
`npm-publish` staging job receives `id-token: write`. No npm
token or OIDC write permission belongs in quality CI. npm staging
is not a public release; final npm 2FA approval is separate.
- The repository's public Git history includes a historical reference
to private planning material. Treat this as an unresolved exposure;
inspect historical refs and credentials when relevant. Removing a
reference from the current tree does not erase already-public history.
Review rights and third-party attribution before distributing changes.

See `CONTRIBUTING.md`, `SECURITY.md`, and `RELEASING.md` for the
corresponding contributor, vulnerability-reporting, and release details.

See `CONTRIBUTING.md`, `SECURITY.md` and `docs/releasing.md` for
contribution, security reporting and release procedures.
227 changes: 47 additions & 180 deletions CHANGELOG.md
Comment thread
christophersesugh marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
@@ -1,196 +1,63 @@
# Changelog

Notable changes to Throughline are recorded here. Package versions follow
Semantic Versioning independently of the version-1 trace and program schemas.
All notable changes to Throughline are recorded here. Package versions follow
[Semantic Versioning](https://semver.org/) independently of version-1
program and trace schemas. Changes are grouped using
[Keep a Changelog](https://keepachangelog.com/).

## Unreleased
## [Unreleased]

### Fixed (cross-browser toolbar)

- Keep the wide playback toolbar compact in WebKit without constraining native selector height; verify the compact bar still encloses every control across browser engines.

### Fixed (narration review)

- Coordinate browser-global speech synthesis between multiple Throughline players; newer narration takes over while displaced players pause and stop owning cancellation.
- Pause with an accessible error on unexpected speech interruption instead of stalling autoplay or advancing a failed utterance.
- Restart narration for repeated seeks to the same step and replace stale speech when authored guidance changes.
- Keep the dual-audio 360px breakpoint while restoring a generic three-row fallback at <=300px content widths, covering players with no audio, only narration, only step tones, or both. Verify embedded layouts with actual browser element bounds.

### Added (opt-in caption narration)

- Offer muted-by-default browser caption narration separately from step tones, using speech-synchronized playback without new runtime dependencies.
- Pause/resume speaking with playback; cancel on seek, scenario change and unmount; preserve the original timer when narration is off.


### Changed (development preview sound)

- Expose the existing opt-in Web Audio speaker control in every local playground example and scenario comparison, initially muted. No default audio in the published React player and no new audio dependencies.


### Changed (state hierarchy and motion)

- Give the present its own color. `--thl-active` (new) marks the current send, its label and the Play button; `--thl-trail` becomes the same hue washed out for history; `--thl-change` becomes the single warm color for changed values. Previously focus and change were near-identical neutrals (about 0.02-0.03 apart in OKLab) and history was the only colored mark.
- Keep trail color on strokes and arrowheads only; visited and revealed edge labels stay `--thl-muted` so 10px text keeps at least 4.5:1 contrast.
- Reserve dashes for structure. Selected nodes and keyboard focus are an outer ring (`.thl-ring`) instead of a dashed outline and a 3px stroke that matched authored focus; the ring is the first-rect-safe sibling drawn after the node body.
- Animate only a forward single step. Seeking the timeline, rewinding and replacing the trace settle on the final frame instead of replaying the send. The decision is latched per step in the player.
- Sequence motion within a step: the arrow draws, its arrowhead and label fade in, then a changed value flashes (waiting for the arrow when the step has a send). Durations derive from `--thl-step-ms`, which the player sets from the playback speed.

### Fixed (reduced motion)

- Reduced motion did not disable the send animation: the opt-out selector `.thl-transferred .thl-edge` was less specific than the rule that set the animation, so the animation still ran under `prefers-reduced-motion: reduce`. Animations are now declared only under `prefers-reduced-motion: no-preference`, and a test fails on any unguarded animation rule.

### Changed (responsive player controls)

- Add a small consistent gap between the visualization and its optional title and bottom controls.

- Place chapter and diagram navigation beside transport controls in one compact adaptive footer, with 14px visible icons, slimmer native inputs and 40px mobile hit targets.
- Move variable-length captions below the footer as accessible step disclosures, retaining a one-line preview and a bounded independently scrollable detailed explanation.
- Keep the diagram and playback controls stationary as authored notes and evidence change between steps.


### Improved (workflow playback visual review)

- Retain authored node and connector activity across later steps; seeking
backwards reconstructs the earlier trail without leaking future state.
- Animate each current send directly on its existing arrow path instead of
drawing a second line; repeated sends restart the same-path animation.
- Keep shown-but-unsent links visibly distinct, preserve partial
collapsed-group provenance and announce cumulative progress to screen readers.
Neither transfers nor tinted endpoints imply acknowledgment or persistence.


### Changed (pre-release visual review)

- Add a source-backed Vite preview for browser inspection before publishing or deploying.
- Compact group/node/cell geometry, reduce panel whitespace, set 2px corners and 1.5rem player padding, and replace boxed icon actions with accessible borderless hit targets.
- Move chapter, viewport and hierarchy navigation below the caption into a common footer with playback controls; keep the authored narrative in the caption.
- Size the SVG stage from stable layout content rather than a 52vh placeholder; cap only dense content and retain mobile fit/zoom semantics.
- Place visible relation labels away from node values and competing labels; when space is insufficient, keep the full relation in its SVG title rather than drawing over nodes.


### Hardened (TL-I16 candidate)

- Reject unsupported trace versions and missing frame arrays at the React reader boundary; this is not full validation of untrusted serialized state.
- Reuse a shared node-box set during dense edge routing and record cyclic-layout diagnostic benchmarks.
- Exercise hostile authored text in Chromium and rejected reader versions in isolated packed React SSR.
- Record source verification and outstanding manual, documentation-app and release gates.

### Added (TL-I15)

- React-only guided chapters and authored causal explanations with explicit,
validated compiled-event provenance and accessible text parity.
- Independent scenario selector and deterministic checkout success, terminal
failure and timeout/retry/recovery fixtures.
- Unit and Chromium regressions for evidence, chapter seeking, isolated
scenario switching and safe/narrow-screen guidance rendering.

### Fixed (TL-I15 review follow-up)

- Provide a dedicated Restart chapter button to seek to the current chapter\'s
first frame even when its option is already selected.
- Reconcile removed scenario IDs to the fallback instead of silently selecting
a previously removed option on reinsertion; test empty/populated transitions.

### Compatibility

- Only additive optional React props/exports, no version-1 schema, grammar
or legacy player-default changes.


### Fixed (TL-I14 review follow-up)

- Give undeclared lanes separate internal identities even when their names equal an explicit group ID; resolve geometry by lane name, not an ambiguous ID fallback.
- Highlight a collapsed boundary when a real constituent relation sends, without animating the entire aggregate or implying a destination write.
- Show and announce authored focus and changed state inside collapsed summaries; compile the actual published hierarchy fence as a regression fixture.

### Added (TL-I14, compatibility proposal pending)

- Optional hierarchical group IDs, explicit parent references and validated `group "Name" id foo [under parent] as row|column|tree` syntax; legacy flat groups are unchanged.
- Read-only collapsed summaries, exact provenance of aggregated cross-boundary links, nested deterministic layouts, drill-down/breadcrumb controls and regression coverage.

### Compatibility

- Program and trace schemas remain version 1; old compilers reject the new opt-in syntax, and old players may show hierarchical traces as flat groups.
- Merge of the source changes is blocked on approval of the separate group-model compatibility ADR in `context`.



### Fixed

- Correct two-finger pinch translation when zoom and midpoint movement occur
together; focus now centers edge-positioned entities accurately.
- Bound the physical SVG height for dense, narrow diagrams while preserving
fit-to-view aspect ratio. Let page scrolling continue at zoom limits and
preserve native Ctrl/Meta+wheel browser zoom.
- Add unit and Chromium regressions for each TL-I13 review finding.
## [0.1.0]

### Added

- TL-I13 guided viewport: bounded pan, zoom and fit-to-view with wheel, keyboard
and touch gestures, selected-entity inspection and explicit follow-active mode.
- Manual camera precedence, trace replacement reset and corresponding unit and
browser regressions without changing the version-1 trace schema.
- React-independent scene projection with deterministic entity, link and
transfer provenance, including focus filtering and stable seeking.
- Optional nested groups, validated parent references, collapsible summaries,
drill-down controls and breadcrumbs; existing flat groups remain valid.
- Bounded pan, zoom, fit-to-view and follow-active navigation with mouse,
keyboard and touch controls, plus selected-entity inspection.
- Authored guided chapters, evidence-backed explanations and independent
scenario comparisons, including deterministic distributed-checkout examples.
- Separate opt-in browser caption narration synchronized with playback;
step-tone sonification remains optional and off by default.
- Build-time Remark validation via `@0xbuff/throughline/remark` and opt-in
literal-source MDX conversion with the React `ThroughlineEmbed` component.
- Native fullscreen support and a source-backed Vite playground for visually
inspecting examples and responsive playback during development.
- Tested integration patterns for Fumadocs Unified, Next.js App Router, Astro,
react-markdown, mdx-bundler and markdown-to-jsx.
- Expanded keyed React reconciliation and distributed checkout reference traces.

### Changed

- Introduce a React-independent, view-only scene projection with stable node,
edge and transfer provenance, selection/focus filtering, and deterministic
fallback layout clipping. Hidden/stale focus targets retain overview,
projection-owned data is detached and frozen, and React preserves authored
group layout preferences. Existing playback and trace schemas are unchanged.

### Tested

- Add packed package integration fixtures for Fumadocs Unified, Next.js App Router, Astro React islands, react-markdown, mdx-bundler and markdown-to-jsx, with frozen npm consumer locks, browser hydration/interaction checks, unchanged-document regressions, and a release-gated integration guide.

### Added

- Add opt-in Remark MDX JSX output with literal source attributes and validated
component identifiers, plus a memoized `ThroughlineEmbed` React bridge.
- Verify MDX escaping, atomic multi-fence validation, registered-component
rendering, stable-source playback and independent packed consumers.
- Redesigned the optional React 19 player with responsive step-based controls,
accessible detail disclosures, a state inspector and light/dark/auto themes.
- Updated player CSS tokens to distinguish current activity, accumulated
history and changed values; selection uses a separate focus ring.
- Playback now animates only a single forward step; seeking, rewinding and
trace replacement settle directly on the target frame.
- Persistent activity trails and collapsing groups retain the underlying
authored relation and event provenance without implying durable writes.

### Fixed

- Use verified source coordinates for Remark body diagnostics in nested Markdown;
do not falsely attribute unpositioned semantic errors to the fence header.

### Added

- Added dependency-free `@0xbuff/throughline/remark` validation subpath for
parser-owned `thl` fences, source-positioned build failures and unchanged
Markdown ASTs; MDX rendering remains a separate integration.

### Fixed

- Announce native fullscreen request failures without interrupting in-page playback;
expose player keyboard shortcuts and descriptive focus instructions.
- Make ended sonification voices safe to clean up after step changes or unmount,
and stop/restart the cue when replacing a trace with an equal frame count.
- Add keyboard/slider, trace replacement during playback, reduced-motion CSS,
fullscreen refusal and sound lifecycle regression coverage.

### Changed

- Redesigned the React player with an optional unbranded title, centered
visualization, borderless caption/count, and bottom playback controls.
- Introduced neutral OKLCH light/dark/auto CSS tokens and default `0.325rem`
radius while preserving existing trace/sonification contracts.

### Added

- Native fullscreen maximize/minimize toggle with safe unavailable-state
handling, browser state synchronization, and responsive controls.
- Browser regression tests for shell, theme overrides, fullscreen and sound.

### Added

- Expanded the keyed reconciliation reference to include its commit beat;
added a distributed checkout timeout, idempotent retry and recovery trace.
- Added deterministic seeking, transfer correctness, version/value-boundary,
and browser rendering regressions for sophisticated reference examples.
- Documented teaching questions, current player limitations and the
unsupported serialized trace-version reader gap.
- Prevented a compact playback-toolbar height discrepancy in WebKit while
preserving visible, usable controls across engines and narrow widths.
- Corrected reduced-motion behavior so send animations are disabled when
the operating system requests reduced motion.
- Improved narration ownership across multiple players, speech interruption
handling, repeated seeking and stale-utterance cancellation.
- Restored responsive control layouts at 300px and smaller widths across
combinations of narration and sonification options.
- Corrected two-finger pinch translation, edge-positioned camera focus and
scroll behavior at zoom limits.
- Fixed collapsed-group summaries, name collisions between lanes and explicit
group IDs, and authored focus/changed-state announcements.
- Fixed chapter restart, removed-scenario fallback, fullscreen failure
announcements, and audio cleanup during trace replacement or unmount.
- Improved Remark diagnostics for nested Markdown and validated input
boundaries for unsupported serialized trace versions.

## [0.0.2] — 2026-11-08

Expand Down
Loading
Loading