codymaster 4.4.4 → 4.5.1

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 (190) 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 +7 -1
  16. package/skills/_shared/helpers.md +50 -14
  17. package/skills/cm-autopilot/SKILL.md +29 -0
  18. package/skills/cm-autopilot/scripts/autopilot.py +190 -0
  19. package/skills/cm-continuity/SKILL.md +90 -28
  20. package/skills/cm-quality-gate/SKILL.md +11 -1
  21. package/skills/cm-safe-deploy/SKILL.md +38 -2
  22. package/skills/cm-security-gate/SKILL.md +158 -34
  23. package/skills/cm-skill-chain/SKILL.md +47 -1
  24. package/skills/cm-start/SKILL.md +11 -2
  25. package/skills/cm-test-gate/SKILL.md +3 -0
  26. package/skills/boxme-git-config/SKILL.md +0 -56
  27. package/skills/boxme-local-dev/SKILL.md +0 -66
  28. package/skills/jobs-to-be-done/SKILL.md +0 -266
  29. package/skills/jobs-to-be-done/references/case-studies.md +0 -154
  30. package/skills/jobs-to-be-done/references/competitive-strategy.md +0 -280
  31. package/skills/jobs-to-be-done/references/diagnostics.md +0 -158
  32. package/skills/jobs-to-be-done/references/innovation-process.md +0 -392
  33. package/skills/jobs-to-be-done/references/organizational-change.md +0 -328
  34. package/skills/marketplace-report-crawler/SKILL.md +0 -176
  35. package/skills/marketplace-report-crawler/config/accounts.json +0 -41
  36. package/skills/marketplace-report-crawler/config/report-types.json +0 -422
  37. package/skills/marketplace-report-crawler/config/sessions.json +0 -3
  38. package/skills/marketplace-report-crawler/scripts/ab-wrapper.sh +0 -102
  39. package/skills/marketplace-report-crawler/scripts/browser-actions/lazada/lazada-actions.js +0 -114
  40. package/skills/marketplace-report-crawler/scripts/browser-actions/shopee/shopee-actions.js +0 -94
  41. package/skills/marketplace-report-crawler/scripts/browser-actions/tiktok/tiktok-actions.js +0 -272
  42. package/skills/marketplace-report-crawler/scripts/crawl-runner.js +0 -281
  43. package/skills/marketplace-report-crawler/scripts/session-check.sh +0 -72
  44. package/skills/marketplace-report-crawler/scripts/session-manager.sh +0 -349
  45. package/skills/marketplace-report-crawler/scripts/setup-folders.sh +0 -83
  46. package/skills/medical-research/SKILL.md +0 -194
  47. package/skills/medical-research/scripts/evidence_checker.py +0 -288
  48. package/skills/mom-test/SKILL.md +0 -267
  49. package/skills/mom-test/references/avoiding-bad-data.md +0 -221
  50. package/skills/mom-test/references/case-studies.md +0 -306
  51. package/skills/mom-test/references/commitment-advancement.md +0 -219
  52. package/skills/mom-test/references/finding-conversations.md +0 -251
  53. package/skills/mom-test/references/processing-learning.md +0 -256
  54. package/skills/mom-test/references/question-patterns.md +0 -198
  55. package/skills/pandasai-analytics/SKILL.md +0 -251
  56. package/skills/release-it/SKILL.md +0 -235
  57. package/skills/release-it/references/anti-patterns.md +0 -279
  58. package/skills/release-it/references/capacity-planning.md +0 -285
  59. package/skills/release-it/references/chaos-engineering.md +0 -325
  60. package/skills/release-it/references/deployment-strategies.md +0 -331
  61. package/skills/release-it/references/observability.md +0 -301
  62. package/skills/release-it/references/stability-patterns.md +0 -355
  63. package/skills/skill-creator-ultra/.agents/workflows/skill-audit.md +0 -37
  64. package/skills/skill-creator-ultra/.agents/workflows/skill-compare.md +0 -34
  65. package/skills/skill-creator-ultra/.agents/workflows/skill-export.md +0 -51
  66. package/skills/skill-creator-ultra/.agents/workflows/skill-generate.md +0 -39
  67. package/skills/skill-creator-ultra/.agents/workflows/skill-scaffold.md +0 -52
  68. package/skills/skill-creator-ultra/.agents/workflows/skill-simulate.md +0 -25
  69. package/skills/skill-creator-ultra/.agents/workflows/skill-stats.md +0 -31
  70. package/skills/skill-creator-ultra/.agents/workflows/skill-validate.md +0 -25
  71. package/skills/skill-creator-ultra/README.md +0 -1242
  72. package/skills/skill-creator-ultra/SKILL.md +0 -388
  73. package/skills/skill-creator-ultra/agents/analyzer.md +0 -274
  74. package/skills/skill-creator-ultra/agents/comparator.md +0 -202
  75. package/skills/skill-creator-ultra/agents/grader.md +0 -223
  76. package/skills/skill-creator-ultra/assets/eval_review.html +0 -146
  77. package/skills/skill-creator-ultra/eval-viewer/generate_review.py +0 -471
  78. package/skills/skill-creator-ultra/eval-viewer/viewer.html +0 -1325
  79. package/skills/skill-creator-ultra/examples/example_anthropic_frontend.md +0 -109
  80. package/skills/skill-creator-ultra/examples/example_anthropic_pdf.md +0 -116
  81. package/skills/skill-creator-ultra/examples/example_api_docs.md +0 -189
  82. package/skills/skill-creator-ultra/examples/example_db_migration.md +0 -253
  83. package/skills/skill-creator-ultra/examples/example_git_commit.md +0 -111
  84. package/skills/skill-creator-ultra/install.ps1 +0 -289
  85. package/skills/skill-creator-ultra/install.sh +0 -313
  86. package/skills/skill-creator-ultra/phases/phase1_interview.md +0 -202
  87. package/skills/skill-creator-ultra/phases/phase2_extract.md +0 -55
  88. package/skills/skill-creator-ultra/phases/phase3_detect.md +0 -57
  89. package/skills/skill-creator-ultra/phases/phase4_generate.md +0 -543
  90. package/skills/skill-creator-ultra/phases/phase5_test.md +0 -319
  91. package/skills/skill-creator-ultra/phases/phase6_eval.md +0 -301
  92. package/skills/skill-creator-ultra/phases/phase7_iterate.md +0 -103
  93. package/skills/skill-creator-ultra/phases/phase8_optimize.md +0 -113
  94. package/skills/skill-creator-ultra/resources/advanced_patterns.md +0 -499
  95. package/skills/skill-creator-ultra/resources/anti_patterns.md +0 -376
  96. package/skills/skill-creator-ultra/resources/blueprints.md +0 -498
  97. package/skills/skill-creator-ultra/resources/checklist.md +0 -243
  98. package/skills/skill-creator-ultra/resources/composition_cookbook.md +0 -291
  99. package/skills/skill-creator-ultra/resources/description_optimization.md +0 -90
  100. package/skills/skill-creator-ultra/resources/eval_guide.md +0 -133
  101. package/skills/skill-creator-ultra/resources/industry_questions.md +0 -189
  102. package/skills/skill-creator-ultra/resources/interview_questions.md +0 -200
  103. package/skills/skill-creator-ultra/resources/pattern_detection.md +0 -200
  104. package/skills/skill-creator-ultra/resources/prompt_engineering.md +0 -531
  105. package/skills/skill-creator-ultra/resources/schemas.md +0 -430
  106. package/skills/skill-creator-ultra/resources/script_integration.md +0 -593
  107. package/skills/skill-creator-ultra/resources/scripts_guide.md +0 -339
  108. package/skills/skill-creator-ultra/resources/skill_template.md +0 -124
  109. package/skills/skill-creator-ultra/resources/skill_writing_guide.md +0 -634
  110. package/skills/skill-creator-ultra/resources/versioning_guide.md +0 -193
  111. package/skills/skill-creator-ultra/scripts/ci_eval.py +0 -200
  112. package/skills/skill-creator-ultra/scripts/package_skill.py +0 -165
  113. package/skills/skill-creator-ultra/scripts/simulate_skill.py +0 -398
  114. package/skills/skill-creator-ultra/scripts/skill_audit.py +0 -611
  115. package/skills/skill-creator-ultra/scripts/skill_compare.py +0 -265
  116. package/skills/skill-creator-ultra/scripts/skill_export.py +0 -334
  117. package/skills/skill-creator-ultra/scripts/skill_scaffold.py +0 -403
  118. package/skills/skill-creator-ultra/scripts/skill_stats.py +0 -339
  119. package/skills/skill-creator-ultra/scripts/validate_skill.py +0 -411
  120. package/skills/tailwind-mastery/SKILL.md +0 -229
  121. package/skills/vercel-react-best-practices/AGENTS.md +0 -3373
  122. package/skills/vercel-react-best-practices/README.md +0 -123
  123. package/skills/vercel-react-best-practices/SKILL.md +0 -143
  124. package/skills/vercel-react-best-practices/rules/_sections.md +0 -46
  125. package/skills/vercel-react-best-practices/rules/_template.md +0 -28
  126. package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  127. package/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  128. package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  129. package/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  130. package/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  131. package/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  132. package/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  133. package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  134. package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  135. package/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  136. package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  137. package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  138. package/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  139. package/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  140. package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  141. package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  142. package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  143. package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  144. package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  145. package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  146. package/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  147. package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  148. package/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  149. package/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
  150. package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  151. package/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  152. package/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  153. package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  154. package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  155. package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  156. package/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  157. package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  158. package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  159. package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  160. package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  161. package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  162. package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  163. package/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
  164. package/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
  165. package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  166. package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  167. package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  168. package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  169. package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  170. package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  171. package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  172. package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  173. package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  174. package/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  175. package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  176. package/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
  177. package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  178. package/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
  179. package/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  180. package/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
  181. package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  182. package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  183. package/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  184. package/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  185. package/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  186. package/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  187. package/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
  188. package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  189. package/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  190. 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
- };