Commit Graph

721 Commits

Author SHA1 Message Date
Skosh 4e04921205 fix(cli): explain incomplete npx installs (#1693)
Co-authored-by: Aiden Bai <aiden@million.dev>
2026-08-27 17:55:02 -07:00
Skosh 1d3e4a6061 fix(deps): remove shameful hoisting (#1689)
Co-authored-by: Aiden Bai <aiden@million.dev>
2026-08-27 17:20:49 -07:00
Aiden Bai 79d8007281 fix(core): compare changed scope against remote default (#1676) 2026-08-25 12:17:47 -07:00
Skosh 905607f7fc fix: prevent stack overflow in function resolution with depth limiting (#1658)
* fix: prevent stack overflow in function resolution with depth limiting

Add depth limiting to resolveExactLocalFunction to prevent infinite
recursion when resolving function references through deeply nested
expressions, TypeScript path aliases, or complex import chains.

The function now enforces a configurable depth limit
(FUNCTION_RESOLUTION_MAX_DEPTH = 15) and returns null when exhausted
rather than continuing to recurse.

- Add FUNCTION_RESOLUTION_MAX_DEPTH constant (15 levels)
- Thread remainingDepth parameter through all resolution helpers
- Add unit tests for depth limiting
- Add regression test for zustand + Next.js + path aliases case

Closes #1657

Co-authored-by: Skosh <skoshx@users.noreply.github.com>

* test: exercise function resolution stack guard

* refactor: share function chain fixture builder

* test: tighten function resolution regressions

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-08-21 18:55:21 -07:00
Aiden Bai 2b0f06ec70 perf: profile and optimize rule execution (#1663) 2026-08-20 22:05:20 -07:00
Aiden Bai 1971506440 feat(cli): add React-aware runtime traces (#1653)
* feat(cli): record React-aware browser traces

Add an interactive Playwright scanner that streams DevTools traces to disk and reports React rendering hotspots for humans and agents.

* fix(cli): use shared telemetry anonymizer

Keep runtime URL redaction on the canonical core utility after the telemetry helper consolidation.

* feat(cli): visualize component renders during traces

Flash labeled component outlines during runtime scans so users can connect slow interactions to the React work they trigger.

* feat(skill): add runtime performance workflow

Guide agents through repeatable React traces so performance findings stay tied to measured interactions.

* docs(cli): guide runtime scan setup

Explain the recording flow, browser isolation, authenticated sessions, output formats, and trace privacy directly in command help.

* fix(cli): harden runtime trace capture

Preserve evidence across navigations while keeping structured output, telemetry, trace files, and attached-browser cleanup safe under failures and cancellation.

* fix(cli): preserve latest navigation evidence

Keep cross-document layout shifts comparable and retain the most recent bounded performance entries so the recorded interaction remains represented.

* fix(cli): bound runtime scan browser resources

Prevent trace deadlocks, cross-tab capture, and unbounded browser evidence while preserving navigation data through an isolated validated relay.

* fix(cli): preserve busy-page runtime snapshots

Stop tracing concurrently with final probe collection and allow busy pages enough time to flush their bounded performance evidence.

* feat(cli): prompt for runtime scan URL

Let people start an interactive runtime scan without remembering the URL argument while keeping agents and CI deterministic.

* feat(cli): suggest local apps for runtime scans

Replace the bare URL field with a polished chooser that discovers common localhost development servers while preserving custom URL entry.

* fix(cli): use scan terminology in runtime flow

Keep the interactive copy aligned with the command users invoked instead of switching between recording and profiling language.

* fix(cli): center runtime chooser in full terminal

Render the interactive URL chooser as a terminal-sized view so it no longer appears anchored to the previous cursor position.

* fix(cli): harden runtime scan edge cases

Capture popup evidence without leaking browser pages, support redirected interactive output and IPv6 localhost apps, and keep bounded reports honest.
2026-08-16 19:34:13 -07:00
Aiden Bai 28a1a9fd35 chore: add bippy dependency 2026-08-15 00:11:03 +00:00
Aiden Bai ffc2d14254 chore: upgrade Oxc toolchain (#1651) 2026-08-13 23:31:27 -07:00
Aiden Bai 05ef98926d fix: scan standalone Three.js projects and preserve TUI layout (#1646) 2026-08-13 18:18:45 -07:00
Aiden Bai 0b670aa6f5 fix(cli): run agent hooks at turn completion (#1650) 2026-08-13 17:08:53 -07:00
Aiden Bai 8c2f03aea9 feat: make React cleanup first-class (#1624)
* feat: make React cleanup first-class

* refactor: remove editor integrations

* fix: harden React cleanup analysis

* fix: detect default export duplication roots

* fix: unwrap typed duplication roots

* feat: add opt-in project analysis rules

* fix: canonicalize project analysis paths

* fix: harden project analysis precision

* fix: recognize cross-platform project entries

* fix: eliminate project analysis false positives

* fix: harden project analysis reachability

* fix: canonicalize project analysis inputs

* fix: resolve project analysis review findings

* fix: eliminate residual project analysis false positives

* fix: ignore commented registry previews

* fix: eliminate project analysis false positives

* fix: normalize project analysis paths across platforms

* fix: normalize Nextra theme path identity

* test: canonicalize convention fixture paths

* fix: preserve project analysis provenance

* fix: harden project analysis precision

* fix: honor project analysis boundaries

* fix: recognize conditional config plugins

* fix: recognize executable project references

* fix: recognize Stencil tool contracts

* fix: recognize nested tool references

* fix: recognize project setup contracts

* fix: recognize generated and local package consumers

* fix: recognize static template package references

* fix: recognize nested package runtime contracts

* fix: close project analysis parser gaps

* fix: parse project conventions structurally

* refactor: replace structural scanners with parsers

* fix: recognize functional Next CSS config

* fix: close remaining project analysis gaps

* fix: apply tag filters to project analysis

* fix: preserve embedded source positions

* fix: validate static config helper bindings

* fix: bound runtime directory discovery

* fix: close final dependency analysis gaps

* fix: preserve declaration dependency references

* chore: refresh generated rule metadata

* fix: make project analysis portable and bounded

* test: stabilize cleanup scaling guard

* refactor: parse project syntax with oxc

* fix: normalize native filesystem paths

* fix: separate path identity from report paths

* fix: match project files by filesystem identity

* fix: match build glob files by package identity

* fix: use native path keys for file identity

* fix: canonicalize Windows file identities

* fix: canonicalize package ownership paths

* test: inspect Windows path identities

* test: trace Windows package ownership

* fix: keep Windows path identities consistent

* fix: classify test contracts by normalized path

* fix: scope test contracts by canonical package path

* fix: keep test package graphs conservative

* test: keep React complexity advisory
2026-08-13 16:26:08 -07:00
Aiden Bai a2b460d4ae test: stabilize CI timing guards (#1645) 2026-08-13 05:38:07 -07:00
github-actions[bot] 86198f151b chore: version packages (#1618) 2026-08-13 04:38:53 -07:00
Aiden Bai 0f3995b822 fix(cli): recognize supported library projects (#1643)
* fix(cli): recognize supported library projects

* test: fix Docker regression fixture
2026-08-12 20:30:11 -07:00
Aiden Bai c2e353328e fix(ci): stabilize Windows performance profiling test 2026-08-12 09:07:33 +00:00
Aiden Bai a546cd53ce refactor: reduce production dependency surface (#1632) 2026-08-12 00:43:52 -07:00
Aiden Bai 8606ddd089 fix(cli): ignore gitignored configs in staged scans (#1622) 2026-08-10 01:21:07 -07:00
Aiden Bai 55f11e35ca fix(cli): restore copy prompt option (#1623)
* fix(cli): restore copy prompt option

* test(cli): cover prompt copy fallback

* test(cli): tolerate colorized prompt output

* fix(cli): build handoff payload lazily
2026-08-09 18:00:42 -07:00
Aiden Bai 51e198db8b perf: reuse source inventories across project scans (#1617)
* perf: reuse source inventories across project scans

* chore: upgrade Oxc toolchain

* fix: fall back for empty shared inventories
2026-08-09 01:42:22 -07:00
github-actions[bot] d23a0d723c chore: version packages (#1616)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-09 04:53:53 +00:00
github-actions[bot] 3bb84fbeb2 chore: version packages (#1613)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-08 19:17:54 -05:00
Ray Arayilakath e69facac7e feat(lsp): move editor telemetry to Axiom and unify the opt-out (#1610)
* feat(lsp): move editor telemetry to Axiom and unify the opt-out

Completes the cutover. The language server gets the same split as the CLI —
spans and metrics to Axiom, crashes to Sentry — with one difference that matters:
an editor session can run for hours and may never shut down cleanly, so its
exporters use a periodic interval instead of relying on a shutdown flush. Its
counters also now route through `record-metric.ts` rather than calling the Sentry
SDK directly, so they finally carry the run attributes every other metric has.

`is-telemetry-enabled.ts` becomes the single gate for every backend, which fixes
a real hazard: `REACT_DOCTOR_NO_TELEMETRY` was previously honored only by the
language server, and blanking `SENTRY_DSN` no longer silences anything. The evals
harness relied on exactly that, so it would have started reporting eval scans as
production telemetry; it now sets the env flag like the benchmark and delta-audit
runners already did.

Removes what the cutover made dead: the Sentry metric scrubber (no CLI or LSP
metrics flow through Sentry anymore), `resolveTracesSampleRate` and its
constants (neither client records spans), and the span-status and HrTime
constants the deleted tracer bridge used.

Rewrites the AGENTS.md observability section, which described a Sentry-only
architecture, and updates the `--debug` docs wording.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(lsp): correct editor span timing, attribution, and startup export

Give the wide event its real duration. `Effect.makeSpan` stamps the start time
from the clock, and the event is emitted once the burst has already finished —
so start and end landed at the same instant and every editor scan reported a
duration of ~0, even though `durationMs` was correct as an attribute. The span
is now built straight off the tracer, which takes an explicit `startTime`, so
the scan's real window is supplied on both ends. This restores what the Sentry
path got from `startTime`.

Attribute editor telemetry to the editor. Routing LSP counters through
`recordCount` picked up the shared run context, which classified the process as
`command: "inspect"` / `origin: "cli"` — so editor metrics were misfiled in
Axiom and disagreed with the LSP's own Sentry scope, which tags them
`experimental-lsp` / `lsp`. `experimental-lsp` is now a recognized command and
implies the `lsp` origin.

Open the exporters at startup. They were built lazily from the first completed
scan, so a session that recorded session-start counters and was then killed
before any scan finished exported nothing — the shutdown flush found no scope.
Building at init also starts the periodic interval ticking, which is the point
of having one for a daemon.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 19:14:47 -05:00
Ray Arayilakath 738b200e5a feat(cli): send traces, metrics, and the wide event to Axiom (#1609)
* feat(cli): send traces, metrics, and the wide event to Axiom

Moves the CLI's telemetry onto the Axiom transport added in the previous commit.
Sentry keeps crash reporting — its source-map symbolication, issue grouping, and
quotable event id have no Axiom equivalent — so error reports, the prefilled
issue link, and the JSON report's `sentryEventId` are unchanged. Because Effect
exposes a single `Tracer` reference, the two backends are mutually exclusive for
spans, so `tracesSampleRate` is pinned to 0 and the Effect-to-Sentry bridge is
deleted.

Metrics and spans move together because they share one runtime, and that sharing
is load-bearing. `telemetry-runtime.ts` builds the layer once into a long-lived
scope; the run root span, the scan program, and the renderer all draw their
tracer from it. Child spans then nest under the run span natively, with no
`ExternalSpan` stitching. More importantly, Effect tracks delta-temporality state
per metrics exporter instance, so building the layer per program would make every
new exporter re-report each counter in full — silently doubling every metric.
`shutdownTelemetry()` is memoized for the same reason: several exit paths can
fire, and a `--debug` user error flushes before the top-level catch does.

`recordCount` / `recordDistribution` keep their exact signatures, so all ~40 call
sites are untouched; only the body changes to write into Effect's metric
registry. Two constraints differ from Sentry: Effect metric attributes are
string-only, so numbers and booleans are stringified while null and undefined are
dropped rather than coerced to "null"; and histograms need explicit buckets, so
distributions share `METRIC_DISTRIBUTION_BOUNDARIES`. Metrics never touch the
tracer, so they are scrubbed at the emit site instead of by the scrubbing tracer.

`--debug` now prints the Axiom trace id, and crashes carry that id plus `runId`
as Sentry tags — so one pasted id resolves in both backends, replacing the
propagation-context linkage that dies with Sentry tracing.

Verified end to end against a local collector with a real scan: one trace request
and one metrics request, root span with `runInspect` nested under it, the full
wide event, `scan.completed` recorded exactly once, and no home directory or
username on the wire.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(cli): close six review findings in the Axiom cutover

Restore export to a user's own collector. `applyObservability` installed a
backend only when first-party Axiom credentials resolved, so anyone who had
pointed React Doctor at their own OTLP endpoint silently stopped getting spans
once the CLI stopped falling back to `layerUserOtlp` unconditionally. The shared
runtime now builds whenever either first-party credentials or
`REACT_DOCTOR_OTLP_*` are present, and `layerObservability` still prefers the
user's endpoint.

Export metrics for commands that never scan. `version`, `install`, `ci`,
`rules`, and early `inspect` exits record counters like `cli.invoked`, but only
the scan path built the exporter — so `shutdownTelemetry` found no scope and
dropped them. It now ensures the runtime exists before closing it, which is a
no-op when a scan already opened one.

Namespace the environment overrides as `REACT_DOCTOR_AXIOM_*`. The bare
`AXIOM_TOKEN` / `AXIOM_DATASET` names are Axiom's own, and anyone already
running Axiom likely has them exported — reading them would redirect React
Doctor's telemetry into an unrelated account without the user asking.

Carry the Axiom trace id and run id on crash reports as a *context* rather than
tags. Both are unique per run, and tags are the indexed low-cardinality
dimension — AGENTS.md calls this out for `runId` specifically.

Also replaces an inline nanosecond conversion with a named constant, and defers
`LSP_TELEMETRY_EXPORT_INTERVAL_MS` to the commit that actually reads it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(cli): embed the Axiom ingest token

Enables first-party telemetry. Until now the constant was empty, so
`resolveAxiomTelemetryOptions` returned null and the CLI recorded into Effect's
registry and dropped everything on exit — the merge blocker called out on this
stack.

The token is `ingest:create` only, scoped to the `react-doctor` (Events) and
`react-doctor-metrics` (OTel Metrics) datasets, with no expiry and no
organization permissions. It ships in the published tarball and is therefore
extractable; that was the deliberate trade (the alternative — proxying ingest
through `www.react.doctor`, which already hosts the score API — remains
available if abuse shows up). Detection is an Axiom monitor on anomalous ingest
volume; rotation is a patch release.

Verified against the live service: `/v1/traces` and `/v1/metrics` both return
200 for protobuf payloads with their respective dataset headers, which also
confirms the protobuf serialization choice end to end rather than just against
a local collector.

Two tests moved with it. They asserted the "no token configured" path, which is
no longer reachable through the environment; they now assert the embedded
defaults resolve, and — the part that actually matters — that Axiom's own
unprefixed `AXIOM_*` variables still cannot redirect the destination.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 19:14:47 -05:00
Ray Arayilakath c843b01a9e feat(core): add Axiom OTLP transport and an anonymizing tracer (#1608)
* feat(core): add Axiom OTLP transport and an anonymizing tracer

Adds the export path for shipping traces and metrics to Axiom, plus the
anonymization guarantee that has to come with it. Nothing emits yet — the CLI
still routes telemetry to Sentry; this is the engine-side groundwork.

`layerAxiomTraces` and `layerAxiomMetrics` are composed by hand rather than
through `Otlp.layer`, because Axiom routes each signal to a different dataset
via a different header and `Otlp.layer` passes one `headers` object to every
signal. Serialization is protobuf, not JSON: Axiom's `/v1/metrics` accepts
`application/x-protobuf` only. `OtlpSerialization.layerProtobuf` ships with
Effect, so this adds no dependency.

They are separate layers on purpose. Effect tracks delta-temporality state on
the metrics exporter instance, so a second exporter in one process starts with
no previous snapshot and re-reports every counter's full value — doubling every
metric. `telemetry-payload.test.ts` pins that behavior so a future refactor that
merges them fails loudly instead of silently doubling data.

OTLP has no `beforeSend` hook, so Sentry's central scrubber has no equivalent.
`makeScrubbingTracer` wraps the tracer and runs every span name, attribute, and
event payload through `anonymizeText` on the way to the exporter, and is applied
inside `layerAxiomTraces` so an attribute added later cannot bypass it.
`anonymize-text.ts` moves to core (both its scrubbers already lived there) and
`run-inspect.ts` now scrubs `inspect.directory` at the source rather than relying
on the backstop.

`TELEMETRY_SHUTDOWN_TIMEOUT_MS` is 1s, tighter than Sentry's 2s error flush: the
metrics exporter passes `maxBatchSize: "disabled"` internally, which skips
Effect's empty-buffer short-circuit, so it POSTs on every scope close whether or
not anything was recorded. On a firewalled machine that request cannot fail fast,
and unlike the Sentry flush it would run on every scan rather than only on crashes.

Verified against a local collector: correct per-signal datasets and protobuf
content type, and no home directory, username, or secret reaches the wire.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(core): close three review findings in the Axiom transport

Scrub the failure a span ended with. The OTLP tracer runs `Cause.prettyErrors`
over the exit and exports each result as `exception.type` / `exception.message` /
`exception.stacktrace`. None of those go through `span.attribute`, so they
bypassed the scrubbing tracer entirely — and stack traces are full of absolute
paths, meaning any failing scan shipped the user's home directory. This was the
one route into the payload the backstop didn't cover. Interrupt-only causes are
left alone; the exporter emits a fixed label for them and never touches the
error text.

Honor `exportIntervalMs` for traces. It was threaded through to the metrics
exporter but not the tracer, so a long-lived process — the language server —
would hold spans for the full ten-minute default no matter what interval it
asked for.

Trim trailing slashes without a regex. `/\/+$/` backtracks quadratically on a
domain made mostly of slashes, which CodeQL flags as a polynomial-regex denial
of service because the value comes from the caller.

Also corrects a doc comment that still described metrics as being built at exit,
which stopped being true when the CLI moved to a single shared scope.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 19:14:46 -05:00
github-actions[bot] 43863e2f10 chore: version packages (#1607)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-08 15:24:23 -07:00
github-actions[bot] e83abeb694 chore: version packages (#1604)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-08 05:34:32 -07:00
Aiden Bai 13138a4af5 refactor: simplify internals across the workspace (#1590) 2026-08-08 00:20:14 -07:00
github-actions[bot] df8660f419 chore: version packages (#1602)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-07 17:47:30 -07:00
github-actions[bot] 59ae70b4fb chore: version packages (#1586) 2026-08-07 03:14:51 -07:00
Aiden Bai 4b03b15cbe fix(core): honor standard Knip config files (#1584) 2026-08-05 03:12:13 -07:00
github-actions[bot] ff436b0b96 chore: version packages (#1570) 2026-08-05 00:42:33 -07:00
Aiden Bai d934bf6e3f docs: remove outdated scan description 2026-08-05 00:39:25 -07:00
Aiden Bai 1d0e4d6ee9 fix(cli): clean up interactive terminal transitions (#1582) 2026-08-05 00:36:12 -07:00
Aiden Bai 274bd39ae7 fix(cli): print cancellation footer once (#1581) 2026-08-04 22:39:18 -07:00
Aiden Bai 459c5d34dc refactor(cli): remove legacy terminal renderer (#1580) 2026-08-04 19:16:34 -07:00
Aiden Bai da0647e275 fix(cli): keep interactive scans in Ink (#1578)
Remove the legacy interactive renderer fallback by preserving scoped scan behavior in the Ink dashboard. Includes workspace dead-code ownership and degraded-baseline gate parity.
2026-08-04 16:45:51 -07:00
Aiden Bai 60e4d8e102 fix(cli): isolate interactive React runtime (#1577)
Bundle the Ink and React renderer so inspected projects cannot supply a missing or incompatible React runtime. Exercise the packed CLI in a real PTY against a React 18 fixture.
2026-08-04 15:01:08 -07:00
Aiden Bai 212b8b4113 fix: harden CLI against Sentry crash clusters (#1572) 2026-08-04 03:37:33 -07:00
Aiden Bai a7e0d1bf8c test: stabilize cross-platform CI timing (#1571) 2026-08-04 02:43:01 -07:00
github-actions[bot] dcfe06428d chore: version packages (#1548) 2026-08-03 18:25:23 -07:00
cursor[bot] f958625acb chore: simplify cleanup architecture hot spots (#1464)
Co-authored-by: Aiden Bai <aiden@million.dev>
2026-08-03 17:39:06 -07:00
cursor[bot] 45e818a34b fix: clean up config and telemetry drift (#1023)
Co-authored-by: Aiden Bai <aiden@million.dev>
2026-08-03 17:37:34 -07:00
cursor[bot] 3acb41bad6 fix: align ESLint rule metadata (#987)
Co-authored-by: Aiden Bai <aiden@million.dev>
2026-08-03 17:37:09 -07:00
cursor[bot] 45afa01cc2 refactor: remove stale scan plumbing (#1565)
Co-authored-by: Aiden Bai <aiden@million.dev>
2026-08-03 14:21:14 -07:00
Aiden Bai ba04952cb3 fix(cli): preserve scrollback during project selection (#1566) 2026-08-03 13:34:40 -07:00
Aiden Bai 48ec9a8020 fix(cli): keep large workspace scans responsive (#1549)
* fix: keep large workspace scans responsive

* fix: harden large workspace scans

* test: normalize workspace path on Windows

* fix: resolve workspace exclusions after root redirects

* fix: honor workspace scan boundaries

* fix: keep bounded workspace scans responsive

* fix: preserve dead-code reachability

* refactor: tighten workspace scan controls

* fix(cli): bound staged workspace scans

* fix: eliminate pathological large-file scans

* fix: handle incomplete and conflicted scans

* test: configure conflict merge identity

* perf: cache repeated module resolution probes

* fix(cli): show all incomplete scan warnings

* fix(core): preserve cooperative scan semantics

* perf(cli): streamline workspace scan startup

* perf(cli): harden large workspace scans

* fix(cli): keep scan progress inline

* fix(scan): correct workspace result completeness

* fix(cli): simplify live scan status

* fix(core): make scan deadlines opt-in

* fix(scan): preserve complete workspace results

* perf(scan): accelerate very large workspaces

* fix(scan): yield CPU to foreground work

* perf(scan): avoid unnecessary project indexing

* fix(cli): keep final report inline

* test(cli): stabilize terminal recording setup

* fix(core): honor scan deadline during index probe

* fix(core): skip lint after incomplete index probe

* fix(core): preserve scoped lint ownership

* fix(cli): restore project picker on cancellation
2026-08-03 04:59:45 -07:00
Aiden Bai 44922d6782 FPFNFIX82 Fix form and fragment diagnostics (#1561)
* fix(rules): correct form and fragment diagnostics

* fix(rules): handle fragment review edge cases

* fix: handle document-top fragment links

* fix(a11y): parse ids from html tags only

* fix(a11y): resolve static fragment aliases

* fix(a11y): retain known fragment targets

* fix(a11y): tokenize html id attributes

* fix: preserve known fragment IDs in mixed spreads

* fix: preserve known fragment ID defaults
2026-08-03 03:03:00 -07:00
Aiden Bai c3683a2850 feat(cli): make the interactive report the default (#1542)
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
2026-08-02 01:09:19 -07:00
github-actions[bot] 0b673ccb76 chore: version packages (#1462) 2026-07-31 22:57:26 -07:00
Aiden Bai 2db2a97283 perf: reduce scan startup and workspace contention (#1533) 2026-07-30 19:42:52 -07:00