<p align="center">
  <img src="./docs/images/dsh-harbor-logo.png" alt="DSH Harbor" width="120" />
</p>

<p align="center">
  <a href="./README.md">English</a> &middot; <a href="./README.zh.md">简体中文</a> &middot; <a href="./README.zh-TW.md">繁體中文</a> &middot; <a href="./README.ja.md">日本語</a> &middot; <a href="./README.ko.md">한국어</a> &middot; <a href="./README.fr.md">Français</a> &middot; <a href="./README.es.md">Español</a> &middot; <a href="./README.de.md">Deutsch</a> &middot; <a href="./README.pt.md">Português</a> &middot; <a href="./README.ru.md">Русский</a> &middot; <a href="./README.hi.md">हिन्दी</a> &middot; <a href="./README.tr.md">Türkçe</a> &middot; <a href="./README.th.md"><b>ไทย</b></a> &middot; <a href="./README.vi.md">Tiếng Việt</a> &middot; <a href="./README.id.md">Bahasa Indonesia</a>
</p>

# dsh-harbor

กระจกแบบอ่านอย่างเดียวสำหรับปลั๊กอิน [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) ที่คุณติดตั้งไว้ แสดงว่าแต่ละตัว**ทำอะไรได้บ้าง** มีจุดใดที่**ขัดแย้งกัน** และ**มีอะไรเปลี่ยนไป**นับจากการสแกนครั้งล่าสุด พร้อมหลักฐานที่ตรวจสอบได้สำหรับทุกความสามารถที่ตรวจพบ

จะจัดการสิ่งใดหรือไม่เป็นการตัดสินใจของคุณ harbor มีหน้าที่รายงานข้อเท็จจริง ไม่ตัดสิน ไม่ควบคุมการติดตั้ง และไม่ดักจับสิ่งใด

## สิ่งที่เป็น — และสิ่งที่ไม่ใช่

harbor ทำเพียงอย่างเดียว คือดูแลบัญชีรายการปลั๊กอินที่คุณติดตั้งไว้อย่างต่อเนื่องโดยมีหลักฐานรองรับ บัญชีนี้มีสามส่วน ได้แก่ รายการปลั๊กอินทั้งหมด (ปลั๊กอินจากบุคคลที่สามทุกตัวที่ติดตั้ง พร้อมตำแหน่งซอร์สเมื่อ detector หาได้) การเทียบสิ่งที่แต่ละปลั๊กอินประกาศกับสิ่งที่โค้ดทำจริง และลำดับเวลาของการเปลี่ยนแปลงระหว่างการสแกน

สิ่งที่ harbor ตั้งใจไม่ทำก็เป็นส่วนสำคัญของการออกแบบเช่นกัน harbor ไม่ตรวจรับหรือกีดกันปลั๊กอินก่อนติดตั้ง เพราะการควบคุมการรับเข้าเป็นหน้าที่ของเครื่องมือ marketplace สำหรับปลั๊กอิน harbor ไม่ลงลึกถึงการติดตาม upstream dependencies โดยการตรวจ upstream ครอบคลุมเฉพาะเวอร์ชันของปลั๊กอินแล้วจบเพียงเท่านั้น harbor ไม่ทำการตรวจสอบโค้ดทั่วไป และไม่ดักจับ ปิดกั้น หรือ sandbox พฤติกรรมของปลั๊กอิน

ข้อสุดท้ายไม่ใช่การตัดสินใจเรื่องขอบเขต แต่เป็นข้อเท็จจริงของ host runtime Cordis ของ DSH ไม่มี capability sandbox ปลั๊กอินทำงานอยู่ใน Node realm หลักของ host ด้วยสิทธิ์เดียวกับ host เอง harbor ทำให้ความสามารถต่าง ๆ **มองเห็นได้** **ตรวจจับ**ได้ และ**เทียบเคียง**กับคำประกาศได้ แต่ไม่สามารถปิดความสามารถเหล่านั้นได้ การจำกัดพฤติกรรมปลั๊กอินต้องอาศัยการรองรับจาก DSH loader เอง และขั้นตอนการประกาศด้านล่างคือวิธีสร้างมาตรฐานดังกล่าวด้วยข้อมูลแทนการถกเถียงในเชิงนามธรรม

สุดท้าย harbor รายงานข้อเท็จจริง ไม่ใช่คะแนน ผลลัพธ์ของมันคือ “ตรวจพบอะไร และหลักฐานอยู่ที่ไหน” เสมอ ไม่ใช่ระดับความเสี่ยงหรือคะแนนคุณภาพ ความหมายของสิ่งที่พบต่อคุณขึ้นอยู่กับวิจารณญาณของคุณ ไม่ใช่ของ harbor

> **สถานะ: `0.1.0-rc.2` อยู่ระหว่างการเสริมความแข็งแกร่งให้ release candidate** CLI, เส้นทาง hub ที่จำกัดเฉพาะ loopback, แผงการตั้งค่า DSH, ความคลาดเคลื่อนข้าม profile และการตรวจ upstream แบบเลือกใช้พร้อมใช้งานแล้ว host ที่กำลังทำงานจะให้ข้อมูล runtime tools, providers และ routes ส่วนเมื่ออยู่นอก host ข้อมูล runtime จะลดระดับเป็น `available: false` อย่างชัดเจน detector ยังคงเป็นแบบ heuristic และอยู่ระหว่างปรับเทียบกับ ecosystem ที่กว้างขึ้น จึงควรตรวจหลักฐานแทนการถือว่าสิ่งที่ตรวจไม่พบคือหลักฐานว่าไม่มีอยู่

## สิ่งที่ตรวจสอบ

```
~/.dsh/profiles/*                → bundle จากบุคคลที่สามที่ติดตั้งแล้ว (ทั้ง npm และ link:)
  ├─ declared    package.json / cordis.patch.yml — สิ่งที่ปลั๊กอินระบุเกี่ยวกับตัวเอง
  ├─ runtime     tools / routes / providers ที่ลงทะเบียนใน host จริง
  ├─ static      subprocess, egress, การเขียน config ภายนอก — พร้อม file:line
  ├─ versions    ความคลาดเคลื่อน (ในเครื่อง, ตรวจเสมอ) + upstream (ผ่านเครือข่าย, เลือกใช้)
  └─ snapshot    diff เทียบการสแกนก่อนหน้า: เวอร์ชันใหม่ ความสามารถใหม่
        └─ การเทียบเคียง: dsh.capabilities ที่ประกาศไว้ กับสิ่งที่ตรวจพบ
```

ความสามารถเป็นชุดคงที่สิบสามรายการ ได้แก่ client injection, ความเสี่ยงของ realm, สำเนา realm, global hooks, ตัวเชื่อมต่อ LLM, subprocesses, network egress, web routes, การลงทะเบียน tools, เซิร์ฟเวอร์ MCP, การเขียน config ภายนอก, การจัดการ credentials และการอ่าน environment ชุดนี้คงที่เพื่อให้รายงานเปรียบเทียบและทำ diff ระหว่างการสแกนได้ รายการอ้างอิงอย่างเป็นทางการอยู่ใน [SPEC.md](./SPEC.md) §2 และแหล่งข้อมูลจริงที่เครื่องอ่านได้คือ `src/scan/detectors.mjs`

การเลือกใช้คำเป็นกลางโดยตั้งใจ คือ **ความสามารถ** ไม่ใช่ความเสี่ยง สำหรับปลั๊กอินบางตัว การเรียก subprocesses คือจุดประสงค์ทั้งหมดของมัน รายงานตอบว่า “สิ่งนี้ทำอะไรได้” และปล่อยคำถามว่า “ควรทำหรือไม่” ให้คุณตัดสินใจ

## เวอร์ชัน

harbor ตอบคำถามเกี่ยวกับเวอร์ชันสองข้อและแยกออกจากกันอย่างชัดเจน

**ความคลาดเคลื่อนข้าม profile** เป็นข้อมูลภายในเครื่องทั้งหมด การที่ปลั๊กอินเดียวกันมีเวอร์ชันต่างกันในแต่ละ profile คือข้อเท็จจริงของเครื่องนี้ จึงคำนวณให้ทุกครั้งที่สแกนโดยไม่มีค่าใช้จ่ายเพิ่มเติม การติดตั้งแบบ `link:` หรือ `file:` จะไม่ถือเป็นฐาน “ใหม่ล่าสุด” เพราะ working tree ที่ล้ำหน้าเวอร์ชันที่เผยแพร่แล้วเป็นเรื่องปกติ ไม่ใช่ความคลาดเคลื่อน

**การตรวจ upstream** ติดต่อออกนอกเครื่อง จึงไม่เป็นส่วนหนึ่งของการสแกนเริ่มต้น CLI ต้องใช้ `harbor scan --check-updates` ส่วนในแผงต้องกดปุ่มอย่างชัดเจน โดยข้อความข้างปุ่มก็ระบุไว้ นี่เป็นการทำงานเพียงอย่างเดียวในหน้านั้นที่ติดต่อออกนอกเครื่องของคุณ แต่ละผลลัพธ์จะอยู่ในหนึ่งในห้าสถานะต่อไปนี้:

- **behind** — registry มีเวอร์ชันใหม่กว่า
- **current** — เวอร์ชันที่ติดตั้งตรงกับ registry
- **ahead** — เวอร์ชันที่ติดตั้งใหม่กว่า registry (เป็นสถานะที่เกิดขึ้นได้จริงบนเครื่องของผู้ดูแล)
- **local** — การติดตั้งแบบ `link:` / `file:` ซึ่งไม่มี upstream ให้เปรียบเทียบ และจะไม่แสดงว่า “เป็นเวอร์ชันล่าสุด”
- **unknown** — การค้นหาล้มเหลว

registry จะอ่านจาก `.npmrc` ของคุณเอง (รวมถึงการกำหนดทับ `@scope:registry`) และไม่เคย hardcode เป็น npmjs ผลลัพธ์จะ cache ไว้บนดิสก์เป็นเวลาหกชั่วโมง

## การติดตั้ง

สำหรับการพัฒนาในเครื่อง ให้ติดตั้งจาก checkout:

```bash
dsh plugin --profile web add link:/path/to/dsh-harbor
```

`dsh plugin` จะส่งต่ออาร์กิวเมนต์ที่เหลือให้ pnpm ภายในไดเรกทอรี profile และ `link:` จะสร้าง symlink จาก dependency ของ profile ไปยัง checkout นี้ การ rebuild จึงแสดงผลโดยตรง เมื่อติดตั้งจาก registry ให้ใช้ tag ผู้สมัคร `next`:

```bash
dsh plugin --profile web add @zseven-w/dsh-harbor@next
```

จากนั้น restart DSH เพื่อโหลดชั้น profile ใหม่

แผงจะปรากฏใน Web UI ของ DSH ภายใต้ **Settings** ในส่วน **DSH Harbor** ซึ่งเป็นกระจกเดียวกับ CLI แสดง inventory พร้อมหลักฐาน ข้อขัดแย้ง เวอร์ชัน และ diff นับจากการสแกนครั้งล่าสุด ปุ่ม **Check for updates** เป็นการทำงานเพียงอย่างเดียวในหน้านั้นที่ติดต่อออกนอกเครื่องของคุณ แผงนี้เป็นส่วน hub ของปลั๊กอิน ซึ่งจะ mount เฉพาะใน profile ที่มี web server

ไฟล์ executable ของปลั๊กอินติดตั้งอยู่ภายใน profile ที่เลือก การเพิ่มปลั๊กอินไปยัง `web` ไม่ได้ทำให้ `harbor` อยู่ใน global `PATH` ของ shell ให้เรียกใช้ผ่าน profile นั้น:

```bash
pnpm --dir ~/.dsh/profiles/web exec harbor scan
```

สำหรับการเรียกจาก checkout หรือเรียกผ่าน registry แบบครั้งเดียว ให้ใช้คำสั่งใดคำสั่งหนึ่งต่อไปนี้แทน:

```bash
node /path/to/dsh-harbor/src/cli.mjs scan
pnpm dlx @zseven-w/dsh-harbor@next scan
```

## การใช้งาน

ตัวอย่างด้านล่างใช้ `harbor` เป็นคำย่อแทนรูปแบบการเรียกใช้แบบใดแบบหนึ่งข้างต้น

```bash
harbor scan                 # inventory, ข้อขัดแย้ง และการเปลี่ยนแปลงนับจากการสแกนล่าสุด
harbor scan --check-updates # + การตรวจ upstream กับ registry แบบเลือกใช้ (ผ่านเครือข่าย)
harbor manifest ./my-plugin # ร่างบล็อก dsh.capabilities สำหรับปลั๊กอินของคุณ
```

เพิ่ม `--evidence` เพื่อพิมพ์หลักฐานจากซอร์สแบบ `file:line` ที่มีอยู่ ใช้ `--json` สำหรับรายงานฉบับเต็มที่เครื่องอ่านได้ และใช้ `--no-snapshot` เพื่อข้ามการเขียนฐานสำหรับ diff ข้อเท็จจริงที่มาจาก manifest, filesystem หรือ runtime อาจไม่มีบรรทัดซอร์สและจะมีป้ายระบุอย่างเหมาะสม

ตัวสแกนไม่มี dependency และไม่จำเป็นต้องติดตั้ง DSH จึงทำงานใน CI ได้เช่นกัน

## สำหรับผู้เขียนปลั๊กอิน

`harbor manifest` อ่านปลั๊กอินของคุณด้วยวิธีเดียวกับที่อ่านปลั๊กอินอื่น แล้วร่างสมาชิก `capabilities` สำหรับ merge เข้าไปใน object `dsh` ที่มีอยู่ใน `package.json` โดยจะไม่ขอให้คุณแทนที่ object ทั้งหมดจนสูญเสีย configuration ของ `bundle` หรือ `client` เมื่อประกาศแล้ว การตรวจของ harbor จะกลายเป็นการเทียบ **สิ่งที่ประกาศกับสิ่งที่ตรวจพบ** ความสามารถที่ประกาศแต่ไม่เคยใช้คือสัญญาณรบกวนที่ตัดออกได้ ส่วนความสามารถที่ตรวจพบแต่ไม่ได้ประกาศคือสิ่งที่ควรอธิบาย harbor ประกาศ `dsh.capabilities` ของตัวเองด้วย จึงทำซ้ำขั้นตอนนี้กับตัวเครื่องมือเองได้โดยเรียก `harbor manifest .` ใน repository นี้

ข้อตกลงนี้เขียนไว้ใน [SPEC.md](./SPEC.md) ([SPEC.zh.md](./SPEC.zh.md)) สรุปในบรรทัดเดียว: `dsh.capabilities` คือรายการธรรมดาใน `package.json` ที่บอกว่าโค้ดของปลั๊กอินคุณทำอะไรจริง การประกาศทำได้ง่ายและให้ประโยชน์สองต่อ เครื่องมือตรวจสอบอย่าง harbor สามารถเทียบคำประกาศกับโค้ดของคุณ และผู้ที่ใช้งานปลั๊กอินก็เห็นได้ว่าคุณไม่ได้ซ่อนอะไร ตรวจสอบคำประกาศของตัวเองได้ทุกเมื่อด้วย `harbor manifest <dir>`

## ข้อจำกัด กล่าวอย่างตรงไปตรงมา

harbor อ่านซอร์สของปลั๊กอินทุกตัว จึงเป็นสิ่งที่มีสิทธิ์สูงที่สุดในระบบ และตัว harbor เองก็ปรากฏในรายงานของตน

เมื่อเปิดใช้การตรวจ upstream ตัว harbor เองจะมีความสามารถ network-egress และได้ระบุไว้ในคำประกาศ `dsh.capabilities` แล้ว

## สัญญาอนุญาต

MIT
