SLOPSHOPPER

agents-panel

Side pane listing project, user and plugin agents with a run button each; /agents-panel toggles it.

newpanecommandtoast
★ 1v0.1.0MITupdated 2026-10-08Boom-Vitt/boombignose-mods/agents-panel
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · agents-panel
│ ┃ Agents ✕ › fix the failing auth test and add an audit log call │ ┃ ◆ Agents in this project 0 defined │ ┃ ⏺ Read(src/auth.ts) │ ┃ No custom agents. Add .md files to ⎿ Read 6 lines │ ┃ .claude/agents/. ⏺ Update(src/auth.ts) │ ┃ ⎿ Added 2 lines, removed 1 line │ ┃ click ▶ run to start one · /agents-panel to ⏺ Bash(bun test) │ ┃ hide ⎿ 3 pass, 1 fail │ │ ● Done. refresh now rejects expired claims and logs an audit event. │ │ ✻ Worked for 42s · done 4:20 PM │ │ › /agents-panel │ ⎿ agents-panel: Agents panel open. │ │ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Pane · Agents
◆ Agents in this project 0 defined No custom agents. Add .md files to .claude/agents/. click ▶ run to start one · /agents-panel to hide
README

boombignose-mods

มอด (mod) สำหรับ Claude Code: ตัวช่วยลดความเสี่ยงในการส่งข้อมูลส่วนบุคคลให้โมเดล (pdpa-thai) แถบแสดงการใช้ context (context-bar) แผงรายการ agent (agents-panel) และเวิร์กโฟลว์ multi-agent (boom-big-nose-workflow)

License: MIT tests For Claude Code

ไทย · English

ติดตั้ง · มอดในชุดนี้ · pdpa-thai · ข้อจำกัด · เชื่อถือได้แค่ไหน · คำถามที่พบบ่อย · PDPA กับมอดนี้ · กฎการตรวจจับ

ข้อควรทราบ โครงการนี้เป็นโครงการชุมชนที่ไม่เป็นทางการ และมีผู้ดูแลเพียงคนเดียว ไม่มีความเกี่ยวข้องกับ Anthropic, สำนักงานคณะกรรมการคุ้มครองข้อมูลส่วนบุคคล (PDPC), สำนักงานพัฒนาธุรกรรมทางอิเล็กทรอนิกส์ (ETDA), สำนักงานพัฒนารัฐบาลดิจิทัล (DGA), กระทรวงดิจิทัลเพื่อเศรษฐกิจและสังคม (MDES) หรือหน่วยงานรัฐใดของไทย และไม่ได้รับการสนับสนุนหรือการรับรองจากองค์กรและหน่วยงานเหล่านี้ ชื่อ pdpa-thai คำสั่ง /pdpa-guard และข้อความ PDPA: <โหมด> ในแถบสถานะ อ้างถึงพระราชบัญญัติคุ้มครองข้อมูลส่วนบุคคลเพียงเพราะกฎการตรวจจับออกแบบตามชนิดข้อมูลที่กฎหมายนั้นคุ้มครอง ไม่ได้บ่งชี้ว่าปฏิบัติตามกฎหมายแล้ว ส่วน Claude และ Claude Code เป็นผลิตภัณฑ์ของ Anthropic การกล่าวถึงชื่อเหล่านี้มีไว้เพียงเพื่อบอกว่ามอดในชุดนี้ใช้งานร่วมกับผลิตภัณฑ์ใด

เอกสารนี้ไม่ใช่คำแนะนำทางกฎหมาย สำหรับคำถามทางกฎหมาย โปรดปรึกษาทนายความที่มีคุณสมบัติเหมาะสม หรือเจ้าหน้าที่คุ้มครองข้อมูลส่วนบุคคล (Data Protection Officer, DPO) ขององค์กร และติดตามการตีความอย่างเป็นทางการจาก PDPC ซอฟต์แวร์นี้ให้ใช้ตามสภาพ (as is) โดยไม่มีการรับประกันใด ๆ ตาม สัญญาอนุญาต MIT การตรวจจับใช้นิพจน์ปรกติ (regular expression) ซึ่งไม่รับประกันผล (best-effort) จึงจะมีข้อมูลที่ตรวจไม่พบ และจะมีข้อความทั่วไปบางส่วนถูกปกปิดโดยไม่จำเป็น

โครงการนี้คืออะไร และมีไว้ทำไม

ทุกอย่างในบทสนทนาของ Claude Code ถูกส่งไปให้โมเดลประมวลผล ได้แก่ ข้อความที่พิมพ์ ไฟล์ที่ให้ Claude อ่าน ผลลัพธ์ของคำสั่ง และไฟล์ CLAUDE.md ดังนั้นเมื่อทำงานกับข้อมูลลูกค้า ใบสมัครงาน หรือบันทึกของระบบ (log) ข้อมูลส่วนบุคคล เช่น เลขประจำตัวประชาชน หมายเลขโทรศัพท์ หรืออีเมล จึงอาจติดไปกับคำขอโดยไม่ได้ตั้งใจ

pdpa-thai ตรวจหาข้อมูลส่วนบุคคลรูปแบบที่พบบ่อย ทั้งรูปแบบเฉพาะของไทยและรูปแบบสากล โดยทำงานภายในโปรเซสของ Claude Code แล้วแทนค่าที่พบด้วยป้ายแทนค่า (placeholder) ก่อนที่ Claude Code จะส่งบทสนทนาออกไป มอดนี้ออกแบบมาเพื่อช่วยลดความเสี่ยงเท่านั้น การติดตั้งมอดนี้ไม่ได้ทำให้องค์กรปฏิบัติตามพระราชบัญญัติคุ้มครองข้อมูลส่วนบุคคล พ.ศ. 2562 (PDPA) หรือกฎหมายอื่นใด และไม่ทดแทนการประเมินโดยผู้เชี่ยวชาญ

มอดอื่นเป็นเครื่องมือช่วยงานทั่วไปที่ไม่เกี่ยวกับ PDPA

ติดตั้ง

ต้องใช้ Claude Code เวอร์ชันที่รองรับปลั๊กอินแบบ hook module ทดสอบแล้วกับ Claude Code 2.1.289 เท่านั้น API ของ hook ยังอยู่ในระยะทดลองใช้ (early access) ดังนั้นเวอร์ชันก่อนหน้าหรือใหม่กว่าอาจข้ามการป้องกันบางส่วนหรือทั้งหมดโดยไม่มีการแจ้งเตือน ส่วนป้าย (badge) ของ CI แสดงเพียงว่าชุดทดสอบหน่วย (unit test) ผ่านบน Claude Code เวอร์ชันล่าสุด

claude plugin marketplace add Boom-Vitt/boombignose-mods
claude plugin install pdpa-thai@boombignose-mods
claude plugin install context-bar@boombignose-mods
claude plugin install agents-panel@boombignose-mods
claude plugin install boom-big-nose-workflow@boombignose-mods

แต่ละมอดทำงานแยกกัน เลือกติดตั้งเฉพาะมอดที่ต้องการได้

ใน Codex ติดตั้งได้เฉพาะ boom-big-nose-workflow เพราะมอดอื่นใช้ความสามารถที่มีเฉพาะใน Claude Code:

codex plugin marketplace add Boom-Vitt/boombignose-mods
codex plugin add boom-big-nose-workflow@boombignose-mods

อัปเดตเป็นเวอร์ชันล่าสุด:

claude plugin marketplace update boombignose-mods
claude plugin update pdpa-thai@boombignose-mods

จากนั้นเริ่ม Claude Code ใหม่เพื่อให้การอัปเดตมีผล

ปิดการทำงานชั่วคราว หรือถอนการติดตั้ง:

claude plugin disable pdpa-thai@boombignose-mods
claude plugin uninstall pdpa-thai@boombignose-mods

มอดในชุดนี้

มอดเวอร์ชันคำสั่งหน้าที่
pdpa-thai0.3.0`/pdpa-guard [redact\block\off], /pdpa-blur [on\off\record]`ปกปิดข้อมูลส่วนบุคคลที่ตรวจพบก่อนส่งให้ Claude และพรางข้อมูลบนหน้าจอ (วางเมาส์เพื่อดู หรือวางเมาส์แล้วไม่แสดงค่าจริงในโหมดบันทึกหน้าจอ)
context-bar0.4.0/context-barแถบเหนือช่องพิมพ์ แสดงการใช้ context window แยกตามหมวด และเวลาที่เหลือของ prompt cache
agents-panel0.1.0/agents-panelแผงด้านข้างแสดง agent ของโปรเจกต์ ของผู้ใช้ และของปลั๊กอิน พร้อมปุ่มเรียกใช้
boom-big-nose-workflow0.5.0ไม่ต้องใช้คำสั่ง (บอกเป้าหมายได้เลย) หรือ /bbn-plan, /bbn-review, /bbn-merge และคำสั่ง /bbn-* อื่นเวิร์กโฟลว์ BBN แบบอัตโนมัติ: บอกเป้าหมายเป็นภาษาธรรมดา แล้ว Claude Opus/Sonnet/Haiku กับ Codex CLI วางแผน แยก worktree ต่อ stream เขียนโค้ด รีวิว และ merge เข้า base ในเครื่องผ่าน gate โดยไม่ต้องพิมพ์ slash command (README, แผนภาพ)

/context-bar และ /agents-panel เป็นคำสั่งสลับเปิดและปิด /pdpa-blur สลับเปิดและปิดได้เช่นกัน หรือรับ on, off หรือ record ส่วน /pdpa-guard รับชื่อโหมด

  • context-bar นับถอยหลังโดยถือว่า prompt cache มีอายุ 5 นาที (เป็นค่าคงที่ในโค้ด)
  • ปุ่ม ▶ run ของ agents-panel เริ่ม subagent ตัวนั้นด้วยพรอมต์ (prompt) คงที่ Run the <name> agent on the current project. subagent นั้นทำงานเหมือน agent ทั่วไป คือส่งบทสนทนาไปยังผู้ให้บริการโมเดลที่ตั้งค่าไว้ (โดยค่าเริ่มต้นคือ Anthropic) และทำงานกับโปรเจกต์ได้ภายใต้สิทธิ์ (permission) ที่ตั้งไว้ตามปกติ

ประวัติการเปลี่ยนแปลงของแต่ละมอดอยู่ใน CHANGELOG.md

pdpa-thai

กลไกการทำงาน 3 ชั้น

  1. ตัวป้องกันขาออก (outbound guard) ตรวจและปกปิดข้อมูลก่อนส่งให้โมเดล ครอบคลุม
  2. พรอมต์ที่ผู้ใช้พิมพ์
  3. ข้อความที่บทสนทนาเก็บไว้ (conversation row) เช่น ข้อความในผลลัพธ์ของเครื่องมือ (tool result) และ context ที่ hook อื่นเพิ่มเข้ามา
  4. ข้อความที่แนบไปกับคำขอ เช่น ไฟล์ที่อ้างถึงด้วย @ ไฟล์ CLAUDE.md และ context block อื่น

มอดแก้ไขเฉพาะบล็อกข้อความ (text block) และข้อความในผลลัพธ์ของเครื่องมือ บล็อกชนิดอื่น เช่น รูปภาพหรือเอกสาร ถูกส่งไปตามเดิม

  1. การปฏิเสธการเรียกเครื่องมือ (tool call) ขณะที่โหมดไม่ใช่ off หากการเรียกเครื่องมือของ Claude มีป้ายแทนค่าที่มอดสร้างขึ้นในเซสชัน (session) นี้ตรงตามรูปแบบเดิม มอดจะปฏิเสธการเรียกนั้นและแจ้งให้ Claude ขอค่าจริงจากผู้ใช้ ซึ่งช่วยลดโอกาสที่ป้ายแทนค่าจะถูกเขียนลงไฟล์หรือคำสั่งจริง การตรวจนี้จับไม่ได้หาก Claude ดัดแปลงป้ายแทนค่า หรือป้ายแทนค่ามาจากเซสชันก่อนหน้า
  2. การพรางบนหน้าจอ (hover blur) ข้อมูลที่ตรวจพบซึ่งยังแสดงอยู่ในข้อความของผู้ใช้และของ Claude จะแสดงเป็นแถบสีเทา วางเมาส์เพื่อดูค่าจริง ในโหมด redact พรอมต์ของผู้ใช้แสดงเป็นป้ายแทนค่าอยู่แล้ว บทสนทนาเก็บเฉพาะพรอมต์ที่ปกปิดแล้ว และมอดไม่ได้เก็บสำเนาค่าเดิมไว้ การพรางจึงมีผลหลักกับข้อความของ Claude และข้อความที่ส่งขณะปิดการป้องกัน (off) การพรางเปิดใช้งานโดยค่าเริ่มต้น และทำงานเฉพาะบน terminal และแอปเดสก์ท็อป สำหรับการบันทึกหน้าจอหรือแชร์หน้าจอ ใช้ /pdpa-blur record เพื่อคงการพรางไว้และหยุดการแสดงค่าจริงเมื่อวางเมาส์ ดูหัวข้อ การบันทึกหรือแชร์หน้าจอ

โหมด

โหมดการทำงาน
redact (ค่าเริ่มต้น)แทนค่าที่ตรวจพบด้วยป้ายแทนค่าก่อนส่งให้ Claude
blockไม่ส่งพรอมต์ที่มีข้อมูลส่วนบุคคลที่ตรวจพบ ให้แก้ไขพรอมต์โดยนำข้อมูลนั้นออกแล้วส่งใหม่ ส่วนผลลัพธ์ของเครื่องมือ ไฟล์แนบ และ context ยังถูกปกปิดเหมือนโหมด redact
offปิดทั้งการปกปิดและการปฏิเสธการเรียกเครื่องมือ (การพรางบนหน้าจอควบคุมแยกด้วย /pdpa-blur)

โหมดและการตั้งค่าการพรางไม่ได้บันทึกลงดิสก์ และจะเริ่มที่โหมด redact พร้อมเปิดการพรางและปิดโหมดบันทึกหน้าจอทุกครั้งที่เริ่ม Claude Code ส่วน /clear จะคงโหมดปัจจุบันไว้หรือไม่นั้น ผู้ดูแลโครงการยังไม่ได้ตรวจสอบ (ดูโหมดปัจจุบันได้โดยใช้ /pdpa-guard โดยไม่ระบุอาร์กิวเมนต์ หรือดูที่แถบสถานะ)

คำสั่ง

/pdpa-guard           แสดงโหมดปัจจุบัน
/pdpa-guard redact    ปกปิดก่อนส่ง (ค่าเริ่มต้น)
/pdpa-guard block     ไม่ส่งพรอมต์ที่มีข้อมูลส่วนบุคคลที่ตรวจพบ
/pdpa-guard off       ปิดการป้องกัน
/pdpa-blur            สลับการพรางบนหน้าจอ (เปิดหากปิดอยู่ ปิดหากเปิดอยู่หรืออยู่ในโหมดบันทึกหน้าจอ)
/pdpa-blur on         เปิดการพราง วางเมาส์เพื่อดูค่าจริง
/pdpa-blur off        ปิดการพราง
/pdpa-blur record     โหมดบันทึกหน้าจอ: เปิดการพราง และวางเมาส์แล้วไม่แสดงค่าจริง

อาร์กิวเมนต์อื่นของ /pdpa-blur จะไม่เปลี่ยนการตั้งค่าใด และแสดงเพียงบรรทัดวิธีใช้ (usage)

แถบสถานะ (status line) แสดง PDPA: <โหมด> และต่อท้ายด้วย · REC เมื่ออยู่ในโหมดบันทึกหน้าจอ (เช่น PDPA: redact · REC) และเมื่อมอดปกปิดพรอมต์หรือข้อความที่บทสนทนาเก็บไว้ หรือไม่ส่งพรอมต์ จะมีข้อความแจ้งเตือน (toast) บอกจำนวนรายการที่พบ ส่วนการปกปิดใน CLAUDE.md, context block อื่น และไฟล์แนบ เช่น ไฟล์ที่อ้างถึงด้วย @ จะไม่มีการแจ้งเตือน ข้อความแจ้งเตือนนับเฉพาะรายการที่ตรงกับกฎ การไม่มีข้อความแจ้งเตือนไม่ได้หมายความว่าไม่มีข้อมูลส่วนบุคคลถูกส่งออกไป และการมีข้อความแจ้งเตือนก็ไม่ได้หมายความว่าข้อความนั้นไม่มีข้อมูลส่วนบุคคลเหลืออยู่แล้ว

ตรวจสอบว่ามอดทำงานอยู่ หลังเริ่ม Claude Code แถบสถานะควรแสดง PDPA: redact หรือ PDPA: block หากไม่แสดง แสดงว่ามอดไม่ได้โหลดและไม่มีการปกปิดใด ๆ ให้ใช้ claude --debug เพื่อดูสาเหตุ การทำงานแบบไม่มีหน้าจอโต้ตอบ (headless) เช่น claude -p ไม่มีแถบสถานะ จึงควรตรวจผลลัพธ์ของ debug ก่อนพึ่งพาการป้องกันในกรณีนั้น

การบันทึกหรือแชร์หน้าจอ

/pdpa-blur record เปิดโหมดบันทึกหน้าจอ (recording mode) สำหรับการบันทึกวิดีโอหน้าจอและการแชร์หน้าจอ การพรางยังเปิดอยู่ และการวางเมาส์จะไม่เปิดค่าที่พรางไว้ตลอดเวลาที่อยู่ในโหมดนี้ โหมดนี้ใช้ได้เฉพาะบน terminal และแอปเดสก์ท็อปเช่นเดียวกับการพรางแบบปกติ ไม่ได้บันทึกลงดิสก์ และทุกครั้งที่เริ่ม Claude Code การพรางจะเปิดอยู่และโหมดบันทึกหน้าจอจะปิดอยู่ ออกจากโหมดนี้ด้วย /pdpa-blur on หรือ /pdpa-blur off ควรหยุดบันทึกก่อนออกจากโหมดนี้ เพราะ /pdpa-blur on จะกลับมาแสดงค่าจริงเมื่อวางเมาส์ และ /pdpa-blur โดยไม่ระบุอาร์กิวเมนต์จะปิดการพราง นอกจากนี้เมื่อเริ่ม Claude Code ใหม่ โหมดบันทึกหน้าจอจะปิดอยู่ จึงควรตรวจแถบสถานะทุกครั้งหลังเริ่มใหม่หรือกลับมาทำงานต่อ (resume)

โหมดบันทึกหน้าจอพรางเฉพาะค่าที่ตรวจพบในข้อความของผู้ใช้และข้อความของ Claude ส่วนสิ่งอื่นที่ Claude Code แสดง เช่น การเรียกเครื่องมือ (tool call) และผลลัพธ์ ส่วนต่างของไฟล์ (diff) การคิดของโมเดล (thinking) ข้อความแจ้งเตือน และแผงอื่น จะแสดงตามปกติ

โหมดบันทึกหน้าจอไม่ครอบคลุม

  • ข้อมูลส่วนบุคคลที่กฎตรวจไม่พบ เช่น ชื่อที่ไม่มีป้ายกำกับหรือคำนำหน้าชื่อ (ดูหัวข้อ ข้อจำกัด) ซึ่งจะแสดงตามจริงโดยไม่ถูกพราง
  • ข้อความที่กำลังพิมพ์ในช่องพรอมต์ก่อนกดส่ง (ตัวป้องกันแทนค่าเมื่อกดส่งเท่านั้น)
  • การเรียกเครื่องมือ ผลลัพธ์ของเครื่องมือ และผลลัพธ์ของคำสั่งบนหน้าจอ
  • ข้อความต้นฉบับที่ปรากฏบนหน้าจอด้วยเหตุอื่น เช่น ไฟล์ที่เปิดอยู่ในหน้าต่างอื่น
  • การเลือกข้อความ ซึ่งอาจทำให้ข้อความที่พรางไว้อ่านได้บนหน้าจอ และการคัดลอกซึ่งยังได้ข้อความจริง

ในโหมด redact พรอมต์ที่ผู้ใช้ส่งแล้วแสดงเป็นป้ายแทนค่าอยู่แล้ว การพรางจึงมีผลหลักกับข้อความของ Claude และข้อความที่ส่งขณะปิดการป้องกัน (off) ข้อจำกัดอื่นของการพรางในหัวข้อ ข้อจำกัด ยังคงมีผล

ก่อนบันทึกหรือแชร์หน้าจอ

  1. ตั้งตัวป้องกันเป็นโหมด redact หรือ block (/pdpa-guard redact)
  2. สั่ง /pdpa-blur record และตรวจว่าแถบสถานะลงท้ายด้วย · REC
  3. ตรวจวิดีโอที่บันทึกไว้ก่อนแชร์

การพรางนี้เป็นเพียงการปิดบังทางสายตา ไม่ใช่หลักประกัน

ตัวอย่างก่อนและหลัง

ข้อความที่ผู้ใช้พิมพ์ (ค่าจริงแสดงเป็นคำอธิบายในวงเล็บมุม):

ช่วยร่างอีเมลแจ้งลูกค้า เบอร์ <เบอร์มือถือ 10 หลัก> อีเมล <อีเมลของลูกค้า>

ข้อความที่ Claude ได้รับในโหมด redact:

ช่วยร่างอีเมลแจ้งลูกค้า เบอร์ [REDACTED:PHONE_1~k3x9q] อีเมล [REDACTED:EMAIL_1~k3x9q]

รูปแบบของป้ายแทนค่าคือ [REDACTED:<ชนิด>_<ลำดับ>~<ส่วนต่อท้ายประจำเซสชัน>]

  • ชนิดข้อมูลบอก Claude ว่าตำแหน่งนั้นเป็นข้อมูลชนิดใด Claude จึงยังเขียนคำตอบที่อ้างถึงป้ายแทนค่าได้
  • ค่าเดียวกันที่ปรากฏซ้ำในข้อความชุดเดียวกัน (พรอมต์ ผลลัพธ์ของเครื่องมือหนึ่งรายการ ไฟล์แนบหนึ่งไฟล์ หรือกลุ่ม context block) ได้ป้ายแทนค่าเดียวกัน ลำดับเริ่มนับใหม่ในแต่ละชุด ดังนั้น PHONE_1 ในพรอมต์กับ PHONE_1 ในไฟล์ที่อ้างถึงด้วย @ หรือในผลลัพธ์ของเครื่องมือครั้งถัดไป อาจไม่ใช่หมายเลขเดียวกัน
  • ส่วนต่อท้ายประจำเซสชัน (session suffix) 5 อักขระช่วยให้มอดแยกป้ายแทนค่าที่มอดสร้างขึ้นจริงในเซสชันนี้ ออกจากข้อความที่เพียงกล่าวถึงรูปแบบของป้ายแทนค่า เช่น เอกสารฉบับนี้
  • การปกปิดย้อนกลับไม่ได้ มอดไม่มีตารางสำหรับแปลงป้ายแทนค่ากลับเป็นค่าเดิม

ข้อมูลที่ตรวจจับ

ชนิดสิ่งที่ตรวจ
THAI_IDเลขประจำตัวประชาชน 13 หลักซึ่งมีหลักตรวจสอบ (check digit) ถูกต้องตามสูตร mod 11
CARDเลขบัตรชำระเงิน (payment card) 13-19 หลักที่ผ่านการตรวจแบบ Luhn
PHONEหมายเลขโทรศัพท์มือถือและโทรศัพท์พื้นฐานของไทย รวมถึงรูปแบบ +66 และ 0066
EMAILที่อยู่อีเมล ยกเว้นอีเมลที่ใช้โดเมน example.com, example.org หรือ example.net โดยตรง (อีเมลที่ใช้โดเมนย่อยของโดเมนเหล่านี้ยังถูกปกปิด)
IPที่อยู่ IPv4 ยกเว้น 127.x.x.x และ 0.0.0.0
SECRETโทเค็น (token) ที่ขึ้นต้นด้วยคำนำหน้า (prefix) ที่รู้จัก ค่าหลัง Bearer และค่าหลังป้ายกำกับ (label) เช่น password, secret, token, api_key, รหัสผ่าน ทั้งนี้มอดนี้ไม่ใช่เครื่องมือสแกนความลับ (secret scanner) ตรวจพบเฉพาะรูปแบบที่ระบุไว้ใน DETECTION และข้ามค่าที่มีลักษณะเป็นโค้ด
PASSPORTเลขหนังสือเดินทางที่อยู่ถัดจากป้ายกำกับ เช่น passport, เลขที่หนังสือเดินทาง, พาสปอร์ต
BANK_ACCOUNTตัวเลข 10-15 หลักที่อยู่ถัดจากป้ายกำกับ เช่น เลขที่บัญชี, บัญชี, account no., พร้อมเพย์, PromptPay
DOBวันที่แบบตัวเลข (คั่นด้วย / . หรือ -) ที่อยู่ถัดจากป้ายกำกับ เช่น วันเกิด, date of birth, DOB ส่วนวันที่ที่เขียนชื่อเดือนเป็นตัวอักษรจะตรวจไม่พบ
SENSITIVEค่าหลังป้ายกำกับของหมวดข้อมูลอ่อนไหวส่วนใหญ่ตามมาตรา 26 เฉพาะเมื่อเขียนในรูป ป้ายกำกับ: ค่า เป็นภาษาไทยหรืออังกฤษ เช่น ศาสนา, ข้อมูลสุขภาพ, ประวัติอาชญากรรม ทั้งนี้ไม่ครอบคลุมถ้อยคำรูปแบบอื่น และไม่ครอบคลุมข้อมูลอื่นที่คณะกรรมการคุ้มครองข้อมูลส่วนบุคคลอาจประกาศกำหนด
ADDRESSค่าที่เขียนในรูป ป้ายกำกับ: ค่า โดยใช้ป้ายกำกับ ที่อยู่, home address หรือ mailing address (ป้ายกำกับ address: อย่างเดียวจะตรวจไม่พบ)
NAMEค่าที่เขียนในรูป ป้ายกำกับ: ค่า โดยใช้ป้ายกำกับ เช่น ชื่อ, นามสกุล, full name, surname รวมถึงชื่อที่ตามหลังคำนำหน้าชื่อ นาย, นาง, นางสาว, น.ส., ด.ช., ด.ญ., Mr, Mrs, Ms, Miss, Dr

สำหรับ SENSITIVE, ADDRESS และ NAME รูป ป้ายกำกับ: ค่า รวมถึง ป้ายกำกับ = ค่า เครื่องหมายทวิภาคแบบเต็มความกว้าง (:) และคีย์ JSON ในเครื่องหมายคำพูด เช่น "label": "value" ค่าหลังป้ายกำกับจะสิ้นสุดที่เครื่องหมายจุลภาค (,) อัฒภาค (;) เครื่องหมายคำพูด } หรือการขึ้นบรรทัดใหม่ที่พบก่อน ส่วนที่เหลือของที่อยู่หรือรายการจะถูกส่งไปตามที่เขียน และค่าที่ขึ้นต้นด้วย [ หรือ { (อาร์เรย์หรืออ็อบเจกต์ JSON) จะไม่ตรงกับกฎกลุ่มนี้เลย จึงไม่มีส่วนใดในค่านั้นถูกแทนค่า เว้นแต่กฎอื่น เช่น PHONE หรือ EMAIL ตรวจพบ

ทุกกฎอ่านเลขไทย (๐-๙) เหมือนเลขอารบิก

หมวดข้อมูลอ่อนไหวอ้างอิงมาตรา 26 แห่งพระราชบัญญัติคุ้มครองข้อมูลส่วนบุคคล พ.ศ. 2562 (ฉบับ PDF ที่ PDPC เผยแพร่, ตรวจสอบเมื่อ 4 ตุลาคม 2569) รายการป้ายกำกับทั้งหมด ข้อยกเว้น และการตรวจจับผิด (false positive) ที่ทราบ อยู่ใน docs/DETECTION.md

ข้อมูลของผู้ใช้ไปที่ใด

  • การตรวจจับและการปกปิดทำงานภายในโปรเซสของ Claude Code (บนเครื่องของผู้ใช้เมื่อใช้งานในเครื่อง หรือบนเครื่องที่เซสชันคลาวด์หรือเซสชันระยะไกลทำงานอยู่) ในเซสชันคลาวด์หรือเซสชันระยะไกล ค่าเดิมอยู่บนเครื่องนั้นแล้วก่อนที่มอดจะตรวจ มอดเปลี่ยนเฉพาะสิ่งที่ส่งต่อจากเครื่องนั้นไปให้โมเดล
  • pdpa-thai และ context-bar ไม่เรียกเครือข่าย โปรเซสภายนอก โมเดล หรือ MCP ด้วยตัวเอง ส่วน agents-panel เริ่ม subagent ผ่าน $.agent.spawn เฉพาะเมื่อผู้ใช้กดปุ่ม ▶ run และ subagent นั้นทำงานเหมือน agent ทั่วไป
  • boom-big-nose-workflow ไม่มีโค้ดฮุก คำสั่งของมอดรันสคริปต์ของมอดเอง (git, node, claude mcp list และ gh สำหรับการตรวจการล็อกอินใน /bbn-doctor และ /bbn-merge --apply --pr) เริ่ม subagent ในบทบาทเขียนโค้ด รวมโค้ด และรีวิว ซึ่งทำงานเหมือน agent ทั่วไป ถ้าติดตั้ง Codex CLI ไว้ bbn-codex.sh จะรัน Codex CLI ของผู้ใช้ ซึ่งเรียก OpenAI ด้วยการล็อกอินของผู้ใช้เอง และเพิ่มเซิร์ฟเวอร์ MCP ระยะไกล 2 ตัว คือ Context7 (https://mcp.context7.com/mcp) และ Perplexity (https://api.perplexity.ai/mcp ต้อง sign in ก่อน) คำค้นที่ agent ส่งไปยังเซิร์ฟเวอร์ที่เชื่อมต่ออยู่จะไปถึงบริการเหล่านั้น
  • ทุกครั้งที่มีการ push และ pull request CI จะทำการตรวจเฉพาะในเครื่อง (local-only) 2 รายการ ได้แก่ การค้นหาข้อความในโค้ดฮุกของทุกมอดว่ามีการเรียกเครือข่าย โปรเซส โมเดล หรือ MCP หรือ fetch( หรือไม่ และการตรวจว่าการเรียกเอนจินทุกรายการในบรรทัด calls: ที่ claude plugin validate pdpa-thai แสดง เป็นการเรียกกลุ่ม state, ui, clock หรือ command เท่านั้น การตรวจทั้งสองไม่ได้พิสูจน์สิ่งใดเกี่ยวกับมอดอื่นหรือตัว Claude Code เอง รายละเอียดของการตรวจทั้งสองและสิ่งที่ไม่ครอบคลุมอธิบายไว้แห่งเดียวในหัวข้อ สิ่งที่ CI ตรวจ
  • บทสนทนาที่ปกปิดแล้วยังถูกส่งไปยังผู้ให้บริการโมเดลที่ตั้งค่าไว้ (โดยค่าเริ่มต้นคือ Anthropic หรือผู้ให้บริการอื่น เช่น Amazon Bedrock หรือ Google Cloud Vertex AI) เช่นเดียวกับบทสนทนา Claude Code ทั่วไป
  • มอดนี้ไม่ได้เปลี่ยนวิธีที่ผู้ให้บริการโมเดลที่ตั้งค่าไว้ (โดยค่าเริ่มต้นคือ Anthropic) จัดเก็บ เก็บรักษา หรือใช้ข้อมูลที่ได้รับ ซึ่งเป็นไปตามข้อตกลงและการตั้งค่าระหว่างผู้ใช้หรือองค์กรกับผู้ให้บริการนั้น
  • การปกปิดมีผลกับสำเนาที่โมเดลอ่าน ค่าที่ตรวจพบแต่ละจุดถูกแทนด้วยป้ายแทนค่าก่อนส่งให้โมเดล แต่ค่าเดียวกันอาจยังถูกส่งออกไปหากปรากฏในส่วนที่มอดไม่ได้แก้ไข (ดูหัวข้อ ข้อจำกัด) และข้อมูลที่กฎตรวจไม่พบจะถูกส่งไปตามเดิม
  • การปกปิดไม่ใช่การทำให้เป็นข้อมูลนิรนาม (anonymisation) บทสนทนาที่ปกปิดแล้วอาจยังระบุตัวบุคคลได้ทั้งทางตรงหรือทางอ้อม ซึ่งเป็นลักษณะของข้อมูลส่วนบุคคลตามนิยามในมาตรา 6 ของ PDPA (ฉบับ PDF ที่ PDPC เผยแพร่, ตรวจสอบเมื่อ 4 ตุลาคม 2569) จึงอาจยังเป็นข้อมูลส่วนบุคคล และประเด็น เช่น ฐานทางกฎหมายในการประมวลผลและการส่งหรือโอนข้อมูลไปยังต่างประเทศ อาจยังต้องพิจารณา ควรปรึกษาทนายความที่มีคุณสมบัติเหมาะสมหรือ DPO ขององค์กร
  • มอดนี้แก้ไขเฉพาะสิ่งที่ Claude Code ส่งให้โมเดล ช่องทางอื่นเป็นช่องทางแยกต่างหาก ไม่อยู่ในขอบเขตของมอด และอาจได้รับค่าเดิม ได้แก่ Remote Control (ซึ่งส่งต่อผ่านบริการของ Anthropic ไปยัง claude.ai หรือแอป Claude) hook แบบคำสั่ง (command hook) ในการตั้งค่าของผู้ใช้ ระบบรวบรวม telemetry ที่องค์กรตั้งค่าไว้ และรายงานที่ผู้ใช้ส่งให้ Anthropic

ข้อจำกัด

  • กฎทั้งหมดเป็นนิพจน์ปรกติที่ไม่รับประกันผล จะมีข้อมูลที่ตรวจไม่พบ และจะมีข้อความทั่วไปบางส่วนถูกปกปิด
  • มอดนี้ไม่ใช่เครื่องมือสแกนความลับ (secret scanner) ตรวจพบเฉพาะรูปแบบโทเค็นและป้ายกำกับที่ระบุไว้ใน DETECTION และข้ามค่าที่มีลักษณะเป็นโค้ด จึงไม่ควรนำความลับเข้ามาในเซสชัน และควรใช้เครื่องมือสแกนความลับโดยเฉพาะ
  • ค่าหลังป้ายกำกับ (SENSITIVE, ADDRESS, NAME) จะสิ้นสุดที่เครื่องหมายจุลภาค อัฒภาค เครื่องหมายคำพูด } หรือการขึ้นบรรทัดใหม่ที่พบก่อน ส่วนที่เหลือของที่อยู่หรือรายการจะถูกส่งไปตามที่เขียน ค่าหลังป้ายกำกับที่ขึ้นต้นด้วย [ หรือ { (อาร์เรย์หรืออ็อบเจกต์ JSON) จะไม่ตรงกับกฎกลุ่มนี้เลย มีเพียงกฎอื่น เช่น PHONE หรือ EMAIL ที่ยังอาจแทนค่าบางส่วนในนั้นได้
  • ชื่อและที่อยู่ที่ไม่มีป้ายกำกับหรือคำนำหน้าชื่อ เช่น ชื่อที่ปรากฏกลางประโยค จะตรวจไม่พบ
  • ไม่ตรวจเนื้อหาในรูปภาพและเอกสารที่แนบเป็นบล็อกแยก
  • Claude Code ไม่เปิดให้มอดแก้ไขเนื้อหาบางส่วน จึงไม่มีการปกปิดในส่วนนั้น ได้แก่ กระบวนการคิดของโมเดล (thinking) และค่าที่ Claude ส่งให้เครื่องมือ (tool_use input)
  • ประวัติการสนทนาที่เปิดต่อ (resume) และทรานสคริปต์ (transcript) ของ subagent ที่บันทึกไว้แล้ว มอดจะไม่ตรวจซ้ำ ส่วนที่ไม่ได้ปกปิดในขณะบันทึกจะถูกส่งไปตามเดิม
  • ผลลัพธ์ของเครื่องมือแบบมีโครงสร้างและเนื้อหาของไฟล์แนบ (เช่น ไฟล์ที่อ้างถึงด้วย @) ที่ Claude Code เก็บไว้ยังคงเป็นค่าเดิมในทรานสคริปต์ และการแสดงผลลัพธ์ของเครื่องมือบนหน้าจอไม่ถูกพราง
  • ประวัติพรอมต์ของ Claude Code เอง (ที่เรียกกลับด้วยปุ่มลูกศรขึ้น) อยู่นอกการควบคุมของมอด และอาจเก็บข้อความที่ผู้ใช้พิมพ์ไว้บนเครื่องโดยไม่ปกปิด
  • ไม่ตรวจพรอมต์ระบบ (system prompt) เช่น ข้อมูลสภาพแวดล้อม คำแนะนำของเซิร์ฟเวอร์ MCP และส่วนที่ปลั๊กอินอื่นเพิ่มเข้าไป รวมถึงคำอธิบายของเครื่องมือและ skill
  • ไม่มีการปกปิดใน 3 ส่วนต่อไปนี้ ได้แก่ คำตอบของ Claude ข้อความสรุปที่ได้จากการบีบอัดบทสนทนา (compaction) และข้อความแจ้งจากระบบ (notice)
  • ค่าที่ถูกแบ่งไว้ในหลายข้อความอาจหลุดการตรวจจับ
  • หาก hook ของมอดเกิดข้อผิดพลาด (throw) หรือใช้เวลาเกินที่ Claude Code กำหนดต่อ hook หนึ่งตัว Claude Code จะข้าม hook นั้นและส่งข้อความไปตามเดิมโดยไม่ปกปิดและไม่มีการแจ้งเตือน (fail-open)
  • หากมอดไม่ได้โหลด จะไม่มีการปกปิดใด ๆ และสัญญาณเดียวคือไม่มีรายการ PDPA: บนแถบสถานะ ให้ใช้ claude --debug เพื่อดูสาเหตุ ทั้งนี้การทำงานแบบ headless (เช่น claude -p) ไม่มีแถบสถานะ
  • API ของ hook ยังอยู่ในระยะทดลองใช้ (early access) มอดนี้ทดสอบแล้วกับ Claude Code 2.1.289 เท่านั้น เวอร์ชันก่อนหน้าหรือใหม่กว่าอาจข้ามการป้องกันบางส่วนหรือทั้งหมดโดยไม่มีการแจ้งเตือน และป้าย (badge) ของ CI แสดงเพียงว่าชุดทดสอบหน่วย (unit test) ผ่านบน Claude Code เวอร์ชันล่าสุด
  • hook ของปลั๊กอินอื่นที่ทำงานก่อนมอดนี้อาจเห็นข้อความต้นฉบับ
  • ผลลัพธ์ของเครื่องมือและข้อความอื่นในบทสนทนาอาจแสดงในรูปแบบเดิมชั่วครู่ก่อนถูกปกปิด ทั้งบนหน้าจอของผู้ใช้และปลายทางที่เซสชันถูกส่งต่อไปแสดง เช่น Remote Control (ซึ่งส่งต่อผ่านบริการของ Anthropic ไปยัง claude.ai หรือแอป Claude) หรือ SDK stream
  • มอดนี้แก้ไขเฉพาะสิ่งที่ Claude Code ส่งให้โมเดล ช่องทางอื่นเป็นช่องทางแยกต่างหาก ไม่อยู่ในขอบเขตของมอด และอาจได้รับค่าเดิม ได้แก่ Remote Control (ซึ่งส่งต่อผ่านบริการของ Anthropic ไปยัง claude.ai หรือแอป Claude) hook แบบคำสั่ง (command hook) ในการตั้งค่าของผู้ใช้ ระบบรวบรวม telemetry ที่องค์กรตั้งค่าไว้ และรายงานที่ผู้ใช้ส่งให้ Anthropic
  • การพรางบนหน้าจอเป็นเพียงการปิดบังด้วยสี การคัดลอก การเลือกข้อความ โปรแกรมอ่านหน้าจอ การค้นหาใน terminal และการบันทึกหรือ log ของ terminal (เช่น tmux หรือ asciinema) ยังได้ค่าจริง ส่วนวิดีโอบันทึกหน้าจอจะเห็นค่าจริงเมื่อวางเมาส์บนข้อความนั้น เว้นแต่เปิดโหมดบันทึกหน้าจอ (/pdpa-blur record) ไว้ ทั้งนี้โหมดบันทึกหน้าจอไม่ครอบคลุมช่องพรอมต์ก่อนกดส่ง ผลลัพธ์ของเครื่องมือหรือคำสั่ง และข้อความต้นฉบับที่แสดงอยู่ที่อื่น (ดูหัวข้อ การบันทึกหรือแชร์หน้าจอ) terminal ที่ปรับความต่างของสีอัตโนมัติ (เช่น terminal ใน VS Code ซึ่งเปิดการตั้งค่า minimum contrast ratio ไว้โดยค่าเริ่มต้น) อาจแสดงข้อความที่พรางไว้ให้อ่านได้ การพรางใช้ได้เฉพาะ terminal และแอปเดสก์ท็อป และไม่พรางข้อความที่ยาวเกิน 100,000 ตัวอักษร
  • การปฏิเสธการเรียกเครื่องมือจับเฉพาะป้ายแทนค่าของเซสชันนี้ที่เขียนตรงตามรูปแบบเดิม และไม่ทำงานในโหมด off
  • ข้อความแจ้งเตือนนับเฉพาะรายการที่ตรงกับกฎ การไม่มีข้อความแจ้งเตือนไม่ได้หมายความว่าไม่มีข้อมูลส่วนบุคคลถูกส่งออกไป และการมีข้อความแจ้งเตือนก็ไม่ได้หมายความว่าข้อความนั้นไม่มีข้อมูลส่วนบุคคลเหลืออยู่แล้ว
  • Claude เห็นเพียงป้ายแทนค่า จึงใช้ค่าจริงทำงานไม่ได้ และการปกปิดย้อนกลับไม่ได้ การปิดการป้องกันจึงไม่ได้คืนค่าที่ถูกปกปิดไปแล้ว หากงานต้องใช้ค่าจริง ให้ใช้ /pdpa-guard off แล้วส่งค่าจริงอีกครั้ง และเปิดกลับด้วย /pdpa-guard redact เมื่องานนั้นเสร็จ ระหว่างที่ปิดอยู่ มอดจะไม่ปฏิเสธการเรียกเครื่องมือที่มีป้ายแทนค่าเดิม จึงควรตรวจสิ่งที่ Claude เขียนลงไฟล์
  • ข้อมูลที่ส่งออกไประหว่างปิดการป้องกัน (off) จะคงอยู่ในบทสนทนาตามเดิม การเปิดการป้องกันกลับไม่ได้ปกปิดย้อนหลัง และข้อมูลนั้นจะถูกส่งซ้ำไปกับทุกคำขอถัดไปในบทสนทนาเดียวกัน หากต้องการตัดออก ให้ใช้ /clear หรือเริ่มเซสชันใหม่
  • CLAUDE.md, context block อื่น และไฟล์แนบ จะคงผลจากครั้งแรกที่ Claude Code เตรียมเนื้อหานั้นไว้ การเปลี่ยนโหมดภายหลังจึงไม่มีผลกับเนื้อหาที่เตรียมไว้แล้ว ทั้งนี้ context block จะถูกเตรียมใหม่หลังใช้ /clear หรือหลังการบีบอัดบทสนทนา
  • CLAUDE.md และ context block อื่นถูกปกปิดด้วย Claude จึงไม่เห็นค่าจริงที่ผู้ใช้ตั้งใจเขียนไว้ เช่น อีเมลของผู้ใช้ใน CLAUDE.md
  • ข้อมูลที่เปิดเผยต่อสาธารณะอยู่แล้ว เช่น หมายเลขโทรศัพท์ติดต่อของหน่วยงาน ก็ถูกปกปิดหากตรงกับรูปแบบ
  • มอดนี้ช่วยลดข้อมูลที่ถูกส่งออกไป แต่ไม่ได้ทำให้ Claude Code หยุดส่งบทสนทนา (ที่ปกปิดแล้ว) ไปยังผู้ให้บริการโมเดลที่ตั้งค่าไว้ (โดยค่าเริ่มต้นคือ Anthropic)
  • มอดทำงานแยกตามผู้ใช้และตามเครื่อง และผู้ใช้ปิดได้ทุกเมื่อ (/pdpa-guard off หรือ claude plugin disable) จึงบังคับใช้จากส่วนกลางไม่ได้ และมอดไม่เก็บบันทึกการ
Source 2 files
hooks/register.tsx 136 lines
1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register } from 'claude-code'
3
4import type { Agent } from '../types'
5
6const PANE = 'agents-panel'
7const agents = atom({ plugin: 'agents-panel', key: 'agents' } as const, [])
8
9const DOTS = ['blue', 'cyan', 'yellow', 'magenta', 'red', 'green']
10const SECTIONS: Record<string, string> = {
11  projectSettings: 'PROJECT  .claude/agents',
12  userSettings: 'USER  ~/.claude/agents',
13  plugin: 'PLUGIN',
14}
15
16// ponytail: single-line frontmatter values only; a `description: >` block reads as ">"
17function front(src: string): Record<string, string> {
18  const out: Record<string, string> = {}
19  const block = /^---\r?\n([\s\S]*?)\r?\n---/.exec(src)?.[1] ?? ''
20  for (const line of block.split('\n')) {
21    const i = line.indexOf(':')
22    if (i > 0 && !/^\s/.test(line)) out[line.slice(0, i).trim()] = line.slice(i + 1).trim().replace(/^["']|["']$/g, '')
23  }
24  return out
25}
26
27async function load($: EngineInterface): Promise<Agent[]> {
28  const out: Agent[] = []
29  const seen = new Set<string>()
30
31  // frontmatter has the description and model; the usage breakdown does not
32  const files = await $.fs.list('.claude/agents').catch(() => [])
33  for (const f of files) {
34    if (f.kind !== 'file' || !f.name.endsWith('.md')) continue
35    const fm = front(String(await $.fs.read(`.claude/agents/${f.name}`)))
36    const name = fm.name ?? f.name.slice(0, -3)
37    seen.add(name)
38    out.push({ name, source: 'projectSettings', model: fm.model ?? null, description: fm.description ?? '', tokens: 0 })
39  }
40
41  // user and plugin agents (and any project one the files above missed)
42  const { context } = await $.session.usage({ breakdown: 'summary' }).catch(() => ({ context: {} as never }))
43  for (const a of context.breakdown?.agents ?? []) {
44    if (!seen.has(a.agentType)) out.push({ name: a.agentType, source: a.source, model: null, description: '', tokens: a.tokens })
45  }
46  return out
47}
48
49export const register: Register = on => {
50  let isOpen = false
51
52  on('session.start', async ($, e, next) => {
53    await $.command.register({
54      name: 'agents-panel',
55      description: 'Show or hide a side pane listing project, user and plugin agents',
56    })
57    return next(e)
58  })
59
60  on('command.run', { command: 'agents-panel' }, async $ => {
61    if (isOpen) {
62      await $.ui.close({ id: PANE })
63      return { text: 'Agents panel closed.' }
64    }
65    const list = await load($)
66    await update($, agents, () => list)
67    await $.ui.open({ id: PANE, title: 'Agents' })
68    isOpen = true
69    return { text: 'Agents panel open.' }
70  })
71
72  on('ui.close', ($, e, next) => {
73    if (e.id === PANE) isOpen = false
74    return next(e)
75  })
76
77  on('ui.render', { component: 'Pane', requestId: PANE }, async ($, e) => {
78    const { Box, Button, Text } = $.ui.resolve(e)
79    const list = await read($, agents)
80    const order = [...Object.keys(SECTIONS), ...new Set(list.map(a => a.source).filter(s => !(s in SECTIONS)))]
81
82    return (
83      <Box flexDirection="column">
84        <Box justifyContent="space-between">
85          <Text bold>◆ Agents <Text dimColor>in this project</Text></Text>
86          <Text dimColor>{list.length} defined</Text>
87        </Box>
88        {list.length === 0 && (
89          <Box marginTop={1}>
90            <Text dimColor>No custom agents. Add .md files to .claude/agents/.</Text>
91          </Box>
92        )}
93        {order.map(src => {
94          const rows = list.filter(a => a.source === src)
95          if (rows.length === 0) return null
96          return (
97            <Box key={src} flexDirection="column" marginTop={1}>
98              <Text color="blue" bold>{SECTIONS[src] ?? src.toUpperCase()} <Text dimColor>· {rows.length}</Text></Text>
99              {rows.map((a, i) => (
100                <Box key={a.name} flexDirection="column" marginTop={1}>
101                  <Box justifyContent="space-between">
102                    <Box>
103                      <Text color={DOTS[i % DOTS.length]}>● </Text>
104                      <Text bold>{a.name}</Text>
105                      {a.model !== null && <Text dimColor> {a.model}</Text>}
106                    </Box>
107                    <Button
108                      key={`run-${a.name}`}
109                      label="▶ run"
110                      dimColor
111                      onPress={async () => {
112                        const r = await $.agent.spawn({
113                          subagentType: a.name,
114                          description: `run ${a.name}`,
115                          prompt: `Run the ${a.name} agent on the current project.`,
116                        })
117                        $.ui.toast(r.deny ? `${a.name}: ${r.deny}` : `${a.name} started`)
118                      }}
119                    />
120                  </Box>
121                  <Text dimColor wrap="truncate-end">
122                    {a.description || `~${a.tokens} tokens in the Agent tool prompt`}
123                  </Text>
124                </Box>
125              ))}
126            </Box>
127          )
128        })}
129        <Box marginTop={1}>
130          <Text dimColor>click ▶ run to start one · /agents-panel to hide</Text>
131        </Box>
132      </Box>
133    )
134  })
135}
136
types/index.d.ts 14 lines
1export type Agent = {
2  name: string
3  source: string
4  model: string | null
5  description: string
6  tokens: number
7}
8
9declare module 'claude-code' {
10  interface PluginState {
11    'agents-panel': { agents: Agent[] }
12  }
13}
14