# Send employee-skills-importer to your agent
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
## Fast path
- Download the package from Yavira.
- Extract it into a folder your agent can access.
- Paste one of the prompts below and point your agent at the extracted folder.
## Suggested prompts
### New install

```text
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete.
```
### Upgrade existing

```text
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run.
```
## Machine-readable fields
```json
{
  "schemaVersion": "1.0",
  "item": {
    "slug": "employee-skills-importer",
    "name": "employee-skills-importer",
    "source": "tencent",
    "type": "skill",
    "category": "数据分析",
    "sourceUrl": "https://clawhub.ai/inna-demidova/employee-skills-importer",
    "canonicalUrl": "https://clawhub.ai/inna-demidova/employee-skills-importer",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadUrl": "/downloads/employee-skills-importer",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=employee-skills-importer",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "packageFormat": "ZIP package",
    "primaryDoc": "SKILL.md",
    "includedAssets": [
      "README.md",
      "EXAMPLE_OUTPUT.md",
      "SKILL.md"
    ],
    "downloadMode": "redirect",
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/employee-skills-importer"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    }
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/employee-skills-importer",
    "downloadUrl": "https://openagent3.xyz/downloads/employee-skills-importer",
    "agentUrl": "https://openagent3.xyz/skills/employee-skills-importer/agent",
    "manifestUrl": "https://openagent3.xyz/skills/employee-skills-importer/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/employee-skills-importer/agent.md"
  }
}
```
## Documentation

### Employee Skills Importer

This skill automates the process of importing employee skills from CSV files into a Supabase database. It parses the CSV, checks what already exists in the database, and generates idempotent SQL scripts to insert missing data.

### Overview

The skill performs a 3-step process:

Identify and insert missing skill categories - Extract categories from CSV headers, check database, generate INSERT script
Identify and insert missing skills - Extract skills with their categories, check database, generate INSERT script
Generate employee_skills INSERT script - Map employees by name, link skills, create final INSERT statements

### CSV Format Requirements

The CSV must have:

Row 1: Empty or metadata (ignored)
Row 2: Skill category names spanning multiple columns
Row 3+: Individual skill names (column headers, may span multiple rows due to line breaks)
Employee data rows: Employee data with First Name, Last Name in first two columns, followed by skill experience values

Example structure:

,,,,,,.NET,,,,,Front-end,,,Java,,,
First Name,Last Name,Full Name,Unit,...,C#,ASP.net,MVC,...,JavaScript,HTML,CSS,...,Java,Spring,...
John,Doe,John Doe,Unit 1,...,5,4,3,...,6,6,5,...,0,0,...

### Step 1: Skill Categories

Parse row 2 to extract unique category names
Query the database to check existing categories:
SELECT name FROM skill_categories


Generate idempotent INSERT for missing categories:
INSERT INTO skill_categories (name) 
VALUES ('Category1'), ('Category2'), ('Category3')
ON CONFLICT (name) DO NOTHING;

### Step 2: Skills

Parse skill name rows and map to categories from row 2
Query database for existing skills:
SELECT s.name, sc.name as category_name 
FROM skills s 
LEFT JOIN skill_categories sc ON s.category_id = sc.id


For each skill to insert:

Find the category_id using a subquery
Generate idempotent INSERT:

INSERT INTO skills (name, category_id)
VALUES 
  ('C#', (SELECT id FROM skill_categories WHERE name = '.NET')),
  ('JavaScript', (SELECT id FROM skill_categories WHERE name = 'Front-end'))
ON CONFLICT (name) DO NOTHING;

### Step 3: Employee Skills

Parse employee rows (first_name, last_name, skill values)
Query employees table to get employee IDs:
SELECT id, first_name, last_name FROM employees


For each employee, for each skill with non-zero experience:

Look up employee_id by matching first_name + last_name
Look up skill_id using subquery
CRITICAL: Use TRIM() in WHERE clause to handle whitespace variations in database
Generate INSERT:

INSERT INTO employee_skills (employee_id, skill_id, years_of_experience)
VALUES 
  (
    (SELECT id FROM employees WHERE TRIM(first_name) = 'John' AND TRIM(last_name) = 'Doe'),
    (SELECT id FROM skills WHERE name = 'C#'),
    5
  )
ON CONFLICT (employee_id, skill_id) DO UPDATE 
SET years_of_experience = EXCLUDED.years_of_experience;

### Database Schema

skill_categories table: id (uuid), name (text, unique)
skills table: id (uuid), name (text, unique), category_id (uuid FK to skill_categories)
employees table: id (uuid), first_name (text), last_name (text)
employee_skills table: id (uuid), employee_id (uuid FK), skill_id (uuid FK), years_of_experience (real)

### Idempotency

All generated SQL scripts use ON CONFLICT clauses to ensure they can be run multiple times without errors:

For categories and skills: ON CONFLICT (name) DO NOTHING
For employee_skills: ON CONFLICT (employee_id, skill_id) DO UPDATE SET years_of_experience = EXCLUDED.years_of_experience

### Data Handling

Skip employees with zero or empty experience values for a skill
Handle numeric experience values (can be integers or decimals like 0.5, 1.7, etc.)
Clean up skill names by trimming whitespace and removing line breaks
Skip rows where employee lookup fails (employee not found in database)
Handle multi-line CSV cells properly
CRITICAL: Deduplicate employee-skill pairs before generating SQL - Keep the highest years value when duplicates exist
CRITICAL: Automatically correct employee name spellings - Use fuzzy matching to find and correct minor spelling differences (e.g., "Victoriia" → "Viktoriia")
CRITICAL: Trim all employee names - Remove leading/trailing whitespace from all names
CRITICAL: Use TRIM() in SQL WHERE clauses - Database may have extra spaces (e.g., "Yurii   Solokha" with 3 spaces)
CRITICAL: Skip employees with no match - If no close match found in database, exclude those records and report them

### Error Prevention

Always use subqueries for foreign key lookups rather than hardcoding UUIDs
Validate that category names match between row 2 and skill lookups
Report any employees from CSV not found in the database
Report any skills that couldn't be mapped to categories

CRITICAL - Prevent Duplicate Key Violations:

Before generating the employee_skills INSERT, deduplicate all records by (first_name, last_name, skill)
When duplicates exist, keep the record with the highest years_of_experience value
This prevents: ON CONFLICT DO UPDATE command cannot affect row a second time

CRITICAL - Automatic Name Correction:

Before generating SQL, validate ALL employees exist in the database
For employees not found by exact match:

Use fuzzy matching (Levenshtein distance or similar) to find close matches in database
If a close match is found (e.g., "Victoriia" → "Viktoriia"), automatically use the database spelling
If no close match is found, skip the employee entirely


Generate a report showing:

Employees with automatic corrections applied: "CSV name → Database name"
Employees skipped (no match found): List with number of skills skipped


This prevents: null value in column "employee_id" violates not-null constraint

### Output Format

The skill produces three SQL scripts plus one report file:

1_insert_categories.sql

-- Insert missing skill categories
INSERT INTO skill_categories (name) 
VALUES ('.NET'), ('Front-end'), ('Java')
ON CONFLICT (name) DO NOTHING;

2_insert_skills.sql

-- Insert missing skills with category mapping
INSERT INTO skills (name, category_id)
VALUES 
  ('C#', (SELECT id FROM skill_categories WHERE name = '.NET')),
  ('ASP.net', (SELECT id FROM skill_categories WHERE name = '.NET')),
  ('JavaScript', (SELECT id FROM skill_categories WHERE name = 'Front-end'))
ON CONFLICT (name) DO NOTHING;

3_insert_employee_skills.sql

-- Insert employee skills
-- Records have been deduplicated and filtered for valid employees only
-- Using TRIM() in WHERE clause to handle whitespace in database
INSERT INTO employee_skills (employee_id, skill_id, years_of_experience)
VALUES 
  (
    (SELECT id FROM employees WHERE TRIM(first_name) = 'John' AND TRIM(last_name) = 'Doe'),
    (SELECT id FROM skills WHERE name = 'C#'),
    5
  ),
  (
    (SELECT id FROM employees WHERE TRIM(first_name) = 'John' AND TRIM(last_name) = 'Doe'),
    (SELECT id FROM skills WHERE name = 'JavaScript'),
    6
  )
ON CONFLICT (employee_id, skill_id) DO UPDATE 
SET years_of_experience = EXCLUDED.years_of_experience;

### Execution Steps

When the user provides a CSV file:

Parse the CSV structure

Read the file and validate format
Extract category names from row 2
Extract skill names from subsequent rows (handling multi-line cells)
Map each skill to its category based on column positions



Query existing data from Supabase

Fetch all existing skill_categories
Fetch all existing skills with their categories
Fetch all employees (id, first_name, last_name)



Generate Script 1: Categories

Compare CSV categories against database
Create INSERT statement for missing categories
Save to file and present to user



Generate Script 2: Skills

Compare CSV skills against database
For missing skills, include category lookup subquery
Create INSERT statement
Save to file and present to user



Generate Script 3: Employee Skills

Parse employee rows
VALIDATE: Compare all CSV employees against database using exact matching
FUZZY MATCH: For non-exact matches, find closest database employee using similarity algorithm

Calculate similarity score for first_name and last_name separately
If combined similarity is above threshold (e.g., 85%), automatically use database name
Track all automatic corrections for reporting


CORRECT: Replace CSV names with database names for matched employees
FILTER: Skip employees with no close match found
DEDUPLICATE: Remove duplicates by (employee, skill), keeping highest years value
Generate INSERT statements using corrected employee names
Generate report showing corrections and skipped employees
Save SQL file and report to outputs directory
Present both files to user



Present all files to the user

Three SQL scripts (1_insert_categories.sql, 2_insert_skills.sql, 3_insert_employee_skills.sql)
One report file (skipped_employees_report.txt) if any employees were skipped
User can execute SQL scripts in order: 1 → 2 → 3
User should review report to fix name mismatches if needed

### Usage Example

User uploads CSV file and says:
"Parse this employee skills CSV and generate SQL insert scripts"

Skill responds:

Analyzes the CSV structure
Connects to Supabase SkillsSystem project
Checks existing data in all three tables
Generates three SQL files
Reports summary (e.g., "Found 5 new categories, 23 new skills, generating inserts for 47 employees")
Presents the three SQL files for download

### Project Configuration

This skill is configured to work with the Supabase project:

Project Name: SkillsSystem
Project ID: ypibfhbklinkvybgotef
Region: eu-central-1

The skill automatically connects to this project when executing queries.

### Error 1: "ON CONFLICT DO UPDATE command cannot affect row a second time"

Cause: Duplicate employee-skill pairs in the generated INSERT statement
Solution: The skill now deduplicates all records before generating SQL. If you see this error, it means deduplication was not performed.
Prevention: Always deduplicate by (first_name, last_name, skill) and keep the highest years value

### Error 2: "null value in column 'employee_id' violates not-null constraint"

Cause: Employee from CSV not found in database (usually due to name spelling differences or whitespace issues)
Solution: The skill now:

Automatically corrects spelling differences using fuzzy matching
Trims all whitespace from names
Uses TRIM() in SQL WHERE clauses to match database records with extra spaces

Common issues:

Spelling variations: "Victoriia"↔"Viktoriia", "Karasyov"↔"Karasov"
Extra whitespace in database: "Yurii   Solokha" (3 spaces)
Leading/trailing spaces

How it works:

Compares CSV names against database using similarity algorithm
If close match found (>83% similarity), automatically uses database spelling
Trims all names before comparison
Uses TRIM(first_name) and TRIM(last_name) in SQL to handle database whitespace
If no close match found, skips the employee and reports it

Result: This error should no longer occur as names are automatically corrected and whitespace is handled

### Name Matching Algorithm

The skill uses the following approach:

Try exact match first (first_name AND last_name)
If no exact match, calculate similarity score using:

Levenshtein distance or similar algorithm
Handles common variations: "Victoriia"↔"Viktoriia", "Karasyov"↔"Karasov"


If similarity > 83% threshold, accept as match
If multiple close matches found, pick the closest one
If no close match, skip the employee
Always trim whitespace from both CSV and database names
Use TRIM() in SQL queries to match records with extra spaces in database
## Trust
- Source: tencent
- Verification: Indexed source record
- Publisher: inna-demidova
- Version: 1.0.0
## Source health
- Status: healthy
- Source download looks usable.
- Yavira can redirect you to the upstream package for this source.
- Health scope: source
- Reason: direct_download_ok
- Checked at: 2026-04-23T16:43:11.935Z
- Expires at: 2026-04-30T16:43:11.935Z
- Recommended action: Download for OpenClaw
## Links
- [Detail page](https://openagent3.xyz/skills/employee-skills-importer)
- [Send to Agent page](https://openagent3.xyz/skills/employee-skills-importer/agent)
- [JSON manifest](https://openagent3.xyz/skills/employee-skills-importer/agent.json)
- [Markdown brief](https://openagent3.xyz/skills/employee-skills-importer/agent.md)
- [Download page](https://openagent3.xyz/downloads/employee-skills-importer)