# How the Skills CLI Agent Detection Mechanism Works: A Deep Dive into `vercel-labs/skills`

> Understand how the Skills CLI detects agents by examining unique filesystem markers. Learn about its configurable detection map in this deep dive into vercel-labs/skills.

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

---

**The Skills CLI detects installed agents by checking for unique marker directories or files on the filesystem, using a configurable detection map defined in [`src/agents.ts`](https://github.com/vercel-labs/skills/blob/main/src/agents.ts).**

The `vercel-labs/skills` repository provides a CLI tool for managing shared skills across multiple AI agent platforms. A critical capability of this tool is its **agent detection mechanism**—the ability to automatically discover which agent runtimes (AMP, OpenClaw, Claude Code, etc.) are present on a user's machine. This article explains exactly how this detection system works, with complete source code references.

## The Two-Step Agent Detection Architecture

The Skills CLI implements agent detection through a clean separation between **configuration** and **execution**. This design allows easy extension for new agents without modifying core detection logic.

### Step 1: Per-Agent Configuration with `detectInstalled` Functions

Each supported agent is defined in [`src/agents.ts`](https://github.com/vercel-labs/skills/blob/main/src/agents.ts) with a `detectInstalled` async function that checks for a filesystem marker unique to that agent:

```typescript
// From src/agents.ts (conceptual structure)
const agents = {
  openclaw: {
    detectInstalled: async () => {
      return fs.existsSync(path.join(os.homedir(), '.openclaw'));
    }
  },
  gemini: {
    detectInstalled: async () => {
      return fs.existsSync(path.join(os.homedir(), '.gemini', 'antigravity'));
    }
  },
  augment: {
    detectInstalled: async () => {
      return fs.existsSync(path.join(os.homedir(), '.augment'));
    }
  }
  // ... additional agents
};

```

The detection checks use **Node.js `fs.existsSync`** for synchronous filesystem presence verification. Each agent targets a distinctive marker:

| Agent | Marker Path | Detection Strategy |
|-------|-------------|------------------|
| OpenClaw | `~/.openclaw` | Hidden directory in home folder |
| Gemini | `~/.gemini/antigravity` | Nested file within hidden directory |
| Augment | `~/.augment` | Hidden directory in home folder |

### Step 2: Aggregation with `detectInstalledAgents()`

The `detectInstalledAgents()` function in [`src/agents.ts`](https://github.com/vercel-labs/skills/blob/main/src/agents.ts) (lines 41-48) orchestrates the complete detection process:

```typescript
// From src/agents.ts
export async function detectInstalledAgents(): Promise<AgentType[]> {
  const results = await Promise.all(
    Object.entries(agents).map(async ([key, config]) => {
      const isInstalled = await config.detectInstalled();
      return isInstalled ? (key as AgentType) : null;
    })
  );
  return results.filter((agent): agent is AgentType => agent !== null);
}

```

This function:
1. Iterates over all entries in the `agents` map
2. Executes each `detectInstalled` function in parallel via `Promise.all`
3. Filters to return only the `AgentType` values for successfully detected agents

## How Commands Use Agent Detection

The **agent detection mechanism** integrates directly into CLI workflows. Here's how key commands leverage it:

### The `add` Command: Auto-Selection of Installed Agents

In [`src/add.ts`](https://github.com/vercel-labs/skills/blob/main/src/add.ts) (lines 36-42), the detection results populate the interactive UI:

```typescript
// From src/add.ts
const installedAgents = await detectInstalledAgents();

// Auto-select detected agents + ensure universal agents are always included
// Universal agents share the .agents/skills folder and are always active

```

This enables a seamless experience where users see only relevant agents pre-selected.

### The `remove` Command: Targeted Cleanup

The `remove` command in [`src/remove.ts`](https://github.com/vercel-labs/skills/blob/main/src/remove.ts) uses detection to determine which agent directories need symlink cleanup, avoiding errors from attempting operations on non-existent installations.

### The `sync` Command: Conditional Synchronization

In [`src/sync.ts`](https://github.com/vercel-labs/skills/blob/main/src/sync.ts), agent detection precedes global skill directory synchronization, ensuring sync operations only target installed agent environments.

## Type Definitions Supporting Detection

The [`src/types.ts`](https://github.com/vercel-labs/skills/blob/main/src/types.ts) file establishes the TypeScript contracts that enable type-safe agent detection:

```typescript
// From src/types.ts
export type AgentType = 
  | 'openclaw'
  | 'gemini'
  | 'augment'
  | 'amp'
  | 'claude'
  | 'universal';

export interface AgentConfig {
  name: string;
  description: string;
  detectInstalled: () => Promise<boolean>;
  skillsDir: string;
  // ... additional configuration
}

```

These types ensure that:
- Only valid `AgentType` values can be returned from detection
- Every agent configuration implements the required `detectInstalled` contract

## Advantages of This Detection Approach

The Skills CLI's **agent detection mechanism** offers several architectural benefits:

- **Extensibility**: Adding new agents requires only a new entry in [`src/agents.ts`](https://github.com/vercel-labs/skills/blob/main/src/agents.ts) with a unique marker path
- **Reliability**: Filesystem-based detection is deterministic and doesn't depend on process enumeration
- **Performance**: `Promise.all` parallelization ensures all checks complete quickly
- **Portability**: Works across macOS, Linux, and Windows (via Node.js path normalization)
- **Maintainability**: Detection logic is centralized and testable

## Summary

The Skills CLI implements **agent detection** through a two-layer system:

- **Configuration layer**: Each agent in [`src/agents.ts`](https://github.com/vercel-labs/skills/blob/main/src/agents.ts) defines a `detectInstalled` function that checks for a unique filesystem marker
- **Aggregation layer**: The `detectInstalledAgents()` function runs all checks in parallel and returns installed agent types

This mechanism powers automatic agent selection in commands like `add`, `remove`, and `sync`, while maintaining extensibility for new agent platforms.

## Frequently Asked Questions

### How does the Skills CLI detect Claude Code installation?

The Skills CLI detects Claude Code by checking for a marker directory or file specific to that agent's installation, as defined in the `agents` map within [`src/agents.ts`](https://github.com/vercel-labs/skills/blob/main/src/agents.ts). Each agent uses a unique filesystem path—typically within the user's home directory—that indicates the agent's presence.

### Can I add support for a custom agent to the Skills CLI?

Yes, the detection architecture in [`src/agents.ts`](https://github.com/vercel-labs/skills/blob/main/src/agents.ts) is designed for extensibility. You would add a new entry to the `agents` map with a `detectInstalled` function that checks for your custom agent's unique marker file or directory, plus the required `AgentConfig` properties for skill directory paths and display information.

### Why does the Skills CLI use filesystem markers instead of process detection?

Filesystem markers provide reliable, deterministic detection without requiring runtime process enumeration or environment parsing. According to the `vercel-labs/skills` source code, this approach works across platforms, avoids false positives from transient processes, and integrates cleanly with the CLI's async initialization flow using `fs.existsSync` checks.