pabal-web-mcp 1.3.1 → 1.3.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.
@@ -2448,6 +2448,9 @@ var keywordResearchInputSchema = z6.object({
2448
2448
  writeTemplate: z6.boolean().default(false).describe("If true, write a JSON template at the output path."),
2449
2449
  researchData: z6.string().trim().optional().describe(
2450
2450
  "Optional JSON string with research results (e.g., from mcp-appstore tools). If provided, saves it to the output path."
2451
+ ),
2452
+ researchDataPath: z6.string().trim().optional().describe(
2453
+ "Optional path to a JSON file containing research results. If set, file content is saved to the output path (preferred to avoid escape errors)."
2451
2454
  )
2452
2455
  });
2453
2456
  var jsonSchema6 = zodToJsonSchema6(keywordResearchInputSchema, {
@@ -2545,7 +2548,8 @@ async function handleKeywordResearch(input) {
2545
2548
  competitorApps = [],
2546
2549
  filename,
2547
2550
  writeTemplate = false,
2548
- researchData
2551
+ researchData,
2552
+ researchDataPath
2549
2553
  } = input;
2550
2554
  const { config, locales } = loadProductLocales(slug);
2551
2555
  const primaryLocale = resolvePrimaryLocale(config, locales);
@@ -2608,16 +2612,34 @@ async function handleKeywordResearch(input) {
2608
2612
  const fileName = filename || defaultFileName;
2609
2613
  let outputPath = path11.join(researchDir, fileName);
2610
2614
  let fileAction;
2611
- if (writeTemplate || researchData) {
2612
- const payload = researchData ? (() => {
2613
- try {
2614
- return JSON.parse(researchData);
2615
- } catch (err) {
2615
+ const parseJsonWithContext = (text) => {
2616
+ try {
2617
+ return JSON.parse(text);
2618
+ } catch (err) {
2619
+ const message = err instanceof Error ? err.message : String(err);
2620
+ const match = /position (\d+)/i.exec(message) || /column (\d+)/i.exec(message) || /char (\d+)/i.exec(message);
2621
+ if (match) {
2622
+ const pos = Number(match[1]);
2623
+ const start = Math.max(0, pos - 40);
2624
+ const end = Math.min(text.length, pos + 40);
2625
+ const context = text.slice(start, end);
2616
2626
  throw new Error(
2617
- `Failed to parse researchData JSON: ${err instanceof Error ? err.message : String(err)}`
2627
+ `Failed to parse researchData JSON: ${message}
2628
+ Context around ${pos}: ${context}`
2618
2629
  );
2619
2630
  }
2620
- })() : buildTemplate({
2631
+ throw new Error(`Failed to parse researchData JSON: ${message}`);
2632
+ }
2633
+ };
2634
+ const loadResearchDataFromPath = (p) => {
2635
+ if (!fs11.existsSync(p)) {
2636
+ throw new Error(`researchDataPath not found: ${p}`);
2637
+ }
2638
+ const raw = fs11.readFileSync(p, "utf-8");
2639
+ return parseJsonWithContext(raw);
2640
+ };
2641
+ if (writeTemplate || researchData) {
2642
+ const payload = researchData ? parseJsonWithContext(researchData) : researchDataPath ? loadResearchDataFromPath(researchDataPath) : buildTemplate({
2621
2643
  slug,
2622
2644
  locale,
2623
2645
  platform,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pabal-web-mcp",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "type": "module",
5
5
  "description": "MCP server for ASO data management with shared types and utilities",
6
6
  "author": "skyu",