@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.
- package/README.md +71 -13
- package/dist/cli.js +8 -2
- package/package.json +1 -1
- package/skills/README.md +4 -0
- package/skills/adspro-to-superads/SKILL.md +157 -732
- package/skills/adspro-to-superads/references/global-invariant-check.md +49 -0
- package/skills/adspro-to-superads/references/migration-contract.md +57 -0
- package/skills/adspro-to-superads/references/phase-0-inventory.md +39 -0
- package/skills/adspro-to-superads/references/phase-1-2-gradle-manifest.md +85 -0
- package/skills/adspro-to-superads/references/phase-3-config-migration.md +159 -0
- package/skills/adspro-to-superads/references/phase-4-wrapper-observability.md +70 -0
- package/skills/adspro-to-superads/references/phase-5-7-callsites-layout-cleanup.md +73 -0
- package/skills/adspro-to-superads/references/principles-and-authority.md +73 -0
- package/skills/adspro-to-superads/references/user-questions.md +53 -0
- package/skills/adspro-to-superads/snippets/ads-api-quick.md +20 -0
- package/skills/adspro-to-superads/templates/migration-inventory.md +42 -0
- package/skills/super-ads-ab-test/SKILL.md +91 -23
- package/skills/super-ads-adb-test/SKILL.md +85 -36
- package/skills/super-ads-adb-test/{references → examples}/scenarios-sample.md +5 -5
- package/skills/super-ads-add-placement/SKILL.md +145 -50
- package/skills/super-ads-add-placement/references/call-site-api.md +33 -0
- package/skills/super-ads-add-placement/snippets/app-open.md +25 -0
- package/skills/super-ads-add-placement/snippets/fullscreen-nav.md +14 -0
- package/skills/super-ads-add-placement/snippets/inline-banner-native.md +19 -0
- package/skills/super-ads-add-placement/snippets/preload-event.md +13 -0
- package/skills/super-ads-add-placement/snippets/reward.md +17 -0
- package/skills/super-ads-config/SKILL.md +94 -36
- package/skills/super-ads-debug/SKILL.md +87 -37
- package/skills/super-ads-debug/references/logging-setup.md +2 -0
- package/skills/super-ads-debug/scripts/filter-logads.sh +21 -0
- package/skills/super-ads-debug-override/SKILL.md +154 -81
- package/skills/super-ads-debug-override/snippets/arm-override.md +9 -0
- package/skills/super-ads-debug-override/snippets/check-module.md +8 -0
- package/skills/super-ads-debug-override/snippets/clear-override.md +9 -0
- package/skills/super-ads-debug-override/snippets/confirm-active.md +16 -0
- package/skills/super-ads-guide/SKILL.md +129 -0
- package/skills/super-ads-guide/references/compatibility.md +26 -0
- package/skills/super-ads-guide/references/sdk-version-check.md +50 -0
- package/skills/super-ads-integrate/SKILL.md +145 -47
- package/skills/super-ads-integrate/references/application-setup.md +2 -21
- package/skills/super-ads-integrate/references/gradle-setup.md +1 -13
- package/skills/super-ads-integrate/snippets/consent-request.md +12 -0
- package/skills/super-ads-integrate/templates/application-oncreate.md +17 -0
- package/skills/super-ads-integrate/templates/gradle-dependencies.md +17 -0
- package/skills/super-ads-release-check/SKILL.md +85 -32
- package/skills/super-ads-show-rate/SKILL.md +87 -36
- package/skills/super-ads-show-rate/references/collect-snippet.md +2 -36
- package/skills/super-ads-show-rate/scripts/show-rate.sh +25 -0
- package/skills/super-ads-show-rate/snippets/show-events-logger.md +26 -0
- package/skills/super-ads-upgrade/SKILL.md +137 -0
- package/skills/super-ads-upgrade/references/upgrade-hops.md +26 -0
- package/skills/super-ads-upgrade/templates/changelog-template.md +39 -0
- package/skills/super-ads-add-placement/references/call-site-snippets.md +0 -90
- /package/skills/super-ads-ab-test/{references → templates}/firebase-handoff-template.md +0 -0
- /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
|
|
5
|
-
version: 1.
|
|
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
|
-
|
|
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
|
-
|
|
|
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
|
-
|
|
|
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
|
-
|
|
47
|
+
## 🏗️ Recommended Architecture
|
|
22
48
|
|
|
23
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
102
|
+
### 4. Call site
|
|
98
103
|
|
|
99
|
-
|
|
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
|
-
|
|
108
|
+
### 5. Kiểm trên máy
|
|
105
109
|
|
|
106
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
5
|
-
version: 1.
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
##
|
|
121
|
-
|
|
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`
|