/** * The skills an agent may load, and where they are looked up. * * A skill is **named in a definition, never inherited from the machine**: * `skills:` is an allowlist exactly like `tools:`, so what an agent can do * stays readable in its own file. Only the *lookup* reaches outside, nearest * first: the skill shipped beside the definition, then the repository's, then * the user's. Whoever is closest to the work wins the name. * * pi does the rest: the system prompt carries a name, a description and a path, * and the model opens `SKILL.md` itself with `read`. That is why a declared * skill the model cannot reach is a configuration error rather than a silence * at runtime: a flow's validation reports it, and spawn throws it. */ import { type Skill } from "@earendil-works/pi-coding-agent"; import type { Agent } from "./agent.ts"; /** Alias to pi's skill type, so a caller names it without importing pi. */ export type { Skill }; /** A directory to search, and the label pi records for what it finds there. */ export type SkillDir = { /** Absolute path of the directory. It legitimately may not exist. */ dir: string; /** Where a skill found here came from: `"agent"`, `"project"` or `"user"`. */ source: string; }; /** * The directories a declared skill is looked up in, **nearest first**. * * The agent's own directory is `/skills/`: `agents/scout.md` keeps * its skills in `agents/scout/skills/`, so a definition and what it needs * travel together and a clone of the repository resolves the same names. An * agent built in memory has no definition file and therefore no own directory. * * The other two are the project's and the user's, and they are the deliberate * hole in "a subagent inherits nothing": a name still has to be written in the * definition, but where it resolves depends on the machine. A skill that must * run anywhere ships beside its agent. */ export declare function skillDirs(agent: Agent, cwd: string): SkillDir[]; /** Every code a {@link SkillProblem} can carry, in the order they are found. */ export declare const SKILL_CODES: readonly ["skills-without-read", "unknown-skill", "skill-hidden"]; /** One reason an agent's `skills:` cannot be handed to it. */ export type SkillProblem = { readonly code: (typeof SKILL_CODES)[number]; readonly message: string; }; /** * What an agent's `skills:` names, looked up nearest first, and every reason * one of them would never reach the model: a toolset without `read` (pi hides * the whole section), a name found nowhere, and a skill whose frontmatter says * `disable-model-invocation` (pi hides that one). * * The one lookup, for the two callers that must agree on it: spawn, which * throws the first problem, and a flow's validation, which reports them all * before anything runs. `skills` is in declaration order and holds what was * found, problems or not. */ export declare function findSkills(agent: Agent, cwd: string, tools: readonly string[]): { skills: Skill[]; problems: SkillProblem[]; }; /** * Resolves what an agent's `skills:` names, in the order it named them. * * Throws rather than dropping one: a missing skill is a typo in a definition, * and finding out through prose that quietly lacks a step costs more than * failing at spawn. A TypeScript workflow has no validation before it runs, so * this is where it finds out; a flow found out before its first spawn. */ export declare function resolveSkills(agent: Agent, cwd: string, tools: readonly string[]): Skill[]; //# sourceMappingURL=skills.d.ts.map