[FEATURE] update command doesn't support private-git source type - all private SSH-installed skills are skipped #6

Closed
opened 2026-03-18 15:20:01 +00:00 by kmisachenka · 1 comment
kmisachenka commented 2026-03-18 15:20:01 +00:00 (Migrated from github.com)

Description

The update command silently skips all skills installed from private Git SSH URLs (e.g. ssh://[email protected]:port/user/repo.git). These skills are stored in the lock file with "sourceType": "private-git", but the update command only recognizes github, gitlab, and database as updateable source types.

Steps to Reproduce

  1. Install skills from a private Git repo:
    npx agent-skills-cli install ssh://[email protected]:37234/user/skills.git -a claude cursor
    
  2. Verify skills are installed (~/.skills/skills.lock shows all entries with "sourceType": "private-git")
  3. Run update:
    npx agent-skills-cli update
    
  4. Select all skills when prompted

Expected Behavior

Skills should be updated by re-cloning from the original SSH source URL stored in the lock file.

Actual Behavior

📦 No remote skills to update.
Local skills cannot be updated automatically.

All private-git skills are treated as local/non-updateable, even though the CLI has their full SSH clone URL stored in the lock file.

Root Cause

Two issues in dist/cli/commands/utils-commands.jsregisterUpdateCommand:

1. Source type filter excludes private-git (line ~312)

const updateable = skillsToUpdate.filter(
  s => s.sourceType === 'github' || s.sourceType === 'gitlab' || s.sourceType === 'database'
);

private-git is not in this list, so every private-git skill is filtered out.

2. URL parsing regex only matches github.com/gitlab.com (line ~329)

const urlMatch = skill.source.match(/(github|gitlab)\.com\/([^/]+)\/([^/]+)/);

Even if private-git were added to the filter, this regex would fail to match SSH URLs like ssh://[email protected]:37234/user/repo.git, causing the update to fail with "Invalid source URL".

Suggested Fix

  1. Add 'private-git' to the updateable source type filter:

    const updateable = skillsToUpdate.filter(
      s => s.sourceType === 'github' || s.sourceType === 'gitlab' || s.sourceType === 'database' || s.sourceType === 'private-git'
    );
    
  2. For private-git skills, skip the URL regex parsing and use skill.source directly as the clone URL:

    if (skill.sourceType === 'private-git') {
      await execAsync(`git clone --depth 1 ${skill.source} .`, { cwd: tempDir });
    } else {
      const urlMatch = skill.source.match(/(github|gitlab)\.com\/([^/]+)\/([^/]+)/);
      if (!urlMatch) {
        spinner.fail(`${skill.scopedName}: Invalid source URL`);
        failCount++;
        continue;
      }
      await execAsync(`git clone --depth 1 ${skill.source} .`, { cwd: tempDir });
    }
    

    In fact, the regex match result (urlMatch) is never actually used beyond the null-check — the clone always uses skill.source directly. So the regex validation could simply be skipped for private-git sources.

Environment

  • agent-skills-cli version: 1.1.7
  • Node.js: v24.1.0
  • OS: macOS (darwin 25.3.0)
## Description The `update` command silently skips all skills installed from private Git SSH URLs (e.g. `ssh://[email protected]:port/user/repo.git`). These skills are stored in the lock file with `"sourceType": "private-git"`, but the update command only recognizes `github`, `gitlab`, and `database` as updateable source types. ## Steps to Reproduce 1. Install skills from a private Git repo: ```bash npx agent-skills-cli install ssh://[email protected]:37234/user/skills.git -a claude cursor ``` 2. Verify skills are installed (`~/.skills/skills.lock` shows all entries with `"sourceType": "private-git"`) 3. Run update: ```bash npx agent-skills-cli update ``` 4. Select all skills when prompted ## Expected Behavior Skills should be updated by re-cloning from the original SSH source URL stored in the lock file. ## Actual Behavior ``` 📦 No remote skills to update. Local skills cannot be updated automatically. ``` All `private-git` skills are treated as local/non-updateable, even though the CLI has their full SSH clone URL stored in the lock file. ## Root Cause Two issues in `dist/cli/commands/utils-commands.js` → `registerUpdateCommand`: ### 1. Source type filter excludes `private-git` (line ~312) ```js const updateable = skillsToUpdate.filter( s => s.sourceType === 'github' || s.sourceType === 'gitlab' || s.sourceType === 'database' ); ``` `private-git` is not in this list, so every private-git skill is filtered out. ### 2. URL parsing regex only matches github.com/gitlab.com (line ~329) ```js const urlMatch = skill.source.match(/(github|gitlab)\.com\/([^/]+)\/([^/]+)/); ``` Even if `private-git` were added to the filter, this regex would fail to match SSH URLs like `ssh://[email protected]:37234/user/repo.git`, causing the update to fail with "Invalid source URL". ## Suggested Fix 1. Add `'private-git'` to the updateable source type filter: ```js const updateable = skillsToUpdate.filter( s => s.sourceType === 'github' || s.sourceType === 'gitlab' || s.sourceType === 'database' || s.sourceType === 'private-git' ); ``` 2. For `private-git` skills, skip the URL regex parsing and use `skill.source` directly as the clone URL: ```js if (skill.sourceType === 'private-git') { await execAsync(`git clone --depth 1 ${skill.source} .`, { cwd: tempDir }); } else { const urlMatch = skill.source.match(/(github|gitlab)\.com\/([^/]+)\/([^/]+)/); if (!urlMatch) { spinner.fail(`${skill.scopedName}: Invalid source URL`); failCount++; continue; } await execAsync(`git clone --depth 1 ${skill.source} .`, { cwd: tempDir }); } ``` In fact, the regex match result (`urlMatch`) is never actually used beyond the null-check — the clone always uses `skill.source` directly. So the regex validation could simply be skipped for `private-git` sources. ## Environment - **agent-skills-cli version:** 1.1.7 - **Node.js:** v24.1.0 - **OS:** macOS (darwin 25.3.0)
Karanjot786 commented 2026-05-11 06:23:26 +00:00 (Migrated from github.com)

Fixed in commit ce8b418. Two changes:

  1. private-git added to the updateable source type filter
  2. URL regex validation is skipped for private-git entries — the SSH URL from the lock file is used directly for git clone
Fixed in commit ce8b418. Two changes: 1. `private-git` added to the updateable source type filter 2. URL regex validation is skipped for `private-git` entries — the SSH URL from the lock file is used directly for `git clone`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rtlabs-llm-agents/agent-skills-cli#6
No description provided.