/**
 * Lib-side portable subset of the hub's `lib/utils/slash-dispatch-utils.ts`.
 *
 * The full hub file owns the SERVER-SIDE parser/dispatcher (depends on
 * `slash-commands-config`, `slash-commands-static`, `doc-source-config-utils`,
 * `chat-admin-types`, `rag-table-config`) which stays hub-side.
 *
 * What MIGRATES here is the wire contract + the small text helpers consumed
 * by chat surfaces in the lib + the hub UI:
 *   - `WireCommandOverride`        — wire-shape (chat request body)
 *   - `parseWireCommandOverride`   — wire validator
 *   - `CommandOverride`            — server-built dispatch result type
 *     (presentation typed as `string` here; the hub narrows via its own
 *     `SlashCommandPresentation` union)
 *   - `extractEntityIdFilter`      — `CommandOverride` → narrowed filter
 *   - `sanitizeTitleForChat`       — collapse control chars in titles
 *   - `formatSingularLookupInvocation` — `/cmd "value"` builder
 *   - `buildDiscussAddendum`       — server-side Discuss addendum prose
 *
 * Validation constants (regex + length caps) are duplicated here verbatim
 * to keep the lib's wire validator self-contained.
 */
/** Wire-supplied `CommandOverride` — the subset of fields a client (chat
 *  shell) is allowed to send on the request body. Excludes
 *  `systemPromptAddendum` by construction: addendum injection is a
 *  Rule-5b bypass vector, so we never accept it from the wire. */
export interface WireCommandOverride {
    entityIdFilter?: {
        tableId: string;
        id: string;
    };
    retrievalQueryOverride?: string;
}
/**
 * Parse + validate a wire-supplied `commandOverride` from the chat
 * request body. Returns the validated subset OR `null` if the input is
 * missing / malformed in every field.
 */
export declare function parseWireCommandOverride(raw: unknown): WireCommandOverride | null;
/**
 * Sanitize a free-text title for use inside a chat-visible string:
 * collapse control chars (\r \n \t) to single spaces and trim. Defends
 * against a row title containing embedded newlines (which would split
 * the rendered prompt across visible lines + survive into ILIKE in a
 * confusing way) and tab/CR artifacts from sloppy imports.
 */
export declare function sanitizeTitleForChat(value: string | null | undefined): string;
/**
 * Compose a singular-lookup slash invocation as the user-visible chat
 * message: `/<cmd> "<value>"` (or `/<cmd>` when value is empty).
 *
 * SINGLE SOURCE OF TRUTH for the quoting convention `parseSlashCommand`
 * consumes: outer `"`-pair triggers `singularLookup`; unquoted args run
 * FTS; empty args browse. Internal `"` chars are backslash-escaped so
 * the visible string is paste-able / re-runnable.
 */
export declare function formatSingularLookupInvocation(cmdId: string, value?: string | null): string;
/** Command-override structure passed to `buildChatContext.opts.commandOverride`. */
export interface CommandOverride {
    retrievalScope?: string[];
    systemPromptAddendum?: string;
    retrievalQueryOverride?: string | null;
    /** Singular-item lookup. When set, retrieval bypasses FTS and queries the
     *  named table directly via ILIKE on the matchFields. */
    entityLookup?: {
        tableId: string;
        value: string;
        matchFields: string[];
    };
    /** Singular row by primary key. Used by the inline object-card
     *  "Discuss" action — the client knows the exact row id from a prior
     *  chip. Higher precedence than `entityLookup` (route enforces) and
     *  `retrievalQueryOverride`. The retrieval layer still runs the table's
     *  `searchFilter` so privacy invariants hold. */
    entityIdFilter?: {
        tableId: string;
        id: string;
    };
    /** "Browse" bypass for bare slash list commands. The search layer
     *  treats this as "skip FTS — return rows from these tableIds ordered
     *  by the configured `primaryDateColumn` DESC". */
    browseScope?: string[];
    /** Presentation hint propagated from the slash command. Hub narrows to
     *  its `SlashCommandPresentation` union; lib leaves as `string` for
     *  decoupling. */
    presentation?: string;
}
/**
 * Resolve the wire `entityIdFilter` from a `CommandOverride`, optionally
 * narrowed to a specific `tableId`. Returns the validated `{ tableId, id }`
 * pair only when both fields are present, non-empty, and (when an expected
 * tableId is passed) match. Returns `null` otherwise.
 */
export declare function extractEntityIdFilter(override: CommandOverride | null | undefined, expectedTableId?: string): {
    tableId: string;
    id: string;
} | null;
/**
 * Server-only synthesizer for the Discuss-action system-prompt addendum.
 * Called by the chat route AFTER `parseWireCommandOverride` accepts an
 * `entityIdFilter` — the addendum text is composed from server-trusted
 * values (the row's tableId + id) so a malicious client can't inject
 * arbitrary prompt content.
 */
export declare function buildDiscussAddendum(args: {
    tableId: string;
    id: string;
}): string;
//# sourceMappingURL=slash-dispatch-utils.d.ts.map