@hungvv/super-ads-skills 1.0.0 → 1.1.0

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.
Files changed (55) hide show
  1. package/README.md +71 -13
  2. package/dist/cli.js +8 -2
  3. package/package.json +1 -1
  4. package/skills/README.md +4 -0
  5. package/skills/adspro-to-superads/SKILL.md +157 -732
  6. package/skills/adspro-to-superads/references/global-invariant-check.md +49 -0
  7. package/skills/adspro-to-superads/references/migration-contract.md +57 -0
  8. package/skills/adspro-to-superads/references/phase-0-inventory.md +39 -0
  9. package/skills/adspro-to-superads/references/phase-1-2-gradle-manifest.md +85 -0
  10. package/skills/adspro-to-superads/references/phase-3-config-migration.md +159 -0
  11. package/skills/adspro-to-superads/references/phase-4-wrapper-observability.md +70 -0
  12. package/skills/adspro-to-superads/references/phase-5-7-callsites-layout-cleanup.md +73 -0
  13. package/skills/adspro-to-superads/references/principles-and-authority.md +73 -0
  14. package/skills/adspro-to-superads/references/user-questions.md +53 -0
  15. package/skills/adspro-to-superads/snippets/ads-api-quick.md +20 -0
  16. package/skills/adspro-to-superads/templates/migration-inventory.md +42 -0
  17. package/skills/super-ads-ab-test/SKILL.md +91 -23
  18. package/skills/super-ads-adb-test/SKILL.md +85 -36
  19. package/skills/super-ads-adb-test/{references → examples}/scenarios-sample.md +5 -5
  20. package/skills/super-ads-add-placement/SKILL.md +145 -50
  21. package/skills/super-ads-add-placement/references/call-site-api.md +33 -0
  22. package/skills/super-ads-add-placement/snippets/app-open.md +25 -0
  23. package/skills/super-ads-add-placement/snippets/fullscreen-nav.md +14 -0
  24. package/skills/super-ads-add-placement/snippets/inline-banner-native.md +19 -0
  25. package/skills/super-ads-add-placement/snippets/preload-event.md +13 -0
  26. package/skills/super-ads-add-placement/snippets/reward.md +17 -0
  27. package/skills/super-ads-config/SKILL.md +94 -36
  28. package/skills/super-ads-debug/SKILL.md +87 -37
  29. package/skills/super-ads-debug/references/logging-setup.md +2 -0
  30. package/skills/super-ads-debug/scripts/filter-logads.sh +21 -0
  31. package/skills/super-ads-debug-override/SKILL.md +154 -81
  32. package/skills/super-ads-debug-override/snippets/arm-override.md +9 -0
  33. package/skills/super-ads-debug-override/snippets/check-module.md +8 -0
  34. package/skills/super-ads-debug-override/snippets/clear-override.md +9 -0
  35. package/skills/super-ads-debug-override/snippets/confirm-active.md +16 -0
  36. package/skills/super-ads-guide/SKILL.md +129 -0
  37. package/skills/super-ads-guide/references/compatibility.md +26 -0
  38. package/skills/super-ads-guide/references/sdk-version-check.md +50 -0
  39. package/skills/super-ads-integrate/SKILL.md +145 -47
  40. package/skills/super-ads-integrate/references/application-setup.md +2 -21
  41. package/skills/super-ads-integrate/references/gradle-setup.md +1 -13
  42. package/skills/super-ads-integrate/snippets/consent-request.md +12 -0
  43. package/skills/super-ads-integrate/templates/application-oncreate.md +17 -0
  44. package/skills/super-ads-integrate/templates/gradle-dependencies.md +17 -0
  45. package/skills/super-ads-release-check/SKILL.md +85 -32
  46. package/skills/super-ads-show-rate/SKILL.md +87 -36
  47. package/skills/super-ads-show-rate/references/collect-snippet.md +2 -36
  48. package/skills/super-ads-show-rate/scripts/show-rate.sh +25 -0
  49. package/skills/super-ads-show-rate/snippets/show-events-logger.md +26 -0
  50. package/skills/super-ads-upgrade/SKILL.md +137 -0
  51. package/skills/super-ads-upgrade/references/upgrade-hops.md +26 -0
  52. package/skills/super-ads-upgrade/templates/changelog-template.md +39 -0
  53. package/skills/super-ads-add-placement/references/call-site-snippets.md +0 -90
  54. /package/skills/super-ads-ab-test/{references → templates}/firebase-handoff-template.md +0 -0
  55. /package/skills/super-ads-config/{references → examples}/patch-examples.md +0 -0
@@ -1,57 +1,63 @@
1
1
  ---
2
2
  schema: 1
3
3
  name: super-ads-add-placement
4
- description: Use when an app that already runs SuperAds needs a new ad placement or a placement moved/changed — config via the super-ads MCP, call site in app code, then verification on device.
5
- version: 1.0.0
4
+ description: Use when an app already on SuperAds needs a new or changed ad placement - MCP config, call site, device check
5
+ version: 1.1.0
6
6
  group: Ads
7
+ superAds: ">=4.0.0 <5.0.0"
7
8
  ---
8
9
 
9
10
  # Gắn thêm placement vào app đã dùng SuperAds
10
11
 
11
12
  Ba phần luôn đi cùng nhau: **config** (placement + adItem + unit), **call site** (lời gọi `Ads.show` / `Ads.dispatchEvent` trong code app), **kiểm tra** trên thiết bị.
12
13
 
13
- | Bước | Tài liệu |
14
+ ## When to use
15
+
16
+ - "Thêm inter khi bấm nút X", "thêm native vào màn Y", "đổi banner sang collapsible", "thêm app open".
17
+
18
+ ## 🚫 When NOT to use
19
+
20
+ - App chưa có SuperAds → [super-ads-integrate](../super-ads-integrate/SKILL.md).
21
+ - App còn AdsPro → `adspro-to-superads`.
22
+ - Chỉ chỉnh tần suất / giá trị key của placement có sẵn, không đụng code: [super-ads-config](../super-ads-config/SKILL.md) (và `super-ads-show-rate` nếu cần đo trước/sau).
23
+
24
+ ## 📋 Prerequisites
25
+
26
+ - Định tuyến skill và kiểm version SDK: [super-ads-guide](../super-ads-guide/SKILL.md).
27
+ - Quy tắc version: skill này nhắm SuperAds `>=4.0.0 <5.0.0`. Nếu app dùng SuperAds thấp hơn, dừng lại và khuyến nghị (không ép) nâng cấp bằng [super-ads-upgrade](../super-ads-upgrade/SKILL.md) trước khi tiếp tục.
28
+ - Viết tắt: `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
29
+ - Thứ tự nguồn sự thật: (1) code SDK (`SA/api/…`), (2) `MIGRATION.md`, (3) tri thức key và `format-playbooks.md`, (4) code hiện có của app: wrapper, quy ước đặt tên placement, cách các màn khác đang gọi ad. Code app quyết định **cách viết**, SDK quyết định **hành vi**.
30
+ - Recon trước: file config đang nạp, placement có sẵn, wrapper của app, một màn tương tự đã gắn ad (Bước 1 của Workflow).
31
+ - MCP `super-ads` đang kết nối.
32
+
33
+ ## ⚡ Quick Reference
34
+
35
+ | Cần | Mở |
14
36
  |---|---|
15
- | Call site theo format | [references/call-site-snippets.md](references/call-site-snippets.md) |
37
+ | API `Ads.show`, `AdTarget`, callback, inline trong list | [references/call-site-api.md](references/call-site-api.md) |
38
+ | Fullscreen có điều hướng (INTER, NATIVE_FULL_ACTIVITY) | [snippets/fullscreen-nav.md](snippets/fullscreen-nav.md) |
39
+ | Reward / Reward Interstitial | [snippets/reward.md](snippets/reward.md) |
40
+ | Inline: banner, native, collapsible | [snippets/inline-banner-native.md](snippets/inline-banner-native.md) |
41
+ | Preload theo event | [snippets/preload-event.md](snippets/preload-event.md) |
42
+ | App Open khi quay lại app | [snippets/app-open.md](snippets/app-open.md) |
16
43
  | Chọn format, recipe config | `tools/ai_agent_tools/docs/format-playbooks.md`, MCP `list_ad_formats` / `get_format_recipe` |
17
44
  | Quy trình MCP (patch, conflict, sync) | `tools/ai_agent_tools/AI_ADS_PLAYBOOK.md` |
18
- | Ý nghĩa key, placement, tác động patch | MCP `explain_key` / `explain_placement` / `impact_of_patch` (`tools/ai_agent_tools/src/mcp/tools.js:177-219`); nguồn: `tools/ai_agent_tools/data/ads_key_knowledge.json` |
19
- | Kiểm trên máy | `super-ads-adb-test` |
45
+ | Kiểm trên máy | [super-ads-adb-test](../super-ads-adb-test/SKILL.md) |
20
46
 
21
- Viết tắt: `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
47
+ ## 🏗️ Recommended Architecture
22
48
 
23
- ## When to use
24
- - "Thêm inter khi bấm nút X", "thêm native vào màn Y", "đổi banner sang collapsible", "thêm app open".
49
+ Một placement mới là ba phần cùng đổi, theo thứ tự:
25
50
 
26
- ## When NOT to use
27
- - App chưa có SuperAds → `super-ads-integrate`.
28
- - App còn AdsPro → `adspro-to-superads`.
29
- - Chỉ chỉnh tần suất / giá trị key của placement có sẵn, không đụng code: `super-ads-config` (và `super-ads-show-rate` nếu cần đo trước/sau).
30
-
31
- ## Authority order
32
- 1. Code SDK (`SA/api/…`).
33
- 2. `MIGRATION.md`.
34
- 3. Tri thức key và `format-playbooks.md`.
35
- 4. Code hiện có của app: wrapper, quy ước đặt tên placement, cách các màn khác đang gọi ad. Code app quyết định **cách viết**, SDK quyết định **hành vi**.
36
-
37
- ## Contract
38
- **MUST**
39
- - Recon trước: file config đang nạp, placement có sẵn, wrapper của app, một màn tương tự đã gắn ad.
40
- - Đổi config **chỉ** qua MCP `super-ads` (`scaffold_ad` → `impact_of_patch` → user duyệt → `apply_patch` → `validate_config` → `sync_to_source`; `create_ad` chỉ trong ca ở Phase 3). Không sửa tay file JSON.
41
- - `impact_of_patch` trước **mọi** `apply_patch`. User duyệt đúng patch đó rồi mới áp.
42
- - `validate_config` sạch error trước khi `sync_to_source`.
43
- - Call site theo wrapper của app nếu có. Không có thì theo [call-site-snippets.md](references/call-site-snippets.md).
44
- - Placement id trong code trùng **chính xác** id trong config (phân biệt hoa thường).
45
- - Inline: truyền `AdTarget.AdView(container, lifecycle)`; trong Fragment dùng `viewLifecycleOwner.lifecycle`.
46
- - Fullscreen chặn luồng (sang màn sau, nhận thưởng): xử lý cả nhánh fail. Ad lỗi không được làm kẹt người dùng.
51
+ 1. **Config** (qua MCP): `scaffold_ad` → `impact_of_patch` → user duyệt → `apply_patch` → `validate_config` → `sync_to_source`.
52
+ 2. **Call site** (code app): theo wrapper của app nếu có, không thì theo [snippets](references/call-site-api.md).
53
+ 3. **Kiểm trên máy**: show → Impression, cộng một kịch bản fail.
47
54
 
48
- **MUST NOT**
49
- - Không bịa ad unit id. Không lấy unit của app khác.
50
- - Không dùng unit test `ca-app-pub-3940256099942544` trong config sẽ phát hành.
51
- - Không thêm network/plugin mới (dependency) khi chưa hỏi.
52
- - Không gọi `Ads.show` song song với wrapper đã có cho cùng việc.
55
+ Placement id trong code phải trùng chính xác id trong config.
56
+
57
+ ## Workflow
58
+
59
+ ### Stop conditions (dừng và hỏi user)
53
60
 
54
- ## Stop conditions (dừng và hỏi user)
55
61
  - Thiếu ad unit id thật, hoặc chưa rõ network.
56
62
  - `validate_config` báo lỗi mà cách sửa đổi hành vi placement khác.
57
63
  - Thay đổi ảnh hưởng nhiều hơn 1 placement (dùng chung adItem, `reload.*`, chain, `show.keyTimeBetween`).
@@ -60,15 +66,15 @@ Viết tắt: `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
60
66
  - App có wrapper riêng mà chưa rõ cách dùng, hoặc không có màn nào tương tự để theo.
61
67
  - Quyết định sản phẩm: vị trí, thời điểm show, tần suất, có thưởng khi đóng sớm hay không (`RewardAdCallback.applyForAnyAdFull`).
62
68
 
63
- ## Phase 1: Recon
69
+ ### 1. Recon
70
+
64
71
  1. Tìm `Ads.init` (và `Ads.loadFromJson`) trong `Application` → tên file config (asset) và có remote hay không.
65
72
  2. `read_working_config` (MCP): placement có sẵn, quy ước đặt tên, network đang dùng, và `defaultSyncPath` có đúng file ở bước 1 không. `explain_placement` cho placement mẫu nếu cần hiểu key của nó.
66
73
  3. Tìm wrapper: grep `Ads.show(` trong app. Nhiều chỗ gọi qua cùng một hàm thì đó là wrapper.
67
74
  4. Chọn một màn đã gắn ad cùng nhóm format làm mẫu.
68
75
 
69
- **Verify:** ghi được: file config (và `defaultSyncPath` có khớp không), placement mẫu, hàm wrapper (hoặc "không có"), màn mẫu.
76
+ ### 2. Chọn format
70
77
 
71
- ## Phase 2: Chọn format
72
78
  | Nhu cầu | Format | Ghi chú |
73
79
  |---|---|---|
74
80
  | Chen giữa hai màn | `INTER` (hoặc `NATIVE_FULL_ACTIVITY`) | `NavAdCallback`, key `mode.navigate` |
@@ -80,9 +86,8 @@ Viết tắt: `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
80
86
 
81
87
  Danh sách format thật: `SA/domain/model/ad/AdFormat.kt:12`. Recipe config: MCP `get_format_recipe`.
82
88
 
83
- **Verify:** format, network, unit id đã chốt với user.
89
+ ### 3. Config qua MCP
84
90
 
85
- ## Phase 3: Config qua MCP
86
91
  1. Sinh patch: `scaffold_ad` với id theo quy ước của app, cộng các key theo recipe. Mỗi key không có trong recipe: `explain_key` (truyền `format`), ghi `confidence`; `confidence` khác `verified` hoặc `appliesToFormat` khác `true` thì nói rõ với user.
87
92
  2. `impact_of_patch` với đúng patch sẽ áp.
88
93
  - `mustAsk = true` ⇒ dừng, hỏi user nguyên văn từng mục `askReasons`.
@@ -92,30 +97,85 @@ Danh sách format thật: `SA/domain/model/ad/AdFormat.kt:12`. Recipe config: MC
92
97
  - `create_ad` (tự apply, không qua `impact_of_patch`) chỉ dùng khi không ai khác đang sửa song song (`tools/ai_agent_tools/src/mcp/tools.js:284-291`) **và** chỉ tạo entity mới, user đã duyệt spec (format, network, unit, id).
93
98
  4. `validate_config` → sửa đến khi hết error (mỗi lần sửa lại qua bước 2-3). `explain_placement` cho placement mới để kiểm `issues` / `unresolved`.
94
99
  5. Trình user diff thực tế (`diff_configs` hoặc `history`). Khác diff đã duyệt ⇒ không sync, hỏi lại.
95
- 6. `sync_to_source`: trước đó `read_working_config`, kiểm `defaultSyncPath` đúng file config app nạp (Phase 1); không đúng thì truyền `targetPath`.
100
+ 6. `sync_to_source`: trước đó `read_working_config`, kiểm `defaultSyncPath` đúng file config app nạp (Bước 1); không đúng thì truyền `targetPath`.
96
101
 
97
- **Verify:** `validate_config` không error; file config trên đĩa (đúng file app nạp) có placement mới.
102
+ ### 4. Call site
98
103
 
99
- ## Phase 4: Call site
100
- - Viết theo wrapper hoặc mẫu trong [call-site-snippets.md](references/call-site-snippets.md).
104
+ - Viết theo wrapper hoặc mẫu trong [references/call-site-api.md](references/call-site-api.md) (snippet theo format ở bảng Quick Reference).
101
105
  - Preload: thêm `Ads.dispatchEvent(activity, "<event>")` ở chỗ app biết sắp cần ad, event khớp `preload.eventActive`.
102
106
  - Build module app: `./gradlew :<appModule>:assembleDebug`. Báo nguyên văn kết quả.
103
107
 
104
- **Verify:** build pass; grep thấy placement id trong code và trong config.
108
+ ### 5. Kiểm trên máy
105
109
 
106
- ## Phase 5: Kiểm trên máy
107
- - Chạy `super-ads-adb-test`: ít nhất kịch bản "show → Impression" cho placement mới, và một kịch bản fail (mất mạng hoặc cooldown) để chắc nhánh fail không làm kẹt người dùng.
110
+ - Chạy [super-ads-adb-test](../super-ads-adb-test/SKILL.md): ít nhất kịch bản "show → Impression" cho placement mới, và một kịch bản fail (mất mạng hoặc cooldown) để chắc nhánh fail không làm kẹt người dùng.
108
111
  - Không có máy: ghi **chưa kiểm trên thiết bị**.
109
112
 
110
- **Verify:** có dòng `adEventSink Impression: public=<placement>` (`SA/show/AdEventRouter.kt:67`), hoặc ghi rõ là chưa chạy.
113
+ ## 🔧 API Reference
114
+
115
+ | MCP tool | Mục đích |
116
+ |---|---|
117
+ | `read_working_config` | Xem config đang làm việc, `defaultSyncPath` |
118
+ | `list_ad_formats` / `get_format_recipe` | Chọn format, recipe config |
119
+ | `scaffold_ad` | Sinh patch cho placement mới |
120
+ | `explain_key` / `explain_placement` / `impact_of_patch` | Ý nghĩa key, placement, tác động patch (`tools/ai_agent_tools/src/mcp/tools.js:177-219`); nguồn: `tools/ai_agent_tools/data/ads_key_knowledge.json` |
121
+ | `apply_patch` | Áp patch đã duyệt |
122
+ | `validate_config` | Kiểm config trước khi sync |
123
+ | `diff_configs` / `history` | Diff thực tế, lịch sử thay đổi |
124
+ | `sync_to_source` | Ghi vào file config app nạp |
125
+ | `create_ad` | Tạo entity mới (tự apply), chỉ trong ca ở bước 3 |
126
+
127
+ Call site (`Ads.show`, `AdTarget`, callback): [references/call-site-api.md](references/call-site-api.md).
128
+
129
+ ## ✅ Best Practices
130
+
131
+ - Đổi config **chỉ** qua MCP `super-ads` (`scaffold_ad` → `impact_of_patch` → user duyệt → `apply_patch` → `validate_config` → `sync_to_source`; `create_ad` chỉ trong ca ở Bước 3). Không sửa tay file JSON.
132
+ - `impact_of_patch` trước **mọi** `apply_patch`. User duyệt đúng patch đó rồi mới áp.
133
+ - `validate_config` sạch error trước khi `sync_to_source`.
134
+ - Call site theo wrapper của app nếu có. Không có thì theo [call-site-api.md](references/call-site-api.md).
135
+ - Placement id trong code trùng **chính xác** id trong config (phân biệt hoa thường).
136
+ - Inline: truyền `AdTarget.AdView(container, lifecycle)`; trong Fragment dùng `viewLifecycleOwner.lifecycle`.
137
+ - Fullscreen chặn luồng (sang màn sau, nhận thưởng): xử lý cả nhánh fail. Ad lỗi không được làm kẹt người dùng.
138
+
139
+ ## ❌ Anti-patterns
111
140
 
112
- ## Anti-patterns
141
+ - Bịa ad unit id, hoặc lấy unit của app khác.
142
+ - Dùng unit test `ca-app-pub-3940256099942544` trong config sẽ phát hành.
143
+ - Thêm network/plugin mới (dependency) khi chưa hỏi.
144
+ - Gọi `Ads.show` song song với wrapper đã có cho cùng việc.
113
145
  - Thêm placement vào config mà quên call site (hoặc ngược lại).
114
146
  - Copy placement có sẵn rồi đổi tên nhưng vẫn dùng chung adItem: hai placement chung cooldown và bộ đếm.
115
147
  - `mode.show = SHOW_LOADED` mà không có `Ads.dispatchEvent` tương ứng: fail `LOAD:208` mãi.
116
148
  - Gắn inline vào container `GONE` hoặc kích thước 0.
117
149
 
150
+ ## ⚠️ Common Issues
151
+
152
+ **`apply_patch` trả `VERSION_CONFLICT`.**
153
+ Cause: config đã đổi từ lúc đọc. Solution: `read_working_config` + `history`, dựng lại patch, `impact_of_patch` lại (chi tiết ở Workflow bước 3).
154
+
155
+ **Placement fail `LOAD:208` mãi.**
156
+ Cause: `mode.show = SHOW_LOADED` mà chưa có `Ads.dispatchEvent` tương ứng. Solution: thêm `Ads.dispatchEvent` đúng `preload.eventActive`, hoặc dùng `LOAD_AND_SHOW` ([snippets/preload-event.md](snippets/preload-event.md)).
157
+
158
+ ## Files created
159
+
160
+ - Không tạo file source mới. Placement mới là entry thêm vào file config hiện có (qua MCP), không phải file riêng.
161
+
162
+ ## Files modified
163
+
164
+ - File config (asset) app đang nạp: ghi qua MCP `sync_to_source`, không sửa tay.
165
+ - Code app tại call site (hoặc wrapper của app): lời gọi `Ads.show` / `Ads.dispatchEvent`.
166
+
167
+ ## Verification
168
+
169
+ Báo output thật. Sau mỗi bước ở Workflow:
170
+
171
+ 1. **Recon:** ghi được: file config (và `defaultSyncPath` có khớp không), placement mẫu, hàm wrapper (hoặc "không có"), màn mẫu.
172
+ 2. **Chọn format:** format, network, unit id đã chốt với user.
173
+ 3. **Config qua MCP:** `validate_config` không error; file config trên đĩa (đúng file app nạp) có placement mới.
174
+ 4. **Call site:** build pass; grep thấy placement id trong code và trong config.
175
+ 5. **Kiểm trên máy:** có dòng `adEventSink Impression: public=<placement>` (`SA/show/AdEventRouter.kt:67`), hoặc ghi rõ là chưa chạy.
176
+
118
177
  ## Checklist
178
+
119
179
  - [ ] Recon xong, có màn mẫu.
120
180
  - [ ] Format, network, unit id đã chốt.
121
181
  - [ ] `impact_of_patch` cho mọi patch, user duyệt đúng patch đó (`mustAsk` đã hỏi).
@@ -124,5 +184,40 @@ Danh sách format thật: `SA/domain/model/ad/AdFormat.kt:12`. Recipe config: MC
124
184
  - [ ] Build pass (trích output).
125
185
  - [ ] Đã kiểm trên máy, hoặc ghi rõ chưa.
126
186
 
187
+ ## 📈 Performance Notes
188
+
189
+ > **Not applicable for this skill.**
190
+
191
+ ## 🔒 Security Notes
192
+
193
+ > **Not applicable for this skill.**
194
+
195
+ ## 🔄 Migration Guide
196
+
197
+ > **Not applicable for this skill.**
198
+
127
199
  ## Output
200
+
128
201
  File đã sửa (code app, config), diff config, output build, kết quả kiểm trên máy, phần chưa xác minh.
202
+
203
+ ## Examples
204
+
205
+ - Fullscreen có điều hướng: [snippets/fullscreen-nav.md](snippets/fullscreen-nav.md)
206
+ - Reward: [snippets/reward.md](snippets/reward.md)
207
+ - Inline: [snippets/inline-banner-native.md](snippets/inline-banner-native.md)
208
+ - Preload theo event: [snippets/preload-event.md](snippets/preload-event.md)
209
+ - App Open: [snippets/app-open.md](snippets/app-open.md)
210
+ - Inline trong danh sách: [references/call-site-api.md](references/call-site-api.md)
211
+
212
+ ## 📚 References
213
+
214
+ - [super-ads-guide](../super-ads-guide/SKILL.md): định tuyến, kiểm version SDK.
215
+ - [super-ads-upgrade](../super-ads-upgrade/SKILL.md): nâng cấp SuperAds.
216
+ - [super-ads-integrate](../super-ads-integrate/SKILL.md), [super-ads-config](../super-ads-config/SKILL.md), [super-ads-adb-test](../super-ads-adb-test/SKILL.md).
217
+ - `adspro-to-superads`, `super-ads-show-rate`: skill anh em.
218
+ - Mẫu wrapper: [../adspro-to-superads/references/wrapper-template.md](../adspro-to-superads/references/wrapper-template.md).
219
+ - Repo SDK: `MIGRATION.md`, `tools/ai_agent_tools/AI_ADS_PLAYBOOK.md`, `tools/ai_agent_tools/docs/format-playbooks.md`.
220
+
221
+ ## 🏷️ Tags
222
+
223
+ `superads`, `placement`, `mcp`, `call-site`, `config`, `ads`
@@ -0,0 +1,33 @@
1
+ # Call site theo nhóm format
2
+
3
+ > Authority: code SDK. `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
4
+ > App đã có wrapper (vd `AdsUtils`, extension `showAdView`) thì **gọi qua wrapper**, không gọi `Ads.show` trực tiếp bên cạnh. Mẫu wrapper: [../../adspro-to-superads/references/wrapper-template.md](../../adspro-to-superads/references/wrapper-template.md).
5
+
6
+ ## API dùng chung
7
+
8
+ | API | Chữ ký / hành vi | Nguồn |
9
+ |---|---|---|
10
+ | `Ads.show` | `show(placementId, activity, target = AdTarget.AdFull, callback = LoggerAdsCallback())`; callback chạy trên main; gọi trước khi init xong thì xếp hàng chờ | `SA/api/Ads.kt:200-217` |
11
+ | `AdTarget` | `AdFull` (fullscreen) hoặc `AdView(container, lifecycleOfViewOwner = null)` (inline) | `SA/api/model/AdTarget.kt:7-15` |
12
+ | `AdsCallback` | `onAdImpression`, `onAdShowedFull`, `onAdDismissedFull`, `onAdCollapsibleDismiss`, `onAdFailed`, `onUserEarnedReward`, `onAdClicked` (đều có thân mặc định) | `SA/api/callback/AdsCallback.kt:32-120` |
13
+ | `NavAdCallback` | gọi `onNav` một lần theo `mode.navigate`; fail thì `NavResult.Failed` | `SA/api/callback/AdsCallback.kt:122-191` |
14
+ | `RewardAdCallback` | gọi `onReward` một lần lúc dismiss; `Premium` coi là `Success` | `SA/api/callback/AdsCallback.kt:194-266` |
15
+ | `Ads.dispatchEvent` | preload các adItem có `preload.eventActive` chứa event | `SA/api/Ads.kt:247-249` |
16
+ | `Ads.destroyByPlacement` / `Ads.dismissByPlacement` | huỷ ad + cache của placement / đóng ad đang hiện và dừng reload | `SA/api/Ads.kt:225-237` |
17
+
18
+ ## Snippet theo nhóm format
19
+
20
+ | Nhóm format | Snippet |
21
+ |---|---|
22
+ | Fullscreen có điều hướng (INTER, NATIVE_FULL_ACTIVITY) | [../snippets/fullscreen-nav.md](../snippets/fullscreen-nav.md) |
23
+ | Reward / Reward Interstitial | [../snippets/reward.md](../snippets/reward.md) |
24
+ | Inline: banner, native, collapsible | [../snippets/inline-banner-native.md](../snippets/inline-banner-native.md) |
25
+ | Preload theo event | [../snippets/preload-event.md](../snippets/preload-event.md) |
26
+ | App Open khi quay lại app | [../snippets/app-open.md](../snippets/app-open.md) |
27
+ | Inline trong danh sách (RecyclerView / Epoxy) | mục "Inline trong danh sách" bên dưới |
28
+
29
+ ## Inline trong danh sách (RecyclerView / Epoxy)
30
+
31
+ Mẫu: `app/src/main/java/com/android/hd/ads2026/test/NativeTestActivity.kt:49-65`.
32
+ - Gọi `Ads.show` lúc bind item quảng cáo, với container của chính item đó.
33
+ - Trả placement khi unbind (`AdPlacementController.recyclePlacement`, `app/src/main/java/com/android/hd/ads2026/AdPlacementController.kt:131`). Đây là helper của app mẫu, không thuộc SDK.
@@ -0,0 +1,25 @@
1
+ # App Open khi quay lại app
2
+
3
+ > Authority: code SDK. `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
4
+ > App đã có wrapper (vd `AdsUtils`, extension `showAdView`) thì **gọi qua wrapper**, không gọi `Ads.show` trực tiếp bên cạnh. Mẫu wrapper: [../../adspro-to-superads/references/wrapper-template.md](../../adspro-to-superads/references/wrapper-template.md).
5
+
6
+ API dùng chung: [../references/call-site-api.md](../references/call-site-api.md).
7
+
8
+ ```kotlin
9
+ // Application.onCreate, sau Ads.init
10
+ // appOpenAllowed: cờ của app, chỉ bật sau callback consent và sau lần vào app đầu (splash).
11
+ AppLifecycleMonitor(
12
+ onForeground = {
13
+ if (appOpenAllowed) {
14
+ Ads.config.getActivityProvider()?.getActivityOnTopNotAds()?.let { Ads.show("<app_open_placement>", it) }
15
+ }
16
+ },
17
+ onBackground = {},
18
+ ).register()
19
+ ```
20
+
21
+ **Không bỏ guard:** `onForeground` chạy cả ở `ON_START` đầu tiên lúc mở app lạnh (`SA/api/lifecycle/AppLifecycleMonitor.kt:19-21`), tức trước khi consent ở Activity đầu kịp trả về. Không có guard thì App Open gửi request trước consent. App mẫu chặn tạm bằng thời gian (`app/src/main/java/com/android/hd/ads2026/MyApplication.kt:61`).
22
+
23
+ - `AppLifecycleMonitor` chỉ chuyển `onStart`/`onStop` của `ProcessLifecycleOwner` (`SA/api/lifecycle/AppLifecycleMonitor.kt:9-29`). Mẫu đăng ký: `app/src/main/java/com/android/hd/ads2026/MyApplication.kt:58-72`.
24
+ - Guard sau fullscreen (`appOpen.guardAfterFullscreenMs`) chặn App Open ngay sau khi đóng một fullscreen (`POLICY:108`, `SA/engine/rules/FullscreenRules.kt:74-97`).
25
+ - Điều kiện thêm (màn splash, không show lần mở đầu…) là logic của app: theo cách app đang làm, chưa có thì hỏi user.
@@ -0,0 +1,14 @@
1
+ # Fullscreen có điều hướng (INTER, NATIVE_FULL_ACTIVITY)
2
+
3
+ > Authority: code SDK. `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
4
+ > App đã có wrapper (vd `AdsUtils`, extension `showAdView`) thì **gọi qua wrapper**, không gọi `Ads.show` trực tiếp bên cạnh. Mẫu wrapper: [../../adspro-to-superads/references/wrapper-template.md](../../adspro-to-superads/references/wrapper-template.md).
5
+
6
+ API dùng chung: [../references/call-site-api.md](../references/call-site-api.md).
7
+
8
+ ```kotlin
9
+ Ads.show("<placement>", activity, callback = NavAdCallback { result ->
10
+ goNext() // gọi cho cả Success và Failed: ad lỗi không được chặn luồng người dùng
11
+ })
12
+ ```
13
+
14
+ Thời điểm `onNav` do key `mode.navigate` quyết định, SDK không tự điều hướng (tra `mode.navigate` trong `tools/ai_agent_tools/data/ads_key_knowledge.json`).
@@ -0,0 +1,19 @@
1
+ # Inline: banner, native, collapsible
2
+
3
+ > Authority: code SDK. `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
4
+ > App đã có wrapper (vd `AdsUtils`, extension `showAdView`) thì **gọi qua wrapper**, không gọi `Ads.show` trực tiếp bên cạnh. Mẫu wrapper: [../../adspro-to-superads/references/wrapper-template.md](../../adspro-to-superads/references/wrapper-template.md).
5
+
6
+ API dùng chung: [../references/call-site-api.md](../references/call-site-api.md).
7
+
8
+ ```kotlin
9
+ // Activity
10
+ Ads.show("<placement>", this, AdTarget.AdView(binding.adContainer, lifecycle), object : AdsCallback {
11
+ override fun onAdFailed(placementId: String, error: AdError) { binding.adContainer.isVisible = false }
12
+ })
13
+
14
+ // Fragment: dùng lifecycle của VIEW, không phải của fragment
15
+ Ads.show("<placement>", requireActivity(), AdTarget.AdView(binding.adContainer, viewLifecycleOwner.lifecycle))
16
+ ```
17
+
18
+ - Mẫu thật: `app/src/main/java/com/android/hd/ads2026/test/BaseTestActivity.kt:79-84`.
19
+ - SDK theo dõi lifecycle chủ view chỉ với collapsible và banner collapsible. Banner/native thường **không** theo dõi (`SA/presentation/presenter/InlinePresenter.kt:23-27`). Dọn ad khi màn hình chết thì theo cách app đang làm ở các màn khác; chưa có tiền lệ thì hỏi user.
@@ -0,0 +1,13 @@
1
+ # Preload theo event
2
+
3
+ > Authority: code SDK. `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
4
+ > App đã có wrapper (vd `AdsUtils`, extension `showAdView`) thì **gọi qua wrapper**, không gọi `Ads.show` trực tiếp bên cạnh. Mẫu wrapper: [../../adspro-to-superads/references/wrapper-template.md](../../adspro-to-superads/references/wrapper-template.md).
5
+
6
+ API dùng chung: [../references/call-site-api.md](../references/call-site-api.md).
7
+
8
+ ```kotlin
9
+ Ads.dispatchEvent(activity, "<event>") // event phải nằm trong preload.eventActive của adItem
10
+ ```
11
+
12
+ - Mẫu: `app/src/main/java/com/android/hd/ads2026/test/BaseTestActivity.kt:87-92`.
13
+ - `mode.show = SHOW_LOADED` thì show **chỉ** dùng ad đã preload; chưa có thì fail `LOAD:208`. Muốn load lúc show thì dùng `LOAD_AND_SHOW` (tra `mode.show` trong file tri thức).
@@ -0,0 +1,17 @@
1
+ # Reward / Reward Interstitial
2
+
3
+ > Authority: code SDK. `SA/` = `super-ads/src/main/java/com/android/fullhd/super_ads/`.
4
+ > App đã có wrapper (vd `AdsUtils`, extension `showAdView`) thì **gọi qua wrapper**, không gọi `Ads.show` trực tiếp bên cạnh. Mẫu wrapper: [../../adspro-to-superads/references/wrapper-template.md](../../adspro-to-superads/references/wrapper-template.md).
5
+
6
+ API dùng chung: [../references/call-site-api.md](../references/call-site-api.md).
7
+
8
+ ```kotlin
9
+ Ads.show("<placement>", activity, callback = RewardAdCallback(applyForAnyAdFull = false) { result ->
10
+ when (result) {
11
+ is RewardResult.Success -> grantReward()
12
+ is RewardResult.Failed -> showNoReward()
13
+ }
14
+ })
15
+ ```
16
+
17
+ `applyForAnyAdFull = true` (mặc định) cho thưởng cả khi đóng ad mà không nhận reward (`SA/api/callback/AdsCallback.kt:194-199`). Chọn giá trị là **quyết định sản phẩm**, phải hỏi user.
@@ -1,54 +1,53 @@
1
1
  ---
2
2
  schema: 1
3
3
  name: super-ads-config
4
- description: Use when an existing SuperAds config needs a value changed, an entity enabled/disabled/removed, or any patch applied through the super-ads MCP — explain, compute impact, get the user's approval for that exact patch, apply, verify, then sync.
5
- version: 1.0.0
4
+ description: Use when an existing SuperAds config needs a value changed, an entity toggled or removed via the super-ads MCP
5
+ version: 1.1.0
6
6
  group: Ads
7
+ superAds: ">=4.0.0 <5.0.0"
7
8
  ---
8
9
 
9
10
  # Sửa config SuperAds qua MCP, có điểm dừng bắt buộc
10
11
 
11
12
  Mỗi thay đổi config đi đúng một vòng: **hiểu** (`explain_*`) → **tính tác động** (`impact_of_patch`) → **user duyệt đúng patch đó** → **áp** (`apply_patch`) → **kiểm lại** (`history`, `validate_config`) → **sync**. Điểm dừng do tool quyết định (`mustAsk`), không do agent tự đánh giá.
12
13
 
13
- | Cần | Tài liệu |
14
- |---|---|
15
- | Output thật của `impact_of_patch` (3 ca) | [references/patch-examples.md](references/patch-examples.md) |
16
- | Quy trình MCP chung (conflict, cộng tác, sync) | `tools/ai_agent_tools/AI_ADS_PLAYBOOK.md` |
17
- | Ý nghĩa key | MCP `explain_key`; nguồn `tools/ai_agent_tools/data/ads_key_knowledge.json` |
18
- | Tool | `explain_key` / `explain_placement` / `impact_of_patch` (`tools/ai_agent_tools/src/mcp/tools.js:177-219`), `apply_patch` (`tools/ai_agent_tools/src/mcp/tools.js:354-380`) |
19
-
20
14
  ## When to use
21
15
  - "Tăng cooldown inter lên 60 s", "tắt placement X", "đổi timeout load của adItem Y", "xoá adItem cũ", mọi patch lên working config.
22
16
 
23
- ## When NOT to use
17
+ ## 🚫 When NOT to use
24
18
  - Thêm placement mới kèm call site trong code → `super-ads-add-placement` (skill đó dùng lại vòng này cho phần config).
25
19
  - Đo show rate trước/sau → `super-ads-show-rate`.
26
20
  - Ad lỗi một lần cụ thể → `super-ads-debug`.
27
21
  - Tạo config từ đầu (`create_config`) → `super-ads-integrate`.
28
22
 
29
- ## Authority order
23
+ ## 📋 Prerequisites
24
+ - Định tuyến skill và kiểm version SDK: xem [super-ads-guide](../super-ads-guide/SKILL.md).
25
+ - Skill này nhắm SuperAds `>=4.0.0 <5.0.0`. App dùng SuperAds thấp hơn ⇒ **dừng** và khuyến nghị (không ép) nâng cấp qua [super-ads-upgrade](../super-ads-upgrade/SKILL.md) trước khi tiếp tục.
26
+ - MCP `super-ads` đã kết nối (các tool `read_working_config`, `explain_key`, `explain_placement`, `impact_of_patch`, `apply_patch`, `history`, `validate_config`, `sync_to_source`).
27
+ - Quy trình MCP chung (conflict, cộng tác, sync): `tools/ai_agent_tools/AI_ADS_PLAYBOOK.md`.
28
+
29
+ ## ⚡ Quick Reference
30
+
31
+ | Cần | Tài liệu |
32
+ |---|---|
33
+ | Output thật của `impact_of_patch` (3 ca) | [examples/patch-examples.md](examples/patch-examples.md) |
34
+ | Quy trình MCP chung | `tools/ai_agent_tools/AI_ADS_PLAYBOOK.md` |
35
+ | Ý nghĩa key | MCP `explain_key`; nguồn `tools/ai_agent_tools/data/ads_key_knowledge.json` |
36
+
37
+ Skill này không có `references/`, `templates/`, `snippets/` hay `scripts/`: ví dụ duy nhất nằm trong `examples/`.
38
+
39
+ ## 🏗️ Recommended Architecture
40
+ Vòng xử lý: `read_working_config` → `explain_*` → `impact_of_patch` → user duyệt → `apply_patch` → `history` + `validate_config` → `sync_to_source`. Mỗi bước có **Verify** ở phần Workflow.
41
+
42
+ Thứ tự thẩm quyền khi các nguồn mâu thuẫn:
30
43
  1. Kết quả tool MCP (`impact_of_patch`, `validate_config`): quyết định có phải dừng hay không.
31
44
  2. Code SDK, qua `explain_key` (`confidence`, `sdkSource`).
32
45
  3. `AI_ADS_PLAYBOOK.md`.
33
46
  4. Lời user trong hội thoại: quyết định **giá trị** và **có áp hay không**.
34
47
 
35
- ## Contract
36
- **MUST**
37
- - `impact_of_patch` với **đúng** patch sắp áp, trước mọi `apply_patch`. `ok:false` (`PATCH_INVALID`) thì dừng, sửa patch; kết quả lỗi không bao giờ được coi là an toàn.
38
- - Trình user trước khi áp: patch, `changedPaths`, `affectedPlacements`, hành vi dự kiến (từ `explain_key.effect`), `confidence` của từng key, rủi ro.
39
- - `mustAsk = true`: hỏi **nguyên văn từng** câu trong `askReasons`, nhận câu trả lời rõ cho từng câu.
40
- - `apply_patch` với `baseVersion` đọc được ở bước 1 và đúng patch đã duyệt.
41
- - Sau khi áp: so op trong `history` (theo `opId` trả về) với patch đã duyệt.
42
- - `validate_config` sạch error trước `sync_to_source`; `defaultSyncPath` đúng file app nạp.
43
-
44
- **MUST NOT**
45
- - **`mustAsk = false` không phải quyền tự sửa.** Mọi `apply_patch` cần user duyệt đúng patch đó. Câu duyệt chung trước đó ("cứ sửa đi") không thay được duyệt patch, cũng không thay được câu trả lời cho từng `askReasons`.
46
- - **Không retry mù khi `VERSION_CONFLICT`.** Đọc lại, tính lại impact; patch hoặc tác động đổi thì xin duyệt lại. Không dùng `replace_working_config` để ghi đè.
47
- - **Không `sync_to_source` khi diff thực tế khác diff đã duyệt.**
48
- - Không sửa tay file JSON. Không tự chọn giá trị thay user (cooldown, maxShow, unit id).
49
- - Không đổi patch sau khi user duyệt mà không chạy lại `impact_of_patch` và xin duyệt lại.
48
+ ## Workflow
50
49
 
51
- ## Stop conditions (dừng và hỏi user)
50
+ ### Stop conditions (dừng và hỏi user)
52
51
  - `impact_of_patch.mustAsk = true`: mỗi `askReasons[].rule` là một câu hỏi:
53
52
 
54
53
  | `rule` | Ý nghĩa |
@@ -64,26 +63,26 @@ Mỗi thay đổi config đi đúng một vòng: **hiểu** (`explain_*`) → **
64
63
  - Op trong `history` khác patch đã duyệt.
65
64
  - Hoàn tác bị từ chối (`PATCH_INVALID`, code `TEST_FAILED`): path đã bị actor khác đổi.
66
65
 
67
- ## Phase 1: Đọc
66
+ ### Phase 1: Đọc
68
67
  1. `read_working_config` → ghi `version` (dùng làm `baseVersion`), `defaultSyncPath`.
69
68
  2. `explain_placement` cho placement liên quan (`issues`, `unresolved`); `explain_key` (kèm `format`) cho từng key sẽ đổi.
70
69
 
71
70
  **Verify:** ghi được `baseVersion`, placement đích, nghĩa và `confidence` của từng key.
72
71
 
73
- ## Phase 2: Tính tác động
72
+ ### Phase 2: Tính tác động
74
73
  1. Soạn patch JSON Patch (RFC 6902), path tới key phẳng có dấu chấm: `/adItems/<id>/config/show.timeBetweenMs`.
75
74
  2. `impact_of_patch {patch}` (mặc định chạy trên workspace, trả kèm `baseVersion`). `baseVersion` khác bước 1 ⇒ quay lại Phase 1.
76
75
 
77
76
  **Verify:** có `ok:true`, `changedPaths` đúng các path định đổi, `affectedPlacements` đã đọc.
78
77
 
79
- ## Phase 3: Duyệt
78
+ ### Phase 3: Duyệt (điểm dừng bắt buộc)
80
79
  1. Trình: patch, `changedPaths`, `affectedPlacements` (kèm `reasons`), hành vi dự kiến, `confidence`, rủi ro.
81
80
  2. `mustAsk = true` ⇒ hỏi nguyên văn từng `askReasons[].text`. `mustAsk = false` ⇒ vẫn hỏi "áp đúng patch này?".
82
81
  3. Chỉ sang Phase 4 khi user đồng ý **đúng patch đã trình**. User sửa giá trị ⇒ quay lại Phase 2.
83
82
 
84
83
  **Verify:** có câu trả lời rõ cho patch và cho từng `askReasons`.
85
84
 
86
- ## Phase 4: Áp
85
+ ### Phase 4: Áp
87
86
  `apply_patch {baseVersion, patch, summary}`. Đang cộng tác với một phiên `open_editor` thì truyền `editorSessionId` (xem `AI_ADS_PLAYBOOK.md`).
88
87
 
89
88
  | Kết quả | Làm gì |
@@ -93,7 +92,7 @@ Mỗi thay đổi config đi đúng một vòng: **hiểu** (`explain_*`) → **
93
92
  | `VALIDATION_FAILED` | Dừng, trình `validation` |
94
93
  | `PATCH_INVALID` | Dừng, patch sai path/op |
95
94
 
96
- ## Phase 5: Kiểm sau khi áp
95
+ ### Phase 5: Kiểm sau khi áp
97
96
  1. `history {sinceVersion: <baseVersion>}` → record có `opId` vừa nhận: `patch` và `changedPaths` phải khớp bản đã duyệt; không có op nào khác của actor khác chen vào cùng path.
98
97
  2. Khác ⇒ dừng, báo user, đề nghị hoàn tác:
99
98
  - Đã áp kèm `editorSessionId`: `undo_last_change {editorSessionId}` (`tools/ai_agent_tools/src/mcp/tools.js:403-419`).
@@ -102,7 +101,7 @@ Mỗi thay đổi config đi đúng một vòng: **hiểu** (`explain_*`) → **
102
101
 
103
102
  **Verify:** op khớp patch đã duyệt; `validate_config.errors` rỗng.
104
103
 
105
- ## Phase 6: Sync
104
+ ### Phase 6: Sync
106
105
  1. Chưa chạy thử trên máy ⇒ hỏi user có cần kiểm trước không (`super-ads-adb-test`). Không tự bỏ qua câu hỏi này.
107
106
  2. Trình diff thực tế (`diff_configs` hoặc op trong `history`). Khác diff đã duyệt ⇒ không sync.
108
107
  3. `read_working_config`: `defaultSyncPath` đúng file app nạp? Không đúng ⇒ truyền `targetPath`.
@@ -110,15 +109,54 @@ Mỗi thay đổi config đi đúng một vòng: **hiểu** (`explain_*`) → **
110
109
 
111
110
  **Verify:** file trên đĩa (đúng file app nạp) có thay đổi; không còn thay đổi ngoài patch đã duyệt.
112
111
 
113
- ## Anti-patterns
112
+ ## 🔧 API Reference
113
+
114
+ | Tool | Mục đích | Nguồn |
115
+ |---|---|---|
116
+ | `explain_key` / `explain_placement` / `impact_of_patch` | Hiểu key, placement và tính tác động của patch | `tools/ai_agent_tools/src/mcp/tools.js:177-219` |
117
+ | `apply_patch` | Áp đúng patch đã duyệt lên working config | `tools/ai_agent_tools/src/mcp/tools.js:354-380` |
118
+ | `read_working_config`, `history`, `validate_config`, `diff_configs`, `undo_last_change`, `sync_to_source` | Đọc, đối soát, kiểm và đồng bộ | Phase 1, 5, 6 ở trên |
119
+
120
+ ## ✅ Best Practices
121
+ - `impact_of_patch` với **đúng** patch sắp áp, trước mọi `apply_patch`. `ok:false` (`PATCH_INVALID`) thì dừng, sửa patch; kết quả lỗi không bao giờ được coi là an toàn.
122
+ - Trình user trước khi áp: patch, `changedPaths`, `affectedPlacements`, hành vi dự kiến (từ `explain_key.effect`), `confidence` của từng key, rủi ro.
123
+ - `mustAsk = true`: hỏi **nguyên văn từng** câu trong `askReasons`, nhận câu trả lời rõ cho từng câu.
124
+ - `apply_patch` với `baseVersion` đọc được ở bước 1 và đúng patch đã duyệt.
125
+ - Sau khi áp: so op trong `history` (theo `opId` trả về) với patch đã duyệt.
126
+ - `validate_config` sạch error trước `sync_to_source`; `defaultSyncPath` đúng file app nạp.
127
+
128
+ ## ❌ Anti-patterns
129
+ - **`mustAsk = false` không phải quyền tự sửa.** Mọi `apply_patch` cần user duyệt đúng patch đó. Câu duyệt chung trước đó ("cứ sửa đi") không thay được duyệt patch, cũng không thay được câu trả lời cho từng `askReasons`.
130
+ - **Không retry mù khi `VERSION_CONFLICT`.** Đọc lại, tính lại impact; patch hoặc tác động đổi thì xin duyệt lại. Không dùng `replace_working_config` để ghi đè.
131
+ - **Không `sync_to_source` khi diff thực tế khác diff đã duyệt.**
132
+ - Không sửa tay file JSON. Không tự chọn giá trị thay user (cooldown, maxShow, unit id).
133
+ - Không đổi patch sau khi user duyệt mà không chạy lại `impact_of_patch` và xin duyệt lại.
114
134
  - Thấy `mustAsk:false` rồi áp luôn.
115
135
  - Gộp nhiều thay đổi không liên quan vào một patch để hỏi một lần.
116
136
  - Gặp `VERSION_CONFLICT` thì đổi `baseVersion` rồi gửi lại cùng patch.
117
137
  - Đổi `show.timeBetweenMs` ở adItem dùng chung mà chỉ nói về một placement.
118
138
  - Gọi `undo_last_change` không có `editorSessionId` cho op AI áp độc lập.
119
139
 
120
- ## Giới hạn
121
- Test (`test/explain.test.js`, `test/skills.test.js`) chứng minh tool tính đúng và skill có đủ quy tắc. Không có test tự động chứng minh agent thật sự dừng ở điểm dừng.
140
+ ## ⚠️ Common Issues
141
+
142
+ | Problem | Cause | Solution |
143
+ |---|---|---|
144
+ | `VERSION_CONFLICT` khi `apply_patch` | Actor khác đã đổi working config sau bước đọc | Phase 1 lại, chạy lại `impact_of_patch`, xin duyệt lại nếu khác |
145
+ | `undo_last_change` không dùng được | Op áp không kèm `editorSessionId` nên không nằm trong stack undo | Dùng `inversePatch` trong `history` qua `impact_of_patch`, user duyệt, `apply_patch` |
146
+ | `inversePatch` bị từ chối (`PATCH_INVALID`, `TEST_FAILED`) | Path đã bị actor khác đổi | Dừng, hỏi user, không ghi đè |
147
+
148
+ Giới hạn: test (`test/explain.test.js`, `test/skills.test.js`) chứng minh tool tính đúng và skill có đủ quy tắc. Không có test tự động chứng minh agent thật sự dừng ở điểm dừng.
149
+
150
+ ## Files created
151
+ Skill này không tạo file nguồn.
152
+
153
+ ## Files modified
154
+ Không sửa code app. Chỉ file config JSON mà app nạp (`defaultSyncPath` hoặc `targetPath`), qua MCP `apply_patch` rồi `sync_to_source`, đúng patch user đã duyệt. Không sửa tay.
155
+
156
+ ## Verification
157
+ - `history`: op (theo `opId`) khớp patch đã duyệt.
158
+ - `validate_config`: `errors` rỗng.
159
+ - File trên đĩa đúng file app nạp, không còn thay đổi ngoài patch đã duyệt.
122
160
 
123
161
  ## Checklist
124
162
  - [ ] `baseVersion`, nghĩa và `confidence` từng key.
@@ -128,5 +166,25 @@ Test (`test/explain.test.js`, `test/skills.test.js`) chứng minh tool tính đ
128
166
  - [ ] `validate_config` sạch.
129
167
  - [ ] Đã hỏi về chạy thử; diff thực tế khớp; `sync_to_source` đúng file.
130
168
 
169
+ ## 📈 Performance Notes
170
+ > **Not applicable for this skill.**
171
+
172
+ ## 🔒 Security Notes
173
+ > **Not applicable for this skill.**
174
+
175
+ ## 🔄 Migration Guide
176
+ > **Not applicable for this skill.**
177
+
131
178
  ## Output
132
179
  Patch đã áp, `opId`, `affectedPlacements`, câu trả lời của user cho từng `askReasons`, kết quả `validate_config`, file đã sync, phần chưa xác minh (chưa chạy trên máy…).
180
+
181
+ ## Examples
182
+ - [examples/patch-examples.md](examples/patch-examples.md): output thật của `impact_of_patch` cho 3 ca (`mustAsk: false`, `MULTI_PLACEMENT`, `MONETIZATION_KEY`) và patch lỗi.
183
+
184
+ ## 📚 References
185
+ - [super-ads-guide](../super-ads-guide/SKILL.md), [super-ads-upgrade](../super-ads-upgrade/SKILL.md)
186
+ - [super-ads-add-placement](../super-ads-add-placement/SKILL.md), [super-ads-show-rate](../super-ads-show-rate/SKILL.md), [super-ads-debug](../super-ads-debug/SKILL.md), [super-ads-integrate](../super-ads-integrate/SKILL.md), [super-ads-adb-test](../super-ads-adb-test/SKILL.md)
187
+ - `tools/ai_agent_tools/AI_ADS_PLAYBOOK.md`, `tools/ai_agent_tools/data/ads_key_knowledge.json`
188
+
189
+ ## 🏷️ Tags
190
+ `super-ads` `config` `mcp` `json-patch` `impact` `approval`