Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
3f40da7
docs(packages): drop internal design, progress and review references …
krassx Oct 12, 2026
2b03fe1
docs: remove internal document links and progress notes from READMEs
krassx Oct 12, 2026
de2e7a2
docs(samples): drop internal review and scenario references from samp…
krassx Oct 12, 2026
80f8957
docs(scripts): drop internal review references from script comments
krassx Oct 12, 2026
edc1137
Merge docs cleanup: drop internal design/progress/review references f…
krassx Oct 12, 2026
884d962
chore: drop internal doc, tier and review-round references from comme…
krassx Oct 12, 2026
1cca65d
chore(samples): drop internal doc and review-round references from sa…
krassx Oct 12, 2026
5730439
Merge leftover doc-reference cleanup (conflicting comment hunks resol…
krassx Oct 12, 2026
6eda665
docs: repair comments and test titles damaged by the doc-reference cl…
krassx Oct 12, 2026
c8f19c9
docs: repair comments damaged by the doc-reference cleanup (chunk 2)
krassx Oct 12, 2026
219e40a
Merge branch 'worktree-agent-a85fd3b207f8b1ba4' into chore/drop-inter…
krassx Oct 12, 2026
ccff221
docs: repair damaged comments and titles left by the doc-reference cl…
krassx Oct 12, 2026
09b508d
Merge branch 'worktree-agent-a0668c2d27efc0cbd' into chore/drop-inter…
krassx Oct 12, 2026
2acac9a
docs: drop the last mentions of the internal alignment notes from two…
krassx Oct 12, 2026
a113be9
docs: remove the last internal review ids from test titles, comments …
krassx Oct 12, 2026
037f6cb
style: format the shortened it.each title
krassx Oct 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,8 @@ jobs:
#
# These existed but were OUTSIDE the gate until 2026-07-27: the `check` job runs
# `turbo run test:coverage`, and the four harness packages define only `test:e2e`, so
# turbo reported `<NONEXISTENT>` and skipped them silently. The adversarial review
# (docs/review/e2e-harnesses.md, SEV1 #1) identified that as the root cause of most of
# its ~90 SEV1 findings surviving ~100% unit coverage.
# turbo reported `<NONEXISTENT>` and skipped them silently. An adversarial review
# identified that as the root cause of most of its ~90 severe findings surviving ~100% unit coverage.
#
# Separate job so it runs alongside `check` and so its extra runtime setup
# (bun, deno) is isolated. Bun and Deno are installed deliberately: the harness SKIPS
Expand Down
16 changes: 4 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,13 @@
A single SDK targeting every JavaScript runtime — browsers, Node.js, Bun, Deno, Electron, Cloudflare Workers, Vercel Edge, and Web/Service Workers.

> **Status:** implemented. Runnable SDKs exist for every target runtime, plus frontend, meta-framework and
> backend adapters, session replay, APM, OpenTelemetry and source-map tooling. Implementation state is tracked
> in [`docs/PROGRESS.md`](docs/PROGRESS.md) (read it first); all code follows the binding standards in
> [`docs/implementation-standards.md`](docs/implementation-standards.md) (test-first TDD + per-entity mutator loop).

## Docs

- [`docs/PROGRESS.md`](docs/PROGRESS.md) — **what is implemented** (the hand-off doc; read first).
- [`docs/design/sdk-design.md`](docs/design/sdk-design.md) — architecture & design (Draft v3). Android-canonical; thin kernel + pub/sub event flow (§16). Read alongside `PROGRESS.md` for the as-built deltas.
- [`docs/implementation-standards.md`](docs/implementation-standards.md) — testing & coding standards (binding).
- [`docs/dev-environment.md`](docs/dev-environment.md) — toolchain reference.
- [`CLAUDE.md`](CLAUDE.md) — guidance for AI agents working in this repo.
> backend adapters, session replay, APM, OpenTelemetry and source-map tooling. Development follows test-first
> practice with a per-entity mutation check.

## Layout

`packages/*` — the SDK packages across tiers 0–5 (foundation → kernel → platform → mid-tier → framework adapters → umbrella). See design §5.
`packages/*` — the SDK packages, from the foundation tier (types, util, logger, protocol) through the kernel,
the platform SDKs, the framework adapters and the umbrella package.

## Develop

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import * as webview from '@bugsee/webview';
import * as webworker from '@bugsee/webworker';
import { describe, expect, it } from 'vitest';

// EXPORT PARITY across the directly imported packages and the framework-adapter subpaths (review R2D-4).
// EXPORT PARITY across the directly imported packages and the framework-adapter subpaths.
//
// The umbrella entries are pinned in `packages/bugsee/src/export-parity.test.ts`. A user who imports
// `@bugsee/vercel-edge`, `@bugsee/webworker`, `@bugsee/nextjs/server`... directly gets the same product, so the
Expand Down Expand Up @@ -155,7 +155,7 @@ describe('the re-exports are the SAME functions, not look-alikes', () => {
});
});

// FORBIDDEN names (R5H-4). `relaunchEdge` / `rememberEdgeLaunch` are the SEAM of the meta-framework edge adapters
// FORBIDDEN names. `relaunchEdge` / `rememberEdgeLaunch` are the SEAM of the meta-framework edge adapters
// (`@bugsee/vercel-edge/relaunch-edge`). They once leaked into `@bugsee/bugsee/edge-light` and `@bugsee/cloudflare`
// through `export *` from the vercel-edge index, where a plain `relaunchEdge()` silently re-ran `launchEdge` and
// dropped the umbrella's extensions / the Cloudflare launch. They must never be public on any package entry.
Expand Down
4 changes: 2 additions & 2 deletions packages/adapter-kit/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @bugsee/adapter-kit — runtime-portable primitives shared by the SSR meta-framework adapters
// (@bugsee/{nextjs,remix,nuxt,sveltekit,astro}). See docs/design/meta-framework-adapters.md §3 (the
// shared kit) — P4 (server-error bridge) + P5 (trace-data). Depends only on @bugsee/core; no runtime-
// (@bugsee/{nextjs,remix,nuxt,sveltekit,astro}).
// The shared kit: the server-error bridge and the trace-data primitive. Depends only on @bugsee/core; no runtime-
// specific imports, so it is safe in node, edge, and browser graphs alike.
export { type ReportServerErrorOptions, reportServerError } from './report-server-error';
export {
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-kit/src/report-server-error.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// @bugsee/adapter-kit — the server-error bridge (P4): stitch a framework's server-side throw to the
// @bugsee/adapter-kit — the server-error bridge: stitch a framework's server-side throw to the
// active Bugsee session. Shared by every SSR meta-framework adapter (Next.js `onRequestError`, SvelteKit
// `handleError`, Remix `handleError`, Nuxt `nitroApp.hooks('error')`, Astro middleware catch) — each maps
// its framework's error context to a capture `event`, then delegates the reporting here.
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-kit/src/trace-data.fuzz.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { describe, expect, it } from 'vitest';
import { getTraceparent, traceMetaEntries, traceMetaTag } from './trace-data';

/**
* Property-based tests for the trace-data primitive (P5) — the BE→FE continuation capstone. Its output
* Property-based tests for the trace-data primitive — the BE→FE continuation capstone. Its output
* leaves the SDK twice over: as a W3C `traceparent` a peer parser must accept, and as raw HTML injected
* into an SSR `<head>`. Both are "for any trace" claims, so both are checked as properties:
*
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-kit/src/trace-data.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// @bugsee/adapter-kit — the trace-data primitive (P5): read the active server-request trace as a W3C
// @bugsee/adapter-kit — the trace-data primitive: read the active server-request trace as a W3C
// `traceparent`, for injecting into the SSR HTML (`<meta name="traceparent">`) so the client pageload
// adopts the server trace (BE→FE continuation, the moat's correlation capstone). Shared by every SSR
// meta-framework adapter (Next.js `generateMetadata`, SvelteKit `transformPageChunk`, Nuxt `render:html`,
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-kit/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineConfig } from 'vitest/config';

// Coverage gate per docs/implementation-standards.md §4: 100% line/functions/statements, >=90% branch.
// Coverage gate: 100% line/functions/statements, >=90% branch.
export default defineConfig({
test: {
// The runner is far slower than a dev machine — roughly 7-18x under coverage instrumentation — and
Expand Down
7 changes: 3 additions & 4 deletions packages/angular/src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
reportError,
} from '@bugsee/web-adapter';

// The @bugsee/angular ERROR SEAM (frontend-adapters §7 fan-out — the F6-thin pattern for Angular). Angular
// The @bugsee/angular ERROR SEAM (the thin-adapter pattern for Angular). Angular
// reports uncaught errors through its injectable `ErrorHandler` (`handleError(error)`); the app replaces it
// via `{ provide: ErrorHandler, useClass: BugseeErrorHandler }`. We report the error to the launched Bugsee
// client, UNWRAPPING Angular's error wrapper (`error.ngOriginalError`) to the real thrown error, and DELEGATE
Expand Down Expand Up @@ -60,7 +60,7 @@ export function createAngularErrorHandler(options: AngularErrorHandlerOptions =
} {
return {
handleError(error) {
// Contained (Wave 2.1): unguarded, an SDK failure escaped into Angular's error pipeline AND skipped
// Contained: unguarded, an SDK failure escaped into Angular's error pipeline AND skipped
// the delegate below — so the app lost both its error handling and its own handler.
neverThrow(() => reportAngularError(error, options), options.onError);
options.delegate?.handleError(error); // keep a chained handler (e.g. the default ErrorHandler)
Expand All @@ -75,8 +75,7 @@ export function createAngularErrorHandler(options: AngularErrorHandlerOptions =
* primary one — REPLACES whatever handler the application had. With nothing chained, an app that provided a
* custom `ErrorHandler` lost it silently, and an app that provided none lost Angular's default, which is the
* only thing that surfaces an uncaught error in the console. Measured against real `@angular/core`: the
* default prints one `console.error('ERROR', error)`; resolving `BugseeErrorHandler` printed none
* (docs/review/frontend-adapters-vue-angular-svelte-solid.md SEV1 #2).
* default prints one `console.error('ERROR', error)`; resolving `BugseeErrorHandler` printed none.
*
* Angular is a structural peer here — never imported — so its default is reproduced rather than delegated to.
*/
Expand Down
5 changes: 2 additions & 3 deletions packages/angular/src/host-boundary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { BugseeErrorHandler, createAngularErrorHandler } from './error';
import * as renderTracker from './render-tracker';
import * as routerMod from './router';

// Wave 2.1/2.3 — docs/review/frontend-adapters-vue-angular-svelte-solid.md SEV1 #1 + #2.
const throwingClient = () =>
({
logException: () => {
Expand Down Expand Up @@ -102,9 +101,9 @@ describe('BugseeErrorHandler does not silently delete the app’s error surfacin
});
});

// WAVE 2.2 — the enforcement half. The tests above cover the ErrorHandler seam the review named; nothing
// The enforcement half. The tests above cover the ErrorHandler seam the review named; nothing
// covered the rest, and nothing failed when a new export arrived without a containment test.
describe('the host-boundary contract (Wave 2.2)', () => {
describe('the host-boundary contract', () => {
const hostileClient = (): Bugsee =>
new Proxy({} as Bugsee, {
get() {
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @bugsee/angular — Angular adapter (tier 4). Error seam (ErrorHandler) + Router naming.
// See docs/design/frontend-adapters.md §7. Structural peer — no @angular/core / @angular/router import.
// @bugsee/angular — Angular adapter. Error seam (ErrorHandler) + Router naming.
// Structural peer — no @angular/core / @angular/router import.
// v1: error + routing only (component/change-detection depth is the shared depth pass).

// Single-install re-export: surface the full public SDK (launch, Bugsee, options + manual-API
Expand Down
6 changes: 3 additions & 3 deletions packages/angular/src/router.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { neverThrow, type RouteNamingOptions, setRouteName } from '@bugsee/web-adapter';

// The @bugsee/angular ROUTER NAMING integration (frontend-adapters §7 + the F5/D5 two-phase naming seam).
// The @bugsee/angular ROUTER NAMING integration (the two-phase naming seam).
// Angular's activated-route snapshot tree carries the matched route config; walk it to build the
// parameterized pattern (`/users/:id` — Angular's colon syntax, same as the backend adapters) and refine
// the active navigation transaction (opened raw-URL by the F1 navigation source) via the shared
// the active navigation transaction (opened raw-URL by the navigation source) via the shared
// `setRouteName` seam. A STRUCTURAL PEER over the snapshot/router shapes (no `@angular/router` import) →
// version-agnostic + unit-testable. The user owns the `NavigationEnd` filter (they have the import),
// keeping this robust + decoupled — wire once after the router is ready:
Expand Down Expand Up @@ -52,7 +52,7 @@ function routePatternFromSnapshotUnsafe(
return segments.length > 0 ? `/${segments.join('/')}` : undefined;
}

/** Refine the active transaction to the router's CURRENT activated route pattern (D5 phase-2). Call on each
/** Refine the active transaction to the router's CURRENT activated route pattern. Call on each
* `NavigationEnd`. A no-op when the current route has no usable pattern. */
export function setRouteNameFromRouter(
router: AngularRouterLike,
Expand Down
2 changes: 1 addition & 1 deletion packages/angular/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineConfig } from 'vitest/config';

// Coverage gate per docs/implementation-standards.md §4: 100% line/functions/statements, >=90% branch.
// Coverage gate: 100% line/functions/statements, >=90% branch.
// environment 'node': the Angular adapter is a STRUCTURAL PEER (no @angular import) tested injection-first
// with plain objects — the same discipline as the other adapters.
export default defineConfig({
Expand Down
2 changes: 1 addition & 1 deletion packages/astro-e2e/test/astro.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ describe('@bugsee/astro — real Astro boot e2e', () => {

// WAVE V0 — the collector VALIDATES every upload against the shipped wire contract, and this is what
// makes it count. Until the shared kit landed, this harness carried its own collector copy that did no
// validation at all, so the entry-payload contract added in Wave 3b.2 (logs.json / network.json /
// validation at all, so the entry-payload contract (logs.json / network.json /
// events.json — the files that carry the actual captured data) covered exactly one of the five suites.
//
// A violation the collector records but nobody asserts is the same false assurance as no check at all.
Expand Down
4 changes: 2 additions & 2 deletions packages/astro-e2e/test/collector.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// The mock collector now lives in @bugsee/e2e-kit (Wave V0). This package used to carry its own diverged
// copy, which — critically — did NO schema validation, so the entry-payload contract added in Wave 3b.2
// The mock collector now lives in @bugsee/e2e-kit. This package used to carry its own diverged
// copy, which — critically — did NO schema validation, so the entry-payload contract
// covered instrumentation-tests alone. Re-exported here so existing `./collector` imports keep working.
export { type CapturedUpload, type MockCollector, startMockCollector } from '@bugsee/e2e-kit';
2 changes: 1 addition & 1 deletion packages/astro/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function registerClient(
return await launch(appToken, options);
}

// API parity with the umbrella entries (review R2D-4): the same VALUE surface, thin re-exports of the same functions.
// API parity with the umbrella entries: the same VALUE surface, thin re-exports of the same functions.
export {
addReportAttachment,
BugseeStatus,
Expand Down
8 changes: 4 additions & 4 deletions packages/astro/src/edge-relaunch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type Bugsee, BugseeStatus, getStatus, launchEdge } from '@bugsee/vercel
import { afterEach, describe, expect, it, vi } from 'vitest';
import { registerServerEdge, relaunch } from './edge';

// R3P-9: the `/edge` entry's `relaunch` used to be the plain vercel-edge one, which re-runs `launchEdge` and
// The `/edge` entry's `relaunch` used to be the plain vercel-edge one, which re-runs `launchEdge` and
// ignored the `launch` seam `registerServerEdge` accepts (e.g. Cloudflare's launch). It now takes the same seam.
const okTransport = () =>
vi.fn(async () => ({
Expand Down Expand Up @@ -52,8 +52,8 @@ describe('@bugsee/astro/edge relaunch', () => {
expect(getStatus(carrier)).toBe(BugseeStatus.Launched);
});

// R4H-4: the install-time seam is the DEFAULT for a plain `relaunch()` (an explicit argument still wins).
it('a plain relaunch() re-runs the custom launch the entry was INSTALLED with (R4H-4)', async () => {
// The install-time seam is the DEFAULT for a plain `relaunch()` (an explicit argument still wins).
it('a plain relaunch() re-runs the custom launch the entry was INSTALLED with', async () => {
const carrier = {};
const custom = vi.fn((token: string, options: Parameters<typeof launchEdge>[1]) => {
const client = launchEdge(token, options);
Expand All @@ -69,7 +69,7 @@ describe('@bugsee/astro/edge relaunch', () => {
expect(getStatus(carrier)).toBe(BugseeStatus.Launched);
});

it('an explicit launch beats the install-time one (R4H-4)', async () => {
it('an explicit launch beats the install-time one', async () => {
const carrier = {};
const installed = vi.fn((token: string, options: Parameters<typeof launchEdge>[1]) => {
const client = launchEdge(token, options);
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/edge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('registerServerEdge', () => {
expect(launchEdge).not.toHaveBeenCalled();
});

it('remembers the install-time launch on its carrier for a plain relaunch (R4H-4)', () => {
it('remembers the install-time launch on its carrier for a plain relaunch', () => {
const launch = vi.fn(() => ({}) as never);
const carrier = {};
registerServerEdge('tok', { launch, carrier });
Expand Down Expand Up @@ -130,7 +130,7 @@ describe('createEdgeMiddleware', () => {
expect(next).toHaveBeenCalledTimes(1); // the route still ran
});

it('redacts secrets in the request URL before they reach http.url (Wave 1.1)', async () => {
it('redacts secrets in the request URL before they reach http.url', async () => {
// Astro hands us the FULL request URL, query included — unlike vercel-edge, which reduces it to a
// pathname. So this is the one edge adapter where a `?token=` reaches the attribute intact.
await createEdgeMiddleware({ getClient: () => ({ id: 'c' }) as never })(
Expand Down
10 changes: 5 additions & 5 deletions packages/astro/src/edge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export interface AstroEdgeOptions extends BugseeEdgeLaunchOptions {
export function registerServerEdge(appToken: string, options: AstroEdgeOptions = {}): Bugsee {
const { launch = launchEdge, ...launchOptions } = options;
const client = launch(appToken, launchOptions);
rememberEdgeLaunch(launch, launchOptions.carrier); // the default for a plain relaunch() (R4H-4)
rememberEdgeLaunch(launch, launchOptions.carrier); // the default for a plain relaunch()
return client;
}

Expand All @@ -56,7 +56,7 @@ function edgeAttributes(context: AstroMiddlewareContext): Record<string, Attribu
const url = context?.request?.url;
if (method !== undefined) attrs['http.method'] = method;
// Astro exposes the FULL request URL (query included), unlike vercel-edge's pathname reduction — so it
// needs the same scrub the network path got (Wave 1.1).
// needs the same scrub the network path got.
if (url !== undefined) attrs['http.url'] = sanitizeUrl(url);
return attrs;
}
Expand All @@ -83,7 +83,7 @@ export function createEdgeMiddleware(options: CreateEdgeMiddlewareOptions = {}):
* wires for edge (`{ entrypoint: '@bugsee/astro/edge', order: 'pre' }`). */
export const onRequest: AstroMiddleware = createEdgeMiddleware();

// API parity with the umbrella entries (review R2D-4): the same VALUE surface, thin re-exports of the same functions.
// API parity with the umbrella entries: the same VALUE surface, thin re-exports of the same functions.
export {
addReportAttachment,
BugseeStatus,
Expand All @@ -98,8 +98,8 @@ export {
/**
* Stop the running client and launch again with the remembered token through the SAME launch seam
* `registerServerEdge` was installed with (default `launchEdge`), so a custom launch (e.g. Cloudflare's) is re-run
* rather than silently replaced by the plain edge one the `@bugsee/vercel-edge` `relaunch` would use (R3P-9).
* That install-time seam is remembered on the carrier and is the DEFAULT here (R4H-4); an explicit `launch`
* rather than silently replaced by the plain edge one the `@bugsee/vercel-edge` `relaunch` would use.
* That install-time seam is remembered on the carrier and is the DEFAULT here; an explicit `launch`
* argument wins and is remembered in turn.
* Bugsee options return to their defaults; integration seams are kept. Rejects when nothing was launched.
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/middleware.fuzz.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// Two untrusted inputs meet here: the request URL (attacker-controlled) and the downstream `Response`
// (whatever the app's routes, endpoints and adapters return, at any status, with any content type, at any
// point in a streaming/caching chain). The Wave 4.5 regression came from exactly this space — a 304 with
// point in a streaming/caching chain). The regression came from exactly this space — a 304 with
// `content-type: text/html` reached the reconstruct and turned every cached page into a 500 — so the
// invariants are stated over the WHOLE status × content-type space rather than the handful of shapes that
// happened to be in the example tests.
Expand Down Expand Up @@ -41,7 +41,7 @@ function makeResponse(status: number, body: string, contentType?: string): Respo
}

describe('injectTraceIntoResponse — properties', () => {
// The Wave 4.5 class, generalized: no status, and no content type, may turn a working response into a
// The class, generalized: no status, and no content type, may turn a working response into a
// thrown error. An adapter that breaks the response is worse than an adapter that injects nothing.
it('never throws, for any constructible status × content-type (the 304 class, generalized)', async () => {
await fc.assert(
Expand Down
Loading
Loading