Commit Graph

836 Commits

Author SHA1 Message Date
Tommy D. Rossi 5637a13003 fix: guard timestamp recording against cross-session contamination
If recording is stopped and restarted inside the same execute() call,
the finally block could append an interval from the old recording into
the new recording's executionTimestamps. Fix by comparing against the
snapshotted recordingStartedAt instead of just checking non-null.
2026-02-25 13:16:51 +01:00
Tommy D. Rossi a0b7af1adb fix: update playwright submodule with oracle review fixes 2026-02-25 13:12:58 +01:00
Tommy D. Rossi 1cad56f1a2 fix: recording session ID routing, IIFE for timestamps, default speed 5x
cdp-relay.ts:
- Fix pre-existing bug: recording HTTP routes (/recording/start, stop,
  status, cancel) were treating CDP session IDs (pw-tab-*) as executor
  session IDs, causing 'Session not found' errors. Now skip executor
  lookup when sessionId is a CDP session ID and pass it through directly
  to the extension for tab routing.

executor.ts:
- Use async IIFE instead of let+try for VM execution timestamp tracking.
  Cleaner pattern: const result = await (async () => { try/finally })()

ffmpeg.ts + skill.md:
- Change default idle speed from 4x to 5x
2026-02-25 13:12:41 +01:00
Tommy D. Rossi d84cdba528 feat: add page.onMouseAction callback + tests
Adds onMouseAction to playwright fork — an async callback on Page
that fires before every mouse action (move/down/up/wheel). Covers
both page.mouse.* and locator-initiated actions.

Test validates:
- Callback fires for page.mouse.click() with correct coordinates
- Callback fires for locator.click() with resolved element center
- Callback stops firing when set to null
2026-02-25 12:57:41 +01:00
Tommy D. Rossi 2d0f4ac456 fix: address oracle review — shell injection, range validation, timestamp robustness
ffmpeg.ts:
- Replace exec() with spawn() for ffmpeg/ffprobe — no shell interpreter,
  no injection risk from filenames with special characters
- Filter invalid ranges in computeIdleSections() after clamping to video
  bounds (handles timestamps exceeding video duration)
- Use path.basename() for timer IDs instead of split('/') for Windows compat

executor.ts:
- Use try/finally around VM execution so execution timestamps are recorded
  even when code throws — the execution still occupied real time that should
  not be sped up in the demo video
- Snapshot recordingStartedAt before try to avoid race if stopRecording()
  is called inside the same execute() clearing the field
2026-02-25 12:51:48 +01:00
Tommy D. Rossi 95bda7acc7 feat: demo video creation — auto speed up idle sections during recordings
Add ffmpeg.ts with utilities for video manipulation:
- concatenateVideos: merge multiple video files with trim/scale/fps normalization
- speedUpSections: speed up arbitrary timestamp ranges in a single ffmpeg pass
- computeIdleSections: compute idle gaps from execution timestamps
- createDemoVideo: high-level wrapper that takes stopRecording() result and
  produces a sped-up video where idle time (between execute() calls) is fast-forwarded

Executor changes:
- Track execution timestamps (start/end in seconds) while recording is active
- startRecording wrapper resets tracking state
- stopRecording wrapper returns executionTimestamps alongside path/duration/size
- cancelRecording wrapper clears tracking state
- Expose createDemoVideo in the sandbox VM context

The recording timeline looks like:
  0s      5s   8s   12s  15s  20s  25s   30s
  ├───────┼────┼────┼────┼────┼────┼─────┤
          ▓▓▓▓▓     ▓▓▓▓▓     ▓▓▓▓▓▓▓▓▓
          exec1     exec2     exec3
  ░░░░░░░       ░░░░░       ░░░░░
  IDLE(4x)      IDLE(4x)    IDLE(4x)

A 1-second buffer (INTERACTION_BUFFER_SECONDS) is kept around each
execution at normal speed so viewers see context before/after actions.

Requires ffmpeg + ffprobe on the system.
2026-02-25 12:45:04 +01:00
Tommy D. Rossi 0d3ec43da3 fix: stop forcing light mode on connectOverCDP pages
Removed the preserveSystemColorScheme() workaround from executor.ts that was
mutating private Playwright internals via (context as any)._options to patch
around the forced light mode.

The root cause is now fixed in @xmorse/playwright-core@1.59.4: the default
colorScheme fallback in page.emulatedMedia() changed from 'light' to
'no-override', so Chrome respects the user's system color scheme.

Activated the previously-todo test that validates dark mode is preserved
after MCP connection (matchesDark: true, matchesLight: false).
2026-02-24 15:31:14 +01:00
Tommy D. Rossi 9c376b7637 website: brighter dark mode links, lighter diagram font weight
- Dark mode --link-accent: #79bbff → #aadcff for better visibility
- Diagram font-weight: 500 → 400 for thinner box-drawing and text
2026-02-24 15:22:30 +01:00
Tommy D. Rossi 6dca255bd7 website: tune diagram colors — darker structure, teal-green labels, heavier weight
- Structure chars darkened: #c0c0c0 → #999 (light), #555#666 (dark)
- Labels switched to teal-green: #0d7a5f (light), #6ee7b7 (dark)
- Removed bold from labels, bumped diagram font-weight to 500 so
  box-drawing characters aren't paper-thin at 400
2026-02-24 14:49:35 +01:00
Tommy D. Rossi 786c6bf395 new test for logs from iframes 2026-02-24 14:44:21 +01:00
Tommy D. Rossi 1a9c6ddcd0 website: add diagram Prism language, CodeBlock showLineNumbers prop, brighter dark mode links
- Custom 'diagram' Prism language: box-drawing chars get neutral color,
  text labels get a saturated blue so they pop against the structure
- CodeBlock gains showLineNumbers prop (default true) and skips Prism
  highlighting when lang is empty
- Diagram block in index page uses lang='diagram' with line numbers off
- Dark mode --link-accent bumped from #58a6ff to #79bbff for better
  visibility against dark backgrounds
2026-02-24 14:44:08 +01:00
Tommy D. Rossi c23eced495 Update .gitignore 2026-02-23 16:19:52 +01:00
Tommy D. Rossi cab71368e6 nn 2026-02-23 16:19:38 +01:00
Tommy D. Rossi d32a8c901e fix: auto-select extension with active targets when multiple Chrome profiles are connected
When multiple Chrome profiles have the playwriter extension installed, the
MCP fails with 'Multiple extensions connected. Specify extensionId.' even
if only one profile has playwriter-enabled tabs.

The relay's getExtensionConnection fallback now checks if exactly one
extension has active targets (connectedTargets > 0) and auto-selects it.
Falls through to the existing error when zero or multiple extensions are
active, so no regressions for single-extension setups.

The fix lives in the relay so all clients (MCP, Stagehand, raw CDP)
benefit. CLI session creation is unaffected — it still prompts the user
to pick a browser with --browser when multiple profiles are connected.

Fixes #52
2026-02-23 15:19:06 +01:00
Tommy D. Rossi 8f2dcc822e website: simplify code examples, tighten code letter-spacing
- Remove -s 1 from all CLI examples (kept in sessions section for isolation demo)
- Remove unnecessary await from -e expressions (CLI auto-awaits)
- Remove console.log wrappers where CLI auto-prints results
- Reduce code letter-spacing from 0.02em to 0.01em
2026-02-22 22:46:39 +01:00
Tommy D. Rossi e27c8ccdf2 website: update title, description and intro paragraph
- Title now mentions Chrome extension, CLI, and agents
- First paragraph rewritten to lead with what Playwriter is instead of 'You want your agent to...'
- Meta description updated to match new voice
2026-02-22 22:02:01 +01:00
Tommy D. Rossi f87b0243cd format 2026-02-22 15:21:38 +01:00
Tommy D. Rossi e475c2f582 readme: lead with 'uses your own Chrome' differentiator
The main selling point — using your actual Chrome session instead of
spawning a fresh browser — was buried in comparison tables halfway down.

Rewrote the tagline to highlight this upfront, added a short hero
paragraph explaining why fresh Chrome is a problem, and moved the
vs Playwright MCP comparison table to the top of the page.
2026-02-21 20:00:37 +01:00
Tommy D. Rossi b30d9e5f3f website: increase placeholder resolution from 32px to 64px
4x the pixel count for sharper pixelated placeholders.
All files still under 4KB so Vite inlines them as base64.
2026-02-21 17:06:56 +01:00
Tommy D. Rossi ad2ac529d4 website: fix code block line number alignment when lineHeight prop differs from default
The CodeBlock component passes lineHeight to the parent <div> but the <code>
element was inheriting line-height: 1.85 from the Prism CSS rule
(code[class*="language-"]) which has higher specificity than inheritance.
This caused line numbers and code lines to drift apart when a custom
lineHeight was passed (e.g. the architecture diagram at 1.5).

Fix: pass lineHeight as inline style on <code> so it overrides the CSS rule.
Also reduce diagram block line-height from 1.5 to 1.3 for tighter rendering.
2026-02-21 16:52:35 +01:00
Tommy D. Rossi ee948930fe website: move placeholders to src/assets for Vite base64 inlining, add LazyVideo component
Placeholders are now generated into src/assets/placeholders/ instead of
public/ so Vite's asset pipeline processes them. Since all are < 4KB,
Vite auto-inlines them as base64 data URIs via assetsInlineLimit — zero
extra HTTP requests for placeholders.

- Static imports resolve to data:image/png;base64,... at build time
- JSDoc on placeholder props documents why static imports are required
  (synchronous availability, Vite inlining) and warns against dynamic
  imports and public/ paths
- New LazyVideo component: same pixelated poster pattern, uses native
  <video preload="none" loading="lazy"> for zero-JS lazy loading
2026-02-21 15:58:21 +01:00
Tommy D. Rossi 3b3959f5ab website: add pixelated image placeholders with fade-in transition
Build-time script generates tiny 32px-wide versions of all images in
public/ using sharp. At runtime, PixelatedImage component renders these
with CSS image-rendering: pixelated (nearest-neighbor / point sampling)
for a crisp mosaic effect, then fades in the real image on load.

- Auto-discovers images in public/, skips placeholder- prefixed files
- Mtime check skips regeneration when placeholder is newer than source
- Callback ref handles cached images where onLoad fires before mount
- Explicit z-index prevents placeholder from covering the real image
- Runs automatically as part of pnpm build in website package
2026-02-21 15:22:39 +01:00
Tommy D. Rossi 00baca9c2b playwriter skill self improvement: reduce wasted context on JS-heavy sites
Add explicit guidance to use playwriter first for JS-rendered websites and blocking overlays, based on repeated failures where webfetch/curl returned empty shells and screenshots were used too early.

Key updates:\n- Add a hard 'when to use playwriter vs webfetch/curl' rule in the main skill docs\n- Add a 'snapshot before screenshot' rule to prevent slow image-first debugging loops\n- Add a concrete anti-pattern for JS-rendered sites in common mistakes\n- Add obstacle-handling flow for cookie/login/age-gate overlays\n- Add media extraction/download pattern using evaluate + Node fetch/fs\n- Update skill frontmatter description (and well-known discovery copies) so context-loaded summaries also include the JS-heavy-site rule
2026-02-21 13:10:57 +01:00
Tommy D. Rossi 1b98de0660 website: add lineHeight prop to CodeBlock, use relative values
Default 1.85 (~22px at 12px font), reduced to 1.5 for ASCII diagram.
Updated editorial-prism.css base to match.
2026-02-21 11:09:22 +01:00
Tommy D. Rossi 8871a3f36f website: user-centered copy rewrite, fix image layout shift, replace HTML entities
- Rewrite landing page copy to focus on user needs: agent controlling
  your browser, low context usage, unrestricted capabilities, collaboration
- Add Collaboration section (captchas, consent walls, getting agent unstuck)
- Replace HTML entities (&mdash; &apos; &ndash;) with JS string expressions
- Add width/height to screenshot image to prevent layout shift
- Add no-layout-shift requirement to AGENTS.md
2026-02-20 23:25:48 +01:00
Tommy D. Rossi 5c1ef5d332 website: increase code block line height from 18px to 24px 2026-02-20 23:08:17 +01:00
Tommy D. Rossi aaeb20643a website: rename liveline.css → editorial.css, liveline-prism.css → editorial-prism.css
Update all imports in globals.css, AGENTS.md, and _index.tsx comment.
2026-02-20 23:02:21 +01:00
Tommy D. Rossi 258f42527c website: move editorial tokens to globals.css, remove --ll- prefix
All CSS variables previously scoped under .liveline-page with --ll- prefix
are now at :root in globals.css with no prefix. Four names conflicting with
shadcn were renamed: --brand-primary, --brand-secondary, --link-accent,
--page-border.

Class renames: .liveline-page → .editorial-page, .liveline-article →
.editorial-article, .ll-bleed → .bleed, .ll-inline-code → .inline-code,
.ll-prose → .editorial-prose.

Filenames kept as-is for this commit to isolate the rename.
2026-02-20 23:02:02 +01:00
Tommy D. Rossi 2a2f4a9230 website: make liveline the index page, move old index to /github
- Renamed liveline.tsx → _index.tsx (landing page)
- Renamed _index.tsx → github.tsx (/github route)
2026-02-20 22:29:11 +01:00
Tommy D. Rossi 9ab7233d6a website: enable prerender for index route 2026-02-20 22:28:59 +01:00
Tommy D. Rossi 8eee5ce5d4 skill: add preference note to playwriter description
Clarify in the skill frontmatter that playwriter should be used over
other Playwright MCPs since it connects to the user's existing Chrome
instead of launching a new browser instance.
2026-02-20 22:18:13 +01:00
Tommy D. Rossi 44b367a927 website: fix dark mode, table contrast, prose opacity, add AGENTS.md
Dark mode fix: import liveline.css and liveline-prism.css via CSS @import
in globals.css instead of JS import in the route file. This brings them
into the Tailwind compilation chain so @variant dark works. @variant dark
silently fails in CSS files imported only via JS — documented this
constraint in website/AGENTS.md.

- Prism dark colors use CSS variables on :root with @variant dark
- liveline.css dark overrides use @variant dark nested inside selectors
- Table cells use --ll-text-primary for full contrast in both modes
- Prose paragraphs at 0.82 opacity, bold and inline code punch through
  to full opacity for visual hierarchy
- Prose line-height increased to 22px
- Add website/AGENTS.md documenting dark mode rules
2026-02-20 17:20:09 +01:00
Tommy D. Rossi b2ab69c236 website: bold keywords in every paragraph, saturated prism colors, font-weight 500 for code
- Add <strong> to every paragraph so each has at least one bold keyword
- Increase light mode Prism saturation: brighter purple, amber, green, blue
- Set font-weight 500 for code blocks and inline code
- Add letter-spacing 0.02em to code blocks and inline code
2026-02-20 16:06:45 +01:00
Tommy D. Rossi b7f02ac9f4 website: add transparent PNG favicons, typed meta/links exports, OG image
- Replace favicon.ico with transparent PNG favicons (32px, 16px) generated
  from the gray extension icon, preserving alpha channel
- Move favicon links from hardcoded JSX to typed LinksFunction export in
  root.tsx, rendered via <Links /> component
- Type liveline meta export as MetaFunction
- Add properly sized OG image (1200x630) for X/Slack/Discord previews,
  update meta tags to reference it
2026-02-20 15:57:12 +01:00
Tommy D. Rossi 3917c5137d website: clean up liveline page, fix dark mode, add OG tags
- Remove 5 ChartPlaceholder stubs that were never replaced with real content
- Add OG meta tags (title, description, og:image 1280x800, twitter:card
  summary_large_image) for rich previews on X, Slack, Discord
- Rename PropsTable to ComparisonTable with configurable headers prop,
  fixing the hardcoded 'Prop/Type/Default' headers on comparison tables
- Remove stale Antigravity/Jetski comparison section
- Switch dark mode from .dark class toggle to prefers-color-scheme media
  query via Tailwind @custom-variant. Remove inline JS script from root.tsx,
  update all .dark selectors in liveline.css, liveline-prism.css to use
  @variant dark from globals.css so strategy is defined in one place
- Fix scrollbar colors: light gray on light backgrounds, subtle white on
  dark backgrounds (was using --color-muted which was invisible in both)
- Update remote access section with traforo link, VPN/firewall context,
  MCP env var docs, and more use cases from docs/remote-access.md
2026-02-20 15:44:16 +01:00
Tommy D. Rossi 11b615c297 add screenshot 2026-02-20 15:26:53 +01:00
Tommy D. Rossi 0032c65212 Update pnpm-lock.yaml 2026-02-20 15:26:36 +01:00
Tommy D. Rossi e7b7aad8a9 Update liveline.tsx 2026-02-20 15:26:34 +01:00
Tommy D. Rossi 5f764ed200 test(snapshot): speed up aria-label screenshot coverage
Optimize the real-page aria label screenshot integration test by reducing page load overhead (parallel page setup and lighter load wait), while keeping meaningful coverage on complex public pages.

Use old.reddit.com and Hacker News for coverage, preserve label rendering and screenshot assertions, and bump playwriter version/changelog.
2026-02-20 15:22:04 +01:00
Tommy D. Rossi 3d6fcb845b feat(executor): add state-aware page-close warnings
Warn only when a closed page is stored in session state (for example state.page), include affected state key names in warning text, and preserve automatic fallback to another open page.

Also standardize skill guidance/examples on state.page, add integration coverage for warning and non-warning close paths, and simplify warning-scope bookkeeping by removing execution-id map state in favor of scope object tracking.
2026-02-20 14:40:05 +01:00
Tommy D. Rossi fdb19c5736 increase table cell contrast in light mode (muted opacity 0.35 -> 0.5) 2026-02-20 13:04:05 +01:00
Tommy D. Rossi a7ab6708ef fix code block bleed alignment and line numbers
- Fixed --ll-bleed to 44px (8px padding + 36px line-number width, border-box)
- Line numbers fixed width 36px (always fits 3 digits, no layout shift)
- Line number opacity increased from 0.15 to 0.3 in both light and dark mode
- Commented out code block background
2026-02-20 12:57:41 +01:00
Tommy D. Rossi acd63a9235 liveline: add Link component, OL, remove BackButton, dedent code blocks, spacing tweaks
- Add A (link) component with --ll-accent color, bright #58a6ff in dark mode
- Add OL (ordered list) component for numbered steps
- Remove BackButton from EditorialPage
- Use string-dedent for all CodeBlock strings, properly indented in source
- Getting started steps as OL with clickable Chrome Web Store link
- Star on GitHub link in intro paragraph
- Inline heading rule (flex + 1px line) replaces separate Divider
- Heading padding 24px top/bottom, article gap 32px
- Sidebar TOC item spacing increased to 5px
- Centered image captions
2026-02-20 12:53:21 +01:00
Tommy D. Rossi abd28162aa liveline: inline heading rule, restore diagram, increase spacing
- SectionHeading now renders as flex row with hairline rule extending
  to fill remaining width after the heading text (matching benji.org)
- Removed separate Divider from Section component
- Restored original diagram layout from before refactor
- Increased article gap to 32px, heading padding to 24px top/bottom
- Centered image captions
2026-02-20 12:43:06 +01:00
Tommy D. Rossi 984f41cfbe extract editorial components to markdown.tsx, simplify liveline to content-only
- New website/src/components/markdown.tsx with all reusable components:
  EditorialPage, TableOfContents, BackButton, P, Code, Caption, CodeBlock,
  ChartPlaceholder, Section, Divider, SectionHeading, List, Li, PropsTable
- liveline.tsx reduced from ~988 to ~370 lines, now pure content
- Renamed Paragraph->P, InlineCode->Code for brevity
- TOC accepts items/logo props for reuse across pages
- Centered image captions
- Divider with equal top/bottom padding
- Variable spacing CSS rules for code blocks, images, section dividers
2026-02-20 12:38:54 +01:00
Tommy D. Rossi 23da0767e9 fix diagram 2026-02-20 12:29:07 +01:00
Tommy D. Rossi 2cb144099a Update pnpm-lock.yaml 2026-02-20 12:26:03 +01:00
Tommy D. Rossi 4079b2ac84 Update package.json 2026-02-20 12:26:00 +01:00
Tommy D. Rossi d338dba8c0 Update globals.css 2026-02-20 12:25:55 +01:00
Tommy D. Rossi 7fe09ea35e liveline: JetBrainsMono Nerd Font Mono for code blocks, fix diagram alignment
- Add @font-face for JetBrainsMono Nerd Font Mono (nerd-fonts v3.3.0) with
  proper box-drawing glyph support for seamless Unicode diagram rendering
- Update --ll-font-code to use NF Mono as primary, fallback to JetBrains Mono/SF Mono
- Fix liveline-prism.css: use var(--ll-font-code) instead of hardcoded SF Mono
- Remove unused Google Fonts JetBrains Mono link from root.tsx
- Fix diagram: keep Unicode box chars for seamless lines, use ASCII < > v for
  arrows (◄ ► ▼ render at inconsistent widths), recount all columns
2026-02-20 12:25:32 +01:00