codymaster 4.4.5 → 4.5.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.
Files changed (197) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +29 -14
  3. package/commands/demo.md +1 -1
  4. package/dist/context-bus.js +70 -0
  5. package/dist/context-db.js +265 -0
  6. package/dist/continuity.js +12 -0
  7. package/dist/file-watcher.js +79 -0
  8. package/dist/index.js +152 -1
  9. package/dist/l0-indexer.js +158 -0
  10. package/dist/mcp-context-server.js +400 -0
  11. package/dist/migrate-json-to-sqlite.js +126 -0
  12. package/dist/skill-chain.js +19 -3
  13. package/dist/token-budget.js +108 -0
  14. package/dist/uri-resolver.js +203 -0
  15. package/package.json +5 -1
  16. package/scripts/gate-0-secrets.js +63 -0
  17. package/scripts/gate-1-syntax.js +53 -0
  18. package/scripts/gate-5-dist-verify.js +55 -0
  19. package/scripts/gate-6-smoke-test.js +30 -0
  20. package/scripts/index-codebase.sh +552 -0
  21. package/scripts/mcp-bridge.js +284 -0
  22. package/scripts/postinstall.js +301 -0
  23. package/scripts/security-fixer.js +143 -0
  24. package/scripts/security-scan.js +55 -0
  25. package/scripts/test-gemini.js +13 -0
  26. package/scripts/todo-bridge.js +112 -0
  27. package/skills/_shared/helpers.md +50 -14
  28. package/skills/cm-autopilot/SKILL.md +29 -0
  29. package/skills/cm-autopilot/scripts/autopilot.py +190 -0
  30. package/skills/cm-continuity/SKILL.md +90 -28
  31. package/skills/cm-skill-chain/SKILL.md +47 -1
  32. package/skills/cm-start/SKILL.md +11 -2
  33. package/skills/boxme-git-config/SKILL.md +0 -56
  34. package/skills/boxme-local-dev/SKILL.md +0 -66
  35. package/skills/jobs-to-be-done/SKILL.md +0 -266
  36. package/skills/jobs-to-be-done/references/case-studies.md +0 -154
  37. package/skills/jobs-to-be-done/references/competitive-strategy.md +0 -280
  38. package/skills/jobs-to-be-done/references/diagnostics.md +0 -158
  39. package/skills/jobs-to-be-done/references/innovation-process.md +0 -392
  40. package/skills/jobs-to-be-done/references/organizational-change.md +0 -328
  41. package/skills/marketplace-report-crawler/SKILL.md +0 -176
  42. package/skills/marketplace-report-crawler/config/accounts.json +0 -41
  43. package/skills/marketplace-report-crawler/config/report-types.json +0 -422
  44. package/skills/marketplace-report-crawler/config/sessions.json +0 -3
  45. package/skills/marketplace-report-crawler/scripts/ab-wrapper.sh +0 -102
  46. package/skills/marketplace-report-crawler/scripts/browser-actions/lazada/lazada-actions.js +0 -114
  47. package/skills/marketplace-report-crawler/scripts/browser-actions/shopee/shopee-actions.js +0 -94
  48. package/skills/marketplace-report-crawler/scripts/browser-actions/tiktok/tiktok-actions.js +0 -272
  49. package/skills/marketplace-report-crawler/scripts/crawl-runner.js +0 -281
  50. package/skills/marketplace-report-crawler/scripts/session-check.sh +0 -72
  51. package/skills/marketplace-report-crawler/scripts/session-manager.sh +0 -349
  52. package/skills/marketplace-report-crawler/scripts/setup-folders.sh +0 -83
  53. package/skills/medical-research/SKILL.md +0 -194
  54. package/skills/medical-research/scripts/evidence_checker.py +0 -288
  55. package/skills/mom-test/SKILL.md +0 -267
  56. package/skills/mom-test/references/avoiding-bad-data.md +0 -221
  57. package/skills/mom-test/references/case-studies.md +0 -306
  58. package/skills/mom-test/references/commitment-advancement.md +0 -219
  59. package/skills/mom-test/references/finding-conversations.md +0 -251
  60. package/skills/mom-test/references/processing-learning.md +0 -256
  61. package/skills/mom-test/references/question-patterns.md +0 -198
  62. package/skills/pandasai-analytics/SKILL.md +0 -251
  63. package/skills/release-it/SKILL.md +0 -235
  64. package/skills/release-it/references/anti-patterns.md +0 -279
  65. package/skills/release-it/references/capacity-planning.md +0 -285
  66. package/skills/release-it/references/chaos-engineering.md +0 -325
  67. package/skills/release-it/references/deployment-strategies.md +0 -331
  68. package/skills/release-it/references/observability.md +0 -301
  69. package/skills/release-it/references/stability-patterns.md +0 -355
  70. package/skills/skill-creator-ultra/.agents/workflows/skill-audit.md +0 -37
  71. package/skills/skill-creator-ultra/.agents/workflows/skill-compare.md +0 -34
  72. package/skills/skill-creator-ultra/.agents/workflows/skill-export.md +0 -51
  73. package/skills/skill-creator-ultra/.agents/workflows/skill-generate.md +0 -39
  74. package/skills/skill-creator-ultra/.agents/workflows/skill-scaffold.md +0 -52
  75. package/skills/skill-creator-ultra/.agents/workflows/skill-simulate.md +0 -25
  76. package/skills/skill-creator-ultra/.agents/workflows/skill-stats.md +0 -31
  77. package/skills/skill-creator-ultra/.agents/workflows/skill-validate.md +0 -25
  78. package/skills/skill-creator-ultra/README.md +0 -1242
  79. package/skills/skill-creator-ultra/SKILL.md +0 -388
  80. package/skills/skill-creator-ultra/agents/analyzer.md +0 -274
  81. package/skills/skill-creator-ultra/agents/comparator.md +0 -202
  82. package/skills/skill-creator-ultra/agents/grader.md +0 -223
  83. package/skills/skill-creator-ultra/assets/eval_review.html +0 -146
  84. package/skills/skill-creator-ultra/eval-viewer/generate_review.py +0 -471
  85. package/skills/skill-creator-ultra/eval-viewer/viewer.html +0 -1325
  86. package/skills/skill-creator-ultra/examples/example_anthropic_frontend.md +0 -109
  87. package/skills/skill-creator-ultra/examples/example_anthropic_pdf.md +0 -116
  88. package/skills/skill-creator-ultra/examples/example_api_docs.md +0 -189
  89. package/skills/skill-creator-ultra/examples/example_db_migration.md +0 -253
  90. package/skills/skill-creator-ultra/examples/example_git_commit.md +0 -111
  91. package/skills/skill-creator-ultra/install.ps1 +0 -289
  92. package/skills/skill-creator-ultra/install.sh +0 -313
  93. package/skills/skill-creator-ultra/phases/phase1_interview.md +0 -202
  94. package/skills/skill-creator-ultra/phases/phase2_extract.md +0 -55
  95. package/skills/skill-creator-ultra/phases/phase3_detect.md +0 -57
  96. package/skills/skill-creator-ultra/phases/phase4_generate.md +0 -543
  97. package/skills/skill-creator-ultra/phases/phase5_test.md +0 -319
  98. package/skills/skill-creator-ultra/phases/phase6_eval.md +0 -301
  99. package/skills/skill-creator-ultra/phases/phase7_iterate.md +0 -103
  100. package/skills/skill-creator-ultra/phases/phase8_optimize.md +0 -113
  101. package/skills/skill-creator-ultra/resources/advanced_patterns.md +0 -499
  102. package/skills/skill-creator-ultra/resources/anti_patterns.md +0 -376
  103. package/skills/skill-creator-ultra/resources/blueprints.md +0 -498
  104. package/skills/skill-creator-ultra/resources/checklist.md +0 -243
  105. package/skills/skill-creator-ultra/resources/composition_cookbook.md +0 -291
  106. package/skills/skill-creator-ultra/resources/description_optimization.md +0 -90
  107. package/skills/skill-creator-ultra/resources/eval_guide.md +0 -133
  108. package/skills/skill-creator-ultra/resources/industry_questions.md +0 -189
  109. package/skills/skill-creator-ultra/resources/interview_questions.md +0 -200
  110. package/skills/skill-creator-ultra/resources/pattern_detection.md +0 -200
  111. package/skills/skill-creator-ultra/resources/prompt_engineering.md +0 -531
  112. package/skills/skill-creator-ultra/resources/schemas.md +0 -430
  113. package/skills/skill-creator-ultra/resources/script_integration.md +0 -593
  114. package/skills/skill-creator-ultra/resources/scripts_guide.md +0 -339
  115. package/skills/skill-creator-ultra/resources/skill_template.md +0 -124
  116. package/skills/skill-creator-ultra/resources/skill_writing_guide.md +0 -634
  117. package/skills/skill-creator-ultra/resources/versioning_guide.md +0 -193
  118. package/skills/skill-creator-ultra/scripts/ci_eval.py +0 -200
  119. package/skills/skill-creator-ultra/scripts/package_skill.py +0 -165
  120. package/skills/skill-creator-ultra/scripts/simulate_skill.py +0 -398
  121. package/skills/skill-creator-ultra/scripts/skill_audit.py +0 -611
  122. package/skills/skill-creator-ultra/scripts/skill_compare.py +0 -265
  123. package/skills/skill-creator-ultra/scripts/skill_export.py +0 -334
  124. package/skills/skill-creator-ultra/scripts/skill_scaffold.py +0 -403
  125. package/skills/skill-creator-ultra/scripts/skill_stats.py +0 -339
  126. package/skills/skill-creator-ultra/scripts/validate_skill.py +0 -411
  127. package/skills/tailwind-mastery/SKILL.md +0 -229
  128. package/skills/vercel-react-best-practices/AGENTS.md +0 -3373
  129. package/skills/vercel-react-best-practices/README.md +0 -123
  130. package/skills/vercel-react-best-practices/SKILL.md +0 -143
  131. package/skills/vercel-react-best-practices/rules/_sections.md +0 -46
  132. package/skills/vercel-react-best-practices/rules/_template.md +0 -28
  133. package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  134. package/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  135. package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  136. package/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  137. package/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  138. package/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  139. package/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  140. package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  141. package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  142. package/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  143. package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  144. package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  145. package/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  146. package/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  147. package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  148. package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  149. package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  150. package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  151. package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  152. package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  153. package/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  154. package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  155. package/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  156. package/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
  157. package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  158. package/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  159. package/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  160. package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  161. package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  162. package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  163. package/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  164. package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  165. package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  166. package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  167. package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  168. package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  169. package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  170. package/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
  171. package/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
  172. package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  173. package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  174. package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  175. package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  176. package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  177. package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  178. package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  179. package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  180. package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  181. package/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  182. package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  183. package/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
  184. package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  185. package/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
  186. package/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  187. package/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
  188. package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  189. package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  190. package/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  191. package/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  192. package/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  193. package/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  194. package/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
  195. package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  196. package/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  197. package/skills/web-design-guidelines/SKILL.md +0 -39
@@ -1,102 +0,0 @@
1
- #!/usr/bin/env bash
2
- # =============================================================================
3
- # ab-wrapper.sh — agent-browser thin wrapper
4
- # =============================================================================
5
- # Provides shorthand commands for marketplace report crawling.
6
- # Cross-agent compatible: any AI agent can call these commands.
7
- #
8
- # Usage:
9
- # ./ab-wrapper.sh login <platform> <brand-id> # Guided login
10
- # ./ab-wrapper.sh check <platform> <brand-id> # Check session
11
- # ./ab-wrapper.sh crawl <platform> <brand-id> <YYYYMM> # Crawl reports
12
- # ./ab-wrapper.sh open <platform> <brand-id> <url> # Open URL with session
13
- # ./ab-wrapper.sh snapshot <platform> <brand-id> # Get page snapshot
14
- # ./ab-wrapper.sh close <platform> <brand-id> # Close browser
15
- # =============================================================================
16
-
17
- set -euo pipefail
18
-
19
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
- PROFILE_ROOT="${MARKETPLACE_PROFILE_ROOT:-$HOME/.marketplace-crawler/profiles}"
21
- AB_CMD="${AGENT_BROWSER_CMD:-npx -y agent-browser}"
22
-
23
- get_profile_dir() {
24
- echo "$PROFILE_ROOT/${1}-${2}"
25
- }
26
-
27
- ensure_ab() {
28
- if ! command -v agent-browser &>/dev/null && ! npx -y agent-browser --version &>/dev/null 2>&1; then
29
- echo "❌ agent-browser not found. Installing..."
30
- npm install -g agent-browser 2>/dev/null || {
31
- echo "⚠️ Global install failed. Using npx (slower first run)."
32
- }
33
- fi
34
- }
35
-
36
- # --- Commands ---
37
-
38
- case "${1:-help}" in
39
- login)
40
- "$SCRIPT_DIR/session-manager.sh" login "$2" "$3"
41
- ;;
42
- check)
43
- "$SCRIPT_DIR/session-manager.sh" check "$2" "$3"
44
- ;;
45
- crawl)
46
- platform="$2"
47
- brand_id="$3"
48
- period="${4:-$(date -v-1m +%Y%m 2>/dev/null || date -d '-1 month' +%Y%m)}"
49
- echo "🕷️ Starting crawl: $platform / $brand_id / $period"
50
- node "$SCRIPT_DIR/crawl-runner.js" --plan --platform "$platform" --brand-id "$brand_id" --period "$period"
51
- ;;
52
- open)
53
- profile_dir=$(get_profile_dir "$2" "$3")
54
- mkdir -p "$profile_dir"
55
- $AB_CMD --profile "$profile_dir" open "$4"
56
- ;;
57
- snapshot)
58
- profile_dir=$(get_profile_dir "$2" "$3")
59
- $AB_CMD --profile "$profile_dir" snapshot -i --json
60
- ;;
61
- screenshot)
62
- profile_dir=$(get_profile_dir "$2" "$3")
63
- output="${4:-/tmp/marketplace-screenshot-$(date +%s).png}"
64
- $AB_CMD --profile "$profile_dir" screenshot "$output"
65
- echo "📸 Screenshot saved: $output"
66
- ;;
67
- close)
68
- profile_dir=$(get_profile_dir "$2" "$3")
69
- $AB_CMD --profile "$profile_dir" close 2>/dev/null || true
70
- echo "🔒 Browser closed for $2/$3"
71
- ;;
72
- exec)
73
- # Pass any agent-browser command with the correct profile
74
- profile_dir=$(get_profile_dir "$2" "$3")
75
- shift 3
76
- $AB_CMD --profile "$profile_dir" "$@"
77
- ;;
78
- help|*)
79
- echo ""
80
- echo "🕷️ ab-wrapper — Marketplace Browser Automation"
81
- echo "════════════════════════════════════════════════"
82
- echo ""
83
- echo "Session Management:"
84
- echo " login <platform> <brand-id> Guided login (headed browser)"
85
- echo " check <platform> <brand-id> Check session validity"
86
- echo ""
87
- echo "Crawling:"
88
- echo " crawl <platform> <brand-id> [YYYYMM] Generate & show crawl plan"
89
- echo ""
90
- echo "Browser Control:"
91
- echo " open <platform> <brand-id> <url> Open URL with saved session"
92
- echo " snapshot <platform> <brand-id> Get accessibility tree (JSON)"
93
- echo " screenshot <platform> <brand-id> [path] Take screenshot"
94
- echo " close <platform> <brand-id> Close browser"
95
- echo " exec <platform> <brand-id> <ab-args...> Run any agent-browser command"
96
- echo ""
97
- echo "Environment:"
98
- echo " MARKETPLACE_PROFILE_ROOT Default: ~/.marketplace-crawler/profiles"
99
- echo " AGENT_BROWSER_CMD Default: npx -y agent-browser"
100
- echo ""
101
- ;;
102
- esac
@@ -1,114 +0,0 @@
1
- /**
2
- * Lazada Browser Actions
3
- * ==================================================
4
- * JavaScript snippets to inject into Lazada Seller Center pages.
5
- */
6
-
7
- /**
8
- * Open calendar and go to the target month using next/prev buttons
9
- * Used for platform_income, platform_wallet
10
- */
11
- function lazadaCalendar_selectMonthRange(yearMonth) {
12
- // Try to find the date picker input
13
- const dateInputs = document.querySelectorAll('.next-date-picker-input input, input[placeholder*="YYYY"]');
14
- if (dateInputs.length > 0) {
15
- dateInputs[0].click(); // Open picker
16
-
17
- setTimeout(() => {
18
- // Find the 'Last Month' preset if it exists
19
- const presets = document.querySelectorAll('.next-date-picker-quick span');
20
- for (const preset of presets) {
21
- if (preset.textContent.trim() === 'Tháng trước' || preset.textContent.trim() === 'Last month') {
22
- preset.click();
23
- return;
24
- }
25
- }
26
-
27
- // Otherwise find the 'OK' button and click it to accept default (usually last 30 days)
28
- const okBtn = document.querySelector('.next-btn-primary');
29
- if (okBtn) okBtn.click();
30
- }, 500);
31
- }
32
- }
33
-
34
- /**
35
- * Lazada Paid Ads uses a specific date input format
36
- * Used for paid_ads_onsite_report, paid_ads_product
37
- */
38
- function lazadaAds_setDateRange(startDateStr, endDateStr) {
39
- // Check the 'Product' checkbox if needed for paid_ads_product
40
- const productCheckbox = document.querySelector('input[type="checkbox"][value="product"]');
41
- if (productCheckbox && !productCheckbox.checked) {
42
- productCheckbox.click();
43
- }
44
-
45
- // Find date inputs (DD/MM/YYYY format usually)
46
- const inputs = document.querySelectorAll('.next-input input');
47
- if (inputs.length >= 2) {
48
- // Start Date
49
- inputs[0].value = startDateStr;
50
- inputs[0].dispatchEvent(new Event('input', { bubbles: true }));
51
- inputs[0].dispatchEvent(new Event('change', { bubbles: true }));
52
-
53
- // End Date
54
- inputs[1].value = endDateStr;
55
- inputs[1].dispatchEvent(new Event('input', { bubbles: true }));
56
- inputs[1].dispatchEvent(new Event('change', { bubbles: true }));
57
- }
58
- }
59
-
60
- /**
61
- * Select from Lazada dropdown list
62
- * Used for shipping_fee_details
63
- */
64
- function lazadaMultiSelect_selectDates(targetYYYYMM) {
65
- // Find the dropdown button
66
- const dropdownTrigger = document.querySelector('.next-select-trigger');
67
- if (dropdownTrigger) {
68
- dropdownTrigger.click();
69
-
70
- setTimeout(() => {
71
- // Select logic
72
- const items = document.querySelectorAll('.next-menu-item');
73
- for(const item of items) {
74
- if(item.textContent.trim().includes(targetYYYYMM)) {
75
- item.click();
76
- }
77
- }
78
- }, 500);
79
- }
80
- }
81
-
82
- /**
83
- * Click export button on Lazada
84
- */
85
- function lazadaClickExport() {
86
- const buttons = document.querySelectorAll('button');
87
- for (const btn of buttons) {
88
- const text = btn.textContent.trim().toLowerCase();
89
- if (text.includes('tải xuống') || text.includes('xuất dữ liệu') || text.includes('export') || text.includes('download')) {
90
- btn.click();
91
-
92
- // Some export buttons open a dropdown. If so, look for Excel/PDF option.
93
- setTimeout(() => {
94
- const menuItems = document.querySelectorAll('.next-menu-item');
95
- for (const item of menuItems) {
96
- if (item.textContent.toLowerCase().includes('excel') || item.textContent.toLowerCase().includes('pdf')) {
97
- item.click();
98
- return true;
99
- }
100
- }
101
- }, 500);
102
-
103
- return true;
104
- }
105
- }
106
- return false;
107
- }
108
-
109
- module.exports = {
110
- lazadaCalendar_selectMonthRange,
111
- lazadaAds_setDateRange,
112
- lazadaMultiSelect_selectDates,
113
- lazadaClickExport
114
- };
@@ -1,94 +0,0 @@
1
- /**
2
- * Shopee Browser Actions
3
- * ==================================================
4
- * JavaScript snippets to inject into Shopee Seller pages.
5
- */
6
-
7
- /**
8
- * Select month range on Shopee's typical calendar-range picker
9
- * Used for platform_income, platform_wallet, ads_wallet_historical
10
- */
11
- function shopeeCalendar_selectMonthRange(yearMonth) {
12
- // Shopee usually has a date range input that opens a popper with two calendars.
13
- const dateRangeInputs = document.querySelectorAll('.shopee-date-range-picker input');
14
- if (dateRangeInputs.length > 0) {
15
- dateRangeInputs[0].click(); // Open picker
16
-
17
- setTimeout(() => {
18
- // Very naive approach: try to find 'THIS_MONTH' or 'LAST_MONTH' button
19
- // Or try to select the 1st and last day. Shopee's calendar is highly custom.
20
- const lastMonthBtn = Array.from(document.querySelectorAll('.shopee-popover span, .shopee-popover div')).find(el => el.textContent.trim() === 'Tháng trước' || el.textContent.trim() === 'Last Month');
21
- if (lastMonthBtn) {
22
- lastMonthBtn.click();
23
- }
24
- }, 500);
25
- }
26
- }
27
-
28
- /**
29
- * Select a specific month in a month-picker
30
- * Used for platform_report (PDF)
31
- */
32
- function shopeeMonthPicker_selectMonth(yearMonth) {
33
- const monthInput = document.querySelector('.shopeesc-month-picker, .month-picker-input');
34
- if (monthInput) {
35
- monthInput.click();
36
- setTimeout(() => {
37
- // Find the specific month cell
38
- const monthStr = parseInt(yearMonth.substring(4, 6), 10).toString();
39
- const cells = document.querySelectorAll('.month-cell, .shopee-month-table td');
40
- for (const cell of cells) {
41
- if (cell.textContent.trim() === monthStr || cell.textContent.trim().includes(`Tháng ${monthStr}`)) {
42
- cell.click();
43
- break;
44
- }
45
- }
46
- }, 500);
47
- }
48
- }
49
-
50
- /**
51
- * Input Start and End date directly into text inputs
52
- * Used for paid_ads_onsite_report (date_input)
53
- */
54
- function shopeeDateInput_setDate(startDateStr, endDateStr) {
55
- // Usually there are two inputs: start date and end date
56
- const inputs = document.querySelectorAll('.shopee-input__input[placeholder*="YYYY"], input[placeholder*="Ngày"]');
57
- if (inputs.length >= 2) {
58
- // Start date
59
- const startInput = inputs[0];
60
- startInput.value = startDateStr;
61
- startInput.dispatchEvent(new Event('input', { bubbles: true }));
62
- startInput.dispatchEvent(new Event('change', { bubbles: true }));
63
-
64
- // End date
65
- const endInput = inputs[1];
66
- endInput.value = endDateStr;
67
- endInput.dispatchEvent(new Event('input', { bubbles: true }));
68
- endInput.dispatchEvent(new Event('change', { bubbles: true }));
69
- }
70
- }
71
-
72
- /**
73
- * Click export button
74
- */
75
- function shopeeClickExport() {
76
- // Tries to find common export buttons
77
- const exportBtn = Array.from(document.querySelectorAll('button')).find(btn => {
78
- const text = btn.textContent.trim().toLowerCase();
79
- return text.includes('xuất') || text.includes('export') || text.includes('tải');
80
- });
81
-
82
- if (exportBtn) {
83
- exportBtn.click();
84
- return true;
85
- }
86
- return false;
87
- }
88
-
89
- module.exports = {
90
- shopeeCalendar_selectMonthRange,
91
- shopeeMonthPicker_selectMonth,
92
- shopeeDateInput_setDate,
93
- shopeeClickExport
94
- };
@@ -1,272 +0,0 @@
1
- /**
2
- * TikTok Browser Actions — Date Selection & Export
3
- * ==================================================
4
- * JavaScript snippets to inject into TikTok Seller Center pages.
5
- *
6
- * Extracted from Power Automate Desktop flow: "20260209 GBS Tiktok"
7
- *
8
- * TikTok uses:
9
- * 1. core-picker (TikTok Design System) — for Income, Wallet pages
10
- * 2. pulse-select — for pagination on Invoice page
11
- */
12
-
13
- // ============================================================================
14
- // TIKTOK INCOME / WALLET — core-picker date range
15
- // URL: https://seller-vn.tiktok.com/finance/transactions?shop_region=VN&tab=settled_tab
16
- // URL: https://seller-vn.tiktok.com/finance/withdraw-new
17
- // ============================================================================
18
-
19
- /**
20
- * Select first and last day of target month in TikTok core-picker
21
- * Used for TikTok Income and Wallet pages
22
- *
23
- * @param {string} yearMonth - Format: "YYYYMM" (e.g., "202602")
24
- */
25
- function tiktokCorePicker_selectMonthRange(yearMonth) {
26
- const lastDay = new Date(yearMonth.slice(0, 4), yearMonth.slice(4, 6), 0)
27
- .getDate().toString().padStart(2, '0');
28
-
29
- const cells = [...document.querySelectorAll('.core-picker-cell-in-view .core-picker-date-value')];
30
- const first = cells.find(c => c.textContent.trim() === '01');
31
- const last = cells.find(c => c.textContent.trim() === lastDay);
32
-
33
- first?.click();
34
- setTimeout(() => last?.click(), 100);
35
- }
36
-
37
- // ============================================================================
38
- // TIKTOK AFFILIATE INVOICE — Month picker + Table scraping
39
- // URL: https://seller-vn.tiktok.com/finance/invoice?shop_region=VN
40
- // ============================================================================
41
-
42
- /**
43
- * Select target month in TikTok month picker (Jan-Dec display)
44
- * Used for TikTok Affiliate Invoice page
45
- *
46
- * @param {string} yearMonth - Format: "YYYYMM" (e.g., "202602")
47
- */
48
- function tiktokMonthPicker_selectMonth(yearMonth) {
49
- const month = parseInt(yearMonth.substring(4, 6), 10);
50
- const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
51
- 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];
52
- const monthName = monthNames[month - 1];
53
-
54
- const cells = document.querySelectorAll('.core-picker-date-value');
55
- let targetCell = null;
56
-
57
- for (let i = 0; i < cells.length; i++) {
58
- if (cells[i].textContent.trim() === monthName) {
59
- targetCell = cells[i];
60
- break;
61
- }
62
- }
63
-
64
- if (targetCell) {
65
- targetCell.click();
66
- setTimeout(function() {
67
- targetCell.click(); // Double-click to confirm
68
- }, 300);
69
- }
70
- }
71
-
72
- /**
73
- * Set pagination to 50 items per page
74
- * Used on TikTok Affiliate Invoice page for large datasets
75
- */
76
- function tiktokPagination_set50PerPage() {
77
- const options = document.querySelectorAll('.pulse-select-option');
78
-
79
- for (let option of options) {
80
- const label = option.querySelector('.pulse-select-option-label-single');
81
- if (label && label.textContent.trim() === '50/Page') {
82
- option.click();
83
- return true;
84
- }
85
- }
86
- return false;
87
- }
88
-
89
- /**
90
- * Get max page number from TikTok pagination
91
- * @returns {number|null} Max page number
92
- */
93
- function tiktokPagination_getMaxPage() {
94
- const paginationElement = document.querySelector('.core-pagination-list');
95
- if (!paginationElement) return null;
96
-
97
- const pageItems = paginationElement.querySelectorAll('.core-pagination-item');
98
- let maxPage = 0;
99
-
100
- pageItems.forEach(item => {
101
- const text = item.textContent.trim();
102
- if (/^\d+$/.test(text)) {
103
- const pageNumber = parseInt(text, 10);
104
- if (pageNumber > maxPage) {
105
- maxPage = pageNumber;
106
- }
107
- }
108
- });
109
-
110
- return maxPage || null;
111
- }
112
-
113
- /**
114
- * Click next page button in TikTok pagination
115
- */
116
- function tiktokPagination_clickNext() {
117
- const element = document.querySelector('.core-pagination-item-next');
118
- if (!element) return;
119
-
120
- element.scrollIntoView({ behavior: 'smooth', block: 'center' });
121
-
122
- const rect = element.getBoundingClientRect();
123
- const x = rect.left + rect.width / 2;
124
- const y = rect.top + rect.height / 2;
125
-
126
- element.dispatchEvent(new MouseEvent('mousemove', {
127
- view: window, bubbles: true, cancelable: true, clientX: x, clientY: y
128
- }));
129
-
130
- element.dispatchEvent(new MouseEvent('click', {
131
- view: window, bubbles: true, cancelable: true, button: 0
132
- }));
133
- }
134
-
135
- // ============================================================================
136
- // HELPER — Scroll to bottom
137
- // ============================================================================
138
-
139
- function scrollToBottom() {
140
- window.scrollTo({
141
- top: document.body.scrollHeight,
142
- behavior: "smooth"
143
- });
144
- }
145
-
146
- // ============================================================================
147
- // BROWSER AGENT INSTRUCTIONS — TIKTOK COMPLETE FLOWS
148
- // ============================================================================
149
-
150
- /**
151
- * === TIKTOK PLATFORM INCOME ===
152
- * 1. Navigate to: https://seller-vn.tiktok.com/finance/transactions?shop_region=VN&tab=settled_tab
153
- * 2. Wait for text "Lịch sử xuất dữ liệu" to appear (up to 200s)
154
- * 3. Wait 1s
155
- * 4. Click "Xuất" button
156
- * 5. Wait 1s → Click SVG calendar icon to open date picker
157
- * 6. Wait 1s → Click another SVG to clear existing date
158
- * 7. Execute tiktokCorePicker_selectMonthRange(yearMonth)
159
- * 8. Wait 1s → Click "OK" button
160
- * 9. Wait 2s → Click "Xuất" (the export Span inside popup)
161
- * 10. Wait for "Đang xuất" text to disappear (up to 600s!)
162
- * 11. Wait 1s → Click "Tải xuống" button
163
- * 12. Save file as: {yearMonth}_{brand}_platform_income.xlsx
164
- *
165
- * === TIKTOK WALLET ===
166
- * 1. Navigate to: https://seller-vn.tiktok.com/finance/withdraw-new?is_new_connect=0&shop_region=VN
167
- * 2. Wait for "Lịch sử xuất dữ liệu" (up to 200s)
168
- * 3. Scroll down 500px
169
- * 4. Click "Xuất"
170
- * 5. Click SVG → clear → select date range (same as Income)
171
- * 6. Click OK → Click "Xuất" button
172
- * 7. Wait for "Đang xuất" to disappear (up to 600s)
173
- * 8. Click "Tải xuống"
174
- * 9. Save as: {yearMonth}_{brand}_platform_wallet.xlsx
175
- *
176
- * === TIKTOK AFFILIATE INVOICE ===
177
- * 1. Navigate to: https://seller-vn.tiktok.com/finance/invoice?shop_region=VN
178
- * 2. Wait for page load
179
- * 3. Click "Biên nhận hoa hồng liên kết"
180
- * 4. Wait 2s → Click SVG to open month picker
181
- * 5. Execute tiktokMonthPicker_selectMonth(yearMonth)
182
- * 6. Wait 3s → Click "OK"
183
- * 7. Check if "Nothing here at the moment" exists
184
- * - If yes: skip (no data)
185
- * - If no: continue below
186
- * 8. Scroll to bottom
187
- * 9. Click pagination dropdown → Execute tiktokPagination_set50PerPage()
188
- * 10. Get max page: tiktokPagination_getMaxPage()
189
- * 11. If single page: extract table → save as .xlsx
190
- * 12. If multiple pages: loop through pages:
191
- * a. Extract table data from current page
192
- * b. Save as: {yearMonth}_{brand}_affiliate_invoice_report_part_{pageNum}.xlsx
193
- * c. Click next: tiktokPagination_clickNext()
194
- * d. Wait 2s → repeat
195
- *
196
- * TABLE EXTRACTION CSS SELECTOR:
197
- * Rows: html > body > div:eq(0) > div:eq(1) > main > div:eq(0) >
198
- * div:eq(0) > div:eq(0) > div:eq(1) > div:eq(0) > div:eq(0) >
199
- * div:eq(0) > div:eq(0) > div:eq(2) > div:eq(0) > div:eq(0) >
200
- * div:eq(0) > div:eq(0) > div:eq(0) > table > tbody > tr
201
- *
202
- * Columns:
203
- * - td:eq(0) > div > span > div > div (Column 1)
204
- * - td:eq(1) > div > span (Column 2)
205
- * - td:eq(2) > div > span (Column 3)
206
- * - td:eq(3) > div > span (Column 4)
207
- * - td:eq(4) > div > span (Column 5)
208
- */
209
-
210
- // ============================================================================
211
- // TIKTOK ADS AND AFFILIATE ORDERS
212
- // ============================================================================
213
-
214
- /**
215
- * Handle TikTok Business Center (Ads) date picker
216
- * Used for ads_cost, ads_revenue
217
- */
218
- function tiktokAds_setDateRange(startDateStr, endDateStr) {
219
- // Usually involves clicking the date picker button
220
- const pickerBtn = document.querySelector('.byted-date-picker, .date-picker-trigger');
221
- if (pickerBtn) {
222
- pickerBtn.click();
223
- setTimeout(() => {
224
- // Very naive: find inputs or presets inside the popup
225
- // TikTok Business Center uses a complex React date picker
226
- const presets = document.querySelectorAll('.byted-picker-preset-item');
227
- for (const preset of presets) {
228
- if (preset.textContent.trim().includes('Last Month') || preset.textContent.trim().includes('Tháng trước')) {
229
- preset.click();
230
- break;
231
- }
232
- }
233
- }, 500);
234
- }
235
- }
236
-
237
- /**
238
- * Click typical TikTok export buttons
239
- */
240
- function tiktokClickExport() {
241
- const exportBtns = document.querySelectorAll('button');
242
- for (const btn of exportBtns) {
243
- const text = btn.textContent.trim().toLowerCase();
244
- if (text.includes('export') || text.includes('xuất') || text.includes('tải')) {
245
- btn.click();
246
- return true;
247
- }
248
- }
249
-
250
- // Also check divs/spans that act as buttons (TikTok uses these heavily)
251
- const allElements = document.querySelectorAll('div, span');
252
- for (const el of allElements) {
253
- const text = el.textContent.trim().toLowerCase();
254
- if ((text === 'export' || text === 'xuất' || text === 'tải xuống') && el.children.length === 0) {
255
- el.click();
256
- return true;
257
- }
258
- }
259
-
260
- return false;
261
- }
262
-
263
- module.exports = {
264
- tiktokCorePicker_selectMonthRange,
265
- tiktokMonthPicker_selectMonth,
266
- tiktokPagination_set50PerPage,
267
- tiktokPagination_getMaxPage,
268
- tiktokPagination_clickNext,
269
- scrollToBottom,
270
- tiktokAds_setDateRange,
271
- tiktokClickExport
272
- };