agentsclimarketplace

Vscode configuration validation

Skill fabioc-aloha/Alex_Skill_Mall/plugins/platform-tooling/vscode-configuration-validation

284 curated plugins for AI assistants across 16 categories: security, Azure, documentation, code quality, cloud infrastructure, and more. Works with GitHub Copilot. Drop into .github/skills/local/ and go.

Install
npx -y skills add fabioc-aloha/Alex_Skill_Mall --skill vscode-configuration-validation

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Validate VS Code extension manifest against runtime code usage

SKILL.md

7.9 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it

VS Code Extension Configuration Validation

Domain: VS Code extension development, configuration management, quality assurance
Complexity: Intermediate
Prerequisites: Understanding of VS Code extension manifest (package.json), TypeScript

Decision Table

SymptomRoot CauseFix
Config value not persistingKey not in contributes.configurationRegister in package.json
Command "not found" errorCommand not in contributes.commandsAdd command declaration
View not renderingView ID mismatchMatch id in viewsContainers/views
Context menu missingwhen clause failsFix context key expression
Activation too lateMissing activation eventAdd onCommand:* or onView:*
Runtime config errorTry-catch missingWrap config access in try-catch

Problem

VS Code extensions fail at runtime when:

  • Configuration keys are updated without being registered in package.json
  • Commands are invoked but not declared in manifest
  • Views/webviews reference unregistered IDs
  • Context keys are set but not documented

These misconfigurations don't cause compile-time errors and only surface when users interact with specific features.

Solution

Systematic validation of VS Code extension manifest against runtime code usage.

1. Configuration Registration Validation

Check: All workspace.getConfiguration().update() calls reference registered properties.

// ❌ WRONG - config key not registered
await vscode.workspace.getConfiguration('alex.skillRecommendations')
  .update('code-review.accepted', count + 1, ConfigurationTarget.Global);

// ✅ RIGHT - key registered in package.json or wrapped in try-catch
try {
  await vscode.workspace.getConfiguration('alex.skillRecommendations')
    .update('code-review.accepted', count + 1, ConfigurationTarget.Global);
} catch (error) {
  console.log(`Skip tracking: ${error}`);
}

Audit Pattern:

# Find all config.update() calls
grep -r "getConfiguration.*\.update\(" src/

# Cross-reference with package.json properties section
# Each update() key must exist in "configuration.properties"

2. Command Registration Validation

Check: All commands.registerCommand() calls match declared commands in manifest.

// Code registration
vscode.commands.registerCommand('alex.validateHeir', async () => {...});

// Must have package.json declaration
{
  "contributes": {
    "commands": [{
      "command": "alex.validateHeir",
      "title": "Validate as Heir Project"
    }]
  }
}

Audit Pattern:

# Find all command registrations
grep -r "registerCommand\(['\"]alex\." src/

# Extract command names and verify each exists in package.json

3. Configuration Read Validation

Check: All getConfiguration().get() calls match registered properties.

// This config read should have a registered property
const enabled = vscode.workspace.getConfiguration('alex.voice').get('enabled', false);

// Check package.json has "alex.voice.enabled"

Warning Pattern: Configuration reads with no defaults are risky:

// ⚠️ No fallback - will be undefined if not registered
const value = config.get('someKey');

// ✅ Better - always provide default
const value = config.get('someKey', defaultValue);

4. Error Handling Patterns

For Dynamic Configuration Keys (skill recommendations, user preferences):

Option A: Register schema with dynamic pattern (complex) Option B: Graceful try-catch (simple, recommended)

// Pattern: Non-critical dynamic config
async function trackUserPreference(key: string, value: any) {
  try {
    await vscode.workspace.getConfiguration('alex.dynamic')
      .update(key, value, ConfigurationTarget.Global);
  } catch (error) {
    // Log but don't fail - tracking is optional
    console.log(`[the AI assistant] Skipping preference tracking: ${error}`);
  }
}

For Critical Configuration:

// Pattern: Essential config must be registered
await vscode.workspace.getConfiguration('alex.globalKnowledge')
  .update('remoteRepo', repo, ConfigurationTarget.Global);
// No try-catch - failure should bubble up

Validation Checklist

Pre-Publish Review

  • Search code for getConfiguration().update() calls
  • Verify each updated key exists in package.json properties OR has try-catch
  • Search for registerCommand() calls
  • Verify each command exists in contributes.commands
  • Check for dynamic config patterns (user tracking, etc.)
  • Apply graceful degradation pattern for non-critical features

Automated Audit Script

Pseudocode: validate-manifest
1. Search src/**/*.ts for getConfiguration('section').update('key') calls
2. Load contributes.configuration.properties from package.json
3. For each config update found in source code:
   If the full key (section.key) is NOT in package.json properties:
     Flag as unregistered config write (potential runtime error)
4. Report all mismatches
$issues += "⚠️  $fullKey - not registered (verify try-catch exists)"

} }

if ($issues.Count -gt 0) { Write-Host "Configuration validation issues:" -ForegroundColor Yellow $issues | ForEach-Object { Write-Host $_ } exit 1 }


## Common Pitfalls

1. **Dynamic Configuration Keys**: User preferences, tracking counters
   - **Solution**: Either register dynamic schema or use try-catch pattern

2. **Namespaced Configuration**: `alex.skill.subkey.value`
   - **Solution**: Register full dotted path: `"alex.skill.subkey.value": {...}`

3. **Multi-Target Updates**: Workspace vs Global vs WorkspaceFolder
   - **Solution**: Test configuration across all scopes

4. **Configuration Migration**: Deprecated settings
   - **Solution**: Use `deprecationMessage` in property definition

## Real-World Example: Skill Recommendations

**Problem**: Tracking skill usage without bloating package.json with hundreds of dynamic keys.

**Solution**: Graceful degradation pattern
```typescript
async function trackRecommendation(skillId: string, accepted: boolean) {
  try {
    const context = 'alex.skillRecommendations';
    const key = `${skillId}.${accepted ? 'accepted' : 'dismissed'}`;
    const current = vscode.workspace.getConfiguration(context).get<number>(key, 0);
    await vscode.workspace.getConfiguration(context).update(
      key, 
      current + 1, 
      vscode.ConfigurationTarget.Global
    );
  } catch (error) {
    // Feature degrades gracefully - recommendations still work
    console.log(`[the AI assistant] Skipping recommendation tracking: ${error}`);
  }
}

Why This Works:

  • Feature works with or without tracking
  • No user-facing error for unregistered config
  • Logging helps debug if tracking is important
  • Simple implementation vs complex dynamic schema

Integration with Existing QA

Add to .github/instructions/extension-audit-methodology.instructions.md:

### Configuration Validation

Before each release:
1. Run `node scripts/release-preflight.cjs`
2. Review any warnings for try-catch coverage
3. Test configuration updates in clean VS Code instance
4. Verify error messages are user-friendly

Resources


Sources of Truth:

  • Incident: Skill recommendations broken due to unregistered config (2026-02-15)
  • Root Cause: alex.skillRecommendations.* keys not in package.json
  • Fix: Try-catch wrapper in src/chat/skillRecommendations.ts

Keep looking

Skills are one crate of 327,069. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.