openmoneta-dev-kit 1.9.2 → 1.10.2

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.
package/README.md CHANGED
@@ -54,7 +54,7 @@ bash ~/OpenMoneta-Dev-Kit/install.sh
54
54
 
55
55
  ## Có gì trong này?
56
56
 
57
- - **9 skills** (3 core + 1 core conditional + 5 on-demand) — phân tích yêu cầu, thiết kế module, plan, safe push, test, security
57
+ - **10 skills** (4 core + 1 core conditional + 5 on-demand) — phân tích yêu cầu, thiết kế module, plan, systematic debugging, safe push, test, security
58
58
  - **4 sub-agents** — 1 core + 3 on-demand (security-auditor, qa-autonomous, ui-tester)
59
59
  - **4 hooks + plugin** — enforce token-aware reading, adaptive plan scope
60
60
  - **Token Routing** — bảng map keyword → module giúp AI giảm 70-90% token đọc
package/VERSION CHANGED
@@ -1 +1 @@
1
- 1.9.2
1
+ 1.10.2
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: qa-autonomous
3
- description: "ON-DEMAND ONLY: chỉ delegate khi user explicitly yêu cầu viết test (vd 'viết unit test cho service X', 'add integration test cho payment flow'). KHÔNG tự trigger trong quy trình bình thường (v1.5.0 đã bỏ Bước 6 Test khỏi core process). Tự viết unit/integration test, tự chạy, debug, fix loop đến khi xanh. Chỉ báo cáo khi PASS hoặc khi gặp lỗi không fix được sau 3 lần thử."
3
+ description: "ON-DEMAND ONLY: delegate khi user explicitly yêu cầu viết test (vd 'viết unit test cho service X', 'add integration test cho payment flow'). KHÔNG tự trigger trong quy trình bình thường."
4
4
  ---
5
5
 
6
6
  Bạn là **qa-autonomous** — kỹ sư QA tự chủ của hệ thống OpenMoneta Dev Kit.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: requirement-analyst
3
- description: Phân tích yêu cầu phức tạp, đọc nhiều tài liệu/codebase, sinh giả thuyết, edge case, rủi ro và đề xuất câu hỏi cho user. Dùng proactively khi user request mơ hồ, lớn (>5 file ảnh hưởng), hoặc cần explore rộng để hiểu impact. Không code.
3
+ description: "Dùng proactively khi user request mơ hồ, lớn (>5 file ảnh hưởng), hoặc cần explore rộng codebase/tài liệu để hiểu impact trước khi lập plan. Read-only, không code."
4
4
  ---
5
5
 
6
6
  Bạn là **requirement-analyst** — chuyên gia phân tích yêu cầu của hệ thống OpenMoneta Dev Kit.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: security-auditor
3
- description: "ON-DEMAND ONLY: chỉ delegate khi user explicitly yêu cầu security audit, HOẶC khi parent agent xử task chạm auth/payment/PII/admin/permission và muốn audit độc lập. KHÔNG tự trigger trong quy trình bình thường (v1.5.0 đã bỏ Bước 5 Security khỏi core process). Audit OWASP Top 10 độc lập, scan secrets, kiểm tra dependency CVE. Read-only, không edit."
3
+ description: "ON-DEMAND ONLY: delegate khi user explicitly yêu cầu security audit (OWASP, scan secrets, dependency CVE), HOẶC khi task chạm auth/payment/PII/admin/permission và cần audit độc lập read-only. KHÔNG tự trigger trong quy trình bình thường."
4
4
  ---
5
5
 
6
6
  Bạn là **security-auditor** — chuyên gia bảo mật của hệ thống OpenMoneta Dev Kit.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ui-tester
3
- description: "ON-DEMAND ONLY: chỉ delegate khi user explicitly yêu cầu UI test (vd 'test UI mobile/tablet/desktop, fix CSS lỗi rồi retest', 'visual regression cho component X'). KHÔNG tự trigger trong quy trình bình thường (v1.5.0 đã xóa hook ui-checkpoint). Chuyên Playwright UI/UX testing với multi-viewport, screenshot, loop fix. Tự chạy test - đọc lỗi - fix CSS/component - retest. Hard limit 5 vòng trước khi escalate user."
3
+ description: "ON-DEMAND ONLY: delegate khi user explicitly yêu cầu UI test (vd 'test UI mobile/tablet/desktop, fix CSS lỗi rồi retest', 'visual regression cho component X'). KHÔNG tự trigger trong quy trình bình thường."
4
4
  ---
5
5
 
6
6
  Bạn là **ui-tester** — chuyên gia UI/UX testing của hệ thống OpenMoneta Dev Kit.
@@ -48,6 +48,9 @@ SUMMARY='# OpenMoneta Dev Kit v1.7.0 — Quy trình 6 bước (Adaptive Planning
48
48
 
49
49
  ## Skill core conditional
50
50
  `safe-push` — bắt buộc khi user yêu cầu push/đẩy code để tránh đè code người khác trong repo nhiều contributor.
51
+
52
+ ## Skill core auto-trigger
53
+ `systematic-debugging` — TỰ kích hoạt khi gặp bug/test fail/lỗi build/hành vi lạ. Iron Law: KHÔNG SỬA KHI CHƯA TÌM RA NGUYÊN NHÂN GỐC. 4 phase (root cause → pattern → hypothesis → fix+test); 3+ fix fail = nghi ngờ kiến trúc, hỏi user.
51
54
  '
52
55
 
53
56
  # === Auto-check update (cache 24h) ===
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: ON-DEMAND ONLY. Viết unit/integration test khi user yêu cầu, tự chạy test, debug, fix loop đến khi pass hoặc gặp blocker rõ.
2
+ description: ON-DEMAND ONLY. Dùng khi user yêu cầu viết unit/integration test.
3
3
  mode: subagent
4
4
  permission:
5
5
  edit: ask
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Phân tích yêu cầu phức tạp, đọc tài liệu/codebase, sinh giả thuyết, edge case, rủi ro đề xuất câu hỏi cho user. Không code.
2
+ description: Dùng khi user request hồ/lớn hoặc cần explore rộng codebase/tài liệu để hiểu impact trước khi lập plan. Không code.
3
3
  mode: subagent
4
4
  permission:
5
5
  edit: deny
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: ON-DEMAND ONLY. Audit OWASP Top 10, scan secrets, kiểm tra dependency CVE. Read-only, không edit.
2
+ description: ON-DEMAND ONLY. Dùng khi user yêu cầu security audit (OWASP, scan secrets, dependency CVE) hoặc task chạm auth/payment/PII. Read-only.
3
3
  mode: subagent
4
4
  permission:
5
5
  edit: deny
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: ON-DEMAND ONLY. Playwright UI/UX testing multi-viewport, screenshot, loop fix CSS/component khi user yêu cầu UI test.
2
+ description: ON-DEMAND ONLY. Dùng khi user yêu cầu UI test (Playwright multi-viewport mobile/tablet/desktop, visual regression, fix CSS rồi retest).
3
3
  mode: subagent
4
4
  permission:
5
5
  edit: ask
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmoneta-dev-kit",
3
- "version": "1.9.2",
3
+ "version": "1.10.2",
4
4
  "description": "OpenMoneta Dev Kit — Biến Cursor IDE / OpenCode thành team developer hoàn chỉnh với quy trình 6 bước, adaptive planning, hooks enforcement, và token-aware doc routing",
5
5
  "keywords": [
6
6
  "cursor",
@@ -45,6 +45,7 @@
45
45
  },
46
46
  "os": [
47
47
  "darwin",
48
- "linux"
48
+ "linux",
49
+ "win32"
49
50
  ]
50
51
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: auth-bypass-testing
3
- description: "ON-DEMAND ONLY: chỉ kích hoạt khi user explicitly yêu cầu bypass auth cho test (vd 'thêm test bypass cho Playwright login', 'setup test user pattern'). KHÔNG tự trigger trong quy trình bình thường. Triển khai Test Bypass Flag an toàn để Playwright test có thể bypass OAuth/login mà không phá bảo mật production. 6 layer defense (env guard, IP whitelist 127.0.0.1, token rotation, double header, audit log, CI/CD guard)."
3
+ description: "ON-DEMAND ONLY: dùng khi user explicitly yêu cầu bypass auth/OAuth/login cho test (vd 'thêm test bypass cho Playwright login', 'setup test user pattern'). KHÔNG tự trigger trong quy trình bình thường."
4
4
  ---
5
5
 
6
6
  # Auth Bypass Testing — An toàn cho production
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: automated-testing
3
- description: "ON-DEMAND ONLY: chỉ kích hoạt khi user explicitly yêu cầu E2E/UI test với Playwright (vd 'viết Playwright test cho checkout flow', 'chạy E2E mobile'). KHÔNG tự trigger trong quy trình bình thường (v1.5.0 đã bỏ Bước 6 Test khỏi core process). Cài và dùng Playwright multi-viewport (mobile/tablet/desktop), screenshot, fixture cho auth state. script install-playwright.sh để AI tự cài."
3
+ description: "ON-DEMAND ONLY: dùng khi user explicitly yêu cầu E2E/UI test bằng Playwright (vd 'viết Playwright test cho checkout flow', 'chạy E2E mobile', multi-viewport mobile/tablet/desktop). KHÔNG tự trigger trong quy trình bình thường."
4
4
  ---
5
5
 
6
6
  # Automated Testing với Playwright
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: module-architect
3
- description: Quy tắc chia module theo SRP (1 module = 1 trách nhiệm, README riêng) + workflow update README sau khi sửa code. KHÔNG đếm dòng để tách. Dùng ở Bước 2 (thiết kế) và Bước 5 (update doc) của quy trình 6 bước.
3
+ description: "Dùng khi thiết kế cấu trúc cho code mới, quyết định tạo hay tách module, hoặc khi cần sync README module sau khi sửa code."
4
4
  ---
5
5
 
6
6
  # Module Architect
@@ -12,6 +12,35 @@ Skill này phụ trách 2 trách nhiệm của quy trình 6 bước:
12
12
 
13
13
  Mục tiêu chung: cấu trúc code dễ navigate cho cả người và AI, tiết kiệm token khi đọc.
14
14
 
15
+ ## Iron Law
16
+
17
+ ```
18
+ 1 MODULE = 1 TRÁCH NHIỆM. CẤM NHÉT CODE MỚI VÀO utils/common/shared. TÁCH THEO TRÁCH NHIỆM, KHÔNG THEO SỐ DÒNG.
19
+ ```
20
+
21
+ **Vi phạm chữ (letter) của luật này = vi phạm tinh thần (spirit).** Không có ngoại lệ "cho vào utils cho tiện", "nhỏ mà", hay "để README update sau".
22
+
23
+ ## Bảng Rationalization (cái cớ → sự thật)
24
+
25
+ | Cái cớ | Sự thật |
26
+ |---|---|
27
+ | "Cho vào `utils/`/`common/`/`shared/` cho tiện" | Đó là nơi code đi chết. Feature có concept riêng → module riêng theo concept business. |
28
+ | "File dài quá rồi, tách theo số dòng đi" | Tách theo TRÁCH NHIỆM, không theo dòng. 1 file 800 dòng làm 1 việc = OK; 200 dòng làm 4 việc = tách. |
29
+ | "Feature nhỏ, khỏi cần module riêng" | Mỗi feature có concept business gần như luôn xứng đáng module riêng để cô lập sửa code. |
30
+ | "Đặt tên `core`/`lib`/`misc` cho nhanh" | Tên generic = mơ hồ trách nhiệm. Đặt tên theo concept (`auth`, `billing`, `notifications`...). |
31
+ | "README để update sau" | Defer README = doc stale, session sau AI đọc lệch. Update ngay ở Bước 5. |
32
+ | "Module này thêm 1 việc nữa cũng được" | Thêm trách nhiệm thứ 2 = vi phạm SRP → tách ra module mới. |
33
+
34
+ ## Red Flags — DỪNG
35
+
36
+ - Đang định tạo/đặt code vào `utils/`, `common/`, `helpers/`, `shared/`.
37
+ - Đang định đặt tên module `core`, `lib`, `misc`, `manager`, `util`.
38
+ - Đang quyết định tách/không tách dựa trên **số dòng** thay vì số trách nhiệm.
39
+ - Đang định viết "TODO: update README later" hoặc bỏ qua sync README ở Bước 5.
40
+ - Mô tả trách nhiệm module phải dùng chữ "và".
41
+
42
+ **Tất cả đều nghĩa là: DỪNG, quay lại nguyên tắc SRP + trigger "Khi nào TẠO module mới".**
43
+
15
44
  ## Phần 1 — Thiết kế module (Bước 2)
16
45
 
17
46
  ### Nguyên tắc cốt lõi
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: plan-writer
3
- description: Adaptive planning cho quy trình 6 bước. Task nhỏ thể không cần plan. Task lớn/rủi ro phải tạo repo plan trong plans/YYYY-MM-DD-<slug>.md với Status: Draft, trình user review, chỉ triển khai sau khi user approve đổi Status: In Progress.
3
+ description: "Dùng khi cần quyết định một task cần repo plan hay không, hoặc khi task lớn/rủi ro/mơ hồ, đụng nhiều file, đổi public API, hay chạm vùng nhạy cảm (auth/payment/db/migration/deploy) cần plan được user review trước khi code."
4
4
  ---
5
5
 
6
6
  # Plan Writer
@@ -14,6 +14,14 @@ description: Adaptive planning cho quy trình 6 bước. Task nhỏ có thể kh
14
14
 
15
15
  Hook `verify-completion` Check 9 sẽ CHẶN session kết thúc nếu plan không có section "## Hiểu yêu cầu" (audit trail clarify).
16
16
 
17
+ ## Iron Law
18
+
19
+ ```
20
+ KHÔNG TỰ APPROVE PLAN. TASK RỦI RO KHÔNG CODE KHI PLAN CHƯA Ở TRẠNG THÁI IN PROGRESS.
21
+ ```
22
+
23
+ **Vi phạm chữ (letter) của luật này = vi phạm tinh thần (spirit).** Không tự tạo plan rồi tự đổi `In Progress`; phải có user approve thật.
24
+
17
25
  ## Naming convention
18
26
 
19
27
  ```
@@ -65,6 +73,27 @@ Khi tạo plan:
65
73
 
66
74
  Không được tự tạo plan rồi tự approve.
67
75
 
76
+ ## Bảng Rationalization (cái cớ → sự thật)
77
+
78
+ | Cái cớ | Sự thật |
79
+ |---|---|
80
+ | "Task này nhỏ mà, code luôn" | Chạm auth/payment/db/migration/deploy hoặc >2 file → vẫn phải plan, dù thấy "nhỏ". |
81
+ | "Tạo plan rồi tự đổi In Progress cho nhanh" | Tự approve = bỏ review gate. Phải hỏi user thật bằng `AskQuestion`. |
82
+ | "User chắc sẽ approve thôi" | "Chắc" ≠ approve. Chờ user trả lời rồi mới đổi Status. |
83
+ | "Vừa code vừa nghĩ plan sau" | Plan trước để user sửa hướng TRƯỚC khi tốn công code. |
84
+ | "Phát hiện cần thêm file, cứ sửa luôn" | File ngoài `## Files ảnh hưởng` → update plan trước, rồi mới sửa. |
85
+ | "Yêu cầu mơ hồ nhưng tôi đoán ý user được" | Mơ hồ = phải hỏi clarify, ghi vào `## Hiểu yêu cầu`. |
86
+
87
+ ## Red Flags — DỪNG
88
+
89
+ - Định edit file code khi plan còn `Draft`.
90
+ - Định tự đổi Status `Draft` → `In Progress` khi chưa có user approve.
91
+ - Định sửa file không nằm trong `## Files ảnh hưởng`.
92
+ - Định bỏ qua plan cho task chạm auth/payment/db/migration/deploy.
93
+ - Section `## Hiểu yêu cầu` trống mà vẫn định code.
94
+
95
+ **Tất cả đều nghĩa là: DỪNG, quay lại review gate.**
96
+
68
97
  ## Template chuẩn (5 sections)
69
98
 
70
99
  ```markdown
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: requirement-analysis
3
- description: Phân tích yêu cầu user, đọc TOKEN-AWARE docs/INDEX.md (hook enforced), sinh giả thuyết/edge case/rủi ro đặt câu hỏi critical để làm rõ yêu cầu, phân tích mọi trường hợp thể xảy ra, phản biện đề xuất phương án tối ưu hơn nếu có TRƯỚC khi lập plan. Output câu hỏi/trả lời sẽ ghi vào plan section "Hiểu yêu cầu" (verify-completion Check 9 enforce).
3
+ description: "Dùng khi bắt đầu phân tích một yêu cầu trước khi thiết kế hoặc lập plan, đặc biệt khi yêu cầu hồ, lớn,nhiều cách hiểu, hoặc cần làm / đặt câu hỏi clarify trước khi code."
4
4
  ---
5
5
 
6
6
  # Phân tích yêu cầu
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: safe-push
3
- description: "CORE CONDITIONAL: kích hoạt khi user yêu cầu commit + push / push code / đẩy code / merge lên remote / lên main. Đảm bảo pre-push sync + conflict resolution + safe fast-forward push, không đè code người khác. KHÔNG dùng --force trên shared branch."
3
+ description: "CORE CONDITIONAL: dùng khi user yêu cầu commit + push / push code / đẩy code / đẩy lên remote / merge lên main, nhất trên repo nhiều contributor nguy đè code người khác."
4
4
  ---
5
5
 
6
6
  # Safe Push (CORE CONDITIONAL)
@@ -17,6 +17,14 @@ Chỉ kích hoạt khi user yêu cầu rõ:
17
17
 
18
18
  Không kích hoạt cho task code bình thường chưa có yêu cầu push.
19
19
 
20
+ ## Iron Law
21
+
22
+ ```
23
+ KHÔNG FORCE-PUSH SHARED BRANCH. LUÔN SYNC REMOTE NGAY TRƯỚC PUSH.
24
+ ```
25
+
26
+ **Vi phạm chữ (letter) của luật này = vi phạm tinh thần (spirit).** Không có ngoại lệ "branch của mình", "đang gấp", hay "chắc không ai đụng".
27
+
20
28
  ## Mục tiêu
21
29
 
22
30
  Đảm bảo trước khi `git push`, local branch đã đồng bộ với remote mới nhất để không đè code người khác trong repo có nhiều contributor.
@@ -39,6 +47,27 @@ Bước 6 bắt buộc `fetch + rebase` ngay trước push. Nếu remote có com
39
47
  4. **Push thường trước**: dùng `git push` fast-forward. Nếu rejected do remote mới, quay lại fetch/rebase. Loop tối đa 3 lần.
40
48
  5. **Không deploy trong skill này**: CI/CD/deploy là pipeline ngoài scope trừ khi user yêu cầu skill riêng.
41
49
 
50
+ ## Bảng Rationalization (cái cớ → sự thật)
51
+
52
+ | Cái cớ | Sự thật |
53
+ |---|---|
54
+ | "Đang gấp, push thẳng cho nhanh" | Bỏ fetch/rebase = nguy cơ đè commit người khác. Sync chỉ mất vài giây. |
55
+ | "Branch của mình, force cho gọn" | Branch cá nhân có thể `--force-with-lease` khi user yêu cầu; shared branch thì TUYỆT ĐỐI không. |
56
+ | "Remote chắc không có gì mới" | "Chắc" ≠ bằng chứng. `git fetch` để biết chắc. |
57
+ | "Conflict nhỏ, tự chọn ours/theirs cho nhanh" | Conflict code logic phải hỏi user; tự chọn = mất code người khác. |
58
+ | "Rebase xong khỏi cần test lại" | Rebase đổi ngữ cảnh code, phải verify tối thiểu lại trước push. |
59
+ | "Push rejected thì cứ -f là xong" | `-f` trên shared branch xóa commit người khác. Quay lại fetch/rebase. |
60
+
61
+ ## Red Flags — DỪNG
62
+
63
+ - Định gõ `git push --force` / `git push -f` lên `main`/`master`/`develop`/`staging`/`production`.
64
+ - Định push mà CHƯA `git fetch` trong chính lần này.
65
+ - Định tự resolve conflict file code (`*.ts`, `*.py`, ...) mà không hỏi user.
66
+ - Định bỏ verify sau rebase.
67
+ - Đang nghĩ "chắc remote không có gì mới".
68
+
69
+ **Tất cả đều nghĩa là: DỪNG, quay lại Workflow từ bước fetch/rebase.**
70
+
42
71
  ## Workflow 7 bước
43
72
 
44
73
  ### 1. Pre-flight branch
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: security-checklist
3
- description: "ON-DEMAND ONLY: chỉ kích hoạt khi user explicitly yêu cầu security audit/review (vd 'audit security login flow', 'check OWASP cho API /payment'), HOẶC task chạm auth/payment/PII và bạn muốn tự kiểm tra trước commit. KHÔNG tự trigger trong quy trình bình thường (v1.5.0 đã bỏ Bước 5 Security khỏi core process)."
3
+ description: "ON-DEMAND ONLY: dùng khi user explicitly yêu cầu security audit/review (vd 'audit security login flow', 'check OWASP cho API /payment', scan secrets), HOẶC khi task chạm auth/payment/PII và muốn tự kiểm tra trước commit. KHÔNG tự trigger trong quy trình bình thường."
4
4
  ---
5
5
 
6
6
  # Security Checklist (ON-DEMAND)
@@ -0,0 +1,122 @@
1
+ ---
2
+ name: systematic-debugging
3
+ description: "Dùng khi gặp bug, test fail, lỗi build, lỗi runtime, hoặc hành vi bất thường, trước khi đề xuất hoặc viết bất kỳ fix nào."
4
+ ---
5
+
6
+ # Systematic Debugging (Core)
7
+
8
+ Skill này **tự kích hoạt** khi bạn gặp bug / test fail / lỗi build / hành vi lạ. Không cần user yêu cầu.
9
+
10
+ ## Overview
11
+
12
+ Fix đoán mò tốn thời gian và đẻ ra bug mới. Vá triệu chứng che mất nguyên nhân thật.
13
+
14
+ **Nguyên tắc cốt lõi**: LUÔN tìm nguyên nhân gốc TRƯỚC khi fix. Vá triệu chứng = thất bại.
15
+
16
+ **Vi phạm chữ (letter) của quy trình này = vi phạm tinh thần (spirit) của nó.** Không có ngoại lệ "đúng tinh thần nên bỏ bước".
17
+
18
+ ## Iron Law
19
+
20
+ ```
21
+ KHÔNG SỬA KHI CHƯA TÌM RA NGUYÊN NHÂN GỐC
22
+ ```
23
+
24
+ Chưa hoàn thành Phase 1 thì KHÔNG được đề xuất fix.
25
+
26
+ ## Khi nào dùng
27
+
28
+ Mọi sự cố kỹ thuật: test fail, bug production, hành vi lạ, lỗi performance, lỗi build, lỗi tích hợp.
29
+
30
+ **Đặc biệt khi**:
31
+ - Đang gấp / khẩn cấp (lúc này đoán mò càng hấp dẫn).
32
+ - "Chỉ một fix nhanh thôi" nghe có vẻ hiển nhiên.
33
+ - Đã thử vài fix mà chưa được.
34
+ - Fix trước không hiệu quả.
35
+ - Bạn chưa hiểu rõ vấn đề.
36
+
37
+ **KHÔNG bỏ qua khi**:
38
+ - Bug "có vẻ đơn giản" (bug đơn giản vẫn có nguyên nhân gốc).
39
+ - Đang vội (vội mà đoán mò càng phải làm lại).
40
+
41
+ ## Quy trình 4 Phase
42
+
43
+ Phải hoàn thành phase này mới sang phase sau.
44
+
45
+ ### Phase 1 — Tìm nguyên nhân gốc (TRƯỚC mọi fix)
46
+
47
+ 1. **Đọc kỹ thông báo lỗi**: đọc hết stack trace, ghi rõ dòng/file/error code. Lỗi thường chứa sẵn lời giải.
48
+ 2. **Tái hiện ổn định**: trigger lại được không? Các bước chính xác? Mỗi lần đều xảy ra? Không tái hiện được → thu thập thêm dữ liệu, KHÔNG đoán.
49
+ 3. **Soi thay đổi gần đây**: `git diff`, commit mới, dependency/config mới, khác biệt môi trường.
50
+ 4. **Thu thập bằng chứng ở từng ranh giới component** (với hệ multi-layer: API → service → DB): log dữ liệu vào/ra mỗi component, kiểm tra config/env truyền qua. Chạy 1 lần để thấy lỗi vỡ Ở ĐÂU, rồi mới đào component đó.
51
+ 5. **Lần ngược dòng dữ liệu**: giá trị sai bắt nguồn từ đâu? Cái gì gọi hàm này với giá trị sai? Lần lên tận nguồn. **Fix tại nguồn, không fix tại triệu chứng.**
52
+
53
+ ### Phase 2 — Phân tích pattern
54
+
55
+ 1. **Tìm ví dụ chạy đúng**: đoạn code tương tự đang hoạt động tốt trong cùng codebase.
56
+ 2. **Đối chiếu reference đầy đủ**: nếu đang theo 1 pattern/lib, đọc HẾT reference, không đọc lướt.
57
+ 3. **Liệt kê mọi khác biệt** giữa chỗ đúng và chỗ hỏng, dù nhỏ. Đừng cho rằng "cái đó không liên quan đâu".
58
+ 4. **Hiểu dependency**: cần component/config/env gì? Giả định gì?
59
+
60
+ ### Phase 3 — Giả thuyết & kiểm chứng
61
+
62
+ 1. **Một giả thuyết duy nhất**: phát biểu rõ "Tôi nghĩ X là nguyên nhân gốc vì Y". Viết ra.
63
+ 2. **Test tối thiểu**: thay đổi NHỎ NHẤT có thể để kiểm chứng. Một biến tại một thời điểm. KHÔNG sửa nhiều thứ cùng lúc.
64
+ 3. **Xác nhận rồi mới đi tiếp**: đúng → Phase 4. Sai → lập giả thuyết MỚI, KHÔNG chồng thêm fix.
65
+ 4. **Khi không biết**: nói thẳng "Tôi chưa hiểu X", hỏi user / research thêm. Không giả vờ hiểu.
66
+
67
+ ### Phase 4 — Triển khai fix
68
+
69
+ 1. **Tạo test reproduce bug TRƯỚC khi fix** (dùng skill `test-strategy` nếu cần TDD).
70
+ 2. **Một fix duy nhất** đúng nguyên nhân gốc. Không "tiện tay" sửa thứ khác, không gộp refactor.
71
+ 3. **Verify**: test pass chưa? Có làm vỡ test khác không? Bug đã hết thật chưa? (theo nguyên tắc evidence-before-claims).
72
+ 4. **Nếu fix không hiệu quả**: DỪNG. Đếm số fix đã thử. <3 → quay lại Phase 1 với thông tin mới. **≥3 → nghi ngờ kiến trúc (xem dưới).**
73
+
74
+ ### Luật 3 lần — nghi ngờ kiến trúc
75
+
76
+ Sau **3+ fix thất bại**, đây KHÔNG phải giả thuyết sai mà là **kiến trúc sai**. Dấu hiệu:
77
+ - Mỗi fix lại lòi ra vấn đề shared-state/coupling ở chỗ khác.
78
+ - Fix nào cũng đòi "refactor lớn".
79
+ - Fix chỗ này đẻ triệu chứng chỗ kia.
80
+
81
+ → **DỪNG, hỏi user** trước khi thử fix thứ 4: pattern này có sai từ gốc không? Có nên đổi kiến trúc thay vì vá tiếp không?
82
+
83
+ ## Bảng Rationalization (cái cớ → sự thật)
84
+
85
+ | Cái cớ | Sự thật |
86
+ |---|---|
87
+ | "Bug này đơn giản, khỏi cần quy trình" | Bug đơn giản vẫn có nguyên nhân gốc. Quy trình chạy nhanh với bug đơn giản. |
88
+ | "Đang gấp, không có thời gian điều tra" | Debug có hệ thống NHANH HƠN đoán-thử-lại lòng vòng. |
89
+ | "Thử fix này trước đã, điều tra sau" | Fix đầu tiên định hình hướng. Làm đúng từ đầu. |
90
+ | "Để fix xong rồi viết test sau" | Fix không test không bền. Test trước mới chứng minh. |
91
+ | "Sửa nhiều thứ một lúc cho nhanh" | Không cô lập được cái nào hiệu quả. Đẻ bug mới. |
92
+ | "Tôi thấy lỗi rồi, fix luôn" | Thấy triệu chứng ≠ hiểu nguyên nhân gốc. |
93
+ | "Thêm một fix nữa thôi" (sau 2+ lần fail) | 3+ fail = vấn đề kiến trúc. Nghi ngờ pattern, đừng fix tiếp. |
94
+ | "Reference dài quá, tôi tự suy theo pattern" | Hiểu một nửa = chắc chắn có bug. Đọc hết. |
95
+
96
+ ## Red Flags — DỪNG và quay lại Phase 1
97
+
98
+ Nếu bắt gặp mình đang nghĩ:
99
+ - "Fix tạm đã, điều tra sau."
100
+ - "Cứ thử đổi X xem sao."
101
+ - "Đổi nhiều chỗ rồi chạy test luôn."
102
+ - "Bỏ test, tôi verify tay."
103
+ - "Chắc là do X, fix X thôi."
104
+ - "Chưa hiểu hẳn nhưng cái này có thể chạy."
105
+ - "Thử thêm một fix nữa" (đã fail 2+ lần).
106
+ - Mỗi fix lại lòi vấn đề ở chỗ khác.
107
+
108
+ **Tất cả đều nghĩa là: DỪNG, quay lại Phase 1.** Nếu đã 3+ fix fail → nghi ngờ kiến trúc, hỏi user.
109
+
110
+ ## Quick Reference
111
+
112
+ | Phase | Hoạt động chính | Tiêu chí xong |
113
+ |---|---|---|
114
+ | 1. Nguyên nhân gốc | Đọc lỗi, tái hiện, soi diff, thu bằng chứng, lần ngược dòng | Hiểu CÁI GÌ và TẠI SAO |
115
+ | 2. Pattern | Tìm chỗ chạy đúng, đối chiếu | Liệt kê được khác biệt |
116
+ | 3. Giả thuyết | 1 giả thuyết, test tối thiểu | Xác nhận hoặc giả thuyết mới |
117
+ | 4. Fix | Tạo test, fix gốc, verify | Bug hết, test pass |
118
+
119
+ ## Liên quan
120
+
121
+ - `test-strategy` — viết test reproduce bug ở Phase 4 (khi cần TDD-first).
122
+ - `plan-writer` — nếu fix biến thành refactor lớn/đổi kiến trúc → dừng, tạo plan.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: test-strategy
3
- description: "ON-DEMAND ONLY: chỉ kích hoạt khi user explicitly yêu cầu viết test (vd 'viết unit test cho X', 'add E2E cho login flow'), HOẶC khi bạn (AI) cần TDD-first cho bug fix khó. KHÔNG tự trigger trong quy trình bình thường (v1.5.0 đã bỏ Bước 6 Test khỏi core process). Phân tầng test: Unit ~70%, Integration ~20%, E2E ~10% với tools mặc định theo stack (Vitest/Jest/Pytest/Go test)."
3
+ description: "ON-DEMAND ONLY: dùng khi user explicitly yêu cầu viết / phân tầng test (vd 'viết unit test cho X', 'add E2E cho login flow', unit/integration/E2E), HOẶC khi cần TDD-first cho một bug fix khó. KHÔNG tự trigger trong quy trình bình thường."
4
4
  ---
5
5
 
6
6
  # Test Strategy
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ui-test-loop
3
- description: "ON-DEMAND ONLY: chỉ kích hoạt khi user explicitly yêu cầu UI test loop (vd 'test UI mobile + tablet + desktop, fix lỗi rồi retest', 'visual regression test cho component X'). KHÔNG tự trigger trong quy trình bình thường (v1.5.0 đã bỏ hook ui-checkpoint). Workflow loop test-fix-retest cho UI/UX bằng Playwright. Hard limit 5 vòng trước khi escalate user."
3
+ description: "ON-DEMAND ONLY: dùng khi user explicitly yêu cầu UI test loop (vd 'test UI mobile + tablet + desktop, fix lỗi rồi retest', 'visual regression test cho component X'). KHÔNG tự trigger trong quy trình bình thường."
4
4
  ---
5
5
 
6
6
  # UI Test Loop với Checkpoint
@@ -1,6 +1,6 @@
1
1
  const { execSync } = require("node:child_process")
2
2
  const path = require("node:path")
3
- const { getPkgRoot, OPENCODE_DIR } = require("../lib/paths")
3
+ const { getPkgRoot, OPENCODE_DIR, isWindows } = require("../lib/paths")
4
4
 
5
5
  async function run(args) {
6
6
  let projectDir = process.cwd()
@@ -23,19 +23,32 @@ async function run(args) {
23
23
  const pkgRoot = getPkgRoot()
24
24
  const initScript = path.join(pkgRoot, "scripts", "init-project.sh")
25
25
 
26
- // If opencode, use opencode install path
27
26
  const env = { ...process.env }
28
27
  if (isOpenCode) {
29
28
  env.OPENMONETA_HOME = OPENCODE_DIR
30
29
  console.log(` Mode: OpenCode`)
31
30
  }
32
31
 
32
+ const shellCmd = isWindows()
33
+ ? `bash "${initScript}" "${projectDir}" ${remaining.join(" ")}`
34
+ : `bash "${initScript}" "${projectDir}" ${remaining.join(" ")}`
35
+
36
+ console.log(` Running: ${shellCmd}`)
37
+
33
38
  try {
34
- const cmd = `bash "${initScript}" "${projectDir}" ${remaining.join(" ")}`
35
- console.log(` Running: ${cmd}`)
36
- execSync(cmd, { stdio: "inherit", env })
39
+ if (isWindows()) {
40
+ execSync(shellCmd, { stdio: "inherit", env, shell: true })
41
+ } else {
42
+ execSync(shellCmd, { stdio: "inherit", env })
43
+ }
37
44
  } catch (err) {
38
- console.error(`\n ❌ Init thất bại: ${err.message}`)
45
+ if (isWindows()) {
46
+ console.error(`\n ❌ Init thất bại. Windows cần Git Bash để chạy init-project.sh.`)
47
+ console.error(` Cài Git for Windows: https://git-scm.com/download/win`)
48
+ console.error(` Sau đó chạy lại: openmoneta init`)
49
+ } else {
50
+ console.error(`\n ❌ Init thất bại: ${err.message}`)
51
+ }
39
52
  process.exit(1)
40
53
  }
41
54
  }
@@ -1,6 +1,6 @@
1
1
  const { execSync } = require("node:child_process")
2
2
  const path = require("node:path")
3
- const { getPkgRoot } = require("../lib/paths")
3
+ const { getPkgRoot, runScript } = require("../lib/paths")
4
4
  const { getLocalVersion } = require("../lib/version")
5
5
 
6
6
  async function run(args) {
@@ -20,10 +20,10 @@ async function run(args) {
20
20
  console.log(`\n 🔧 Cài OpenMoneta Dev Kit v${v} cho OpenCode`)
21
21
  }
22
22
 
23
- // Cursor install
24
23
  if (both || cursorOnly) {
25
24
  try {
26
- const cmd = `bash "${path.join(pkgRoot, "install.sh")}" --yes`
25
+ const flags = autoYes ? "--yes" : ""
26
+ const cmd = `${runScript("install.sh", pkgRoot)} ${flags}`.trim()
27
27
  console.log(`\n ▶ Cursor...`)
28
28
  execSync(cmd, { stdio: "inherit", cwd: pkgRoot })
29
29
  console.log(` ✅ Cursor done.`)
@@ -32,10 +32,10 @@ async function run(args) {
32
32
  }
33
33
  }
34
34
 
35
- // OpenCode install
36
35
  if (both || opencodeOnly) {
37
36
  try {
38
- const cmd = `bash "${path.join(pkgRoot, "install-opencode.sh")}" --yes`
37
+ const flags = autoYes ? "--yes" : ""
38
+ const cmd = `${runScript("install-opencode.sh", pkgRoot)} ${flags}`.trim()
39
39
  console.log(`\n ▶ OpenCode...`)
40
40
  execSync(cmd, { stdio: "inherit", cwd: pkgRoot })
41
41
  console.log(` ✅ OpenCode done.`)
@@ -1,7 +1,7 @@
1
1
  const { unlinkSync, rmdirSync, existsSync, readdirSync, lstatSync } = require("node:fs")
2
2
  const path = require("node:path")
3
3
  const { execSync } = require("node:child_process")
4
- const { CURSOR_DIR, OPENCODE_DIR, isInstalled, getPkgRoot } = require("../lib/paths")
4
+ const { CURSOR_DIR, OPENCODE_DIR, isInstalled, getPkgRoot, isWindows, runScript } = require("../lib/paths")
5
5
 
6
6
  function rmDir(dir) {
7
7
  if (!existsSync(dir)) return
@@ -39,20 +39,28 @@ async function run(args) {
39
39
 
40
40
  console.log(`\n 🗑 Uninstalling OpenMoneta Dev Kit...`)
41
41
 
42
- // Try calling uninstall.sh first (handles backup restore)
43
42
  const pkgRoot = getPkgRoot()
44
- const uninstallScript = path.join(pkgRoot, "uninstall.sh")
45
- if (existsSync(uninstallScript)) {
43
+ const flags = [autoYes ? "--yes" : "", purge ? "--purge" : ""].filter(Boolean).join(" ")
44
+
45
+ if (isWindows()) {
46
46
  try {
47
- const flags = [autoYes ? "--yes" : "", purge ? "--purge" : ""].filter(Boolean).join(" ")
48
- execSync(`bash "${uninstallScript}" ${flags}`, { stdio: "inherit" })
47
+ execSync(`${runScript("uninstall.sh", pkgRoot)} ${flags}`.trim(), { stdio: "inherit", cwd: pkgRoot })
49
48
  return
50
49
  } catch {
51
50
  console.log(` Manual uninstall...`)
52
51
  }
52
+ } else {
53
+ const uninstallScript = path.join(pkgRoot, "uninstall.sh")
54
+ if (existsSync(uninstallScript)) {
55
+ try {
56
+ execSync(`bash "${uninstallScript}" ${flags}`.trim(), { stdio: "inherit" })
57
+ return
58
+ } catch {
59
+ console.log(` Manual uninstall...`)
60
+ }
61
+ }
53
62
  }
54
63
 
55
- // Manual removal
56
64
  for (const dir of [CURSOR_DIR, OPENCODE_DIR]) {
57
65
  if (!existsSync(dir)) continue
58
66
  for (const item of ["templates", "skills", "agents", "hooks", "scripts"]) {
@@ -1,6 +1,6 @@
1
1
  const { execSync } = require("node:child_process")
2
2
  const path = require("node:path")
3
- const { getPkgRoot, isInstalled } = require("../lib/paths")
3
+ const { getPkgRoot, isInstalled, isWindows, runScript } = require("../lib/paths")
4
4
  const { getLocalVersion, getLatestVersion } = require("../lib/version")
5
5
 
6
6
  async function run(args) {
@@ -42,7 +42,7 @@ async function run(args) {
42
42
  if (isInstalled("cursor")) {
43
43
  console.log(`\n ▶ Cursor global...`)
44
44
  try {
45
- execSync(`bash "${path.join(pkgRoot, "install.sh")}" --yes`, { stdio: "inherit", cwd: pkgRoot })
45
+ execSync(`${runScript("install.sh", pkgRoot)} --yes`, { stdio: "inherit", cwd: pkgRoot })
46
46
  } catch {
47
47
  console.error(` ⚠ Cursor update failed`)
48
48
  }
@@ -51,7 +51,7 @@ async function run(args) {
51
51
  if (isInstalled("opencode")) {
52
52
  console.log(`\n ▶ OpenCode global...`)
53
53
  try {
54
- execSync(`bash "${path.join(pkgRoot, "install-opencode.sh")}" --yes`, { stdio: "inherit", cwd: pkgRoot })
54
+ execSync(`${runScript("install-opencode.sh", pkgRoot)} --yes`, { stdio: "inherit", cwd: pkgRoot })
55
55
  } catch {
56
56
  console.error(` ⚠ OpenCode update failed`)
57
57
  }
@@ -67,11 +67,20 @@ async function run(args) {
67
67
  try {
68
68
  require("node:fs").accessSync(docsIndex)
69
69
  console.log(`\n ▶ Syncing project: ${path.basename(cwd)}`)
70
- execSync(`bash "${initScript}" "${cwd}"`, { stdio: "inherit" })
70
+ if (isWindows()) {
71
+ execSync(`bash "${initScript}" "${cwd}"`, { stdio: "inherit", shell: true })
72
+ } else {
73
+ execSync(`bash "${initScript}" "${cwd}"`, { stdio: "inherit" })
74
+ }
71
75
  console.log(`\n ✅ Project synced.`)
72
- } catch {
73
- console.log(`\n ℹ Không phát hiện project OpenMoneta ở thư mục hiện tại.`)
74
- console.log(` Sync thủ công: openmoneta init`)
76
+ } catch (err) {
77
+ if (isWindows()) {
78
+ console.log(`\n ⚠ Không thể sync project (cần Git Bash). Cài tại: https://git-scm.com/download/win`)
79
+ console.log(` Sau đó chạy thủ công: bash "${initScript}" "${cwd}"`)
80
+ } else {
81
+ console.log(`\n ℹ Không phát hiện project OpenMoneta ở thư mục hiện tại.`)
82
+ console.log(` Sync thủ công: openmoneta init`)
83
+ }
75
84
  }
76
85
  }
77
86
 
package/src/lib/paths.js CHANGED
@@ -31,6 +31,17 @@ function isInstalled(target) {
31
31
  return installedVersion(target) !== null
32
32
  }
33
33
 
34
+ function isWindows() {
35
+ return process.platform === "win32"
36
+ }
37
+
38
+ function runScript(scriptName, pkgRoot) {
39
+ if (isWindows()) {
40
+ return `powershell.exe -ExecutionPolicy Bypass -File "${path.join(pkgRoot, scriptName.replace(/\\.sh$/, ".ps1"))}"`
41
+ }
42
+ return `bash "${path.join(pkgRoot, scriptName)}"`
43
+ }
44
+
34
45
  module.exports = {
35
46
  setPkgRoot(r) {
36
47
  ROOT = r
@@ -43,4 +54,6 @@ module.exports = {
43
54
  versionFilePath,
44
55
  installedVersion,
45
56
  isInstalled,
57
+ isWindows,
58
+ runScript,
46
59
  }