pabal-web-mcp 1.3.13 → 1.4.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.
@@ -1252,6 +1252,9 @@ ${researchSections.join("\n")}
1252
1252
 
1253
1253
  `;
1254
1254
  }
1255
+ prompt += `**Priority:** When both iOS and Android research exist, keep iOS keywords first and only add Android keywords if there is room after meeting character limits.
1256
+
1257
+ `;
1255
1258
  prompt += `## Step 2: Optimize All Fields (${primaryLocale})
1256
1259
 
1257
1260
  `;
@@ -1445,9 +1448,12 @@ ${optimizedPrimary}
1445
1448
  const hasPrimaryResearch = primaryResearchSections.length > 0;
1446
1449
  prompt += `## Keyword Research (Per Locale)
1447
1450
 
1451
+ `;
1452
+ prompt += `When both iOS and Android research exist for a locale, treat iOS keywords as primary; use Android keywords only if space remains after fitting iOS keywords within character limits.
1453
+
1448
1454
  `;
1449
1455
  if (hasPrimaryResearch) {
1450
- prompt += `**\u{1F4DA} ENGLISH (${primaryLocale}) Keywords - Use as fallback for locales without research:**
1456
+ prompt += `**\u{1F4DA} ENGLISH (${primaryLocale}) Keywords - Use as fallback for locales without research (MUST TRANSLATE to target language):**
1451
1457
  ${primaryResearchSections.join("\n")}
1452
1458
 
1453
1459
  `;
@@ -1466,35 +1472,42 @@ ${researchSections.join(
1466
1472
 
1467
1473
  `;
1468
1474
  } else if (hasPrimaryResearch) {
1469
- prompt += `### Locale ${loc}: \u26A0\uFE0F No saved research - USE ENGLISH (${primaryLocale}) KEYWORDS
1475
+ prompt += `### Locale ${loc}: \u26A0\uFE0F No saved research - TRANSLATE ENGLISH KEYWORDS TO ${loc.toUpperCase()}
1470
1476
  `;
1471
1477
  prompt += `No keyword research found at ${researchDir}.
1472
1478
  `;
1473
- prompt += `**FALLBACK:** Translate English keywords from primary locale (${primaryLocale}) into ${loc}:
1479
+ prompt += `**CRITICAL FALLBACK STRATEGY:** You MUST translate English keywords from primary locale (${primaryLocale}) into ${loc}. DO NOT use English keywords directly.
1480
+
1481
+ `;
1482
+ prompt += `**Translation Steps:**
1483
+ `;
1484
+ prompt += `1. Take the Tier 1/2/3 keywords from English research above (${primaryLocale})
1474
1485
  `;
1475
- prompt += `1. Take the Tier 1/2/3 keywords from English research above
1486
+ prompt += `2. **TRANSLATE each English keyword into ${loc}** - use natural, native expressions (NOT literal word-for-word translation)
1476
1487
  `;
1477
- prompt += `2. Translate each English keyword naturally into ${loc} (not literal translation)
1488
+ prompt += `3. Ensure translated keywords are what ${loc} users would actually search for in their language
1478
1489
  `;
1479
- prompt += `3. Use native expressions that ${loc} users would actually search for
1490
+ prompt += `4. Verify translations are culturally appropriate and contextually relevant
1480
1491
  `;
1481
- prompt += `4. Verify translations are culturally appropriate
1492
+ prompt += `5. Apply the **TRANSLATED** keywords (in ${loc} language) following the same tier strategy
1482
1493
  `;
1483
- prompt += `5. Apply translated keywords following the same tier strategy
1494
+ prompt += `6. **DO NOT use English keywords in ${loc} locale** - all keywords must be in ${loc} language
1484
1495
 
1485
1496
  `;
1486
1497
  } else {
1487
- prompt += `### Locale ${loc}: \u26A0\uFE0F No research - USE ENGLISH KEYWORDS FROM optimizedPrimary
1498
+ prompt += `### Locale ${loc}: \u26A0\uFE0F No research - TRANSLATE ENGLISH KEYWORDS FROM optimizedPrimary TO ${loc.toUpperCase()}
1488
1499
  `;
1489
- prompt += `No keyword research found. Extract keywords from the optimizedPrimary JSON above and translate them:
1500
+ prompt += `No keyword research found. Extract keywords from the optimizedPrimary JSON above and **TRANSLATE them to ${loc}**:
1490
1501
  `;
1491
- prompt += `1. Extract keywords from \`aso.keywords\` in optimizedPrimary
1502
+ prompt += `1. Extract keywords from \`aso.keywords\` in optimizedPrimary (these are in English/${primaryLocale})
1492
1503
  `;
1493
- prompt += `2. Translate each English keyword naturally into ${loc}
1504
+ prompt += `2. **TRANSLATE each English keyword naturally into ${loc}** - use native search expressions
1494
1505
  `;
1495
- prompt += `3. Use native expressions that ${loc} users would actually search for
1506
+ prompt += `3. Ensure translated keywords match what ${loc} users would actually search for
1496
1507
  `;
1497
- prompt += `4. Apply translated keywords to all ASO fields
1508
+ prompt += `4. Apply the **TRANSLATED** keywords (in ${loc} language) to all ASO fields
1509
+ `;
1510
+ prompt += `5. **DO NOT use English keywords in ${loc} locale** - all keywords must be translated to ${loc}
1498
1511
 
1499
1512
  `;
1500
1513
  }
@@ -1503,6 +1516,8 @@ ${researchSections.join(
1503
1516
 
1504
1517
  `;
1505
1518
  prompt += `For EACH locale:
1519
+ `;
1520
+ prompt += `- Priority: Keep iOS-sourced keywords first; add Android keywords only if there is remaining space after iOS keywords fit within field limits.
1506
1521
  `;
1507
1522
  prompt += `1. Take the TRANSLATED content (below)
1508
1523
  `;
@@ -1581,9 +1596,9 @@ ${researchSections.join(
1581
1596
  `;
1582
1597
  prompt += `Process EACH locale in this batch sequentially:
1583
1598
  `;
1584
- prompt += `1. Use saved keyword research OR translate from primary locale if missing (see fallback strategy above)
1599
+ prompt += `1. Use saved keyword research (in target language) OR **TRANSLATE English keywords from primary locale** if missing (see fallback strategy above - MUST translate, not use English directly)
1585
1600
  `;
1586
- prompt += `2. Replace keywords in ALL fields:
1601
+ prompt += `2. Replace keywords in ALL fields (use translated keywords in target language):
1587
1602
  `;
1588
1603
  prompt += ` - \`aso.keywords\` array
1589
1604
  `;
@@ -1639,11 +1654,11 @@ ${researchSections.join(
1639
1654
  `;
1640
1655
  prompt += `**1. Keyword Source**
1641
1656
  `;
1642
- prompt += ` - If saved research exists: Cite file(s) used; list selected top 10 keywords
1657
+ prompt += ` - If saved research exists: Cite file(s) used; list selected top 10 keywords (in target language)
1643
1658
  `;
1644
- prompt += ` - If using fallback: List translated keywords from primary locale with translation rationale
1659
+ prompt += ` - If using fallback: List **TRANSLATED** keywords from primary locale (English \u2192 target language) with translation rationale
1645
1660
  `;
1646
- prompt += ` - Show final 10 keywords in target language with tier assignments
1661
+ prompt += ` - Show final 10 keywords **IN TARGET LANGUAGE** with tier assignments - DO NOT show English keywords
1647
1662
 
1648
1663
  `;
1649
1664
  prompt += `**2. Updated JSON** (complete locale structure with keyword replacements)
@@ -1801,6 +1816,12 @@ Parse error: ${data.parseError}
1801
1816
  lines.push("\n----");
1802
1817
  return lines.join("\n");
1803
1818
  }
1819
+ function getPlatformPriority(platform) {
1820
+ const normalized = (platform || "").toLowerCase();
1821
+ if (normalized === "ios") return 0;
1822
+ if (normalized === "android") return 1;
1823
+ return 2;
1824
+ }
1804
1825
  function mergeKeywordData(entries) {
1805
1826
  const merged = {
1806
1827
  tier1_core: [],
@@ -1815,7 +1836,12 @@ function mergeKeywordData(entries) {
1815
1836
  const seenKeywords = /* @__PURE__ */ new Set();
1816
1837
  const seenGaps = /* @__PURE__ */ new Set();
1817
1838
  const seenPatterns = /* @__PURE__ */ new Set();
1818
- for (const entry of entries) {
1839
+ const entriesByPriority = [...entries].sort((a, b) => {
1840
+ const aPriority = getPlatformPriority(extractMeta(a.data).platform);
1841
+ const bPriority = getPlatformPriority(extractMeta(b.data).platform);
1842
+ return aPriority - bPriority;
1843
+ });
1844
+ for (const entry of entriesByPriority) {
1819
1845
  if (entry.data?.parseError) continue;
1820
1846
  const meta = extractMeta(entry.data);
1821
1847
  if (meta.platform && !merged.platforms.includes(meta.platform)) {
@@ -1872,8 +1898,15 @@ function mergeKeywordData(entries) {
1872
1898
  }
1873
1899
  function formatMergedData(merged, researchDir) {
1874
1900
  const lines = [];
1875
- lines.push(`### Combined Keyword Research (${merged.platforms.join(" + ")})`);
1901
+ const hasIos = merged.platforms.some(
1902
+ (platform) => platform && platform.toLowerCase() === "ios"
1903
+ );
1904
+ const platformLabel = merged.platforms.length > 0 ? merged.platforms.join(" + ") : "Unknown";
1905
+ lines.push(
1906
+ `### Combined Keyword Research (${platformLabel})${hasIos ? " \u2014 iOS prioritized" : ""}`
1907
+ );
1876
1908
  lines.push(`Source: ${researchDir}`);
1909
+ lines.push(`Priority: iOS > Android > others (use Android only after iOS keywords fit character limits)`);
1877
1910
  if (merged.tier1_core.length > 0) {
1878
1911
  lines.push(`
1879
1912
  **Tier 1 (Core - use in title/subtitle):** ${merged.tier1_core.join(", ")}`);
@@ -2004,7 +2037,7 @@ This tool returns a PROMPT containing:
2004
2037
 
2005
2038
  ## KEYWORD SOURCES
2006
2039
  - Uses SAVED keyword research from .aso/keywordResearch/products/[slug]/locales/
2007
- - iOS and Android research are automatically combined
2040
+ - iOS and Android research are automatically combined (iOS prioritized; Android fills remaining slots when limits apply)
2008
2041
  - If locale research is missing, use English keywords and translate
2009
2042
 
2010
2043
  **CRITICAL:** Only processes existing locale files. Does NOT create new files.`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pabal-web-mcp",
3
- "version": "1.3.13",
3
+ "version": "1.4.1",
4
4
  "type": "module",
5
5
  "description": "MCP server for ASO data management with shared types and utilities",
6
6
  "author": "skyu",