clew-code 0.2.13 → 0.2.14

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 (52) hide show
  1. package/dist/main.js +2596 -2527
  2. package/docs/architecture.html +148 -148
  3. package/docs/architecture.th.html +79 -79
  4. package/docs/clew-code-architecture.html +6 -6
  5. package/docs/commands.html +225 -224
  6. package/docs/commands.th.html +132 -131
  7. package/docs/configuration.html +147 -147
  8. package/docs/configuration.th.html +108 -108
  9. package/docs/daemon.html +129 -129
  10. package/docs/daemon.th.html +73 -73
  11. package/docs/features/bridge-mode.html +99 -99
  12. package/docs/features/bridge-mode.th.html +90 -90
  13. package/docs/features/evals.html +182 -182
  14. package/docs/features/evals.th.html +90 -90
  15. package/docs/features/peer.html +178 -178
  16. package/docs/features/searxng-search.html +151 -151
  17. package/docs/features/searxng-search.th.html +95 -95
  18. package/docs/features/sentry-setup.html +157 -157
  19. package/docs/features/sentry-setup.th.html +97 -97
  20. package/docs/index.html +298 -299
  21. package/docs/index.th.html +292 -292
  22. package/docs/installation.html +105 -105
  23. package/docs/installation.th.html +105 -105
  24. package/docs/internals/growthbook-ab-testing.html +113 -113
  25. package/docs/internals/growthbook-ab-testing.th.html +81 -81
  26. package/docs/internals/hidden-features.html +175 -149
  27. package/docs/internals/hidden-features.th.html +135 -109
  28. package/docs/loop.html +181 -181
  29. package/docs/loop.th.html +227 -227
  30. package/docs/mcp.html +247 -247
  31. package/docs/mcp.th.html +207 -207
  32. package/docs/models.html +110 -111
  33. package/docs/models.th.html +61 -61
  34. package/docs/peer.html +236 -236
  35. package/docs/peer.th.html +280 -280
  36. package/docs/permission-model.html +102 -102
  37. package/docs/permission-model.th.html +67 -67
  38. package/docs/plugins.html +102 -102
  39. package/docs/plugins.th.html +79 -79
  40. package/docs/providers.html +126 -126
  41. package/docs/providers.th.html +80 -80
  42. package/docs/quick-start.html +93 -93
  43. package/docs/quick-start.th.html +1 -1
  44. package/docs/research-memory.html +82 -82
  45. package/docs/research-memory.th.html +72 -72
  46. package/docs/skills.html +117 -117
  47. package/docs/skills.th.html +90 -90
  48. package/docs/tools.html +170 -170
  49. package/docs/tools.th.html +84 -84
  50. package/docs/troubleshooting.html +106 -106
  51. package/docs/troubleshooting.th.html +85 -85
  52. package/package.json +162 -164
package/docs/peer.th.html CHANGED
@@ -1,280 +1,280 @@
1
- <!DOCTYPE html>
2
- <html lang="th">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>ระบบ Peer — Clew</title>
7
- <meta name="description" content="ระบบ peer-to-peer บน LAN — ค้นหา, ส่งข้อความ, มอบหมายงาน, และรันคำสั่งระยะไกลระหว่าง Clew instances">
8
- <link rel="preconnect" href="https://fonts.googleapis.com">
9
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
- <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Noto+Sans+Thai:wght@400;500;600;700&display=swap" rel="stylesheet">
11
- <link rel="stylesheet" href="css/styles.css">
12
- <link rel="icon" type="image/svg+xml" href="./assets/clew.svg">
13
- </head>
14
- <body>
15
- <header class="header"></header>
16
- <div class="app">
17
- <aside class="sidebar" id="sidebar"></aside>
18
- <div class="sidebar-overlay" id="sidebarOverlay"></div>
19
- <div class="content-wrap">
20
- <main class="content">
21
- <div class="breadcrumbs"><a href="index.th.html">หน้าแรก</a><span class="sep">/</span><span>ระบบ Peer</span></div>
22
- <h1>ระบบ Peer</h1>
23
- <p class="section-subtitle">Peer-to-peer บน LAN — ค้นหา Clew instances อื่น, ส่งข้อความ, มอบหมายงาน, และรันคำสั่งระยะไกล</p>
24
-
25
- <p>ระบบ peer อยู่ใน <code>src/peer/</code> และประกอบด้วย 3 ชั้นหลัก: <strong>PeerServer</strong> (HTTP server), <strong>PeerDiscovery</strong> (สแกน LAN), และ <strong>PeerStore</strong> (registry ในหน่วยความจำ)</p>
26
-
27
- <h2>สถาปัตยกรรม</h2>
28
- <pre><code> ┌─────────────────────────────────────────────────────────────────────────────┐
29
- │ PEER SYSTEM FLOW │
30
- └─────────────────────────────────────────────────────────────────────────────┘
31
-
32
- ┌──────────────────────────┐
33
- │ /peer share │
34
- │ (Machine A — Worker) │
35
- └────────────┬─────────────┘
36
- │
37
- ┌─────────────────┼─────────────────┐
38
- â–¼ â–¼ â–¼
39
- ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
40
- │ PeerServer │ │PeerDiscovery │ │ PeerStore │
41
- │ HTTP :random │ │ │ │ (in-memory) │
42
- │ port │ │ │ │ │
43
- └──────┬───────┘ └──────┬───────┘ └──────────────┘
44
- │ │
45
- │ ┌────────────┼────────────┐
46
- │ │ │ │
47
- │ ▼ ▼ ▼
48
- │ ┌────────┐ ┌────────┐ ┌─────────────┐
49
- │ │ File │ │ UDP │ │ PeerStore │
50
- │ │ ~/.cl/ │ │multicast│ │ (singleton) │
51
- │ │ peers/ │ │239... │ │ │
52
- │ │{pid}. │ │:42069 │ │ │
53
- │ │ json │ │ │ │ │
54
- │ └────┬───┘ └────┬───┘ └─────────────┘
55
- │ │ │
56
- │ │ │ heartbeat ทุก 30s
57
- │ │ │ stale timeout 90s
58
- │ │ │
59
- â–¼ â–¼ â–¼
60
- ┌─────────────────────────────────────────────────────┐
61
- │ LAN NETWORK │
62
- │ │
63
- │ ┌─────────┐ ┌─────────┐ │
64
- │ │ Machine B│◄───────►│ Machine C│ ... │
65
- │ │ Clew Code│ query │ Clew Code│ │
66
- │ └────┬─────┘ └────┬─────┘ │
67
- │ │ │ │
68
- └────────┼────────────────────┼─────────────────────────┘
69
- │ │
70
- │ /peer discover │ /peer discover
71
- â–¼ â–¼
72
-
73
-
74
- ═══ WORKER (Machine A) ENDPOINTS ═══
75
-
76
- Peer อื่น POST /peer-info ──► { hostname, ip, cwd, shell, ... }
77
- │ POST /peer-msg ──► รับข้อความ chat
78
- ├───────────────► POST /peer-todo ──► รับ task (ไปอยู่ใน inbox)
79
- │ POST /peer-exec ──► รัน shell command + คืน stdout/stderr
80
-
81
-
82
- ═══ CLIENT (Machine B) TOOLS ═══
83
-
84
- /peer discover ──► scan files + UDP query (3s timeout)
85
- │
86
- â–¼
87
- [peer list]
88
- │
89
- ┌───────────────────┼───────────────────┐
90
- â–¼ â–¼ â–¼
91
- /peer join /peer send_task /peer run
92
- (POST /peer-info) (POST /peer-todo) (POST /peer-exec)
93
-
94
- │
95
- â–¼
96
- /peer send_message ──► POST /peer-msg ──► inbox ปลายทาง
97
- /peer broadcast ──► POST /peer-msg ──► ทุก peer ที่เชื่อมต่อ
98
- /peer ping ──► GET /peer-info ──► เช็ค alive
99
-
100
-
101
- ═══ DAEMON (agentLoop.ts) ═══
102
-
103
- ┌───────────────────────────────────┐
104
- │ Autonomous Agent Loop │
105
- │ - ฟัง /peer-todo ตลอด 24/7 │
106
- │ - รับ task จาก remote peers │
107
- │ - execute ใน background worker │
108
- │ - สูงสุด 3 workers พร้อมกัน │
109
- └───────────────────────────────────┘
110
-
111
-
112
- ═══ DATA LIFECYCLE ═══
113
-
114
- advertise ──► heartbeat ทุก 30s
115
- │
116
- ├── 90s ไม่มี heartbeat ──► stale → evict
117
- │
118
- stop share ──► send UDP "offline"
119
- delete peer file
120
- close HTTP server</code></pre>
121
-
122
- <h2>เทคนิคและหลักการ</h2>
123
-
124
- <h3>Discovery แบบสองชั้น (Two-Layer Discovery)</h3>
125
- <p>ทำไมไม่ใช้แค่ UDP multicast หรือแค่ file-based อย่างเดียว?</p>
126
- <ul>
127
- <li><strong>File-based</strong> — ทำงานบนเครื่องเดียวกันได้ทันที โดยไม่ต้องใช้ network เลย แค่อ่าน/เขียนไฟล์ JSON ใน <code>~/.claude/peers/</code> ซึ่งเร็วกว่าและไม่ต้องกังวลเรื่อง firewall</li>
128
- <li><strong>UDP Multicast</strong> — ข้ามเครื่องได้ผ่าน LAN ใช้ multicast group <code>239.255.37.37:42069</code> ไม่ต้องรู้ IP ปลายทางล่วงหน้า</li>
129
- <li><strong>ทำไมต้องทั้งสอง?</strong> — แต่ละวิธีมีข้อจำกัด: file-based ข้ามเครื่องไม่ได้, UDP multicast อาจถูกบล็อคด้วย network policy การใช้ทั้งสองวิธีทำให้ discovery ทำงานได้ในทุกสภาพแวดล้อม โดยไม่ต้องให้ผู้ใช้ configure อะไรเลย</li>
130
- </ul>
131
-
132
- <h3>Lease-based Task Claiming</h3>
133
- <p>เมื่อมีหลาย worker (หรือหลาย daemon process) วิ่งพร้อมกัน จะป้องกันไม่ให้ task ถูกทำซ้ำได้อย่างไร?</p>
134
- <ul>
135
- <li><strong>Atomic lease</strong> — ก่อนเริ่ม task, worker ต้องขอ lease ด้วย <code>leaseTask(id, agentId)</code> ซึ่งเช็คว่า task ยังไม่มีใครจอง และเขียน lease owner + expiry timestamp ลงไฟล์แบบ atomic (read-modify-write ภายใต้ lock)</li>
136
- <li><strong>Lease expiry</strong> — ถ้า worker crash หรือ disconnect, lease จะหมดอายุเอง (default 30 นาที) ทำให้ worker อื่นมารับงานต่อได้ — <em>crash recovery โดยไม่ต้องมี distributed coordinator</em></li>
137
- <li><strong>Stale lease cleanup</strong> — ตอน startLoop จะรอ 2 วินาที แล้วเรียก <code>expireLeases()</code> เพื่อ clear lease เก่าจาก session ก่อนหน้า</li>
138
- <li><strong>ทำไมไม่ใช้ lock file?</strong> — lock file แบบ OS-level (flock) ใช้ข้าม process บนเครื่องเดียวกันได้ แต่ใช้ข้ามเครื่องไม่ได้ Lease บนไฟล์ JSON แก้ปัญหานี้ได้โดยไม่ต้องพึ่ง external service อย่าง Redis/ZooKeeper</li>
139
- </ul>
140
-
141
- <h3>Heartbeat + Stale Eviction</h3>
142
- <p>Peer discovery ต้องรู้ว่าใครยัง alive อยู่ โดยไม่ต้อง polling:</p>
143
- <ul>
144
- <li><strong>Push-based heartbeat</strong> — แต่ละ peer ส่ง beacon ทุก 30 วินาที ผ่านทั้ง file (เขียน timestamp ใหม่) และ UDP multicast</li>
145
- <li><strong>Pull-based eviction</strong> — consumer เช็คอายุของ peer entry ถ้าเกิน 90 วินาที (<code>PEER_STALE_TIMEOUT</code>) ถือว่า stale → evict</li>
146
- <li><strong>3× heartbeat interval</strong> — timeout = 3 × heartbeat interval เป็นค่า default ในระบบ distributed systems (ให้โอกาส retry ก่อน宣布ตาย)</li>
147
- <li><strong>Graceful shutdown</strong> — ตอน <code>/peer stop</code> จะส่ง UDP "offline" message + ลบไฟล์ peer ทันที ไม่ต้องรอ timeout</li>
148
- </ul>
149
-
150
- <h3>Random Port Binding</h3>
151
- <p>PeerServer bind ที่ port 0 (OS เลือก port ว่างให้):</p>
152
- <ul>
153
- <li><strong>No port conflicts</strong> — ถ้าใช้ fixed port แล้วมีหลาย instance จะชนกัน</li>
154
- <li><strong>Security through obscurity</strong> — port สุ่มทำให้ attacker สแกนหายากกว่า fixed port (แต่ไม่ใช่ security หลัก — security จริงอยู่ที่ authentication layer)</li>
155
- <li><strong>Discovery solves discovery</strong> — ไม่ต้องรู้ port ล่วงหน้า เพราะ discovery protocol จะบอก port ให้เอง</li>
156
- </ul>
157
-
158
- <h3>Message Broadcasting</h3>
159
- <p><code>peer_broadcast</code> ส่ง task ไปทุก peer ที่เชื่อมต่อพร้อมกัน:</p>
160
- <ul>
161
- <li>ไม่ใช่ UDP broadcast — ใช้ HTTP POST sequential ไปทีละ peer (fire-and-forget)</li>
162
- <li>รองรับ parallel สูงสุด 8 peers ต่อ 1 batch</li>
163
- <li>เหมาะสำหรับ: deploy to all machines, run tests everywhere, health check ทุก node</li>
164
- </ul>
165
-
166
- <h2>องค์ประกอบหลัก</h2>
167
-
168
- <h3>PeerServer <code>src/peer/PeerServer.ts</code></h3>
169
- <p>HTTP server ขนาดเล็กที่เริ่มบน port สุ่ม (OS เลือกให้) เมื่อรัน <code>/peer share</code> แต่ละ endpoint รองรับการโต้ตอบแบบต่างๆ:</p>
170
- <table>
171
- <tr><th>Endpoint</th><th>Method</th><th>หน้าที่</th></tr>
172
- <tr><td><code>/peer-info</code></td><td>GET</td><td>ส่งข้อมูล peer (hostname, IP, cwd, shell, platform)</td></tr>
173
- <tr><td><code>/peer-msg</code></td><td>POST</td><td>รับข้อความ chat จาก peer อื่น</td></tr>
174
- <tr><td><code>/peer-todo</code></td><td>POST</td><td>รับ task ที่ถูกมอบหมายจาก peer อื่น</td></tr>
175
- <tr><td><code>/peer-exec</code></td><td>POST</td><td>รันคำสั่ง shell และส่งคืน stdout/stderr</td></tr>
176
- </table>
177
-
178
- <h3>PeerDiscovery <code>src/peer/PeerDiscovery.ts</code></h3>
179
- <p>กลไกค้นหา 2 วิธีทำงานร่วมกัน:</p>
180
- <ul>
181
- <li><strong>File-based</strong> — แต่ละ instance เขียนไฟล์ <code>~/.claude/peers/{pid}.json</code> เก็บข้อมูล hostname, IP, port, shell, cwd instances อื่นอ่านไฟล์เพื่อค้นหา peer ในเครื่องเดียวกัน</li>
182
- <li><strong>UDP Multicast</strong> — ส่ง heartbeat beacon ไปที่ <code>239.255.37.37:42069</code> ทุก 30 วินาที ตอบกลับ <code>clew-peer-query</code> ด้วย <code>clew-peer-info</code> ใช้ข้ามเครื่อง</li>
183
- <li><strong>Stale eviction</strong> — Peer ที่ไม่เห็น 90 วินาที (<code>PEER_STALE_TIMEOUT</code>) จะถูกลบอัตโนมัติ</li>
184
- </ul>
185
-
186
- <h3>PeerStore <code>src/peer/PeerStore.ts</code></h3>
187
- <p>Singleton registry ในหน่วยความจำที่เก็บ peer ทั้งหมดที่รู้จัก (ทั้งที่ค้นพบและที่ join เอง), ข้อความ chat, todos, และ custom tags (ชื่อที่กำหนดเอง, บทบาท)</p>
188
- <ul>
189
- <li><strong>Discovered peers</strong> — ถูกลบอัตโนมัติเมื่อ stale</li>
190
- <li><strong>Joined connections</strong> — คงอยู่ถาวร ไม่ถูกลบอัตโนมัติ</li>
191
- <li><strong>Tags</strong> — ชื่อที่กำหนดเองและบทบาทต่อ peer</li>
192
- </ul>
193
-
194
- <h2>Discovery Protocol</h2>
195
- <pre><code>DiscoveryMessage =
196
- | { type: "clew-peer-query", version: 1 } // broadcast scan
197
- | { type: "clew-peer-info", version: 1, // heartbeat / response
198
- id: string, hostname: string, ip: string, port: number,
199
- cwd: string, sessionId?: string, appVersion: string,
200
- shell?: string, platform?: string, term?: string,
201
- status: "online" | "offline" }
202
-
203
- UDP port: 42069
204
- Multicast IP: 239.255.37.37
205
- Heartbeat: ทุก 30 วินาที
206
- Stale after: 90 วินาที</code></pre>
207
-
208
- <h2>คำสั่ง</h2>
209
- <table>
210
- <tr><th>คำสั่ง</th><th>คำอธิบาย</th></tr>
211
- <tr><td><code>/peer</code></td><td>เปิดเมนู interactive (share, join, discover, inbox)</td></tr>
212
- <tr><td><code>/peer share</code></td><td>เริ่มประกาศ instance นี้เป็น worker บน LAN</td></tr>
213
- <tr><td><code>/peer stop</code></td><td>หยุดประกาศและปิด peer server</td></tr>
214
- <tr><td><code>/peer discover</code></td><td>สแกนหา peers (file + UDP, timeout 3s)</td></tr>
215
- <tr><td><code>/peer join &lt;host&gt; &lt;port&gt;</code></td><td>เชื่อมต่อกับ remote peer ด้วย host และ port</td></tr>
216
- <tr><td><code>/peer name &lt;ชื่อ&gt;</code></td><td>กำหนดชื่อที่แสดงสำหรับตัวเอง</td></tr>
217
- <tr><td><code>/peer role &lt;บทบาท&gt;</code></td><td>กำหนดบทบาท (builder, tester, deployer, ฯลฯ)</td></tr>
218
- <tr><td><code>/peer inbox</code></td><td>ดูข้อความและ todos ที่รออยู่จาก peers</td></tr>
219
- <tr><td><code>/peer disconnect &lt;peer&gt;</code></td><td>ตัดการเชื่อมต่อจาก peer ที่ระบุ</td></tr>
220
- <tr><td><code>/peer todos</code></td><td>แสดงรายการ task ทั้งหมดที่ได้รับ</td></tr>
221
- <tr><td><code>/peer todo done &lt;id&gt;</code></td><td>ทำเครื่องหมาย task ว่าเสร็จแล้ว</td></tr>
222
- </table>
223
-
224
- <h2>AI Tools</h2>
225
- <p>เครื่องมือที่ AI agent ใช้เพื่อโต้ตอบกับระบบ peer:</p>
226
- <table>
227
- <tr><th>Tool</th><th>คำอธิบาย</th></tr>
228
- <tr><td><code>peer_discover</code></td><td>สแกน LAN หา Clew workers</td></tr>
229
- <tr><td><code>peer_join</code></td><td>เชื่อมต่อกับ remote peer ผ่าน HTTP</td></tr>
230
- <tr><td><code>peer_ping</code></td><td>ตรวจสอบว่า peer ออนไลน์อยู่หรือไม่ (GET /peer-info)</td></tr>
231
- <tr><td><code>peer_info</code></td><td>ดึงข้อมูล peer อย่างละเอียด</td></tr>
232
- <tr><td><code>peer_send_message</code></td><td>ส่งข้อความ chat ไปที่ peer</td></tr>
233
- <tr><td><code>peer_send_task</code></td><td>มอบหมาย task ให้ remote worker</td></tr>
234
- <tr><td><code>peer_broadcast</code></td><td>ส่ง task ไปทุก peer ที่เชื่อมต่อพร้อมกัน</td></tr>
235
- <tr><td><code>peer_run</code></td><td>รันคำสั่ง shell บน remote worker</td></tr>
236
- <tr><td><code>peer_disconnect</code></td><td>ลบ peer ออกจากรายการเชื่อมต่อ</td></tr>
237
- <tr><td><code>peer_list_messages</code></td><td>แสดงข้อความ chat ทั้งหมดที่ได้รับ</td></tr>
238
- <tr><td><code>peer_list_roles</code></td><td>แสดงรายการ peers พร้อมบทบาท</td></tr>
239
- <tr><td><code>peer_list_tasks</code></td><td>แสดง task ทั้งหมดและสถานะ</td></tr>
240
- <tr><td><code>peer_set_name</code></td><td>กำหนดชื่อที่แสดงให้ peer</td></tr>
241
- <tr><td><code>peer_set_role</code></td><td>กำหนดบทบาทให้ peer</td></tr>
242
- <tr><td><code>peer_share</code></td><td>เปิด/ปิด/เช็คสถานะการแชร์</td></tr>
243
- </table>
244
-
245
- <h2>การเชื่อมต่อกับ DAEMON</h2>
246
- <p>Autonomous agent loop (<code>src/services/autonomous/agentLoop.ts</code>) เชื่อมต่อกับ PeerServer เพื่อรับ task จาก remote peers:</p>
247
- <ul>
248
- <li>ฟัง <code>/peer-todo</code> POST ตลอด 24/7</li>
249
- <li>จัดคิว task ที่ได้รับและประมวลผลใน background workers</li>
250
- <li>สูงสุด 3 workers พร้อมกัน; task timeout หลัง 30 นาที</li>
251
- <li>ดูผลลัพธ์ผ่าน <code>/peer todos</code> และ <code>/tasks</code></li>
252
- </ul>
253
-
254
- <h2>ไฟล์ในระบบ</h2>
255
- <table>
256
- <tr><th>ไฟล์</th><th>หน้าที่</th></tr>
257
- <tr><td><code>src/peer/PeerServer.ts</code></td><td>HTTP server พร้อม endpoint /peer-info, /peer-msg, /peer-todo, /peer-exec</td></tr>
258
- <tr><td><code>src/peer/PeerDiscovery.ts</code></td><td>ค้นหา peer ผ่านไฟล์ + UDP multicast บน LAN</td></tr>
259
- <tr><td><code>src/peer/PeerStore.ts</code></td><td>Singleton registry ใน memory (peers, messages, todos, tags)</td></tr>
260
- <tr><td><code>src/peer/types.ts</code></td><td>Shared types และค่าคงที่ของ protocol</td></tr>
261
- <tr><td><code>src/commands/peer/</code></td><td>Interactive peer menu และ CLI commands</td></tr>
262
- <tr><td><code>src/tools/Peer*Tool/</code></td><td>16 AI agent tools สำหรับ peer operations</td></tr>
263
- <tr><td><code>src/services/autonomous/agentLoop.ts</code></td><td>Daemon integration: รับ remote tasks ผ่าน PeerServer</td></tr>
264
- </table>
265
-
266
- <footer class="footer">
267
- <span>Clew Code v0.2.7 — Open Source</span>
268
- <div class="footer-links">
269
- <a href="https://github.com/ClewCode/ClewCode">GitHub</a>
270
- <a href="https://github.com/ClewCode/ClewCode/issues">Issues</a>
271
- </div>
272
- </footer>
273
- </main>
274
- <nav class="toc-sidebar"></nav>
275
- </div>
276
- </div>
277
- <script src="js/main.js"></script>
278
- </body>
279
- </html>
280
-
1
+ <!DOCTYPE html>
2
+ <html lang="th">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>ระบบ Peer — Clew</title>
7
+ <meta name="description" content="ระบบ peer-to-peer บน LAN — ค้นหา, ส่งข้อความ, มอบหมายงาน, และรันคำสั่งระยะไกลระหว่าง Clew instances">
8
+ <link rel="preconnect" href="https://fonts.googleapis.com">
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
+ <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Noto+Sans+Thai:wght@400;500;600;700&display=swap" rel="stylesheet">
11
+ <link rel="stylesheet" href="css/styles.css">
12
+ <link rel="icon" type="image/svg+xml" href="./assets/clew.svg">
13
+ </head>
14
+ <body>
15
+ <header class="header"></header>
16
+ <div class="app">
17
+ <aside class="sidebar" id="sidebar"></aside>
18
+ <div class="sidebar-overlay" id="sidebarOverlay"></div>
19
+ <div class="content-wrap">
20
+ <main class="content">
21
+ <div class="breadcrumbs"><a href="index.th.html">หน้าแรก</a><span class="sep">/</span><span>ระบบ Peer</span></div>
22
+ <h1>ระบบ Peer</h1>
23
+ <p class="section-subtitle">Peer-to-peer บน LAN — ค้นหา Clew instances อื่น, ส่งข้อความ, มอบหมายงาน, และรันคำสั่งระยะไกล</p>
24
+
25
+ <p>ระบบ peer อยู่ใน <code>src/peer/</code> และประกอบด้วย 3 ชั้นหลัก: <strong>PeerServer</strong> (HTTP server), <strong>PeerDiscovery</strong> (สแกน LAN), และ <strong>PeerStore</strong> (registry ในหน่วยความจำ)</p>
26
+
27
+ <h2>สถาปัตยกรรม</h2>
28
+ <pre><code> ┌─────────────────────────────────────────────────────────────────────────────┐
29
+ │ PEER SYSTEM FLOW │
30
+ └─────────────────────────────────────────────────────────────────────────────┘
31
+
32
+ ┌──────────────────────────┐
33
+ │ /peer share │
34
+ │ (Machine A — Worker) │
35
+ └────────────┬─────────────┘
36
+ │
37
+ ┌─────────────────┼─────────────────┐
38
+ â–¼ â–¼ â–¼
39
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
40
+ │ PeerServer │ │PeerDiscovery │ │ PeerStore │
41
+ │ HTTP :random │ │ │ │ (in-memory) │
42
+ │ port │ │ │ │ │
43
+ └──────┬───────┘ └──────┬───────┘ └──────────────┘
44
+ │ │
45
+ │ ┌────────────┼────────────┐
46
+ │ │ │ │
47
+ │ ▼ ▼ ▼
48
+ │ ┌────────┐ ┌────────┐ ┌─────────────┐
49
+ │ │ File │ │ UDP │ │ PeerStore │
50
+ │ │ ~/.cl/ │ │multicast│ │ (singleton) │
51
+ │ │ peers/ │ │239... │ │ │
52
+ │ │{pid}. │ │:42069 │ │ │
53
+ │ │ json │ │ │ │ │
54
+ │ └────┬───┘ └────┬───┘ └─────────────┘
55
+ │ │ │
56
+ │ │ │ heartbeat ทุก 30s
57
+ │ │ │ stale timeout 90s
58
+ │ │ │
59
+ â–¼ â–¼ â–¼
60
+ ┌─────────────────────────────────────────────────────┐
61
+ │ LAN NETWORK │
62
+ │ │
63
+ │ ┌─────────┐ ┌─────────┐ │
64
+ │ │ Machine B│◄───────►│ Machine C│ ... │
65
+ │ │ Clew Code│ query │ Clew Code│ │
66
+ │ └────┬─────┘ └────┬─────┘ │
67
+ │ │ │ │
68
+ └────────┼────────────────────┼─────────────────────────┘
69
+ │ │
70
+ │ /peer discover │ /peer discover
71
+ â–¼ â–¼
72
+
73
+
74
+ ═══ WORKER (Machine A) ENDPOINTS ═══
75
+
76
+ Peer อื่น POST /peer-info ──► { hostname, ip, cwd, shell, ... }
77
+ │ POST /peer-msg ──► รับข้อความ chat
78
+ ├───────────────► POST /peer-todo ──► รับ task (ไปอยู่ใน inbox)
79
+ │ POST /peer-exec ──► รัน shell command + คืน stdout/stderr
80
+
81
+
82
+ ═══ CLIENT (Machine B) TOOLS ═══
83
+
84
+ /peer discover ──► scan files + UDP query (3s timeout)
85
+ │
86
+ â–¼
87
+ [peer list]
88
+ │
89
+ ┌───────────────────┼───────────────────┐
90
+ â–¼ â–¼ â–¼
91
+ /peer join /peer send_task /peer run
92
+ (POST /peer-info) (POST /peer-todo) (POST /peer-exec)
93
+
94
+ │
95
+ â–¼
96
+ /peer send_message ──► POST /peer-msg ──► inbox ปลายทาง
97
+ /peer broadcast ──► POST /peer-msg ──► ทุก peer ที่เชื่อมต่อ
98
+ /peer ping ──► GET /peer-info ──► เช็ค alive
99
+
100
+
101
+ ═══ DAEMON (agentLoop.ts) ═══
102
+
103
+ ┌───────────────────────────────────┐
104
+ │ Autonomous Agent Loop │
105
+ │ - ฟัง /peer-todo ตลอด 24/7 │
106
+ │ - รับ task จาก remote peers │
107
+ │ - execute ใน background worker │
108
+ │ - สูงสุด 3 workers พร้อมกัน │
109
+ └───────────────────────────────────┘
110
+
111
+
112
+ ═══ DATA LIFECYCLE ═══
113
+
114
+ advertise ──► heartbeat ทุก 30s
115
+ │
116
+ ├── 90s ไม่มี heartbeat ──► stale → evict
117
+ │
118
+ stop share ──► send UDP "offline"
119
+ delete peer file
120
+ close HTTP server</code></pre>
121
+
122
+ <h2>เทคนิคและหลักการ</h2>
123
+
124
+ <h3>Discovery แบบสองชั้น (Two-Layer Discovery)</h3>
125
+ <p>ทำไมไม่ใช้แค่ UDP multicast หรือแค่ file-based อย่างเดียว?</p>
126
+ <ul>
127
+ <li><strong>File-based</strong> — ทำงานบนเครื่องเดียวกันได้ทันที โดยไม่ต้องใช้ network เลย แค่อ่าน/เขียนไฟล์ JSON ใน <code>~/.claude/peers/</code> ซึ่งเร็วกว่าและไม่ต้องกังวลเรื่อง firewall</li>
128
+ <li><strong>UDP Multicast</strong> — ข้ามเครื่องได้ผ่าน LAN ใช้ multicast group <code>239.255.37.37:42069</code> ไม่ต้องรู้ IP ปลายทางล่วงหน้า</li>
129
+ <li><strong>ทำไมต้องทั้งสอง?</strong> — แต่ละวิธีมีข้อจำกัด: file-based ข้ามเครื่องไม่ได้, UDP multicast อาจถูกบล็อคด้วย network policy การใช้ทั้งสองวิธีทำให้ discovery ทำงานได้ในทุกสภาพแวดล้อม โดยไม่ต้องให้ผู้ใช้ configure อะไรเลย</li>
130
+ </ul>
131
+
132
+ <h3>Lease-based Task Claiming</h3>
133
+ <p>เมื่อมีหลาย worker (หรือหลาย daemon process) วิ่งพร้อมกัน จะป้องกันไม่ให้ task ถูกทำซ้ำได้อย่างไร?</p>
134
+ <ul>
135
+ <li><strong>Atomic lease</strong> — ก่อนเริ่ม task, worker ต้องขอ lease ด้วย <code>leaseTask(id, agentId)</code> ซึ่งเช็คว่า task ยังไม่มีใครจอง และเขียน lease owner + expiry timestamp ลงไฟล์แบบ atomic (read-modify-write ภายใต้ lock)</li>
136
+ <li><strong>Lease expiry</strong> — ถ้า worker crash หรือ disconnect, lease จะหมดอายุเอง (default 30 นาที) ทำให้ worker อื่นมารับงานต่อได้ — <em>crash recovery โดยไม่ต้องมี distributed coordinator</em></li>
137
+ <li><strong>Stale lease cleanup</strong> — ตอน startLoop จะรอ 2 วินาที แล้วเรียก <code>expireLeases()</code> เพื่อ clear lease เก่าจาก session ก่อนหน้า</li>
138
+ <li><strong>ทำไมไม่ใช้ lock file?</strong> — lock file แบบ OS-level (flock) ใช้ข้าม process บนเครื่องเดียวกันได้ แต่ใช้ข้ามเครื่องไม่ได้ Lease บนไฟล์ JSON แก้ปัญหานี้ได้โดยไม่ต้องพึ่ง external service อย่าง Redis/ZooKeeper</li>
139
+ </ul>
140
+
141
+ <h3>Heartbeat + Stale Eviction</h3>
142
+ <p>Peer discovery ต้องรู้ว่าใครยัง alive อยู่ โดยไม่ต้อง polling:</p>
143
+ <ul>
144
+ <li><strong>Push-based heartbeat</strong> — แต่ละ peer ส่ง beacon ทุก 30 วินาที ผ่านทั้ง file (เขียน timestamp ใหม่) และ UDP multicast</li>
145
+ <li><strong>Pull-based eviction</strong> — consumer เช็คอายุของ peer entry ถ้าเกิน 90 วินาที (<code>PEER_STALE_TIMEOUT</code>) ถือว่า stale → evict</li>
146
+ <li><strong>3× heartbeat interval</strong> — timeout = 3 × heartbeat interval เป็นค่า default ในระบบ distributed systems (ให้โอกาส retry ก่อน宣布ตาย)</li>
147
+ <li><strong>Graceful shutdown</strong> — ตอน <code>/peer stop</code> จะส่ง UDP "offline" message + ลบไฟล์ peer ทันที ไม่ต้องรอ timeout</li>
148
+ </ul>
149
+
150
+ <h3>Random Port Binding</h3>
151
+ <p>PeerServer bind ที่ port 0 (OS เลือก port ว่างให้):</p>
152
+ <ul>
153
+ <li><strong>No port conflicts</strong> — ถ้าใช้ fixed port แล้วมีหลาย instance จะชนกัน</li>
154
+ <li><strong>Security through obscurity</strong> — port สุ่มทำให้ attacker สแกนหายากกว่า fixed port (แต่ไม่ใช่ security หลัก — security จริงอยู่ที่ authentication layer)</li>
155
+ <li><strong>Discovery solves discovery</strong> — ไม่ต้องรู้ port ล่วงหน้า เพราะ discovery protocol จะบอก port ให้เอง</li>
156
+ </ul>
157
+
158
+ <h3>Message Broadcasting</h3>
159
+ <p><code>peer_broadcast</code> ส่ง task ไปทุก peer ที่เชื่อมต่อพร้อมกัน:</p>
160
+ <ul>
161
+ <li>ไม่ใช่ UDP broadcast — ใช้ HTTP POST sequential ไปทีละ peer (fire-and-forget)</li>
162
+ <li>รองรับ parallel สูงสุด 8 peers ต่อ 1 batch</li>
163
+ <li>เหมาะสำหรับ: deploy to all machines, run tests everywhere, health check ทุก node</li>
164
+ </ul>
165
+
166
+ <h2>องค์ประกอบหลัก</h2>
167
+
168
+ <h3>PeerServer <code>src/peer/PeerServer.ts</code></h3>
169
+ <p>HTTP server ขนาดเล็กที่เริ่มบน port สุ่ม (OS เลือกให้) เมื่อรัน <code>/peer share</code> แต่ละ endpoint รองรับการโต้ตอบแบบต่างๆ:</p>
170
+ <table>
171
+ <tr><th>Endpoint</th><th>Method</th><th>หน้าที่</th></tr>
172
+ <tr><td><code>/peer-info</code></td><td>GET</td><td>ส่งข้อมูล peer (hostname, IP, cwd, shell, platform)</td></tr>
173
+ <tr><td><code>/peer-msg</code></td><td>POST</td><td>รับข้อความ chat จาก peer อื่น</td></tr>
174
+ <tr><td><code>/peer-todo</code></td><td>POST</td><td>รับ task ที่ถูกมอบหมายจาก peer อื่น</td></tr>
175
+ <tr><td><code>/peer-exec</code></td><td>POST</td><td>รันคำสั่ง shell และส่งคืน stdout/stderr</td></tr>
176
+ </table>
177
+
178
+ <h3>PeerDiscovery <code>src/peer/PeerDiscovery.ts</code></h3>
179
+ <p>กลไกค้นหา 2 วิธีทำงานร่วมกัน:</p>
180
+ <ul>
181
+ <li><strong>File-based</strong> — แต่ละ instance เขียนไฟล์ <code>~/.claude/peers/{pid}.json</code> เก็บข้อมูล hostname, IP, port, shell, cwd instances อื่นอ่านไฟล์เพื่อค้นหา peer ในเครื่องเดียวกัน</li>
182
+ <li><strong>UDP Multicast</strong> — ส่ง heartbeat beacon ไปที่ <code>239.255.37.37:42069</code> ทุก 30 วินาที ตอบกลับ <code>clew-peer-query</code> ด้วย <code>clew-peer-info</code> ใช้ข้ามเครื่อง</li>
183
+ <li><strong>Stale eviction</strong> — Peer ที่ไม่เห็น 90 วินาที (<code>PEER_STALE_TIMEOUT</code>) จะถูกลบอัตโนมัติ</li>
184
+ </ul>
185
+
186
+ <h3>PeerStore <code>src/peer/PeerStore.ts</code></h3>
187
+ <p>Singleton registry ในหน่วยความจำที่เก็บ peer ทั้งหมดที่รู้จัก (ทั้งที่ค้นพบและที่ join เอง), ข้อความ chat, todos, และ custom tags (ชื่อที่กำหนดเอง, บทบาท)</p>
188
+ <ul>
189
+ <li><strong>Discovered peers</strong> — ถูกลบอัตโนมัติเมื่อ stale</li>
190
+ <li><strong>Joined connections</strong> — คงอยู่ถาวร ไม่ถูกลบอัตโนมัติ</li>
191
+ <li><strong>Tags</strong> — ชื่อที่กำหนดเองและบทบาทต่อ peer</li>
192
+ </ul>
193
+
194
+ <h2>Discovery Protocol</h2>
195
+ <pre><code>DiscoveryMessage =
196
+ | { type: "clew-peer-query", version: 1 } // broadcast scan
197
+ | { type: "clew-peer-info", version: 1, // heartbeat / response
198
+ id: string, hostname: string, ip: string, port: number,
199
+ cwd: string, sessionId?: string, appVersion: string,
200
+ shell?: string, platform?: string, term?: string,
201
+ status: "online" | "offline" }
202
+
203
+ UDP port: 42069
204
+ Multicast IP: 239.255.37.37
205
+ Heartbeat: ทุก 30 วินาที
206
+ Stale after: 90 วินาที</code></pre>
207
+
208
+ <h2>คำสั่ง</h2>
209
+ <table>
210
+ <tr><th>คำสั่ง</th><th>คำอธิบาย</th></tr>
211
+ <tr><td><code>/peer</code></td><td>เปิดเมนู interactive (share, join, discover, inbox)</td></tr>
212
+ <tr><td><code>/peer share</code></td><td>เริ่มประกาศ instance นี้เป็น worker บน LAN</td></tr>
213
+ <tr><td><code>/peer stop</code></td><td>หยุดประกาศและปิด peer server</td></tr>
214
+ <tr><td><code>/peer discover</code></td><td>สแกนหา peers (file + UDP, timeout 3s)</td></tr>
215
+ <tr><td><code>/peer join &lt;host&gt; &lt;port&gt;</code></td><td>เชื่อมต่อกับ remote peer ด้วย host และ port</td></tr>
216
+ <tr><td><code>/peer name &lt;ชื่อ&gt;</code></td><td>กำหนดชื่อที่แสดงสำหรับตัวเอง</td></tr>
217
+ <tr><td><code>/peer role &lt;บทบาท&gt;</code></td><td>กำหนดบทบาท (builder, tester, deployer, ฯลฯ)</td></tr>
218
+ <tr><td><code>/peer inbox</code></td><td>ดูข้อความและ todos ที่รออยู่จาก peers</td></tr>
219
+ <tr><td><code>/peer disconnect &lt;peer&gt;</code></td><td>ตัดการเชื่อมต่อจาก peer ที่ระบุ</td></tr>
220
+ <tr><td><code>/peer todos</code></td><td>แสดงรายการ task ทั้งหมดที่ได้รับ</td></tr>
221
+ <tr><td><code>/peer todo done &lt;id&gt;</code></td><td>ทำเครื่องหมาย task ว่าเสร็จแล้ว</td></tr>
222
+ </table>
223
+
224
+ <h2>AI Tools</h2>
225
+ <p>เครื่องมือที่ AI agent ใช้เพื่อโต้ตอบกับระบบ peer:</p>
226
+ <table>
227
+ <tr><th>Tool</th><th>คำอธิบาย</th></tr>
228
+ <tr><td><code>peer_discover</code></td><td>สแกน LAN หา Clew workers</td></tr>
229
+ <tr><td><code>peer_join</code></td><td>เชื่อมต่อกับ remote peer ผ่าน HTTP</td></tr>
230
+ <tr><td><code>peer_ping</code></td><td>ตรวจสอบว่า peer ออนไลน์อยู่หรือไม่ (GET /peer-info)</td></tr>
231
+ <tr><td><code>peer_info</code></td><td>ดึงข้อมูล peer อย่างละเอียด</td></tr>
232
+ <tr><td><code>peer_send_message</code></td><td>ส่งข้อความ chat ไปที่ peer</td></tr>
233
+ <tr><td><code>peer_send_task</code></td><td>มอบหมาย task ให้ remote worker</td></tr>
234
+ <tr><td><code>peer_broadcast</code></td><td>ส่ง task ไปทุก peer ที่เชื่อมต่อพร้อมกัน</td></tr>
235
+ <tr><td><code>peer_run</code></td><td>รันคำสั่ง shell บน remote worker</td></tr>
236
+ <tr><td><code>peer_disconnect</code></td><td>ลบ peer ออกจากรายการเชื่อมต่อ</td></tr>
237
+ <tr><td><code>peer_list_messages</code></td><td>แสดงข้อความ chat ทั้งหมดที่ได้รับ</td></tr>
238
+ <tr><td><code>peer_list_roles</code></td><td>แสดงรายการ peers พร้อมบทบาท</td></tr>
239
+ <tr><td><code>peer_list_tasks</code></td><td>แสดง task ทั้งหมดและสถานะ</td></tr>
240
+ <tr><td><code>peer_set_name</code></td><td>กำหนดชื่อที่แสดงให้ peer</td></tr>
241
+ <tr><td><code>peer_set_role</code></td><td>กำหนดบทบาทให้ peer</td></tr>
242
+ <tr><td><code>peer_share</code></td><td>เปิด/ปิด/เช็คสถานะการแชร์</td></tr>
243
+ </table>
244
+
245
+ <h2>การเชื่อมต่อกับ DAEMON</h2>
246
+ <p>Autonomous agent loop (<code>src/services/autonomous/agentLoop.ts</code>) เชื่อมต่อกับ PeerServer เพื่อรับ task จาก remote peers:</p>
247
+ <ul>
248
+ <li>ฟัง <code>/peer-todo</code> POST ตลอด 24/7</li>
249
+ <li>จัดคิว task ที่ได้รับและประมวลผลใน background workers</li>
250
+ <li>สูงสุด 3 workers พร้อมกัน; task timeout หลัง 30 นาที</li>
251
+ <li>ดูผลลัพธ์ผ่าน <code>/peer todos</code> และ <code>/tasks</code></li>
252
+ </ul>
253
+
254
+ <h2>ไฟล์ในระบบ</h2>
255
+ <table>
256
+ <tr><th>ไฟล์</th><th>หน้าที่</th></tr>
257
+ <tr><td><code>src/peer/PeerServer.ts</code></td><td>HTTP server พร้อม endpoint /peer-info, /peer-msg, /peer-todo, /peer-exec</td></tr>
258
+ <tr><td><code>src/peer/PeerDiscovery.ts</code></td><td>ค้นหา peer ผ่านไฟล์ + UDP multicast บน LAN</td></tr>
259
+ <tr><td><code>src/peer/PeerStore.ts</code></td><td>Singleton registry ใน memory (peers, messages, todos, tags)</td></tr>
260
+ <tr><td><code>src/peer/types.ts</code></td><td>Shared types และค่าคงที่ของ protocol</td></tr>
261
+ <tr><td><code>src/commands/peer/</code></td><td>Interactive peer menu และ CLI commands</td></tr>
262
+ <tr><td><code>src/tools/Peer*Tool/</code></td><td>16 AI agent tools สำหรับ peer operations</td></tr>
263
+ <tr><td><code>src/services/autonomous/agentLoop.ts</code></td><td>Daemon integration: รับ remote tasks ผ่าน PeerServer</td></tr>
264
+ </table>
265
+
266
+ <footer class="footer">
267
+ <span>Clew Code 0.2.13 — Open Source</span>
268
+ <div class="footer-links">
269
+ <a href="https://github.com/ClewCode/ClewCode">GitHub</a>
270
+ <a href="https://github.com/ClewCode/ClewCode/issues">Issues</a>
271
+ </div>
272
+ </footer>
273
+ </main>
274
+ <nav class="toc-sidebar"></nav>
275
+ </div>
276
+ </div>
277
+ <script src="js/main.js"></script>
278
+ </body>
279
+ </html>
280
+