@gilangranggaid/kilua-agent 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/bin/kilua.js +31 -42
  2. package/bin/kilua.mjs +31 -42
  3. package/package.json +1 -1
package/bin/kilua.js CHANGED
@@ -92,7 +92,7 @@ const TOOLS_OPENAI = [
92
92
  type: "function",
93
93
  function: {
94
94
  name: "run_cmd",
95
- description: "Menjalankan perintah terminal lokal untuk instalasi dependencies, test, build, atau verifikasi project.",
95
+ description: "Menjalankan perintah terminal lokal untuk instalasi dependencies, test, build, install skill (npx skills add), atau verifikasi project.",
96
96
  parameters: { type: "object", properties: { command: { type: "string" } }, required: ["command"] }
97
97
  }
98
98
  }
@@ -148,7 +148,7 @@ async function runInteractiveConfig() {
148
148
 
149
149
  console.log("\x1b[35m=== KILUA CONFIG ===\x1b[0m\nPath: " + SETTINGS_PATH);
150
150
  console.log("1) 9Router Local / Claude Code Proxy (Port 20128)");
151
- console.log("2) TokenHarbor / 9Router / OpenRouter (OpenAI-compatible)");
151
+ console.log("2) TokenHarbor / OpenRouter / Custom (OpenAI-compatible)");
152
152
  console.log("3) Google Gemini (AI Studio Key)\n");
153
153
 
154
154
  const choice = (await promptQuestion(rl, "Pilihan [1/2/3] (default 1): ")).trim() || "1";
@@ -156,21 +156,19 @@ async function runInteractiveConfig() {
156
156
 
157
157
  if (choice === "1") {
158
158
  const defaultUrl = "http://127.0.0.1:20128/v1";
159
- const defaultModel = "harobor";
160
-
161
159
  const baseUrl = (await promptQuestion(rl, `Base URL (${defaultUrl}): `)).trim() || defaultUrl;
162
- const key = (await promptQuestion(rl, `API Key/Token (kosongkan jika tidak perlu): `)).trim();
163
- const model = (await promptQuestion(rl, `Model (${defaultModel}): `)).trim() || defaultModel;
160
+ const key = (await promptQuestion(rl, `API Key/Token (kosongkan jika lokal): `)).trim();
161
+ const model = (await promptQuestion(rl, `Nama Model yang ingin dipakai di 9Router (contoh: harobor): `)).trim();
164
162
 
165
163
  settings = {
166
164
  provider: "anthropic",
167
165
  base_url: baseUrl.replace(/\/+$/, ""),
168
166
  api_key: key,
169
- model
167
+ model: model || "harobor"
170
168
  };
171
169
  } else if (choice === "3") {
172
170
  const key = (await promptQuestion(rl, "Masukkan GEMINI_API_KEY: ")).trim();
173
- const model = (await promptQuestion(rl, "Nama Model (gemini-3.5-flash-lite): ")).trim() || "gemini-3.5-flash-lite";
171
+ const model = (await promptQuestion(rl, "Nama Model (contoh: gemini-3.5-flash-lite): ")).trim() || "gemini-3.5-flash-lite";
174
172
  settings = {
175
173
  provider: "openai",
176
174
  base_url: "https://generativelanguage.googleapis.com/v1beta/openai",
@@ -179,9 +177,9 @@ async function runInteractiveConfig() {
179
177
  };
180
178
  } else {
181
179
  console.log("Contoh Base URL: https://tokenharbor.ai/v1");
182
- const baseUrl = (await promptQuestion(rl, "Base URL (https://tokenharbor.ai/v1): ")).trim() || "https://tokenharbor.ai/v1";
180
+ const baseUrl = (await promptQuestion(rl, "Base URL: ")).trim() || "https://tokenharbor.ai/v1";
183
181
  const key = (await promptQuestion(rl, "API Key: ")).trim();
184
- const model = (await promptQuestion(rl, "Model (deepseek-v4.1-flash:free): ")).trim() || "deepseek-v4.1-flash:free";
182
+ const model = (await promptQuestion(rl, "Nama Model (contoh: deepseek-v4.1-flash:free): ")).trim() || "deepseek-v4.1-flash:free";
185
183
  settings = {
186
184
  provider: "openai",
187
185
  api_key: key,
@@ -236,13 +234,15 @@ function buildSystemPrompt() {
236
234
  return `Kamu KILUA, AI Coding Agent otonom di terminal lokal. Folder aktif: ${process.cwd()}.
237
235
  KEMAMPUAN TOOLS:
238
236
  - read_file, write_file, edit_file, list_dir
239
- - run_cmd: menjalankan perintah terminal lokal (npm, npx, git, node, python, build, test, curl, dsb).
237
+ - run_cmd: menjalankan perintah terminal lokal (npm, npx, git, node, python, build, test, curl, install skill, dsb).
240
238
 
241
- ATURAN OTONOM KILUA (SELF-TESTING):
239
+ ATURAN OTONOM KILUA (SELF-TESTING & AUTO-INSTALL SKILL):
242
240
  1. Jika pengguna meminta membuat project/fitur/skrip, JANGAN langsung serahkan begitu saja. Kamu HARUS mencoba atau memvalidasinya sendiri terlebih dahulu menggunakan run_cmd (misal: jalankan skrip, test, build, atau cek sintaks).
243
241
  2. Jika ada error saat kamu mencoba, perbaiki langsung menggunakan edit_file/write_file sampai berhasil.
244
242
  3. Setelah berhasil dicoba dan dipastikan tidak error, barulah beri tahu pengguna hasil dan cara menjalankannya.
245
- 4. Kamu dapat menginstall skill baru atau CLI menggunakan run_cmd (misalnya: npx skills add <nama-skill> atau npm i).${skillsInfo}
243
+ 4. Jika pengguna di chat menyuruh kamu install skill (misal: "install skill vercel-labs/skills@find-skills" atau skill lain), jalankan run_cmd dengan perintah:
244
+ npx skills add <nama-skill> --cwd "${SKILLS_DIR}"
245
+ Lalu beri tahu pengguna bahwa skill tersebut telah siap dipakai.${skillsInfo}
246
246
 
247
247
  Respon ringkas, padat, dan bertindak langsung.`;
248
248
  }
@@ -454,11 +454,12 @@ function printHelp() {
454
454
  \x1b[1m\x1b[35m=== PERINTAH SLASH KILUA (/) ===\x1b[0m
455
455
  \x1b[36m/help\x1b[0m Lihat panduan perintah ini
456
456
  \x1b[36m/models\x1b[0m Lihat dan ganti model AI saat ini
457
- \x1b[36m/skills\x1b[0m Lihat daftar skills yang terpasang
458
- \x1b[36m/install-skill\x1b[0m Pasang skill baru (misal: /install-skill vercel-labs/skills@find-skills)
457
+ \x1b[36m/skills\x1b[0m Lihat daftar skills yang terpasang di Kilua
459
458
  \x1b[36m/clear\x1b[0m Bersihkan riwayat percakapan sesi ini
460
459
  \x1b[36m/config\x1b[0m Ubah API Key, Provider, atau Base URL
461
460
  \x1b[36m/exit\x1b[0m Keluar dari Kilua Agent
461
+
462
+ \x1b[90mTips: Untuk menginstall skill baru, cukup suruh Kilua di chat (misal: "tolong install skill find-skills")!\x1b[0m
462
463
  `);
463
464
  }
464
465
 
@@ -472,12 +473,12 @@ async function handleSlashCommand(cmd, settings, convo, rl) {
472
473
  }
473
474
 
474
475
  if (action === "/models" || action === "/model") {
475
- console.log(`\n\x1b[33mModel aktif saat ini:\x1b[0m \x1b[32m${settings.model}\x1b[0m`);
476
- console.log(`Rekomendasi Model:`);
477
- console.log(`- TokenHarbor : deepseek-v4.1-flash:free`);
478
- console.log(`- Gemini : gemini-3.5-flash-lite, gemini-2.5-flash`);
479
- console.log(`- 9Router : harobor, claude-3-5-sonnet-20241022\n`);
480
- const newModel = (await promptQuestion(rl, `Ganti model (Enter untuk tetap '${settings.model}'): `)).trim();
476
+ if (!settings.base_url || !settings.api_key) {
477
+ console.log(`\n\x1b[33m[!] Belum terhubung ke config provider. Jalankan /config terlebih dahulu.\x1b[0m\n`);
478
+ return settings;
479
+ }
480
+ console.log(`\n\x1b[33mModel aktif saat ini:\x1b[0m \x1b[32m${settings.model}\x1b[0m (Provider: ${settings.base_url})`);
481
+ const newModel = (await promptQuestion(rl, `Ganti nama model (Enter untuk tetap '${settings.model}'): `)).trim();
481
482
  if (newModel) {
482
483
  settings.model = newModel;
483
484
  saveSettings(settings);
@@ -490,8 +491,8 @@ async function handleSlashCommand(cmd, settings, convo, rl) {
490
491
  const list = listInstalledSkills();
491
492
  console.log(`\n\x1b[35m=== SKILLS TERPASANG (${SKILLS_DIR}) ===\x1b[0m`);
492
493
  if (!list.length) {
493
- console.log(`(Belum ada skill tambahan terpasang)`);
494
- console.log(`Ketik \x1b[36m/install-skill <nama-skill>\x1b[0m untuk menambah skill.`);
494
+ console.log(`Belum ada skill tambahan terpasang.`);
495
+ console.log(`Suruh Kilua di chat untuk install, misal: \x1b[36m"Kilua, tolong install skill vercel-labs/skills@find-skills"\x1b[0m`);
495
496
  } else {
496
497
  for (const s of list) {
497
498
  console.log(`- \x1b[32m${s.name}\x1b[0m: ${s.desc}`);
@@ -501,22 +502,6 @@ async function handleSlashCommand(cmd, settings, convo, rl) {
501
502
  return settings;
502
503
  }
503
504
 
504
- if (action === "/install-skill") {
505
- const target = parts.slice(1).join(" ").trim();
506
- if (!target) {
507
- console.log(`\x1b[33mContoh penggunaan: /install-skill vercel-labs/skills@find-skills\x1b[0m`);
508
- return settings;
509
- }
510
- console.log(`\x1b[35m[Memasang skill ${target}...]\x1b[0m`);
511
- try {
512
- execSync(`npx skills add ${target}`, { cwd: SKILLS_DIR, stdio: "inherit" });
513
- console.log(`\x1b[32m✓ Skill ${target} berhasil dipasang!\x1b[0m\n`);
514
- } catch (e) {
515
- console.error(`[!] Gagal memasang skill:`, e.message);
516
- }
517
- return settings;
518
- }
519
-
520
505
  if (action === "/clear") {
521
506
  convo.length = 0;
522
507
  console.clear();
@@ -545,8 +530,12 @@ async function main() {
545
530
 
546
531
  let settings = loadSettings();
547
532
 
548
- if (!settings.api_key) {
549
- console.log("\x1b[33m[!] Belum ada konfigurasi AI key.\x1b[0m");
533
+ // Validasi ketat: jika belum ada base_url atau api_key, WAJIB setup dulu
534
+ const isLocalProxy = settings.base_url?.includes("127.0.0.1") || settings.base_url?.includes("localhost");
535
+ const hasValidConfig = settings.base_url && (settings.api_key || isLocalProxy);
536
+
537
+ if (!hasValidConfig) {
538
+ console.log("\x1b[33m[!] Belum ada konfigurasi AI key / provider.\x1b[0m");
550
539
  settings = await runInteractiveConfig();
551
540
  }
552
541
 
@@ -559,7 +548,7 @@ async function main() {
559
548
  console.log("\x1b[1m\x1b[35m=== KILUA AI CLI AGENT ===\x1b[0m");
560
549
  console.log(`CWD : \x1b[33m${process.cwd()}\x1b[0m`);
561
550
  console.log(`Provider: \x1b[32m${settings.base_url}\x1b[0m (${settings.model})`);
562
- console.log(`Config : \x1b[90m${SETTINGS_PATH}\x1b[0m (ketik \x1b[36m/help\x1b[0m untuk perintah slash)\n`);
551
+ console.log(`Config : \x1b[90m${SETTINGS_PATH}\x1b[0m (ketik \x1b[36m/help\x1b[0m untuk panduan)\n`);
563
552
 
564
553
  let rl = readline.createInterface({ input: process.stdin, output: process.stdout });
565
554
  const ask = () => {
package/bin/kilua.mjs CHANGED
@@ -92,7 +92,7 @@ const TOOLS_OPENAI = [
92
92
  type: "function",
93
93
  function: {
94
94
  name: "run_cmd",
95
- description: "Menjalankan perintah terminal lokal untuk instalasi dependencies, test, build, atau verifikasi project.",
95
+ description: "Menjalankan perintah terminal lokal untuk instalasi dependencies, test, build, install skill (npx skills add), atau verifikasi project.",
96
96
  parameters: { type: "object", properties: { command: { type: "string" } }, required: ["command"] }
97
97
  }
98
98
  }
@@ -148,7 +148,7 @@ async function runInteractiveConfig() {
148
148
 
149
149
  console.log("\x1b[35m=== KILUA CONFIG ===\x1b[0m\nPath: " + SETTINGS_PATH);
150
150
  console.log("1) 9Router Local / Claude Code Proxy (Port 20128)");
151
- console.log("2) TokenHarbor / 9Router / OpenRouter (OpenAI-compatible)");
151
+ console.log("2) TokenHarbor / OpenRouter / Custom (OpenAI-compatible)");
152
152
  console.log("3) Google Gemini (AI Studio Key)\n");
153
153
 
154
154
  const choice = (await promptQuestion(rl, "Pilihan [1/2/3] (default 1): ")).trim() || "1";
@@ -156,21 +156,19 @@ async function runInteractiveConfig() {
156
156
 
157
157
  if (choice === "1") {
158
158
  const defaultUrl = "http://127.0.0.1:20128/v1";
159
- const defaultModel = "harobor";
160
-
161
159
  const baseUrl = (await promptQuestion(rl, `Base URL (${defaultUrl}): `)).trim() || defaultUrl;
162
- const key = (await promptQuestion(rl, `API Key/Token (kosongkan jika tidak perlu): `)).trim();
163
- const model = (await promptQuestion(rl, `Model (${defaultModel}): `)).trim() || defaultModel;
160
+ const key = (await promptQuestion(rl, `API Key/Token (kosongkan jika lokal): `)).trim();
161
+ const model = (await promptQuestion(rl, `Nama Model yang ingin dipakai di 9Router (contoh: harobor): `)).trim();
164
162
 
165
163
  settings = {
166
164
  provider: "anthropic",
167
165
  base_url: baseUrl.replace(/\/+$/, ""),
168
166
  api_key: key,
169
- model
167
+ model: model || "harobor"
170
168
  };
171
169
  } else if (choice === "3") {
172
170
  const key = (await promptQuestion(rl, "Masukkan GEMINI_API_KEY: ")).trim();
173
- const model = (await promptQuestion(rl, "Nama Model (gemini-3.5-flash-lite): ")).trim() || "gemini-3.5-flash-lite";
171
+ const model = (await promptQuestion(rl, "Nama Model (contoh: gemini-3.5-flash-lite): ")).trim() || "gemini-3.5-flash-lite";
174
172
  settings = {
175
173
  provider: "openai",
176
174
  base_url: "https://generativelanguage.googleapis.com/v1beta/openai",
@@ -179,9 +177,9 @@ async function runInteractiveConfig() {
179
177
  };
180
178
  } else {
181
179
  console.log("Contoh Base URL: https://tokenharbor.ai/v1");
182
- const baseUrl = (await promptQuestion(rl, "Base URL (https://tokenharbor.ai/v1): ")).trim() || "https://tokenharbor.ai/v1";
180
+ const baseUrl = (await promptQuestion(rl, "Base URL: ")).trim() || "https://tokenharbor.ai/v1";
183
181
  const key = (await promptQuestion(rl, "API Key: ")).trim();
184
- const model = (await promptQuestion(rl, "Model (deepseek-v4.1-flash:free): ")).trim() || "deepseek-v4.1-flash:free";
182
+ const model = (await promptQuestion(rl, "Nama Model (contoh: deepseek-v4.1-flash:free): ")).trim() || "deepseek-v4.1-flash:free";
185
183
  settings = {
186
184
  provider: "openai",
187
185
  api_key: key,
@@ -236,13 +234,15 @@ function buildSystemPrompt() {
236
234
  return `Kamu KILUA, AI Coding Agent otonom di terminal lokal. Folder aktif: ${process.cwd()}.
237
235
  KEMAMPUAN TOOLS:
238
236
  - read_file, write_file, edit_file, list_dir
239
- - run_cmd: menjalankan perintah terminal lokal (npm, npx, git, node, python, build, test, curl, dsb).
237
+ - run_cmd: menjalankan perintah terminal lokal (npm, npx, git, node, python, build, test, curl, install skill, dsb).
240
238
 
241
- ATURAN OTONOM KILUA (SELF-TESTING):
239
+ ATURAN OTONOM KILUA (SELF-TESTING & AUTO-INSTALL SKILL):
242
240
  1. Jika pengguna meminta membuat project/fitur/skrip, JANGAN langsung serahkan begitu saja. Kamu HARUS mencoba atau memvalidasinya sendiri terlebih dahulu menggunakan run_cmd (misal: jalankan skrip, test, build, atau cek sintaks).
243
241
  2. Jika ada error saat kamu mencoba, perbaiki langsung menggunakan edit_file/write_file sampai berhasil.
244
242
  3. Setelah berhasil dicoba dan dipastikan tidak error, barulah beri tahu pengguna hasil dan cara menjalankannya.
245
- 4. Kamu dapat menginstall skill baru atau CLI menggunakan run_cmd (misalnya: npx skills add <nama-skill> atau npm i).${skillsInfo}
243
+ 4. Jika pengguna di chat menyuruh kamu install skill (misal: "install skill vercel-labs/skills@find-skills" atau skill lain), jalankan run_cmd dengan perintah:
244
+ npx skills add <nama-skill> --cwd "${SKILLS_DIR}"
245
+ Lalu beri tahu pengguna bahwa skill tersebut telah siap dipakai.${skillsInfo}
246
246
 
247
247
  Respon ringkas, padat, dan bertindak langsung.`;
248
248
  }
@@ -454,11 +454,12 @@ function printHelp() {
454
454
  \x1b[1m\x1b[35m=== PERINTAH SLASH KILUA (/) ===\x1b[0m
455
455
  \x1b[36m/help\x1b[0m Lihat panduan perintah ini
456
456
  \x1b[36m/models\x1b[0m Lihat dan ganti model AI saat ini
457
- \x1b[36m/skills\x1b[0m Lihat daftar skills yang terpasang
458
- \x1b[36m/install-skill\x1b[0m Pasang skill baru (misal: /install-skill vercel-labs/skills@find-skills)
457
+ \x1b[36m/skills\x1b[0m Lihat daftar skills yang terpasang di Kilua
459
458
  \x1b[36m/clear\x1b[0m Bersihkan riwayat percakapan sesi ini
460
459
  \x1b[36m/config\x1b[0m Ubah API Key, Provider, atau Base URL
461
460
  \x1b[36m/exit\x1b[0m Keluar dari Kilua Agent
461
+
462
+ \x1b[90mTips: Untuk menginstall skill baru, cukup suruh Kilua di chat (misal: "tolong install skill find-skills")!\x1b[0m
462
463
  `);
463
464
  }
464
465
 
@@ -472,12 +473,12 @@ async function handleSlashCommand(cmd, settings, convo, rl) {
472
473
  }
473
474
 
474
475
  if (action === "/models" || action === "/model") {
475
- console.log(`\n\x1b[33mModel aktif saat ini:\x1b[0m \x1b[32m${settings.model}\x1b[0m`);
476
- console.log(`Rekomendasi Model:`);
477
- console.log(`- TokenHarbor : deepseek-v4.1-flash:free`);
478
- console.log(`- Gemini : gemini-3.5-flash-lite, gemini-2.5-flash`);
479
- console.log(`- 9Router : harobor, claude-3-5-sonnet-20241022\n`);
480
- const newModel = (await promptQuestion(rl, `Ganti model (Enter untuk tetap '${settings.model}'): `)).trim();
476
+ if (!settings.base_url || !settings.api_key) {
477
+ console.log(`\n\x1b[33m[!] Belum terhubung ke config provider. Jalankan /config terlebih dahulu.\x1b[0m\n`);
478
+ return settings;
479
+ }
480
+ console.log(`\n\x1b[33mModel aktif saat ini:\x1b[0m \x1b[32m${settings.model}\x1b[0m (Provider: ${settings.base_url})`);
481
+ const newModel = (await promptQuestion(rl, `Ganti nama model (Enter untuk tetap '${settings.model}'): `)).trim();
481
482
  if (newModel) {
482
483
  settings.model = newModel;
483
484
  saveSettings(settings);
@@ -490,8 +491,8 @@ async function handleSlashCommand(cmd, settings, convo, rl) {
490
491
  const list = listInstalledSkills();
491
492
  console.log(`\n\x1b[35m=== SKILLS TERPASANG (${SKILLS_DIR}) ===\x1b[0m`);
492
493
  if (!list.length) {
493
- console.log(`(Belum ada skill tambahan terpasang)`);
494
- console.log(`Ketik \x1b[36m/install-skill <nama-skill>\x1b[0m untuk menambah skill.`);
494
+ console.log(`Belum ada skill tambahan terpasang.`);
495
+ console.log(`Suruh Kilua di chat untuk install, misal: \x1b[36m"Kilua, tolong install skill vercel-labs/skills@find-skills"\x1b[0m`);
495
496
  } else {
496
497
  for (const s of list) {
497
498
  console.log(`- \x1b[32m${s.name}\x1b[0m: ${s.desc}`);
@@ -501,22 +502,6 @@ async function handleSlashCommand(cmd, settings, convo, rl) {
501
502
  return settings;
502
503
  }
503
504
 
504
- if (action === "/install-skill") {
505
- const target = parts.slice(1).join(" ").trim();
506
- if (!target) {
507
- console.log(`\x1b[33mContoh penggunaan: /install-skill vercel-labs/skills@find-skills\x1b[0m`);
508
- return settings;
509
- }
510
- console.log(`\x1b[35m[Memasang skill ${target}...]\x1b[0m`);
511
- try {
512
- execSync(`npx skills add ${target}`, { cwd: SKILLS_DIR, stdio: "inherit" });
513
- console.log(`\x1b[32m✓ Skill ${target} berhasil dipasang!\x1b[0m\n`);
514
- } catch (e) {
515
- console.error(`[!] Gagal memasang skill:`, e.message);
516
- }
517
- return settings;
518
- }
519
-
520
505
  if (action === "/clear") {
521
506
  convo.length = 0;
522
507
  console.clear();
@@ -545,8 +530,12 @@ async function main() {
545
530
 
546
531
  let settings = loadSettings();
547
532
 
548
- if (!settings.api_key) {
549
- console.log("\x1b[33m[!] Belum ada konfigurasi AI key.\x1b[0m");
533
+ // Validasi ketat: jika belum ada base_url atau api_key, WAJIB setup dulu
534
+ const isLocalProxy = settings.base_url?.includes("127.0.0.1") || settings.base_url?.includes("localhost");
535
+ const hasValidConfig = settings.base_url && (settings.api_key || isLocalProxy);
536
+
537
+ if (!hasValidConfig) {
538
+ console.log("\x1b[33m[!] Belum ada konfigurasi AI key / provider.\x1b[0m");
550
539
  settings = await runInteractiveConfig();
551
540
  }
552
541
 
@@ -559,7 +548,7 @@ async function main() {
559
548
  console.log("\x1b[1m\x1b[35m=== KILUA AI CLI AGENT ===\x1b[0m");
560
549
  console.log(`CWD : \x1b[33m${process.cwd()}\x1b[0m`);
561
550
  console.log(`Provider: \x1b[32m${settings.base_url}\x1b[0m (${settings.model})`);
562
- console.log(`Config : \x1b[90m${SETTINGS_PATH}\x1b[0m (ketik \x1b[36m/help\x1b[0m untuk perintah slash)\n`);
551
+ console.log(`Config : \x1b[90m${SETTINGS_PATH}\x1b[0m (ketik \x1b[36m/help\x1b[0m untuk panduan)\n`);
563
552
 
564
553
  let rl = readline.createInterface({ input: process.stdin, output: process.stdout });
565
554
  const ask = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gilangranggaid/kilua-agent",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Autonomous AI Coding Agent for your terminal and VS Code",
5
5
  "type": "module",
6
6
  "main": "bin/kilua.js",