/**
 * Pure index-filtering + prompt-index formatting helpers.
 *
 * Matching semantics are ported from curator's battle-tested
 * `searchSkillsFromIndex`: case-insensitive substring match on
 * name/displayName/description, optional tag filter on top, scope filter
 * that always admits global skills, and active-only visibility.
 */
import type { SkillDefinition, SkillIndexItem, SkillSearchQuery } from "../types/index.js";
/** Strip instructions from a full definition to form an index entry. */
export declare function toSkillIndexItem(skill: SkillDefinition): SkillIndexItem;
/**
 * Sort index entries by name (byte order, locale-independent) so every
 * listing renders byte-identically across calls and store backends.
 * Store enumeration order (Redis SCAN, fs.readdir, S3 listings) is not
 * stable — an unsorted listing would shuffle between calls and invalidate
 * provider prompt caches. Returns a new array.
 */
export declare function sortSkillIndex(items: SkillIndexItem[]): SkillIndexItem[];
/** Filter index entries by query/tag/scope. Active skills only. */
export declare function filterSkillIndex(items: SkillIndexItem[], query: SkillSearchQuery): SkillIndexItem[];
/**
 * Reject resource paths that could escape a skill's namespace: absolute
 * paths, traversal segments, and empty segments. The manager validates
 * before reaching any store — this is defense in depth for stores whose
 * keys are built by concatenation (S3, Redis) or path joining.
 */
export declare function isSafeSkillResourcePath(resourcePath: string): boolean;
/**
 * Whether a skill is visible from the calling scope. Fails closed, matching
 * `filterSkillIndex`: a scoped skill is hidden unless the caller supplies a
 * `scopeId` that the skill explicitly lists. Omitting `scopeId` therefore
 * yields global skills only — it must never expose a scoped skill by name
 * through `use_skill` / `read_skill_resource` (#1139).
 */
export declare function isSkillVisibleInScope(skill: Pick<SkillDefinition, "scope" | "scopeIds">, scopeId?: string): boolean;
/**
 * Render the `<available_skills>` block embedded in the use_skill tool
 * description ("tool" discovery mode). One line per skill — name,
 * description, tags — instructions never appear here.
 *
 * Budget handling is uniform and stateless: over budget, every
 * description drops to its first sentence, then to a hard 80-char cap.
 * The render is a pure function of the (sorted) index, so the tool
 * description stays byte-identical across calls — a prerequisite for
 * provider prompt caching. Names are never dropped.
 */
export declare function renderSkillListing(items: SkillIndexItem[], budgetChars: number): string | null;
/**
 * Render the compact skills index appended to the system prompt
 * ("system-prompt" discovery mode). Names + descriptions only —
 * instructions are never included; the model loads them via use_skill.
 * Returns null when nothing is visible so callers can skip injection.
 */
export declare function formatSkillsPromptIndex(items: SkillIndexItem[], maxItems: number): string | null;
