skit
skit (Session Kit) is a vendor-neutral format and package manager for session kits: it defines the profiles, prompts, permission packs, state, hooks and CLI tools an AI agent session needs for a role, and installs and distributes them as one kit. Adapters apply kits to each agent, so any vendor can use them by providing an adapter; IST is one such adapter, connecting kits to Claude Code, Codex, Cursor and more.
As a user
You don't need to learn most of this page. In IST you work by talking to your AI sessions, and the AI runs most skit commands for you.
What you type yourself is usually just one command, to add a kit:
skit install @marnex/tutorial-kit --source proxy
Occasionally you may also check or remove what you installed with skit list and skit uninstall <kit>.
What the AI runs for you. Profiles tell the AI which prompts to read, so a session runs commands like skit prompt show <name> on its own when it starts or when it needs instructions. You don't type these.
Making your own kit or prompt. You don't need to write skit.json by hand either. Ask an AI session in plain language, for example:
- "Make a prompt called
conventionsthat tells my worker sessions to run the tests before every commit." - "Package my reviewer profile and its prompts as a skit kit."
The AI can use the reference below to do it.
Reference (for kit authors and AI sessions)
The rest of this page is the precise reference for skit commands and the skit.json format. It is what an AI session (or a kit author) relies on.
A skit (session kit) bundles everything an AI session needs for one role or workflow and installs it in one step:
| What a kit can ship | skit.json key | What it becomes |
|---|---|---|
| System prompts | components.profiles | Session profiles (persona, instructions, allowed tools) used by isesh start -p <profile> |
| Prompts | components.prompts | On-demand instructions a session reads with skit prompt show <name> |
| CLI tools | dependencies.npm / components.clis | Global commands the prompts tell the AI to run (e.g. itda, imessenger) |
| Hooks | components.hooks | chook / dhook / phook hook files |
| State | components.states | Initial profile state directories |
| Permission packs | components.packs | Named allowedTools sets merged into ~/.sesh/permission-packs.json |
skit install downloads the kit, installs its CLI dependencies, copies each component to its install location, and records the profile, prompt and state files it wrote so skit uninstall can remove them cleanly.
This page describes the skit version pinned by the IST beta release shown in the banner above (snapshot current lists what you have installed). Newer skit releases change some behavior, notably browse and --source. For why kits are versioned and how a running session picks up a kit update, see Versioned Prompts, What Changes on an Upgrade and When Sessions Load Prompts.
Commands
| Command | Purpose |
|---|---|
install | Install a kit |
uninstall | Remove an installed kit |
list | List installed kits |
prompt list / prompt show | Browse and read installed prompts |
orphans | Find prompt/profile files no kit manages |
browse | List kits published in a GitLab group |
info | Show the kit in the current directory |
pack | Build a .tgz from the current directory |
publish | Publish the current kit to GitLab |
gitignore | Add skit defaults to .gitignore |
install
Install a skit package (alias: skit i).
skit install <package> [options]
Arguments:
<package>- A scoped kit name (@scope/name, optionally@scope/[email protected]), a local kit directory, or a local.tgzfile
Options:
-v, --verbose- Show detailed output (every installed file)--dry-run- Show what would be installed without installing--group <name>- GitLab group override for the token fallback (normally auto-resolved)--source <source>-gitlaborproxy; passed to the token fallback (see below)
Where the kit is downloaded from. skit first fetches the kit from the IST registry proxy. Public kits download anonymously, with no GitLab account or token. Only if the proxy refuses the request (a private kit you are not entitled to) does skit fall back to glpkg install --generic with your own GitLab token; --group and --source only affect that fallback. If both fail, the install fails.
Examples:
# Install the TDA kit
skit install @ist/tda-kit
# Install a public kit (no GitLab setup needed)
skit install @marnex/tutorial-kit --source proxy
# Install from a local directory while developing a kit
skit install ./my-kit --verbose
Re-installing a kit (for example, a newer version) first removes the files recorded for its previous installation, then copies the new ones. Files you added yourself next to them are left alone.
uninstall
Remove an installed kit and the files recorded for it (alias: skit rm). Profile permission overlays the kit applied are reverted.
Hook directories (components.hooks) are not recorded, so uninstall leaves them in ~/.chook/hooks/, ~/.dhook/hooks/ or ~/.phook/hooks/; remove them by hand if needed. CLIs installed from dependencies.npm also stay installed.
skit uninstall <package> [options]
Options:
-v, --verbose- Show detailed output--dry-run- Show what would be removed without removing
list
List installed kits with their version and file count (alias: skit ls).
skit list [options]
Options:
--json- Output as JSON
Installed kits are recorded in ~/.ist/installed-kits.json.
prompt
Kit-aware prompt management. Prompts are grouped by the kit that installed them.
skit prompt list [options] # alias: skit prompt ls
skit prompt show <name> [options]
prompt list options:
--json- Output as JSON-p, --profile <name>- Show prompts scoped to a specific profile-a, --all- Show all scopes (global and every profile), plus unmanaged prompt files
prompt show options:
-p, --profile <name>- Read from a profile's scope instead of the global scope--raw- Print the content only, without the kit header
Scope rules. Every prompt lives in exactly one scope:
| Scope | Directory | Read with |
|---|---|---|
| global | ~/.ist/prompts/global/ | skit prompt show <name> |
| profile | ~/.ist/prompts/profiles/<profile>/ | skit prompt show <name> --profile <profile> |
How skit prompt show <name> resolves a prompt:
- With
--profile <profile>, it looks only in that profile's scope. It does not fall back to global. - Without
--profile, it prefers the global prompt. If no global prompt of that name exists, it may return a profile-scoped prompt that a kit installed under the same name.
So to let a profile-specific prompt override a shared one, try the profile scope first, then global:
skit prompt show conventions --profile tda-worker 2>/dev/null \
|| skit prompt show conventions
When a prompt is not found, skit prompt show prints Prompt not found: <name> and exits with a non-zero code. The # from <kit> header goes to stderr, so stdout carries only the prompt content.
skit prompt show reads the file from disk each time it runs, so it always returns what is currently installed (see When Sessions Load Prompts).
orphans
Find prompt and profile files under ~/.ist/prompts/ and ~/.ist/profiles/ that no installed kit manages (for example, files left behind by hand edits or old installs).
Prompts you write yourself, such as a conventions prompt, are also reported as orphans because no kit owns them. Review the list before using --clean.
skit orphans [options]
Options:
--json- Output as JSON--clean- Delete all orphaned files (asks for confirmation)--force- Skip the confirmation (use with--clean)-i, --interactive- Choose which files to delete--dry-run- Show what would be deleted without deleting
browse
List the kits published for a scope (latest version of each).
skit browse <org> [options]
Arguments:
<org>- The scope, with or without@(e.g.@ist)
Options:
--json- Output as JSON
browse reads the GitLab group mapped to the scope and lists its packages through the GitLab API, so it needs a scope mapping and a GitLab token from gitlab-config. Without them it prints an error. You do not need browse to install a public kit whose name you already know.
info
Show the manifest of the kit in the current directory (name, version, components).
skit info [options]
Options:
--json- Print the parsedskit.jsonas JSON
pack
Pack the current directory into a .tgz kit, using the files / exclude globs in skit.json.
skit pack [options]
Options:
-o, --output <dir>- Output directory (default:.)--dry-run- List the files that would be included without creating the archive
pack fails if the kit ships prompts and install.prompts is missing or not a valid prompt scope (see Prompt install path rules).
publish
Publish the kit in the current directory to the GitLab package registry (alias: skit p).
skit publish [options]
Options:
--bump <type>- Bump the version first (patch,minor,major)--dry-run- Test the publish without publishing-v, --verbose- Show detailed output
gitignore
Create a .gitignore with skit defaults (*.tgz, node_modules/), or append the missing entries to an existing one.
skit gitignore [options]
Options:
-f, --force- Overwrite an existing.gitignoreinstead of appending
skit.json Reference
Every kit has a skit.json manifest at its root.
Top-level fields
| Field | Required | Description |
|---|---|---|
name | Yes | Scoped package name, @scope/kit-name |
version | Yes | Semver version, e.g. 0.1.0 |
type | Yes | Always "skit" |
description | No | One-line summary |
components | Yes | What the kit ships, grouped by type (see Components) |
install | Yes | Where file components install, plus optional scripts (see install) |
files | No | Globs of files to include when packing. Defaults to **/*; skit.json is always included |
exclude | No | Globs of files to leave out when packing |
dependencies.npm | No | npm packages to install globally before the components, usually the CLIs your prompts use. Value is a version string, or { "version": "...", "source": "npm" | "proxy" } to pick the registry. The default is proxy (the IST registry proxy, anonymous); npm installs from public npmjs |
dependencies.skit | No | Other kits to install first: { "@scope/kit": "<version>" | "latest" }. Installed recursively |
registry | No | Maps npm scopes used in dependencies.npm to their GitLab group: { "@scope": { "group": "<group>", "url": "<optional registry URL>" } } |
profilePermissions | No | Adds allowedTools entries to profiles, including profiles from other kits: { "<profile>": ["Bash(mytool:*)"] }. Reverted on uninstall |
glpkg | No | Managed by the publishing tooling (groups, policy). Don't edit by hand |
pricing, runtime | No | Informational metadata; access is decided server-side |
dependencies.pip is accepted but not installed: skit ignores it.
Do not use dependencies.cli, requires, or clis[].bin. The installer ignores them.
Components
Each component entry has a name, a file (path inside the kit), and an optional description.
| Type | Extra fields | Installs to |
|---|---|---|
profiles | prompts: names of prompts scoped to this profile | install.profiles (normally ~/.ist/profiles/). Profile files are Markdown or JSON |
prompts | – | install.prompts, unless a profile lists the prompt in its prompts array: then it goes to ~/.ist/prompts/profiles/<profile>/ |
clis | package instead of file | Installed globally as an npm package; its own bin entries become commands |
hooks | type: chook, dhook or phook; file is a directory | ~/.chook/hooks/<name>/, ~/.dhook/hooks/<name>/ or ~/.phook/hooks/<name>/ (not removed by uninstall) |
states | – | install.states (default ~/.ist/state/profiles/) |
packs | – | Merged into ~/.sesh/permission-packs.json |
For CLIs, prefer dependencies.npm: it pins an exact version and lets you choose the source per package.
install
| Field | Description |
|---|---|
profiles | Profile directory, normally ~/.ist/profiles/ |
prompts | Prompt directory. Must be a valid scope (see below). Required if the kit ships prompts |
states | State directory (default ~/.ist/state/profiles/) |
pre | Shell commands run in the kit directory before components are installed |
post | Shell commands run after everything is installed |
Prompt install path rules
install.prompts must be one of:
| Path | Visible to |
|---|---|
~/.ist/prompts/global/ | All sessions |
~/.ist/prompts/profiles/<name>/ | Sessions using profile <name> |
~/.ist/prompts/sessions/<name>/ | One specific session |
Any other value makes skit pack fail; skit install only warns (visible with --verbose). Use ~/.ist/prompts/global/ for a general-purpose kit, and the per-profile prompts array to scope individual prompts.
Install order
- Install
dependencies.npmpackages - Install
dependencies.skitkits - Run
install.prescripts - Install
components.clis - Install
components.hooks - Remove files from a previous installation of the same kit
- Copy profiles, prompts, packs and states
- Apply
profilePermissions - Record the kit in
~/.ist/installed-kits.json - Run
install.postscripts
A dependencies.npm entry is installed globally at the version the kit pins, even if a different version of that CLI is already installed.
Examples
Minimal kit: one profile and prompts
The onboarding tutorial kit (@marnex/tutorial-kit) ships one profile and six global prompts:
{
"name": "@marnex/tutorial-kit",
"version": "0.1.0",
"description": "Hands-on IST onboarding tutorial — you type the commands, the AI coaches.",
"type": "skit",
"files": ["skit.json", "README.md", "prompts/**/*.md", "profiles/**"],
"components": {
"prompts": [
{ "name": "tutorial-index", "file": "prompts/tutorial-index.md", "description": "Tutorial router — pick a module and see your progress" },
{ "name": "tutorial-00-hello", "file": "prompts/tutorial-00-hello.md", "description": "Module 0 — confirm your install" }
],
"profiles": [
{ "name": "tutorial", "file": "profiles/tutorial.json", "description": "Sandbox profile — auto-surfaces the tutorial router on start" }
]
},
"install": {
"prompts": "~/.ist/prompts/global/",
"profiles": "~/.ist/profiles/"
}
}
(Four more tutorial prompts are omitted here.)
After skit install:
| Component | Installed file |
|---|---|
tutorial profile | ~/.ist/profiles/tutorial.json |
tutorial-index prompt | ~/.ist/prompts/global/tutorial-index.md |
The profile is a JSON file with a system prompt and the tools the session may use. Its system prompt tells the AI to run skit prompt show tutorial-index on startup, so the prompts and the profile work as one unit:
{
"name": "tutorial",
"description": "Sandbox profile for the IST onboarding tutorial",
"systemPrompt": "# IST Onboarding Tutorial ...\n1. Run `skit prompt show tutorial-index` and follow its instructions ...",
"allowedTools": ["Read", "Bash(skit:*)", "Bash(isesh:*)", "Bash(ilogsession:*)"]
}
Full kit: profiles, scoped prompts and CLIs
A simplified excerpt of @ist/tda-kit (some prompts and fields omitted), which ships the Manager/Worker profiles and the CLIs those profiles rely on:
{
"name": "@ist/tda-kit",
"version": "0.8.2",
"description": "Top-Down Agent kit - Manager/Worker pattern profiles. Includes the TDA CLIs.",
"type": "skit",
"dependencies": {
"npm": {
"@ist/tda": "0.1.8"
}
},
"files": ["skit.json", "profiles/*.md", "prompts/*.md"],
"components": {
"profiles": [
{
"name": "tda-manager",
"file": "profiles/tda-manager.md",
"description": "Manager role - delegates work, monitors workers",
"prompts": ["worker-strategies"]
},
{
"name": "tda-worker",
"file": "profiles/tda-worker.md",
"description": "Worker role - executes tasks from Manager"
}
],
"prompts": [
{ "name": "worker-management", "file": "prompts/worker-management.md", "description": "Worker creation, task assignment, monitoring guide" },
{ "name": "worker-strategies", "file": "prompts/worker-strategies.md", "description": "Multi-brainstorm, parallel and review patterns" }
]
},
"install": {
"profiles": "~/.ist/profiles/",
"prompts": "~/.ist/prompts/global/"
}
}
What this shows:
| Part | Effect |
|---|---|
dependencies.npm | Installs the CLIs the profiles use (here itda; the full manifest also lists the isesh, imessenger and ilogsession packages), pinned to tested versions |
profiles[].prompts on tda-manager | worker-strategies is installed to ~/.ist/prompts/profiles/tda-manager/, so only manager sessions see it: skit prompt show worker-strategies --profile tda-manager |
| Other prompts | worker-management has no profile scope, so it goes to ~/.ist/prompts/global/ and every session can read it |
Configuration
skit needs no configuration for public kits. It reads these optional environment variables:
| Variable | Effect |
|---|---|
SKIT_REGISTRY | Registry proxy base URL (defaults to the IST registry proxy) |
SKIT_REGISTRY_MAPPING | Comma-separated extra scopes to treat as IST-hosted |
A GitLab token (through glpkg) is only needed for private kits and for skit browse.
Installation Locations
| Component | Location |
|---|---|
| Profiles | ~/.ist/profiles/ |
| Global prompts | ~/.ist/prompts/global/ |
| Profile-scoped prompts | ~/.ist/prompts/profiles/<profile>/ |
| Session-scoped prompts | ~/.ist/prompts/sessions/<session>/ |
| States | ~/.ist/state/profiles/ |
| Permission packs | ~/.sesh/permission-packs.json |
| Hooks | ~/.chook/hooks/, ~/.dhook/hooks/, ~/.phook/hooks/ |
| CLIs | Global npm packages |
| Installed-kit registry | ~/.ist/installed-kits.json |