# Project-Level vs Global Skill Installation Scopes in the Skills CLI

> Understand project-level vs global skill installation scopes in the Skills CLI. Install skills locally for a project or user-wide for all projects.

- Repository: [Vercel Labs/skills](https://github.com/vercel-labs/skills)
- Tags: internals
- Published: 2026-04-23

---

**The Skills CLI supports two installation scopes: project-level (default, stored in `.agents/skills`) installs skills locally to the current repository, while global (`-g` flag, stored in `~/.agents/skills`) installs them user-wide across all projects.**

The `skills` CLI from Vercel Labs provides flexible skill management through two distinct installation scopes. Understanding when to use project-level versus global installation helps you manage AI agent dependencies effectively across repositories and development environments.

## What Determines the Installation Scope

The scope is controlled by the `--global` (or `-g`) flag parsed in [`src/list.ts`](https://github.com/vercel-labs/skills/blob/main/src/list.ts) lines 50-54. When omitted, the CLI defaults to project-level scope:

```typescript
// From src/list.ts
const scope = options.global === true ? true : false;

```

This boolean propagates through the installation and listing logic to determine where skills are stored and discovered.

## Project-Level Installation Scope

Project-level scope is the default behavior when running `skills add` without flags. This installs skills into a hidden directory within your repository.

### Storage Location

The canonical project-level directory is resolved by `getCanonicalSkillsDir(false, cwd)` in [`src/installer.ts`](https://github.com/vercel-labs/skills/blob/main/src/installer.ts) lines 70-73:

```typescript
// Project scope: uses current working directory
return join(cwd, ".agents", "skills");

```

This creates the path `<project-root>/.agents/skills/<skill-name>`.

### Agent-Specific Directories

Each agent receives its own subdirectory within the project. The `getAgentBaseDir` function in [`src/installer.ts`](https://github.com/vercel-labs/skills/blob/main/src/installer.ts) lines 80-87 constructs:

```typescript
// Project scope: agent.skillsDir relative to cwd
return join(cwd, agent.skillsDir);

```

For example, Claude skills install to `.claude/skills/`, Cursor skills to `.cursor/skills/`, etc.

### Use Cases

- **CI/CD pipelines**: Skills travel with the repository, ensuring consistent builds
- **Team collaboration**: All developers share identical skill configurations through version control
- **Temporary experimentation**: Test skills without affecting your global environment

## Global Installation Scope

Global scope installs skills user-wide, making them available from any project directory on your machine.

### Storage Location

The canonical global directory is resolved by `getCanonicalSkillsDir(true, cwd)` in [`src/installer.ts`](https://github.com/vercel-labs/skills/blob/main/src/installer.ts) lines 70-73:

```typescript
// Global scope: uses user's home directory
return join(homedir(), ".agents", "skills");

```

This creates the path `~/.agents/skills/<skill-name>`.

### Agent-Specific Global Directories

For global installs, `getAgentBaseDir` in [`src/installer.ts`](https://github.com/vercel-labs/skills/blob/main/src/installer.ts) lines 80-87 uses each agent's `globalSkillsDir` property:

```typescript
// Global scope: agent.globalSkillsDir relative to home
return join(homedir(), agent.globalSkillsDir);

```

This typically resolves to paths like `~/.claude/skills/` or `~/.cursor/skills/`.

### Global Support Requirements

Not all agents support global installation. The `installSkillForAgent` function in [`src/installer.ts`](https://github.com/vercel-labs/skills/blob/main/src/installer.ts) lines 21-28 validates this:

```typescript
if (isGlobal && agent.globalSkillsDir === undefined) {
  console.log(
    `${agent.displayName} does not support global skill installation`
  );
  return;
}

```

If an agent lacks `globalSkillsDir` in its configuration (defined in [`src/types.ts`](https://github.com/vercel-labs/skills/blob/main/src/types.ts) lines 63-64), the CLI aborts with a clear error message.

### Use Cases

- **Personal assistants**: Skills you want available in every project directory
- **Cross-project utilities**: Common tools that don't belong to any specific repository
- **System-wide defaults**: Base skill set that augments project-specific installations

## CLI Commands and Scope Behavior

### Installing Skills

```bash

# Project-level installation (default)

skills add vercel-labs/agent-gpt

# Global installation

skills add vercel-labs/agent-gpt -g

# or

skills add vercel-labs/agent-gpt --global

```

### Listing Installed Skills

The `skills list` command respects the same scope flag:

```bash

# List project-level skills only

skills list

# List global skills (includes all agent global directories)

skills list -g

```

The listing implementation in [`src/installer.ts`](https://github.com/vercel-labs/skills/blob/main/src/installer.ts) lines 48-53 builds scope types:

```typescript
const scopeTypes: ScopeType[] = [];
if (isGlobal) {
  scopeTypes.push({ global: true });
}

```

When `isGlobal` is true, the scanner walks both the canonical global directory and each agent's `globalSkillsDir`.

### Lock File Management

Each scope maintains its own lock file for tracking installations:

| Scope | Lock File Location |
|-------|-------------------|
| Project | [`skills-lock.json`](https://github.com/vercel-labs/skills/blob/main/skills-lock.json) in project root |
| Global | `~/.agents/.skill-lock.json` |

The [`skill-lock.ts`](https://github.com/vercel-labs/skills/blob/main/skill-lock.ts) module handles both paths transparently based on the scope parameter.

## Programmatic Scope Control

For TypeScript consumers, the `getInstallPath` function accepts a scope configuration:

```typescript
import { getInstallPath } from './src/installer.ts';

// Project-level path
const localPath = getInstallPath('my-skill', 'claude', { cwd: process.cwd() });
// Returns: /path/to/project/.claude/skills/my-skill

// Global-level path
const globalPath = getInstallPath('my-skill', 'claude', { global: true });
// Returns: /home/user/.claude/skills/my-skill

```

The function validates paths through `isPathSafe` to prevent directory traversal attacks (lines 10-19 in [`src/installer.ts`](https://github.com/vercel-labs/skills/blob/main/src/installer.ts)).

## Summary

- **Project-level scope** (`--local` or default) installs skills to `<project>/.agents/skills/` and agent-specific subdirectories, tracked in [`skills-lock.json`](https://github.com/vercel-labs/skills/blob/main/skills-lock.json)
- **Global scope** (`-g` or `--global`) installs skills to `~/.agents/skills/` and `~/.<agent>/skills/` directories, tracked in `~/.agents/.skill-lock.json`
- Not all agents support global installation—those lacking `globalSkillsDir` will error when `-g` is used
- The `getCanonicalSkillsDir` and `getAgentBaseDir` functions in [`src/installer.ts`](https://github.com/vercel-labs/skills/blob/main/src/installer.ts) handle path resolution for both scopes

## Frequently Asked Questions

### What happens if I install the same skill in both project and global scopes?

Both installations coexist independently. When running `skills list` without `-g`, you'll see the project version. With `skills list -g`, you'll see the global version. The CLI does not automatically merge or deduplicate across scopes.

### Can I convert a project-level skill to global without reinstalling?

There's no built-in `skills migrate` command. You would need to run `skills add <skill> -g` to install globally, then `skills remove <skill>` (project scope) to remove the local copy. The skill package will be re-downloaded during the global installation.

### Why does my agent not support global installation?

Agents must explicitly define `globalSkillsDir` in their configuration (see [`src/types.ts`](https://github.com/vercel-labs/skills/blob/main/src/types.ts) lines 63-64). If an agent only specifies `skillsDir`, it's designed for project-level use only—often because the agent itself lacks a concept of global configuration or because global skills could conflict with the agent's security model.

### How do I check which scope a skill is installed in?

Run both listing commands and compare:

```bash
skills list        # Project scope

skills list -g     # Global scope

```

If the skill appears in both outputs, it's installed in both scopes. The `skills list` command does not currently indicate "both" in a single invocation—you must check separately.