Lewati ke konten

Kontrol jarak jauh dan seluler

Control Center adalah aplikasi desktop, tetapi pekerjaan yang dilacaknya tidak berhenti saat Anda meninggalkan meja. Kontrol jarak jauh memasangkan ponsel Anda dengan cc_server milik Anda, menggunakan Remote, aplikasi pendamping di remote.usectrl.dev, sehingga Anda dapat mengikuti fleet dari sana: membaca pesan dan tiket, membalas agen, memilah umpan berita Anda, tanpa audio, transkrip, kode sumber, atau kredensial yang ada di server pernah meninggalkannya.

Anggap saja ini sebagai pendamping yang sebagian besar hanya untuk membaca bagi dek. Ini tidak dimaksudkan untuk menggantikan klien desktop lengkap.

Ponsel menjangkau cc_server melalui WebSocket: baik koneksi langsung (loopback, LAN, tailnet, atau wss://) maupun ruang yang dibatasi undangan pada broker pensinyalan yang meneruskan frame tersegel. Tidak ada kanal data peer-to-peer.

Ponsel yang dipasangkan menjangkau sebagian kecil permukaan server yang memang disengaja:

  • Baca tiket, agen, space beserta pesannya dan umpan berita Anda
  • Balas: kirim pesan di sebuah space, perbarui atau tetapkan tiket, tandai artikel sebagai sudah dibaca atau disimpan
  • Jalankan playbook: buat instance templat rencana yang tersimpan beserta parameternya. Ini hanya mengusulkan rencana; tidak ada yang dieksekusi atau membelanjakan anggaran sampai operator menyetujuinya di Plan Studio pada klien lengkap
  • Beralih ruang kerja, dari pemilih milik ponsel itu sendiri

Itu hampir semua yang bisa dilakukannya. Ponsel adalah prinsipal dengan hak istimewa lebih rendah daripada klien lengkap. Ia tidak dapat menjalankan proses, membelanjakan anggaran LLM, melakukan push ke GitHub, atau membuat ruang kerja. Lihat model akses untuk mengetahui bagaimana hal itu ditegakkan, bukan sekadar diniatkan.

Koneksi berjalan melalui relay dengan perantara: server bergabung ke satu ruang yang dibatasi undangan pada broker wss:// sebagai pemiliknya, dan setiap klien yang dipasangkan — desktop, web, ponsel — bergabung ke ruang yang sama dengan token masuk yang dibatasi waktu. Tiga bagian bekerja bersama:

Bagian Peran
Remote (aplikasi ponsel) Aplikasi web pendamping, yang secara bawaan dihosting di remote.usectrl.dev, atau dihosting sendiri. Dimuat di peramban, menyimpan catatan pairing di IndexedDB.
Broker relay Relay wss:// tanpa status (cc_signaling_server) yang menghosting ruang N-arah. Ia membawa hanya frame buram: setiap payload tersegel ujung ke ujung antara ponsel dan server, sehingga broker tidak pernah melihat data aplikasi atau rahasia pairing dan tidak pernah menafsirkan apa yang diteruskannya.
cc_server Pemilik ruang. Ia menjawab panggilan ponsel melalui dispatcher yang sama dengan yang digunakan setiap klien lain.

Tawaran pairing membawa deskriptor koneksi yang mencantumkan setiap jalur ke server (LAN, tailnet, wss:// publik, relay) beserta sidik jari identitasnya. Resolver ponsel memilih jalur terbaik yang dapat dijangkau dan menyematkan sidik jari pada koneksi pertama (TOFU); relay menjamin konektivitas bahkan ketika tidak ada jalur langsung, tanpa pernah bisa membaca lalu lintasnya.

Pairing dibuat dari aplikasi dan dikirim sebagai tautan mendalam; lihat Pasangkan perangkat untuk prosedurnya. Yang penting di sini adalah anatominya.

https://<pwa-host>/#<payload>

Payload berada di fragment URL, bagian setelah # yang tidak pernah dikirim peramban ke server, sehingga host HTTPS PWA tidak pernah melihatnya. Payload membawa semua yang dibutuhkan ponsel untuk menjangkau server dan membuktikan identitasnya: deskriptor koneksi (setiap jalur ditambah sidik jari identitas), id perangkat yang baru dibuat, kunci yang dibagikan sebelumnya sepanjang 32 byte, dan stempel kedaluwarsa. Ponsel mendekodenya, menyimpan catatan pairing secara lokal, dan menghapus fragment agar rahasianya hilang dari URL.

Ada dua bentuk payload dan keduanya tidak dapat dipertukarkan. QR ponsel yang dibuat dari panel pairing di dalam aplikasi adalah PairingPayload v2 di atas, yang diarahkan ke host PWA Remote. cc_server pair --client-url menghasilkan tautan v1 yang berbeda dan lebih lama ({s, i, k} — URL server, id perangkat, kunci) yang ditujukan hanya untuk klien web.

Keduanya juga berbeda masa berlakunya, dan hal ini mudah disalahpahami:

Dibuat oleh Kedaluwarsa kredensial
Panel pairing di dalam aplikasi (pairing.mint) 30 hari, selalu
cc_server pair di baris perintah Tidak ada — kredensial tidak kedaluwarsa

Perangkat yang dipasangkan bersifat terautentikasi tetapi tidak tepercaya. Beberapa gerbang independen mencegah pairing yang disetujui (atau bocor) berubah menjadi kendali penuh atas server.

1. Keanggotaan, bukan pairing, adalah batasnya

Bagian berjudul “1. Keanggotaan, bukan pairing, adalah batasnya”

Kunci pairing yang valid membuktikan perangkat mana Anda. Apa yang boleh Anda baca atau ubah ditentukan oleh peran ruang kerja Anda, yang diselesaikan ulang pada setiap panggilan, dan oleh izin per repo untuk apa pun yang mengekspos konten repo. Perangkat yang memegang kunci yang sepenuhnya sah tetapi dimiliki oleh pengguna yang bukan anggota ruang kerja yang disebutkan akan ditolak dengan “Not a member of this workspace”.

Batas bawah peran diturunkan dari jenis operasinya, kecuali operasi itu mendeklarasikan batasnya sendiri: pembacaan memerlukan guest, mutasi memerlukan member, operasi destruktif memerlukan admin.

2. Ponsel adalah tingkat sesi yang lebih rendah

Bagian berjudul “2. Ponsel adalah tingkat sesi yang lebih rendah”

Selain pemeriksaan peran, sesi ponsel membawa kemampuan yang lebih rendah daripada sesi desktop atau web. Operasi yang dideklarasikan khusus klien lengkap ditolak untuk ponsel sebelum handler berjalan, tanpa memandang seberapa tinggi hak istimewa pengguna di baliknya: membuat, menampilkan, mengganti nama, dan mencabut pairing perangkat; membaca dan menyetel konektivitas tunnel; pencadangan server serta ekspor/impor ruang kerja; deteksi dan penghentian proses; probe adapter; pengaturan server; admin SSO; kendali fleet; serta mengambil alih atau mengembalikan agen yang sedang berjalan.

3. Daftar izin alat yang menolak secara bawaan

Bagian berjudul “3. Daftar izin alat yang menolak secara bawaan”

Khusus untuk permukaan alat MCP (tools/call), daftar izin yang menolak secara bawaan mengatur alat mana yang boleh dipanggil ponsel. Apa pun yang tidak terdaftar akan ditolak sebelum dijalankan. Daftar itu didominasi operasi baca dan observasi, ditambah segelintir penulisan yang hanya lokal — sebuah pesan, pembaruan tiket, penandaan artikel — yang tidak membelanjakan anggaran LLM, tidak menjalankan proses, dan tidak menyentuh sistem eksternal.

Misalnya ditolak: berkonsultasi dengan agen, memulai tinjauan AI, menghentikan agen, menerbitkan tinjauan ke GitHub, merekrut atau memberhentikan agen, membuat ruang kerja.

Server tidak menyimpan “ruang kerja saat ini”. Ia tanpa status secara desain: setiap panggilan yang bercakupan ruang kerja harus menyebutkan workspace_id targetnya dalam argumennya, dan dispatcher menolak panggilan itu mentah-mentah ketika id tersebut tidak ada atau menyebut ruang kerja yang tidak terdaftar di server — sebelum apa pun membuka basis data. Karena itu, ponsel tidak akan pernah mewarisi atau tergelincir ke cakupan klien lain, dan menyebut ruang kerja asing juga tidak membantu, karena pemeriksaan keanggotaan di gerbang 1 tetap berlaku. Ini adalah invarian isolasi ruang kerja yang sama dengan yang ditegakkan oleh bagian lain produk.

5. Frame tersegel ujung ke ujung yang dikunci dengan kunci yang dibagikan sebelumnya

Bagian berjudul “5. Frame tersegel ujung ke ujung yang dikunci dengan kunci yang dibagikan sebelumnya”

Setiap frame antara ponsel dan server tersegel dengan kunci pairing; token masuk hanya membawa klien ke dalam ruang, ia tidak mendekripsi apa pun. Broker meneruskan ciphertext dan tidak pernah melihat kuncinya. Perangkat yang dicabut akan mendapati kredensialnya sudah hilang, sehingga ia gagal secara tertutup saat menyambung kembali.

Kredensial yang dibuat aplikasi dibatasi waktu 30 hari; setelah itu gerbang koneksi menolaknya dan ponsel harus melakukan pairing ulang. Pencabutan bersifat langsung: server memantau tabel perangkat dan memutus sesi terbuka perangkat yang dicabut dalam hitungan detik, bukan menunggu koneksi berikutnya.

Pembatas jendela geser membatasi lalu lintas alat jarak jauh pada 120 panggilan per menit, dengan sub-batas yang lebih ketat 30 per menit untuk verb yang mengubah data. Anggaran itu milik prinsipal, bukan sesi: tiga perangkat Anda menarik dari satu jatah, sehingga klien yang dibajak tidak dapat menambah kelonggaran dengan membuka lebih banyak sesi dan satu anggota yang berisik tidak dapat merampas jatah anggota lain.

Broker relay sengaja dibuat bodoh: ia menghosting ruang, meneruskan frame tersegel, dan tidak menyimpan akun, data aplikasi, maupun kunci. Ruang dibatasi undangan dan bersifat sementara. Data aplikasi, audio, transkrip, kode sumber, dan kredensial semuanya tetap berada di server.

Setelah dipasangkan, ponsel menerima pembaruan langsung sebagai frame notifikasi — pesan agen baru, tiket yang ditugaskan kepada Anda, perubahan status — yang mencerminkan notifikasi desktop itu sendiri. Server menyiarkan frame tersebut ke setiap sesi yang terhubung dan filter ruang kerja diterapkan di sisi klien, sehingga apa yang Anda lihat terbatas pada ruang kerja yang sedang Anda lihat.

Permukaan Apa yang ditampilkan
Pengaturan → Anda → Perangkat Anda (/workspaces/:workspaceId/settings/you/devices) Klien yang dipasangkan beserta status langsungnya, plus Pasangkan klien baru (peramban web, aplikasi desktop, atau ponsel) dan cabut

Panel yang sama juga membuat pairing untuk peramban atau aplikasi desktop kedua, bukan hanya ponsel — alurnya identik, hanya tautan mendalamnya yang berbeda.