แนวคิด
คำแนะนำนี้จะอธิบายแนวคิดหลักเบื้องหลัง OpenSpec และวิธีที่พวกเขาทำงานร่วมกัน สำหรับการใช้งานจริง โปรดดูที่ เริ่มต้นใช้งาน และ เวิร์กโฟลว์
ปรัชญา
OpenSpec สร้างขึ้นจากหลักการสี่ประการ:
fluid not rigid — ไม่มีขั้นตอนที่ตายตัว ทำงานในสิ่งที่สมเหตุสมผล
iterative not waterfall — เรียนรู้ขณะสร้าง ปรับปรุงไปพร้อมกัน
easy not complex — การตั้งค่าที่น้ำหนักเบา พิธีกรรมน้อยที่สุด
brownfield-first — ทำงานร่วมกับโค้ดเบสที่มีอยู่แล้ว ไม่ใช่แค่โปรเจกต์ใหม่ทำไมหลักการเหล่านี้จึงสำคัญ
Fluid not rigid (ยืดหยุ่น ไม่ตายตัว). ระบบสเปคแบบดั้งเดิมจะบังคับให้คุณเข้าสู่ขั้นตอนต่างๆ: คุณวางแผนก่อน จากนั้นจึงนำไปปฏิบัติ แล้วก็เสร็จ OpenSpec มีความยืดหยุ่นมากกว่า — คุณสามารถสร้างสิ่งประดิษฐ์ (artifacts) ได้ตามลำดับที่เหมาะกับงานของคุณ
Iterative not waterfall (วนซ้ำ ไม่ใช่วอเตอร์ฟอล). ความต้องการมีการเปลี่ยนแปลง ความเข้าใจลึกซึ้งขึ้น สิ่งที่ดูเหมือนเป็นแนวทางที่ดีในตอนแรกอาจไม่สามารถใช้งานได้หลังจากที่คุณเห็นโค้ดเบสแล้ว OpenSpec ยอมรับความเป็นจริงนี้
Easy not complex (ง่าย ไม่ซับซ้อน). เฟรมเวิร์กสเปคบางตัวต้องมีการตั้งค่าอย่างกว้างขวาง รูปแบบที่เข้มงวด หรือกระบวนการที่หนัก OpenSpec ไม่เป็นอุปสรรคของคุณ เริ่มต้นในไม่กี่วินาที เริ่มทำงานได้ทันที ปรับแต่งเฉพาะเมื่อจำเป็นเท่านั้น
Brownfield-first (ให้ความสำคัญกับโปรเจกต์เก่าก่อน). งานซอฟต์แวร์ส่วนใหญ่ไม่ใช่การสร้างจากศูนย์ — แต่เป็นการปรับเปลี่ยนระบบที่มีอยู่ วิธีการแบบเดลต้า (delta-based) ของ OpenSpec ทำให้ง่ายต่อการระบุการเปลี่ยนแปลงของพฤติกรรมที่มีอยู่ ไม่ใช่แค่การอธิบายระบบใหม่
ภาพรวม
OpenSpec จัดระเบียบงานของคุณออกเป็นสองส่วนหลัก:
┌────────────────────────────────────────────────────────────────────┐
│ openspec/ │
│ │
│ ┌─────────────────────┐ ┌───────────────────────────────┐ │
│ │ specs/ │ │ changes/ │ │
│ │ │ │ │ │
│ │ แหล่งข้อมูลจริง │◄─────│ การปรับเปลี่ยนที่เสนอ │ │
│ │ ระบบของคุณทำงาน │ merge│ แต่ละการเปลี่ยนแปลง = หนึ่งโฟลเดอร์ │
│ │ อย่างไรในปัจจุบัน │ │ ประกอบด้วย artifacts และ deltas │
│ │ │ │ │ │
│ └─────────────────────┘ └───────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────┘Specs เป็นแหล่งข้อมูลจริง — อธิบายพฤติกรรมปัจจุบันของระบบของคุณ
Changes เป็นการปรับเปลี่ยนที่เสนอ — อยู่ในโฟลเดอร์แยกจนกว่าคุณจะพร้อมผสานเข้าด้วยกัน
การแยกส่วนนี้เป็นกุญแจสำคัญ คุณสามารถทำงานหลายการเปลี่ยนแปลงพร้อมกันได้โดยไม่ขัดแย้ง คุณสามารถตรวจสอบการเปลี่ยนแปลงก่อนที่จะมีผลกับ specs หลัก และเมื่อคุณเก็บถาวรการเปลี่ยนแปลง deltas จะผสานเข้าสู่แหล่งข้อมูลจริงได้อย่างราบรื่น
พื้นที่ทำงานสำหรับการประสานงาน (Coordination Workspaces)
รองรับ Workspace อยู่ในขั้นเบต้า โมเดล local-view ด้านล่างคือทิศทางปัจจุบัน แต่การทำงานอัตโนมัติภายนอก การบูรณาการ และเวิร์กโฟลว์ที่ยาวนาน ยังควรจัดการพฤติกรรมคำสั่ง ไฟล์สถานะ และเอาต์พุต JSON ว่าอยู่ในระหว่างการพัฒนา
คำสั่งด้านล่างให้ขั้นตอนการตั้งค่าเบื้องต้นสำหรับการเปิดมุมมองท้องถิ่น (local views) บน repos หรือโฟลเดอร์ที่เชื่อมโยง
โปรเจกต์ OpenSpec ภายใน repo เป็นค่าเริ่มต้นที่เหมาะสมเมื่อ repo เดียวเป็นเจ้าของขั้นตอนการวางแผน การดำเนินการ และการเก็บถาวร บางงานครอบคลุมหลาย repo หรือโฟลเดอร์ สำหรับกรณีนี้ OpenSpec coordination workspace คือมุมมองเฉพาะเครื่อง (machine-local view) ที่รวม paths ที่เชื่อมโยง สถานะ opener และการตั้งค่า agent ไว้ด้วยกัน
แบบจำลองทางความคิดของ workspace มีดังนี้:
text
workspace = มุมมองท้องถิ่นส่วนตัวบน context stores, initiatives, repos, และโฟลเดอร์
context store = คอนเทนเนอร์บริบทที่ใช้ร่วมกันแบบถาวร
initiative = บริบทการประสานงานแบบถาวรภายใน context store
link = ชื่อที่เสถียรสำหรับ repo หรือโฟลเดอร์ที่ workspace สามารถแก้ไขได้ในเครื่อง
change = หนึ่งชิ้นงานที่วางแผนไว้; การดำเนินการอยู่ใน repo ที่เป็นเจ้าของWorkspace มีโครงสร้างแตกต่างจากโปรเจกต์ภายใน repo:
text
getGlobalDataDir()/workspaces/<workspace-name>/
├── workspace.yaml # บันทึกมุมมองท้องถิ่นส่วนตัว
├── AGENTS.md # คำแนะนำ runtime ที่สร้างขึ้น
└── <workspace-name>.code-workspace # ไฟล์ workspace ของ editor ที่สร้างขึ้นสถานะ OpenSpec ภายใน repo ยังคงโครงสร้างเดิม:
text
repo-root/
└── openspec/
├── specs/
└── changes/ความแตกต่างนี้สำคัญ โฟลเดอร์ workspace เป็นพื้นผิวการประสานงานท้องถิ่นสำหรับการเปิดและตรวจสอบ repos หรือโฟลเดอร์ที่เชื่อมโยง ไดเรกทอรี openspec/ ของแต่ละ repo ยังคงเป็นที่สำหรับ specs ที่ repo เป็นเจ้าของ changes ภายใน repo และการวางแผนการดำเนินการ ผู้ใช้ไม่จำเป็นต้องรันคำสั่ง openspec init ภายในโฟลเดอร์ workspace
ชื่อ link ที่เสถียรคือวิธีที่ workspace อ้างอิงถึง repos และโฟลเดอร์ บันทึก workspace ส่วนตัวเก็บชื่อเช่น api, web หรือ checkout และแมปไปยัง paths ภายในเครื่องของ runtime
yaml
# workspace.yaml
version: 1
name: platform
context: null
links:
api: /repos/api
web: /repos/webเมื่อ workspace เปิด initiative, context จะบันทึก binding ของ context-store ที่เลือกและ id ของ initiative stores ที่เลือกจาก registry ยังคงพกพาได้ด้วย id; stores ที่เลือกผ่าน path จะรักษา runtime-local path ไว้โดยเจตนาเนื่องจาก workspace.yaml เป็นสถานะท้องถิ่นส่วนตัว
yaml
context:
kind: initiative
store:
id: platform
selector:
kind: registry
id: platform
initiative:
id: billing-launchPaths ที่เชื่อมโยงอาจเป็น repo ทั้งหมด โฟลเดอร์ภายใน monorepo ขนาดใหญ่ หรือโฟลเดอร์ที่มีอยู่อื่นๆ ไม่จำเป็นต้องมีสถานะ openspec/ ภายใน repo ก่อนจึงจะเข้าร่วมการวางแผนของ workspace ได้ การดำเนินการ การตรวจสอบ หรือเวิร์กโฟลว์การเก็บถาวรในภายหลังอาจต้องการความพร้อมของ repo มากขึ้น แต่การมองเห็นในการวางแผนเริ่มต้นจาก link
text
multi-repo:
api -> /repos/api
web -> /repos/web
large monorepo:
billing -> /repos/platform/services/billing
checkout -> /repos/platform/apps/checkoutWorkspaces ที่จัดการอยู่ภายใต้ไดเรกทอรีข้อมูล OpenSpec มาตรฐาน:
text
getGlobalDataDir()/workspacesหมายความว่าเป็น $XDG_DATA_HOME/openspec/workspaces เมื่อตั้งค่า XDG_DATA_HOME, ~/.local/share/openspec/workspaces บน fallback แบบ Unix และ %LOCALAPPDATA%\openspec\workspaces บน fallback แบบ Windows ดั้งเดิม เชลล์ Windows ดั้งเดิม PowerShell และ WSL2 ต่างเก็บ strings ของ path สำหรับ runtime ที่รัน OpenSpec พื้นฐานนี้ไม่แปลงระหว่าง D:\repo, /mnt/d/repo และ UNC WSL paths
OpenSpec ยังสามารถอ่านราก workspace เบตารุ่นเก่าเป็นข้อมูลที่เข้ากันได้ แต่ workspaces ที่จัดการตอนนี้ใช้บันทึก workspace.yaml ที่รากดังกล่าวข้างต้น โฟลเดอร์ workspace ยังคงเป็นแหล่งข้อมูลหลักสำหรับมุมมองท้องถิ่นส่วนตัวของมันเอง
การมองเห็นของ workspace ไม่ใช่การผูกมัดต่อการเปลี่ยนแปลง ตั้งค่า workspace เมื่อ OpenSpec ควรรู้ว่า repos หรือโฟลเดอร์ใดเกี่ยวข้อง; สร้าง change ในภายหลังเมื่อคุณพร้อมวางแผนฟีเจอร์ การแก้ไขไข โปรเจกต์ หรือชิ้นงานอื่นๆ
คำสั่งที่เป็นประโยชน์:
bash
# การตั้งค่าแบบมีคำแนะนำ
openspec workspace setup
# การตั้งค่าที่เป็นมิตรกับระบบอัตโนมัติ
openspec workspace setup --no-interactive --name platform --link /repos/api --link web=/repos/web
openspec workspace setup --no-interactive --name platform --link /repos/api --opener codex-cli
# ดู workspaces ที่รู้จักจาก local registry
openspec workspace list
openspec workspace ls
# เพิ่มหรือซ่อมแซม links สำหรับ workspace ที่เลือก
openspec workspace link /repos/api
openspec workspace link api-service /repos/api
openspec workspace relink api-service /new/path/to/api
# ตรวจสอบสิ่งที่เครื่องนี้สามารถแก้ไขได้
openspec workspace doctor
openspec workspace doctor --workspace platform
# รีเฟรชคำแนะนำภายใน workspace และทักษะ agent
openspec workspace update
openspec workspace update --workspace platform --tools codex,claude
# เปิดชุดงานที่เชื่อมโยง
openspec workspace open
openspec workspace open platform --agent github-copilot
openspec workspace open --editor
# เปิด initiative ในรูปแบบมุมมอง workspace ท้องถิ่น
openspec workspace open --initiative billing-launch --store platform
openspec workspace open --initiative billing-launch --store-path /repos/platform-contextworkspace setup จะสร้าง workspace ในตำแหน่งมาตรฐานเสมอ บันทึกใน local registry แสดงตำแหน่งของ workspace และต้องการอย่างน้อยหนึ่ง repo หรือโฟลเดอร์ที่เชื่อมโยง การตั้งค่าแบบโต้ตอบจะถามหา opener ที่ต้องการและสามารถติดตั้งทักษะ OpenSpec สำหรับ agents ที่เลือก การตั้งค่าแบบไม่โต้ตอบจะเก็บ opener เพียงตัวเดียวเมื่อมีการระบุ --opener codex-cli, --opener claude, --opener github-copilot หรือ --opener editor
ทักษะของ workspace จะถูกติดตั้งเฉพาะในราก workspace เท่านั้น โปรไฟล์ global ที่ใช้งานอยู่จะเลือกว่าเวิร์กโฟลว์ทักษะใดจะถูกสร้าง; --tools เลือกว่า agents ใดจะได้รับ การตั้งค่าและอัปเดต workspace ไม่สร้างไฟล์คำสั่ง slash แม้ว่า global delivery จะรวมคำสั่ง รัน openspec workspace update เพื่อรีเฟรชคำแนะนำภายใน workspace และเพิ่ม รีเฟรช หรือลบไดเรกทอรีทักษะ workspace ที่จัดการโดยไม่ต้องแก้ไข repos หรือโฟลเดอร์ที่เชื่อมโยง
OpenSpec ยังดูแลไฟล์ open ของ root workspace: บล็อกคำแนะนำที่จัดการโดย OpenSpec ใน AGENTS.md และไฟล์ <workspace-name>.code-workspace สำหรับเครื่องเพื่อเปิดใน VS Code และ GitHub Copilot-in-VS-Code Workspace ที่จัดการไม่ใช่ repo ดังนั้น OpenSpec จึงไม่สร้าง .gitignore เริ่มต้นของ workspace หรือไดเรกทอรี changes/ ระดับ workspace เริ่มต้น
ไฟล์ workspace ของ VS Code ที่ดูแลจะลิสต์ repos หรือโฟลเดอร์ที่เชื่อมโยงที่ถูกต้องก่อน จากนั้นตามด้วยบริบท initiative เมื่อแนบมา และจากนั้นคือไฟล์ workspace ของ OpenSpec VS Code จะแสดงรายการเหล่านั้นเป็น multi-root workspace
workspace open เปิดชุดงานที่เชื่อมโยงด้วย opener ที่ต้องการที่เก็บไว้ เว้นแต่จะส่ง --agent <tool> หรือ --editor สำหรับเซสชันนั้น การส่งทั้ง opener override ถือเป็นข้อผิดพลาด การเปิด root workspace ทำให้ repos และโฟลเดอร์ที่เชื่อมโยงมองเห็นได้สำหรับการสำรวจและบริบท; การดำเนินการเริ่มต้นหลังจากที่ผู้ใช้ร้องขออย่างชัดเจน
workspace link และ workspace relink บันทึกเฉพาะโฟลเดอร์ที่มีอยู่เท่านั้น; ไม่สร้าง คัดลอก ย้าย เริ่มต้น หรือแก้ไข repo หรือโฟลเดอร์ที่เชื่อมโยง หลังจาก link หรือ relink สำเร็จ OpenSpec จะรีเฟรชคำแนะนำที่จัดการและไฟล์ workspace ของ VS Code
คำสั่ง workspace ที่ต้องการ workspace หนึ่งสามารถรันจากที่ใดก็ได้ด้วย --workspace <name> หากคุณรันคำสั่งเหล่านั้นภายในโฟลเดอร์ workspace หรือไดเรกทอรีย่อย OpenSpec จะใช้ workspace ปัจจุบันนั้น หากมี workspaces ที่รู้จักหลายตัวและคุณไม่ได้ส่ง --workspace <name> คำสั่งของมนุษย์จะแสดงตัวเลือก; --json และ --no-interactive จะล้มเหลวพร้อมข้อผิดพลาดสถานะแบบมีโครงสร้างแทนที่จะถาม
คำสั่ง workspace โดยตรงรองรับเอาต์พุต JSON สำหรับสคริปต์ การตอบสนอง JSON เก็บข้อมูลหลักในวัตถุ workspace, workspaces หรือ link และรายงานคำเตือนหรือข้อผิดพลาดในอาร์เรย์ status วัตถุที่ทำงานปกติใช้ status: []
Specs
Specs อธิบายพฤติกรรมของระบบของคุณโดยใช้ข้อกำหนดและสถานการณ์ที่มีโครงสร้าง
โครงสร้าง
openspec/specs/
├── auth/
│ └── spec.md # พฤติกรรมการยืนยันตัวตน
├── payments/
│ └── spec.md # การประมวลผลการชำระเงิน
├── notifications/
│ └── spec.md # ระบบการแจ้งเตือน
└── ui/
└── spec.md # พฤติกรรม UI และธีมจัดระเบียบ specs ตามโดเมน — การจัดกลุ่มตามตรรกะที่เหมาะสมกับระบบของคุณ รูปแบบทั่วไป:
- ตามพื้นที่ฟีเจอร์:
auth/,payments/,search/ - ตามคอมโพเนนต์:
api/,frontend/,workers/ - ตาม bounded context:
ordering/,fulfillment/,inventory/
รูปแบบ Spec
สเปคมีข้อกำหนด และแต่ละข้อกำหนดมีสถานการณ์:
markdown
# ข้อกำหนดการยืนยันตัวตน (Auth Specification)
## วัตถุประสงค์
การจัดการการยืนยันตัวตนและเซสชันสำหรับแอปพลิเคชัน
## ข้อกำหนด (Requirements)
### ข้อกำหนด: การยืนยันตัวตนผู้ใช้
ระบบ SHALL ออกโทเค็น JWT เมื่อเข้าสู่ระบบสำเร็จ
#### สถานการณ์: ข้อมูลรับรองที่ถูกต้อง
- GIVEN ผู้ใช้ที่มีข้อมูลรับรองที่ถูกต้อง
- WHEN ผู้ใช้ส่งแบบฟอร์มเข้าสู่ระบบ
- THEN โทเค็น JWT จะถูกส่งกลับ
- AND ผู้ใช้จะถูกเปลี่ยนเส้นทางไปยังแดชบอร์ด
#### สถานการณ์: ข้อมูลรับรองไม่ถูกต้อง
- GIVEN ข้อมูลรับรองที่ไม่ถูกต้อง
- WHEN ผู้ใช้ส่งแบบฟอร์มเข้าสู่ระบบ
- THEN ข้อความแสดงข้อผิดพลาดจะปรากฏขึ้น
- AND ไม่มีการออกโทเค็น
### ข้อกำหนด: การหมดอายุของเซสชัน
ระบบ MUST ให้เซสชันหมดอายุหลังจากไม่มีกิจกรรม 30 นาที
#### สถานการณ์: หมดเวลาเนื่องจากไม่มีกิจกรรม
- GIVEN เซสชันที่ยืนยันตัวตนแล้ว
- WHEN ผ่านไป 30 นาทีโดยไม่มีกิจกรรม
- THEN เซสชันจะถูกยกเลิก
- AND ผู้ใช้ต้องยืนยันตัวตนอีกครั้งองค์ประกอบสำคัญ:
| องค์ประกอบ | วัตถุประสงค์ |
|---|---|
## Purpose | คำอธิบายภาพรวมของโดเมนของ spec นี้ |
### Requirement: | พฤติกรรมเฉพาะที่ระบบต้องมี |
#### Scenario: | ตัวอย่างที่เป็นรูปธรรมของข้อกำหนดในการปฏิบัติ |
| SHALL/MUST/SHOULD | คำสำคัญตาม RFC 2119 ที่ระบุความแข็งแกร่งของข้อกำหนด |
ทำไมถึงจัดระเบียบ Specs ด้วยวิธีนี้
ข้อกำหนดคือ "อะไร" — ระบุว่าระบบควรทำอะไรโดยไม่กำหนดการนำไปใช้
สถานการณ์คือ "เมื่อไหร่" — ให้ตัวอย่างที่เป็นรูปธรรมที่สามารถตรวจสอบได้ สถานการณ์ที่ดี:
- สามารถทดสอบได้ (คุณสามารถเขียนการทดสอบอัตโนมัติได้)
- ครอบคลุมทั้งเส้นทางที่ถูกต้องและกรณีขอบเขต
- ใช้รูปแบบ Given/When/Then หรือรูปแบบที่มีโครงสร้างคล้ายกัน
คำสำคัญ RFC 2119 (SHALL, MUST, SHOULD, MAY) สื่อสารความตั้งใจ:
- MUST/SHALL — ข้อกำหนดเบ็ดเสร็จ
- SHOULD — แนะนำ แต่มีข้อยกเว้น
- MAY — ทางเลือก
Spec คืออะไร (และไม่ใช่อะไร)
Spec คือ สัญญาพฤติกรรม ไม่ใช่แผนการดำเนินการ
เนื้อหา Spec ที่ดี:
- พฤติกรรมที่สังเกตได้ที่ผู้ใช้หรือระบบปลายน้ำพึ่งพา
- อินพุต เอาต์พุต และเงื่อนไขข้อผิดพลาด
- ข้อจำกัดภายนอก (ความปลอดภัย ความเป็นส่วนตัว ความน่าเชื่อถือ ความเข้ากันได้)
- สถานการณ์ที่สามารถทดสอบหรือตรวจสอบอย่างชัดเจน
สิ่งที่ควรหลีกเลี่ยงใน specs:
- ชื่อคลาส/ฟังก์ชันภายใน
- การเลือกไลบรารีหรือเฟรมเวิร์ก
- รายละเอียดการดำเนินการทีละขั้น
- แผนการดำเนินงานโดยละเอียด (สิ่งเหล่านั้นควรอยู่ใน
design.mdหรือtasks.md)
ทดสอบอย่างเร็ว:
- หากการนำไปใช้สามารถเปลี่ยนแปลงได้โดยไม่เปลี่ยนพฤติกรรมที่มองเห็นจากภายนอก นั่นอาจไม่ควรอยู่ใน spec
รักษาความเบา: ความเข้มงวดเชิงรุก (Progressive Rigor)
OpenSpec มุ่งหวังที่จะหลีกเลี่ยงระบบราชการ ใช้ระดับความเบาที่ยังคงทำให้การเปลี่ยนแปลงสามารถตรวจสอบได้
Spec แบบเบา (ค่าเริ่มต้น):
- ข้อกำหนดเชิงพฤติกรรมสั้นๆ ที่เน้นพฤติกรรม
- ขอบเขตและสิ่งที่ไม่ใช่เป้าหมายที่ชัดเจน
- การตรวจสอบการยอมรับที่เป็นรูปธรรมไม่กี่รายการ
Spec แบบเต็ม (สำหรับความเสี่ยงสูงกว่า):
- การเปลี่ยนแปลงข้ามทีมหรือข้าม repo
- การเปลี่ยนแปลง API/สัญญา การโยกย้าย ปัญหาด้านความปลอดภัย/ความเป็นส่วนตัว
- การเปลี่ยนแปลงที่ความคลุมเครืออาจก่อให้เกิดการแก้ไขไขที่มีค่าใช้จ่ายสูง
การเปลี่ยนแปลงส่วนใหญ่ควรอยู่ในโหมดเบา
ความร่วมมือระหว่างมนุษย์และ Agent
ในหลายทีม มนุษย์จะสำรวจและ agents จะร่าง artifacts วนรอบที่ตั้งใจไว้คือ:
- มนุษย์ให้ความตั้งใจ บริบท และข้อจำกัด
- Agent แปลงสิ่งนี้เป็นข้อกำหนดเชิงพฤติกรรมและสถานการณ์
- Agent เก็บรายละเอียดการดำเนินการไว้ใน
design.mdและtasks.mdไม่ใช่spec.md - การตรวจสอบยืนยันโครงสร้างและความชัดเจนก่อนการดำเนินการ
สิ่งนี้ทำให้ specs อ่านง่ายสำหรับมนุษย์และสอดคล้องสำหรับ agents
การเปลี่ยนแปลง
การเปลี่ยนแปลงคือข้อเสนอแก้ไขระบบของคุณ ซึ่งถูกจัดรูปแบบเป็นโฟลเดอร์ที่มีทุกอย่างที่จำเป็นเพื่อความเข้าใจและการนำไปใช้
โครงสร้างการเปลี่ยนแปลง
openspec/changes/add-dark-mode/
├── proposal.md # ทำไมและทำอะไร
├── design.md # อย่างไร (แนวทางทางเทคนิค)
├── tasks.md # รายการตรวจสอบการนำไปใช้
├── .openspec.yaml # เมตาดาต้าการเปลี่ยนแปลง (ไม่บังคับ)
└── specs/ # สเปคเดลต้า
└── ui/
└── spec.md # สิ่งที่เปลี่ยนแปลงใน ui/spec.mdแต่ละการเปลี่ยนแปลงเป็นหน่วยที่สมบูรณ์ในตัวเอง มันประกอบด้วย:
- เอกสาร — เอกสารที่บันทึกความตั้งใจ การออกแบบ และงาน
- สเปคเดลต้า — ข้อกำหนดสำหรับสิ่งที่ถูกเพิ่ม แก้ไข หรือลบ
- เมตาดาต้า — การกำหนดค่าตัวเลือกสำหรับการเปลี่ยนแปลงนี้โดยเฉพาะ
ทำไมการเปลี่ยนแปลงถึงเป็นโฟลเดอร์
การจัดแพ็กเกจการเปลี่ยนแปลงเป็นโฟลเดอร์มีข้อดีหลายประการ:
รวมทุกอย่างอยู่ด้วยกัน ข้อเสนอ การออกแบบ งาน และสเปคอยู่ในที่เดียว ไม่ต้องค้นหาจากหลายสถานที่
ทำงานคู่ขนาน การเปลี่ยนแปลงหลายรายการสามารถมีอยู่พร้อมกันได้โดยไม่ขัดแย้ง ทำงานกับ
add-dark-modeขณะที่fix-auth-bugก็อยู่ในระหว่างดำเนินการประวัติที่ชัดเจน เมื่อเก็บเข้าคลังแล้ว การเปลี่ยนแปลงจะย้ายไปที่
changes/archive/พร้อมบริบทที่สมบูรณ์ คุณย้อนดูและเข้าใจได้ไม่เพียงแต่ว่ามีอะไรเปลี่ยน แต่ยังเข้าใจว่าทำไมสะดวกสำหรับการตรวจสอบ โฟลเดอร์การเปลี่ยนแปลงตรวจสอบง่าย — เปิดมัน อ่านข้อเสนอ ตรวจสอบการออกแบบ ดูเดลต้าสเปค
เอกสาร
เอกสารคือเอกสารภายในการเปลี่ยนแปลงที่ช่วยนำทางงาน
กระแสเอกสาร
proposal ──────► specs ──────► design ──────► tasks ──────► implement
│ │ │ │
ทำไม ทำอะไร อย่างไร ขั้นตอน
+ ขอบเขต เปลี่ยนแปลง แนวทาง ที่ต้องทำเอกสารสร้างขึ้นต่อเนื่องจากกันและกัน แต่ละเอกสารให้บริบทสำหรับเอกสารถัดไป
ประเภทเอกสาร
ข้อเสนอ (proposal.md)
ข้อเสนอบันทึก ความตั้งใจ, ขอบเขต, และ แนวทาง ในระดับสูง
markdown
# ข้อเสนอ: เพิ่มโหมดมืดเจตนา
ผู้ใช้ได้ร้องขอตัวเลือกโหมดมืดเพื่อลดอาการเมื่อยล้าของดวงตา ระหว่างการใช้งานในตอนกลางคืน และให้สอดคล้องกับค่าที่ตั้งไว้ของระบบ
ขอบเขต
อยู่ในขอบเขต:
- ปุ่มสลับธีมในการตั้งค่า
- การตรวจจับค่าที่ตั้งไว้ของระบบ
- จัดเก็บค่าที่ตั้งไว้ใน localStorage
อยู่นอกขอบเขต:
- ธีมสีที่กำหนดเอง (งานในอนาคต)
- การแทนที่ธีมแยกตามหน้า
แนวทาง
ใช้ CSS custom properties สำหรับการจัดการธีม ร่วมกับ React context สำหรับการจัดการสถานะ ตรวจจับค่าที่ตั้งไว้ของระบบเมื่อโหลดครั้งแรก และอนุญาตให้แทนที่ด้วยตนเอง
**เมื่อใดควรอัปเดตข้อเสนอ:**
- ขอบเขตเปลี่ยนแปลง (แคบลงหรือกว้างขึ้น)
- เจตนาชัดเจนขึ้น (เข้าใจปัญหาได้ดีกว่าเดิม)
- แนวทางเปลี่ยนแปลงอย่างมีนัยสำคัญ
#### สเปค (สเปคแบบเดลตาใน `specs/`)
สเปคแบบเดลตาอธิบาย**สิ่งที่เปลี่ยนแปลง**เมื่อเทียบกับสเปคปัจจุบัน ดู [สเปคแบบเดลตา](#delta-specs) ด้านล่าง
#### การออกแบบ (`design.md`)
การออกแบบบันทึก**แนวทางทางเทคนิค**และ**การตัดสินใจด้านสถาปัตยกรรม**
````markdown
# การออกแบบ: เพิ่มโหมดมืด
## แนวทางทางเทคนิค
สถานะธีมจัดการผ่าน React Context เพื่อหลีกเลี่ยง prop drilling
CSS custom properties ช่วยให้สลับได้ในขณะรันไทม์โดยไม่ต้องสลับคลาส
## การตัดสินใจด้านสถาปัตยกรรม
### การตัดสินใจ: Context แทน Redux
ใช้ React Context สำหรับสถานะธีมเพราะ:
- สถานะแบบไบนารีเรียบง่าย (สว่าง/มืด)
- ไม่มีการเปลี่ยนสถานะที่ซับซ้อน
- หลีกเลี่ยงการเพิ่มการพึ่งพา Redux
### การตัดสินใจ: CSS Custom Properties
ใช้ตัวแปร CSS แทน CSS-in-JS เพราะ:
- ทำงานร่วมกับ stylesheet ที่มีอยู่
- ไม่มี overhead ขณะรันไทม์
- โซลูชันที่มีอยู่ในเบราว์เซอร์โดยธรรมชาติ
## การไหลของข้อมูลThemeProvider (context) │ ▼ ThemeToggle ◄──► localStorage │ ▼ CSS Variables (applied to :root)
## การเปลี่ยนแปลงไฟล์
- `src/contexts/ThemeContext.tsx` (ใหม่)
- `src/components/ThemeToggle.tsx` (ใหม่)
- `src/styles/globals.css` (แก้ไข)เมื่อใดควรอัปเดตการออกแบบ:
- การนำไปใช้พบว่าแนวทางไม่สามารถทำงานได้
- ค้นพบโซลูชันที่ดีกว่า
- การพึ่งพาหรือข้อจำกัดเปลี่ยนแปลง
งาน (tasks.md)
งานคือรายการตรวจสอบการนำไปใช้ — ขั้นตอนที่เป็นรูปธรรมพร้อมช่องทำเครื่องหมาย
markdown
# งาน
## 1. พื้นฐานของธีม
- [ ] 1.1 สร้าง ThemeContext พร้อมสถานะสว่าง/มืด
- [ ] 1.2 เพิ่ม CSS custom properties สำหรับสี
- [ ] 1.3 ดำเนินการจัดเก็บข้อมูลใน localStorage
- [ ] 1.4 เพิ่มการตรวจจับค่าที่ตั้งไว้ของระบบ
## 2. คอมโพเนนต์ UI
- [ ] 2.1 สร้างคอมโพเนนต์ ThemeToggle
- [ ] 2.2 เพิ่มปุ่มสลับไปยังหน้าการตั้งค่า
- [ ] 2.3 อัปเดต Header เพื่อเพิ่มปุ่มสลับด่วน
## 3. การจัดรูปแบบ
- [ ] 3.1 กำหนดจานสีของธีมมืด
- [ ] 3.2 อัปเดตคอมโพเนนต์ให้ใช้ตัวแปร CSS
- [ ] 3.3 ทดสอบอัตราส่วนคอนทราสต์เพื่อการเข้าถึงแนวทางปฏิบัติที่ดีสำหรับงาน:
- จัดกลุ่มงานที่เกี่ยวข้องภายใต้หัวข้อ
- ใช้ลำดับเลขชั้น (1.1, 1.2 เป็นต้น)
- รักษางานให้เล็กพอที่จะทำให้เสร็จในหนึ่งเซสชัน
- ทำเครื่องหมายงานเมื่อทำเสร็จ
สเปคแบบเดลตา
สเปคแบบเดลตาเป็นแนวคิดหลักที่ทำให้ OpenSpec ทำงานได้ดีสำหรับการพัฒนาแบบ brownfield โดยอธิบายสิ่งที่เปลี่ยนแปลงแทนการระบุสเปคทั้งหมดซ้ำ
รูปแบบ
markdown
# เดลตาสำหรับ Auth
## ข้อกำหนดที่เพิ่ม
### ข้อกำหนด: การยืนยันตัวตนสองชั้น
ระบบต้องรองรับการยืนยันตัวตนสองชั้นแบบ TOTP
#### สถานการณ์: การลงทะเบียน 2FA
- กำหนดให้ ผู้ใช้ที่ยังไม่ได้เปิดใช้ 2FA
- เมื่อ ผู้ใช้เปิดใช้ 2FA ในการตั้งค่า
- แสดง QR code สำหรับตั้งค่าแอปยืนยันตัวตน
- และ ผู้ใช้ต้องยืนยันด้วยรหัสก่อนเปิดใช้งาน
#### สถานการณ์: การเข้าสู่ระบบด้วย 2FA
- กำหนดให้ ผู้ใช้ที่เปิดใช้ 2FA แล้ว
- เมื่อ ผู้ใช้ส่งข้อมูลรับรองที่ถูกต้อง
- แสดงการท้าทาย OTP
- และ การเข้าสู่ระบบจะเสร็จสมบูรณ์เมื่อ OTP ถูกต้องเท่านั้น
## ข้อกำหนดที่แก้ไข
### ข้อกำหนด: การหมดอายุเซสชัน
ระบบต้องทำให้เซสชันหมดอายุหลังจากไม่มีกิจกรรม 15 นาที
(เดิม: 30 นาที)
#### สถานการณ์: หมดเวลาเนื่องจากไม่มีกิจกรรม
- กำหนดให้ เซสชันที่ยืนยันตัวตนแล้ว
- เมื่อ ผ่านไป 15 นาทีโดยไม่มีกิจกรรม
- เซสชันจะถูกยกเลิก
## ข้อกำหนดที่ลบออก
### ข้อกำหนด: จดจำฉัน
(เลิกใช้เพื่อรองรับ 2FA ผู้ใช้ควรยืนยันตัวตนใหม่ทุกเซสชัน)ส่วนของเดลตา
| ส่วน | ความหมาย | เกิดอะไรขึ้นเมื่อเก็บถาวร |
|---|---|---|
## ข้อกำหนดที่เพิ่ม | พฤติกรรมใหม่ | เพิ่มต่อท้ายสเปคหลัก |
## ข้อกำหนดที่แก้ไข | พฤติกรรมที่เปลี่ยนแปลง | แทนที่ข้อกำหนดที่มีอยู่ |
## ข้อกำหนดที่ลบออก | พฤติกรรมที่เลิกใช้ | ลบออกจากสเปคหลัก |
ทำไมใช้เดลตาแทนสเปคเต็ม
ความชัดเจน เดลตาแสดงให้เห็นอย่างชัดเจนว่ามีอะไรเปลี่ยนแปลง การอ่านสเปคเต็ม คุณจะต้องเปรียบเทียบกับเวอร์ชันปัจจุบันด้วยตนเอง
หลีกเลี่ยงความขัดแย้ง การเปลี่ยนแปลงสองรายการสามารถแตะไฟล์สเปคเดียวกันได้โดยไม่ขัดแย้ง ตราบใดที่แก้ไขข้อกำหนดที่ต่างกัน
ประสิทธิภาพในการตรวจสอบ ผู้ตรวจสอบเห็นเฉพาะสิ่งที่เปลี่ยนแปลง ไม่ใช่บริบทที่ไม่เปลี่ยนแปลง มุ่งเน้นไปที่สิ่งที่สำคัญ
เหมาะสมกับ brownfield งานส่วนใหญ่เป็นการแก้ไขพฤติกรรมที่มีอยู่ เดลตาทำให้การแก้ไขเป็นสิ่งที่มีความสำคัญลำดับแรก ไม่ใช่สิ่งที่คิดทีหลัง
สคีมา
สคีมากำหนดประเภทองค์ประกอบและความสัมพันธ์ระหว่างกันสำหรับเวิร์กโฟลว์
สคีมาทำงานอย่างไร
yaml
# openspec/schemas/spec-driven/schema.yaml
name: spec-driven
artifacts:
- id: proposal
generates: proposal.md
requires: [] # ไม่มีการพึ่งพา สามารถสร้างได้ก่อน
- id: specs
generates: specs/**/*.md
requires: [proposal] # ต้องมี proposal ก่อนสร้าง
- id: design
generates: design.md
requires: [proposal] # สามารถสร้างพร้อมกับ specs ได้
- id: tasks
generates: tasks.md
requires: [specs, design] # ต้องมีทั้ง specs และ design ก่อนองค์ประกอบต่างๆ สร้างกราฟการพึ่งพา:
proposal
(โหนดราก)
│
┌─────────────┴─────────────┐
│ │
▼ ▼
specs design
(requires: (requires:
proposal) proposal)
│ │
└─────────────┬─────────────┘
│
▼
tasks
(requires:
specs, design)การพึ่งพาเป็นตัวเปิดใช้งาน ไม่ใช่ประตู แสดงให้เห็นว่าสามารถสร้างอะไรได้ ไม่ใช่สิ่งที่ต้องสร้างต่อไป คุณสามารถข้ามการออกแบบได้หากไม่ต้องการ คุณสามารถสร้างสเปคก่อนหรือหลังการออกแบบก็ได้ — ทั้งสองขึ้นอยู่กับ proposal เพียงอย่างเดียว
สคีมาที่มีมาในตัว
spec-driven (ค่าเริ่มต้น)
เวิร์กโฟลว์มาตรฐานสำหรับการพัฒนาแบบขับเคลื่อนด้วยสเปค:
proposal → specs → design → tasks → implementเหมาะสำหรับ: งานฟีเจอร์ส่วนใหญ่ที่ต้องการตกลงในสเปคก่อนนำไปใช้
สคีมาที่กำหนดเอง
สร้างสคีมาที่กำหนดเองสำหรับเวิร์กโฟลว์ของทีมคุณ:
bash
# สร้างจากศูนย์
openspec schema init research-first
# หรือแยกจากสคีมาที่มีอยู่
openspec schema fork spec-driven research-firstตัวอย่างสคีมาที่กำหนดเอง:
yaml
# openspec/schemas/research-first/schema.yaml
name: research-first
artifacts:
- id: research
generates: research.md
requires: [] # ทำวิจัยก่อน
- id: proposal
generates: proposal.md
requires: [research] # ข้อเสนออิงจากผลวิจัย
- id: tasks
generates: tasks.md
requires: [proposal] # ข้ามสเปค/การออกแบบ ไปที่งานเลยดูรายละเอียดเพิ่มเติมเกี่ยวกับการสร้างและใช้สคีมาที่กำหนดเองได้ที่ การปรับแต่ง
การเก็บถาวร
การเก็บถาวรทำให้การเปลี่ยนแปลงเสร็จสมบูรณ์ โดยรวมสเปคแบบเดลตาเข้ากับสเปคหลัก และรักษาการเปลี่ยนแปลงไว้เพื่อเป็นประวัติ
เกิดอะไรขึ้นเมื่อคุณเก็บถาวร
ก่อนเก็บถาวร:
openspec/
├── specs/
│ └── auth/
│ └── spec.md ◄────────────────┐
└── changes/ │
└── add-2fa/ │
├── proposal.md │
├── design.md │ รวม
├── tasks.md │
└── specs/ │
└── auth/ │
└── spec.md ─────────┘
หลังเก็บถาวร:
openspec/
├── specs/
│ └── auth/
│ └── spec.md # ตอนนี้รวมข้อกำหนด 2FA แล้ว
└── changes/
└── archive/
└── 2025-01-24-add-2fa/ # รักษาไว้เพื่อเป็นประวัติ
├── proposal.md
├── design.md
├── tasks.md
└── specs/
└── auth/
└── spec.mdกระบวนการเก็บถาวร
รวมเดลตา ส่วนของสเปคแบบเดลตาแต่ละส่วน (เพิ่ม/แก้ไข/ลบออก) จะถูกนำไปใช้กับสเปคหลักที่เกี่ยวข้อง
ย้ายไปเก็บถาวร โฟลเดอร์การเปลี่ยนแปลงจะย้ายไปที่
changes/archive/พร้อมคำนำหน้าเป็นวันที่เพื่อเรียงลำดับตามเวลารักษาบริบท องค์ประกอบทั้งหมดยังคงอยู่ครบถ้วนในที่เก็บถาวร คุณสามารถย้อนดูได้เสมอเพื่อเข้าใจว่าทำไมจึงมีการเปลี่ยนแปลง
ทำไมการเก็บถาวรจึงสำคัญ
สถานะที่สะอาด การเปลี่ยนแปลงที่ใช้งานอยู่ (changes/) แสดงเฉพาะงานที่กำลังดำเนินการ งานที่เสร็จแล้วจะย้ายออกไป
บันทึกการตรวจสอบ ที่เก็บถาวรรักษาบริบทที่สมบูรณ์ของการเปลี่ยนแปลงทุกครั้ง — ไม่ใช่แค่สิ่งที่เปลี่ยน แต่ยังมีข้อเสนอที่อธิบายเหตุผล การออกแบบที่อธิบายวิธีการ และงานที่แสดงให้เห็นการทำงานที่ทำเสร็จ
วิวัฒนาการของสเปค สเปคเติบโตอย่างเป็นธรรมชาติเมื่อมีการเก็บถาวรการเปลี่ยนแปลง แต่ละที่เก็บถาวรจะรวมเดลตาของมัน สร้างข้อกำหนดที่ครอบคลุมเมื่อเวลาผ่านไป
ทุกอย่างทำงานร่วมกันอย่างไร
┌──────────────────────────────────────────────────────────────────────────────┐
│ ขั้นตอน OPENSPEC │
│ │
│ ┌────────────────┐ │
│ │ 1. เริ่มต้น │ /opsx:propose (หลัก) หรือ /opsx:new (ขยาย) │
│ │ การเปลี่ยนแปลง│ │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 2. สร้าง │ /opsx:ff หรือ /opsx:continue (เวิร์กโฟลว์ขยาย) │
│ │ องค์ประกอบ │ สร้าง proposal → specs → design → tasks │
│ │ │ (ตามการพึ่งพาของสคีมา) │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 3. นำไปใช้ │ /opsx:apply │
│ │ งาน │ ดำเนินงานตามรายการ ทำเครื่องหมายเมื่อเสร็จ │
│ │ │◄──── อัปเดตองค์ประกอบเมื่อเรียนรู้สิ่งใหม่ │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 4. ตรวจสอบ │ /opsx:verify (ไม่บังคับ) │
│ │ ผลงาน │ ตรวจสอบว่าการนำไปใช้ตรงกับสเปค │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ ┌──────────────────────────────────────────────┐ │
│ │ 5. เก็บถาวร │────►│ สเปคแบบเดลตารวมเข้ากับสเปคหลัก │ │
│ │ การเปลี่ยนแปลง│ │ โฟลเดอร์การเปลี่ยนแปลงย้ายไปที่ archive/ │ │
│ └────────────────┘ │ สเปคตอนนี้เป็นแหล่งข้อมูลจริงที่อัปเดตแล้ว │ │
│ └──────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘วัฏจักรที่มีคุณค่า:
- สเปคอธิบายพฤติกรรมปัจจุบัน
- การเปลี่ยนแปลงเสนอการแก้ไข (ในรูปแบบเดลตา)
- การนำไปใช้ทำให้การเปลี่ยนแปลงเกิดขึ้นจริง
- การเก็บถาวรรวมเดลตาเข้ากับสเปค
- สเปคตอนนี้อธิบายพฤติกรรมใหม่
- การเปลี่ยนแปลงครั้งถัดไปสร้างบนสเปคที่อัปเดตแล้ว
อภิธานศัพท์
| คำศัพท์ | คำจำกัดความ |
|---|---|
| เอกสาร (Artifact) | เอกสารภายในหนึ่งการเปลี่ยนแปลง (ข้อเสนอ, การออกแบบ, งาน หรือข้อกำหนดเดลตา) |
| จัดเก็บถาวร (Archive) | กระบวนการเสร็จสิ้นการเปลี่ยนแปลงและรวมเดลตาเข้ากับข้อกำหนดหลัก |
| การเปลี่ยนแปลง (Change) | การแก้ไขที่เสนอต่อระบบ จัดรูปแบบเป็นโฟลเดอร์ที่มีเอกสารประกอบ |
| ข้อกำหนดเดลตา (Delta spec) | ข้อกำหนดที่อธิบายการเปลี่ยนแปลง (เพิ่ม/แก้ไข/ลบ) เมื่อเทียบกับข้อกำหนดปัจจุบัน |
| โดเมน (Domain) | การจัดกลุ่มเชิงตรรกะสำหรับข้อกำหนด (เช่น auth/, payments/) |
| ข้อกำหนด (Requirement) | พฤติกรรมเฉพาะที่ระบบต้องมี |
| สถานการณ์ (Scenario) | ตัวอย่างที่เป็นรูปธรรมของข้อกำหนด โดยทั่วไปอยู่ในรูปแบบ เมื่อ/ถ้า/จากนั้น |
| โครงร่าง (Schema) | คำจำกัดความของประเภทเอกสารและการพึ่งพาอาศัยกัน |
| ข้อกำหนด (Spec) | ข้อกำหนดที่อธิบายพฤติกรรมของระบบ ประกอบด้วยข้อกำหนดและสถานการณ์ |
| แหล่งข้อมูลที่แท้จริง (Source of truth) | ไดเรกทอรี openspec/specs/ ซึ่งมีพฤติกรรมที่ตกลงร่วมกันในปัจจุบัน |
ขั้นตอนถัดไป
- เริ่มต้นใช้งาน - ขั้นตอนแรกเชิงปฏิบัติ
- ขั้นตอนการทำงาน - รูปแบบที่พบบ่อยและเมื่อใดควรใช้แต่ละแบบ
- คำสั่ง - อ้างอิงคำสั่งทั้งหมด
- การปรับแต่ง - สร้างโครงร่างที่กำหนดเองและกำหนดค่าโปรเจกต์ของคุณ