* test: add comprehensive tests for barrel file directory imports
- Add tests for tsconfig path alias resolution to index.ts
- Add tests for baseUrl resolution to index.ts
- Add tests for relative directory imports to index.ts
- Add Next.js-specific test with auto-detected entries
- Add direct resolver tests to verify directory resolution
Tests confirm that barrel files imported via directory paths (e.g., @/features/foo -> foo/index.ts) are correctly resolved and not flagged as unused.
Related to issue #1699
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
* test: add moduleResolution bundler test for directory imports
Test confirms that directory imports work correctly with moduleResolution: bundler setting (used by Next.js).
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
* test(core): cover directory barrel reachability
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
Co-authored-by: Aiden Bai <aiden@million.dev>
* fix: extract entry points from implicit sub-projects outside workspace patterns
When the root package.json declares workspaces, sub-projects outside the
declared workspace globs were discovered but their entry points (main, bin,
exports) were skipped. This caused false positives in unused-file detection.
The fix removes the isDeclaredWorkspace predicate from entry extraction -
any package with a valid package.json should have its entry points extracted
regardless of workspace pattern matching.
Fixes#1665
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
* chore: add changeset for issue #1665 fix
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
* test: consolidate implicit workspace entry regression
* docs(changeset): clarify implicit entry fix
---------
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>
* 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>
* 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