Phoenix 

Phoenix is a very barebones that is scriptable via , and which I have taken to instead of Moom to a degree.

This is a snapshot of my configuration:

// ********************************************************************************
//  Setup and TODO
// ********************************************************************************

Phoenix.set({
  daemon: false,
  openAtLogin: true
});

/*
 * API docs: https://kasper.github.io/phoenix/
 *
 * TODO:  
 * - [ ] Drag and Drop Snap (can't be implemented in current Phoenix, apparently)
 * - [X] Move mode
 * - [x] Move to adjacent window
 * - [x] More logical handling of sixths
 * - [x] Hint Manager class
 * - [x] Cleanup Constants
 * - [x] Basic Space handling
 * - [x] Move mouse pointer on rotation focus changes
 * - [x] Centered popup
 * - [x] Frame abstraction
 */

// ********************************************************************************
//  Constants & Feature Flags
// ********************************************************************************

const DEBUG = false; // Toggle verbose logging & optional debug helpers.

/**
 * Direction identifiers used throughout layout, navigation and tiling logic.
 * Semantic (capitalized) strings are used instead of single-letter aliases for clarity.
 */
const DIR = Object.freeze({
  NONE: "none",
  COLS: "Cols",
  FULL: "Full",
  NORTH: "North",
  SOUTH: "South",
  EAST: "East",
  WEST: "West",
  NW: "North-West",
  NE: "North-East",
  SW: "South-West",
  SE: "South-East"
});

/**
 * Layout related configuration.
 * MODES enumerates the available tiling strategies applied per-screen in rotation.
 */
const LAYOUT = Object.freeze({
  MODES: [DIR.NONE, DIR.EAST, DIR.WEST, DIR.COLS]
});

/**
 * Hint system tuning.
 * CHARS defines the selection alphabet; ICON batching avoids UI stalls on large window counts.
 */
const HINT = Object.freeze({
  APPEARANCE: "dark",
  CANCEL_KEY: "escape",
  CHARS: "FJDKSLAGHRUEIWOVNCM",
  LAZY_ICONS: true,
  ICON_BATCH_DELAY: 0.015,
  ICON_BATCH_SIZE: 12,
  MAX_OVERLAP_ADJUST: 500,
  TEXT_ONLY_THRESHOLD: 25,
  DEBUG_OVERLAY: false,
});


// Direction aliases removed (use DIR.* directly for clarity and grep-ability)

/** Geometry and heuristic values (pixel units). */
const GEOM = Object.freeze({
  PADDING: 8,
  OVERLAP_TOLERANCE: 6
});

/** Performance tuning thresholds for window registry & event debounce. */
const PERF = Object.freeze({
  REGISTRY_TTL_BASE_MS: 450,
  REGISTRY_TTL_MAX_MS: 1200,
  REGISTRY_TTL_MIN_MS: 200,
  REGISTRY_ADAPTIVE: true,
  EVENT_DEBOUNCE_MS: 80,
  NEIGHBOR_SCAN_MAX_DIST: 600 // px: early break distance when building directional neighbor lists
});

/** Focus tracking limits & feature toggles. */
const FOCUS = Object.freeze({
  ENABLE_GLOBAL_MRU: true,
  GLOBAL_MRU_LIMIT: 25,
  ENABLE_DIRECTIONAL_MRU: true,
  DIRECTIONAL_MRU_LIMIT: 15,
  MOVE_POINTER_ON_FOCUS: true // Toggle mouse centering after focus changes
});

/** Move mode nudge distances (pixels). */
const MOVE = Object.freeze({
  NUDGE_SMALL: 10,
  NUDGE_LARGE: 50
});

// Runtime mutable tracking
var LAST_POSITION = {
  window: null,
  grid: "",
  positions: []
};
var LAST_POSITION_INDEX = -1;
var ICON_CACHE = {};
function iconKey(win) {
  try {
    const app = win.app();
    if (app.bundleIdentifier) {
      const bid = app.bundleIdentifier();
      if (bid) return bid;
    }
    return 'pid:' + app.pid();
  } catch (e) {
    return 'hash:' + win.hash();
  }
}

// --------------------------------------------------------------------------------
// Utilities Namespace
// --------------------------------------------------------------------------------
const Util = (() => {
  function log(...args) { if (DEBUG) Phoenix.log(args.join(' ')); }
  function rotateArray(arr, n) {
    if (!arr.length) return arr;
    n = ((n % arr.length) + arr.length) % arr.length;
    return arr.slice(n).concat(arr.slice(0, n));
  }
  function clamp(v, min, max) { return v < min ? min : (v > max ? max : v); }
  return { log, rotateArray, clamp };
})();

// ********************************************************************************
//  Keyboard Bindings
//  Cheat Sheet:
//    ctrl+opt+return / arrows : stepped sizing / grid cycles
//    shift+ctrl+opt+arrows    : vertical reposition sequences
//    ctrl+opt+h/j/k/l         : focus adjacent (vim)
//    ctrl+opt+cmd+←/→         : move window to screen
//    shift+ctrl+opt+cmd+←/→   : move window to space
//    shift+ctrl+z             : cycle tiling mode
//    shift+cmd+space          : hints
//    ctrl+opt+cmd+m           : move mode (later binding)
// ********************************************************************************

// --- 1. Grid / Size Cycling (Moom-like) ---

// ********************************************************************************
//  Keyboard Bindings
// ********************************************************************************

// Moom-like bindings
Key.on("return", ["control", "option"], () => { Window.focused().positionInGrid(4, 0, 3).centerMouse() });
// Mixed grid bases (4/6/16) intentionally provide progressive sizing steps.
Key.on("left", ["control", "option"], () => steppedSizing(Window.focused(), [[4, 0, 2], [6, 0, 3], [16, 0, 9]]));
Key.on("right", ["control", "option"], () => steppedSizing(Window.focused(), [[4, 1, 3], [6, 2, 5], [16, 6, 15]]));
Key.on("up", ["control", "option"], () => steppedSizing(Window.focused(), [[4, 0, 1], [4, 0, 3]]));
Key.on("down", ["control", "option"], () => steppedSizing(Window.focused(), [[4, 2, 3], [8, 2, 13], [6, 1, 4]]));
Key.on("left", ["shift", "control", "option"], () => { Window.focused().reposition(DIR.WEST).centerMouse() });
Key.on("right", ["shift", "control", "option"], () => { Window.focused().reposition(DIR.EAST).centerMouse() });
Key.on("up", ["shift", "control", "option"], () => { Window.focused().reposition(DIR.NORTH).centerMouse() });
Key.on("down", ["shift", "control", "option"], () => { Window.focused().reposition(DIR.SOUTH).centerMouse() });
// Sixths
// --- 2. Sixth Segments ---
Key.on(",", ["shift", "control", "option"], () => { Window.focused().positionInGrid(6, 0, 0).centerMouse() });
Key.on(".", ["shift", "control", "option"], () => { Window.focused().positionInGrid(6, 1, 1).centerMouse() });
Key.on("-", ["shift", "control", "option"], () => { Window.focused().positionInGrid(6, 2, 2).centerMouse() });
Key.on(";", ["shift", "control", "option"], () => { Window.focused().positionInGrid(6, 2, 2).centerMouse() }); // US
Key.on(",", ["control", "option"], () => { Window.focused().positionInGrid(6, 3, 3).centerMouse() });
Key.on(".", ["control", "option"], () => { Window.focused().positionInGrid(6, 4, 4).centerMouse() });
Key.on("-", ["control", "option"], () => { Window.focused().positionInGrid(6, 5, 5).centerMouse() });
Key.on(";", ["control", "option"], () => { Window.focused().positionInGrid(6, 5, 5).centerMouse() }); // US
// Move horizontally between screens
// --- 3. Screen Transfer ---
Key.on("right", ["control", "option", "command"], () => Window.focused().toScreen(DIR.EAST).centerMouse());
Key.on("left", ["control", "option", "command"], () => Window.focused().toScreen(DIR.WEST).centerMouse());
// Move horizontally between spaces
// --- 4. Space Transfer ---
Key.on("right", ["shift", "control", "option", "command"], () => Window.focused().toSpace(DIR.EAST));
Key.on("left", ["shift", "control", "option", "command"], () => Window.focused().toSpace(DIR.WEST));
// Change focus to adjacent window (Vim-like: h=West, l=East)
// --- 5. Focus Navigation (Vim-like) ---
Key.on("h", ["control", "option"], () => { Window.focused().focusAdjacent(DIR.WEST).centerMouse() }); // FIX: Previously inverted
Key.on("j", ["control", "option"], () => { Window.focused().focusAdjacent(DIR.SOUTH).centerMouse() });
Key.on("k", ["control", "option"], () => { Window.focused().focusAdjacent(DIR.NORTH).centerMouse() });
Key.on("l", ["control", "option"], () => { Window.focused().focusAdjacent(DIR.EAST).centerMouse() }); // FIX: Previously inverted

// --- 6. Tiling Mode / Rotation ---
Key.on("z", ["shift", "control"], () => wm.change_tiling_mode())
Key.on("n", ["shift", "control"], () => wm.rotate(-1, false));
Key.on("n", ["shift", "control", "option"], () => wm.rotate(-1, true));
Key.on("m", ["shift", "control"], () => wm.rotate(1, false));
Key.on("m", ["shift", "control", "option"], () => wm.rotate(1, true));

// --- 7. Modes & Hints ---
Key.on('m', ['control', 'option', 'command'], () => MoveMode.activate(Window.focused()));
Key.on("space", ["shift", "command"], () => HintManager.activate());


// ********************************************************************************
// Size steps
// ********************************************************************************

function steppedSizing(win, gridPositions) {
  if (!gridPositions || !gridPositions.length) return win; // Guard against empty cycles
  if (!win.isEqual(LAST_POSITION.window)) {
    LAST_POSITION_INDEX = 0;
    LAST_POSITION.window = win;
  } else if (JSON.stringify(LAST_POSITION.positions) != JSON.stringify(gridPositions)) {
    LAST_POSITION_INDEX = 0; // Accept simple stringify comparison (small arrays)
  }
  const res = win.positionInGrid.apply(win, gridPositions[LAST_POSITION_INDEX]).centerMouse();
  LAST_POSITION.grid = gridPositions[LAST_POSITION_INDEX].join(",");
  LAST_POSITION_INDEX = (LAST_POSITION_INDEX + 1) % gridPositions.length;
  LAST_POSITION.positions = gridPositions;
  return res
}


// ********************************************************************************
//  Hints
// ********************************************************************************

class Hints {
  constructor() {
    this.active = false;
    this.keys = [];
    this.hints = {};
    this.escbind = null;
    this.bsbind = null;
    this.id = Math.random();
  } // constructor

  cancel() {
    for (var activator in this.hints) {
      if (this.hints[activator])
        this.hints[activator].modal.close();
    };
    // remove all key bindings
    Key.off(this.escbind);
    Key.off(this.bsbind);
    this.keys.map(Key.off);
    // clear hints
    this.hints = {};
    this.keys = [];
    this.active = false;
    return this;
  } // cancel

  show(windows, prefix) {
    const self = this;
    prefix = prefix || "";
    const t0 = Date.now();

    // Allow callers to omit windows: pull from WindowRegistry (all screens) then filter to current space
    if (!windows) {
      try {
        const focused = Window.focused();
        let spaceId = null;
        if (focused && focused.spaces) {
          const sp = focused.spaces();
          if (sp && sp.length) {
            try { spaceId = sp[0].hash ? sp[0].hash() : sp[0]; } catch (e) { }
          }
        }
        if (spaceId) {
          // Directly query space-partitioned entries (avoids allocating all entries and filtering)
          windows = WindowRegistry.getSpaceEntries(spaceId).map(e => e.win);
        } else {
          // Fallback to all entries if space cannot be determined
          windows = WindowRegistry.getAllEntries().map(e => e.win);
        }
      } catch (e) {
        windows = WindowRegistry.getAllEntries().map(e => e.win);
      }
    }

    if (!windows || !windows.length) return this;
    const totalWindows = windows.length;
    const textOnly = totalWindows > HINT.TEXT_ONLY_THRESHOLD;

    // If more windows than hint characters, build a two-level selection rather than recursive early-return.
    // Partition windows into buckets keyed by first-level char.
    if (windows.length > HINT.CHARS.length) {
      const buckets = {};
      windows.forEach((win, idx) => {
        const key = HINT.CHARS[idx % HINT.CHARS.length];
        (buckets[key] = buckets[key] || []).push(win);
      });
      // Show only first-level hints now; activating one expands second level.
      Object.keys(buckets).forEach((ch, i) => {
        const pseudoWin = buckets[ch][0]; // anchor modal to first window in bucket
        const hash = iconKey(pseudoWin);
        if (!ICON_CACHE[hash]) ICON_CACHE[hash] = pseudoWin.app().icon();
        const hint = Modal.build({
          text: prefix + ch,
          appearance: HINT.APPEARANCE,
          icon: ICON_CACHE[hash],
          weight: 16,
          duration: 0,
        }).attach(pseudoWin);
        self.hints[prefix + ch] = { win: pseudoWin, modal: hint, position: 0, active: true, bucket: buckets[ch] };
      });
      self._prepareKeyHandlersForBuckets(prefix);
      this.active = true;
      return this;
    }

    // Use WindowRegistry metadata directly (avoids duplicate frame/title/icon lookups)
    const entriesByHash = {};
    WindowRegistry.getAllEntries().forEach(e => { entriesByHash[e.hash] = e; });
    const tMetaStart = Date.now();
    const meta = windows.map((win, i) => {
      const h = win.hash();
      const snap = entriesByHash[h];
      if (snap) return { win, i, hash: h, multi: snap.multi, frame: snap.frame, titleShort: snap.titleShort };
      // fallback minimal (rare path)
      return { win, i, hash: h, multi: false, frame: win.frame(), titleShort: "" };
    });
    const tMetaEnd = Date.now();

    // Build hints in one pass
    // Create all modals without (or with cached) icons first for fast initial paint
    const lazyQueue = [];
    const tModalStart = Date.now();
    meta.forEach(m => {
      const ikey = iconKey(m.win);
      const hasIcon = !!ICON_CACHE[ikey];
      if (!textOnly) {
        if (hasIcon === false && HINT.LAZY_ICONS) lazyQueue.push({ key: ikey, win: m.win });
        else if (!hasIcon && !HINT.LAZY_ICONS) { // eager path if lazy disabled
          try { ICON_CACHE[ikey] = m.win.app().icon(); } catch (e) { }
        }
      }
      let label = "";
      if (!textOnly && m.multi) label += "  |  " + (m.titleShort || "");
      const hint = Modal.build({
        text: prefix + HINT.CHARS[m.i] + label,
        appearance: HINT.APPEARANCE,
        icon: (textOnly ? undefined : (ICON_CACHE[ikey] || undefined)),
        weight: 16,
        duration: 0,
      }).attach(m.win);
      self.hints[prefix + HINT.CHARS[m.i]] = { win: m.win, modal: hint, position: 0, active: true, _iconKey: ikey };
    });
    const tModalEnd = Date.now();

    // Lazy icon loading in small timed batches to keep UI responsive
    if (!textOnly && HINT.LAZY_ICONS && lazyQueue.length) {
      let idx = 0;
      function loadBatch() {
        const slice = lazyQueue.slice(idx, idx + HINT.ICON_BATCH_SIZE);
        slice.forEach(entry => {
          if (!ICON_CACHE[entry.key]) {
            try { ICON_CACHE[entry.key] = entry.win.app().icon(); } catch (e) { }
          }
          // Update modal icon if still active
          for (const activator in self.hints) {
            const h = self.hints[activator];
            if (h && h._iconKey === entry.key && ICON_CACHE[entry.key]) {
              h.modal.icon = ICON_CACHE[entry.key];
            }
          }
        });
        idx += HINT.ICON_BATCH_SIZE;
        if (idx < lazyQueue.length) Timer.after(HINT.ICON_BATCH_DELAY, loadBatch);
      }
      Timer.after(HINT.ICON_BATCH_DELAY, loadBatch);
    }

    // Overlap adjustment (single pass, sorted by origin.y)
    const activators = Object.keys(self.hints).sort((a, b) => self.hints[a].modal.origin.y - self.hints[b].modal.origin.y);
    if (!textOnly && activators.length > 1) { // skip costly adjustments in text-only mode
      let adjustments = 0;
      for (let i = 0; i < activators.length; i++) {
        const a = self.hints[activators[i]].modal;
        const aBottom = a.origin.y + a.frame().height + GEOM.PADDING;
        for (let j = i + 1; j < activators.length; j++) {
          if (adjustments > HINT.MAX_OVERLAP_ADJUST) break;
          const b = self.hints[activators[j]].modal;
          // Early vertical non-overlap break (list sorted by y increasing)
          if (b.origin.y > aBottom) break;
          // Overlap test
          if (
            a.origin.x < b.origin.x + b.frame().width + GEOM.PADDING &&
            a.origin.x + a.frame().width > b.origin.x - GEOM.PADDING &&
            a.origin.y < b.origin.y + b.frame().height + GEOM.PADDING &&
            a.origin.y + a.frame().height > b.origin.y - GEOM.PADDING
          ) {
            b.origin = { x: b.origin.x, y: a.origin.y + a.frame().height + GEOM.PADDING };
            adjustments++;
          }
        }
        if (adjustments > HINT.MAX_OVERLAP_ADJUST) break;
      }
    }

    self.escbind = Key.on(HINT.CANCEL_KEY, [], () => self.cancel());
    this.active = true;

    // Debug overlay (appears briefly)
    if (HINT.DEBUG_OVERLAY) {
      const tEnd = Date.now();
      try {
        const stats = [
          `win:${totalWindows}`,
          `text:${textOnly}`,
          `meta:${tMetaEnd - tMetaStart}ms`,
          `modal:${tModalEnd - tModalStart}ms`,
          `lazyQ:${lazyQueue.length}`,
          `total:${tEnd - t0}ms`
        ].join('  ');
        Modal.build({
          text: stats,
          appearance: HINT.APPEARANCE,
          weight: 12,
          duration: 0.9,
        }).flash(Screen.main ? Screen.main() : Screen.all()[0]);
      } catch (e) { }
    }
    return this;
  } // show

  _prepareKeyHandlersForBuckets(prefix) {
    // Replace existing handlers with bucket-expansion logic.
    const self = this;
    const sequences = Object.keys(self.hints);
    self.keys = [];
    HINT.CHARS.split("").forEach(ch => {
      self.keys.push(Key.on(ch, [], function () {
        const activator = prefix + ch;
        const entry = self.hints[activator];
        if (!entry) return; // not a valid first-level key
        // Close first-level modals except chosen bucket
        sequences.forEach(seq => { if (seq !== activator) self.hints[seq].modal.close(); });
        const bucket = entry.bucket;
        // Clear hints and rebuild with second-level inside bucket
        const bucketWins = bucket;
        self.cancel();
        self.show(bucketWins, activator); // recursing with prefix expands second level
      }));
    });
  }

  activate() {
    var self = this;

    if (this.active) {
      self.cancel();
    } else {
      Event.once("mouseDidLeftClick", function () { self.cancel(); });

      this.show(Window.all({ visible: true }));

      var sequence = "";
      self.keys = [];
      HINT.CHARS.split("").forEach(function (hintchar) {
        // set up each individual hint handler
        self.keys.push(Key.on(hintchar, [], function () {
          // ISSUE: Potential race if windows close mid-sequence; consider validating hint.win.exists().
          sequence += hintchar;
          for (var activator in self.hints) {
            var hint = self.hints[activator];
            if (!hint.active) continue;
            if (activator[hint.position] === hintchar) {
              hint.position++;
              if (hint.position === activator.length) {
                hint.win.focus();
                Mouse.move({
                  x: hint.modal.origin.x + hint.modal.frame().width / 2,
                  y: Screen.all()[0].frame().height - hint.modal.origin.y - hint.modal.frame().height / 2
                });
                return self.cancel();
              }
              hint.modal.text = hint.modal.text.substr(1);
            } else {
              hint.modal.close();
              hint.active = false;
            }
          }
        }));
      });

      self.bsbind = Key.on("delete", [], function () {
        if (!sequence.length)
          self.cancel();
        var letter = sequence[sequence.length - 1];
        sequence = sequence.substr(0, sequence.length - 1);
        for (var activator in self.hints) {
          var hint = self.hints[activator];
          if (hint.active) {
            hint.position--;
            hint.modal.text = letter + hint.modal.text;
          } else if (activator.substr(0, sequence.length) === sequence) {
            hint.modal.show();
            hint.active = true;
          }
        }
      });
    }
  } // activate
}


// ********************************************************************************
//  Window Manager Abstraction
// ********************************************************************************

class WindowManager {
  constructor() {
    this.tiling_modes = Array(Screen.all().length)
    this.tiling_modes.fill(DIR.NONE)
    this.timers = Array(Screen.all().length)
    this.layouts = Array(Screen.all().length)
  }

  change_tiling_mode() {
    const window = Window.focused(),
      screen = window.screen(),
      index = Screen.all().indexOf(screen),
      visible = screen.windows({ visible: true })

    // rotate tiling mode
    this.tiling_modes[index] = LAYOUT.MODES[(LAYOUT.MODES.indexOf(this.tiling_modes[index]) + 1) % LAYOUT.MODES.length]
  if (DEBUG) Phoenix.log(index + " " + this.tiling_modes[index]);

    // Try layout cache reuse
    const key = layoutCacheKey(screen, this.tiling_modes[index], visible)
    let cached = LAYOUT_CACHE.get(key)
    if (cached) {
      const layout = new Layout(screen, this.tiling_modes[index])
      layout.frames = cached.map(f => new Frame(f.x, f.y, f.width, f.height))
      this.layouts[index] = layout
    } else {
      this.layouts[index] = new Layout(screen, this.tiling_modes[index])
      // store frames snapshot
      LAYOUT_CACHE.set(key, this.layouts[index].frames.map(f => ({ x: f.x, y: f.y, width: f.width, height: f.height })))
    }

    var modal = Modal.build({
      text: "Tiling mode: " + this.tiling_modes[index],
      appearance: HINT.APPEARANCE,
      weight: 24,
      icon: App.get('Phoenix').icon(),
      duration: 0.5,
    }).flash(screen)

  if (DEBUG) Phoenix.log("layouts pre-apply count=" + this.layouts[index].frames.length);

    this.layouts[index].windows = visible
    this.layouts[index].apply()

  if (DEBUG) Phoenix.log("layouts applied");
    return this
  }

  rotate(dir, focus_only) {
    const window = Window.focused(),
      screen = window.screen(),
      index = Screen.all().indexOf(screen)
    Phoenix.log(index + " " + dir + " " + this.layouts[index].windows.map(x => x.hash()))
    this.layouts[index].rotate(dir).apply(screen)
    return this
  }
}

const wm = new WindowManager()


// ********************************************************************************
//  Layout Abstraction
// ********************************************************************************

class Layout {
  constructor(screen, mode) {
    this.frames = []
    this.windows = []
    switch (mode) {
      case DIR.EAST:
        this.east(screen)
        break;
      case DIR.WEST:
        this.west(screen)
        break;
      case DIR.COLS:
        this.cols(screen)
        break;
    }
  }

  east(screen) {
    const f = screen.flippedVisibleFrame(),
      v = screen.windows({ visible: true }),
      c = v.length - 1,
      w = f.width / 2,
      h = ~~(f.height / c),
      self = this
    this.screen = screen
    if (v.length === 1) {
      this.frames.push(new Frame(f.x, f.y, f.width, f.height).pad())
    } else {
      // main window
      self.frames.push(new Frame(f.x, f.y, w, f.height)
        .displace(f.width / 2, 0).pad())
      // secondary windows
      for (var i = 0; i < c; i++) {
        self.frames.push(new Frame(f.x, f.y, w, h)
          .displace(0, h * i).pad())
      }
    }
    return this
  }

  west(screen) {
    const f = screen.flippedVisibleFrame(),
      v = screen.windows({ visible: true }),
      c = v.length - 1,
      w = f.width / 2,
      h = ~~(f.height / c),
      self = this
    this.screen = screen
    if (v.length === 1) {
      self.frames.push(new Frame(f.x, f.y, f.width, f.height).pad())
    } else {
      // main window
      self.frames.push(new Frame(f.x, f.y, w, f.height)
        .pad())
      // secondary windows
      for (var i = 0; i < c; i++) {
        self.frames.push(new Frame(f.x, f.y, w, h)
          .displace(w, h * i).pad())
      }
    }
    return this
  }

  cols(screen) {
    const f = screen.flippedVisibleFrame(),
      v = screen.windows({ visible: true }),
      c = v.length,
      w = ~~(f.width / c),
      h = f.height,
      self = this
    this.screen = screen

    // all windows
    for (var i = 0; i < c; i++) {
      self.frames.push(new Frame(f.x, f.y, w, h)
        .displace(w * i, 0).pad())
    }
    return this
  }

  none(screen) {
    this.frames = []
    return this
  }

  rotate(dir) {
    // Use utility rotation (non-mutating) instead of Array.prototype extension.
    this.windows = Util.rotateArray(this.windows, dir);
    return this
  }

  apply() {
    const self = this
    if (this.frames.length)
      for (var i = 0; i < self.windows.length; i++) {
        self.windows[i].setFrame(self.frames[i])
      }
    return this
  }
}


// ********************************************************************************
//  Frame Abstraction
// ********************************************************************************

class Frame {
  constructor(x, y, width, height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
  }

  pad() {
    return new Frame(
      this.x + GEOM.PADDING / 2,
      this.y + GEOM.PADDING / 2,
      this.width - GEOM.PADDING,
      this.height - GEOM.PADDING
    )
  }

  snap(screen, dir) { // Expects a DIR.* token; unsupported values leave frame unchanged.
    const s = screen.flippedVisibleFrame();
    const f = new Frame(this.x, this.y, this.width, this.height);
    // Align to right side for east-oriented quadrants
    if ([DIR.EAST, DIR.NE, DIR.SE].includes(dir)) f.x += s.width - f.width;
    // Align to bottom side for south-oriented quadrants
    if ([DIR.SE, DIR.SW].includes(dir)) f.y += s.height - f.height;
    // Full width if explicitly requested
    if (dir === DIR.FULL) f.width = s.width;
    // Full height for full or pure east/west halves
    if ([DIR.FULL, DIR.EAST, DIR.WEST].includes(dir)) f.height = s.height;
    return f;
  }

  displace(x, y) { // Does not clamp to screen intentionally (used for relative moves)
    return new Frame(
      this.x + x,
      this.y + y,
      this.width,
      this.height
    )
  }

  log() {
    Phoenix.log(this.x + ", " + this.y + ", " + this.width + ", " + this.height);
    return this;
  }

  rect() {
    return {
      x: this.x,
      y: this.y,
      width: this.width,
      height: this.height
    }
  }

  ratio(a, b) { // Returns a transformer that scales a frame from space a -> space b
    var wr = b.width / a.width,
      hr = b.height / a.height;

    return ({ x, y, width, height }) => {
      x = Math.round(b.x + (x - a.x) * wr);
      y = Math.round(b.y + (y - a.y) * hr);
      width = Math.round(width * wr);
      height = Math.round(height * hr);
      return { x, y, width, height }
    }
  }
}


// ********************************************************************************
//  Window Extensions
// ********************************************************************************


// Snap a window in a given direction
Window.prototype.to = function (direction) { // Half-screen quadrant snap utility
  var s = this.screen(),
    f = s.flippedVisibleFrame(),
    frame = new Frame(
      f.x,
      f.y,
      f.width / 2,
      f.height / 2,
    ).snap(s, direction).pad();
  this.setFrame(frame);
};


// Move a window to a given screen
Window.prototype.toScreen = function (dir) { // East/West nearest screen by X origin (vertical stack not handled yet)
  var screen = null;
  if (dir === DIR.EAST || dir === DIR.WEST) {
    const cur = this.screen();
    const curX = cur.origin().x;
    // Find nearest screen strictly to the east or west
    screen = Screen.all()
      .filter(s => dir === DIR.EAST ? s.origin().x > curX : s.origin().x < curX)
      .sort((a, b) => Math.abs(a.origin().x - curX) - Math.abs(b.origin().x - curX))[0];
    if (screen) {
      const ratio = Frame.prototype.ratio(cur.flippedVisibleFrame(), screen.flippedVisibleFrame());
      this.setFrame(ratio(this.frame()));
    }
  }
  return this;
};


// Algorithmic vertical repositioning: cycles a column between spanning both rows and a single-top/single-bottom cell.
// Grid assumptions: 2 rows layout (cells even; indices laid out row-major). Examples (4 cells: 2x2, 6 cells: 3x2)
// Behavior:
//   - If window spans both rows in a column and moved NORTH -> collapse to top cell of that column.
//   - If window spans both rows and moved SOUTH -> collapse to bottom cell of that column.
//   - If window is a single bottom cell and moved NORTH -> move to top cell (same column).
//   - If window is a single top cell and moved SOUTH -> move to bottom cell (same column).
//   - Otherwise no change.
Window.prototype.reposition = function(dir) {
  if (!this.isEqual(LAST_POSITION.window)) return this;
  const spec = LAST_POSITION.grid; // e.g. "6,2,5"
  if (!spec) return this;
  const parts = spec.split(',').map(s => parseInt(s,10));
  if (parts.length !== 3 || parts.some(isNaN)) return this;
  const [cells,start,end] = parts;
  if (cells % 2 !== 0) return this; // only handle 2-row grids (row-major assumption)
  const cols = cells / 2;
  const startCol = start % cols;
  const endCol = end % cols;
  const startRow = Math.floor(start / cols);
  const endRow = Math.floor(end / cols);
  let targetStart = start, targetEnd = end;

  if (dir === DIR.NORTH || dir === DIR.SOUTH) {
    // Vertical cycling (existing logic, slightly reorganized)
    // Operate only when selection is a single column span (may cover both rows or a single cell)
    if (startCol !== endCol) return this;
    const spansBoth = startRow !== endRow; // two rows
    if (dir === DIR.NORTH) {
      if (spansBoth || startRow === 1) { // spanning or bottom single -> collapse to top
        targetStart = startCol; // row 0
        targetEnd = targetStart;
      } else return this; // already top
    } else { // SOUTH
      if (spansBoth || startRow === 0) { // spanning or top single -> collapse to bottom
        targetStart = startCol + cols; // row 1
        targetEnd = targetStart;
      } else return this; // already bottom
    }
  } else if (dir === DIR.EAST || dir === DIR.WEST) {
    // Horizontal cycling: mirror vertical behavior across columns within a single row.
    // Only operate when selection spans a single row (may cover multiple columns) OR is a single cell.
    if (startRow !== endRow) return this; // ignore multi-row spans (vertical logic handles those)
    const spansMultiple = startCol !== endCol;
    if (spansMultiple) {
      // Collapse a multi-column span to an edge cell depending on direction.
      if (dir === DIR.WEST) {
        targetStart = startRow * cols + startCol; // leftmost
        targetEnd = targetStart;
      } else { // EAST
        targetStart = startRow * cols + endCol; // rightmost
        targetEnd = targetStart;
      }
    } else { // single cell -> move laterally within row if possible
      if (dir === DIR.WEST && startCol > 0) {
        targetStart = targetEnd = start - 1;
      } else if (dir === DIR.EAST && startCol < cols - 1) {
        targetStart = targetEnd = start + 1;
      } else return this; // edge cell, no change
    }
  } else {
    return this; // unsupported direction
  }

  if (targetStart !== start || targetEnd !== end) {
    this.positionInGrid(cells, targetStart, targetEnd);
  }
  return this;
};


Window.prototype.positionInGrid = function (cells, start, end) {
  if (cells <= 0) return this;
  if (start < 0 || end < 0 || start >= cells || end >= cells) return this; // Guard invalid indices
  LAST_POSITION = {
    window: this,
    grid: cells + "," + start + "," + end
  }
  var cols = ~~(cells / 2);
  var screen = this.screen();
  var cellwidth = (screen.width() - ((cols - 1) * GEOM.PADDING)) / cols;
  var cellheight = (screen.height() - GEOM.PADDING) / 2;

  var startc = start % cols,
    startw = ~~(start / cols),
    startl = screen.origin().x + (cellwidth + GEOM.PADDING) * startc,
    startt = screen.origin().y + (cellheight + GEOM.PADDING) * startw,
    startr = startl + cellwidth,
    startb = startt + cellheight;

  var endc = end % cols,
    endw = ~~(end / cols),
    endl = screen.origin().x + (cellwidth + GEOM.PADDING) * endc,
    endt = screen.origin().y + (cellheight + GEOM.PADDING) * endw,
    endr = endl + cellwidth,
    endb = endt + cellheight;

  var frame = this.frame();
  frame.x = Math.min(startl, endl);
  frame.y = Math.min(startt, endt);
  frame.width = Math.max(startr, endr) - frame.x;
  frame.height = Math.max(startb, endb) - frame.y;
  this.setFrame(frame);
  return this;
}


// Resize a window by coeff units in the given direction
// coeff: -n shrinks by pixels units, +n grows by n pixels
Window.prototype.resize = function (dir, coeff) {
  var frame = this.frame()

  if (dir === DIR.WEST) frame.x += coeff * -1
  if (dir === DIR.NORTH) frame.y += coeff * -1
  if ([DIR.EAST, DIR.WEST].indexOf(dir) > -1) frame.width += coeff
  if ([DIR.NORTH, DIR.SOUTH].indexOf(dir) > -1) frame.height += coeff

  // Minimal size clamp
  if (frame.width < 40) frame.width = 40;
  if (frame.height < 40) frame.height = 40;
  this.setFrame(frame)
  return this
}


Window.prototype.toSpace = function (dir) {
  var curSpace = this.spaces()[0],
    newSpace = curSpace.next()

  if (dir === DIR.WEST)
    newSpace = curSpace.previous()

  if (!newSpace) return this; // Guard end-of-chain

  curSpace.removeWindows([this])
  newSpace.addWindows([this])
  this.focus()
  return this
}


Window.prototype.centerMouse = function () {
  if (!FOCUS.MOVE_POINTER_ON_FOCUS) return this;
  Mouse.move({
    x: this.frame().x + this.frame().width / 2,
    y: this.frame().y + this.frame().height / 2
  })
  return this
}

// Nudge the window by an (x,y) offset determined by direction
// dir: one of EAST/WEST/NORTH/SOUTH or single-char h/j/k/l synonyms
// amount: pixels (default MOVE.NUDGE_SMALL)
Window.prototype.nudge = function (dir, amount) {
  amount = amount || MOVE.NUDGE_SMALL;
  const frame = this.frame();
  switch (dir) {
    case DIR.EAST: case 'E': case 'l': frame.x += amount; break;
    case DIR.WEST: case 'W': case 'h': frame.x -= amount; break;
    case DIR.SOUTH: case 'S': case 'j': frame.y += amount; break;
    case DIR.NORTH: case 'N': case 'k': frame.y -= amount; break;
    default: return this;
  }
  // Clamp to screen visible frame
  try {
    const s = this.screen().flippedVisibleFrame();
    if (frame.x < s.x) frame.x = s.x;
    if (frame.y < s.y) frame.y = s.y;
    if (frame.x + frame.width > s.x + s.width) frame.x = s.x + s.width - frame.width;
    if (frame.y + frame.height > s.y + s.height) frame.y = s.y + s.height - frame.height;
  } catch (e) { }
  this.setFrame(frame);
  return this;
}


Window.prototype.log = function () {
  Phoenix.log(this.frame().x + "," + this.frame().y + "," + this.frame().width + "," + this.frame().height)
  return this
}


// ********************************************************************************
//  Focus Adjacent Window
// ********************************************************************************
// Refined adjacency: uses frame edges & overlap rather than just centers.
// Ranking (updated):
//  1. Overlapping along perpendicular axis (preferred)
//  2. Larger overlap span (how much they overlap along the perpendicular axis)
//  3. Larger window area (prefer substantial targets)
//  4. Primary directional distance (edge-to-edge, nearer is better)
//  5. Perpendicular center distance (tie-breaker)
// If no overlapping candidates exist, non-overlapping ones are considered (overlap span = 0).
// Does not traverse to other screens (future extension point).
Window.prototype.focusAdjacent = function (dir) {
  const cur = this.frame();
  const screen = this.screen();
  // Fast path: pull stats first (does not rebuild). If snapshot still valid soon, we avoid revalidation churn across rapid key repeats.
  const stats = (WindowRegistry.stats && WindowRegistry.stats()) || null;
  const entries = WindowRegistry.get(screen); // may rebuild if expired
  if (!entries.length) return this;
  const screenEntries = entries.filter(e => !e.win.isEqual(this));
  if (!screenEntries.length) return this;
  const { byLeft, byRight, byTop, byBottom } = WindowRegistry.getIndices(screen);
  // Attempt neighbor graph fast-path (precomputed directional adjacency)
  let neighborHashes = [];
  try {
    const nh = WindowRegistry.neighbors(this.hash());
    if (dir === DIR.NORTH && nh.North) neighborHashes = nh.North;
    else if (dir === DIR.SOUTH && nh.South) neighborHashes = nh.South;
    else if (dir === DIR.EAST && nh.East) neighborHashes = nh.East;
    else if (dir === DIR.WEST && nh.West) neighborHashes = nh.West;
  } catch (e) { }
  let neighborEntries = null;
  if (neighborHashes.length) {
    // Build a hash->entry map once (entries already small per screen)
    const map = new Map(entries.map(e => [e.hash, e]));
    neighborEntries = neighborHashes.map(h => map.get(h)).filter(Boolean);
  }

  // Allow a small tolerance so touching or slightly overlapping edges still count
  const TOL = FOCUS.ENABLE_GLOBAL_MRU ? GEOM.OVERLAP_TOLERANCE : 0; // pixels (centralized)
  const curCenterX = cur.x + cur.width / 2;
  const curCenterY = cur.y + cur.height / 2;

  const horizOverlap = (a, b) => !(a.x + a.width <= b.x + TOL || b.x + b.width <= a.x + TOL);
  const vertOverlap = (a, b) => !(a.y + a.height <= b.y + TOL || b.y + b.height <= a.y + TOL);

  // MRU bias helper (lower rank = more recent). Missing => large number.
  function mruRank(win) {
    if (!FOCUS.ENABLE_GLOBAL_MRU || !FOCUS_MRU.length) return 9999;
    const h = win.hash();
    const idx = FOCUS_MRU.indexOf(h);
    return idx === -1 ? 9999 : idx; // index 0 = most recent
  }

  function directionalMruRank(win) {
    if (!FOCUS.ENABLE_DIRECTIONAL_MRU) return 9999;
    const list = DIRECTIONAL_FOCUS_MRU[dir];
    if (!list || !list.length) return 9999;
    const h = win.hash();
    const idx = list.indexOf(h);
    return idx === -1 ? 9999 : idx;
  }

  function classify(entry) {
    const w = entry.win;
    const f = entry.frame;
    const centerX = entry.cx;
    const centerY = entry.cy;
    let primaryDist = Infinity;
    let overlapsPerp = false;
    let overlapSpan = 0;

    switch (dir) {
      case DIR.NORTH:
        if (f.y + f.height <= cur.y + TOL || centerY < curCenterY) {
          overlapsPerp = horizOverlap(f, cur);
          if (overlapsPerp) {
            const left = Math.max(f.x, cur.x);
            const right = Math.min(f.x + f.width, cur.x + cur.width);
            overlapSpan = Math.max(0, right - left);
          }
          primaryDist = Math.max(0, cur.y - (f.y + f.height));
        }
        break;
      case DIR.SOUTH:
        if (f.y >= cur.y + cur.height - TOL || centerY > curCenterY) {
          overlapsPerp = horizOverlap(f, cur);
          if (overlapsPerp) {
            const left = Math.max(f.x, cur.x);
            const right = Math.min(f.x + f.width, cur.x + cur.width);
            overlapSpan = Math.max(0, right - left);
          }
          primaryDist = Math.max(0, f.y - (cur.y + cur.height));
        }
        break;
      case DIR.EAST:
        if (f.x >= cur.x + cur.width - TOL || centerX > curCenterX) {
          overlapsPerp = vertOverlap(f, cur);
          if (overlapsPerp) {
            const top = Math.max(f.y, cur.y);
            const bottom = Math.min(f.y + f.height, cur.y + cur.height);
            overlapSpan = Math.max(0, bottom - top);
          }
          primaryDist = Math.max(0, f.x - (cur.x + cur.width));
        }
        break;
      case DIR.WEST:
        if (f.x + f.width <= cur.x + TOL || centerX < curCenterX) {
          overlapsPerp = vertOverlap(f, cur);
          if (overlapsPerp) {
            const top = Math.max(f.y, cur.y);
            const bottom = Math.min(f.y + f.height, cur.y + cur.height);
            overlapSpan = Math.max(0, bottom - top);
          }
          primaryDist = Math.max(0, cur.x - (f.x + f.width));
        }
        break;
      default:
        return null;
    }
    if (primaryDist === Infinity) return null;
    // Lazy compute of perpendicular center delta only if needed later; store centers for tie-break.
    return { w, f, overlapsPerp, overlapSpan, area: f.width * f.height, primaryDist, cx: centerX, cy: centerY, z: entry.z, mru: mruRank(w), dmru: directionalMruRank(w) };
  }

  // Binary search helpers for lower/upper bounds
  function upperBound(arr, getter, value) { // last index with getter(el) <= value
    let lo = 0, hi = arr.length - 1, ans = -1;
    while (lo <= hi) {
      const mid = (lo + hi) >> 1;
      if (getter(arr[mid]) <= value) { ans = mid; lo = mid + 1; } else hi = mid - 1;
    }
    return ans;
  }
  function lowerBound(arr, getter, value) { // first index with getter(el) >= value
    let lo = 0, hi = arr.length - 1, ans = arr.length;
    while (lo <= hi) {
      const mid = (lo + hi) >> 1;
      if (getter(arr[mid]) >= value) { ans = mid; hi = mid - 1; } else lo = mid + 1;
    }
    return ans;
  }

  let candidatePool = [];
  if (neighborEntries && neighborEntries.length) {
    candidatePool = neighborEntries;
  } else {
    // Original directional index coarse filtering
    switch (dir) {
      case DIR.NORTH: {
        const limit = cur.y + TOL;
        const idx = upperBound(byBottom, e => e.y + e.h, limit);
        if (idx >= 0) candidatePool = byBottom.slice(0, idx + 1);
        break;
      }
      case DIR.SOUTH: {
        const start = cur.y + cur.height - TOL;
        const idx = lowerBound(byTop, e => e.y, start);
        if (idx < byTop.length) candidatePool = byTop.slice(idx);
        break;
      }
      case DIR.EAST: {
        const start = cur.x + cur.width - TOL;
        const idx = lowerBound(byLeft, e => e.x, start);
        if (idx < byLeft.length) candidatePool = byLeft.slice(idx);
        break;
      }
      case DIR.WEST: {
        const limit = cur.x + TOL;
        const idx = upperBound(byRight, e => e.x + e.w, limit);
        if (idx >= 0) candidatePool = byRight.slice(0, idx + 1);
        break;
      }
      default:
        candidatePool = screenEntries;
    }
    if (!candidatePool.length) candidatePool = screenEntries;
  }

  const candidates = candidatePool.map(classify).filter(Boolean);
  if (!candidates.length) return this;

  // Prefer: overlap > larger overlap span > larger area > nearer primary distance > nearer perpendicular center > (fallback z original order).
  candidates.sort((a, b) => {
    // Primary structural ordering
    const ov = (a.overlapsPerp === b.overlapsPerp ? 0 : a.overlapsPerp ? -1 : 1);
    if (ov) return ov;
    const span = b.overlapSpan - a.overlapSpan; if (span) return span;
    const areaDiff = b.area - a.area; if (areaDiff) return areaDiff;
    const dmruDiff = a.dmru - b.dmru; if (dmruDiff) return dmruDiff; // direction-specific recency before global MRU
    const mruDiff = a.mru - b.mru; if (mruDiff) return mruDiff; // global recency fallback
    const prim = a.primaryDist - b.primaryDist; if (prim) return prim;
    // Deferred perpendicular center distance calculation
    const aPerp = (dir === DIR.NORTH || dir === DIR.SOUTH) ? Math.abs(curCenterX - a.cx) : Math.abs(curCenterY - a.cy);
    const bPerp = (dir === DIR.NORTH || dir === DIR.SOUTH) ? Math.abs(curCenterX - b.cx) : Math.abs(curCenterY - b.cy);
    if (aPerp !== bPerp) return aPerp - bPerp;
    return ((a.z ?? 9999) - (b.z ?? 9999));
  });

  const target = candidates[0];
  if (target) {
    target.w.focus();
    // Record directional MRU hit
    recordDirectionalFocus(dir, target.w);
    // Return the newly focused window so method chaining (e.g. .centerMouse()) applies to it
    return target.w;
  }
  return this; // no change
}


// ********************************************************************************
//  Modal Extensions
// ********************************************************************************

// Flash a modal in the center of a given screen
Modal.prototype.flash = function (screen) {
  var tf = this.frame(),
    sf = screen.frame();
  this.origin = {
    x: sf.x + sf.width / 2 - tf.width / 2,
    y: sf.y + sf.height / 2 - tf.height / 2
  }
  this.show();
  return this;
}


Modal.prototype.attach = function (window) {
  var tf = this.frame(),
    wf = window.frame(),
    sf = window.screen().frame();

  this.origin = {
    x: Math.min(
      Math.max(wf.x + wf.width / 2 - tf.width / 2, sf.x),
      sf.x + sf.width - tf.width
    ),
    y: Math.min(
      Math.max(Screen.all()[0].frame().height - (wf.y + wf.height / 2 + tf.height / 2), sf.y),
      sf.y + sf.height - tf.height
    )
  };
  this.show();
  return this;
}


// ********************************************************************************
//  Screen Extensions
// ********************************************************************************

Screen.prototype.width = function () { // DEPRECATED
  return this.flippedVisibleFrame().width - GEOM.PADDING * 2
}


Screen.prototype.height = function () { // DEPRECATED
  return this.flippedVisibleFrame().height - GEOM.PADDING * 2
}


Screen.prototype.origin = function () { // DEPRECATED
  return {
    x: this.flippedVisibleFrame().x + GEOM.PADDING,
    y: this.flippedVisibleFrame().y + GEOM.PADDING
  }
}


// ********************************************************************************
//  Utilities
// ********************************************************************************

// Unified WindowRegistry: shared snapshot for visible windows with derived metrics.
// Replaces WindowSnapshotCache and can be extended further (e.g., directional indices).
const WindowRegistry = (() => {
  let ttl = PERF.REGISTRY_TTL_BASE_MS; // adaptive TTL (starts at base)
  let expiry = 0;
  let cache = new Map(); // screenIndex -> { entries: [...], indices: { byLeft, byRight, byTop, byBottom } }
  let lastRebuildTs = 0;
  let lastDuration = 0;
  let consecutiveFast = 0;
  let consecutiveSlow = 0;
  let version = 0; // incremented on any structural change
  let flatAll = null; // cached flattened entries array for getAllEntries / space partition
  let flatAllVersion = -1;
  let bySpace = new Map(); // spaceId -> array of entries
  let neighborsVersion = -1; // version of neighbor graph
  let neighborMap = new Map(); // hash -> {North:[],South:[],East:[],West:[]}
  // Dirty flags for incremental index resorting
  let dirtyLeft = false, dirtyRight = false, dirtyTop = false, dirtyBottom = false, dirtySpace = false;

  function buildEntry(w, order) {
    const f = w.frame();
    const app = w.app();
    let appId = null;
    try { appId = (app.bundleIdentifier && app.bundleIdentifier()) || app.pid(); } catch (e) { appId = app.pid(); }
    const title = w.title();
    // Precompute whether app has multiple windows (expensive to call repeatedly later)
    let multi = false;
    try { multi = app.windows().length > 1; } catch (e) { multi = false; }
    return {
      win: w,
      frame: f,
      x: f.x, y: f.y, w: f.width, h: f.height,
      cx: f.x + f.width / 2,
      cy: f.y + f.height / 2,
      area: f.width * f.height,
      z: order,
      hash: w.hash(),
      appId: appId,
      titleShort: title.length > 15 ? title.substr(0, 15) + "…" : title,
      multi
    };
  }

  function rebuild() {
    const start = Date.now();
    cache.clear();
    bySpace.clear();
    Screen.all().forEach((scr, idx) => {
      const entries = scr.windows({ visible: true }).map(buildEntry);
      // Precompute directional indices (store indices to avoid duplicating objects)
      const byLeft = entries.slice().sort((a, b) => a.x - b.x);
      const byRight = entries.slice().sort((a, b) => (a.x + a.w) - (b.x + b.w));
      const byTop = entries.slice().sort((a, b) => a.y - b.y);
      const byBottom = entries.slice().sort((a, b) => (a.y + a.h) - (b.y + b.h));
      cache.set(idx, { entries, indices: { byLeft, byRight, byTop, byBottom } });
      // space partitioning (first space only heuristic)
      entries.forEach(e => {
        let sid = null;
        try { const sp = e.win.spaces && e.win.spaces(); if (sp && sp.length) sid = sp[0].hash ? sp[0].hash() : sp[0]; } catch (err) { }
        if (!sid) return; // skip if unknown
        if (!bySpace.has(sid)) bySpace.set(sid, []);
        bySpace.get(sid).push(e);
      });
    });
    lastDuration = Date.now() - start;
    lastRebuildTs = Date.now();
    // Adaptive backoff: if rebuilds are expensive, extend TTL; if very cheap repeatedly, allow slight shrink
    if (PERF.REGISTRY_ADAPTIVE) {
      if (lastDuration > 25) { // considered slow
        consecutiveSlow++; consecutiveFast = 0;
        if (consecutiveSlow >= 2) { // two slow rebuilds back to back
          ttl = Math.min(PERF.REGISTRY_TTL_MAX_MS, Math.round(ttl * 1.4));
          consecutiveSlow = 0; // reset streak
        }
      } else if (lastDuration < 6) { // very fast
        consecutiveFast++; consecutiveSlow = 0;
        if (consecutiveFast >= 4 && ttl > PERF.REGISTRY_TTL_MIN_MS) {
          ttl = Math.max(PERF.REGISTRY_TTL_MIN_MS, Math.round(ttl * 0.85));
          consecutiveFast = 0;
        }
      } else {
        consecutiveFast = 0; consecutiveSlow = 0; // neutral rebuild
      }
    }
    expiry = Date.now() + ttl;
    version++;
    flatAll = null; // invalidate flattened cache
    flatAllVersion = -1;
    neighborsVersion = -1; neighborMap.clear();
  }

  function ensureIndices(scrIdx) {
    const rec = cache.get(scrIdx);
    if (!rec) return;
    if (dirtyLeft) rec.indices.byLeft = rec.entries.slice().sort((a, b) => a.x - b.x);
    if (dirtyRight) rec.indices.byRight = rec.entries.slice().sort((a, b) => (a.x + a.w) - (b.x + b.w));
    if (dirtyTop) rec.indices.byTop = rec.entries.slice().sort((a, b) => a.y - b.y);
    if (dirtyBottom) rec.indices.byBottom = rec.entries.slice().sort((a, b) => (a.y + a.h) - (b.y + b.h));
  }

  function flushDirty() {
    if (!(dirtyLeft || dirtyRight || dirtyTop || dirtyBottom || dirtySpace)) return;
    cache.forEach((_, idx) => ensureIndices(idx));
    if (dirtySpace) rebuildSpacePartitions();
    dirtyLeft = dirtyRight = dirtyTop = dirtyBottom = dirtySpace = false;
    version++; flatAll = null; flatAllVersion = -1;
    neighborsVersion = -1; neighborMap.clear();
  }

  function rebuildSpacePartitions() {
    bySpace.clear();
    cache.forEach(rec => {
      rec.entries.forEach(e => {
        let sid = null;
        try { const sp = e.win.spaces && e.win.spaces(); if (sp && sp.length) sid = sp[0].hash ? sp[0].hash() : sp[0]; } catch (err) { }
        if (!sid) return;
        if (!bySpace.has(sid)) bySpace.set(sid, []);
        bySpace.get(sid).push(e);
      });
    });
  }

  function updateWindow(win, typ) {
    if (Date.now() > expiry) rebuild(); // baseline freshness
    const scr = win.screen && win.screen();
    if (!scr) { return; }
    const idx = Screen.all().indexOf(scr);
    if (idx === -1) return;
    let rec = cache.get(idx);
    if (!rec) { rebuild(); return; }
    const h = win.hash();
    if (typ === 'close') {
      const beforeLen = rec.entries.length;
      rec.entries = rec.entries.filter(e => e.hash !== h);
      if (rec.entries.length !== beforeLen) {
        dirtyLeft = dirtyRight = dirtyTop = dirtyBottom = true; dirtySpace = true; version++; flatAll = null; flatAllVersion = -1;
        neighborsVersion = -1; neighborMap.clear();
      }
      return;
    }
    // find existing
    let entry = rec.entries.find(e => e.hash === h);
    if (!entry) {
      if (typ === 'open') {
        entry = buildEntry(win);
        rec.entries.push(entry);
        dirtyLeft = dirtyRight = dirtyTop = dirtyBottom = true; dirtySpace = true;
        version++; flatAll = null; flatAllVersion = -1;
      }
      return;
    }
    // move/resize: update geometry in place
    if (typ === 'move' || typ === 'resize') {
      const f = win.frame();
      if (f.x !== entry.x || f.y !== entry.y || f.width !== entry.w || f.height !== entry.h) {
        entry.frame = f; entry.x = f.x; entry.y = f.y; entry.w = f.width; entry.h = f.height; entry.cx = f.x + f.width / 2; entry.cy = f.y + f.height / 2; entry.area = f.width * f.height;
        dirtyLeft = dirtyRight = dirtyTop = dirtyBottom = true; dirtySpace = true; version++; flatAll = null; flatAllVersion = -1;
        neighborsVersion = -1; neighborMap.clear();
      }
    }
  }

  function buildNeighbors() {
    // Build directional neighbor lists using sweep-line heuristics.
    flushDirty();
    neighborMap.clear();
    const all = flatAll && flatAllVersion === version ? flatAll : (() => { let arr = []; cache.forEach(v => arr = arr.concat(v.entries)); return arr; })();
    // Initialize
    all.forEach(e => neighborMap.set(e.hash, { North: [], South: [], East: [], West: [] }));
    const TOL = GEOM.OVERLAP_TOLERANCE;
    // Horizontal neighbors (E/W): sort by x
    const byX = all.slice().sort((a, b) => a.x - b.x);
    for (let i = 0; i < byX.length; i++) {
      const a = byX[i];
      for (let j = i + 1; j < byX.length; j++) {
        const b = byX[j];
        if (b.x - (a.x + a.w) > PERF.NEIGHBOR_SCAN_MAX_DIST) break; // hard cap distance to limit scan
        // vertical overlap check
        const overlapY = !(a.y + a.h <= b.y + TOL || b.y + b.h <= a.y + TOL);
        if (!overlapY) continue;
        const dist = b.x - (a.x + a.w);
        if (dist >= -TOL) { // b to the East of a
          neighborMap.get(a.hash).East.push(b.hash);
          neighborMap.get(b.hash).West.push(a.hash);
        }
      }
    }
    // Vertical neighbors (N/S): sort by y
    const byY = all.slice().sort((a, b) => a.y - b.y);
    for (let i = 0; i < byY.length; i++) {
      const a = byY[i];
      for (let j = i + 1; j < byY.length; j++) {
        const b = byY[j];
        if (b.y - (a.y + a.h) > 600) break;
        const overlapX = !(a.x + a.w <= b.x + TOL || b.x + b.w <= a.x + TOL);
        if (!overlapX) continue;
        const dist = b.y - (a.y + a.h);
        if (dist >= -TOL) { // b South of a
          neighborMap.get(a.hash).South.push(b.hash);
          neighborMap.get(b.hash).North.push(a.hash);
        }
      }
    }
    neighborsVersion = version;
  }

  return {
    get(screen) {
      if (Date.now() > expiry) rebuild();
      flushDirty();
      const idx = Screen.all().indexOf(screen);
      const rec = cache.get(idx);
      return rec ? rec.entries : [];
    },
    getIndices(screen) {
      if (Date.now() > expiry) rebuild();
      flushDirty();
      const idx = Screen.all().indexOf(screen);
      const rec = cache.get(idx);
      return rec ? rec.indices : { byLeft: [], byRight: [], byTop: [], byBottom: [] };
    },
    getAllEntries() { // flattened list across screens (no rebuild loop duplication)
      if (Date.now() > expiry) rebuild();
      flushDirty();
      let all = [];
      cache.forEach(v => { all = all.concat(v.entries); });
      return all;
    },
    getAllEntriesFlattened() { // cached flattened array until version changes
      if (Date.now() > expiry) rebuild();
      flushDirty();
      if (flatAll && flatAllVersion === version) return flatAll;
      flatAll = [];
      cache.forEach(v => { flatAll = flatAll.concat(v.entries); });
      flatAllVersion = version;
      return flatAll;
    },
    getSpaceEntries(spaceId) { if (Date.now() > expiry) rebuild(); flushDirty(); return bySpace.get(spaceId) || []; },
    updateWindow,
    neighbors(hash) { if (neighborsVersion !== version) buildNeighbors(); return neighborMap.get(hash) || { North: [], South: [], East: [], West: [] }; },
    clear() { cache.clear(); expiry = 0; },
    /**
     * WindowRegistry statistics snapshot.
     * @returns {{ttl:number, expiresIn:number, lastDuration:number, version:number, cachedFlat:boolean}}
     */
    stats() { return { ttl, expiresIn: Math.max(0, expiry - Date.now()), lastDuration, version, cachedFlat: !!flatAll }; }
  };
})();

// Layout cache: key = screenIndex|mode|windowHashes (sorted). Stores array of frames.
const LAYOUT_CACHE = new Map();
function layoutCacheKey(screen, mode, windows) {
  const idx = Screen.all().indexOf(screen);
  const hashes = windows.map(w => w.hash()).sort().join(':');
  return idx + '|' + mode + '|' + hashes;
}

// (Removed) Array.prototype.rotate -- replaced with Util.rotateArray to avoid prototype pollution.

// Opposite direction lookup (includes diagonals for symmetry operations)
const OPPOSITE = Object.freeze({
  [DIR.NORTH]: DIR.SOUTH,
  [DIR.SOUTH]: DIR.NORTH,
  [DIR.EAST]: DIR.WEST,
  [DIR.WEST]: DIR.EAST,
  [DIR.NW]: DIR.SE,
  [DIR.NE]: DIR.SW,
  [DIR.SW]: DIR.NE,
  [DIR.SE]: DIR.NW,
});
function opposite(dir) { return OPPOSITE[dir] || dir; }

// ********************************************************************************
//  Focus MRU Tracking
// ********************************************************************************
// Tracks most recently focused windows to bias adjacency (recency preference after area/overlap).
const FOCUS_MRU = [];
// Directional MRU: direction -> array of window hashes (most recent first)
const DIRECTIONAL_FOCUS_MRU = { North: [], South: [], East: [], West: [] };
function recordFocus(win) {
  if (!FOCUS.ENABLE_GLOBAL_MRU || !win) return;
  try {
    const h = win.hash();
    const idx = FOCUS_MRU.indexOf(h);
    if (idx !== -1) FOCUS_MRU.splice(idx, 1);
    FOCUS_MRU.unshift(h);
    if (FOCUS_MRU.length > FOCUS.GLOBAL_MRU_LIMIT) FOCUS_MRU.pop();
  } catch (e) { }
}

function recordDirectionalFocus(dir, win) {
  if (!FOCUS.ENABLE_DIRECTIONAL_MRU || !win) return;
  const bucket = DIRECTIONAL_FOCUS_MRU[dir];
  if (!bucket) return;
  try {
    const h = win.hash();
    const idx = bucket.indexOf(h);
    if (idx !== -1) bucket.splice(idx, 1);
    bucket.unshift(h);
    if (bucket.length > FOCUS.DIRECTIONAL_MRU_LIMIT) bucket.pop();
  } catch (e) { }
}

['windowDidBecomeMain', 'windowDidFocus'].forEach(ev => Event.on(ev, () => {
  try { const w = Window.focused(); if (w) recordFocus(w); } catch (e) { }
}));


// ********************************************************************************
//  Startup
// ********************************************************************************

const HintManager = new Hints() // ISSUE: Singleton pattern; if reloaded dynamically may leak old key bindings.

// ********************************************************************************
//  Move Mode Controller
// ********************************************************************************
class MoveModeController {
  constructor() {
    this.active = false;
    this.window = null;
    this.overlay = null;
    this.bindings = [];
  }
  _buildOverlay() {
    if (!this.window) return;
    try { if (this.overlay) this.overlay.close(); } catch (e) { }
    try {
      // Fetch or cache the app icon for the focused window
      let ic = undefined;
      try {
        const key = iconKey(this.window);
        if (!ICON_CACHE[key]) {
          ICON_CACHE[key] = this.window.app().icon();
        }
        ic = ICON_CACHE[key];
      } catch (e) { }
      this.overlay = Modal.build({
        text: '[ MOVE ]\nEnter/Esc to exit',
        appearance: HINT.APPEARANCE,
        weight: 18,
        duration: 0, // persistent until closed
        icon: ic
      }).attach(this.window);
    } catch (e) { }
  }
  _repositionOverlay() { // refresh modal position after window move
    if (!this.overlay || !this.window) return;
    try { this.overlay.attach(this.window); } catch (e) { }
  }
  activate(win) {
    if (this.active) { // toggle off
      return this.deactivate();
    }
    this.window = win || Window.focused();
    if (!this.window) return;
    this.active = true;
    this._buildOverlay();
    this._bindKeys();
  }
  _bindKeys() {
    const self = this;
    const push = (k, mods, fn) => { self.bindings.push(Key.on(k, mods, fn)); };
    function nudgeDir(dir, amt) {
      if (!self.window || !self.active) return;
      self.window.nudge(dir, amt);
      self._repositionOverlay();
    }
    // Unmodified keys = LARGE nudges
  push('h', [], () => nudgeDir(DIR.WEST, MOVE.NUDGE_LARGE));
  push('j', [], () => nudgeDir(DIR.SOUTH, MOVE.NUDGE_LARGE));
  push('k', [], () => nudgeDir(DIR.NORTH, MOVE.NUDGE_LARGE));
  push('l', [], () => nudgeDir(DIR.EAST, MOVE.NUDGE_LARGE));
  push('left', [], () => nudgeDir(DIR.WEST, MOVE.NUDGE_LARGE));
  push('down', [], () => nudgeDir(DIR.SOUTH, MOVE.NUDGE_LARGE));
  push('up', [], () => nudgeDir(DIR.NORTH, MOVE.NUDGE_LARGE));
  push('right', [], () => nudgeDir(DIR.EAST, MOVE.NUDGE_LARGE));
    // Shift-modified keys = SMALL nudges
  push('h', ['shift'], () => nudgeDir(DIR.WEST, MOVE.NUDGE_SMALL));
  push('j', ['shift'], () => nudgeDir(DIR.SOUTH, MOVE.NUDGE_SMALL));
  push('k', ['shift'], () => nudgeDir(DIR.NORTH, MOVE.NUDGE_SMALL));
  push('l', ['shift'], () => nudgeDir(DIR.EAST, MOVE.NUDGE_SMALL));
  push('left', ['shift'], () => nudgeDir(DIR.WEST, MOVE.NUDGE_SMALL));
  push('down', ['shift'], () => nudgeDir(DIR.SOUTH, MOVE.NUDGE_SMALL));
    push('up', ['shift'], () => nudgeDir(NORTH, MOVE.NUDGE_SMALL));
    push('right', ['shift'], () => nudgeDir(EAST, MOVE.NUDGE_SMALL));
    // Exit keys
    push('escape', [], () => self.deactivate());
    push('return', [], () => self.deactivate());
    // Auto-cancel on mouse click (like hints)
    Event.once("mouseDidLeftClick", () => self.deactivate());
  }
  deactivate() {
    if (!this.active) return;
    this.active = false;
    this.window = null;
    this.bindings.forEach(Key.off); this.bindings = [];
    try { if (this.overlay) this.overlay.close(); } catch (e) { }
    this.overlay = null;
  }
}

const MoveMode = new MoveModeController();

Modal.build({
  text: "Ready",
  appearance: HINT.APPEARANCE,
  weight: 24,
  icon: App.get('Phoenix').icon(),
  duration: 0.5,
}).flash(Screen.all()[0]);

// ********************************************************************************
//  Cache Invalidation Hooks
// ********************************************************************************
// Debounced invalidation so rapid bursts of events (e.g. live resize) only rebuild once.
; (function () {
  if (typeof WindowRegistry === 'undefined') return;
  let invalidateTimer = null;
  const DEBOUNCE_MS = PERF.EVENT_DEBOUNCE_MS; // migrated from WINDOW_EVENT_DEBOUNCE_MS
  function scheduleInvalidate(kind, winFetcher) {
    // For open/close we still fallback to full clear; for move/resize attempt incremental
    if (kind === 'move' || kind === 'resize') {
      try { const w = winFetcher && winFetcher(); if (w) WindowRegistry.updateWindow(w, kind); } catch (e) { }
      return; // no debounce needed for simple geometry update
    }
    if (invalidateTimer) return; // coalesce full rebuild triggers
    invalidateTimer = Timer.after(DEBOUNCE_MS / 1000, () => { WindowRegistry.clear(); invalidateTimer = null; });
  }

  Event.on('windowDidMove', () => scheduleInvalidate('move', () => Window.focused()));
  Event.on('windowDidResize', () => scheduleInvalidate('resize', () => Window.focused()));
  Event.on('windowDidOpen', () => scheduleInvalidate('open'));
  Event.on('windowDidClose', () => scheduleInvalidate('close'));
  Event.on('windowDidMinimize', () => scheduleInvalidate('close'));
  Event.on('windowDidUnminimize', () => scheduleInvalidate('open'));
  Event.on('windowDidChangeScreen', () => scheduleInvalidate('open'));
  Event.on('windowDidChangeSpace', () => scheduleInvalidate('open'));
  Event.on('windowDidBecomeMain', () => scheduleInvalidate('move', () => Window.focused()));
})();

This page is referenced in: