Skip to content
Subako TypeScript SDK
Esc
navigateopen⌘Jpreview
On this page

Skills

Packaging a skill bundle and pushing new versions of it.

A skill is a bundle of knowledge and procedure that an agent can read. You upload it as an archive, and an agent version grants it by id.

The archive

A skill is a gzipped tar of the bundle directory, with SKILL.md at its root.

tar -czf skill.tar.gz -C ./refunds .

The SDK takes the bytes in whatever form you have them:

type SkillArchive = Uint8Array | Blob | ReadableStream<Uint8Array>;

Uploading

import { openAsBlob } from "node:fs";

const skill = await subako.skills.create(await openAsBlob("./skill.tar.gz"));

That creates the skill and its first version. Later versions go to the same skill:

await subako.skills.pushVersion(skill.skill_id, new Uint8Array(archive));

Each push is a new numbered version. Nothing is overwritten.

const versions = await subako.skills.listVersions(skill.skill_id, { limit: 20 });
const all = await subako.skills.list();

await subako.skills.rename(skill.skill_id, { name: "refunds-2026" });
await subako.skills.delete(skill.skill_id);

A stream is not retried

A request whose body is a ReadableStream cannot be read twice, so the SDK does not retry it. If you want the retries, pass a Blob or a Uint8Array instead — the SDK can replay those. See Timeouts and retries.

Granting it to an agent

The upload does not make the skill reachable. An agent version has to name it:

await subako.agents.publishVersion(agentId, {
	model: { format: "anthropic", model: "claude-sonnet-5", max_tokens: 8192 },
	skills: [
		{ name: "refunds", skill_id: skill.skill_id, version: { type: "latest" } },
	],
});

name is the label the model sees the skill under. The two version pins behave differently:

PropType
{ type: "latest" }?VersionPinBody

Resolved when each session is created, child sessions included. A session started after you push version 4 sees version 4; one already running stays where it was.

TypeVersionPinBody
{ type: "pinned", number: 3 }?VersionPinBody

Always that version. Pushing a new one changes nothing until you publish a config that names it.

TypeVersionPinBody

latest is the one that surprises people: it does not update a live session, and it does not need a new agent version either. Pushing a skill version changes what tomorrow’s sessions read.

Was this page helpful?