CodeSkills

Skills

Skills are portable, reusable instruction bundles that give Bahulam expertise in specific domains. Each skill is a SKILL.md file with frontmatter metadata and optional reference resources.


What Are Skills?

A skill is a self-contained package that teaches Bahulam how to do something well — a coding framework, a testing pattern, a deployment workflow, or any repeated task.

Skills are:

  • Portable — share them across projects and teams
  • Installable — from local files, GitHub repos, or URLs
  • Discoverable — listed by name, description, and scope
  • Compatible — work with both Bahulam and Claude Code

Skill Structure

A skill is a directory or file with this layout:

my-skill/
├── SKILL.md          # Skill definition (required)
└── references/       # Optional reference resources
    ├── api.md
    └── examples/

SKILL.md Frontmatter

---
name: my-skill
description: "Brief description of what this skill provides"
compatibility: "bahulam"  # or "claude-code" or both
---

The body of SKILL.md contains the instructions Bahulam will follow when the skill is invoked. This can include code patterns, conventions, architecture guidelines, and step-by-step workflows.

References Directory

The references/ directory can contain additional files that the skill references. These are loaded on demand when the agent uses the skill_view tool with a specific resource path.


Skill Discovery

Bahulam searches for skills in four locations, in priority order (higher priority shadows lower):

  1. .bahulam/skills/ — project-local skills (highest priority)
  2. .claude/skills/ — project-local Claude Code compatibility
  3. ~/.bahulam/skills/ — user-global skills
  4. ~/.claude/skills/ — user-global Claude Code compatibility

A project-level skill with the same name as a global skill shadows the global one. This lets you override team-wide skills with project-specific versions.


Managing Skills

Skills can be managed two ways: from the interactive REPL with the /skills slash command, or from the shell with bahulam skills ….

/skills (inside the REPL)

Typing /skills on its own opens an interactive picker:

> /skills
  Installed skills · 2 bundles

  ▸ autoprompt      global    Explicit-only useful-first orchestration…
    react-testing   project   Best practices for testing React components…

  ↑↓ move · Enter view SKILL.md · r remove · Esc close

Inline subcommands work too:

/skills list [--project|--all]
/skills install <git-url|path> [--project] [--force]
/skills view <name> [resource]
/skills remove <name> [--project]
/skills update <name> [--project]

bahulam skills (from the shell)

Same operations, without launching the REPL:

# List installed skills (aligned table)
bahulam skills list
bahulam skills list --project      # only project scope
bahulam skills list --all          # both scopes
bahulam skills list --json         # machine-readable
 
# Install
bahulam skills install ./path/to/my-skill
bahulam skills install https://github.com/org/my-skill
bahulam skills install ./my-skill --project   # scope to this repo
bahulam skills install ./my-skill --force     # overwrite an existing skill
 
# View, update, remove
bahulam skills view my-skill
bahulam skills view my-skill references/api.md
bahulam skills update my-skill [--project]
bahulam skills remove my-skill [--project]

Note — if a source repository ships multiple SKILL.md bundles that all declare the same name: (e.g. one variant per agent tool), the installer keeps the first bundle found and reports a duplicate-collapsed warning. Use --only <name> on the underlying API if you need to pick a specific variant.


Invoking Skills

There are two invocation modes. Which one applies depends on how the skill’s SKILL.md is written.

1. Auto pickup (describe the task)

Each turn the CLI hands the agent a metadata list of your installed skills — name, description, scope — via the skills_list tool. When your prompt matches a skill’s description, the agent calls skill_view on its own to load the full SKILL.md, then follows those instructions for the rest of the turn.

> write unit tests for the Button component using our testing conventions

If react-testing is installed and its description mentions testing React components, the agent loads it and applies the conventions with no extra ceremony.

2. Explicit invocation (name the skill)

Some skills refuse to auto-activate on their own — usually because running them is expensive, opinionated, or side-effectful. Those skills declare an explicit trigger in their SKILL.md. You activate them by name, either as a /-prefixed command or in plain English:

> /autoprompt build a rate limiter that survives cold starts

> use the autoprompt skill to plan a rewrite of the billing pipeline

The /autoprompt form is not a REPL slash command — it is a skill-defined trigger the agent recognizes after reading the loaded SKILL.md. Different skills define different triggers (some use /name, some watch for specific keywords like "review this PR", some require a direct mention).

How to tell which mode a skill uses

Read the skill’s SKILL.md:

> /skills view autoprompt

The frontmatter description describes when the agent should auto-activate. The body usually spells out any explicit-only rules — for example:

“Never infer invocation from ordinary requests. The invocation authorizes the mission.”

That kind of sentence means the skill will not fire until you name it yourself.


Creating a Skill

Create a directory with a SKILL.md file:

---
name: react-testing
description: "Best practices for testing React components with Testing Library"
compatibility: "bahulam"
---
 
# React Testing Guidelines
 
## Conventions
- Use `@testing-library/react` for component tests
- Use `@testing-library/jest-dom` for custom matchers
- Prefer `getByRole` over `getByTestId`
 
## Patterns
 
### Testing User Interactions
```tsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
 
it('submits the form on button click', async () => {
  const user = userEvent.setup();
  render(<MyForm />);
  await user.click(screen.getByRole('button', { name: /submit/i }));
  expect(screen.getByText(/success/i)).toBeInTheDocument();
});

Async Testing

Use waitFor or findBy queries for async operations.


Then install it:

```bash
bahulam skills install ./react-testing