ข้ามไปยังเนื้อหา

ควบคุมระยะไกลและมือถือ

Control Center เป็นแอปเดสก์ท็อป แต่งานที่มันติดตามอยู่ไม่หยุดลงเมื่อคุณลุกจากโต๊ะ การควบคุมระยะไกลจับคู่โทรศัพท์ของคุณกับ cc_server โดยใช้ Remote ซึ่งเป็นแอปคู่หูที่ remote.usectrl.dev เพื่อให้คุณติดตามฟลีตได้จากที่นั่น: อ่านข้อความและตั๋วงาน ตอบกลับเอเจนต์ คัดแยกฟีดข่าวของคุณ โดยที่เสียง ถอดเสียง ซอร์สโค้ด หรือข้อมูลรับรองที่อยู่บน เซิร์ฟเวอร์จะไม่หลุดออกไปจากเซิร์ฟเวอร์เลย

คิดว่ามันเป็นคู่หูที่เน้นการอ่านเป็นหลักของหน้าจอหลัก ไม่ได้มีไว้แทนที่ ไคลเอนต์เดสก์ท็อปเต็มรูปแบบ

โทรศัพท์เข้าถึง cc_server ผ่าน WebSocket ไม่ว่าจะเป็นการเชื่อมต่อโดยตรง (ลูปแบ็ก LAN tailnet หรือ wss://) หรือห้องที่ต้องมีคำเชิญบนโบรกเกอร์ส่งสัญญาณ ซึ่งส่งต่อเฟรมที่ปิดผนึกไว้ ไม่มีช่องข้อมูลแบบเพียร์ทูเพียร์

โทรศัพท์ที่จับคู่แล้วเข้าถึงพื้นผิวของเซิร์ฟเวอร์ได้เพียงส่วนเล็กๆ ที่จงใจจำกัดไว้:

  • อ่าน ตั๋วงาน เอเจนต์ สเปซ และข้อความของสิ่งเหล่านั้น รวมทั้งฟีดข่าวของคุณ
  • ตอบกลับ: ส่งข้อความในสเปซ อัปเดตหรือมอบหมายตั๋วงาน ทำเครื่องหมายบทความ ว่าอ่านแล้วหรือบันทึกไว้
  • รันเพลย์บุ๊ก: สร้างอินสแตนซ์ของเทมเพลตแผนที่บันทึกไว้พร้อมพารามิเตอร์ของมัน สิ่งนี้เพียง_เสนอ_แผนเท่านั้น ไม่มีอะไรทำงานหรือใช้จ่ายจนกว่าผู้ปฏิบัติงาน จะอนุมัติใน Plan Studio บนไคลเอนต์เต็มรูปแบบ
  • สลับเวิร์กสเปซ จากตัวเลือกของโทรศัพท์เอง

เท่านี้ก็เกือบทั้งหมดแล้ว โทรศัพท์เป็นพรินซิปัลที่มีสิทธิ์ต่ำกว่าไคลเอนต์ เต็มรูปแบบ จึงสร้างกระบวนการ ใช้งบ LLM พุชไปยัง GitHub หรือสร้างเวิร์กสเปซไม่ได้ ดูโมเดลการเข้าถึงเพื่อดูว่าสิ่งนี้ถูกบังคับใช้อย่างไร ไม่ใช่แค่ตั้งใจไว้

การเชื่อมต่ออาศัยรีเลย์แบบมีตัวกลาง: เซิร์ฟเวอร์เข้าร่วมห้องที่ต้องมีคำเชิญ หนึ่งห้องบนโบรกเกอร์ wss:// ในฐานะเจ้าของ และไคลเอนต์ที่จับคู่แล้วทุกตัว — เดสก์ท็อป เว็บ โทรศัพท์ — เข้าร่วมห้องเดียวกันด้วยโทเค็นอนุญาตเข้าที่จำกัดเวลา องค์ประกอบสามส่วนทำงานร่วมกัน:

องค์ประกอบ บทบาท
Remote (แอปโทรศัพท์) เว็บแอปคู่หู ซึ่งโดยค่าเริ่มต้นโฮสต์ที่ remote.usectrl.dev หรือโฮสต์เองก็ได้ โหลดในเบราว์เซอร์ และเก็บบันทึกการจับคู่ไว้ใน IndexedDB
โบรกเกอร์รีเลย์ รีเลย์ wss:// ที่ไม่เก็บสถานะ (cc_signaling_server) ซึ่งโฮสต์ห้องแบบ N ทาง โดยบรรทุกเฉพาะเฟรมทึบ: ทุกเพย์โหลดถูกปิดผนึกแบบต้นทางถึงปลายทางระหว่างโทรศัพท์กับเซิร์ฟเวอร์ โบรกเกอร์จึงไม่เห็นข้อมูลแอปหรือความลับของการจับคู่ และไม่ตีความสิ่งที่มันส่งต่อเลย
cc_server เจ้าของห้อง ตอบคำเรียกจากโทรศัพท์ผ่านตัวจ่ายงานตัวเดียวกับที่ไคลเอนต์อื่นทุกตัวใช้

ข้อเสนอการจับคู่มีตัวบ่งชี้การเชื่อมต่อที่ระบุทุกเส้นทางไปยังเซิร์ฟเวอร์ (LAN tailnet wss:// สาธารณะ รีเลย์) พร้อมลายนิ้วมือระบุตัวตนของเซิร์ฟเวอร์ ตัวเลือกเส้นทางของโทรศัพท์จะเลือกเส้นทางที่ดีที่สุดที่เข้าถึงได้ และปักหมุด ลายนิ้วมือเมื่อเชื่อมต่อครั้งแรก (TOFU) รีเลย์รับประกันการเชื่อมต่อแม้ไม่มี เส้นทางโดยตรง โดยไม่สามารถอ่านทราฟฟิกได้เลย

การจับคู่ถูกสร้างจากแอปและส่งมอบเป็นดีปลิงก์ ดู จับคู่อุปกรณ์ สำหรับขั้นตอน สิ่งที่สำคัญในที่นี้ คือโครงสร้างของมัน

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

เพย์โหลดอยู่ในแฟรกเมนต์ของ URL ซึ่งเป็นส่วนหลัง # ที่เบราว์เซอร์ไม่เคยส่ง ไปยังเซิร์ฟเวอร์ โฮสต์ HTTPS ของ PWA จึงไม่เคยเห็นมัน เพย์โหลดบรรทุกทุกอย่าง ที่โทรศัพท์ต้องใช้เพื่อเข้าถึงเซิร์ฟเวอร์และพิสูจน์ว่ามันคือใคร: ตัวบ่งชี้ การเชื่อมต่อ (ทุกเส้นทางพร้อมลายนิ้วมือระบุตัวตน) รหัสอุปกรณ์ที่เพิ่งสร้างใหม่ คีย์ที่แชร์ล่วงหน้า 32 ไบต์ และตราประทับเวลาหมดอายุ โทรศัพท์ถอดรหัสเพย์โหลด เก็บบันทึกการจับคู่ไว้ในเครื่อง และตัดแฟรกเมนต์ออกเพื่อให้ความลับหลุดออกจาก URL

เพย์โหลดมีสองรูปแบบและใช้แทนกันไม่ได้ QR ของโทรศัพท์ที่สร้างจากแผงจับคู่ ในแอปคือ PairingPayload v2 ข้างต้น ซึ่งชี้ไปที่โฮสต์ PWA ของ Remote ส่วน cc_server pair --client-url จะสร้างลิงก์ v1 ที่เก่ากว่าและต่างออกไป ({s, i, k} — URL เซิร์ฟเวอร์ รหัสอุปกรณ์ คีย์) ซึ่งมีไว้สำหรับไคลเอนต์เว็บ เท่านั้น

ทั้งสองยังมีอายุการใช้งานต่างกัน ซึ่งเข้าใจผิดได้ง่าย:

ออกโดย การหมดอายุของข้อมูลรับรอง
แผงจับคู่ในแอป (pairing.mint) 30 วันเสมอ
cc_server pair บนบรรทัดคำสั่ง ไม่มี — ข้อมูลรับรองไม่หมดอายุ

อุปกรณ์ที่จับคู่แล้วผ่านการรับรองความถูกต้องแต่ไม่ได้รับความเชื่อถือ ด่านอิสระหลายชั้นช่วยไม่ให้การจับคู่ที่ได้รับอนุมัติ (หรือรั่วไหล) กลายเป็น การควบคุมเซิร์ฟเวอร์ทั้งหมด

คีย์จับคู่ที่ถูกต้องพิสูจน์ว่า_คุณคืออุปกรณ์ใด_ สิ่งที่คุณอ่านหรือแก้ไขได้ ตัดสินจากบทบาทในเวิร์กสเปซของคุณ ซึ่งคำนวณใหม่ในการเรียกทุกครั้ง และจากสิทธิ์ที่ให้ในระดับรีโปสำหรับทุกอย่างที่เปิดเผยเนื้อหาของรีโป อุปกรณ์ ที่ถือคีย์ซึ่งใช้ได้ดีแต่เป็นของผู้ใช้ที่ไม่ได้เป็นสมาชิกของเวิร์กสเปซที่ระบุ จะถูกปฏิเสธด้วยข้อความ “Not a member of this workspace”

ระดับบทบาทขั้นต่ำอนุมานจากชนิดของการดำเนินการ เว้นแต่การดำเนินการนั้น จะประกาศระดับของตัวเอง: การอ่านต้องมี guest การเปลี่ยนแปลงต้องมี member และการดำเนินการที่ทำลายข้อมูลต้องมี admin

นอกเหนือจากการตรวจสอบบทบาท เซสชันของโทรศัพท์ยังมีความสามารถต่ำกว่าเซสชัน เดสก์ท็อปหรือเว็บ การดำเนินการที่ประกาศว่าใช้ได้เฉพาะไคลเอนต์เต็มรูปแบบ จะถูกปฏิเสธสำหรับโทรศัพท์ก่อนที่ตัวจัดการจะทำงาน ไม่ว่าผู้ใช้ที่อยู่เบื้องหลัง จะมีสิทธิ์มากเพียงใด: การออก รายการ เปลี่ยนชื่อ และเพิกถอนการจับคู่อุปกรณ์; การอ่านและตั้งค่าการเชื่อมต่ออุโมงค์; การสำรองข้อมูลเซิร์ฟเวอร์และการนำออก/ นำเข้าเวิร์กสเปซ; การตรวจจับและฆ่ากระบวนการ; การตรวจสอบอะแดปเตอร์; การตั้งค่าเซิร์ฟเวอร์; การดูแล SSO; การควบคุมฟลีต; และการเข้ายึดหรือคืน เอเจนต์ที่กำลังทำงาน

3. รายการอนุญาตเครื่องมือแบบปฏิเสธโดยค่าเริ่มต้น

หัวข้อที่มีชื่อว่า “3. รายการอนุญาตเครื่องมือแบบปฏิเสธโดยค่าเริ่มต้น”

สำหรับพื้นผิวเครื่องมือ MCP โดยเฉพาะ (tools/call) รายการอนุญาตแบบปฏิเสธ โดยค่าเริ่มต้นจะควบคุมว่าโทรศัพท์เรียกเครื่องมือใดได้ สิ่งที่ไม่อยู่ในรายการ จะถูกปฏิเสธก่อนที่จะทำงาน รายการนี้เน้นการอ่านและการเฝ้าดูเป็นหลัก บวกการเขียนเฉพาะในเครื่องไม่กี่อย่าง — ข้อความหนึ่งข้อความ การอัปเดต ตั๋วงานหนึ่งครั้ง การทำเครื่องหมายบทความหนึ่งรายการ — ซึ่งไม่ใช้งบ LLM ไม่สร้างกระบวนการ และไม่แตะระบบภายนอก

ตัวอย่างที่ถูกปฏิเสธ: การปรึกษาเอเจนต์ การเริ่มรีวิวด้วย AI การฆ่าเอเจนต์ การเผยแพร่รีวิวไปยัง GitHub การจ้างหรือปลดเอเจนต์ การสร้างเวิร์กสเปซ

เซิร์ฟเวอร์ไม่มี “เวิร์กสเปซปัจจุบัน” เลย มันไม่เก็บสถานะโดยการออกแบบ: การเรียกที่ผูกกับเวิร์กสเปซทุกครั้งต้องระบุ workspace_id เป้าหมายในอาร์กิวเมนต์ ของตน และตัวจ่ายงานจะปฏิเสธการเรียกทันทีเมื่อขาดค่านั้นหรือระบุเวิร์กสเปซ ที่เซิร์ฟเวอร์ไม่ได้ลงทะเบียนไว้ — ก่อนที่สิ่งใดจะเปิดฐานข้อมูล โทรศัพท์ จึงสืบทอดหรือหลุดเข้าไปในขอบเขตของไคลเอนต์อื่นไม่ได้เลย และการระบุเวิร์กสเปซ ภายนอกก็ไม่ช่วยเช่นกัน เพราะการตรวจสอบการเป็นสมาชิกในด่านที่ 1 ยังมีผลอยู่ นี่คือหลักประกันการแยกโดเมนของเวิร์กสเปซ แบบเดียวกับที่ผลิตภัณฑ์ส่วนที่เหลือบังคับใช้

5. เฟรมที่ปิดผนึกแบบต้นทางถึงปลายทางด้วยคีย์ที่แชร์ล่วงหน้า

หัวข้อที่มีชื่อว่า “5. เฟรมที่ปิดผนึกแบบต้นทางถึงปลายทางด้วยคีย์ที่แชร์ล่วงหน้า”

ทุกเฟรมระหว่างโทรศัพท์กับเซิร์ฟเวอร์ถูกปิดผนึกด้วยคีย์จับคู่ โทเค็นอนุญาตเข้า เพียงนำไคลเอนต์เข้าห้องเท่านั้น ไม่ได้ถอดรหัสสิ่งใด โบรกเกอร์ส่งต่อข้อความ เข้ารหัสและไม่เคยเห็นคีย์ อุปกรณ์ที่ถูกเพิกถอนจะพบว่าข้อมูลรับรองของตนหายไปแล้ว จึงล้มเหลวแบบปิดเมื่อเชื่อมต่อใหม่

ข้อมูลรับรองที่สร้างจากแอปถูกจำกัดเวลาไว้ 30 วัน เมื่อเกินกว่านั้นด่าน การเชื่อมต่อจะปฏิเสธ และโทรศัพท์ต้องจับคู่ใหม่ การเพิกถอนมีผลทันที: เซิร์ฟเวอร์เฝ้าดูตารางอุปกรณ์และตัดเซสชันที่เปิดอยู่ของอุปกรณ์ที่ถูกเพิกถอน ภายในไม่กี่วินาที แทนที่จะรอการเชื่อมต่อครั้งถัดไป

ตัวจำกัดแบบหน้าต่างเลื่อนกำหนดเพดานทราฟฟิกเครื่องมือระยะไกลไว้ที่ 120 ครั้ง ต่อนาที พร้อมเพดานย่อยที่เข้มกว่าคือ 30 ครั้งต่อนาทีสำหรับคำสั่งที่เปลี่ยนแปลง ข้อมูล งบนี้เป็นของพรินซิปัล ไม่ใช่ของเซสชัน: อุปกรณ์สามเครื่องของคุณ ใช้โควตาเดียวกัน ไคลเอนต์ที่ถูกยึดจึงหาพื้นที่เพิ่มไม่ได้ด้วยการเปิดเซสชัน มากขึ้น และสมาชิกที่ส่งคำขอถี่ก็ทำให้สมาชิกคนอื่นอดโควตาไม่ได้

โบรกเกอร์รีเลย์ถูกออกแบบให้เรียบง่ายโดยเจตนา: มันโฮสต์ห้อง ส่งต่อเฟรม ที่ปิดผนึก และไม่เก็บบัญชี ข้อมูลแอป หรือคีย์ใดๆ ห้องต้องมีคำเชิญและอยู่ ชั่วคราว ข้อมูลแอป เสียง ถอดเสียง ซอร์สโค้ด และข้อมูลรับรองทั้งหมดยังคง อยู่บนเซิร์ฟเวอร์

เมื่อจับคู่แล้ว โทรศัพท์จะได้รับการอัปเดตสดเป็นเฟรมแจ้งเตือน — ข้อความใหม่ จากเอเจนต์ ตั๋วงานที่มอบหมายให้คุณ การเปลี่ยนแปลงสถานะ — สะท้อนการแจ้งเตือน ของเดสก์ท็อปเอง เซิร์ฟเวอร์กระจายเฟรมเหล่านั้นไปยังทุกเซสชันที่เชื่อมต่ออยู่ และตัวกรองเวิร์กสเปซถูกใช้ฝั่งไคลเอนต์ สิ่งที่คุณเห็นจึงจำกัดขอบเขตอยู่ที่ เวิร์กสเปซที่คุณกำลังดูอยู่

ส่วนติดต่อ สิ่งที่แสดง
การตั้งค่า → คุณ → อุปกรณ์ของคุณ (/workspaces/:workspaceId/settings/you/devices) ไคลเอนต์ที่จับคู่แล้วพร้อมสถานะสด พร้อมปุ่ม จับคู่ไคลเอนต์ใหม่ (เว็บเบราว์เซอร์ แอปเดสก์ท็อป หรือโทรศัพท์) และเพิกถอน

แผงเดียวกันยังออกการจับคู่สำหรับเบราว์เซอร์หรือแอปเดสก์ท็อปเครื่องที่สอง ไม่ใช่แค่โทรศัพท์ — ขั้นตอนเหมือนกันทุกประการ ต่างกันแค่ดีปลิงก์