agents
Version:
A home for your AI agents
222 lines (221 loc) • 7.63 kB
TypeScript
//#region src/skills/result.d.ts
/**
* The outcome of a skills operation that can fail in an expected way.
*
* Skill parsing and source I/O return failures as values instead of throwing,
* so a broken `SKILL.md` or an unreachable bucket never takes down the agent.
*
* @template T - The success value.
* @template E - The expected error.
*/
type SkillResult<T, E extends Error> =
| {
readonly ok: true;
readonly value: T;
}
| {
readonly ok: false;
readonly error: E;
};
//#endregion
//#region src/skills/resource.d.ts
declare const skillResourcePathBrand: unique symbol;
/**
* A normalized path to a file inside a skill directory, relative to the
* skill root (for example `references/style-guide.md`). Construct one with
* {@link parseSkillResourcePath}.
*/
type SkillResourcePath = string & {
readonly [skillResourcePathBrand]: true;
};
/**
* What a skill file is for, from the spec's directory conventions:
* `scripts/`, `references/`, and `assets/`. Anything else is a `file`.
*/
type SkillResourceKind = "script" | "reference" | "asset" | "file";
/** A file bundled with a skill, without its content. */
interface SkillResourceInfo {
/** Path relative to the skill directory. */
readonly path: SkillResourcePath;
/** Role inferred from the top-level directory. */
readonly kind: SkillResourceKind;
/** How {@link SkillResource.content} is encoded. */
readonly encoding: "text" | "base64";
/** MIME type, when the extension maps to a known one. */
readonly mimeType?: string;
/** Size in bytes, when the source knows it without reading the file. */
readonly size?: number;
}
/** A file bundled with a skill, with its content. */
interface SkillResource extends SkillResourceInfo {
/** UTF-8 text, or base64 for binary files. */
readonly content: string;
}
/** A resource path that is absolute, escapes the skill, or is malformed. */
declare class InvalidSkillResourcePathError extends Error {
readonly path: string;
/** Stable tag for narrowing. */
readonly _tag: "InvalidSkillResourcePathError";
/** @param path - The rejected path. */
constructor(path: string);
}
/**
* Parse a path to a file inside a skill directory.
*
* @param path - Candidate path relative to the skill root.
* @returns The branded path, or `InvalidSkillResourcePathError` when it is
* empty, absolute, contains `.`/`..`/empty segments or NUL, or names
* `SKILL.md` itself.
*/
declare function parseSkillResourcePath(
path: string
): SkillResult<SkillResourcePath, InvalidSkillResourcePathError>;
//#endregion
//#region src/skills/skill.d.ts
/**
* The Agent Skills `Skill` type and its frontmatter rules. `SKILL.md`
* text parsing lives in `./markdown` so code that only handles parsed
* skills does not load the YAML parser.
*
* The rules come from https://agentskills.io/specification, applied the way
* the spec's guide for agents recommends
* (https://agentskills.io/client-implementation/adding-skills-support):
* a skill that breaks a rule still loads, and each broken rule is returned
* as a warning. Only a skill that cannot be used is rejected: no
* description, no usable name, or frontmatter that is not YAML.
*
* A skill that follows the spec parses with no warnings, so authoring tools
* check `warnings.length === 0` before storing a skill.
*
* Frontmatter keys the spec does not define are kept in
* {@link Skill.extraFields}.
*
* @module
*/
declare const skillNameBrand: unique symbol;
/**
* A skill name the parser accepted. It is always a single safe path segment
* (no `/`, `\`, NUL, or control characters, and not `.` or `..`), so it can
* name a directory, a tool enum value, and a qualified resource path. A name
* from {@link parseSkillName}, or from a parse with no warnings, also follows
* the spec format.
*/
type SkillName = string & {
readonly [skillNameBrand]: true;
};
/** Why a `SKILL.md` or skill field broke a rule. */
type SkillParseErrorCode =
| "missing-frontmatter"
| "invalid-yaml"
| "invalid-frontmatter"
| "invalid-name"
| "name-mismatch"
| "invalid-description"
| "invalid-license"
| "invalid-compatibility"
| "invalid-metadata"
| "invalid-allowed-tools";
/**
* A `SKILL.md` that breaks an Agent Skills rule. Returned as the error of a
* failed parse, or as a warning when the skill loads anyway.
*/
declare class SkillParseError extends Error {
readonly code: SkillParseErrorCode;
/** Stable tag for narrowing. */
readonly _tag: "SkillParseError";
/**
* @param code - Which rule the skill broke.
* @param message - Human-readable explanation, safe to show to a model.
* @param options - The underlying cause, such as a YAML syntax error.
*/
constructor(
code: SkillParseErrorCode,
message: string,
options?: {
cause?: unknown;
}
);
}
/** A parsed Agent Skill: its frontmatter and Markdown instructions. */
interface Skill {
/** The skill's name. */
readonly name: SkillName;
/** What the skill does and when to use it. */
readonly description: string;
/** License name or a reference to a bundled license file. */
readonly license?: string;
/** Environment requirements. */
readonly compatibility?: string;
/** String key-value metadata. Empty when the skill declares none. */
readonly metadata: Readonly<Record<string, string>>;
/** Pre-approved tools from `allowed-tools`. Experimental in the spec. */
readonly allowedTools: readonly string[];
/** Frontmatter keys the spec does not define, kept verbatim. */
readonly extraFields: Readonly<Record<string, unknown>>;
/** Markdown instructions after the frontmatter. */
readonly body: string;
}
/** Options for {@link parseSkill}. */
interface ParseSkillOptions {
/**
* Name of the directory that holds this `SKILL.md`. The spec requires the
* skill's `name` to match it; a mismatch is a warning. A missing `name`
* falls back to the directory, with a warning.
*/
readonly directory?: string;
}
/** The outcome of parsing a skill. */
type SkillParseResult =
| {
readonly ok: true /** The parsed skill. */;
readonly value: Skill;
/**
* Spec rules the skill breaks but was loaded anyway. Empty for a
* skill that follows the spec.
*/
readonly warnings: readonly SkillParseError[];
}
| {
readonly ok: false;
readonly error: SkillParseError;
};
/**
* Parse a skill name against the Agent Skills spec.
*
* The name is NFKC-normalized first. It must be 1-64 characters of
* lowercase letters, digits, and hyphens, must not start or end with a
* hyphen, and must not contain `--`.
*
* @param input - The candidate name.
* @returns The branded name, or `SkillParseError` with code `invalid-name`.
*/
declare function parseSkillName(
input: string
): SkillResult<SkillName, SkillParseError>;
/**
* Whether a model may activate this skill on its own. Skills opt out with
* `disable-model-invocation: true`, as a top-level field or in `metadata`.
*
* @param skill - The parsed skill.
* @returns `false` when the skill disables model invocation.
*/
declare function isModelInvocable(skill: Skill): boolean;
//#endregion
export {
SkillParseErrorCode as a,
parseSkillName as c,
SkillResourceInfo as d,
SkillResourceKind as f,
SkillResult as h,
SkillParseError as i,
InvalidSkillResourcePathError as l,
parseSkillResourcePath as m,
Skill as n,
SkillParseResult as o,
SkillResourcePath as p,
SkillName as r,
isModelInvocable as s,
ParseSkillOptions as t,
SkillResource as u
};
//# sourceMappingURL=skill-DRBcIBjC.d.ts.map