<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Harish Kumar</title>
    <description>The latest articles on DEV Community by Harish Kumar (@harish_kumar).</description>
    <link>https://dev.to/harish_kumar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F201861%2F003407b2-31ea-47d7-b683-7ec9c30ca3ae.png</url>
      <title>DEV Community: Harish Kumar</title>
      <link>https://dev.to/harish_kumar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harish_kumar"/>
    <language>en</language>
    <item>
      <title>What I'm building, and why</title>
      <dc:creator>Harish Kumar</dc:creator>
      <pubDate>Wed, 03 Jun 2026 09:57:16 +0000</pubDate>
      <link>https://dev.to/harish_kumar/what-im-building-and-why-4o3n</link>
      <guid>https://dev.to/harish_kumar/what-im-building-and-why-4o3n</guid>
      <description>&lt;p&gt;I've shipped two OSS products this month: &lt;strong&gt;tracelane&lt;/strong&gt; and &lt;strong&gt;peek&lt;/strong&gt;. They share a recording engine and a trust model. Neither has a SaaS, a dashboard, or a signup. Both work fully offline. This post is the why.&lt;/p&gt;

&lt;h2&gt;
  
  
  tracelane
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The reporter for your WebdriverIO, Playwright, and Cypress tests. Self-contained HTML for every run — replay failures, audit successes, attach to any bug tracker. No SaaS, no dashboard, no signup.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have lost many afternoons to a CI line that says "Element not visible: &lt;code&gt;[data-test=submit]&lt;/code&gt;" and nothing else. The screenshot tells me the page is white. The console log is empty because the assertion fired before the app got to throw anything. The video, if there is one, is hosted on a vendor I'd rather not pay for, behind an auth wall I'd rather not maintain, and gone in 30 days.&lt;/p&gt;

&lt;p&gt;The fix is not novel. &lt;a href="https://www.rrweb.io" rel="noopener noreferrer"&gt;rrweb&lt;/a&gt; records the DOM and console at usable fidelity. The novel part is the constraint I want to enforce: the resulting artifact must be a &lt;strong&gt;single &lt;code&gt;.html&lt;/code&gt; file on disk&lt;/strong&gt; that opens in any browser, fully offline, with the player and event blob inlined. No cloud upload. No signup. Attach it to a Jira ticket, drop it in Slack, archive it in S3, send it to a contractor outside your network — it's just a file.&lt;/p&gt;

&lt;p&gt;Tracelane is one WebdriverIO &lt;strong&gt;Service&lt;/strong&gt; that injects rrweb, drains the in-page buffer on a poll, attaches CDP for failed-network capture, and builds the HTML when a test fails. The Playwright and Cypress integrations follow the same pattern; they ship later in the year.&lt;/p&gt;

&lt;p&gt;The closest commercial equivalents are Cypress Cloud, Replay.io, and Sentry Session Replay. They're all good products. I just didn't want to operate infrastructure for a side project, and the self-contained HTML constraint genuinely changes the shape of "where can this artifact live?" — your bug tracker doesn't need to learn about a new vendor.&lt;/p&gt;

&lt;h2&gt;
  
  
  peek
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Your real browser, exposed to your AI coding agent over MCP — capture once, query forever, never leaves your machine.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude Code, Cursor, Cline, Windsurf — they're all blocked on the same thing: they don't know what's actually in the browser tab I'm asking them about. They can read the source on my disk. They can read documentation. They cannot see the rendered DOM, the network panel, or the &lt;code&gt;console.error&lt;/code&gt; that just fired in the iframe I'm wrestling with. When I describe a bug in plain English they reconstruct what I see from text alone, which is the conversational equivalent of fixing a JavaScript bug over a phone call.&lt;/p&gt;

&lt;p&gt;Peek is a Chrome MV3 extension plus a stdio MCP server. You enable it per-origin from the side panel (off by default for every site). It records via the same &lt;code&gt;@cubenest/rrweb-core&lt;/code&gt; substrate tracelane uses, writes into a local SQLite DB at &lt;code&gt;~/.peek/sessions.db&lt;/code&gt;, and exposes ~20 read-only tools to your AI client over MCP. Your agent can now ask: &lt;em&gt;"console errors from the last 10 seconds"&lt;/em&gt;, &lt;em&gt;"network requests with status &amp;gt;= 400 on &lt;code&gt;example.com&lt;/code&gt;"&lt;/em&gt;, &lt;em&gt;"reconstruct the DOM at the timestamp the click happened"&lt;/em&gt;. Write operations (clicks, inputs, navigation) exist but require explicit per-action authorization recorded in an audit log.&lt;/p&gt;

&lt;p&gt;There is no remote. The MCP transport is stdio. Your agent launches &lt;code&gt;peek-mcp&lt;/code&gt; as a child process, talks to it over stdin/stdout, kills it on exit. Captures live in your home directory until you delete them. The Chrome Web Store submission is pending; alpha testers load the extension unpacked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one repo, two packages, one fork
&lt;/h2&gt;

&lt;p&gt;Both products record. The recorder is the same. So I forked PostHog's well-maintained rrweb lineage into &lt;a href="https://www.npmjs.com/package/@cubenest/rrweb-core" rel="noopener noreferrer"&gt;&lt;code&gt;@cubenest/rrweb-core&lt;/code&gt;&lt;/a&gt;, pinned to a specific commit, with the masking primitives and screenshot fallback I needed already in place. PostHog's fork is ahead of upstream on the things I cared about — masking, large-DOM throttling — and behind on a few things I don't. The fork is vendored (not a transitive npm dep) because the Shai-Hulud 2.0 supply-chain wave in late 2025 made me reconsider the cost of every transitive dep that touches user DOM. One pinned SHA, one audit surface, two products downstream.&lt;/p&gt;

&lt;p&gt;Two products in one repo because the recorder is the load-bearing piece. Splitting them at this stage would mean syncing the fork across two repos manually. When they each justify their own release cadence, they can split.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest pre-1.0 disclosure
&lt;/h2&gt;

&lt;p&gt;This is alpha. Every package version starts with &lt;code&gt;0.1.0-alpha.&lt;/code&gt; The API may shift. Branch protection is on &lt;code&gt;main&lt;/code&gt; (PR + 1 review + CI + DCO + linear history). Every publish goes through npm Trusted Publishing OIDC and ships with SLSA provenance. Renovate runs with a 7-day cooldown (21 days for the &lt;code&gt;@posthog/rrweb&lt;/code&gt; lineage). &lt;a href="https://scorecard.dev/viewer/?uri=github.com/Cubenest/rrweb-stack" rel="noopener noreferrer"&gt;OpenSSF Scorecard&lt;/a&gt; runs weekly. I'm one person; the sustainability budget is documented at &lt;a href="https://github.com/Cubenest/rrweb-stack/blob/main/docs/SUSTAINABILITY.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/SUSTAINABILITY.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @tracelane/cli init  &lt;span class="c"&gt;# WebdriverIO project: install + wire in one command&lt;/span&gt;
npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @peekdev/cli    &lt;span class="c"&gt;# peek: CLI install, then `peek init` wires the MCP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apache 2.0. DCO sign-off on contributions. No telemetry from either tool. Issues + PRs at &lt;a href="https://github.com/Cubenest/rrweb-stack" rel="noopener noreferrer"&gt;&lt;code&gt;Cubenest/rrweb-stack&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you find these useful, &lt;a href="https://github.com/sponsors/harry-harish" rel="noopener noreferrer"&gt;GitHub Sponsors&lt;/a&gt; keeps them maintained at the cadence I can sustain alongside a day job.&lt;/p&gt;

&lt;p&gt;— Harish&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>testing</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
