Skip to main content

Unified Suggester

The Unified Suggester is the main discovery layer that integrates Mental Model (codebase semantic understanding), Skills.sh (external community skills), and Auto-Skill V2 (local pattern detection) to provide ranked skill suggestions with confidence scores and context.

Installation

import { createUnifiedSuggester } from 'auto-skill';

Usage

Basic Example

import { createUnifiedSuggester, type DetectedPattern } from 'auto-skill';

const suggester = createUnifiedSuggester({
  projectPath: process.cwd(),
  enableMental: true,
  enableExternal: true,
});

// Get suggestions based on context
const suggestions = await suggester.suggestForContext({
  detectedPatterns: [
    {
      id: 'pattern-1',
      toolSequence: ['Read', 'Edit', 'Bash'],
      occurrenceCount: 5,
      confidence: 0.85,
      // ... other fields
    },
  ],
  sessionContext: {
    primary_intent: 'implement',
    problem_domains: ['api', 'authentication'],
  },
  filePaths: ['src/api/auth.ts', 'src/middleware/jwt.ts'],
});

console.log(`Found ${suggestions.length} suggestions`);

for (const suggestion of suggestions) {
  console.log(`${suggestion.name} (${Math.round(suggestion.confidence * 100)}%)`);
  console.log(`  Source: ${suggestion.source}`);
  console.log(`  ${suggestion.description}`);
}

API Reference

createUnifiedSuggester(options?)

Create a unified skill suggester that combines all discovery sources.
options
object
Configuration options.
options.projectPath
string
default:"process.cwd()"
Path to the project directory.
options.enableMental
boolean
default:"true"
Enable Mental Model integration for semantic codebase understanding.
options.enableExternal
boolean
default:"true"
Enable Skills.sh integration for external community skills.
options.providers
SkillProvider[]
Optional list of custom SkillProvider instances.
suggester
object
Suggester object exposing suggestion and tracking methods.

suggestForContext(params)

Suggest skills based on current context. Combines suggestions from local patterns (highest confidence), Mental model hints (medium confidence), and external skills (variable confidence based on adoption).
params
object
required
Context parameters for skill suggestions.
params.detectedPatterns
DetectedPattern[]
Array of detected workflow patterns.
params.sessionContext
Record<string, unknown>
Session context including intent, domains, workflow type.
params.filePaths
string[]
Array of file paths being modified.
suggestions
SkillSuggestion[]
Array of skill suggestions sorted by confidence (highest first).

suggestForFiles(filePaths, limit?)

Suggest skills based on file paths using the Mental model.
filePaths
string[]
required
Array of file paths to analyze.
limit
number
default:"10"
Maximum number of suggestions to return.
suggestions
SkillSuggestion[]
Array of skill suggestions sorted by confidence.

suggestForDomain(domainName, limit?)

Suggest skills for a specific Mental domain.
domainName
string
required
Name of the domain (e.g., “Payment”, “User”, “Authentication”).
limit
number
default:"10"
Maximum number of suggestions to return.
suggestions
SkillSuggestion[]
Array of skill suggestions for the domain.

recordSkillUsage(skillName, skillSource, success)

Record that a skill was used and track adoption.
skillName
string
required
Name of the skill that was used.
skillSource
string
required
Source of the skill: "local", "external", or "mental-hint".
success
boolean
required
Whether the skill usage was successful.
readyToGraduate
boolean
Returns true if the skill is ready to graduate to local, false otherwise.

getGraduationCandidates()

Get skills that are ready to graduate to local.
candidates
SkillAdoption[]
Array of skills eligible for graduation.

graduateSkill(skillId)

Graduate an external skill to local.
skillId
string
required
Skill identifier to graduate.

getAdoptionStats(minConfidence?)

Get adoption statistics for all tracked skills.
minConfidence
number
default:"0"
Minimum confidence threshold to include in results.
stats
SkillAdoption[]
Array of skill adoption records sorted by confidence and usage.

Types

SkillSuggestion

A suggested skill with context and confidence.
SkillSuggestion
object
name
string
Skill name.
description
string
Human-readable description.
source
'local' | 'external' | 'mental-hint'
Source of the suggestion:
  • local: From detected patterns
  • external: From Skills.sh community
  • mental-hint: From Mental Model analysis
confidence
number
Confidence score between 0 and 1.
tags
string[]
Skill tags/categories.
mentalContext
object
Mental Model context if source is "mental-hint".
domains
string[]
Related Mental domains.
capability
string
Capability name.
operatesOn
string[]
Entities this capability operates on.
patternMatch
object
Pattern match details if source is "local".
toolSequence
string[]
Tool sequence that triggered this pattern.
occurrences
number
Number of times pattern was detected.
successRate
number
Success rate of the pattern.
externalMetadata
object
External skill metadata if source is "external".
adoption
SkillAdoption
Adoption tracking data if skill has been used.

Discovery Sources

The Unified Suggester combines three sources:

1. Local Patterns (Highest Confidence)

Skills generated from detected workflow patterns:
{
  name: 'react-test-workflow',
  description: 'Workflow for testing React components',
  source: 'local',
  confidence: 0.85,
  patternMatch: {
    toolSequence: ['Read', 'Grep', 'Edit', 'Bash'],
    occurrences: 5,
    successRate: 0.9,
  },
}

2. Mental Model Hints (Medium Confidence)

Skills suggested by semantic codebase analysis:
{
  name: 'payment-processing-skill',
  description: 'Skill for Payment capability',
  source: 'mental-hint',
  confidence: 0.6,
  mentalContext: {
    domains: ['Payment', 'Billing'],
    capability: 'ProcessPayment',
    operatesOn: ['Order', 'Customer'],
  },
}

3. External Skills (Variable Confidence)

Note: External skills integration was deprecated in v5.0. Use createExternalSkillLoader() + createProactiveDiscovery() instead for external skill discovery.

Adoption Tracking

Track skill usage and confidence evolution:
// Record skill usage
const readyToGraduate = suggester.recordSkillUsage(
  'react-testing',
  'external',
  true // success
);

if (readyToGraduate) {
  console.log('Skill is ready to graduate!');
}

// Get graduation candidates
const candidates = suggester.getGraduationCandidates();

for (const candidate of candidates) {
  console.log(`${candidate.skillName}:`);
  console.log(`  Confidence: ${Math.round(candidate.currentConfidence * 100)}%`);
  console.log(`  Usage: ${candidate.usageCount}`);
  console.log(`  Success rate: ${Math.round((candidate.successCount / candidate.usageCount) * 100)}%`);
}

// Graduate a skill
if (candidates.length > 0) {
  suggester.graduateSkill(candidates[0].skillId);
}

Graduation Criteria

Skills graduate from external to local when:
  1. Confidence >= 0.85
  2. Usage count >= 5
  3. Success rate >= 0.8 (80%)
const candidates = suggester.getGraduationCandidates();

for (const candidate of candidates) {
  if (
    candidate.currentConfidence >= 0.85 &&
    candidate.usageCount >= 5 &&
    candidate.successCount / candidate.usageCount >= 0.8
  ) {
    suggester.graduateSkill(candidate.skillId);
  }
}

Advanced Usage

File-Based Discovery

const suggester = createUnifiedSuggester({
  projectPath: '/path/to/project',
  enableMental: true,
});

// Suggest skills for specific files
const suggestions = suggester.suggestForFiles([
  'src/api/payments.ts',
  'src/services/stripe.ts',
  'src/models/order.ts',
]);

console.log(`Found ${suggestions.length} suggestions for payment-related files`);

Domain-Specific Discovery

// Suggest skills for a specific domain
const paymentSkills = suggester.suggestForDomain('Payment', 5);
const userSkills = suggester.suggestForDomain('User', 5);

console.log('Payment skills:');
paymentSkills.forEach(s => console.log(`- ${s.name}`));

console.log('\nUser skills:');
userSkills.forEach(s => console.log(`- ${s.name}`));

Combined Context Discovery

const suggestions = await suggester.suggestForContext({
  detectedPatterns: myPatterns,
  sessionContext: {
    primary_intent: 'implement',
    problem_domains: ['authentication', 'api', 'security'],
    workflow_type: 'backend',
  },
  filePaths: [
    'src/auth/jwt.ts',
    'src/middleware/auth.ts',
    'src/api/routes.ts',
  ],
});

// Filter and categorize
const local = suggestions.filter(s => s.source === 'local');
const mental = suggestions.filter(s => s.source === 'mental-hint');
const external = suggestions.filter(s => s.source === 'external');

console.log(`Local: ${local.length}, Mental: ${mental.length}, External: ${external.length}`);

Adoption Statistics

// Get all adopted skills with at least 50% confidence
const adoptedSkills = suggester.getAdoptionStats(0.5);

console.log('Adoption Statistics:');
console.log(`Total skills tracked: ${adoptedSkills.length}`);

for (const skill of adoptedSkills) {
  const successRate = skill.usageCount > 0
    ? Math.round((skill.successCount / skill.usageCount) * 100)
    : 0;
  
  console.log(`\n${skill.skillName}:`);
  console.log(`  Source: ${skill.source}`);
  console.log(`  Confidence: ${Math.round(skill.currentConfidence * 100)}%`);
  console.log(`  Usage: ${skill.usageCount} times`);
  console.log(`  Success rate: ${successRate}%`);
  console.log(`  Graduated: ${skill.graduatedToLocal ? 'Yes' : 'No'}`);
}

Integration Example

import { createUnifiedSuggester, type DetectedPattern } from 'auto-skill';

class SkillDiscoveryService {
  private suggester: ReturnType<typeof createUnifiedSuggester>;
  
  constructor(projectPath: string) {
    this.suggester = createUnifiedSuggester({
      projectPath,
      enableMental: true,
      enableExternal: true,
    });
  }
  
  async discoverSkills(
    patterns: DetectedPattern[],
    context: Record<string, unknown>,
    files: string[]
  ) {
    const suggestions = await this.suggester.suggestForContext({
      detectedPatterns: patterns,
      sessionContext: context,
      filePaths: files,
    });
    
    return {
      highConfidence: suggestions.filter(s => s.confidence >= 0.7),
      mediumConfidence: suggestions.filter(s => s.confidence >= 0.5 && s.confidence < 0.7),
      lowConfidence: suggestions.filter(s => s.confidence < 0.5),
    };
  }
  
  trackUsage(skillName: string, source: string, success: boolean) {
    const readyToGraduate = this.suggester.recordSkillUsage(
      skillName,
      source,
      success
    );
    
    if (readyToGraduate) {
      console.log(`🎓 ${skillName} is ready to graduate!`);
      // Optionally auto-graduate
      const skillId = skillName.toLowerCase().replace(/\s/g, '-');
      this.suggester.graduateSkill(skillId);
    }
  }
  
  getReport() {
    const candidates = this.suggester.getGraduationCandidates();
    const stats = this.suggester.getAdoptionStats();
    
    return {
      totalSkills: stats.length,
      graduationCandidates: candidates.length,
      bySource: stats.reduce((acc, s) => {
        acc[s.source] = (acc[s.source] || 0) + 1;
        return acc;
      }, {} as Record<string, number>),
    };
  }
}

// Usage
const service = new SkillDiscoveryService('/path/to/project');

const discovered = await service.discoverSkills(
  myPatterns,
  { primary_intent: 'test' },
  ['src/components/Button.test.tsx']
);

console.log(`High confidence: ${discovered.highConfidence.length}`);
console.log(`Medium confidence: ${discovered.mediumConfidence.length}`);

const report = service.getReport();
console.log('Report:', report);

Best Practices

  1. Enable Mental Model: Provides valuable semantic context for large codebases
  2. Track all usage: Always call recordSkillUsage() to improve confidence scores
  3. Review before graduation: Check graduation candidates before auto-graduating
  4. Use appropriate confidence thresholds: Different use cases require different thresholds
  5. Combine sources: Use all three discovery sources for comprehensive suggestions
  6. Filter by confidence: Present high-confidence suggestions first to users

Build docs developers (and LLMs) love