skill()
Proposed helper for adding procedural skill directories to a harness.
Little Harness: published on npm as little-harness@0.2.0-alpha.0 (2026-10-05). Sections labeled UNRELEASED describe source-only changes. Release status
skill() registers procedural knowledge with Little Harness. Use it when the agent needs instructions, examples, or domain playbooks that should not live in every system prompt.
Import
import { createHarness, localHost, skill } from "@little-stack/harness";API Signature
function skill(input: string, options?: RemoteSkillOptions): SkillInput;
function skill(input: SkillInput): SkillInput;
type SkillInput = string | RemoteSkillInput | LocalSkillInput;
type RemoteSkillInput = {
source: string;
} & RemoteSkillOptions;
type LocalSkillInput = {
path?: string;
name?: string;
description?: string;
harnessDir?: string;
files?: Record<string, string | Uint8Array>;
};
type RemoteSkillOptions = {
skills?: readonly string[];
skillMaxRisk?: SkillRiskLevel;
skillRisk?: Record<string, SkillRiskLevel>;
auth?: SkillGitAuth;
};
type SkillRiskLevel = "NONE" | "LOW" | "MEDIUM" | "HIGH" | "CRITICAL";
type SkillGitAuth = {
type: "bearer";
token: string | undefined;
};Parameters
The skill source to register.
Local directory sources must contain SKILL.md. Single-file local sources are treated as the SKILL.md body. Remote sources must be explicit Git URLs; shorthands such as org/repo, github:org/repo, and gitlab:org/repo are rejected.
Explicit remote Git URL. GitHub URLs, GitLab tree URLs, generic HTTPS Git URLs, SSH URLs, and scp-style Git URLs are supported.
Selected remote skill names for this source. If omitted, every non-internal skill in the repository is installed.
Maximum accepted risk for all selected skills from this source.
Per-skill maximum risk overrides for selected remote skills from this source.
Explicit Git authentication for this source. Only bearer tokens are supported.
Path to a local skill directory or single markdown file.
Overrides the name parsed from SKILL.md frontmatter.
Overrides the description parsed from SKILL.md frontmatter.
Overrides the visible directory shown to the model. Defaults to .agents/skills/<name>.
Inline skill files keyed by relative path. Inline skills must include name and description.
Remote Git options used when input is a string URL.
Selected remote skill names, matching repeated --skill usage in the Skills CLI. If omitted, every non-internal skill in the repository is installed.
Maximum accepted risk for all selected skills from this source.
Per-skill maximum risk overrides for selected remote skills.
Explicit Git authentication. Only bearer tokens are supported.
Returns
SkillInput
A lazy skill reference. Little Harness resolves the reference when a session starts, injects compact skill metadata into the prompt, and stages the full skill files read-only under .agents/skills/<name>/.
Example
import { createHarness, skill } from "@little-stack/harness";
const harness = createHarness({
host: localHost(),
model,
system: "Help account teams prepare high-signal customer work.",
tools: { searchDocs, queryCustomers },
skills: [
skill("./skills/customer-briefs"),
skill("https://github.com/anthropics/skills", {
skills: ["frontend-design"],
}),
],
});The helper should make a skill visible in two ways:
- a compact name and description can be disclosed to the model up front
- the full skill directory can be staged read-only under
.agents/skills/<name>/
Directory Input
The simplest input is a local directory containing SKILL.md.
skill("./skills/customer-briefs")Little Harness should read SKILL.md, parse its frontmatter, and expose the rest of the directory as supporting files.
---
name: customer-briefs
description: Use when preparing renewal, expansion, or risk briefs.
---
Before writing the brief, inspect support incidents, product usage,
contract dates, and open account notes.Remote Git Input
Remote skills must use explicit Git URLs:
skill("https://github.com/anthropics/skills", {
skills: ["frontend-design"],
});
skill("https://gitlab.com/acme/agent-skills/-/tree/main", {
skills: ["customer-research"],
});
skill("git@github.com:acme/private-skills.git", {
skills: ["deal-review"],
auth: { type: "bearer", token: process.env.GIT_TOKEN },
});The skills option selects skill names from the repository, matching npx skills add URL --skill frontend-design. If skills is omitted, Little Harness installs every non-internal skill in the source. GitHub URLs, GitLab tree URLs, generic HTTPS Git URLs, SSH URLs, and scp-style Git URLs are supported. Shorthands such as org/repo, github:org/repo, and gitlab:org/repo are rejected.
Remote skills are materialized in the runtime before the session starts. The cache is keyed by resolved commit SHA. To use a specific version, include a commit SHA or ref in the Git URL/source options.
Remote Git skill loading is best-effort at runtime. If a repository cannot be fetched, a selected skill cannot be discovered, or a remote risk audit fails, Little Harness continues without that remote skill and returns a warning. Local skill path and metadata errors remain strict.
Private Git sources can pass explicit auth with auth: { type: "bearer", token: process.env.GIT_TOKEN }. As a host-level fallback, set LITTLE_SKILLS_GIT_TOKEN and restrict where it is sent with LITTLE_SKILLS_GIT_TOKEN_HOSTS.
Risk gates are optional. If your deployment configures one, set skillOidcToken: process.env.VERCEL_OIDC_TOKEN so the runtime can call the Skills API. skillMaxRisk can be set globally, on a harness or role config, or on a specific skill(...) source. For selected remote skills, skillRisk can assign per-skill policy inside that skill(...) call.
Object Input
Use object input when the app wants to override metadata or control the harness directory.
skill({
path: "./skills/customer-briefs",
name: "customer-briefs",
description: "Use when preparing renewal, expansion, or risk briefs.",
});path points to the developer's skill directory. name and description
override SKILL.md metadata when provided. Materialized skills are exposed at
.agents/skills/<name>/ from the harness working directory.
Inline Input
Some apps may generate skills from a CMS, database, or package registry. For that case, a future-compatible inline shape could provide files directly.
skill({
name: "support-triage",
description: "Use when classifying support conversations.",
files: {
"SKILL.md": "# Support Triage\nClassify by urgency and customer impact.",
"examples/p1.md": "A P1 issue blocks production usage.",
},
});Inline skills should follow the same rules as directory skills: short metadata in context, full files exposed read-only.
Resolution Rules
The alpha behavior:
- Resolve local skill paths in the host app; materialize remote Git skill sources in the runtime before the session starts.
- Require a
SKILL.mdentry file for materialized skill directories. - Parse
nameanddescriptionfrom frontmatter unless the caller overrides them. - Materialize local and remote skill files read-only under
.agents/skills/<name>/. - Include prompt-visible skill metadata in the initial prompt; agents load the full body on demand with
cat .agents/skills/<name>/SKILL.md.
This keeps the first prompt compact while letting the agent inspect detailed procedures only when they matter.
What Skills Are Not
Skills are not tools. They do not execute code or grant capabilities by themselves.
Skills are not memory. Do not put user-specific files, secrets, or raw customer data in a skill. Use Persistent Dirs or app tools for data that changes by user, team, or account.
Skills are not exports. If the agent needs to save a report, update a ticket, or write to a product database, expose an explicit tool for that action.