@sayren/mcp 0.1.2 → 0.1.3

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/dist/index.mjs CHANGED
@@ -529,6 +529,16 @@ const RULES = [
529
529
  title: "팝업 메시지는 origin과 source를 모두 검증한다",
530
530
  why: "검증 없이 받으면 아무 창이나 결제 완료를 흉내 낼 수 있다"
531
531
  },
532
+ {
533
+ id: "analytics-start",
534
+ title: "방문 분석은 브라우저에서 한 번 시작한다(`@sayren/storefront-sdk/analytics`)",
535
+ why: "빠지면 셀러 콘솔 애널리틱스가 비어 있다. 서버 파일에서 부르면 아무것도 하지 않는다"
536
+ },
537
+ {
538
+ id: "analytics-ids",
539
+ title: "서버의 API 클라이언트에 방문 식별 쿠키를 싣는다(`analyticsIdsFromCookie`)",
540
+ why: "빠지면 장바구니·결제 시작·구매가 방문과 이어지지 않아 퍼널과 유입별 매출에서 빠진다"
541
+ },
532
542
  {
533
543
  id: "closed-not-failed",
534
544
  title: "팝업이 결과 없이 닫히면 실패로 단정하지 않는다",
@@ -543,7 +553,7 @@ const CLIENT_FILE = /\.(ts|tsx)$/;
543
553
  const SERVER_FILE = /\.server\.(ts|tsx)$/;
544
554
  /**
545
555
  * 만들어진 프로젝트의 소스를 규칙과 대조한다. 정적 검사라 모든 문제를 잡지는 못하지만,
546
- * 이 아홉 가지는 실제로 반복해서 깨지는 것들이다.
556
+ * 여기 있는 것들은 실제로 반복해서 깨지는 것들이다.
547
557
  */
548
558
  function verifySources(files) {
549
559
  const findings = [];
@@ -554,7 +564,8 @@ function verifySources(files) {
554
564
  const has = (needle) => cleaned.some((file) => file.content.includes(needle));
555
565
  for (const file of cleaned) {
556
566
  if (!CLIENT_FILE.test(file.path)) continue;
557
- if (!(SERVER_FILE.test(file.path) || /\/(server|\.server)\//.test(file.path)) && /process\.env\.[A-Z_]/.test(file.content)) findings.push({
567
+ const isServer = SERVER_FILE.test(file.path) || /\/(server|\.server)\//.test(file.path);
568
+ if (!isServer && /process\.env\.[A-Z_]/.test(file.content)) findings.push({
558
569
  ruleId: "server-only-env",
559
570
  file: file.path,
560
571
  detail: "브라우저로 갈 수 있는 파일에서 process.env를 읽는다. `*.server.ts`로 옮긴다"
@@ -586,6 +597,16 @@ function verifySources(files) {
586
597
  detail: "message 리스너가 source(우리가 연 창)를 검증하지 않는다"
587
598
  });
588
599
  }
600
+ if (isServer && /createAnalytics\(/.test(file.content)) findings.push({
601
+ ruleId: "analytics-start",
602
+ file: file.path,
603
+ detail: "서버 파일에서 방문 분석을 시작한다. 서버에서는 아무것도 하지 않으니 브라우저(effect)에서 부른다"
604
+ });
605
+ if (isServer && /createStorefrontClient\(/.test(file.content) && !/analyticsIdsFromCookie|visitorId/.test(file.content)) findings.push({
606
+ ruleId: "analytics-ids",
607
+ file: file.path,
608
+ detail: "서버 API 클라이언트에 방문 식별자가 없다. `...analyticsIdsFromCookie(request.headers.get(\"cookie\"))`를 넘긴다"
609
+ });
589
610
  if (/requestPayment\(/.test(file.content) && /<form\s/.test(file.content)) findings.push({
590
611
  ruleId: "popup-client-submit",
591
612
  file: file.path,
@@ -602,6 +623,11 @@ function verifySources(files) {
602
623
  file: "(프로젝트 전체)",
603
624
  detail: "팝업이 결과 없이 닫힌 경우 결제 상태를 조회하는 코드가 없다"
604
625
  });
626
+ if (has("createStorefrontClient(") && !has("@sayren/storefront-sdk/analytics")) findings.push({
627
+ ruleId: "analytics-start",
628
+ file: "(프로젝트 전체)",
629
+ detail: "방문 분석을 시작하는 코드가 없다. `@sayren/storefront-sdk/analytics`의 createAnalytics를 브라우저에서 한 번 부른다"
630
+ });
605
631
  if (has("createStorefrontClient(") && !has("loader")) findings.push({
606
632
  ruleId: "loader-first",
607
633
  file: "(프로젝트 전체)",
@@ -674,7 +700,8 @@ server.registerTool("get_scaffold_plan", {
674
700
  ],
675
701
  doNotTouch: [
676
702
  "app/lib/payment-popup.ts — 결제 팝업 규칙",
677
- "app/lib/api.server.ts — 테넌트 헤더·토큰 전달·부모 origin",
703
+ "app/lib/api.server.ts — 테넌트 헤더·토큰 전달·부모 origin·방문 식별 쿠키",
704
+ "app/lib/analytics.ts — 방문 분석 시작(브라우저 한 번)과 시작 전 이벤트 큐",
678
705
  "loader에서 데이터를 받는 구조"
679
706
  ],
680
707
  rules: RULES,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sayren/mcp",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sayren-mcp": "./dist/index.mjs"
@@ -12,8 +12,8 @@
12
12
  "dependencies": {
13
13
  "@modelcontextprotocol/sdk": "^1.22.0",
14
14
  "zod": "^4.6.5",
15
- "@sayren/storefront-sdk": "^0.2.0",
16
- "@sayren/store-sdk": "^0.1.1"
15
+ "@sayren/store-sdk": "^0.3.0",
16
+ "@sayren/storefront-sdk": "^0.2.1"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@biomejs/biome": "^2.5.14",
@@ -7,8 +7,8 @@
7
7
  "zod": "^4.6.5"
8
8
  },
9
9
  "versions": {
10
- "@sayren/store-sdk": "0.1.1",
11
- "@sayren/storefront-sdk": "0.2.0",
10
+ "@sayren/store-sdk": "0.3.0",
11
+ "@sayren/storefront-sdk": "0.2.1",
12
12
  "@sayren/ui": "0.1.0"
13
13
  }
14
14
  }