{"version":3,"sources":["../src/debug.ts"],"sourcesContent":["// System-app devtools — the app-facing surface (plan: docs/plans/system-app-devtools.md).\n//\n// Two opt-in, DEV-ONLY instruments for debugging a sandboxed UI-as-app region:\n//   1. `debug.log(...)` — an app→host one-way log surfaced in the host dev panel\n//      / CLI `/debug` stream (instead of hand-fishing console output out of a\n//      cross-origin iframe's devtools).\n//   2. a DOM/layout responder the host can query from outside — the thing a\n//      cross-origin screenshot can't reliably give you (a blank capture is\n//      ambiguous between a real 0-height collapse and a paint artifact) — which\n//      since R3-423 also carries two BOUNDED INPUT verbs, for the canvas/SVG apps\n//      that have no accessibility node to drive from outside at all.\n//\n// SECURITY (the gating constraint — see the plan's §0):\n//   - Both are inert unless the HOST signals dev mode via the `debug-enabled`\n//     channel. The host only sets it for a dev/override session (the `ir-dev-*`\n//     deep link) or an explicit operator developer-mode. A published app served\n//     to a normal user gets `enabled:false` → `debug.log` is a no-op and the\n//     responder never answers. Production isolation is therefore unchanged.\n//   - The responder's vocabulary is CLOSED and fixed in this file: three READ\n//     verbs (snapshotDom / computedStyle / rect) and two bounded ACTION verbs\n//     (dispatchPointer / dispatchKey, §3 below). It is therefore no longer\n//     read-only, and saying so here is the point — the posture documented is the\n//     one that ships. There is still deliberately NO eval bridge: that would turn\n//     a debug aid into remote code execution into the sandbox, and an unrecognised\n//     method is refused rather than interpreted.\n//   - What bounds an ACTION verb: ONE synthetic event per query; `type` drawn from\n//     a 5-name pointer set or a 3-name key set; coordinates clamped to the\n//     viewport; key/code names truncated to 32 chars; button state limited to\n//     \"none\" or \"primary held\"; modifiers coerced to booleans. No caller-supplied\n//     property bag ever reaches an event constructor, and a synthetic event is\n//     `isTrusted:false` in every browser, so it can never satisfy a user-activation\n//     gate (no popup, clipboard write, fullscreen, passkey prompt or download).\n//   - The responder reads only its OWN `document` (it lives in its own opaque\n//     iframe and cannot reach a sibling app), so there is no app↔app leak even\n//     in dev.\n//   - Output is bounded (node/depth/text caps) so a query can't exfiltrate an\n//     unbounded payload or wedge the app.\n//\n// DEV-ONLY, read verbs and action verbs alike: the gate above is re-checked on\n// every query, so in a production session this module answers nothing and sends\n// nothing. Apps that want their own call sites GONE from the shipped bytes (rather\n// than merely inert) guard them behind `import.meta.env.DEV`, which lets the\n// bundler drop them from a production build; the runtime gate is the backstop that\n// holds regardless of how the app was built.\n\nimport { createPushChannel } from './pushChannel';\nimport { sendMessage, addListener } from './sandboxUtils';\nimport { DEBUG_ENABLED, DEBUG_LOG, DEBUG_QUERY, DEBUG_QUERY_RESULT, REQUEST_DEBUG_ENABLED } from './generated/protocol';\n\n/** Severity of a {@link debug.log} entry. */\nexport type DebugLevel = 'debug' | 'info' | 'warn' | 'error';\n\n// ── Dev gate ────────────────────────────────────────────────────────────────\n// The host pushes `debug-enabled:true` only for a dev/override session. Until\n// then (and always in production) it stays false and every instrument is inert.\nconst enabledChannel = createPushChannel<boolean>({\n  pushType: DEBUG_ENABLED,\n  requestType: REQUEST_DEBUG_ENABLED,\n  initial: false,\n  parse: (msg) => (typeof msg.enabled === 'boolean' ? msg.enabled : undefined),\n});\n\n/** Is the host dev-debug surface active for this session? `false` in production. */\nexport const isDebugEnabled = (): boolean => enabledChannel.get();\n\n/** React hook: whether the host dev-debug surface is active (re-renders on change).\n *  Handy for showing a debug affordance only when it would do something. */\nexport const useDebugEnabled = (): boolean => enabledChannel.use();\n\n// ── 1. App→host debug log ─────────────────────────────────────────────────────\n// Best-effort: a value that can't be structured-cloned is replaced with a marker\n// rather than throwing — `debug.log` must never break the app.\nconst MAX_DATA_BYTES = 16 * 1024;\n\nfunction safeData(data: unknown): unknown {\n  if (data === undefined) return undefined;\n  try {\n    const json = JSON.stringify(data);\n    if (json === undefined) return '[unserializable]';\n    if (json.length > MAX_DATA_BYTES) return `[truncated ${json.length}B]`;\n    return JSON.parse(json);\n  } catch {\n    return '[unserializable]';\n  }\n}\n\n/**\n * Emit a structured debug entry to the host dev surface. A NO-OP unless the host\n * has enabled the dev-debug session ({@link isDebugEnabled}); in production it\n * does nothing and sends nothing.\n *\n *   debug.log('info', 'mounted', { activeFile });\n */\nexport function log(level: DebugLevel, message: string, data?: unknown): void {\n  if (!enabledChannel.get()) return; // inert in prod / non-dev sessions\n  try {\n    sendMessage(DEBUG_LOG, { level, message: String(message), data: safeData(data) });\n  } catch {\n    /* transport not ready — drop silently; logging must never throw */\n  }\n}\n\n// ── 2. Read DOM / layout verbs ────────────────────────────────────────────────\n// The host sends `debug-query` { id, method, params }; we reply with\n// `debug-query-result` { id, ok, result | error }. Only ever active while the dev\n// gate is enabled. The vocabulary is fixed: these three verbs READ, and the two in\n// §3 act — nothing in it interprets caller-supplied code.\n\ninterface DomNode {\n  tag: string;\n  id?: string;\n  classes?: string[];\n  attrs?: Record<string, string>;\n  rect?: { x: number; y: number; w: number; h: number };\n  text?: string;\n  children?: DomNode[];\n  truncated?: true;\n}\n\nconst ATTR_ALLOW = new Set(['role', 'aria-hidden', 'data-theme', 'data-active', 'href', 'type', 'hidden']);\nconst MAX_NODES = 2000;\nconst MAX_DEPTH = 25;\nconst MAX_TEXT = 200;\n\nfunction round(n: number): number {\n  return Math.round(n);\n}\n\nfunction snapshotDom(params: { selector?: string; maxDepth?: number; maxNodes?: number }): DomNode | null {\n  if (typeof document === 'undefined') return null;\n  const root = params.selector ? document.querySelector(params.selector) : document.body;\n  if (!root) return null;\n  const maxDepth = Math.min(params.maxDepth ?? MAX_DEPTH, MAX_DEPTH);\n  const maxNodes = Math.min(params.maxNodes ?? MAX_NODES, MAX_NODES);\n  let budget = maxNodes;\n\n  const walk = (el: Element, depth: number): DomNode => {\n    budget--;\n    const r = el.getBoundingClientRect();\n    const classes = el.classList.length ? [...el.classList] : undefined;\n    const attrs: Record<string, string> = {};\n    for (const name of el.getAttributeNames()) {\n      if (ATTR_ALLOW.has(name)) attrs[name] = el.getAttribute(name) ?? '';\n    }\n    // Direct text (not descendants') so a leaf's label is visible without dumping\n    // the whole subtree's text.\n    const ownText = [...el.childNodes]\n      .filter((n) => n.nodeType === 3)\n      .map((n) => (n.textContent ?? '').trim())\n      .join(' ')\n      .trim();\n    const node: DomNode = {\n      tag: el.tagName.toLowerCase(),\n      ...(el.id ? { id: el.id } : {}),\n      ...(classes ? { classes } : {}),\n      ...(Object.keys(attrs).length ? { attrs } : {}),\n      rect: { x: round(r.x), y: round(r.y), w: round(r.width), h: round(r.height) },\n      ...(ownText ? { text: ownText.slice(0, MAX_TEXT) } : {}),\n    };\n    if (depth < maxDepth && el.children.length && budget > 0) {\n      const children: DomNode[] = [];\n      for (const child of el.children) {\n        if (budget <= 0) {\n          node.truncated = true;\n          break;\n        }\n        children.push(walk(child, depth + 1));\n      }\n      if (children.length) node.children = children;\n    } else if (el.children.length) {\n      node.truncated = true;\n    }\n    return node;\n  };\n\n  return walk(root, 0);\n}\n\nfunction computedStyle(params: { selector: string; props: string[] }): Record<string, string> | null {\n  if (typeof document === 'undefined') return null;\n  const el = document.querySelector(params.selector);\n  if (!el) return null;\n  const cs = getComputedStyle(el);\n  const out: Record<string, string> = {};\n  for (const p of params.props.slice(0, 50))\n    out[p] = cs.getPropertyValue(p) || cs[p as keyof CSSStyleDeclaration]?.toString?.() || '';\n  return out;\n}\n\nfunction rects(params: { selector: string }): Array<{ x: number; y: number; w: number; h: number }> {\n  if (typeof document === 'undefined') return [];\n  return [...document.querySelectorAll(params.selector)].slice(0, 200).map((el) => {\n    const r = el.getBoundingClientRect();\n    return { x: round(r.x), y: round(r.y), w: round(r.width), h: round(r.height) };\n  });\n}\n\n// ── 3. Bounded input injection (roadmap R3-423) ───────────────────────────────\n//\n// WHY. A canvas app (arcade) or an SVG app (a hex map) cannot be driven from outside\n// at all: the frame is opaque-origin, so `evaluate_script` cannot reach it, and there\n// is no accessibility node to click — the interactive surface is pixels. The drill\n// either cannot run or degenerates into screenshot-eyeballing.\n//\n// WHY THIS IS NOT AN EVAL BRIDGE. The caller supplies COORDINATES and a key NAME from\n// closed vocabularies, never code and never a selector-driven callback. Everything\n// this can do, a human with a mouse could already do to the same frame; nothing here\n// reads state back beyond the read vocabulary that already exists.\n//\n// WHY IT IS SAFE EVEN SO:\n//   - Same dev gate as the read verbs — inert unless the host pushed\n//     `debug-enabled:true`, which it only does for a dev/override session.\n//   - A synthetic event is `isTrusted: false` in every browser, so it can never\n//     satisfy a USER-ACTIVATION gate: no popup, no clipboard write, no fullscreen,\n//     no passkey prompt, no download. This is the property that keeps a bounded\n//     injector from being an escalation, and it is a browser invariant rather than\n//     something this module enforces.\n//   - The event TYPE comes from a closed set, coordinates are finite and clamped to\n//     the viewport, the button state is \"none\" or \"primary held\" and nothing else,\n//     and modifiers are booleans. No arbitrary property bag reaches the constructor,\n//     so a caller cannot forge `isTrusted` or smuggle a handler.\n//   - It targets whatever is at the point in this frame's OWN document; the frame\n//     cannot reach a sibling app, exactly as for the read verbs.\n\nconst POINTER_TYPES = new Set(['pointerdown', 'pointerup', 'pointermove', 'click', 'dblclick']);\nconst KEY_TYPES = new Set(['keydown', 'keyup', 'keypress']);\n\nconst clampCoord = (v: unknown, max: number): number => {\n  const n = typeof v === 'number' && Number.isFinite(v) ? v : 0;\n  return Math.max(0, Math.min(Math.round(n), Math.max(0, Math.round(max))));\n};\n\nconst flag = (v: unknown): boolean => v === true;\n\n/** The only button mask this verb will synthesise: the primary button. */\nconst PRIMARY = 1;\n\n/**\n * The `buttons` bitmask (which buttons are HELD, not which one changed) for an\n * injected pointer event.\n *\n * This used to be `1` for everything except an up/click, which made EVERY injected\n * move read as a drag: a hover test was impossible to write, and a canvas app's\n * `if (e.buttons)` branch fired on a plain move — exactly the apps the verb targets.\n * So the caller says which it wants, inside the same closed bound as `type`: a move\n * carries NO buttons unless the caller asks for `buttons: 1` (or `drag: true`), and\n * nothing else is accepted. A press is held-by-definition and a release is\n * released-by-definition, so those two do not read the caller's ask at all.\n */\nconst heldButtons = (type: string, params: Record<string, unknown>): number => {\n  if (type === 'pointerdown') return PRIMARY; // a press: the button is down by definition\n  if (type !== 'pointermove') return 0; // pointerup / click / dblclick: already released\n  return params.buttons === PRIMARY || flag(params.drag) ? PRIMARY : 0;\n};\n\n/** Dispatch one bounded pointer event at a viewport coordinate inside THIS frame.\n *  Returns what it hit, so a drill can assert it aimed at the right thing rather\n *  than clicking into the void and reading a screenshot to find out.\n *\n *  `params`: `{ type, x, y, buttons?: 0 | 1, drag?: boolean, ctrl/shift/alt/metaKey? }`.\n *  A `pointermove` is a HOVER by default; pass `buttons: 1` (or `drag: true`) for the\n *  move-with-primary-held that a drag is made of. */\nfunction dispatchPointer(params: Record<string, unknown>): { type: string; x: number; y: number; target: string } {\n  if (typeof document === 'undefined' || typeof window === 'undefined') {\n    throw new Error('no document in this realm');\n  }\n  const type = typeof params.type === 'string' && POINTER_TYPES.has(params.type) ? params.type : 'click';\n  const x = clampCoord(params.x, window.innerWidth);\n  const y = clampCoord(params.y, window.innerHeight);\n  const target = document.elementFromPoint(x, y) ?? document.body;\n  if (!target) throw new Error('nothing at that point');\n  const init: PointerEventInit = {\n    bubbles: true,\n    cancelable: true,\n    composed: true,\n    clientX: x,\n    clientY: y,\n    pointerId: 1,\n    pointerType: 'mouse',\n    isPrimary: true,\n    // `button` names the button whose state CHANGED. A move changes nothing, so it is\n    // -1 there (UI Events §5.2.3) — otherwise a `e.button === 0` check reads a hover\n    // as a primary click.\n    button: type === 'pointermove' ? -1 : 0,\n    buttons: heldButtons(type, params),\n    ctrlKey: flag(params.ctrlKey),\n    shiftKey: flag(params.shiftKey),\n    altKey: flag(params.altKey),\n    metaKey: flag(params.metaKey),\n  };\n  // `click`/`dblclick` are MouseEvents; the rest are PointerEvents. Constructing the\n  // right class matters for a canvas app that reads `pointerId`/`pointerType`.\n  // A realm without `PointerEvent` (jsdom, an older engine) falls back to a\n  // MouseEvent of the SAME TYPE — which still reaches a `pointerdown` listener, so\n  // the verb degrades instead of throwing. The responder must never throw into an\n  // app; and a drill that gets a slightly thinner event is strictly better off than\n  // one that gets an error.\n  const usePointer = type !== 'click' && type !== 'dblclick' && typeof PointerEvent === 'function';\n  target.dispatchEvent(usePointer ? new PointerEvent(type, init) : new MouseEvent(type, init));\n  const desc = target instanceof Element ? target.tagName.toLowerCase() : 'unknown';\n  return { type, x, y, target: desc };\n}\n\n// Legacy `keyCode` / `which`. Deprecated in the UI Events spec for a decade and still\n// what the arcade/canvas input loops this verb exists for actually read\n// (`switch (e.keyCode)`), so an injected key carrying only `key`/`code` is INVISIBLE to\n// them. Derived here from the key NAME — a bounded table plus the printable-character\n// rule — never taken from the caller, so populating them adds no input surface.\nconst LEGACY_KEY_CODES: Record<string, number> = {\n  Backspace: 8,\n  Tab: 9,\n  Enter: 13,\n  Shift: 16,\n  Control: 17,\n  Alt: 18,\n  Pause: 19,\n  CapsLock: 20,\n  Escape: 27,\n  ' ': 32,\n  PageUp: 33,\n  PageDown: 34,\n  End: 35,\n  Home: 36,\n  ArrowLeft: 37,\n  ArrowUp: 38,\n  ArrowRight: 39,\n  ArrowDown: 40,\n  Insert: 45,\n  Delete: 46,\n  Meta: 91,\n  ContextMenu: 93,\n};\n\nconst legacyKeyCode = (key: string, code: string): number => {\n  const named = LEGACY_KEY_CODES[key];\n  if (named !== undefined) return named;\n  // F1–F24 → 112…135: the one family worth deriving instead of listing.\n  const fn = /^F([1-9]|1\\d|2[0-4])$/.exec(key);\n  if (fn) return 111 + Number(fn[1]);\n  // A single printable character reports its UPPERCASE code unit, which is what a\n  // physical keyboard sends for the letter/digit rows ('a' and 'A' are both 65).\n  if (key.length === 1) return key.toUpperCase().charCodeAt(0);\n  // A named `code` covers a key name that is not a single character (an IME/dead key).\n  const fromCode = /^(?:Key([A-Z])|Digit([0-9]))$/.exec(code);\n  if (fromCode) return (fromCode[1] ?? fromCode[2]).charCodeAt(0);\n  return 0; // unknown — 0 is what a browser reports for a key with no legacy code\n};\n\n/** Dispatch one bounded keyboard event at the focused element (or the body) —\n *  an arcade app's real input surface. `key` is passed through as a name (e.g.\n *  `ArrowLeft`, `a`, ` `); `code` defaults to it, and the deprecated-but-ubiquitous\n *  `keyCode`/`which` are derived from them so a legacy input loop sees the key. */\nfunction dispatchKey(params: Record<string, unknown>): { type: string; key: string; target: string } {\n  if (typeof document === 'undefined') throw new Error('no document in this realm');\n  const type = typeof params.type === 'string' && KEY_TYPES.has(params.type) ? params.type : 'keydown';\n  const key = typeof params.key === 'string' ? params.key.slice(0, 32) : '';\n  if (!key) throw new Error('a key name is required');\n  const code = typeof params.code === 'string' ? params.code.slice(0, 32) : key;\n  const target: EventTarget = document.activeElement ?? document.body;\n  const legacy = legacyKeyCode(key, code);\n  target.dispatchEvent(\n    new KeyboardEvent(type, {\n      bubbles: true,\n      cancelable: true,\n      composed: true,\n      key,\n      code,\n      // Deprecated, and load-bearing: `switch (e.keyCode)` is still how most canvas\n      // games read input. Kept consistent with `key`/`code` above.\n      keyCode: legacy,\n      which: legacy,\n      ctrlKey: flag(params.ctrlKey),\n      shiftKey: flag(params.shiftKey),\n      altKey: flag(params.altKey),\n      metaKey: flag(params.metaKey),\n      repeat: flag(params.repeat),\n    }),\n  );\n  const el = document.activeElement;\n  return { type, key, target: el ? el.tagName.toLowerCase() : 'body' };\n}\n\nlet responderStarted = false;\n\n/** Wire the debug responder: the READ verbs (snapshotDom / computedStyle / rect) and\n *  the two BOUNDED ACTION verbs (dispatchPointer / dispatchKey — one synthetic event\n *  per query, closed type set, clamped coordinates, no caller property bag). Not an\n *  eval bridge: an unrecognised method is refused, never interpreted.\n *\n *  Idempotent; called lazily once the dev gate turns on, and every query re-checks the\n *  gate — so in a production session it answers nothing, action verbs included. No\n *  effect when `window` is absent (non-browser realm). */\nfunction startResponder(): void {\n  if (responderStarted || typeof window === 'undefined') return;\n  responderStarted = true;\n  addListener(DEBUG_QUERY, (msg: { id?: unknown; method?: unknown; params?: unknown }) => {\n    if (!enabledChannel.get()) return; // gate: ignore unless dev-enabled\n    const id = msg.id;\n    const method = msg.method;\n    const params = (msg.params ?? {}) as Record<string, unknown>;\n    let ok = true;\n    let result: unknown = null;\n    let error: string | undefined;\n    try {\n      switch (method) {\n        case 'snapshotDom':\n          result = snapshotDom(params as never);\n          break;\n        case 'computedStyle':\n          result = computedStyle(params as never);\n          break;\n        case 'rect':\n          result = rects(params as never);\n          break;\n        case 'dispatchPointer':\n          result = dispatchPointer(params);\n          break;\n        case 'dispatchKey':\n          result = dispatchKey(params);\n          break;\n        default:\n          ok = false;\n          error = `unknown debug method: ${String(method)}`;\n      }\n    } catch (e) {\n      ok = false;\n      error = e instanceof Error ? e.message : String(e);\n    }\n    try {\n      sendMessage(DEBUG_QUERY_RESULT, { id, ok, result, error });\n    } catch {\n      /* transport gone — nothing to do */\n    }\n  });\n}\n\n// Start the responder as soon as the gate flips on (and not before).\nenabledChannel.onChange((enabled) => {\n  if (enabled) startResponder();\n});\n\n/** The dev-only debug surface. Inert unless the host enables it ({@link isDebugEnabled}). */\nexport const debug = { log, isEnabled: isDebugEnabled } as const;\n"],"mappings":"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","names":[]}