Back to skills
SkillHub ClubShip Full StackFull StackIntegration

vscode-extension

Use when developing VSCode extensions - covers language support, LSP integration, and packaging

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3
Hot score
80
Updated
March 20, 2026
Overall rating
C1.6
Composite score
1.6
Best-practice grade
N/A

Install command

npx @skill-hub/cli install mcclowes-lea-vscode-extension

Repository

mcclowes/lea

Skill path: .claude/skills/vscode-extension

Use when developing VSCode extensions - covers language support, LSP integration, and packaging

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack, Integration.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: mcclowes.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install vscode-extension into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/mcclowes/lea before adding vscode-extension to shared team environments
  • Use vscode-extension for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: vscode-extension
# prettier-ignore
description: Use when developing VSCode extensions - covers language support, LSP integration, and packaging
---

# VSCode Extension Development

## Quick Start

```json
// package.json
{
  "name": "vscode-lea",
  "displayName": "Lea Language",
  "engines": { "vscode": "^1.85.0" },
  "categories": ["Programming Languages"],
  "contributes": {
    "languages": [{
      "id": "lea",
      "extensions": [".lea"],
      "configuration": "./language-configuration.json"
    }],
    "grammars": [{
      "language": "lea",
      "scopeName": "source.lea",
      "path": "./syntaxes/lea.tmLanguage.json"
    }]
  }
}
```

## Core Components

### Language Configuration

```json
// language-configuration.json
{
  "comments": { "lineComment": "--" },
  "brackets": [
    ["{", "}"],
    ["[", "]"],
    ["(", ")"]
  ],
  "autoClosingPairs": [
    { "open": "{", "close": "}" },
    { "open": "[", "close": "]" },
    { "open": "(", "close": ")" },
    { "open": "\"", "close": "\"" }
  ],
  "surroundingPairs": [
    ["{", "}"],
    ["[", "]"],
    ["(", ")"],
    ["\"", "\""]
  ]
}
```

### LSP Client Integration

```typescript
import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
} from "vscode-languageclient/node";

export function activate(context: vscode.ExtensionContext) {
  const serverModule = context.asAbsolutePath("server/index.js");

  const serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: { module: serverModule, transport: TransportKind.ipc }
  };

  const clientOptions: LanguageClientOptions = {
    documentSelector: [{ scheme: "file", language: "lea" }],
  };

  const client = new LanguageClient("lea", "Lea", serverOptions, clientOptions);
  client.start();
}
```

### Snippets

```json
// snippets/lea.json
{
  "Function": {
    "prefix": "fn",
    "body": ["let ${1:name} = (${2:params}) -> ${0:body}"],
    "description": "Define a function"
  },
  "Pipeline": {
    "prefix": "pipe",
    "body": ["${1:value}", "  /> ${2:transform}", "  /> ${0:result}"],
    "description": "Create a pipeline"
  }
}
```

## Packaging & Publishing

```bash
# Install vsce
npm install -g @vscode/vsce

# Package extension
vsce package

# Publish to marketplace
vsce publish
```

## Reference Files

- [references/activation.md](references/activation.md) - Activation events
- [references/commands.md](references/commands.md) - Command registration


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/activation.md

```markdown
# Activation Events

## Common Activation Events

```json
{
  "activationEvents": [
    "onLanguage:lea",
    "onCommand:lea.runFile",
    "workspaceContains:**/*.lea",
    "onStartupFinished"
  ]
}
```

## Event Types

### onLanguage

Activates when a file of the specified language is opened.

```json
"activationEvents": ["onLanguage:lea"]
```

### onCommand

Activates when a command is invoked.

```json
"activationEvents": ["onCommand:lea.runFile"]
```

### workspaceContains

Activates when workspace contains matching files.

```json
"activationEvents": ["workspaceContains:**/*.lea"]
```

### onFileSystem

Activates when a file system scheme is accessed.

```json
"activationEvents": ["onFileSystem:lea-virtual"]
```

### onView

Activates when a view is expanded.

```json
"activationEvents": ["onView:leaOutline"]
```

### onUri

Activates when a URI is opened.

```json
"activationEvents": ["onUri"]
```

### onStartupFinished

Activates after VSCode startup is complete.

```json
"activationEvents": ["onStartupFinished"]
```

## Implicit Activation

As of VSCode 1.74+, many contributions implicitly activate:

- `languages` - Files matching the language
- `commands` - When command is invoked
- `grammars` - When grammar is needed

You often don't need explicit activationEvents for these.

## Best Practices

1. **Be specific** - Avoid `*` activation
2. **Lazy load** - Only activate when needed
3. **Combine events** - List multiple for flexibility

```json
{
  "activationEvents": [
    "onLanguage:lea",
    "workspaceContains:**/*.lea"
  ]
}
```

```

### references/commands.md

```markdown
# Command Registration

## Defining Commands

### In package.json

```json
{
  "contributes": {
    "commands": [
      {
        "command": "lea.runFile",
        "title": "Run Lea File",
        "category": "Lea",
        "icon": "$(play)"
      },
      {
        "command": "lea.formatDocument",
        "title": "Format Document",
        "category": "Lea"
      }
    ]
  }
}
```

### In extension.ts

```typescript
import * as vscode from "vscode";

export function activate(context: vscode.ExtensionContext) {
  // Simple command
  const runFile = vscode.commands.registerCommand("lea.runFile", () => {
    const editor = vscode.window.activeTextEditor;
    if (editor) {
      const code = editor.document.getText();
      // Execute code...
    }
  });

  // Command with arguments
  const runSelection = vscode.commands.registerCommand(
    "lea.runSelection",
    (text?: string) => {
      const code = text || vscode.window.activeTextEditor?.document.getText();
      // Execute code...
    }
  );

  context.subscriptions.push(runFile, runSelection);
}
```

## Keybindings

```json
{
  "contributes": {
    "keybindings": [
      {
        "command": "lea.runFile",
        "key": "ctrl+shift+r",
        "mac": "cmd+shift+r",
        "when": "editorLangId == lea"
      }
    ]
  }
}
```

## Menu Contributions

```json
{
  "contributes": {
    "menus": {
      "editor/context": [
        {
          "command": "lea.runFile",
          "when": "editorLangId == lea",
          "group": "navigation"
        }
      ],
      "editor/title": [
        {
          "command": "lea.runFile",
          "when": "editorLangId == lea",
          "group": "navigation"
        }
      ]
    }
  }
}
```

## Command Palette

Commands automatically appear in Command Palette. Control visibility:

```json
{
  "contributes": {
    "menus": {
      "commandPalette": [
        {
          "command": "lea.runFile",
          "when": "editorLangId == lea"
        }
      ]
    }
  }
}
```

## Executing Commands

```typescript
// Execute your own command
await vscode.commands.executeCommand("lea.runFile");

// Execute built-in command
await vscode.commands.executeCommand("editor.action.formatDocument");

// With arguments
await vscode.commands.executeCommand("lea.runSelection", "print(42)");
```

```

vscode-extension | SkillHub