Skip to content

feat(ink-compat): extend Ink compatibility layer parity#30

Merged
RtlZeroMemory merged 5 commits into
mainfrom
codex/ink-compat-finish
Feb 11, 2026
Merged

feat(ink-compat): extend Ink compatibility layer parity#30
RtlZeroMemory merged 5 commits into
mainfrom
codex/ink-compat-finish

Conversation

@RtlZeroMemory

Copy link
Copy Markdown
Owner

This PR extends @rezi-ui/ink-compat toward Ink parity (G1–G7 scope).

Parity features

  • Measurement APIs: measureElement() committed-layout reads + getBoundingBox(), getScrollHeight()/getScrollWidth()
  • ResizeObserver implementation wired to committed layout snapshots
  • Render options parity: onRender, isScreenReaderEnabled, alternateBuffer, incrementalRendering (best-effort surface)
  • useStdin() raw-mode behavior: meaningful isRawModeSupported, ref-counted setRawMode() toggles, clearer unsupported errors
  • Compat smoke: third-party-like patterns for spinner (interval state updates) and gradient (Transform receives flattened text)

Core plumbing

  • createApp() internal callbacks for render/layout (internal_onRender, internal_onLayout)
  • Widget layout snapshot accessor: WidgetRenderer.getRectByIdIndex() + committed id->rect indexing used by ink-compat measurement

Validation

  • npm run build (pass)
  • npm run typecheck (pass)
  • npm run test (pass; 920 tests)

Known deviations / constraints

  • incrementalRendering: accepted for Ink surface parity; currently best-effort/no-op in this implementation
  • Alternate buffer & stdio ownership: backend stream ownership constraints (Node backend doesn’t currently accept stdio overrides)
  • Some scroll/raw-mode edge behaviors may differ from Ink in unusual stream/TTY configurations

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5d3a30b175

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +146 to +148
if (!canUseAlternateBuffer || !alternateBufferActive) return;
writeBestEffort(stdout, ANSI_ALTERNATE_BUFFER_EXIT);
alternateBufferActive = false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve caller-owned alternate buffer state on cleanup

When alternateBufferAlreadyActive is set, this render call starts with alternateBufferActive = true even though it did not enter the alternate buffer itself, but cleanupAlternateBuffer() still unconditionally writes the exit sequence whenever alternateBuffer is enabled. In nested/embedded use (where a parent already owns the alternate buffer), unmounting this instance will send \u001B[?1049l and tear down the parent’s buffer unexpectedly, causing terminal screen/state corruption outside this app.

Useful? React with 👍 / 👎.

Comment on lines +40 to +43
const measuredId = node.internal_id;
const stackPropsWithId = mapped.wrapper
? mapped.stackProps
: { ...mapped.stackProps, id: measuredId };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid reusing IDs across accumulated Static snapshots

This assigns node.internal_id into rendered vnode props, including the <Static> path where vnodes are appended to root.staticVNodes over time, so the same host node ID is duplicated across historical static entries. Core layout indexing keeps the first rect for a given id (buildLayoutRectIndexes only sets when the id is absent), so later snapshots can no longer update that node’s measured rect; measureElement/ResizeObserver for static boxes can become stale after additional static emissions.

Useful? React with 👍 / 👎.

@RtlZeroMemory
RtlZeroMemory merged commit 6bacacb into main Feb 11, 2026
14 checks passed
@RtlZeroMemory
RtlZeroMemory deleted the codex/ink-compat-finish branch February 19, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants