# Buat ekstensi CLI

CLI `hf` mendukung ekstensi, yaitu perintah kustom yang disediakan oleh komunitas dan terintegrasi secara mulus ke dalam CLI. Ekstensi dihosting sebagai repositori GitHub publik dan dapat diinstal dengan satu perintah. Setelah diinstal, ekstensi muncul sebagai perintah tingkat atas `hf` persis seperti perintah bawaan.

Sistem ini terinspirasi oleh [ekstensi GitHub CLI](https://docs.github.com/en/github-cli/github-cli/creating-github-cli-extensions). Dalam panduan ini, Anda akan belajar cara membuat ekstensi Anda sendiri, menerbitkannya, dan membuatnya dapat ditemukan.

> [!TIP]
> Untuk dokumentasi yang ditujukan pengguna mengenai instalasi dan pengelolaan ekstensi, lihat [referensi CLI untuk `hf extensions`](../package_reference/cli#hf-extensions).

## Ikhtisar

Ada dua jenis ekstensi:

1. **Ekstensi skrip shell**: satu file yang dapat dieksekusi (skrip bash, biner terkompilasi, dll.) yang ditempatkan di akar repositori.
2. **Ekstensi Python**: paket Python standar dengan `pyproject.toml`. Diinstal di lingkungan virtual yang terisolasi agar dependensi tidak bentrok dengan sistem pengguna.

Kedua tipe berbagi konvensi yang sama:

- Repositori GitHub **harus** diberi nama `hf-<name>` (misalnya, `hf-claude`, `hf-mem`).
- Setelah terinstal, pengguna menjalankan ekstensi dengan `hf <name>` (misalnya, `hf claude`).
- Ekstensi tersebut terdaftar di `hf --help` di bawah "Perintah ekstensi".

Saat pengguna menjalankan `hf extensions install [OWNER/]hf-<name>`, sistem pertama kali mencari file biner/skrip bernama `hf-<name>` di akar repositori. Jika ditemukan, file tersebut diinstal sebagai ekstensi skrip shell. Jika tidak, sistem beralih ke instalasi repositori sebagai paket Python.

## Buat ekstensi skrip shell

Ekstensi skrip shell adalah tipe yang paling sederhana. Anda hanya perlu sebuah repositori GitHub dengan file yang dapat dieksekusi bernama `hf-<name>` di root.

> [!WARNING]
> Ekstensi skrip shell tidak didukung di Windows. Jika ekstensi Anda harus berfungsi di Windows, buatlah sebagai [ekstensi Python](#create-a-python-extension) sebagai gantinya.

### Contoh minimal

Buat repositori bernama `hf-hello` di GitHub dengan satu file:

**`hf-hello`** (di akar repositori):

```bash
#!/usr/bin/env bash
set -euo pipefail

echo "Hello from hf-hello extension!"
echo "Arguments: $@"
```

Selesai! Pengguna kini dapat menginstal dan menjalankannya:

```bash
>>> hf extensions install <your-username>/hf-hello
>>> hf hello
Hello from hf-hello extension!
Arguments:
```

### Tips untuk ekstensi skrip shell

- Selalu mulai dengan shebang (`#!/usr/bin/env bash`) dan `set -euo pipefail` untuk keamanan.
- Skrip menerima semua argumen tambahan yang diteruskan oleh pengguna. Misalnya, `hf hello --name world` meneruskan `--name world` ke skrip.
- Anda dapat mengakses token Hugging Face pengguna melalui variabel lingkungan `HF_TOKEN` jika mereka telah masuk.
- Tambahkan `manifest.json` di root repositori untuk menyediakan deskripsi (lihat [Menambahkan deskripsi](#add-a-description)).
- Dependensi eksternal (misalnya, `fzf`, `jq`, dll.) **tidak** diinstal secara otomatis bersama ekstensi Anda. Periksa alat yang diperlukan di awal skrip Anda dan gagal dengan anggun menggunakan pesan kesalahan yang membantu jika alat tersebut tidak ada.

> [!TIP]
> Untuk contoh di dunia nyata, lihat [hanouticelina/hf-claude](https://github.com/hanouticelina/hf-claude) — ekstensi skrip shell yang meluncurkan Claude Code dengan HF Inference Providers.

## Buat ekstensi Python

Ekstensi Python adalah paket Python lengkap yang diinstal dalam lingkungan virtual yang terisolasi. Ini adalah pilihan terbaik ketika ekstensi Anda memiliki dependensi Python atau logika yang lebih kompleks.

### Contoh minimal

Buat repositori bernama `hf-hello` di GitHub dengan struktur ini:

```
hf-hello/
├── pyproject.toml
└── src/
    └── hf_hello/
        ├── __init__.py
        └── cli.py
```

**`pyproject.toml`**:

```toml
[build-system]
requires = ["setuptools>=64"]
build-backend = "setuptools.backends._legacy:_Backend"

[project]
name = "hf-hello"
version = "0.1.0"
description = "A hello-world hf CLI extension"
requires-python = ">=3.10"

[project.scripts]
hf-hello = "hf_hello.cli:main"
```

**`src/hf_hello/cli.py`**:

```python
import sys

def main():
    print("Hello from hf-hello extension!")
    print(f"Arguments: {sys.argv[1:]}")

if __name__ == "__main__":
    main()
```

Bagian krusialnya adalah titik masuk `[project.scripts]`: ia **harus** diberi nama `hf-<name>` (di sini, `hf-hello`). Inilah cara CLI `hf` menemukan dan menjalankan ekstensi Anda.

Pengguna menginstal dan menjalankannya dengan cara yang sama:

```bash
>>> hf extensions install <your-username>/hf-hello
>>> hf hello
Hello from hf-hello extension!
Arguments: []
```

### Cara ekstensi Python diinstal

Saat pengguna menginstal ekstensi Python, hal berikut terjadi:

1. Lingkungan virtual dibuat di `~/.local/share/hf/extensions/hf-<name>/venv/`.
2. Paket Anda diinstal melalui `pip install` dari arsip repositori GitHub.
3. Sistem memverifikasi bahwa skrip konsol `hf-<name>` telah dibuat di venv.

Ini berarti dependensi ekstensi Anda terisolasi sepenuhnya — mereka tidak akan bentrok dengan paket Python lain milik pengguna.

> [!TIP]
> Untuk contoh dunia nyata, lihat [alvarobartt/hf-mem](https://github.com/alvarobartt/hf-mem) — ekstensi Python yang memperkirakan kebutuhan memori inferensi untuk model HF.

## Tambahkan deskripsi

Deskripsi membantu pengguna memahami apa yang dilakukan ekstensi Anda. Deskripsi ini muncul di `hf extensions list` dan di `hf --help`.

Sistem mencari deskripsi dalam urutan berikut:

1. **`manifest.json`** di root repositori:

```json
{
    "description": "A short description of what your extension does"
}
```

2. **`pyproject.toml`** `description` field (untuk ekstensi Python):

```toml
[project]
description = "A short description of what your extension does"
```

3. **Deskripsi repositori GitHub** (kolom "About" di halaman repositori).

Untuk ekstensi Python, mengatur `description` di `pyproject.toml` adalah pendekatan yang paling alami. Untuk ekstensi shell script, gunakan file `manifest.json` atau atur deskripsi repositori GitHub.

## Buat ekstensi Anda dapat ditemukan

Untuk membantu pengguna menemukan ekstensi Anda, tambahkan topik **`hf-extension`** ke repositori GitHub Anda:

1. Buka repositori Anda di GitHub.
2. Klik ikon roda gigi di sebelah "About" pada bilah sisi kanan.
3. Di bawah "Topics", tambahkan `hf-extension`.

Ini adalah konvensi komunitas yang memudahkan penelusuran semua ekstensi yang tersedia di [halaman topik hf-extension](https://github.com/topics/hf-extension).

Pengguna kemudian dapat menemukan ekstensi Anda langsung dari CLI dengan `hf extensions search`, yang menampilkan semua repositori GitHub yang diberi tag topik `hf-extension`, diurutkan berdasarkan bintang:

```bash
>>> hf extensions search
NAME   REPO                    STARS DESCRIPTION                         INSTALLED
------ ----------------------- ----- ----------------------------------- ---------
claude hanouticelina/hf-claude     2 Extension for `hf` CLI to launch... yes
agents hanouticelina/hf-agents       HF extension to run local coding...
```

Kolom `INSTALLED` menunjukkan ekstensi mana yang sudah terpasang secara lokal. Dari sana, pengguna dapat memasang ekstensi mana pun yang terdaftar dengan `hf extensions install <repo>`.

## Uji ekstensi Anda

Selama pengembangan, Anda dapat menginstal ekstensi Anda langsung dari repositori GitHub Anda:

```bash
# Install from your repo
>>> hf extensions install <your-username>/hf-<name>

# Run it
>>> hf <name>

# Reinstall after making changes (push to GitHub first)
>>> hf extensions install <your-username>/hf-<name> --force

# Update to the latest version (only if a newer commit is available)
>>> hf extensions update <name>

# List installed extensions
>>> hf extensions list

# Remove when done
>>> hf extensions remove <name>
```

> [!TIP]
> Gunakan `--force` untuk menimpa versi yang sebelumnya terinstal saat menguji pembaruan.

## Perbarui ekstensi yang terpasang

Setelah ekstensi diinstal, Anda dapat memperbaruinya ke versi terbaru yang dipublikasikan di GitHub:

```bash
# Update a single extension (accepts `<name>`, `hf-<name>` or `OWNER/hf-<name>`)
>>> hf extensions update hf-claude

# Check every installed extension and update the outdated ones
>>> hf extensions update
```

`hf extensions update` hanya memperbarui ekstensi yang sudah terpasang. Jika ekstensi belum terpasang, error akan dilempar. Ekstensi yang sudah versi terbaru akan dilewati.

Versi ekstensi adalah commit tempat ekstensi tersebut diinstal, yang ditampilkan sebagai SHA pendek di kolom `VERSION` dari `hf extensions list`. Kolom `LATEST` diperiksa ketika tidak ada commit yang lebih baru tersedia di GitHub, dan menjalankan ekstensi yang sudah kedaluwarsa akan menampilkan petunjuk yang menyarankan `hf extensions update <name>`. Untuk tetap berada dalam batas laju GitHub untuk permintaan yang tidak terautentikasi, `hf` mencari commit terbaru dari setiap ekstensi paling banyak sekali sehari. Atur `HF_HUB_DISABLE_UPDATE_CHECK=1` untuk menonaktifkan pemeriksaan ini.

Jika ekstensi Python berhenti berfungsi karena Python yang digunakan saat instalasinya dihapus (misalnya setelah upgrade Homebrew), `hf extensions update <name>` akan membuat ulang lingkungan virtualnya.

## Aturan penamaan

Nama ekstensi harus mengikuti aturan berikut:

- Repositori GitHub harus diberi nama `hf-<name>`.
- `<name>` harus diawali dengan huruf atau angka.
- `<name>` dapat berisi huruf, angka, `.`, `_`, dan `-`.
- `<name>` tidak boleh bentrok dengan perintah bawaan `hf` (misalnya, `download`, `upload`, `auth`).

Saat menginstal, pengguna dapat menentukan `OWNER/hf-<name>` lengkap atau hanya `hf-<name>` (yang secara default menggunakan organisasi `huggingface`).

## Ekstensi yang ada

Berikut adalah beberapa ekstensi komunitas yang dapat Anda gunakan sebagai referensi:

| Ekstensi | Tipe | Deskripsi |
|-----------|------|-------------|
| [hanouticelina/hf-claude](https://github.com/hanouticelina/hf-claude) | Shell script | Luncurkan Claude Code dengan HF Inference Providers |
| [alvarobartt/hf-mem](https://github.com/alvarobartt/hf-mem) | Python | Perkirakan kebutuhan memori inferensi untuk model HF |

