RENDER_DEBOUNCE_THRESHOLD_MS was declared above the import, which
breaks ES module conventions and can confuse tooling. Move the import
to the top of the module after the license header.
Co-authored-by: Cursor <cursoragent@cursor.com>
_clearIdleTimer() used truthiness on _idleTimeout, so a setTimeout
handle of 0 would not be cleared. Compare against undefined, consistent
with RenderDebouncer rAF handling.
Co-authored-by: Cursor <cursoragent@cursor.com>
dispose(), addRefreshCallback(), and refresh() used truthiness on
_animationFrame, so a requestAnimationFrame handle of 0 would not be
cancelled or deduplicated. Compare against undefined instead, matching
other timer checks in the browser layer.
Co-authored-by: Cursor <cursoragent@cursor.com>
TimeBasedDebouncer can schedule a trailing setTimeout when refresh
requests are throttled. If the debounce window later elapses and an
immediate refresh runs, that pending timeout was left armed and could
fire afterward, causing a duplicate _innerRefresh (e.g. extra live
region updates for screen readers).
Clear any pending timeout and reset _additionalRefreshRequested before
running the immediate refresh path.
Co-authored-by: Cursor <cursoragent@cursor.com>
dispose() cleared the pending timeout but left _refreshTimeoutID and
_additionalRefreshRequested set. After dispose, a stale timeout id or
trailing-refresh flag could confuse a new instance or tests. Match
RenderDebouncer by clearing the timeout id and reset the trailing flag.
Co-authored-by: Cursor <cursoragent@cursor.com>
getCoordsRelativeToElement always returns a two-element tuple, so the
array is always truthy and if (!coords) could never run. hasValidCharSize
already handles the only early-exit path before coordinates are computed.
Co-authored-by: Cursor <cursoragent@cursor.com>
Nullish coalescing binds tighter than the conditional operator, so the
previous expression was parsed as (this._document ?? windowDefined) ?
window.document : null. When this._document was set (e.g. parent
ownerDocument or documentOverride), the ternary still returned
window.document instead of the configured document.
CoreBrowserService.mainDocument is used by AccessibilityManager, viewport
styles, and decoration renderers; CharSizeService already received
this._document directly. Add parentheses so the fallback applies only when
_document is nullish.
Co-authored-by: Cursor <cursoragent@cursor.com>
horizontalDirection called moveToRequestedRow with targetX as the first
argument, but that parameter is the starting row (startY). resetStartingRow
and moveToRequestedCol already pass startY correctly; only this copy-paste
mistake passed a column index where a row was expected.
That could miscompute wrapped-row offsets and emit the wrong horizontal
arrow key sequence when building selection/cursor movement strings.
Co-authored-by: Cursor <cursoragent@cursor.com>
CustomGlyphRasterizer parsed large-arc and sweep flags with parseInt
without a radix when drawing SVG arc paths. Use base 10 for 0/1 flags.
Co-authored-by: Cursor <cursoragent@cursor.com>
KittyGraphicsTypes parsed numeric control values with parseInt
without a radix. Use base 10 explicitly for format, id, dimensions,
and offset fields.
Co-authored-by: Cursor <cursoragent@cursor.com>
_dim() parsed percent, pixel, and cell dimension strings with
parseInt without an explicit radix. Use base 10 for all three paths,
consistent with other numeric parsing fixes in the repo.
Co-authored-by: Cursor <cursoragent@cursor.com>
proposeDimensions summed padding-top/bottom/left/right via bare
parseInt, so non-numeric padding values produced NaN and broke
available width/height. Use radix 10 and || 0 on each side, consistent
with parent element size parsing.
Co-authored-by: Cursor <cursoragent@cursor.com>
Align parent width parsing with the height fix: parseInt with radix
10 and || 0 inside Math.max so non-numeric CSS width does not yield
NaN cols in proposeDimensions.
Co-authored-by: Cursor <cursoragent@cursor.com>
InputHandler parsed palette indices from OSC color sequences with
parseInt without a radix after validating digits-only slots. Use
base 10 for set/report and restore color index parsing.
Co-authored-by: Cursor <cursoragent@cursor.com>
Wheel event DPR factoring parses Chrome/(\d+) with parseInt without a
radix. Add base 10 explicitly, matching getSafariVersion and other
version parsing in the codebase.
Co-authored-by: Cursor <cursoragent@cursor.com>
rgba/rgb CSS parsing used parseInt without a radix on captured digit
groups. Add base 10 explicitly, matching getSafariVersion and other
call sites in the codebase.
Co-authored-by: Cursor <cursoragent@cursor.com>
Safari major version parsing used parseInt without an explicit radix.
Other call sites in the repo use base 10; add the radix for consistency
and to avoid octal interpretation of leading-zero strings.
Co-authored-by: Cursor <cursoragent@cursor.com>
parseInt without a radix can mis-parse leading-zero padding values as
octal. Match AccessibilityManager and document rowCount JSDoc typo.
Co-authored-by: Cursor <cursoragent@cursor.com>
The import/no-cycle refactor had moved IInsertEvent, IDeleteEvent, and
ICircularList into Types.ts, with CircularList.ts re-exporting the event
types from there. That split the list abstraction from its implementation
and pulled Types into the circular-list dependency graph.
Define IInsertEvent, IDeleteEvent, and ICircularList in CircularList.ts
alongside the CircularList class. CircularList.ts now depends only on
Lifecycle and Event, not Types.ts.
Remove those definitions from Types.ts (and the unused Emitter import).
Update callers to import list types from CircularList:
- buffer/Types.ts (IBuffer.lines)
- DecorationService.ts (buffer line insert/delete handlers)
- browser TestUtils.test.ts (mock buffer lines)
Types.ts no longer imports or re-exports circular-list types, preserving
the acyclic Types -> buffer/CircularList boundary.
Co-authored-by: Cursor <cursoragent@cursor.com>
The import/no-cycle refactor had moved IBuffer, IBufferSet, and related
cell/line types into src/common/Types.ts, with buffer/Types.ts only
re-exporting them. That inverted the natural module boundary and made
buffer code depend on the top-level types hub.
Define buffer-owned types in buffer/Types.ts instead:
- CharData, IExtendedAttrs, IAttributeData, ICellData, IBufferLine
- IMarker, IBuffer, IBufferSet, BufferIndex
Restore UnderlineStyle to buffer/Constants.ts (used by IExtendedAttrs)
and remove those definitions from Types.ts.
buffer/Types.ts imports only what it needs from outside the buffer layer:
ICircularList and ICharset from Types, IDisposable from Lifecycle,
IEvent from Event, and UnderlineStyle from Constants. Types.ts does not
import buffer/Types.ts, so the previous Types <-> buffer cycle stays broken.
Update imports across common, browser, headless, addons, and tests to use
common/buffer/Types for buffer types rather than common/Types.
Co-authored-by: Cursor <cursoragent@cursor.com>
Enable oxlint's import/no-cycle rule (import plugin) so circular module
dependencies are caught in CI, similar to eslint-plugin-import/no-cycle
and biome no-import-cycles discussed in the issue.
Relocate shared types and dependencies to remove cycles under src/common:
- Types.ts: host IInsertEvent, IDeleteEvent, IParams, UnderlineStyle,
IBuffer, and IBufferSet; drop imports from CircularList, buffer/Types,
parser/Types, and Services
- CoreTerminal.ts: define and export ICoreTerminal
- ServiceRegistry.ts: define IServiceIdentifier (break Services registry loop)
- UnicodeService: stop constructing UnicodeV6; CoreTerminal registers the
default v6 provider after service creation
- buffer/Types.ts and parser/Types.ts: re-export moved types for callers
Fixes https://github.com/xtermjs/xterm.js/issues/5897
Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the primary lint pipeline with oxlint and oxlint-tsgolint for type-aware TypeScript rules, preserving existing rule behavior from eslint.config.mjs via @oxlint/migrate and targeted jsPlugins (@stylistic/eslint-plugin, eslint-plugin-jsdoc as jsdoc-js, oxlint-plugin-eslint for no-restricted-syntax and object-curly-spacing).
Keep a hybrid ESLint pass (eslint.config.naming.mjs) only for @typescript-eslint/naming-convention until tsgolint implements it (oxc-project/tsgolint#186). Legacy eslint.config.mjs and eslint.config.typings.mjs remain for reference but are no longer used by npm scripts.
Add .oxlintrc.json for src/addons/demo/test and .oxlintrc.typings.json for typings/ (syntax-only, no --type-aware). Update lint, lint-fix, lint-api, and lint-changes to run oxlint first, then naming ESLint. Platform binaries install via oxlint-tsgolint optionalDependencies on Linux, macOS, and Windows.
Fixes https://github.com/xtermjs/xterm.js/issues/5690
Co-authored-by: Cursor <cursoragent@cursor.com>
Follow-up to https://github.com/xtermjs/xterm.js/issues/5896 / PR #5966.
Converting addons to ../../../src/common relative imports broke unit tests:
esbuild emits addon code under addons/*/out-esbuild/ without mirroring the
shared tree, so Node could not load TypeScript sources at runtime
(Cannot find module '../../../src/common/Lifecycle').
Core src/, test/, and headless continue to use relative imports with no
common/* path mappings. Addons keep the prior model until build layout
can share out-esbuild the same way as the main package.
Changes:
- Restore common/* and browser/* paths in addon src/test/benchmark tsconfigs
- Revert addon imports to common/ and browser/ path-mapped specifiers
- Restore NODE_PATH=out-esbuild in bin/test_unit.js for Mocha resolution
- Restore webpack resolve.alias on addons that bundle against out/
Fixes CI test-unit failures on remove-path-mappings-5896.
Co-authored-by: Cursor <cursoragent@cursor.com>
Fixes https://github.com/xtermjs/xterm.js/issues/5896
TypeScript path mappings for common/*, browser/*, and headless/*
were not rewritten in emitted JavaScript, which forced webpack resolve
aliases and NODE_PATH workarounds so runtime could resolve modules.
That added build complexity and broke tooling such as ESLint import/no-cycle.
Changes:
- Convert ~750 imports across src/, addons/, and test/ to relative paths
- Remove common/browser/headless paths and src catch-all mappings from tsconfigs
(keep @xterm/addon-* demo and addon typings paths)
- Remove webpack resolve.alias for common, browser, headless, and vs
- Drop NODE_PATH from unit tests, benchmarks, and VS Code launch config
- Fix addon-image IIPImageStorage to import ./Types after removing catch-all *
Verified: npm run build, esbuild, package, package-headless
Co-authored-by: Cursor <cursoragent@cursor.com>
Add development environment guidance for cloud agents including:
- Demo server startup notes
- Build-before-test requirements
- Note about no external services needed
- tsgo compiler note
- Lint optimization tip
Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
Remove unnecessary unawaited setViewportSize from ProgressAddon tests,
which was the line reported in flaky CI failures. Use serial mode and
scoped hooks per Playwright shared-page guidance, and guard afterAll
teardown when setup fails.
Fixes#5956
Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>