> For the complete documentation index, see [llms.txt](https://docs.haikaldev.my.id/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.haikaldev.my.id/coding-and-hosting/workspace.md).

# Workspace Coding

Fitur unggulan v2.1: bot punya **folder proyek sungguhan** yang bertahan antar percakapan, dan dia bisa **menjalankan kodenya sendiri** — lalu membaca hasilnya, menemukan yang salah, memperbaikinya, dan menjalankan ulang. Tanpa disuruh per langkah.

## Kenapa ini beda

Sebelumnya bot bisa *menulis* kode (`create_file`) tapi tidak pernah *menjalankannya* — jadi dia tidak pernah tahu kodenya benar atau salah. Yang dia kirim adalah tebakan yang rapi.

Sekarang loop-nya lengkap:

```mermaid
flowchart LR
    T["✍️ tulis"] --> R["▶️ jalankan"]
    R --> B["👀 baca STDOUT/STDERR"]
    B --> S{"hasilnya<br>benar?"}
    S -->|tidak| F["🔧 perbaiki"]
    F --> R
    S -->|ya| D["✅ lapor hasil<br><i>sungguhan</i>"]
```

Bukti dari pengujian nyata — bot diberi `jumlah.js` dengan typo `.lenght`. Ini bukan syntax error: kodenya **jalan**, hasilnya saja yang salah (`Total: 0`), jadi bot hanya bisa menemukannya kalau ia benar-benar melihat keluarannya.

```
[AGENT_TOOL] manage_workspace { action: 'run',   path: 'jumlah.js' }   ← lihat hasilnya 0
[AGENT_TOOL] manage_workspace { action: 'read',  path: 'jumlah.js' }   ← baca kodenya
[AGENT_TOOL] manage_workspace { action: 'write', files: [...] }        ← betulkan typo
[AGENT_TOOL] manage_workspace { action: 'run',   path: 'jumlah.js' }   ← Total: 15 ✅
Bot: "Sudah diperbaiki. Kesalahannya ada di `angka.lenght`, seharusnya `angka.length`."
```

{% hint style="success" %}
Yang dinilai pengujiannya **bukan kalimat bot** — melainkan isi berkas di disk dan hasil eksekusi ulang. Bot yang mengaku sudah memperbaiki tapi berkasnya tidak berubah = tes gagal.
{% endhint %}

## Dua jenis workspace

{% tabs %}
{% tab title="👤 Pribadi" %}

|                     |                                            |
| ------------------- | ------------------------------------------ |
| **Milik**           | Satu orang — ikut ke mana pun dia          |
| **Siapa bisa buka** | **Hanya pemilik** — admin grup pun ditolak |
| **Dibuat oleh**     | Siapa saja                                 |
| **Batas**           | 10 per orang                               |

Workspace pribadi tetap bisa dibuka pemiliknya **dari dalam grup** — dengan peringatan satu kali bahwa isinya jadi terbaca anggota lain. Yang bisa *mengubah* tetap hanya pemilik.
{% endtab %}

{% tab title="👥 Grup" %}

|                     |                                 |
| ------------------- | ------------------------------- |
| **Milik**           | Satu grup                       |
| **Siapa bisa buka** | Admin + anggota yang di-`share` |
| **Dibuat oleh**     | Admin grup                      |
| **Batas**           | 10 per grup                     |

Admin yang turun jabatan **langsung kehilangan akses** — status admin dicek saat itu juga, tidak disalin ke daftar terpisah.
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Kenapa identitas disimpan sebagai pasangan nomor + LID?** Satu orang di WhatsApp punya dua identitas, dan mana yang muncul tergantung jenis grupnya. Tanpa memasangkan keduanya, gejalanya adalah *"workspace-ku hilang kalau dibuka dari grup"* — **tanpa error apa pun**.
{% endhint %}

## Cara pakai

{% tabs %}
{% tab title="Lewat obrolan (cara utama)" %}

```
"bikin project todo-api, tulis servernya pakai express"
"jalanin main.py dong"
"kok error? benerin"
"tambahin fitur export csv"
"hapus project lama-ku yang test itu"
```

Bot memutuskan sendiri urutan tool-nya. Kamu tidak perlu tahu nama action-nya.
{% endtab %}

{% tab title="Lewat /ws (cepat & pasti)" %}

```
/ws list                  daftar semua workspace-mu
/ws new todo-api          bikin (tambah kata "grup" untuk workspace grup)
/ws tree                  daftar berkas
/ws cat index.js          lihat isi
/ws run main.py           jalankan
/ws mv a.js src/a.js      ganti nama / pindahkan
/ws rm index.js           hapus berkas
/ws share @orang          beri akses (workspace grup)
```

Tanpa menunggu model berpikir. Daftar lengkapnya di [Referensi Perintah](/referensi/perintah.md).
{% endtab %}
{% endtabs %}

{% hint style="info" %}
`/ws` dan tool AI memanggil **pelaksana yang sama persis** — keduanya tidak mungkin berbeda perilaku, dan gerbang izinnya cuma satu. Dua jalur = dua perilaku = pintu belakang.
{% endhint %}

## Batas-batas

| Batas                  | Nilai                        | Saat terlampaui                                        |
| ---------------------- | ---------------------------- | ------------------------------------------------------ |
| Workspace per wadah    | 10                           | Ditolak dengan kalimat — **tidak menggusur yang lama** |
| Ukuran workspace       | 20 MB                        | Ditolak, disebut sisa ruangnya                         |
| Berkas per workspace   | 200 (di luar `node_modules`) | Ditolak                                                |
| Ukuran per berkas kode | 2 MB                         | Ditolak                                                |
| Ukuran per media       | 8 MB                         | Ditolak                                                |
| Waktu eksekusi         | 15 dtk (maks 30)             | Proses **+ seluruh anaknya** dibunuh                   |
| Proses bersamaan       | 2 (global)                   | *"Tunggu sebentar ya"*                                 |
| Umur tak tersentuh     | 30 hari                      | Dibersihkan housekeeping                               |

Runtime yang tersedia: **node** (`.js`/`.mjs`/`.cjs`) dan **python** (`.py`).

{% hint style="danger" %}
**Bash sengaja tidak ada — dan tidak akan pernah ada.** Bukan karena belum sempat. Pterodactyl tidak memberi akses root, jadi tiga mitigasi standar mati semua: tidak bisa bikin user terpisah, tidak bisa `chroot`, tidak ada Docker-in-Docker. Shell penuh = akses penuh ke `.env` dan sesi WhatsApp.

Ada **mutation test** yang menjaga keputusan ini: kalau suatu hari `bash` dimasukkan ke enum runtime, tesnya gagal. Alasan lengkapnya di [Keamanan](/referensi/keamanan.md).
{% endhint %}

## Keamanan singkat

Lengkapnya — dan ini bagian yang paling serius dipikirkan — ada di [Keamanan](/referensi/keamanan.md). Ringkasnya:

* Eksekusi **tanpa shell** — argumen berupa array, `; rm -rf` cuma teks biasa
* **Env dibangun dari nol** — API key bot tidak pernah ada di `process.env` kode user
* **Permission model Node** mengurung proses ke folder workspace-nya, ditegakkan runtime
* Path traversal, symlink, dan hardlink ditolak di **satu pintu** yang dipakai semua jalur
* Timeout membunuh **seluruh pohon proses**, bukan cuma induknya

## Lanjut

Bagian paling serunya — kode yang barusan ditulis bot bisa langsung **tayang sebagai website**:

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>🌐 Hosting Website</strong></td><td>Dari "bikinin website" sampai URL yang bisa dibuka siapa pun.</td><td><a href="/pages/sVY1aihcAK5MPXFcACKp">/pages/sVY1aihcAK5MPXFcACKp</a></td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.haikaldev.my.id/coding-and-hosting/workspace.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
