Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ All notable changes to Skilz CLI will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.9.0] - 2026-01-21

### Changed

- Documentation updates to match current feature set
- Updated USER_MANUAL.md from v1.6.0 to v1.9.0
- Fixed DEPLOY_PYPI.md version management documentation
- Updated key_facts.md with version management notes

### Documentation

- Added version management section to key_facts.md
- Corrected DEPLOY_PYPI.md to reflect dynamic versioning
- USER_MANUAL.md now documents 1.7 and 1.8 features:
- Gemini native support
- NEW/LEGACY/SLUG format support
- Universal agent custom config
- List command with Agent column
- `--all` flag for list command

## [1.8.0] - 2026-01-09

### Added
Expand Down
24 changes: 15 additions & 9 deletions docs/DEPLOY_PYPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Skilz uses a comprehensive multi-layer testing approach:
- [ ] `./scripts/end_to_end.sh` passes (full feature test)
- [ ] `./scripts/test_rest_marketplace_e2e.sh` passes (live API test)
- [ ] `./scripts/test_bug_fixes_e2e.sh` passes (regression test)
- [ ] Version updated in `src/skilz/__init__.py` and `pyproject.toml`
- [ ] Version updated in `pyproject.toml` (single source of truth)
- [ ] CHANGELOG.md updated with release notes
- [ ] GitHub release created and tagged

Expand Down Expand Up @@ -168,20 +168,26 @@ skilz --version

## Version Management

The version is defined in `src/skilz/__init__.py`:
**Single Source of Truth:** `pyproject.toml` (line 7)

```python
__version__ = "1.2.0" # Update to new version
```

And mirrored in `pyproject.toml`:
The version is defined ONLY in `pyproject.toml`:

```toml
[project]
version = "1.2.0" # Must match __init__.py
version = "1.9.0"
```

The Python package reads this dynamically at runtime via `importlib.metadata`:

```python
# src/skilz/__init__.py
from importlib.metadata import version
__version__ = version("skilz") # Reads from pyproject.toml
```

**Before releasing**, update both files to match.
**Before releasing**, only update `pyproject.toml`. No other files need version changes.

**Note:** Previous versions required updating both `pyproject.toml` AND `__init__.py`. This was fixed in 1.7 to use dynamic version detection, eliminating version sync issues.

## Taskfile Commands Reference

Expand Down
54 changes: 48 additions & 6 deletions docs/USER_MANUAL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Skilz User Manual

**Version 1.6.0**
**Version 1.9.0**

Skilz is the universal package manager for AI skills. It installs, manages, and updates skills across multiple AI coding assistants including Claude Code and OpenCode.

Expand Down Expand Up @@ -176,6 +176,39 @@ Already installed: anthropics_skills/theme-factory (00756142)

---

### NEW Marketplace Format (NEW in 1.7)

Skilz 1.7+ supports a new intuitive skill ID format that mirrors GitHub's URL structure:

**Supported Formats:**

| Format | Example | Description |
|--------|---------|-------------|
| **NEW** | `owner/repo/skill` | Intuitive GitHub-style format |
| **LEGACY** | `owner_repo/skill` | Original underscore format |
| **SLUG** | `owner__repo__skill` | Direct Firestore document ID |

**All formats are REST-first** - they try the skillzwave.ai REST API before falling back to GitHub.

**Examples:**

```bash
# NEW format (recommended)
skilz install anthropics/skills/algorithmic-art

# LEGACY format (backwards compatible)
skilz install anthropics_skills/algorithmic-art

# SLUG format (direct Firestore ID)
skilz install anthropics__skills__algorithmic-art

# Verbose mode shows format detection
skilz install anthropics/skills/algorithmic-art -v
# Output: Detected format: NEW, attempting REST lookup...
```

---

### Installing Local Skills

You can install skills directly from your local filesystem. This is useful for developing new skills or installing skills from other agent directories (like Claude or OpenCode).
Expand Down Expand Up @@ -803,11 +836,20 @@ Skilz supports multiple AI coding assistants. Use `--agent` to target a specific

| Agent | Skills Directory | Notes |
|-------|------------------|-------|
| `claude` | `~/.claude/skills/` (user) or `.claude/skills/` (project) | Native support |
| `gemini` | `~/.gemini/skills/` (user) or `.gemini/skills/` (project) | Native support (NEW in 1.7, requires plugin) |
| `codex` | `~/.codex/skills/` (user) or `.codex/skills/` (project) | Auto-detected from `.codex/` |
| `opencode` | `~/.config/opencode/skill/` (user) or `.opencode/skill/` (project) | Native support |
| `universal` | `~/.skilz/skills/` (user) or `.skilz/skills/` (project) | Supports custom config files (NEW in 1.7) |
| `claude` | `~/.claude/skills/` or `.claude/skills/` | Native support |
| `codex` | `~/.codex/skills/` or `.codex/skills/` | Native support |
| `opencode` | `~/.config/opencode/skill/` or `.opencode/skill/` | Native support |
| `gemini` | `~/.gemini/skills/` or `.gemini/skills/` | Native support (requires plugin) |
| `copilot` | `.github/skills/` | Project-level only |
| `cursor` | `.cursor/skills/` | Project-level only |
| `aider` | `~/.aider/skills/` | User-level |
| `windsurf` | `~/.windsurf/skills/` | User-level |
| `qwen` | `~/.qwen/skills/` | User-level |
| `kimi` | `~/.kimi/skills/` | User-level |
| `crush` | `~/.crush/skills/` | User-level |
| `plandex` | `~/.plandex/skills/` | User-level |
| `zed` | `~/.zed/skills/` | User-level |
| `universal` | `~/.skilz/skills/` or `.skilz/skills/` | Universal fallback |

**Auto-detection:**

Expand Down
39 changes: 32 additions & 7 deletions docs/project_notes/key_facts.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ task typecheck # Run mypy

---

## Version Management

**Single Source of Truth:** `pyproject.toml` line 7

| File | Role |
|------|------|
| `pyproject.toml` | Primary version definition (edit this one) |
| `src/skilz/__init__.py` | Dynamic detection via `importlib.metadata.version("skilz")` |

**Release Process:** Only update `pyproject.toml`. The Python module automatically reads the version from package metadata at runtime.

**Previous Bug (Fixed in 1.7):** Before dynamic detection, version was hardcoded in both files and they would get out of sync, causing `skilz --version` to show wrong version.

---

## Important Paths

| Path | Purpose |
Expand Down Expand Up @@ -109,13 +124,23 @@ Before any PR:

## Verification History

### 2025-01-08 - Instructions Verification
- ✅ Development setup completed successfully (`task install`)
- ✅ All 620 tests passing with 87% coverage (`task test`, `task coverage`)
- ✅ Code quality checks passing (lint, format, typecheck via `task check`)
- ✅ CLI functionality verified (`skilz --version`, `skilz --help`)
- ✅ Project is in production-ready state (v1.7.0)
### 2026-01-21 - v1.9.0 Pre-Release
- ✅ Version bumped to 1.9.0 in pyproject.toml
- ✅ Documentation updated (USER_MANUAL.md, DEPLOY_PYPI.md)
- ✅ CHANGELOG.md updated with 1.9.0 entry
- ✅ All tests passing
- ✅ Local build verified

### 2025-01-09 - v1.8.0 Release
- ✅ List command enhancements (Agent column, --all flag)
- ✅ CLI help discoverability improvements
- ✅ Visit command URL format fix

### 2025-01-08 - v1.7.0 Release
- ✅ Gemini CLI native support
- ✅ NEW/LEGACY/SLUG format support
- ✅ Universal agent custom config

---

*Last Updated: 2025-01-08*
*Last Updated: 2026-01-21*
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "skilz"
version = "1.8.0"
version = "1.9.0"
description = "The universal package manager for AI skills"
readme = "README.md"
license = "MIT"
Expand Down
16 changes: 8 additions & 8 deletions src/skilz/agent_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def _create_builtin_agents() -> dict[str, AgentConfig]:
name="aider",
display_name="Aider",
home_dir=None,
project_dir=Path(".skills") / "skills",
project_dir=Path(".skilz") / "skills",
config_files=("CONVENTIONS.md",),
supports_home=False,
default_mode="copy",
Expand All @@ -182,7 +182,7 @@ def _create_builtin_agents() -> dict[str, AgentConfig]:
name="cursor",
display_name="Cursor",
home_dir=None,
project_dir=Path(".skills") / "skills",
project_dir=Path(".skilz") / "skills",
config_files=(".cursor/rules/RULES.md", ".cursor/rules/RULE.md"),
supports_home=False,
default_mode="copy",
Expand All @@ -193,7 +193,7 @@ def _create_builtin_agents() -> dict[str, AgentConfig]:
name="windsurf",
display_name="Windsurf",
home_dir=None,
project_dir=Path(".skills") / "skills",
project_dir=Path(".skilz") / "skills",
config_files=(),
supports_home=False,
default_mode="copy",
Expand All @@ -203,7 +203,7 @@ def _create_builtin_agents() -> dict[str, AgentConfig]:
name="qwen",
display_name="Qwen CLI",
home_dir=None,
project_dir=Path(".skills") / "skills",
project_dir=Path(".skilz") / "skills",
config_files=("QWEN.md", "CONTEXT.md"),
supports_home=False,
default_mode="copy",
Expand All @@ -213,7 +213,7 @@ def _create_builtin_agents() -> dict[str, AgentConfig]:
name="crush",
display_name="Crush",
home_dir=None,
project_dir=Path(".skills") / "skills",
project_dir=Path(".skilz") / "skills",
config_files=(),
supports_home=False,
default_mode="copy",
Expand All @@ -223,7 +223,7 @@ def _create_builtin_agents() -> dict[str, AgentConfig]:
name="kimi",
display_name="Kimi CLI",
home_dir=None,
project_dir=Path(".skills") / "skills",
project_dir=Path(".skilz") / "skills",
config_files=(),
supports_home=False,
default_mode="copy",
Expand All @@ -233,7 +233,7 @@ def _create_builtin_agents() -> dict[str, AgentConfig]:
name="plandex",
display_name="Plandex",
home_dir=None,
project_dir=Path(".skills") / "skills",
project_dir=Path(".skilz") / "skills",
config_files=(),
supports_home=False,
default_mode="copy",
Expand All @@ -243,7 +243,7 @@ def _create_builtin_agents() -> dict[str, AgentConfig]:
name="zed",
display_name="Zed AI",
home_dir=None,
project_dir=Path(".skills") / "skills",
project_dir=Path(".skilz") / "skills",
config_files=(),
supports_home=False,
default_mode="copy",
Expand Down
18 changes: 12 additions & 6 deletions src/skilz/config_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def _generate_usage_template(
else:
invocation = f'Bash("skilz read <skill-name> --agent {agent_name}")'

# Extended instructions for agents without native support OR when forced
# Extended step-by-step instructions for agents without native support OR when forced
if native_support == "none" or force_extended:
extra_steps = """
Step-by-step process:
Expand All @@ -53,6 +53,16 @@ def _generate_usage_template(
else:
extra_steps = ""

# Usage notes ONLY for agents without native support (not affected by force_extended)
if native_support == "none":
usage_notes = """
Usage notes:
- Only use skills listed in <available_skills> below
- Do not invoke a skill that is already loaded in your context
"""
else:
usage_notes = ""

return f"""<usage>
When users ask you to perform tasks, check if any of the available skills
below can help complete the task more effectively.
Expand All @@ -61,11 +71,7 @@ def _generate_usage_template(
- Invoke: {invocation}
- The skill content will load with detailed instructions
- Base directory provided in output for resolving bundled resources
{extra_steps}
Usage notes:
- Only use skills listed in <available_skills> below
- Do not invoke a skill that is already loaded in your context
</usage>"""
{extra_steps}{usage_notes}</usage>"""


@dataclass
Expand Down
4 changes: 2 additions & 2 deletions src/skilz/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def install_local_skill(
)
elif verbose:
agent_config = get_registry().get(resolved_agent)
project_path = agent_config.project_dir if agent_config else ".skills/skills"
project_path = agent_config.project_dir if agent_config else ".skilz/skills"
print(
f" Note: {get_agent_display_name(resolved_agent)} only supports "
f"project-level installation ({project_path}/)"
Expand Down Expand Up @@ -336,7 +336,7 @@ def install_skill(
)
elif verbose:
agent_config = get_registry().get(resolved_agent)
project_path = agent_config.project_dir if agent_config else ".skills/skills"
project_path = agent_config.project_dir if agent_config else ".skilz/skills"
print(
f" Note: {get_agent_display_name(resolved_agent)} only supports "
f"project-level installation ({project_path}/)"
Expand Down