## Summary
This PR improves the pre-commit hook performance by:
- Using `vitest related` to run only tests affected by changed files
- Adding ability to skip expensive tests (filter tests) during
pre-commit
- Providing a consistent mechanism for skipping expensive tests
## Changes
- Modified `lint-staged.config.mjs` to run `vitest related` with
`SKIP_EXPENSIVE_TESTS=true`
- Updated `test/filter-tests.ts` to use idiomatic `describe.skipIf()`
for conditional test execution
- Changed `test-min` script to use `SKIP_EXPENSIVE_TESTS` environment
variable instead of `--exclude`
- Updated `CLAUDE.md` with documentation about the new test workflow
## Impact
- Pre-commit hooks are now much faster as they:
- Only run tests related to changed files
- Skip 688 expensive filter tests
- Use the same skipping mechanism as `npm run test-min`
## Testing
- ✅ Verified `vitest related` correctly identifies and runs related
tests
- ✅ Confirmed filter tests are skipped when `SKIP_EXPENSIVE_TESTS=true`
- ✅ Tested that full test suite still runs all tests when env var is not
set
- ✅ Pre-commit hooks work correctly with the new setup
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Fixes EBADF error in HeaptrackWrapper by removing redundant file
descriptor close operation
- The net.Socket takes ownership of the FD and closes it during cleanup,
making manual close unnecessary and dangerous
## Root Cause Analysis
The issue occurred in `lib/runtime-tools/heaptrack-wrapper.ts:133` where
the code attempted to manually close a file descriptor that was already
owned by a `net.Socket`. When creating a socket with `new
net.Socket({fd: fd})`, the socket takes ownership of the file descriptor
and closes it during cleanup operations like `resetAndDestroy()`.
Attempting to close the FD again results in:
1. EBADF errors when the FD hasn't been recycled
2. Potentially closing a different resource if the FD has been recycled
by the OS
## Solution
Removed the manual `oldfs.close(fd)` call since the socket handles FD
cleanup automatically. This prevents both the EBADF error and the more
dangerous scenario of closing recycled file descriptors.
## Verification
Created tests to verify that `net.Socket` takes ownership of file
descriptors:
```javascript
// Test confirms that after socket.destroy(), the FD is no longer valid
const fd = fs.openSync(pipePath, O_RDWR | O_NONBLOCK);
const socket = new net.Socket({ fd: fd, readable: true, writable: true });
socket.destroy();
// fs.fstatSync(fd) throws EBADF - confirming FD was closed by socket
```
## Test Plan
- [x] TypeScript compilation passes
- [x] Minimal test suite passes
- [x] Pre-commit hooks pass
- [x] Created unit test to verify net.Socket FD ownership behavior
Fixes COMPILER-EXPLORER-EA7
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
- removes config for firejail (unused, and doesn't exist on aarch64)
- copies execution config to aarch64prod, aarch64staging (as that's the
path that is looked for by the environment)
- unifies c and c++ aarch64 config to "supportBinary" for aarch64
compilers
This adds some unit tests for the front end.
- configures "frontend tests" as a unit tests in `static/tests`,
removing the old cypress-requiring "unit" tests
- hack enough of a DOM to get things working
- port motd and id tests
- *adds* a golden layout checks (see #7807)
- Updates READMEs etc
---------
Co-authored-by: Claude <noreply@anthropic.com>
Root cause: Source mapping happens AFTER beforeSend/ignoreErrors processing, so
frame.filename contains minified bundle paths, not readable source paths.
Changes:
- Add 'Canceled' to ignoreErrors array for clipboard cancellation errors
- Remove frame-based clipboard filtering (doesn't work with minified code)
- Add comprehensive comments explaining source mapping timing issue
- Keep hit testing filter using error message content (works with minified code)
- Document that frame-based filtering is unreliable for Monaco errors
This should finally stop the 20k+ COMPILER-EXPLORER-CGQ clipboard cancellation errors.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds Sentry debugging to capture actual runtime filter data including:
- Error value and type received by filter
- Frame filenames array
- Boolean results of hasClipboardFrame and isCancellationError checks
- Whether filter should have triggered
This will help identify why the filter isn't working despite appearing correct.
Will be removed once issue is identified.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Summary
Fixed the clipboard cancellation filter that was deployed but not
working due to `SentryCapture` context modification.
## Root Cause
The filter was checking for exact equality:
```typescript
event.exception.values[0].value === 'Canceled'
```
But `SentryCapture()` modifies error messages by adding context:
- Original: `"Canceled"`
- Modified: `"Canceled\nSentryCapture Context: Unhandled Promise
Rejection"`
## Solution
Changed to use `startsWith('Canceled')` which:
- ✅ Catches original error: `"Canceled"`
- ✅ Catches modified error: `"Canceled\nSentryCapture Context: ..."`
- ✅ More precise than `includes()` - reduces false positives
- ✅ Still combined with specific stack trace check for safety
## Test Plan
- [x] TypeScript type checking passes
- [x] Pre-commit hooks pass
- [ ] Deploy and verify clipboard cancellation errors are filtered
This should finally stop the 20k+ COMPILER-EXPLORER-CGQ occurrences.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Fixed two Monaco Editor error filters that weren't working due to
misunderstanding the Sentry event structure:
• **COMPILER-EXPLORER-CGQ (Clipboard cancellation)**: Filter was
checking for `'Canceled: Canceled'` but actual error value is just
`'Canceled'`
• **COMPILER-EXPLORER-AXA (Hit testing)**: Filter was checking
`frames[0].function` but due to Sentry wrapping, the function name
appears in the error message instead
## Root Cause
The key insight was examining the actual JSON from Sentry UI rather than
making assumptions:
- Sentry UI displays "type: value" format but JSON has separate `type`
and `value` fields
- `frames[0]` is often Sentry's wrapper (`sentryWrapped`), not the
original error source
- Function names may appear in error messages rather than frame metadata
## Changes
1. **Fixed clipboard filter**: Changed error value check from
`'Canceled: Canceled'` to `'Canceled'`
2. **Fixed hit testing filter**: Changed from checking
`frames[0].function` to checking error message content
3. **Added debugging comments**: Comprehensive notes for future Sentry
filter debugging
## Test Plan
- [x] TypeScript type checking passes
- [x] Minimal test suite passes
- [x] Pre-commit hooks pass
- [ ] Deploy and verify errors are filtered in production
Both issues have 10k+ occurrences so this should significantly reduce
Sentry noise.
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Adds `beforeSend` filter to suppress Monaco Editor clipboard
cancellation errors from Sentry
- Specifically targets "Canceled: Canceled" errors from
`monaco-editor/esm/vs/platform/clipboard/browser/clipboardService.js`
- Fixes Sentry issue COMPILER-EXPLORER-CGQ which has 20,139+ occurrences
but 0 user impact
## Problem
The Monaco Editor clipboard service generates cancellation errors when
clipboard operations are interrupted (e.g., user navigates away during
copy operation). These represent expected behavior rather than
actionable bugs, but were creating noise in Sentry with thousands of
error reports.
## Solution
Following the pattern established in PR #7830, this adds a `beforeSend`
filter that:
1. Checks if the error message is "Canceled: Canceled"
2. Verifies the stack trace contains the Monaco clipboard service file
3. Filters out the error if both conditions are met
## Test Plan
- [x] TypeScript compilation passes (`npm run ts-check`)
- [x] Linting passes (`npm run lint`)
- [x] Minimal test suite passes (`npm run test-min`)
- [x] Pre-commit hooks executed successfully
🤖 Generated with [Claude Code](https://claude.ai/code)
## Summary
- Fixes unhandled promise rejections being logged as "Non-Error capture"
in Sentry issue COMPILER-EXPLORER-BT9
- Converts all promise rejections to use proper Error objects instead of
plain objects/strings/undefined
- Adds defensive handling in Sentry's unhandled rejection listener
## Root Cause
The Sentry issue was caused by services rejecting promises with
non-Error objects:
- `CompilerService.handleRequestError()` rejected with `{request,
error}` plain objects
- Various other services rejected with strings or undefined values
- These triggered the global unhandled rejection handler, which logged
them as "Non-Error capture"
## Changes Made
1. **CompilerService**: Modified `handleRequestError()` to reject with
Error objects while preserving request context
2. **Sentry**: Enhanced unhandled rejection handler to defensively
convert non-Error reasons to Error objects
3. **MultifileService**: Changed string rejections to Error objects
4. **SharingService**: Added descriptive Error objects for link failures
5. **TreePane**: Used Error objects for user cancellation scenarios
6. **CfgView**: Used Error objects for canvas blob creation failures
## Test Plan
- [x] TypeScript compilation passes
- [x] All tests pass (npm run test-min)
- [x] Linter passes
- [x] Pre-commit hooks validated
## Impact
- Reduces Sentry noise from "Non-Error capture" events
- Provides better stack traces for debugging
- Maintains backwards compatibility (consuming code handles both Error
objects and other types)
- More robust error handling throughout the application
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Replace broken regex filter with proper `beforeSend` handler for
Monaco Editor errors
- Fixes noise from Monaco Editor hit testing bug in Firefox (190K+
occurrences)
- Uses structured stack frame checking instead of string parsing
## Root Cause
COMPILER-EXPLORER-AXA was caused by a known Monaco Editor bug in Firefox
where hit testing fails with null reference errors during mouse
operations. The existing regex filter `/i is null
_doHitTestWithCaretPositionFromPoint/` was ineffective because Sentry's
`ignoreErrors` only matches error messages, not stack traces.
## Solution
Added a `beforeSend` callback that:
- Checks if the top stack frame function is
`_doHitTestWithCaretPositionFromPoint`
- Filters out any error thrown directly from this Monaco Editor function
- Uses Sentry's structured stack frames for reliable detection
## References
- Fixes Sentry issue: COMPILER-EXPLORER-AXA (190K+ occurrences)
- Related Monaco Editor bug:
https://github.com/microsoft/monaco-editor/issues/4527
## Test plan
- [x] TypeScript checks pass
- [x] Test suite passes
- [x] Pre-commit hooks pass
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
## Summary
This PR significantly improves type safety for GoldenLayout
configurations, continuing work from issue #4490 "The War of The Types".
This is an **incremental improvement** that establishes a solid
foundation for future work.
## ✅ What We've Accomplished
### Core Type Infrastructure
- **Created comprehensive type system** in
`static/components.interfaces.ts`
- **Added `ComponentConfig<K>`** with proper generic constraints for
type-safe component configurations
- **Added `GoldenLayoutConfig`** to replace unsafe `any[]` content with
strongly-typed `ItemConfig[]`
- **Created `ComponentStateMap`** mapping component names to their
expected state types
- **Added proper TypeScript component name constants** with `as const`
for literal type inference
### Component Configuration Type Safety
- **All component factory functions** now return strongly-typed
configurations
- **Clean type syntax**: `ComponentConfig<'compiler'>` using the
exported constants
- **Eliminated unsafe casts** in component creation and drag source
setup
- **Fixed hub method signatures** that incorrectly expected
`ContentItem` instead of `ItemConfig`
### Bug Fixes and Code Quality
- **Fixed Jeremy's TODO**: Improved `fixBugsInConfig` function typing
- **Discovered and fixed hub type bug**:
`addAtRoot`/`addInEditorStackIfPossible` now accept correct types
- **Removed legacy conversion functions** that were no longer needed
- **Replaced verbose TODO comments** with GitHub issue references for
better organization
### Documentation and Planning
- **Created GitHub issues**
[#7807](https://github.com/compiler-explorer/compiler-explorer/issues/7807)
and
[#7808](https://github.com/compiler-explorer/compiler-explorer/issues/7808)
for remaining work
- **Documented type safety approach** with clear explanations of design
decisions
- **Added comprehensive implementation notes** for future contributors
## 🚧 What's Next (GitHub Issues)
- **Issue #7807**: [Type-safe
serialization/deserialization](https://github.com/compiler-explorer/compiler-explorer/issues/7807)
- localStorage persistence and URL sharing
- SerializedLayoutState implementation
- Version migration support
- **Issue #7808**: [Configuration validation and remaining type
gaps](https://github.com/compiler-explorer/compiler-explorer/issues/7808)
- Enable `fromGoldenLayoutConfig` validation
- Fix upstream GoldenLayout TypeScript definitions
- State type normalization (addresses #4490)
## 📊 Impact
### Type Safety Improvements
- **No more `any` casts** in component configuration creation
- **Compile-time validation** of component names and state types
- **Better IDE support** with autocomplete and type checking
- **Runtime safety** through proper TypeScript interfaces
### Code Quality
- **~100 lines of verbose TODO comments** replaced with concise GitHub
issue references
- **Technical debt reduction** through elimination of unsafe casting
patterns
- **Improved maintainability** with centralized type definitions
- **Better error messages** when component configurations are incorrect
### Files Modified
- `static/components.interfaces.ts` - Core type definitions
- `static/components.ts` - Component factory functions and utilities
- `static/main.ts` - Layout initialization and configuration handling
- `static/hub.ts` - Fixed method signatures
- `static/panes/*.ts` - Updated component creation patterns
## ✅ Testing & Validation
- **All existing tests pass** - no runtime regressions
- **TypeScript compilation succeeds** with strict type checking
- **Linting passes** with no new warnings
- **Pre-commit hooks validated** all changes
- **Manual testing confirmed** layout functionality works correctly
## 🎯 Ready to Merge
This PR represents a **significant incremental improvement** that:
- ✅ **Provides immediate value** through better type safety
- ✅ **Maintains full backward compatibility**
- ✅ **Establishes solid foundation** for future improvements
- ✅ **Centralizes remaining work** in well-documented GitHub issues
- ✅ **Ready for production use** with no runtime changes
The remaining work is clearly tracked in the linked GitHub issues and
can be tackled incrementally in future PRs.
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Removes `rootDirs` so all imports will be relative in the frontend
- Updates (and unifies) imports to be `../types/...` etc instead of
relying on "types" being in the rootDir for the frontend.
- Fixes one type that was being picked up from `lib` in the frontend.
- Adds a precommit hook to check in future
Paves the way to writing _unit_ tests for the frontend for the subset of
the frontend code we can import from `node` (which might be a lot of
it!)
#7766 changed the Monaco language identifier for Rust, but missed a spot
in `formatter-registry.ts`, so now Monaco can’t autoformat (right click
→ “Format Document”) Rust code any more.
<!-- THIS COMMENT IS INVISIBLE IN THE FINAL PR, BUT FEEL FREE TO REMOVE
IT
Thanks for taking the time to improve CE. We really appreciate it.
Before opening the PR, please make sure that the tests & linter pass
their checks,
by running `make check`.
In the best case scenario, you are also adding tests to back up your
changes,
but don't sweat it if you don't. We can discuss them at a later date.
Feel free to append your name to the CONTRIBUTORS.md file
Thanks again, we really appreciate this!
-->
Co-authored-by: Ofek Shilon <oshilon@speedata.io>
Fix#7809 and then some:
Stop processing opt-remarks if none were requested,
Make gcc dump remarks to file,
separate opt-file handling to ClangCompiler and GccCompiler,
make DefaultCompiler inherit GccCompiler,
move some tests around.
Resolves#7780.
Basically a follow-up to #7652; the output format of `rustc --help` was
changed to include angle brackets `<` and `>`. This PR updates the
regexes used to parse the help output and adds some tests.
Fixes#7792
Bootstrap styles `a:has([href])` as a link so the attribute had been
used in the past for things that aren't actually links, yet we want the
style for. It's better to just use `.link-primary` so it doesn't affect
the contents as discovered in #7792
Updated all packages with npm update -S. Removed deprecated
@types/url-join
Fixed TypeScript error caused by package updates:
- The `at()` method is ES2022, but frontend code targets ES5 for
compatibility
- Changed `this.compilerPickers.at(-1)` to
`this.compilerPickers[this.compilerPickers.length - 1]`
Co-authored-by: Claude <noreply@anthropic.com>
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion)
from 2.0.1 to 2.0.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/juliangruber/brace-expansion/releases">brace-expansion's
releases</a>.</em></p>
<blockquote>
<h2>v2.0.2</h2>
<ul>
<li>pkg: publish on tag 2.x 14f1d91</li>
<li>fmt ed7780a</li>
<li>Fix potential ReDoS Vulnerability or Inefficient Regular Expression
(<a
href="https://redirect.github.com/juliangruber/brace-expansion/issues/65">#65</a>)
36603d5</li>
</ul>
<hr />
<p><a
href="https://github.com/juliangruber/brace-expansion/compare/v2.0.1...v2.0.2">https://github.com/juliangruber/brace-expansion/compare/v2.0.1...v2.0.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c85b8ad3f5"><code>c85b8ad</code></a>
4.0.1</li>
<li><a
href="5a5cc176c0"><code>5a5cc17</code></a>
fmt</li>
<li><a
href="0b6a9781e1"><code>0b6a978</code></a>
Fix potential ReDoS Vulnerability or Inefficient Regular Expression (<a
href="https://redirect.github.com/juliangruber/brace-expansion/issues/65">#65</a>)</li>
<li><a
href="6a39bdddcf"><code>6a39bdd</code></a>
4.0.0</li>
<li><a
href="dd72a59047"><code>dd72a59</code></a>
fmt</li>
<li><a
href="278132b187"><code>278132b</code></a>
feat: use string replaces instead of splits (<a
href="https://redirect.github.com/juliangruber/brace-expansion/issues/64">#64</a>)</li>
<li><a
href="70e4c1baf9"><code>70e4c1b</code></a>
add <code>tea.yaml</code></li>
<li><a
href="b01a637b05"><code>b01a637</code></a>
3.0.0</li>
<li><a
href="9e781e913f"><code>9e781e9</code></a>
node 16 is EOL</li>
<li><a
href="6dad2093f8"><code>6dad209</code></a>
docs</li>
<li>Additional commits viewable in <a
href="https://github.com/juliangruber/brace-expansion/compare/v2.0.1...v2.0.2">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/compiler-explorer/compiler-explorer/network/alerts).
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>