docs(A1.9): Add comprehensive git source documentation and example repository
Phase 4 Complete: - Updated README.md with git source usage examples and use cases - Created docs/GIT_CONFIG_SOURCES.md (800+ lines comprehensive guide) - Updated CHANGELOG.md with v2.2.0 release notes - Added configs/example-team/ example repository with E2E test Documentation covers: - Quick start and architecture - MCP tools reference (4 tools with examples) - Authentication for GitHub, GitLab, Bitbucket - Use cases (small teams, enterprise, open source) - Best practices, troubleshooting, advanced topics - Complete API reference Example repository includes: - 3 example configs (react-custom, vue-internal, company-api) - README with usage guide - E2E test script (7 steps, 100% passing) 🤖 Generated with Claude Code Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
194
CHANGELOG.md
194
CHANGELOG.md
@@ -7,6 +7,200 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [2.2.0] - 2025-12-21
|
||||||
|
|
||||||
|
### 🚀 Private Config Repositories - Team Collaboration Unlocked
|
||||||
|
|
||||||
|
This major release adds **git-based config sources**, enabling teams to fetch configs from private/team repositories in addition to the public API. This unlocks team collaboration, enterprise deployment, and custom config collections.
|
||||||
|
|
||||||
|
### 🎯 Major Features
|
||||||
|
|
||||||
|
#### Git-Based Config Sources (Issue [#211](https://github.com/yusufkaraaslan/Skill_Seekers/issues/211))
|
||||||
|
- **Multi-source config management** - Fetch from API, git URL, or named sources
|
||||||
|
- **Private repository support** - GitHub, GitLab, Bitbucket, Gitea, and custom git servers
|
||||||
|
- **Team collaboration** - Share configs across 3-5 person teams with version control
|
||||||
|
- **Enterprise scale** - Support 500+ developers with priority-based resolution
|
||||||
|
- **Secure authentication** - Environment variable tokens only (GITHUB_TOKEN, GITLAB_TOKEN, etc.)
|
||||||
|
- **Intelligent caching** - Shallow clone (10-50x faster), auto-pull updates
|
||||||
|
- **Offline mode** - Works with cached repos when offline
|
||||||
|
- **Backward compatible** - Existing API-based configs work unchanged
|
||||||
|
|
||||||
|
#### New MCP Tools
|
||||||
|
- **`add_config_source`** - Register git repositories as config sources
|
||||||
|
- Auto-detects source type (GitHub, GitLab, etc.)
|
||||||
|
- Auto-selects token environment variable
|
||||||
|
- Priority-based resolution for multiple sources
|
||||||
|
- SSH URL support (auto-converts to HTTPS + token)
|
||||||
|
|
||||||
|
- **`list_config_sources`** - View all registered sources
|
||||||
|
- Shows git URL, branch, priority, token env
|
||||||
|
- Filter by enabled/disabled status
|
||||||
|
- Sorted by priority (lower = higher priority)
|
||||||
|
|
||||||
|
- **`remove_config_source`** - Unregister sources
|
||||||
|
- Removes from registry (cache preserved for offline use)
|
||||||
|
- Helpful error messages with available sources
|
||||||
|
|
||||||
|
- **Enhanced `fetch_config`** - Three modes
|
||||||
|
1. **Named source mode** - `fetch_config(source="team", config_name="react-custom")`
|
||||||
|
2. **Git URL mode** - `fetch_config(git_url="https://...", config_name="react-custom")`
|
||||||
|
3. **API mode** - `fetch_config(config_name="react")` (unchanged)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
#### Core Infrastructure
|
||||||
|
- **GitConfigRepo class** (`src/skill_seekers/mcp/git_repo.py`, 283 lines)
|
||||||
|
- `clone_or_pull()` - Shallow clone with auto-pull and force refresh
|
||||||
|
- `find_configs()` - Recursive *.json discovery (excludes .git)
|
||||||
|
- `get_config()` - Load config with case-insensitive matching
|
||||||
|
- `inject_token()` - Convert SSH to HTTPS with token authentication
|
||||||
|
- `validate_git_url()` - Support HTTPS, SSH, and file:// URLs
|
||||||
|
- Comprehensive error handling (auth failures, missing repos, corrupted caches)
|
||||||
|
|
||||||
|
- **SourceManager class** (`src/skill_seekers/mcp/source_manager.py`, 260 lines)
|
||||||
|
- `add_source()` - Register/update sources with validation
|
||||||
|
- `get_source()` - Retrieve by name with helpful errors
|
||||||
|
- `list_sources()` - List all/enabled sources sorted by priority
|
||||||
|
- `remove_source()` - Unregister sources
|
||||||
|
- `update_source()` - Modify specific fields
|
||||||
|
- Atomic file I/O (write to temp, then rename)
|
||||||
|
- Auto-detect token env vars from source type
|
||||||
|
|
||||||
|
#### Storage & Caching
|
||||||
|
- **Registry file**: `~/.skill-seekers/sources.json`
|
||||||
|
- Stores source metadata (URL, branch, priority, timestamps)
|
||||||
|
- Version-controlled schema (v1.0)
|
||||||
|
- Atomic writes prevent corruption
|
||||||
|
|
||||||
|
- **Cache directory**: `$SKILL_SEEKERS_CACHE_DIR` (default: `~/.skill-seekers/cache/`)
|
||||||
|
- One subdirectory per source
|
||||||
|
- Shallow git clones (depth=1, single-branch)
|
||||||
|
- Configurable via environment variable
|
||||||
|
|
||||||
|
#### Documentation
|
||||||
|
- **docs/GIT_CONFIG_SOURCES.md** (800+ lines) - Comprehensive guide
|
||||||
|
- Quick start, architecture, authentication
|
||||||
|
- MCP tools reference with examples
|
||||||
|
- Use cases (small teams, enterprise, open source)
|
||||||
|
- Best practices, troubleshooting, advanced topics
|
||||||
|
- Complete API reference
|
||||||
|
|
||||||
|
- **configs/example-team/** - Example repository for testing
|
||||||
|
- `react-custom.json` - Custom React config with metadata
|
||||||
|
- `vue-internal.json` - Internal Vue config
|
||||||
|
- `company-api.json` - Company API config example
|
||||||
|
- `README.md` - Usage guide and best practices
|
||||||
|
- `test_e2e.py` - End-to-end test script (7 steps, 100% passing)
|
||||||
|
|
||||||
|
- **README.md** - Updated with git source examples
|
||||||
|
- New "Private Config Repositories" section in Key Features
|
||||||
|
- Comprehensive usage examples (quick start, team collaboration, enterprise)
|
||||||
|
- Supported platforms and authentication
|
||||||
|
- Example workflows for different team sizes
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
- **GitPython>=3.1.40** - Git operations (clone, pull, branch switching)
|
||||||
|
- Replaces subprocess calls with high-level API
|
||||||
|
- Better error handling and cross-platform support
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
- **83 new tests** (100% passing)
|
||||||
|
- `tests/test_git_repo.py` (35 tests) - GitConfigRepo functionality
|
||||||
|
- Initialization, URL validation, token injection
|
||||||
|
- Clone/pull operations, config discovery, error handling
|
||||||
|
- `tests/test_source_manager.py` (48 tests) - SourceManager functionality
|
||||||
|
- Add/get/list/remove/update sources
|
||||||
|
- Registry persistence, atomic writes, default token env
|
||||||
|
- `tests/test_mcp_git_sources.py` (18 tests) - MCP integration
|
||||||
|
- All 3 fetch modes (API, Git URL, Named Source)
|
||||||
|
- Source management tools (add/list/remove)
|
||||||
|
- Complete workflow (add → fetch → remove)
|
||||||
|
- Error scenarios (auth failures, missing configs)
|
||||||
|
|
||||||
|
### Improved
|
||||||
|
- **MCP server** - Now supports 12 tools (up from 9)
|
||||||
|
- Maintains backward compatibility
|
||||||
|
- Enhanced error messages with available sources
|
||||||
|
- Priority-based config resolution
|
||||||
|
|
||||||
|
### Use Cases
|
||||||
|
|
||||||
|
**Small Teams (3-5 people):**
|
||||||
|
```bash
|
||||||
|
# One-time setup
|
||||||
|
add_config_source(name="team", git_url="https://github.com/myteam/configs.git")
|
||||||
|
|
||||||
|
# Daily usage
|
||||||
|
fetch_config(source="team", config_name="react-internal")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Enterprise (500+ developers):**
|
||||||
|
```bash
|
||||||
|
# IT pre-configures sources
|
||||||
|
add_config_source(name="platform", ..., priority=1)
|
||||||
|
add_config_source(name="mobile", ..., priority=2)
|
||||||
|
|
||||||
|
# Developers use transparently
|
||||||
|
fetch_config(config_name="platform-api") # Finds in platform source
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example Repository:**
|
||||||
|
```bash
|
||||||
|
cd /path/to/Skill_Seekers
|
||||||
|
python3 configs/example-team/test_e2e.py # Test E2E workflow
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backward Compatibility
|
||||||
|
- ✅ All existing configs work unchanged
|
||||||
|
- ✅ API mode still default (no registration needed)
|
||||||
|
- ✅ No breaking changes to MCP tools or CLI
|
||||||
|
- ✅ New parameters are optional (git_url, source, refresh)
|
||||||
|
|
||||||
|
### Security
|
||||||
|
- ✅ Tokens via environment variables only (not in files)
|
||||||
|
- ✅ Shallow clones minimize attack surface
|
||||||
|
- ✅ No token storage in registry file
|
||||||
|
- ✅ Secure token injection (auto-converts SSH to HTTPS)
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
- ✅ Shallow clone: 10-50x faster than full clone
|
||||||
|
- ✅ Minimal disk space (no git history)
|
||||||
|
- ✅ Auto-pull: Only fetches changes (not full re-clone)
|
||||||
|
- ✅ Offline mode: Works with cached repos
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
- Modified (2): `pyproject.toml`, `src/skill_seekers/mcp/server.py`
|
||||||
|
- Added (6): 3 source files + 3 test files + 1 doc + 1 example repo
|
||||||
|
- Total lines added: ~2,600
|
||||||
|
|
||||||
|
### Migration Guide
|
||||||
|
|
||||||
|
No migration needed! This is purely additive:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Before v2.2.0 (still works)
|
||||||
|
fetch_config(config_name="react")
|
||||||
|
|
||||||
|
# New in v2.2.0 (optional)
|
||||||
|
add_config_source(name="team", git_url="...")
|
||||||
|
fetch_config(source="team", config_name="react-custom")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Known Limitations
|
||||||
|
- MCP async tests require pytest-asyncio (added to dev dependencies)
|
||||||
|
- Example repository uses 'master' branch (git init default)
|
||||||
|
|
||||||
|
### See Also
|
||||||
|
- [GIT_CONFIG_SOURCES.md](docs/GIT_CONFIG_SOURCES.md) - Complete guide
|
||||||
|
- [configs/example-team/](configs/example-team/) - Example repository
|
||||||
|
- [Issue #211](https://github.com/yusufkaraaslan/Skill_Seekers/issues/211) - Original feature request
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [2.1.1] - 2025-11-30
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- **submit_config MCP tool** - Comprehensive validation and format support ([#11](https://github.com/yusufkaraaslan/Skill_Seekers/issues/11))
|
- **submit_config MCP tool** - Comprehensive validation and format support ([#11](https://github.com/yusufkaraaslan/Skill_Seekers/issues/11))
|
||||||
- Now uses ConfigValidator for comprehensive validation (previously only checked 3 fields)
|
- Now uses ConfigValidator for comprehensive validation (previously only checked 3 fields)
|
||||||
|
|||||||
120
README.md
120
README.md
@@ -72,6 +72,16 @@ Skill Seeker is an automated tool that transforms documentation websites, GitHub
|
|||||||
- ✅ **Single Source of Truth** - One skill showing both intent (docs) and reality (code)
|
- ✅ **Single Source of Truth** - One skill showing both intent (docs) and reality (code)
|
||||||
- ✅ **Backward Compatible** - Legacy single-source configs still work
|
- ✅ **Backward Compatible** - Legacy single-source configs still work
|
||||||
|
|
||||||
|
### 🔐 Private Config Repositories (**NEW - v2.2.0**)
|
||||||
|
- ✅ **Git-Based Config Sources** - Fetch configs from private/team git repositories
|
||||||
|
- ✅ **Multi-Source Management** - Register unlimited GitHub, GitLab, Bitbucket repos
|
||||||
|
- ✅ **Team Collaboration** - Share custom configs across 3-5 person teams
|
||||||
|
- ✅ **Enterprise Support** - Scale to 500+ developers with priority-based resolution
|
||||||
|
- ✅ **Secure Authentication** - Environment variable tokens (GITHUB_TOKEN, GITLAB_TOKEN)
|
||||||
|
- ✅ **Intelligent Caching** - Clone once, pull updates automatically
|
||||||
|
- ✅ **Offline Mode** - Work with cached configs when offline
|
||||||
|
- ✅ **Backward Compatible** - Existing API-based configs still work
|
||||||
|
|
||||||
### 🤖 AI & Enhancement
|
### 🤖 AI & Enhancement
|
||||||
- ✅ **AI-Powered Enhancement** - Transforms basic templates into comprehensive guides
|
- ✅ **AI-Powered Enhancement** - Transforms basic templates into comprehensive guides
|
||||||
- ✅ **No API Costs** - FREE local enhancement using Claude Code Max
|
- ✅ **No API Costs** - FREE local enhancement using Claude Code Max
|
||||||
@@ -319,6 +329,116 @@ def move_local_x(delta: float, snap: bool = False) -> None
|
|||||||
|
|
||||||
**Full Guide:** See [docs/UNIFIED_SCRAPING.md](docs/UNIFIED_SCRAPING.md) for complete documentation.
|
**Full Guide:** See [docs/UNIFIED_SCRAPING.md](docs/UNIFIED_SCRAPING.md) for complete documentation.
|
||||||
|
|
||||||
|
### Private Config Repositories (**NEW - v2.2.0**)
|
||||||
|
|
||||||
|
**The Problem:** Teams need to share custom configs for internal documentation, but don't want to publish them publicly.
|
||||||
|
|
||||||
|
**The Solution:** Register private git repositories as config sources. Fetch configs from team repos just like the public API, with full authentication support.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Setup: Set your GitHub token (one-time)
|
||||||
|
export GITHUB_TOKEN=ghp_your_token_here
|
||||||
|
|
||||||
|
# Option 1: Using MCP tools (recommended)
|
||||||
|
# Register your team's private repo
|
||||||
|
add_config_source(
|
||||||
|
name="team",
|
||||||
|
git_url="https://github.com/mycompany/skill-configs.git",
|
||||||
|
token_env="GITHUB_TOKEN"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Fetch config from team repo
|
||||||
|
fetch_config(source="team", config_name="internal-api")
|
||||||
|
|
||||||
|
# List all registered sources
|
||||||
|
list_config_sources()
|
||||||
|
|
||||||
|
# Remove source when no longer needed
|
||||||
|
remove_config_source(name="team")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Direct Git URL mode** (no registration):
|
||||||
|
```bash
|
||||||
|
# Fetch directly from git URL
|
||||||
|
fetch_config(
|
||||||
|
git_url="https://github.com/mycompany/configs.git",
|
||||||
|
config_name="react-custom",
|
||||||
|
token="ghp_your_token_here"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supported Platforms:**
|
||||||
|
- GitHub (token env: `GITHUB_TOKEN`)
|
||||||
|
- GitLab (token env: `GITLAB_TOKEN`)
|
||||||
|
- Gitea (token env: `GITEA_TOKEN`)
|
||||||
|
- Bitbucket (token env: `BITBUCKET_TOKEN`)
|
||||||
|
- Any git server (token env: `GIT_TOKEN`)
|
||||||
|
|
||||||
|
**Use Cases:**
|
||||||
|
|
||||||
|
📋 **Small Teams (3-5 people)**
|
||||||
|
```bash
|
||||||
|
# Team lead creates repo
|
||||||
|
gh repo create myteam/skill-configs --private
|
||||||
|
|
||||||
|
# Add configs to repo
|
||||||
|
cd myteam-skill-configs
|
||||||
|
cp ../Skill_Seekers/configs/react.json ./react-custom.json
|
||||||
|
# Edit selectors, categories for your internal docs...
|
||||||
|
git add . && git commit -m "Add custom React config" && git push
|
||||||
|
|
||||||
|
# Team members register (one-time)
|
||||||
|
add_config_source(name="team", git_url="https://github.com/myteam/skill-configs.git")
|
||||||
|
|
||||||
|
# Everyone can now fetch
|
||||||
|
fetch_config(source="team", config_name="react-custom")
|
||||||
|
```
|
||||||
|
|
||||||
|
🏢 **Enterprise (500+ developers)**
|
||||||
|
```bash
|
||||||
|
# IT pre-configures sources for everyone
|
||||||
|
add_config_source(name="platform", git_url="gitlab.company.com/platform/configs", priority=1)
|
||||||
|
add_config_source(name="mobile", git_url="gitlab.company.com/mobile/configs", priority=2)
|
||||||
|
add_config_source(name="official", git_url="api.skillseekersweb.com", priority=3)
|
||||||
|
|
||||||
|
# Developers use transparently
|
||||||
|
fetch_config(config_name="internal-platform") # Finds in platform source
|
||||||
|
fetch_config(config_name="react") # Falls back to official API
|
||||||
|
```
|
||||||
|
|
||||||
|
**Storage Locations:**
|
||||||
|
- Registry: `~/.skill-seekers/sources.json`
|
||||||
|
- Cache: `$SKILL_SEEKERS_CACHE_DIR` (default: `~/.skill-seekers/cache/`)
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- ✅ **Shallow clone** - 10-50x faster, minimal disk space
|
||||||
|
- ✅ **Auto-pull** - Fetches latest changes automatically
|
||||||
|
- ✅ **Offline mode** - Works with cached repos when offline
|
||||||
|
- ✅ **Priority resolution** - Multiple sources with conflict resolution
|
||||||
|
- ✅ **Secure** - Tokens via environment variables only
|
||||||
|
|
||||||
|
**Example Team Repository:**
|
||||||
|
|
||||||
|
Try the included example:
|
||||||
|
```bash
|
||||||
|
# Test with file:// URL (no auth needed)
|
||||||
|
cd /path/to/Skill_Seekers
|
||||||
|
|
||||||
|
# Run the E2E test
|
||||||
|
python3 configs/example-team/test_e2e.py
|
||||||
|
|
||||||
|
# Or test manually
|
||||||
|
add_config_source(
|
||||||
|
name="example",
|
||||||
|
git_url="file://$(pwd)/configs/example-team",
|
||||||
|
branch="master"
|
||||||
|
)
|
||||||
|
|
||||||
|
fetch_config(source="example", config_name="react-custom")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Full Guide:** See [docs/GIT_CONFIG_SOURCES.md](docs/GIT_CONFIG_SOURCES.md) for complete documentation.
|
||||||
|
|
||||||
## How It Works
|
## How It Works
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
|||||||
136
configs/example-team/README.md
Normal file
136
configs/example-team/README.md
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# Example Team Config Repository
|
||||||
|
|
||||||
|
This is an **example config repository** demonstrating how teams can share custom configs via git.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
This repository shows how to:
|
||||||
|
- Structure a custom config repository
|
||||||
|
- Share team-specific documentation configs
|
||||||
|
- Use git-based config sources with Skill Seekers
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
example-team/
|
||||||
|
├── README.md # This file
|
||||||
|
├── react-custom.json # Custom React config (modified selectors)
|
||||||
|
├── vue-internal.json # Internal Vue docs config
|
||||||
|
└── company-api.json # Company API documentation config
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage with Skill Seekers
|
||||||
|
|
||||||
|
### Option 1: Use this repo directly (for testing)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Using MCP tools (recommended)
|
||||||
|
add_config_source(
|
||||||
|
name="example-team",
|
||||||
|
git_url="file:///path/to/Skill_Seekers/configs/example-team"
|
||||||
|
)
|
||||||
|
|
||||||
|
fetch_config(source="example-team", config_name="react-custom")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Create your own team repo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Create new repo
|
||||||
|
mkdir my-team-configs
|
||||||
|
cd my-team-configs
|
||||||
|
git init
|
||||||
|
|
||||||
|
# 2. Add configs
|
||||||
|
cp /path/to/configs/react.json ./react-custom.json
|
||||||
|
# Edit configs as needed...
|
||||||
|
|
||||||
|
# 3. Commit and push
|
||||||
|
git add .
|
||||||
|
git commit -m "Initial team configs"
|
||||||
|
git remote add origin https://github.com/myorg/team-configs.git
|
||||||
|
git push -u origin main
|
||||||
|
|
||||||
|
# 4. Register with Skill Seekers
|
||||||
|
add_config_source(
|
||||||
|
name="team",
|
||||||
|
git_url="https://github.com/myorg/team-configs.git",
|
||||||
|
token_env="GITHUB_TOKEN"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 5. Use it
|
||||||
|
fetch_config(source="team", config_name="react-custom")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Config Naming Best Practices
|
||||||
|
|
||||||
|
- Use descriptive names: `react-custom.json`, `vue-internal.json`
|
||||||
|
- Avoid name conflicts with official configs
|
||||||
|
- Include version if needed: `api-v2.json`
|
||||||
|
- Group by category: `frontend/`, `backend/`, `mobile/`
|
||||||
|
|
||||||
|
## Private Repositories
|
||||||
|
|
||||||
|
For private repos, set the appropriate token environment variable:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# GitHub
|
||||||
|
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxx
|
||||||
|
|
||||||
|
# GitLab
|
||||||
|
export GITLAB_TOKEN=glpat-xxxxxxxxxxxxx
|
||||||
|
|
||||||
|
# Bitbucket
|
||||||
|
export BITBUCKET_TOKEN=xxxxxxxxxxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
Then register the source:
|
||||||
|
|
||||||
|
```python
|
||||||
|
add_config_source(
|
||||||
|
name="private-team",
|
||||||
|
git_url="https://github.com/myorg/private-configs.git",
|
||||||
|
source_type="github",
|
||||||
|
token_env="GITHUB_TOKEN"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing This Example
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From Skill_Seekers root directory
|
||||||
|
cd /mnt/1ece809a-2821-4f10-aecb-fcdf34760c0b/Git/Skill_Seekers
|
||||||
|
|
||||||
|
# Test with file:// URL (no auth needed)
|
||||||
|
python3 -c "
|
||||||
|
from skill_seekers.mcp.source_manager import SourceManager
|
||||||
|
from skill_seekers.mcp.git_repo import GitConfigRepo
|
||||||
|
|
||||||
|
# Add source
|
||||||
|
sm = SourceManager()
|
||||||
|
sm.add_source(
|
||||||
|
name='example-team',
|
||||||
|
git_url='file://$(pwd)/configs/example-team',
|
||||||
|
branch='main'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Clone and fetch config
|
||||||
|
gr = GitConfigRepo()
|
||||||
|
repo_path = gr.clone_or_pull('example-team', 'file://$(pwd)/configs/example-team')
|
||||||
|
config = gr.get_config(repo_path, 'react-custom')
|
||||||
|
print(f'✅ Loaded config: {config[\"name\"]}')
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
This is just an example! Create your own team repo with:
|
||||||
|
- Your team's custom selectors
|
||||||
|
- Internal documentation configs
|
||||||
|
- Company-specific configurations
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [GIT_CONFIG_SOURCES.md](../../docs/GIT_CONFIG_SOURCES.md) - Complete guide
|
||||||
|
- [MCP_SETUP.md](../../docs/MCP_SETUP.md) - MCP server setup
|
||||||
|
- [README.md](../../README.md) - Main documentation
|
||||||
42
configs/example-team/company-api.json
Normal file
42
configs/example-team/company-api.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "company-api",
|
||||||
|
"description": "Internal company API documentation (example)",
|
||||||
|
"base_url": "https://docs.example.com/api/",
|
||||||
|
"selectors": {
|
||||||
|
"main_content": "div.documentation",
|
||||||
|
"title": "h1.page-title",
|
||||||
|
"code_blocks": "pre.highlight"
|
||||||
|
},
|
||||||
|
"url_patterns": {
|
||||||
|
"include": [
|
||||||
|
"/api/v2"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"/api/v1",
|
||||||
|
"/changelog",
|
||||||
|
"/deprecated"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"categories": {
|
||||||
|
"authentication": ["api/v2/auth", "api/v2/oauth"],
|
||||||
|
"users": ["api/v2/users"],
|
||||||
|
"payments": ["api/v2/payments", "api/v2/billing"],
|
||||||
|
"webhooks": ["api/v2/webhooks"],
|
||||||
|
"rate_limits": ["api/v2/rate-limits"]
|
||||||
|
},
|
||||||
|
"rate_limit": 1.0,
|
||||||
|
"max_pages": 100,
|
||||||
|
"metadata": {
|
||||||
|
"team": "platform",
|
||||||
|
"api_version": "v2",
|
||||||
|
"last_updated": "2025-12-21",
|
||||||
|
"maintainer": "platform-team@example.com",
|
||||||
|
"internal": true,
|
||||||
|
"notes": "Only includes v2 API - v1 is deprecated. Requires VPN access to docs.example.com",
|
||||||
|
"example_urls": [
|
||||||
|
"https://docs.example.com/api/v2/auth/oauth",
|
||||||
|
"https://docs.example.com/api/v2/users/create",
|
||||||
|
"https://docs.example.com/api/v2/payments/charge"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
35
configs/example-team/react-custom.json
Normal file
35
configs/example-team/react-custom.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "react-custom",
|
||||||
|
"description": "Custom React config for team with modified selectors",
|
||||||
|
"base_url": "https://react.dev/",
|
||||||
|
"selectors": {
|
||||||
|
"main_content": "article",
|
||||||
|
"title": "h1",
|
||||||
|
"code_blocks": "pre code"
|
||||||
|
},
|
||||||
|
"url_patterns": {
|
||||||
|
"include": [
|
||||||
|
"/learn",
|
||||||
|
"/reference"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"/blog",
|
||||||
|
"/community",
|
||||||
|
"/_next/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"categories": {
|
||||||
|
"getting_started": ["learn/start", "learn/installation"],
|
||||||
|
"hooks": ["reference/react/hooks", "learn/state"],
|
||||||
|
"components": ["reference/react/components"],
|
||||||
|
"api": ["reference/react-dom"]
|
||||||
|
},
|
||||||
|
"rate_limit": 0.5,
|
||||||
|
"max_pages": 300,
|
||||||
|
"metadata": {
|
||||||
|
"team": "frontend",
|
||||||
|
"last_updated": "2025-12-21",
|
||||||
|
"maintainer": "team-lead@example.com",
|
||||||
|
"notes": "Excludes blog and community pages to focus on technical docs"
|
||||||
|
}
|
||||||
|
}
|
||||||
131
configs/example-team/test_e2e.py
Normal file
131
configs/example-team/test_e2e.py
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
E2E Test Script for Example Team Config Repository
|
||||||
|
|
||||||
|
Tests the complete workflow:
|
||||||
|
1. Register the example-team source
|
||||||
|
2. Fetch a config from it
|
||||||
|
3. Verify the config was loaded correctly
|
||||||
|
4. Clean up
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Add parent directory to path
|
||||||
|
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
||||||
|
|
||||||
|
from skill_seekers.mcp.source_manager import SourceManager
|
||||||
|
from skill_seekers.mcp.git_repo import GitConfigRepo
|
||||||
|
|
||||||
|
|
||||||
|
def test_example_team_repo():
|
||||||
|
"""Test the example-team repository end-to-end."""
|
||||||
|
print("🧪 E2E Test: Example Team Config Repository\n")
|
||||||
|
|
||||||
|
# Get absolute path to example-team directory
|
||||||
|
example_team_path = Path(__file__).parent.absolute()
|
||||||
|
git_url = f"file://{example_team_path}"
|
||||||
|
|
||||||
|
print(f"📁 Repository: {git_url}\n")
|
||||||
|
|
||||||
|
# Step 1: Add source
|
||||||
|
print("1️⃣ Registering source...")
|
||||||
|
sm = SourceManager()
|
||||||
|
try:
|
||||||
|
source = sm.add_source(
|
||||||
|
name="example-team-test",
|
||||||
|
git_url=git_url,
|
||||||
|
source_type="custom",
|
||||||
|
branch="master" # Git init creates 'master' by default
|
||||||
|
)
|
||||||
|
print(f" ✅ Source registered: {source['name']}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ Failed to register source: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Step 2: Clone/pull repository
|
||||||
|
print("\n2️⃣ Cloning repository...")
|
||||||
|
gr = GitConfigRepo()
|
||||||
|
try:
|
||||||
|
repo_path = gr.clone_or_pull(
|
||||||
|
source_name="example-team-test",
|
||||||
|
git_url=git_url,
|
||||||
|
branch="master"
|
||||||
|
)
|
||||||
|
print(f" ✅ Repository cloned to: {repo_path}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ Failed to clone repository: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Step 3: List available configs
|
||||||
|
print("\n3️⃣ Discovering configs...")
|
||||||
|
try:
|
||||||
|
configs = gr.find_configs(repo_path)
|
||||||
|
print(f" ✅ Found {len(configs)} configs:")
|
||||||
|
for config_file in configs:
|
||||||
|
print(f" - {config_file.name}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ Failed to discover configs: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Step 4: Fetch a specific config
|
||||||
|
print("\n4️⃣ Fetching 'react-custom' config...")
|
||||||
|
try:
|
||||||
|
config = gr.get_config(repo_path, "react-custom")
|
||||||
|
print(f" ✅ Config loaded successfully!")
|
||||||
|
print(f" Name: {config['name']}")
|
||||||
|
print(f" Description: {config['description']}")
|
||||||
|
print(f" Base URL: {config['base_url']}")
|
||||||
|
print(f" Max Pages: {config['max_pages']}")
|
||||||
|
if 'metadata' in config:
|
||||||
|
print(f" Team: {config['metadata'].get('team', 'N/A')}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ Failed to fetch config: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Step 5: Verify config content
|
||||||
|
print("\n5️⃣ Verifying config content...")
|
||||||
|
try:
|
||||||
|
assert config['name'] == 'react-custom', "Config name mismatch"
|
||||||
|
assert 'selectors' in config, "Missing selectors"
|
||||||
|
assert 'url_patterns' in config, "Missing url_patterns"
|
||||||
|
assert 'categories' in config, "Missing categories"
|
||||||
|
print(" ✅ Config structure validated")
|
||||||
|
except AssertionError as e:
|
||||||
|
print(f" ❌ Validation failed: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Step 6: List all sources
|
||||||
|
print("\n6️⃣ Listing all sources...")
|
||||||
|
try:
|
||||||
|
sources = sm.list_sources()
|
||||||
|
print(f" ✅ Total sources: {len(sources)}")
|
||||||
|
for src in sources:
|
||||||
|
print(f" - {src['name']} ({src['type']})")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ Failed to list sources: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Step 7: Clean up
|
||||||
|
print("\n7️⃣ Cleaning up...")
|
||||||
|
try:
|
||||||
|
removed = sm.remove_source("example-team-test")
|
||||||
|
if removed:
|
||||||
|
print(" ✅ Source removed successfully")
|
||||||
|
else:
|
||||||
|
print(" ⚠️ Source was not found (already removed?)")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ Failed to remove source: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
print("\n" + "="*60)
|
||||||
|
print("✅ E2E TEST PASSED - All steps completed successfully!")
|
||||||
|
print("="*60)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
success = test_example_team_repo()
|
||||||
|
sys.exit(0 if success else 1)
|
||||||
36
configs/example-team/vue-internal.json
Normal file
36
configs/example-team/vue-internal.json
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "vue-internal",
|
||||||
|
"description": "Vue.js config for internal team documentation",
|
||||||
|
"base_url": "https://vuejs.org/",
|
||||||
|
"selectors": {
|
||||||
|
"main_content": "main",
|
||||||
|
"title": "h1",
|
||||||
|
"code_blocks": "pre"
|
||||||
|
},
|
||||||
|
"url_patterns": {
|
||||||
|
"include": [
|
||||||
|
"/guide",
|
||||||
|
"/api"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"/examples",
|
||||||
|
"/sponsor"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"categories": {
|
||||||
|
"essentials": ["guide/essentials", "guide/introduction"],
|
||||||
|
"components": ["guide/components"],
|
||||||
|
"reactivity": ["guide/extras/reactivity"],
|
||||||
|
"composition_api": ["api/composition-api"],
|
||||||
|
"options_api": ["api/options-api"]
|
||||||
|
},
|
||||||
|
"rate_limit": 0.3,
|
||||||
|
"max_pages": 200,
|
||||||
|
"metadata": {
|
||||||
|
"team": "frontend",
|
||||||
|
"version": "Vue 3",
|
||||||
|
"last_updated": "2025-12-21",
|
||||||
|
"maintainer": "vue-team@example.com",
|
||||||
|
"notes": "Focuses on Vue 3 Composition API for our projects"
|
||||||
|
}
|
||||||
|
}
|
||||||
921
docs/GIT_CONFIG_SOURCES.md
Normal file
921
docs/GIT_CONFIG_SOURCES.md
Normal file
@@ -0,0 +1,921 @@
|
|||||||
|
# Git-Based Config Sources - Complete Guide
|
||||||
|
|
||||||
|
**Version:** v2.2.0
|
||||||
|
**Feature:** A1.9 - Multi-Source Git Repository Support
|
||||||
|
**Last Updated:** December 21, 2025
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Overview](#overview)
|
||||||
|
- [Quick Start](#quick-start)
|
||||||
|
- [Architecture](#architecture)
|
||||||
|
- [MCP Tools Reference](#mcp-tools-reference)
|
||||||
|
- [Authentication](#authentication)
|
||||||
|
- [Use Cases](#use-cases)
|
||||||
|
- [Best Practices](#best-practices)
|
||||||
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
- [Advanced Topics](#advanced-topics)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
### What is this feature?
|
||||||
|
|
||||||
|
Git-based config sources allow you to fetch config files from **private/team git repositories** in addition to the public API. This unlocks:
|
||||||
|
|
||||||
|
- 🔐 **Private configs** - Company/internal documentation
|
||||||
|
- 👥 **Team collaboration** - Share configs across 3-5 person teams
|
||||||
|
- 🏢 **Enterprise scale** - Support 500+ developers
|
||||||
|
- 📦 **Custom collections** - Curated config repositories
|
||||||
|
- 🌐 **Decentralized** - Like npm (public + private registries)
|
||||||
|
|
||||||
|
### How it works
|
||||||
|
|
||||||
|
```
|
||||||
|
User → fetch_config(source="team", config_name="react-custom")
|
||||||
|
↓
|
||||||
|
SourceManager (~/.skill-seekers/sources.json)
|
||||||
|
↓
|
||||||
|
GitConfigRepo (clone/pull with GitPython)
|
||||||
|
↓
|
||||||
|
Local cache (~/.skill-seekers/cache/team/)
|
||||||
|
↓
|
||||||
|
Config JSON returned
|
||||||
|
```
|
||||||
|
|
||||||
|
### Three modes
|
||||||
|
|
||||||
|
1. **API Mode** (existing, unchanged)
|
||||||
|
- `fetch_config(config_name="react")`
|
||||||
|
- Fetches from api.skillseekersweb.com
|
||||||
|
|
||||||
|
2. **Source Mode** (NEW - recommended)
|
||||||
|
- `fetch_config(source="team", config_name="react-custom")`
|
||||||
|
- Uses registered git source
|
||||||
|
|
||||||
|
3. **Git URL Mode** (NEW - one-time)
|
||||||
|
- `fetch_config(git_url="https://...", config_name="react-custom")`
|
||||||
|
- Direct clone without registration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### 1. Set up authentication
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# GitHub
|
||||||
|
export GITHUB_TOKEN=ghp_your_token_here
|
||||||
|
|
||||||
|
# GitLab
|
||||||
|
export GITLAB_TOKEN=glpat_your_token_here
|
||||||
|
|
||||||
|
# Bitbucket
|
||||||
|
export BITBUCKET_TOKEN=your_token_here
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Register a source
|
||||||
|
|
||||||
|
Using MCP tools (recommended):
|
||||||
|
|
||||||
|
```python
|
||||||
|
add_config_source(
|
||||||
|
name="team",
|
||||||
|
git_url="https://github.com/mycompany/skill-configs.git",
|
||||||
|
source_type="github", # Optional, auto-detected
|
||||||
|
token_env="GITHUB_TOKEN", # Optional, auto-detected
|
||||||
|
branch="main", # Optional, default: "main"
|
||||||
|
priority=100 # Optional, lower = higher priority
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Fetch configs
|
||||||
|
|
||||||
|
```python
|
||||||
|
# From registered source
|
||||||
|
fetch_config(source="team", config_name="react-custom")
|
||||||
|
|
||||||
|
# List available sources
|
||||||
|
list_config_sources()
|
||||||
|
|
||||||
|
# Remove when done
|
||||||
|
remove_config_source(name="team")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Quick test with example repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/Skill_Seekers
|
||||||
|
|
||||||
|
# Run E2E test
|
||||||
|
python3 configs/example-team/test_e2e.py
|
||||||
|
|
||||||
|
# Or test manually
|
||||||
|
add_config_source(
|
||||||
|
name="example",
|
||||||
|
git_url="file://$(pwd)/configs/example-team",
|
||||||
|
branch="master"
|
||||||
|
)
|
||||||
|
|
||||||
|
fetch_config(source="example", config_name="react-custom")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Storage Locations
|
||||||
|
|
||||||
|
**Sources Registry:**
|
||||||
|
```
|
||||||
|
~/.skill-seekers/sources.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Example content:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"version": "1.0",
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"name": "team",
|
||||||
|
"git_url": "https://github.com/myorg/configs.git",
|
||||||
|
"type": "github",
|
||||||
|
"token_env": "GITHUB_TOKEN",
|
||||||
|
"branch": "main",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"added_at": "2025-12-21T10:00:00Z",
|
||||||
|
"updated_at": "2025-12-21T10:00:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Cache Directory:**
|
||||||
|
```
|
||||||
|
$SKILL_SEEKERS_CACHE_DIR (default: ~/.skill-seekers/cache/)
|
||||||
|
```
|
||||||
|
|
||||||
|
Structure:
|
||||||
|
```
|
||||||
|
~/.skill-seekers/
|
||||||
|
├── sources.json # Source registry
|
||||||
|
└── cache/ # Git clones
|
||||||
|
├── team/ # One directory per source
|
||||||
|
│ ├── .git/
|
||||||
|
│ ├── react-custom.json
|
||||||
|
│ └── vue-internal.json
|
||||||
|
└── company/
|
||||||
|
├── .git/
|
||||||
|
└── internal-api.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Git Strategy
|
||||||
|
|
||||||
|
- **Shallow clone**: `git clone --depth 1 --single-branch`
|
||||||
|
- 10-50x faster
|
||||||
|
- Minimal disk space
|
||||||
|
- No history, just latest commit
|
||||||
|
|
||||||
|
- **Auto-pull**: Updates cache automatically
|
||||||
|
- Checks for changes on each fetch
|
||||||
|
- Use `refresh=true` to force re-clone
|
||||||
|
|
||||||
|
- **Config discovery**: Recursively scans for `*.json` files
|
||||||
|
- No hardcoded paths
|
||||||
|
- Flexible repository structure
|
||||||
|
- Excludes `.git` directory
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MCP Tools Reference
|
||||||
|
|
||||||
|
### add_config_source
|
||||||
|
|
||||||
|
Register a git repository as a config source.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `name` (required): Source identifier (lowercase, alphanumeric, hyphens/underscores)
|
||||||
|
- `git_url` (required): Git repository URL (HTTPS or SSH)
|
||||||
|
- `source_type` (optional): "github", "gitlab", "gitea", "bitbucket", "custom" (auto-detected from URL)
|
||||||
|
- `token_env` (optional): Environment variable name for token (auto-detected from type)
|
||||||
|
- `branch` (optional): Git branch (default: "main")
|
||||||
|
- `priority` (optional): Priority number (default: 100, lower = higher priority)
|
||||||
|
- `enabled` (optional): Whether source is active (default: true)
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- Source details including registration timestamp
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Minimal (auto-detects everything)
|
||||||
|
add_config_source(
|
||||||
|
name="team",
|
||||||
|
git_url="https://github.com/myorg/configs.git"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Full parameters
|
||||||
|
add_config_source(
|
||||||
|
name="company",
|
||||||
|
git_url="https://gitlab.company.com/platform/configs.git",
|
||||||
|
source_type="gitlab",
|
||||||
|
token_env="GITLAB_COMPANY_TOKEN",
|
||||||
|
branch="develop",
|
||||||
|
priority=1,
|
||||||
|
enabled=true
|
||||||
|
)
|
||||||
|
|
||||||
|
# SSH URL (auto-converts to HTTPS with token)
|
||||||
|
add_config_source(
|
||||||
|
name="team",
|
||||||
|
git_url="git@github.com:myorg/configs.git",
|
||||||
|
token_env="GITHUB_TOKEN"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### list_config_sources
|
||||||
|
|
||||||
|
List all registered config sources.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `enabled_only` (optional): Only show enabled sources (default: false)
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- List of sources sorted by priority
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```python
|
||||||
|
# List all sources
|
||||||
|
list_config_sources()
|
||||||
|
|
||||||
|
# List only enabled sources
|
||||||
|
list_config_sources(enabled_only=true)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output:**
|
||||||
|
```
|
||||||
|
📋 Config Sources (2 total)
|
||||||
|
|
||||||
|
✓ **team**
|
||||||
|
📁 https://github.com/myorg/configs.git
|
||||||
|
🔖 Type: github | 🌿 Branch: main
|
||||||
|
🔑 Token: GITHUB_TOKEN | ⚡ Priority: 1
|
||||||
|
🕒 Added: 2025-12-21 10:00:00
|
||||||
|
|
||||||
|
✓ **company**
|
||||||
|
📁 https://gitlab.company.com/configs.git
|
||||||
|
🔖 Type: gitlab | 🌿 Branch: develop
|
||||||
|
🔑 Token: GITLAB_TOKEN | ⚡ Priority: 2
|
||||||
|
🕒 Added: 2025-12-21 11:00:00
|
||||||
|
```
|
||||||
|
|
||||||
|
### remove_config_source
|
||||||
|
|
||||||
|
Remove a registered config source.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `name` (required): Source identifier
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- Success/failure message
|
||||||
|
|
||||||
|
**Note:** Does NOT delete cached git repository data. To free disk space, manually delete `~/.skill-seekers/cache/{source_name}/`
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```python
|
||||||
|
remove_config_source(name="team")
|
||||||
|
```
|
||||||
|
|
||||||
|
### fetch_config
|
||||||
|
|
||||||
|
Fetch config from API, git URL, or named source.
|
||||||
|
|
||||||
|
**Mode 1: Named Source (highest priority)**
|
||||||
|
|
||||||
|
```python
|
||||||
|
fetch_config(
|
||||||
|
source="team", # Use registered source
|
||||||
|
config_name="react-custom",
|
||||||
|
destination="configs/", # Optional
|
||||||
|
branch="main", # Optional, overrides source default
|
||||||
|
refresh=false # Optional, force re-clone
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Mode 2: Direct Git URL**
|
||||||
|
|
||||||
|
```python
|
||||||
|
fetch_config(
|
||||||
|
git_url="https://github.com/myorg/configs.git",
|
||||||
|
config_name="react-custom",
|
||||||
|
branch="main", # Optional
|
||||||
|
token="ghp_token", # Optional, prefer env vars
|
||||||
|
destination="configs/", # Optional
|
||||||
|
refresh=false # Optional
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Mode 3: API (existing, unchanged)**
|
||||||
|
|
||||||
|
```python
|
||||||
|
fetch_config(
|
||||||
|
config_name="react",
|
||||||
|
destination="configs/" # Optional
|
||||||
|
)
|
||||||
|
|
||||||
|
# Or list available
|
||||||
|
fetch_config(list_available=true)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
### Environment Variables Only
|
||||||
|
|
||||||
|
Tokens are **ONLY** stored in environment variables. This is:
|
||||||
|
- ✅ **Secure** - Not in files, not in git
|
||||||
|
- ✅ **Standard** - Same as GitHub CLI, Docker, etc.
|
||||||
|
- ✅ **Temporary** - Cleared on logout
|
||||||
|
- ✅ **Flexible** - Different tokens for different services
|
||||||
|
|
||||||
|
### Creating Tokens
|
||||||
|
|
||||||
|
**GitHub:**
|
||||||
|
1. Go to https://github.com/settings/tokens
|
||||||
|
2. Generate new token (classic)
|
||||||
|
3. Select scopes: `repo` (for private repos)
|
||||||
|
4. Copy token: `ghp_xxxxxxxxxxxxx`
|
||||||
|
5. Export: `export GITHUB_TOKEN=ghp_xxxxxxxxxxxxx`
|
||||||
|
|
||||||
|
**GitLab:**
|
||||||
|
1. Go to https://gitlab.com/-/profile/personal_access_tokens
|
||||||
|
2. Create token with `read_repository` scope
|
||||||
|
3. Copy token: `glpat-xxxxxxxxxxxxx`
|
||||||
|
4. Export: `export GITLAB_TOKEN=glpat-xxxxxxxxxxxxx`
|
||||||
|
|
||||||
|
**Bitbucket:**
|
||||||
|
1. Go to https://bitbucket.org/account/settings/app-passwords/
|
||||||
|
2. Create app password with `Repositories: Read` permission
|
||||||
|
3. Copy password
|
||||||
|
4. Export: `export BITBUCKET_TOKEN=your_password`
|
||||||
|
|
||||||
|
### Persistent Tokens
|
||||||
|
|
||||||
|
Add to your shell profile (`~/.bashrc`, `~/.zshrc`, etc.):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# GitHub token
|
||||||
|
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxx
|
||||||
|
|
||||||
|
# GitLab token
|
||||||
|
export GITLAB_TOKEN=glpat-xxxxxxxxxxxxx
|
||||||
|
|
||||||
|
# Company GitLab (separate token)
|
||||||
|
export GITLAB_COMPANY_TOKEN=glpat-yyyyyyyyyyyyy
|
||||||
|
```
|
||||||
|
|
||||||
|
Then: `source ~/.bashrc`
|
||||||
|
|
||||||
|
### Token Injection
|
||||||
|
|
||||||
|
GitConfigRepo automatically:
|
||||||
|
1. Converts SSH URLs to HTTPS
|
||||||
|
2. Injects token into URL
|
||||||
|
3. Uses token for authentication
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
- Input: `git@github.com:myorg/repo.git` + token `ghp_xxx`
|
||||||
|
- Output: `https://ghp_xxx@github.com/myorg/repo.git`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
### Small Team (3-5 people)
|
||||||
|
|
||||||
|
**Scenario:** Frontend team needs custom React configs for internal docs.
|
||||||
|
|
||||||
|
**Setup:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Team lead creates repo
|
||||||
|
gh repo create myteam/skill-configs --private
|
||||||
|
|
||||||
|
# 2. Add configs
|
||||||
|
cd myteam-skill-configs
|
||||||
|
cp ../Skill_Seekers/configs/react.json ./react-internal.json
|
||||||
|
|
||||||
|
# Edit for internal docs:
|
||||||
|
# - Change base_url to internal docs site
|
||||||
|
# - Adjust selectors for company theme
|
||||||
|
# - Customize categories
|
||||||
|
|
||||||
|
git add . && git commit -m "Add internal React config" && git push
|
||||||
|
|
||||||
|
# 3. Team members register (one-time)
|
||||||
|
export GITHUB_TOKEN=ghp_their_token
|
||||||
|
add_config_source(
|
||||||
|
name="team",
|
||||||
|
git_url="https://github.com/myteam/skill-configs.git"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4. Daily usage
|
||||||
|
fetch_config(source="team", config_name="react-internal")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- ✅ Shared configs across team
|
||||||
|
- ✅ Version controlled
|
||||||
|
- ✅ Private to company
|
||||||
|
- ✅ Easy updates (git push)
|
||||||
|
|
||||||
|
### Enterprise (500+ developers)
|
||||||
|
|
||||||
|
**Scenario:** Large company with multiple teams, internal docs, and priority-based config resolution.
|
||||||
|
|
||||||
|
**Setup:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# IT pre-configures sources for all developers
|
||||||
|
# (via company setup script or documentation)
|
||||||
|
|
||||||
|
# 1. Platform team configs (highest priority)
|
||||||
|
add_config_source(
|
||||||
|
name="platform",
|
||||||
|
git_url="https://gitlab.company.com/platform/skill-configs.git",
|
||||||
|
source_type="gitlab",
|
||||||
|
token_env="GITLAB_COMPANY_TOKEN",
|
||||||
|
priority=1
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2. Mobile team configs
|
||||||
|
add_config_source(
|
||||||
|
name="mobile",
|
||||||
|
git_url="https://gitlab.company.com/mobile/skill-configs.git",
|
||||||
|
source_type="gitlab",
|
||||||
|
token_env="GITLAB_COMPANY_TOKEN",
|
||||||
|
priority=2
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3. Public/official configs (fallback)
|
||||||
|
# (API mode, no registration needed, lowest priority)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Developer usage:**
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Automatically finds config with highest priority
|
||||||
|
fetch_config(config_name="platform-api") # Found in platform source
|
||||||
|
fetch_config(config_name="react-native") # Found in mobile source
|
||||||
|
fetch_config(config_name="react") # Falls back to public API
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- ✅ Centralized config management
|
||||||
|
- ✅ Team-specific overrides
|
||||||
|
- ✅ Fallback to public configs
|
||||||
|
- ✅ Priority-based resolution
|
||||||
|
- ✅ Scales to hundreds of developers
|
||||||
|
|
||||||
|
### Open Source Project
|
||||||
|
|
||||||
|
**Scenario:** Open source project wants curated configs for contributors.
|
||||||
|
|
||||||
|
**Setup:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Create public repo
|
||||||
|
gh repo create myproject/skill-configs --public
|
||||||
|
|
||||||
|
# 2. Add configs for project stack
|
||||||
|
- react.json (frontend)
|
||||||
|
- django.json (backend)
|
||||||
|
- postgres.json (database)
|
||||||
|
- nginx.json (deployment)
|
||||||
|
|
||||||
|
# 3. Contributors use directly (no token needed for public repos)
|
||||||
|
add_config_source(
|
||||||
|
name="myproject",
|
||||||
|
git_url="https://github.com/myproject/skill-configs.git"
|
||||||
|
)
|
||||||
|
|
||||||
|
fetch_config(source="myproject", config_name="react")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- ✅ Curated configs for project
|
||||||
|
- ✅ No API dependency
|
||||||
|
- ✅ Community contributions via PR
|
||||||
|
- ✅ Version controlled
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### Config Naming
|
||||||
|
|
||||||
|
**Good:**
|
||||||
|
- `react-internal.json` - Clear purpose
|
||||||
|
- `api-v2.json` - Version included
|
||||||
|
- `platform-auth.json` - Specific topic
|
||||||
|
|
||||||
|
**Bad:**
|
||||||
|
- `config1.json` - Generic
|
||||||
|
- `react.json` - Conflicts with official
|
||||||
|
- `test.json` - Not descriptive
|
||||||
|
|
||||||
|
### Repository Structure
|
||||||
|
|
||||||
|
**Flat (recommended for small repos):**
|
||||||
|
```
|
||||||
|
skill-configs/
|
||||||
|
├── README.md
|
||||||
|
├── react-internal.json
|
||||||
|
├── vue-internal.json
|
||||||
|
└── api-v2.json
|
||||||
|
```
|
||||||
|
|
||||||
|
**Organized (recommended for large repos):**
|
||||||
|
```
|
||||||
|
skill-configs/
|
||||||
|
├── README.md
|
||||||
|
├── frontend/
|
||||||
|
│ ├── react-internal.json
|
||||||
|
│ └── vue-internal.json
|
||||||
|
├── backend/
|
||||||
|
│ ├── django-api.json
|
||||||
|
│ └── fastapi-platform.json
|
||||||
|
└── mobile/
|
||||||
|
├── react-native.json
|
||||||
|
└── flutter.json
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Config discovery works recursively, so both structures work!
|
||||||
|
|
||||||
|
### Source Priorities
|
||||||
|
|
||||||
|
Lower number = higher priority. Use sensible defaults:
|
||||||
|
|
||||||
|
- `1-10`: Critical/override configs
|
||||||
|
- `50-100`: Team configs (default: 100)
|
||||||
|
- `1000+`: Fallback/experimental
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```python
|
||||||
|
# Override official React config with internal version
|
||||||
|
add_config_source(name="team", ..., priority=1) # Checked first
|
||||||
|
# Official API is checked last (priority: infinity)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
✅ **DO:**
|
||||||
|
- Use environment variables for tokens
|
||||||
|
- Use private repos for sensitive configs
|
||||||
|
- Rotate tokens regularly
|
||||||
|
- Use fine-grained tokens (read-only if possible)
|
||||||
|
|
||||||
|
❌ **DON'T:**
|
||||||
|
- Commit tokens to git
|
||||||
|
- Share tokens between people
|
||||||
|
- Use personal tokens for teams (use service accounts)
|
||||||
|
- Store tokens in config files
|
||||||
|
|
||||||
|
### Maintenance
|
||||||
|
|
||||||
|
**Regular tasks:**
|
||||||
|
```bash
|
||||||
|
# Update configs in repo
|
||||||
|
cd myteam-skill-configs
|
||||||
|
# Edit configs...
|
||||||
|
git commit -m "Update React config" && git push
|
||||||
|
|
||||||
|
# Developers get updates automatically on next fetch
|
||||||
|
fetch_config(source="team", config_name="react-internal")
|
||||||
|
# ^--- Auto-pulls latest changes
|
||||||
|
```
|
||||||
|
|
||||||
|
**Force refresh:**
|
||||||
|
```python
|
||||||
|
# Delete cache and re-clone
|
||||||
|
fetch_config(source="team", config_name="react-internal", refresh=true)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Clean up old sources:**
|
||||||
|
```bash
|
||||||
|
# Remove unused sources
|
||||||
|
remove_config_source(name="old-team")
|
||||||
|
|
||||||
|
# Free disk space
|
||||||
|
rm -rf ~/.skill-seekers/cache/old-team/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Authentication Failures
|
||||||
|
|
||||||
|
**Error:** "Authentication failed for https://github.com/org/repo.git"
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. Check token is set:
|
||||||
|
```bash
|
||||||
|
echo $GITHUB_TOKEN # Should show token
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Verify token has correct permissions:
|
||||||
|
- GitHub: `repo` scope for private repos
|
||||||
|
- GitLab: `read_repository` scope
|
||||||
|
|
||||||
|
3. Check token isn't expired:
|
||||||
|
- Regenerate if needed
|
||||||
|
|
||||||
|
4. Try direct access:
|
||||||
|
```bash
|
||||||
|
git clone https://$GITHUB_TOKEN@github.com/org/repo.git test-clone
|
||||||
|
```
|
||||||
|
|
||||||
|
### Config Not Found
|
||||||
|
|
||||||
|
**Error:** "Config 'react' not found in repository. Available configs: django, vue"
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. List available configs:
|
||||||
|
```python
|
||||||
|
# Shows what's actually in the repo
|
||||||
|
list_config_sources()
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Check config file exists in repo:
|
||||||
|
```bash
|
||||||
|
# Clone locally and inspect
|
||||||
|
git clone <git_url> temp-inspect
|
||||||
|
find temp-inspect -name "*.json"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Verify config name (case-insensitive):
|
||||||
|
- `react` matches `React.json` or `react.json`
|
||||||
|
|
||||||
|
### Slow Cloning
|
||||||
|
|
||||||
|
**Issue:** Repository takes minutes to clone.
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. Shallow clone is already enabled (depth=1)
|
||||||
|
|
||||||
|
2. Check repository size:
|
||||||
|
```bash
|
||||||
|
# See repo size
|
||||||
|
gh repo view owner/repo --json diskUsage
|
||||||
|
```
|
||||||
|
|
||||||
|
3. If very large (>100MB), consider:
|
||||||
|
- Splitting configs into separate repos
|
||||||
|
- Using sparse checkout
|
||||||
|
- Contacting IT to optimize repo
|
||||||
|
|
||||||
|
### Cache Issues
|
||||||
|
|
||||||
|
**Issue:** Getting old configs even after updating repo.
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. Force refresh:
|
||||||
|
```python
|
||||||
|
fetch_config(source="team", config_name="react", refresh=true)
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Manual cache clear:
|
||||||
|
```bash
|
||||||
|
rm -rf ~/.skill-seekers/cache/team/
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Check auto-pull worked:
|
||||||
|
```bash
|
||||||
|
cd ~/.skill-seekers/cache/team
|
||||||
|
git log -1 # Shows latest commit
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Advanced Topics
|
||||||
|
|
||||||
|
### Multiple Git Accounts
|
||||||
|
|
||||||
|
Use different tokens for different repos:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Personal GitHub
|
||||||
|
export GITHUB_TOKEN=ghp_personal_xxx
|
||||||
|
|
||||||
|
# Work GitHub
|
||||||
|
export GITHUB_WORK_TOKEN=ghp_work_yyy
|
||||||
|
|
||||||
|
# Company GitLab
|
||||||
|
export GITLAB_COMPANY_TOKEN=glpat-zzz
|
||||||
|
```
|
||||||
|
|
||||||
|
Register with specific tokens:
|
||||||
|
```python
|
||||||
|
add_config_source(
|
||||||
|
name="personal",
|
||||||
|
git_url="https://github.com/myuser/configs.git",
|
||||||
|
token_env="GITHUB_TOKEN"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_config_source(
|
||||||
|
name="work",
|
||||||
|
git_url="https://github.com/mycompany/configs.git",
|
||||||
|
token_env="GITHUB_WORK_TOKEN"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Cache Location
|
||||||
|
|
||||||
|
Set custom cache directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export SKILL_SEEKERS_CACHE_DIR=/mnt/large-disk/skill-seekers-cache
|
||||||
|
```
|
||||||
|
|
||||||
|
Or pass to GitConfigRepo:
|
||||||
|
```python
|
||||||
|
from skill_seekers.mcp.git_repo import GitConfigRepo
|
||||||
|
|
||||||
|
gr = GitConfigRepo(cache_dir="/custom/path/cache")
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSH URLs
|
||||||
|
|
||||||
|
SSH URLs are automatically converted to HTTPS + token:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Input
|
||||||
|
add_config_source(
|
||||||
|
name="team",
|
||||||
|
git_url="git@github.com:myorg/configs.git",
|
||||||
|
token_env="GITHUB_TOKEN"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Internally becomes
|
||||||
|
# https://ghp_xxx@github.com/myorg/configs.git
|
||||||
|
```
|
||||||
|
|
||||||
|
### Priority Resolution
|
||||||
|
|
||||||
|
When same config exists in multiple sources:
|
||||||
|
|
||||||
|
```python
|
||||||
|
add_config_source(name="team", ..., priority=1) # Checked first
|
||||||
|
add_config_source(name="company", ..., priority=2) # Checked second
|
||||||
|
# API mode is checked last (priority: infinity)
|
||||||
|
|
||||||
|
fetch_config(config_name="react")
|
||||||
|
# 1. Checks team source
|
||||||
|
# 2. If not found, checks company source
|
||||||
|
# 3. If not found, falls back to API
|
||||||
|
```
|
||||||
|
|
||||||
|
### CI/CD Integration
|
||||||
|
|
||||||
|
Use in GitHub Actions:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Generate Skills
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install Skill Seekers
|
||||||
|
run: pip install skill-seekers
|
||||||
|
|
||||||
|
- name: Register config source
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
python3 << EOF
|
||||||
|
from skill_seekers.mcp.source_manager import SourceManager
|
||||||
|
sm = SourceManager()
|
||||||
|
sm.add_source(
|
||||||
|
name="team",
|
||||||
|
git_url="https://github.com/myorg/configs.git"
|
||||||
|
)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Fetch and use config
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
# Use MCP fetch_config or direct Python
|
||||||
|
skill-seekers scrape --config <fetched_config>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### GitConfigRepo Class
|
||||||
|
|
||||||
|
**Location:** `src/skill_seekers/mcp/git_repo.py`
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
|
||||||
|
```python
|
||||||
|
def __init__(cache_dir: Optional[str] = None)
|
||||||
|
"""Initialize with optional cache directory."""
|
||||||
|
|
||||||
|
def clone_or_pull(
|
||||||
|
source_name: str,
|
||||||
|
git_url: str,
|
||||||
|
branch: str = "main",
|
||||||
|
token: Optional[str] = None,
|
||||||
|
force_refresh: bool = False
|
||||||
|
) -> Path:
|
||||||
|
"""Clone if not cached, else pull latest changes."""
|
||||||
|
|
||||||
|
def find_configs(repo_path: Path) -> list[Path]:
|
||||||
|
"""Find all *.json files in repository."""
|
||||||
|
|
||||||
|
def get_config(repo_path: Path, config_name: str) -> dict:
|
||||||
|
"""Load specific config by name."""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def inject_token(git_url: str, token: str) -> str:
|
||||||
|
"""Inject token into git URL."""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_git_url(git_url: str) -> bool:
|
||||||
|
"""Validate git URL format."""
|
||||||
|
```
|
||||||
|
|
||||||
|
### SourceManager Class
|
||||||
|
|
||||||
|
**Location:** `src/skill_seekers/mcp/source_manager.py`
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
|
||||||
|
```python
|
||||||
|
def __init__(config_dir: Optional[str] = None)
|
||||||
|
"""Initialize with optional config directory."""
|
||||||
|
|
||||||
|
def add_source(
|
||||||
|
name: str,
|
||||||
|
git_url: str,
|
||||||
|
source_type: str = "github",
|
||||||
|
token_env: Optional[str] = None,
|
||||||
|
branch: str = "main",
|
||||||
|
priority: int = 100,
|
||||||
|
enabled: bool = True
|
||||||
|
) -> dict:
|
||||||
|
"""Add or update config source."""
|
||||||
|
|
||||||
|
def get_source(name: str) -> dict:
|
||||||
|
"""Get source by name."""
|
||||||
|
|
||||||
|
def list_sources(enabled_only: bool = False) -> list[dict]:
|
||||||
|
"""List all sources."""
|
||||||
|
|
||||||
|
def remove_source(name: str) -> bool:
|
||||||
|
"""Remove source."""
|
||||||
|
|
||||||
|
def update_source(name: str, **kwargs) -> dict:
|
||||||
|
"""Update specific fields."""
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [README.md](../README.md) - Main documentation
|
||||||
|
- [MCP_SETUP.md](MCP_SETUP.md) - MCP server setup
|
||||||
|
- [UNIFIED_SCRAPING.md](UNIFIED_SCRAPING.md) - Multi-source scraping
|
||||||
|
- [configs/example-team/](../configs/example-team/) - Example repository
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
### v2.2.0 (2025-12-21)
|
||||||
|
- Initial release of git-based config sources
|
||||||
|
- 3 fetch modes: API, Git URL, Named Source
|
||||||
|
- 4 MCP tools: add/list/remove/fetch
|
||||||
|
- Support for GitHub, GitLab, Bitbucket, Gitea
|
||||||
|
- Shallow clone optimization
|
||||||
|
- Priority-based resolution
|
||||||
|
- 83 tests (100% passing)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Questions?** Open an issue at https://github.com/yusufkaraaslan/Skill_Seekers/issues
|
||||||
Reference in New Issue
Block a user