/**
 * Skill-tool ADAPTERS — the one place the graph's tool DESCRIPTIONS become
 * agentfootprint `Tool`s.
 *
 * `list_skills`, `read_skill` and `skip_step` are described — name, schema,
 * every sentence the model reads — by the pure skill-graph core
 * (`skillToolDescriptors.ts`, `skillSteps.ts`). This module does the last
 * step: hands each descriptor to `defineTool`. That split (9.34.0) is what
 * keeps `read_skill`'s grammar, which is genuinely the graph's — the enum is
 * the catalog, the description is the reachability offer, the result is what
 * the model learns about the skill it activated — out of a module that has to
 * import the framework's tool factory, and therefore out of everything that
 * factory pulls in (artifacts, credentials, check-in, tool sessions).
 *
 * Both tool pairs work over the SAME catalog (a list of `Injection` skills),
 * used by the Agent's auto-attach path AND by `SkillRegistry.toTools()`
 * (explicit composition path). Pulling them out of `core/Agent.ts` removed
 * the v2.4 duplication risk: the Agent auto-attaches its own `read_skill`,
 * the registry builds a sibling — they MUST agree on schema + execute
 * semantics, and now they cannot disagree because neither writes the words.
 *
 * Tool execute is identity-style (returns a confirmation string); the agent's
 * tool-calls subflow inspects the tool name + args and updates
 * `scope.activatedInjectionIds` so the next iteration's InjectionEngine sees
 * the new activation.
 *
 * Zone: HOST. Importing `tools/tools.js` here is the point of the file.
 */
import type { Tool } from '../tools/tools.js';
import { type ReadSkillOffer } from './skillToolDescriptors.js';
import type { Injection } from './types.js';
export type { ReadSkillOffer } from './skillToolDescriptors.js';
/**
 * Build the `list_skills` tool — a no-arg tool that returns the
 * registered skills as `{ id, description }[]`. Lets the LLM discover
 * skills without paying the prompt-token cost of embedding the
 * catalog into every system prompt.
 *
 * Pairs with `read_skill` (which actually activates a skill by id).
 *
 * Returns `undefined` when there are no skills — callers should
 * guard or filter undefined out of their tool list.
 */
export declare function buildListSkillsTool(skills: readonly Injection[]): Tool | undefined;
/**
 * Build the `read_skill` tool — activates a skill for the next
 * iteration. The LLM picks WHICH skill via the `id` argument.
 *
 * Tool execute() returns a confirmation string. The actual bookkeeping
 * (appending the requested skill id to `scope.activatedInjectionIds`)
 * is handled by the Agent's tool-calls subflow, which inspects every
 * `read_skill` tool call by name. The next iteration's InjectionEngine
 * matches Skills with `trigger.kind: 'llm-activated'` by id and
 * includes them in the active set; slot subflows then inject the body
 * + tools.
 *
 * The tool's description lists each Skill's `id` + `description` so
 * the LLM can choose meaningfully without first calling `list_skills`
 * (a perf trade-off — small registries can afford the inline catalog;
 * large ones should use `list_skills` for discovery and rely on the
 * shorter `read_skill` description.) See `surfaceMode` (Block A4) for
 * tunable trade-offs.
 *
 * Returns `undefined` when there are no skills — callers should
 * guard or filter undefined out of their tool list.
 *
 * Pass `offer` to scope the DESCRIPTION to what the graph's gate will actually
 * grant from the current cursor (8.5.0); the enum stays the full catalog either
 * way. Omit it and the tool is byte-identical to what it has always been.
 */
export declare function buildReadSkillTool(skills: readonly Injection[], offer?: ReadSkillOffer): Tool | undefined;
/**
 * Build the `skip_step` tool. Auto-attached to the dispatch registry when
 * ≥1 registered skill declares steps (the `read_skill` auto-attach seam) —
 * always dispatchable, but OFFERED (schema in the request) only while a
 * stepped tenure is active and unfinished. Its execute returns a
 * placeholder; the tool-calls stage overwrites the model-visible result
 * with the authoritative sentence, exactly as the skill-graph gate
 * overwrites `read_skill` refusals — bookkeeping lives where the batch
 * order lives.
 *
 * Lived in `skillSteps.ts` through 9.33.x; moved here in 9.34.0 so that
 * module — the procedure GRAMMAR — stops importing the tool factory. The
 * sentences it speaks are still `skillSteps.ts`'s
 * ({@link skipStepDescriptor}); only the wrapping moved.
 */
export declare function buildSkipStepTool(): Tool;
/**
 * The pair returned by `SkillRegistry.toTools()`. Either entry may be
 * undefined when the registry is empty. Consumers typically destructure:
 *
 *   const { listSkills, readSkill } = registry.toTools();
 *   const tools = [listSkills, readSkill, ...other].filter(Boolean) as Tool[];
 */
export interface SkillToolPair {
    /** The `list_skills` tool, or `undefined` if registry is empty. */
    readonly listSkills: Tool | undefined;
    /** The `read_skill` tool, or `undefined` if registry is empty. */
    readonly readSkill: Tool | undefined;
}
