11
Skill untuk AI Agent
SKILL.md di akar repository bukan dokumentasi untuk manusia, melainkan konteks siap pakai untuk AI agent. Berkas itu dibuka dengan frontmatter name: wilayah-indonesia dan satu description, lalu menyatakan bahwa data tersedia lewat dua cara yang dapat dipertukarkan: Static API dan berkas unduhan. Lingkupnya dibatasi pada apa yang akan diterima agent — kolom, key, dan bentuk response — supaya agent dapat membangun integrasi untuk stack apa pun. SKILL.md:1-81
Perintah wilayah skill menyalin berkas itu ke direktori yang dibaca tiap agent. Pendaftaran subcommand, perintah download, dan tata cara pemasangan paket ada di CLI @emsifa/wilayah. Halaman ini hanya membahas isi SKILL.md dan mekanisme penyalinannya.
Isi SKILL.md
SKILL.md disusun sebagai satu berkas mandiri sehingga agent tidak perlu membuka berkas lain untuk memahami bentuk data. Bagian pertama memaksa agent memilih sumber lebih dulu, dan bahkan menetapkan kalimat yang harus ditanyakan ke pengguna: Do you want to fetch from the API or self-host the data?. SKILL.md:10-152
| Bagian | Muatan | Rujukan |
|---|---|---|
| 1. Which Source Should You Use? | Static API vs unduhan, plus pertanyaan ke pengguna | SKILL.md:10-152 |
| 2. API — What You Get | wrapper data/meta, objek rich, list compact, tabel endpoint, stats.json, polygon, missings.json | SKILL.md:17-1523 |
| 3. Downloaded Files | bentuk csv/sql/json dan kolom tambahan level 1/2 | SKILL.md:154-2004 |
| 4. How IDs and Relationships Work | pemecahan kode menjadi parent | SKILL.md:202-2065 |
| 5. How to Use (for the AI) | urutan pemanggilan dan larangan menebak kode | SKILL.md:208-2136 |
Bagian 2 sampai 4 mengulang bentuk data yang sudah dibahas rinci di halaman Format Response dan Wrapper data/meta, Referensi Endpoint, Polygon dan Boundary, dan Kelengkapan Data dan missings.json. Bagi agent, ringkasan itulah yang membuat SKILL.md cukup dibaca sekali.
Bagian 5 memberi instruksi operasional: panggil endpoint berurutan provinces → regencies/{prov} → districts/{reg} → villages/{dist}, selalu pakai kode nyata dari response sebelumnya, jangan menebak, dan periksa has_path sebelum mengambil /paths/{id}.json. SKILL.md:208-2136
Merutekan skill ke direktori agent
AGENT_REGISTRY menyimpan tiga path per agent: project, global, dan hint untuk label di prompt. Skill selalu diletakkan di dalam direktori wilayah-indonesia dengan nama berkas SKILL.md, keduanya diekspor sebagai SKILL_DIR dan SKILL_FILE. cli/src/utils/paths.ts:9-127 cli/src/utils/paths.ts:22-578
getSkillTargets memilih basis direktori: cwd untuk scope project dan home untuk scope global. Agent opencode mendapat perlakuan khusus pada scope global — varian xdg memakai .config/opencode/..., varian legacy memakai .opencode/.... cli/src/utils/paths.ts:59-819
graph TD
SRC["SKILL.md di akar repo"]
PRE["prebuild: cp ../SKILL.md ke cli/assets/SKILL.md"]
DIST["dist/assets/SKILL.md"]
LOAD["loadSkillContent"]
TARGETS["getSkillTargets(agents, scope)"]
CLAUDE[".claude/skills/wilayah-indonesia/SKILL.md"]
CODEX[".codex/skills/wilayah-indonesia/SKILL.md"]
OPEN[".opencode/skills/wilayah-indonesia/SKILL.md"]
ANTI[".agents/skills/wilayah-indonesia/SKILL.md"]
KIRO[".kiro/skills/wilayah-indonesia/SKILL.md"]
CUSTOM["path dari --target untuk others"]
SRC --> PRE
PRE --> DIST
DIST --> LOAD
SRC --> LOAD
LOAD --> TARGETS
TARGETS --> CLAUDE
TARGETS --> CODEX
TARGETS --> OPEN
TARGETS --> ANTI
TARGETS --> KIRO
LOAD --> CUSTOM
style SRC fill:#336791,color:#fff
style DIST fill:#336791,color:#fff
style LOAD fill:#f59e0b,color:#000
style TARGETS fill:#f59e0b,color:#000
style CLAUDE fill:#2d7d46,color:#fff
style CODEX fill:#2d7d46,color:#fff
style OPEN fill:#2d7d46,color:#fff
style ANTI fill:#2d7d46,color:#fff
style KIRO fill:#2d7d46,color:#fff
style CUSTOM fill:#8b5cf6,color:#fff
%% fig: Sumber skill dan path tujuan tiap agent
%% desc: SKILL.md disalin saat build ke aset CLI, dibaca oleh loadSkillContent, lalu getSkillTargets memetakan tiap agent ke path tujuan; target custom datang dari --target.| Agent | project (basis cwd) | global (basis home) |
|---|---|---|
claude | .claude/skills/wilayah-indonesia/SKILL.md | .claude/skills/wilayah-indonesia/SKILL.md |
codex | .codex/skills/wilayah-indonesia/SKILL.md | .codex/skills/wilayah-indonesia/SKILL.md |
opencode | .opencode/skills/wilayah-indonesia/SKILL.md | .config/opencode/skills/wilayah-indonesia/SKILL.md atau .opencode/skills/wilayah-indonesia/SKILL.md |
antigravity | .agents/skills/wilayah-indonesia/SKILL.md | .gemini/config/skills/wilayah-indonesia/SKILL.md |
kiro | .kiro/skills/wilayah-indonesia/SKILL.md | .kiro/skills/wilayah-indonesia/SKILL.md |
Agent others tidak memakai registry. Path-nya berasal dari --target (alias --out), dan di mode non-interaktif flag itu wajib ada; tanpanya perintah berhenti dengan pesan Missing --target. When using --agent others, you must specify --target <path>. Path relatif diselesaikan terhadap cwd, sedangkan awalan ~/ diganti homedir(). cli/src/commands/skill.ts:240-25210
Sumber berkas dan resolusi loadSkillContent
loadSkillContent() mencoba sejumlah kandidat path berurutan dan hanya menerima berkas yang isinya memuat string "Wilayah Indonesia". Kandidat pertama berada relatif terhadap modul (assets/SKILL.md dan ../assets/SKILL.md), lalu cli/assets/SKILL.md dan assets/SKILL.md relatif cwd, lalu ../SKILL.md. cli/src/utils/skill-source.ts:9-3711
Saat build, script prebuild menyalin ../SKILL.md ke cli/assets/SKILL.md, sehingga paket yang sudah dibundel membawa salinannya sebagai dist/assets/SKILL.md. cli/package.json:36-4012
⚠️ Salah satu kandidat adalah path absolut tetap
/home/emsifa/Dev/personal/data-wilayah/SKILL.md, yaitu path di mesin pengembang. Di mesin lain kandidat itu gagal, laluloadSkillContentmemakai fallback../../../SKILL.mdrelatif modul; bila semua gagal, ia melemparCould not find SKILL.md source. Tried: .... cli/src/utils/skill-source.ts:9-3711 cli/src/utils/skill-source.ts:39-5113
Menulis berkas tujuan
Untuk setiap target, perintah memeriksa exists(target). Bila berkas sudah ada dan --yes tidak diberikan, mode interaktif menawarkan Append / Overwrite / Skip untuk custom target, dan konfirmasi overwrite untuk agent registry. Mode non-interaktif langsung berhenti dengan pesan File exists: ${target} — use --yes to overwrite. cli/src/commands/skill.ts:299-37214
Pilihan Append memakai penanda <!-- wilayah-indonesia:start --> dan <!-- wilayah-indonesia:end -->. Bila kedua penanda sudah ada, isi di antaranya diganti sehingga penulisan ulang tidak menduplikasi blok; bila belum ada, blok ditambahkan di akhir berkas. cli/src/commands/skill.ts:30-4515
⚠️ Dengan
--yes, custom target yang sudah ada selalu ditimpa utuh — komentar di kode menyebut--yesberarti overwrite. Append idempoten hanya tersedia lewat mode interaktif. MenargetkanAGENTS.mdyang sudah berisi instruksi lain akan menghapus isi berkas tersebut. cli/src/commands/skill.ts:354-36916
Mode --dry-run tidak menulis apa pun; ia hanya mencetak daftar target. cli/src/commands/skill.ts:287-29417
stateDiagram-v2
[*] --> ResolveTargets
ResolveTargets --> DryRun: --dry-run
DryRun --> [*]
ResolveTargets --> CheckExists: mode tulis
CheckExists --> Written: berkas belum ada
CheckExists --> Written: --yes menimpa
CheckExists --> Appended: Append dipilih
CheckExists --> Skipped: Skip atau konfirmasi ditolak
CheckExists --> Failed: non-interaktif tanpa --yes
Appended --> [*]
Written --> [*]
Skipped --> [*]
Failed --> [*]
style ResolveTargets fill:#f59e0b,color:#000
style CheckExists fill:#336791,color:#fff
style DryRun fill:#f59e0b,color:#000
style Written fill:#2d7d46,color:#fff
style Appended fill:#8b5cf6,color:#fff
style Skipped fill:#f59e0b,color:#000
style Failed fill:#dc2626,color:#fff
%% fig: Siklus penulisan satu target
%% desc: Target diselesaikan lebih dulu, lalu setiap berkas melewati pemeriksaan keberadaan sebelum ditulis, ditambahi blok, dilewati, atau digagalkan.Opsi perintah skill
skill didefinisikan dengan defineCommand dari citty dan menerima tujuh argumen. cli/src/commands/skill.ts:47-8718
| Flag | Tipe / default | Perilaku |
|---|---|---|
--agent | string | claude, codex, opencode, antigravity, kiro, others, all, atau daftar dipisah koma |
--target, --out | string | path keluaran custom untuk others, harus berakhiran .md |
--global | boolean, false | pasang ke ~ alih-alih ./ |
--yes, -y | boolean, false | lewati konfirmasi; berkas yang ada ditimpa |
--dry-run | boolean, false | hanya mencetak target tanpa menulis |
--cwd | string | mengganti direktori proyek (default process.cwd()) |
--no-interactive | boolean, false | memaksa mode non-interaktif untuk CI |
Di mode interaktif, perintah meminta multiselect agent, lalu meminta path custom yang wajib berakhiran .md bila others dipilih. Setelah itu ia menanyakan scope Project atau Global, dan varian path untuk opencode hanya muncul ketika scope global dipilih. cli/src/commands/skill.ts:158-18319 cli/src/commands/skill.ts:206-22120
Di mode non-interaktif, ketiadaan --agent langsung menggagalkan perintah dengan pesan Missing --agent. Non-interactive mode requires --agent <claude|codex|opencode|antigravity|kiro|others|all> (e.g. --agent claude,antigravity). cli/src/commands/skill.ts:97-10321
Nilai --agent diurai parseAgents: all diperluas menjadi ALL_AGENTS (claude, codex, opencode, antigravity, kiro), duplikat dibuang, dan nilai tak dikenal melempar Unknown agent "...". Valid: .... cli/src/utils/paths.ts:83-11122