export const UPDATE_NOTICE_TEXT = "NOLAN HAS PUSHED A NEW EZ CODER UPDATE";
/** Copy shown when the automatic pre-final ideal-review hook engages. */
export const IDEAL_HOOK_NOTICE_TEXT = "Hook engaged — running an ideal review before finalizing.";
/** Copy shown when the loop-breaker hook fires because the agent looks stuck. */
export const LOOP_BREAK_NOTICE_TEXT = "Hook engaged — breaking a stuck loop and rethinking the approach.";
/** Copy shown when the post-compaction re-grounding hook re-pins the request. */
export const REGROUNDING_NOTICE_TEXT = "Hook engaged — re-grounding on the original request after compaction.";
/** Theme color key for each hook tone. Shared by every render path (live Ink,
 *  Static scrollback, transcript) so colors stay consistent. */
export const HOOK_TONE_COLOR = {
    review: "secondary",
    warning: "warning",
    info: "primary",
};
/**
 * Tool-activity item kinds whose transcript rendering is REPLACED by the pinned
 * LiveToolPanel. These items still flow through live/history state (so flush,
 * overflow, and persistence logic is unchanged) but render to nothing in the
 * transcript — the panel above the activity bar is now their sole display.
 *
 * Client tools (tool_*) and server tools (server_tool_*, e.g. Anthropic's
 * native web_search) both feed the panel so search/fetch looks identical across
 * providers. Sub-agent groups are intentionally excluded: their multi-line tree
 * carries nested activity the single-row panel can't represent, so they keep
 * their own richer transcript row.
 */
const PANEL_REPLACED_TOOL_KINDS = new Set([
    "tool_start",
    "tool_done",
    "tool_group",
    "server_tool_start",
    "server_tool_done",
]);
/**
 * True when an item's transcript row is replaced by the LiveToolPanel.
 *
 * Image-bearing tool results (read/screenshot) are an exception: the inline
 * image is real content the user asked to see, so those items keep rendering
 * in the transcript. Only the text-only activity rows are suppressed.
 */
export function isPanelReplacedToolItem(item) {
    if (!PANEL_REPLACED_TOOL_KINDS.has(item.kind))
        return false;
    return !(item.imagePreviews && item.imagePreviews.length > 0);
}
/**
 * The last item in a transcript slice that actually renders a row. Panel-replaced
 * tool items (now shown only in the LiveToolPanel) render `null`, so they must be
 * skipped when deriving the "previous item" for spacing decisions — otherwise a
 * tool→assistant boundary inserts a blank separator above an invisible row,
 * leaving a phantom gap above the response.
 */
export function lastVisibleTranscriptItem(items) {
    for (let i = items.length - 1; i >= 0; i--) {
        const item = items[i];
        if (item && !isPanelReplacedToolItem(item))
            return item;
    }
    return undefined;
}
/**
 * True when a transcript item carries one or more inline-image previews.
 *
 * Used to detect images in a transcript region before the bottom-anchor shrink
 * backfill tries to reconstruct it as text. A graphics escape's base64 payload
 * is not recognized as zero-width by `wrapAnsi` (it hard-wraps into literal
 * base64 text) and its visual row count never matches its newline count, so a
 * text-only repaint of an image region desyncs Ink's erase math and displaces
 * the on-screen image. Callers bail out of the text repaint when this is true.
 */
export function itemHasImagePreviews(item) {
    return !!(item.imagePreviews && item.imagePreviews.length > 0);
}
//# sourceMappingURL=app-items.js.map