import type { StxOptions } from './types';
/**
 * Detect an app shell file in the given directory.
 *
 * @deprecated Use `layouts/default.stx` instead. The framework now auto-generates
 * the document shell from `stx.config.ts` `app.head` configuration.
 * The app.stx shell pattern is kept for backwards compatibility.
 *
 * Checks for `app.stx` in the project root (or configured shell path).
 * Returns the absolute path if found, null otherwise.
 */
export declare function detectShell(appDir: string, shellConfig?: string | false): string | null;
/**
 * Process the app shell template and split it at the `<slot />` injection point.
 *
 * The shell is processed through `processDirectives()` with a placeholder
 * for the slot, then split into before/after parts for fast page composition.
 */
export declare function processShell(shellPath: string, options: StxOptions): Promise<ProcessedShell | null>;
/**
 * Compose a full page by injecting page content into the processed shell.
 *
 * Wraps the page content in a document structure with the shell's layout,
 * shell scripts, shell styles, and the router.
 */
export declare function composeShellWithPage(shell: ProcessedShell, pageContent: string, pageTitle?: string): string;
/**
 * Strip document wrapper (DOCTYPE, html, head, body) from page content,
 * returning just the body content as a fragment.
 *
 * If the content has no document wrapper, it's returned as-is.
 *
 * Preserves:
 * - `<script>` tags from `<body>` (page scripts)
 * - `<style>` tags from `<head>` (page styles, moved to fragment)
 * - Body content
 *
 * Strips:
 * - `<!DOCTYPE>`, `<html>`, `<head>`, `<body>` wrappers
 * - `<meta>`, `<title>`, `<link>` tags from `<head>`
 */
export declare function stripDocumentWrapper(html: string): string;
/**
 * Check if a request is an SPA navigation request (from the stx router).
 */
export declare function isSpaNavigation(request: Request): boolean;
/**
 * Extract the inner content of the router container element from a full HTML
 * document, preserving any `<style>` tags found in `<head>`.
 *
 * This is what fragment files should contain — NOT the whole body. The SPA
 * router injects fragments directly into the container element via innerHTML,
 * so the fragment must already match the shape of the container's content.
 * If you pass it the whole body (nav + main + footer), the router will dump
 * all of that inside `<main>`, producing a duplicated nav.
 *
 * Falls back to `stripDocumentWrapper` if the container cannot be located.
 *
 * @param html - Full HTML document (with or without doctype/html/head/body)
 * @param containerSelector - Tag name or selector for the router container (e.g. `main`)
 */
export declare function extractContainerContent(html: string, containerSelector?: string): string;
/**
 * Processed shell ready for page injection
 */
export declare interface ProcessedShell {
  beforeSlot: string
  afterSlot: string
  filePath: string
  shellScripts: string[]
  shellStyles: string[]
}
