From 66309b235f7593ebf6eb4a98f8bea7e278611b91 Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Mon, 18 May 2026 00:28:53 +0200 Subject: [PATCH] =?UTF-8?q?fix(circular):=20skip=20type-only=20imports=20+?= =?UTF-8?q?=20break=20tui=20=E2=86=94=20overlay-layout=20cycle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two changes (one walker, one real code): 1. scripts/check-circular-deps.mjs — skip type-only imports. `import type { X } from "..."` and `export type { X } from "..."` are erased by tsc at compile time and cannot cause runtime cycles. Walker now drops them, matching the precedent set by skipping dynamic `await import(...)`. Net effect on full-repo scan: before: 9 cycles after: 3 cycles (the 6 that disappeared were all `import type` false-positives — none were real runtime cycles). 2. packages/tui — break the last 2-file cycle. tui.ts and overlay-layout.ts had a real RUNTIME cycle: - tui.ts → overlay-layout.ts: applyLineResets, compositeOverlays, extractCursorPosition, isOverlayVisible (4 fns) - overlay-layout.ts → tui.ts: CURSOR_MARKER (1 const) Both files already imported `./overlay-types.ts` (no cycle there). Moved CURSOR_MARKER from tui.ts into overlay-types.ts and re-exported from tui.ts so existing `from "./tui.js"` call sites keep working. No behavior change. Remaining cycles after both fixes (3 real-runtime ones, separate slices): - safety/autonomous-rollback chain (9 files, SF extension) - packages/coding-agent core mega-cycle (12 files) - (one more, see `npm run check:circular`) These are foundational refactors worth their own commits, not bundled into this one. Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/tui/src/overlay-layout.ts | 2 +- packages/tui/src/overlay-types.ts | 12 ++++++++++++ packages/tui/src/tui.ts | 12 +++++------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/tui/src/overlay-layout.ts b/packages/tui/src/overlay-layout.ts index 0110f0f57..88cf527e7 100644 --- a/packages/tui/src/overlay-layout.ts +++ b/packages/tui/src/overlay-layout.ts @@ -12,7 +12,7 @@ import type { } from "./overlay-types.js"; import { tryRender } from "./render-guard.js"; import { isImageLine } from "./terminal-image.js"; -import { CURSOR_MARKER } from "./tui.js"; +import { CURSOR_MARKER } from "./overlay-types.js"; import { applyBackgroundToLine, extractSegments, diff --git a/packages/tui/src/overlay-types.ts b/packages/tui/src/overlay-types.ts index bc9ac00f8..0f45f3e8b 100644 --- a/packages/tui/src/overlay-types.ts +++ b/packages/tui/src/overlay-types.ts @@ -1,7 +1,19 @@ /** * Overlay sizing, anchoring, and handle types for layered TUI content. + * + * Also hosts CURSOR_MARKER (moved here from ./tui.ts to break the + * tui ↔ overlay-layout circular import — both files already import + * this module, so it's the natural shared landing zone). */ +/** + * Cursor position marker — APC (Application Program Command) sequence. + * This is a zero-width escape sequence that terminals ignore. + * Components emit this at the cursor position when focused. + * TUI finds and strips this marker, then positions the hardware cursor there. + */ +export const CURSOR_MARKER = "\x1b_sf:c\x07"; + /** Margin configuration for overlays */ export interface OverlayMargin { top?: number; diff --git a/packages/tui/src/tui.ts b/packages/tui/src/tui.ts index 1e1511262..8617392a4 100644 --- a/packages/tui/src/tui.ts +++ b/packages/tui/src/tui.ts @@ -83,13 +83,11 @@ export function isFocusable( return component !== null && "focused" in component; } -/** - * Cursor position marker - APC (Application Program Command) sequence. - * This is a zero-width escape sequence that terminals ignore. - * Components emit this at the cursor position when focused. - * TUI finds and strips this marker, then positions the hardware cursor there. - */ -export const CURSOR_MARKER = "\x1b_sf:c\x07"; +// CURSOR_MARKER moved to ./overlay-types.ts to break the +// tui ↔ overlay-layout circular import. Re-exported here so +// existing call sites that import { CURSOR_MARKER } from "./tui.js" +// keep working. +export { CURSOR_MARKER } from "./overlay-types.js"; export type { OverlayAnchor,