Giao diện
Workflow chính
Đây là chương quan trọng nhất. Nó dạy một quy trình đủ để đưa app từ ý tưởng tới bản chạy được ở nấc 3 (xem Hiện trạng): bạn duyệt đầu và cuối, agent làm phần giữa.
Quy trình đi theo plugin Superpowers trên Claude Code:
brainstorm → spec → plan → thực thi (subagent-driven hoặc executing-plans) + TDD → review → hoàn tất nhánh
Vì sao Superpowers: nó nhẹ, cài một lệnh, và mỗi bước là một skill có tên rõ ràng nên dễ thấy mình đang ở đâu. Các framework khác (OpenSpec, Spec Kit, BMAD, GSD...) có cùng bộ khung tư duy; so sánh ở chương 4.
Ví dụ xuyên suốt chương là lab "Sổ chia tiền nhóm": nhóm bạn đi chơi, ghi ai trả bao nhiêu, app tự tính ai trả ai. Làm lab từng bước ở chương 9.
Tổng quan
| Bước | Skill Superpowers | File sinh ra | Bạn duyệt gì |
|---|---|---|---|
| 1. Brainstorm | brainstorming | (hội thoại) | Trả lời câu hỏi, chọn hướng |
| 2. Spec | brainstorming (cuối bước) | docs/superpowers/specs/... | Phạm vi, quy tắc, tiêu chí chấp nhận |
| 3. Plan | writing-plans | docs/superpowers/plans/... | Task đủ nhỏ, có test, đúng thứ tự |
| 4. Thực thi + TDD | subagent-driven-development hoặc executing-plans, test-driven-development | Code, test, commit | Không duyệt từng dòng; nhìn test và commit |
| 5. Review | requesting-code-review | Ghi chú review | Diff và app chạy thật |
| 6. Hoàn tất nhánh | finishing-a-development-branch | Merge hoặc PR | Chọn cách tích hợp |
Hai chỗ in đậm (spec, plan) và chỗ cuối (diff, app) là nơi thời gian của bạn đáng giá nhất. Sai ở spec thì mọi bước sau làm đúng một thứ sai.
Chuẩn bị
- Plugin Superpowers đã bật. Starter bật sẵn qua
enabledPlugins; cài tay:/plugin install superpowers@claude-plugins-official. Xem Plugin. - Dự án có CLAUDE.md / AGENTS.md và hook. Starter có sẵn:
practice/starter/CLAUDE.mdcòn nhắc agent "Tính năng mới: đi theo quy trình brainstorming → spec → plan → thực thi". - Repo đã
git initvà commit lần đầu, để mỗi bước sau có commit riêng, dễ quay lại. - Dựng bộ khung app trước khi brainstorm (lab làm bằng skill
scaffold-app), để agent brainstorm trên cấu trúc thật. Xem mục "Bộ khung app" ở cuối chương.
Bước 1: Brainstorm
Mục đích: biến một yêu cầu mơ hồ thành hiểu biết chung giữa bạn và agent, trước khi có dòng code nào.
Đề bài lab cố tình viết như người không phải dev kể lại (practice/lab/de-bai.md):
markdown
Mình cần một web app nhỏ để:
1. **Tạo nhóm**: đặt tên nhóm, nhập tên các thành viên.
2. **Ghi khoản chi**: ai trả, bao nhiêu tiền, cho việc gì, chia cho những ai (mặc định cả nhóm, có thể bỏ bớt người).
3. **Xem "Ai trả ai"**: app tự tính, ra danh sách ngắn nhất có thể kiểu "Bình trả An 33.333đ".
## Mong muốn
- Tiền là **đồng Việt Nam**, không có số lẻ. Chia không hết thì phần dư dồn cho ai đó, nhưng **tổng phải khớp từng đồng**.Prompt mẫu:
text
Mình muốn làm app dưới đây. Dùng brainstorming: hỏi lại mình từng câu một
cho tới khi rõ, đề xuất 2–3 hướng làm, rồi viết spec. Chưa viết code.
<dán nội dung de-bai.md>Agent làm gì: hỏi từng câu (phần dư dồn cho ai? thêm thành viên giữa chừng thì khoản chi cũ tính sao?), đề xuất vài hướng kèm đánh đổi, chốt thiết kế với bạn từng phần.
Bạn làm gì: trả lời thật, kể cả "chưa biết". Câu nào agent hỏi mà bạn chưa nghĩ tới, đó chính là chỗ mà không có bước này thì agent sẽ tự đoán.
Bước 2: Spec
File sinh ra: cuối brainstorming, agent viết spec (bản thiết kế) vào docs/superpowers/specs/ và commit.
Spec của lab (practice/lab/checkpoint-1-spec.md) có những phần đáng học nhất là chống mục tiêu và quy tắc nghiệp vụ:
markdown
## Chống mục tiêu (làm thế này là hỏng, dù chạy được)
- Dùng số thực cho tiền → lệch 1 đồng khi chia 3.
- Logic chia tiền nằm trong component React → không test được.
- Tổng số dư khác 0.
## Quy tắc nghiệp vụ
- Tiền là **số nguyên đồng**, > 0.
- Chia đều `amount` cho `n` người: mỗi người `floor(amount / n)`, phần dư chia mỗi người 1 đồng cho **những người đầu danh sách người tham gia**.
- 100.000 / 3 → `[33.334, 33.333, 33.333]`.Và tiêu chí chấp nhận, thứ agent dùng để biết khi nào xong:
markdown
## Kiểm tra chấp nhận
- An, Bình, Chi; An trả 100.000đ cho cả 3 → "Bình trả An 33.333đ", "Chi trả An 33.333đ".
- `bun run check-types` và `bun test` pass.Bạn duyệt gì:
- Phạm vi: mục "Không làm" có đúng ý bạn không? Agent hay làm thừa nếu không bị cấm.
- Quy tắc: có ví dụ số cụ thể chưa?
100.000 / 3 → [33.334, 33.333, 33.333]rõ hơn mười câu mô tả. - Tiêu chí chấp nhận: có kiểm tra được bằng máy hoặc bằng một thao tác cụ thể không?
- Không cần duyệt chi tiết kỹ thuật từng bảng, từng route. Mục "Để người làm tự quyết" là chỗ cho agent.
Sửa spec bằng cách nói với agent ("thêm vào Không làm: sửa/xóa khoản chi"), đừng tự sửa rồi quên báo.
Bước 3: Plan
Prompt mẫu:
text
Spec ổn rồi. Dùng writing-plans để lập kế hoạch triển khai từ spec này.File sinh ra: plan (kế hoạch) ở docs/superpowers/plans/. Mỗi task có file sẽ đụng tới, interface, các bước có checkbox, lệnh kiểm tra và commit. Task 1 trong plan lab (practice/lab/checkpoint-2-plan.md):
markdown
### Task 1: Logic chia tiền
**Files:** tạo `packages/api/src/settle.ts`, `packages/api/src/settle.test.ts`
- [ ] **Bước 1: Viết test fail**
- `splitEqually(90_000, 3)` → `[30_000, 30_000, 30_000]`; `splitEqually(100_000, 3)` → `[33_334, 33_333, 33_333]`.
- A trả 100.000 cho A, B, C → `{ A: 66_666, B: -33_333, C: -33_333 }`.
- `participantIds` rỗng hoặc số tiền không nguyên dương → throw.
- [ ] **Bước 2:** `bun test` → FAIL (chưa có hàm).
- [ ] **Bước 3:** Viết `settle.ts` (tham lam: người nợ nhiều nhất trả người được nhận nhiều nhất; hòa thì theo thứ tự thành viên).
- [ ] **Bước 4:** `bun test` → PASS.
- [ ] **Bước 5:** Commit `feat: logic chia tiền có test`.Bạn duyệt gì:
- Kích thước task: mỗi task làm xong trong một lượt ngắn, có một commit. Task nào kiểu "làm toàn bộ giao diện" thì bảo agent chia nhỏ.
- Có test và lệnh kiểm tra: mỗi task phải có cách tự biết mình xong. Không có thì agent sẽ dừng ở "trông có vẻ xong".
- Thứ tự: logic nghiệp vụ có test trước, rồi dữ liệu, API, cuối cùng mới giao diện. Plan lab đi đúng thứ tự đó (Task 1 logic → 2 schema → 3 API → 4 giao diện).
- Khớp spec: quy tắc và ví dụ số trong spec có xuất hiện thành test không.
Bước 4: Thực thi + TDD
Hết plan, Superpowers hỏi bạn chọn cách thực thi:
| Cách | Hoạt động | Hợp khi |
|---|---|---|
subagent-driven-development | Agent chính điều phối; mỗi task giao cho một subagent riêng, có review giữa các task | Plan nhiều task, muốn ngữ cảnh agent chính gọn. Mặc định nên chọn |
executing-plans | Agent làm tuần tự ngay trong phiên hiện tại | Plan ngắn, hoặc bạn muốn theo dõi sát từng bước |
Prompt mẫu:
text
Thực thi plan này bằng subagent-driven-development. Theo TDD từng task.
Xong mỗi task thì commit.TDD (viết test trước) là thứ giữ cho agent trung thực: Task 1 ở trên bắt buộc thấy bun test FAIL trước khi viết settle.ts, rồi thấy PASS sau. Một test chưa từng đỏ có thể là test không kiểm tra gì.
Rào chắn chạy ngầm trong bước này, bạn không phải nhắc:
- Stop hook
check-on-stop.tschạy typecheck và test mỗi khi agent định dừng; đỏ thì agent phải làm tiếp. Xem Hook. - PreToolUse hook
block-secrets.tschặn commit.env. - Auto mode + allowlist hẹp cho agent chạy lệnh test, build mà không hỏi bạn. Xem Permission mode.
Bạn làm gì: không duyệt từng dòng. Nhìn log commit đi lên theo từng task, thỉnh thoảng xem test đỏ chuyển xanh. Chỉ nhảy vào khi agent hỏi, hoặc khi nó báo đã thử hai cách vẫn hỏng (quy tắc "Khi bí" trong AGENTS.md của starter).
Bước 5: Review
Hai lớp review, cả hai đều cần:
Agent tự review. Superpowers có skill requesting-code-review để một agent khác đọc diff đối chiếu với spec và plan.
text
Dùng requesting-code-review để review toàn bộ thay đổi so với spec.Bạn review. Đây là checkpoint cuối, đừng bỏ:
- Đọc diff, ít nhất là phần logic nghiệp vụ và phần test.
- Chạy app thật. Với lab: tạo nhóm "Đi Đà Lạt" với An, Bình, Chi; An trả 100.000đ cho cả 3; màn hình phải hiện Bình trả An 33.333đ và Chi trả An 33.333đ.
- Skill
verify-appcủa starter để agent tự làm việc này trước (mở trình duyệt, thao tác, chụp màn hình). Bạn xem ảnh và làm lại một lần bằng tay.
Bước 6: Hoàn tất nhánh
text
Dùng finishing-a-development-branch.Skill kiểm tra test vẫn pass rồi hỏi bạn muốn tích hợp ra sao: merge vào nhánh chính ở máy, đẩy lên và mở PR, hay giữ nhánh để làm sau. Bạn chọn, agent làm.
Bị lạc giữa chừng
Lab có sẵn điểm mốc để bắt kịp: practice/lab/checkpoint-1-spec.md (spec đã viết), practice/lab/checkpoint-2-plan.md (plan đã viết), practice/lab/dap-an/ (đáp án tham khảo). Chép file vào dự án rồi đi tiếp từ bước tương ứng. Chi tiết ở chương 9.
Bộ khung app: Better-T-Stack chỉ là một ví dụ
Nguyên tắc: cho agent một bộ khung tốt có sẵn, đừng để agent dựng từ số 0. Agent làm tốt hơn hẳn khi sửa code có cấu trúc rõ (thư mục, cách đặt tên, lệnh build, test đã có) so với khi phải tự quyết hàng chục lựa chọn hạ tầng ngay từ đầu.
- Lab ghim Better-T-Stack 3.49.0 (React + TanStack Router, Hono, oRPC, Drizzle + SQLite, bun). Lý do là thời gian: lệnh đã chạy thử, dựng xong trong khoảng nửa phút,
check-types,db:push,bun testđều chạy được, không cần hạ tầng ngoài. - Lựa chọn khác đều được: create-t3-app, create-next-app, template Vite, hoặc boilerplate nội bộ của công ty. Cái tốt nhất thường là cái nhóm bạn đã quen và đã có quy ước.
- Việc chọn stack có thể đưa vào bước brainstorm: để agent đề xuất vài phương án kèm đánh đổi, người chốt.
- Chốt rồi thì đóng gói lệnh dựng khung thành skill để lần sau lặp lại y hệt. Starter làm vậy với
scaffold-app: một lệnh dài, tham số cố định, kèm bước kiểm tra sau khi dựng.
markdown
2. Chạy đúng lệnh này (không đổi tham số, đã được kiểm chứng):
bunx create-better-t-stack@3.49.0 create . --frontend tanstack-router --backend hono ... --directory-conflict merge
3. `bun run db:push` rồi `bun run check-types`. Cả hai phải pass.
4. Kiểm tra `CLAUDE.md`, `AGENTS.md`, `.claude/` vẫn còn nguyên.(Trích practice/starter/.claude/skills/scaffold-app/SKILL.md, đã rút gọn lệnh.) --directory-conflict merge cho phép dựng khung vào thư mục đã có CLAUDE.md, AGENTS.md, .claude/ mà vẫn giữ nguyên chúng.
Giao diện: khi nào và làm sao
Phần này là quan điểm thực hành, không phải quy tắc của tool.
Claude Code làm tốt giao diện chức năng: form, danh sách, bảng, nối API, xử lý trạng thái loading và lỗi.
Claude Code yếu hơn ở:
- Gu thẩm mỹ mặc định: không chỉ dẫn thì ra giao diện "đúng mà nhạt".
- Bám pixel theo một thiết kế cho trước.
- Tự đánh giá kết quả nhìn: nó không thấy màn hình, trừ khi có vòng chụp màn hình qua MCP trình duyệt (Playwright hoặc Chrome DevTools).
- Tương tác phức tạp: kéo thả, animation, nhiều trạng thái chồng nhau.
Thứ tự khuyên dùng:
- Core nghiệp vụ và dữ liệu bằng TDD trước. Đây là phần agent làm tốt nhất và kiểm tra được bằng máy.
- Sớm có một lát cắt UI xấu mà chạy được xuyên suốt: từ form tới DB tới màn hình kết quả. Mục đích là kiểm tra mình hiểu đúng yêu cầu, không phải để đẹp.
- Một lượt làm đẹp riêng ở cuối, có đầu vào cụ thể: ảnh tham chiếu hoặc Figma, một bộ component (ví dụ shadcn), và vòng chụp màn hình để agent tự so và sửa.
Lab đi đúng thứ tự này. Đề bài ghi thẳng ở mục "Chưa cần": "Đẹp. Chạy đúng là được." Plan để giao diện ở Task 4, sau logic, schema và API.
Ngoại lệ: khi giao diện chính là sản phẩm (landing page, app nặng trải nghiệm) hoặc khách chưa rõ mình muốn gì, làm ngược lại: prototype bấm thử được trước. Có thể dùng phần phác thảo trực quan trong lúc brainstorm, hoặc một spike (bản làm nhanh rồi vứt). Chốt được giao diện rồi mới làm core.
Nguồn
- Superpowers: https://github.com/obra/superpowers
- Cài Superpowers và marketplace chính thức: https://code.claude.com/docs/en/discover-plugins
- Subagents: https://code.claude.com/docs/en/sub-agents
- Hooks: https://code.claude.com/docs/en/hooks