- Allow IDE to determine the best formatter based on settings, not force ESLint formatter (which has issues in v9)
- Added Prettier extension to VSCode extensions list.
- Updated ESLint settings to include working directories for better integration.
- Removed redundant TypeScript formatter settings.
- Excluded `.next` directory from search results in VSCode settings.
- Minor formatting adjustments in ESLint configuration files for consistency.
References: https://github.com/microsoft/vscode-eslint/issues/1826
* Also adds a helpful test:e2e:ci script to test playwright tests inside of a docker image with a clean build to more closely resemble running in CI
* Upgrades playwright version
Closes HDX-2865
Closes HDX-2980
Closes#1443
# Summary
This PR ensures that the schema preview / SQL query preview modal does not have a restrictive max height.
Previously, the CodeMirror component would _sometimes_ have a max height of 150px applied. It appears that this was coming from the global `cm-editor` and `cm-scroller` classes, which were conditionally updated with max height properties in `SQLInlineEditor.tsx` for multi-line inputs.
To fix this, the SQLInlineEditor multiline support now makes use of separate CSS selectors to only apply the max height to inputs with allowMultiline enabled.
## Demo
Modals are now >150px reliably, and multi-line editors are still capped to 150px max height
https://github.com/user-attachments/assets/e3d69c3d-3657-42ef-ba88-a961f0b23cb4
Closes#1449
Closes HDX-2992
# Summary
This PR prevents HyperDX from issuing an invalid query (described in #1449) by disabling the query for sessions when a trace ID is not available. This often happened not just for events without a trace ID but also immediately after opening the side panel while a valid traceId was still loading.
Updating the types to reflect the possibility that trace ID is undefined also exposed the fact that we try to show the trace waterfall and row overview panels on the trace panel even when there is no trace id. This has been fixed.
## Before
https://github.com/user-attachments/assets/91994d82-4c1c-4538-bc4b-0ee31480200a
## After
No invalid query is issued:
https://github.com/user-attachments/assets/300580d3-970e-405f-868b-d0aec9b722e7
When there is no trace id, we don't attempt to render the waterfall:
<img width="1342" height="832" alt="Screenshot 2025-12-05 at 10 02 14 AM" src="https://github.com/user-attachments/assets/80b87d02-2a80-49e2-a0ee-4808d712de0b" />
Closes HDX-2845
# Summary
This PR adds support for specifying a persistent Order By in table charts. Previously, the user could sort by clicking a column, but this was not persisted to the saved chart config. Now, we show an input that allows the user to specify an ordering other than the default, and this order is persisted in the saved chart config.
## Demo
https://github.com/user-attachments/assets/960642fd-9749-4e54-9b84-ab82eb5af3d8
Closes HDX-2977
Closes HDX-2602
# Summary
This PR makes a few changes to improve the filter experience for users with large numbers of facet values.
## On the search page:
1. The limit for facet values upon clicking Load More is now 10k, up from 200. This limit is applied when Load More is explicitly clicked for a single filter key, the default limit on page load remains the same.
2. Because 10k values is too many to display without serious render lag (and 10k values is more than anyone wants to scroll through) we now impose a limit of 50 values displayed with a message encouraging users to search for values if some might be hiding.
3. When a user searches for a filter value, we now automatically load more, as presumably the value they're searching for is not already being displayed in the list
4. Filter values are sorted alphabetically when searching
### Bug Fix
Previously, when a user selected `Load More` for a filter and then switched to a different source, all values from `Load more` would be displayed as values for the second source. This has been fixed, and the Loaded More values are cleared when switching sources.
### Demo
https://github.com/user-attachments/assets/381a6366-25d9-401c-9310-fede75e9a793
## On the services dashboard
1. ServiceNames are now queried from the selected time range, to avoid poor performance or timeouts on large data volumes
2. ServiceNames are now sorted alphabetically in the dropdown
3. We now show up to 10k service names, to match the search page filter value limit
## Future improvements
Ideally, when a user searches for a filter value, we'd dispatch a new query searching for potentially matching values. This would ensure that users could find values outside of the new 10k value limit.
Bumps [jws](https://github.com/brianloveswords/node-jws) from 3.2.2 to 3.2.3.
<details>
<sumry>
<p><em>Sourced from <a/brianloveswords/node-jws/rel.</em><.3</h2>
<h3>Changed</h3>
<ul>
<li>Fix advisoreateSign are
that a non empty secret is provided (via opts.secret, opts.privateKey or opts.key)
when using HMAC algorithms.</li>
<li>Upgrading JWA version to 1.4.2, addressing a compatibility issue for Node >= 25.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/auth0/node-jws/blob/master/CHANGELOG.md">jws's changelog</a>.</em></p>
<blockquote>
<h2>[3.2.3]</h2>
<h3>Changed</h3>
<ul>
<li>Fix advisory GHSA-869p-cjfg-cm3x: createSign and createVerify now require
that a non empty secret is provided (via opts.secret, opts.privateKey or opts.key)
when using HMAC algorithms.</li>
<li>Upgrading JWA version to 1.4.2, adressing a compatibility issue for Node >= 25.</li>
</ul>
<h2>[3.0.0]</h2>
<h3>Changed</h3>
<ul>
<li><strong>BREAKING</strong>: <code>jwt.verify</code> now requires an <code>algorithm</code> parameter, and
<code>jws.createVerify</code> requires an <code>algorithm</code> option. The <code>"alg"</code> field
signature headers is ignored. This mitigates a critical security flaw
in the library which would allow an attacker to generate signatures with
arbitrary contents that would be accepted by <code>jwt.verify</code>. See
<a href="https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/">https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/</a>
for details.</li>
</ul>
<h2><a href="https://github.com/brianloveswords/node-jws/compare/v1.0.1...v2.0.0">2.0.0</a> - 2015-01-30</h2>
<h3>Changed</h3>
<ul>
<li>
<p><strong>BREAKING</strong>: Default payload encoding changed from <code>binary</code> to
<code>utf8</code>. <code>utf8</code> is a is a more sensible default than <code>binary</code> because
many payloads, as far as I can tell, will contain user-facing
strings that could be in any language. (<!-- raw HTML omitted --><a href="https://github.com/brianloveswords/node-jws/commit/6b6de48">6b6de48</a><!-- raw HTML omitted -->)</p>
</li>
<li>
<p>Code reorganization, thanks <a href="https://github.com/fearphage"><code>@fearphage</code></a>! (<!-- raw HTML omitted --><a href="https://github.com/brianloveswords/node-jws/commit/7880050">7880050</a><!-- raw HTML omitted -->)</p>
</li>
</ul>
<h3>Added</h3>
<ul>
<li>Option in all relevant methods for <code>encoding</code>. For those few users
that might be depending on a <code>binary</code> encoding of the messages, this
is for them. (<!-- raw HTML omitted --><a href="https://github.com/brianloveswords/node-jws/commit/6b6de48">6b6de48</a><!-- raw HTML omitted -->)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="4f6e73f24d"><code>4f6e73f</code></a> Merge commit from fork</li>
<li><a href="bd0fea57f3"><code>bd0fea5</code></a> version 3.2.3</li>
<li><a href="7c3b4b4110"><code>7c3b4b4</code></a> Enhance tests for HMAC streaming sign and verify</li>
<li><a href="a9b8ed999d"><code>a9b8ed9</code></a> Improve secretOrKey initialization in VerifyStream</li>
<li><a href="6707fde62c"><code>6707fde</code></a> Improve secret handling in SignStream</li>
<li>See full diff in <a href="https://github.com/brianloveswords/node-jws/compare/v3.2.2...v3.2.3">compare view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a href="https://www.npmjs.com/~julien.wollscheid">julien.wollscheid</a>, a new releaser for jws since your current version.</p>
</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/hyperdxio/hyperdx/network/alerts).
</details>
Closes HDX-2950
# Summary
This PR backports a number of fixes on the Services dashboard from the Enterprise Edition repo:
- The Request Error Rate by Endpoint chart now queries just the top 60 endpoints by max per-bucket error rate to avoid OOMs on datasets with many endpoints.
- The top 20 chart is now sorted according to the selected toggle (by time / by error rate)
- The slowest 10% of queries chart has been updated to correctly indicate that it is showing the slowest 5% of queries
- P95 and Median have been unswapped in the 20 Top Most Time Consuming Endpoints query/tooltip
- The top 20 most time consuming queries dashboard no longer errors out when db.statement is a materialized column
This PR also re-structures some queries to match how they've been structured in the enterprise repo, to avoid drift. See [this PR](https://github.com/DeploySentinel/hyperdx-ee/pull/1024) for more details on those changes.
## Demo
https://github.com/user-attachments/assets/014938b3-33da-411b-b754-7c713f7a8ac8
Closes HDX-2960
# Summary
This PR makes two fixes to improve the charts on the Database tab of the Services dashboard.
1. Previously, the charts were not rendering a series per query, since ClickHouse returns type `Nullable(String)` for the statement expression (`coalesce(nullif(SpanAttributes['db.query.text'], ''), nullif(SpanAttributes['db.statement'], '')) AS "Statement"`). Our `convertCHDataTypeToJSType()` function failed to map this to a `String` type in JS, which resulted in the column not being inferred as a group column by `inferGroupColumns()` in `formatResponseForTimeChart()`.
2. Once we started rendering a series per query, the page immediately started OOM crashing on any serious volume of data because there are too many distinct groups/queries being returned. To fix this, the query now selects only the queries with the highest values in across any time bucket. The queries do the following:
1. First, apply filters and group by query and time bucket
2. Then, `groupArray` the values and time buckets for each query
3. Select the top 60 queries by max value across all time buckets
4. `arrayJoin(zip())` to transform the results back into the row-per-group-per-time-bucket format that `formatResponseForTimeChart` expects.
(This is the same approach recently applied to the `Request Error Rate by endpoint` chart on the HTTP tab).
## Before
<img width="1453" height="791" alt="Screenshot 2025-12-03 at 10 58 31 AM" src="https://github.com/user-attachments/assets/ffa697e4-25bb-4ac6-aed2-703cc3c547bf" />
## After
<img width="1451" height="825" alt="Screenshot 2025-12-03 at 10 57 40 AM" src="https://github.com/user-attachments/assets/42e46d2a-361e-490e-8976-18edeca39e0f" />
Closes HDX-2939
# Summary
This PR fixes a bug that caused the previous period to sometimes round to the incorrect second (see `1:34:59` instead of the desired `1:35:00`).
<img width="329" height="107" alt="Screenshot 2025-12-01 at 9 43 47 AM" src="https://github.com/user-attachments/assets/e967adca-6a91-48c2-be10-dd54ac15846a" />
This was due to the `getPreviousPeriodOffset` function returning an offset at the millisecond level, which was later not rounded to the second in `getPreviousDateRange`. We now round the offset to the nearest second, to match our time picker's granularity.
This PR adds the ability to click on tables or graphs across the app, and be able to deep link into the search page to view the correlated search events.
https://github.com/user-attachments/assets/e5c7c2f2-9b59-42de-bb73-2fa4cb5d09a2
Things to try:
1. **Attributable Functions** (min, max, average, p95, etc) can all reliably give us a y value back to enable filtering directly to the y-values value
2. **Non-attributable Functions** (count, sum, etc) can’t rely on the y value since it depends on the group by logic. As such, these will simply allow you to search by the service without passing the y value for deeper analysis.
3. **Multiple Group Bys** (ex `ServiceName, SpanName`)
4. **Where Clause** (SQL or Lucene)
5. Do a **general test** across the app to ensure everywhere that uses charting behaves the same or better than before.
Some things that don’t work:
1. **Aliases in the group by** - we are hitting limitations with `node-sql-parser` that causes the aliasMap to not generate correctly when using aggregate functions in most cases. We may need to either fix these issues or find an alternative solution.
2. **Expressions in Group By** - If you have expressions in the group by, the filtering will not work based on the current implementation, it does not factor in the result of the expression in the filter value.
3. **Filters are not reflected in the UI on Search** - When you deeplink, the filters in the sidebar do not reflect what is actually being queried. This is because the filter UI logic uses `IN` but the deeplinking uses `=` to achieve the best level of precision (and avoid false positives). As such, this is something that could be improved in the future.
Fixes HDX-2844, HDX-2922
Closes HDX-2777
# Summary
This PR adds a toggle that enables showing "previous period" data on line charts, overlayed with the current period data.
1. The "previous period" is a date range of the same length as the selected "current" date range, immediately prior to the current date range.
2. This feature is only enabled for line charts, bar charts are not enabled when this option is toggled on.
**This PR is organized into a number of commits which may be easier to review one at a time.**
## Followup work
- Improve layout of the DBEditTimeChartForm, pending design review
## Demo
https://github.com/user-attachments/assets/76b220da-810e-4280-8fb3-fa20a9919685
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.1 to 3.14.2.
log</summary>
<p><em>Sourced from <a href="https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md">js-yaml's changelog</a>.</em></p>
<blockquote>
<h2>[3.14.2] - 2025-11-15</h2>
<h3>Security</h3>
<ul>
<li>Backported v4.1.1 fix to v3</li>
</ul>
<h2>[4.1.1] - 2025-11-12</h2>
<h3>Security</h3>
<ul>
<li>Fix prototype pollution issue in yaml merge (<<) operator.</li>
</ul>
<h2>[4.1.0] - 2021-04-15</h2>
<h3>Added</h3>
<ul>
<li>Types are now exported as <code>yaml.types.XXX</code>.</li>
<li>Every type now has <code>options</code> property with original arguments kept as they were
(see <code>yaml.types.int.options</code> as an example).</li>
</ul>
<h3>Changed</h3>
<ul>
<li><code>Schema.extend()</code> now keeps old type order in case of conflicts
(e.g. Schema.extend([ a, b, c ]).extend([ b, a, d ]) is now ordered as <code>abcd</code> instead of <code>cbad</code>).</li>
</ul>
<h2>[4.0.0] - 2021-01-03</h2>
<h3>Changed</h3>
<ul>
<li>Check <a href="https://github.com/nodeca/js-yaml/blob/master/migrate_v3_to_v4.md">migration guide</a> to see details for all breaking changes.</li>
<li>Breaking: "unsafe" tags <code>!!js/function</code>, <code>!!js/regexp</code>, <code>!!js/undefined</code> are
moved to <a href="https://github.com/nodeca/js-yaml-js-types">js-yaml-js-types</a> package.</li>
<li>Breaking: removed <code>safe*</code> functions. Use <code>load</code>, <code>loadAll</code>, <code>dump</code>
instead which are all now safe by default.</li>
<li><code>yaml.DEFAULT_SAFE_SCHEMA</code> and <code>yaml.DEFAULT_FULL_SCHEMA</code> are removed, use
<code>yaml.DEFAULT_SCHEMA</code> instead.</li>
<li><code>yaml.Schema.create(schema, tags)</code> is removed, use <code>schema.extend(tags)</code> instead.</li>
<li><code>!!binary</code> now always mapped to <code>Uint8Array</code> on load.</li>
<li>Reduced nesting of <code>/lib</code> folder.</li>
<li>Parse numbers according to YAML 1.2 instead of YAML 1.1 (<code>01234</code> is now decimal,
<code>0o1234</code> is octal, <code>1:23</code> is parsed as string instead of base60).</li>
<li><code>dump()</code> no longer quotes <code>:</code>, <code>[</code>, <code>]</code>, <code>(</code>, <code>)</code> except when necessary, <a href="https://redirect.github.com/nodeca/js-yaml/issues/470">#470</a>, <a href="https://redirect.github.com/nodeca/js-yaml/issues/557">#557</a>.</li>
<li>Line and column in exceptions are now formatted as <code>(X:Y)</code> instead of
<code>at line X, column Y</code> (also present in compact format), <a href="https://redirect.github.com/nodeca/js-yaml/issues/332">#332</a>.</li>
<li>Code snippet created in exceptions now contains multiple lines with line numbers.</li>
<li><code>dump()</code> now serializes <code>undefined</code> as <code>null</code> in collections and removes keys with
<code>undefined</code> in mappings, <a href="https://redirect.github.com/nodeca/js-yaml/issues/571">#571</a>.</li>
<li><code>dump()</code> with <code>skipInvalid=true</code> now serializes invalid items in collections as null.</li>
<li>Custom tags starting with <code>!</code> are now dumped as <code>!tag</code> instead of <code>!<!tag></code>, <a href="https://redirect.github.com/nodeca/js-yaml/issues/576">#576</a>.</li>
<li>Custom tags starting with <code>tag:yaml.org,2002:</code> are now shorthanded using <code>!!</code>, <a href="https://redirect.github.com/nodeca/js-yaml/issues/258">#258</a>.</li>
</ul>
<h3>Added</h3>
<ul>
<li>Added <code>.mjs</code> (es modules) support.</li>
<li>Added <code>quotingType</code> and <code>forceQuotes</code> options for dumper to configure
string literal style, <a href="https://redirect.github.com/nodeca/js-yaml/issues/290">#290</a>, <a href="https://redirect.github.com/nodeca/js-yaml/issues/529">#529</a>.</li>
<li>Added <code>styles: { '!!null': 'empty' }</code> option for dumper
(serializes <code>{ foo: null }</code> as "<code>foo: </code>"), <a href="https://redirect.github.com/nodeca/js-yaml/issues/570">#570</a>.</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="9963d366df"><code>9963d36</code></a> 3.14.2 released</li>
<li><a href="10d3c8e70a"><code>10d3c8e</code></a> dist rebuild</li>
<li><a href="5278870a17"><code>5278870</code></a> fix prototype pollution in merge (<<) (<a href="https://redirect.github.com/nodeca/js-yaml/issues/731">#731</a>)</li>
<li>See full diff in <a href="https://github.com/nodeca/js-yaml/compare/3.14.1...3.14.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/hyperdxio/hyperdx/network/alerts).
</details>
As part of implementing a dependency upgrade (nuqs) we noticed that it requires Typescript 5, but we are on 4.
We should update this dependency so we don't get too outdated, by bumping this we can unblock other upgrades.
The biggest painpoint in this upgrade was the way that Typescript handles ESM in v4->v5 broke ts-jest ESM handling logic. I have mitigated this problem but using a lower version of `flat` which supports CJS, and mocking `ky` package since it's not actually needed for tests.
Fixes HDX-2900
Closes HDX-2881
# Summary
This PR adds the row-level highlighted attributes to the row overview panel, so that they appear for the span that is selected in the trace waterfall and in an expanded table row:
<img width="1071" height="966" alt="Screenshot 2025-11-20 at 2 32 09 PM" src="https://github.com/user-attachments/assets/febb6c12-4c58-4eac-b085-cbad3601b2fe" />
<img width="814" height="275" alt="Screenshot 2025-11-20 at 2 32 16 PM" src="https://github.com/user-attachments/assets/b3c6fbeb-205e-4b6a-9dfd-5ed9457a57df" />
This PR also makes some small updates to the descriptions of the highlighted attributes in the source configuration form.
Fixes: HDX-2852
If a user used the time picker and chose today, but with a time in the future, existing code would "infer" that and assume it was for an earlier year. Since the UI time picker doesnt allow users to select a _day_ in the future, we should be smart to parse down the time to match now()
Closes HDX-2874
# Summary
This PR hides the table header row when there are no displayed columns. This prevents a glitchy behavior where the table header icons would appear vertically aligned rather than in a horizontal row when loading the table data. This occurred because the table header was rendered with an empty, horizontally-skinny column header for the expand button column, and the icons were in that skinny column header.
I'd recommend reviewing with white space changes hidden - this is a very small change.
## Before
https://github.com/user-attachments/assets/fceb489b-d79d-40f8-99ba-d9e4c2c5ee27
## After
https://github.com/user-attachments/assets/3b382e08-43b7-49e4-81c6-45bb2aa00688
Users reported that the precision was way off to what the threshold value was, this helps ensure the two numbers have the same precision.
Before:
<img width="1280" height="363" alt="image" src="https://github.com/user-attachments/assets/fc1bc72c-a70e-4068-aa06-3a01d6c65b2b" />
After:
<img width="1446" height="618" alt="Screenshot 2025-11-19 at 4 20 38 PM" src="https://github.com/user-attachments/assets/49be78eb-dac9-49f4-b490-a354fb69fb71" />
**Note:** One thing that could be better is if we instead used the Number Format specified on the frontend, this would require us to move the Numbro dependency and logic into common-utils, and we would also probably want to update the alert value UI to also use numbro.. I can take a stab at this if we think it's better. I figured this was a good interim solution.
Fixes HDX-2847