@sayren/mcp 0.11.0 → 0.12.0

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
@@ -283,7 +283,7 @@ function describeWriteResult(result) {
283
283
 
284
284
  //#endregion
285
285
  //#region package.json
286
- var version = "0.11.0";
286
+ var version = "0.12.0";
287
287
 
288
288
  //#endregion
289
289
  //#region src/user-agent.ts
@@ -364,7 +364,7 @@ var AdminApi = class {
364
364
  headers,
365
365
  body: input.body === void 0 ? void 0 : JSON.stringify(input.body),
366
366
  redirect: "error",
367
- signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
367
+ signal: AbortSignal.timeout(input.timeoutMs ?? REQUEST_TIMEOUT_MS)
368
368
  });
369
369
  if (response.status === 204) return {
370
370
  ok: true,
@@ -930,7 +930,7 @@ function verifySources(files) {
930
930
  }
931
931
 
932
932
  //#endregion
933
- //#region src/verify.ts
933
+ //#region src/verify-report.ts
934
934
  const ruleOf = (ruleId) => RULES.find((rule) => rule.id === ruleId);
935
935
  function report(finding) {
936
936
  const rule = ruleOf(finding.ruleId);
@@ -949,23 +949,34 @@ function report(finding) {
949
949
  };
950
950
  }
951
951
  /** 위반을 고치는 순서 — 에이전트가 무엇부터 할지 묻지 않게 한다 */
952
- function nextSteps(findings) {
953
- if (!findings.length) return [
952
+ function nextSteps(findings, target) {
953
+ if (!findings.length) return target === "remote" ? [
954
+ "사용자에게 콘솔 스토어프론트 공간의 [미리보기 열기]로 화면을 확인해 달라고 전한다.",
955
+ "`create_version`으로 버전을 만들고 `get_build`로 빌드 결과를 확인한다.",
956
+ "정적 검사가 잡지 못하는 것은 실제 결제 한 번이 잡는다. 발행 전에 테스트 결제를 권한다."
957
+ ] : [
954
958
  "개발 서버를 띄워 홈에 상품이 보이는지 확인한다.",
955
959
  "테스트 결제로 주문을 한 번 만들어 주문 완료 화면까지 간다.",
956
960
  "정적 검사가 잡지 못하는 것은 실제 결제 한 번이 잡는다."
957
961
  ];
958
962
  const files = [...new Set(findings.map((finding) => finding.templateFile).filter(Boolean))];
963
+ const templateHint = target === "remote" ? `손대지 않아야 하는 파일을 고친 결과일 수 있다 — ${files.join(", ")}을(를) \`read_file\`로 읽어 규칙의 \`example\`과 대조하고 되돌린다.` : `손대지 않아야 하는 파일을 고친 결과일 수 있다 — \`get_template_file\`로 ${files.join(", ")}의 원본을 받아 대조한다.`;
959
964
  return [
960
965
  "위반마다 `fix`대로 고친다. `file`·`line`이 고칠 자리이고 `example`이 옳은 쪽 코드다.",
961
- ...files.length ? [`손대지 않아야 하는 파일을 고친 결과일 수 있다 — \`get_template_file\`로 ${files.join(", ")}의 원본을 받아 대조한다.`] : [],
962
- "고친 뒤 `verify_storefront`를 다시 부른다.",
966
+ ...files.length ? [templateHint] : [],
967
+ target === "remote" ? "고친 뒤 `verify_site`를 다시 부른다. 위반이 남으면 버전 빌드가 규칙 단계(`VERIFY`)에서 실패한다." : "고친 뒤 `verify_storefront`를 다시 부른다.",
963
968
  "규칙 배경이 더 필요하면 위반의 `docUrl` 문서를 읽는다."
964
969
  ];
965
970
  }
966
971
  /** 소스를 규칙과 대조해 고칠 수 있는 보고서로 만든다 */
967
- function buildReport(files) {
968
- const findings = verifySources(files);
972
+ function buildReport(files, target = "local") {
973
+ return reportFromFindings(verifySources(files), files.length, target);
974
+ }
975
+ /**
976
+ * 이미 찾은 위반으로 보고서를 만든다. 원격은 api가 작업 트리에서 `verifySources`를 돌려 위반만 돌려주고, 원인·수정
977
+ * 방법·예시는 이 패키지의 규칙 정의로 채운다.
978
+ */
979
+ function reportFromFindings(findings, checkedFiles, target = "local") {
969
980
  const counts = /* @__PURE__ */ new Map();
970
981
  for (const finding of findings) counts.set(finding.ruleId, (counts.get(finding.ruleId) ?? 0) + 1);
971
982
  const results = RULES.map((rule) => ({
@@ -977,7 +988,7 @@ function buildReport(files) {
977
988
  const reported = findings.map(report);
978
989
  return {
979
990
  ok: findings.length === 0,
980
- checkedFiles: files.length,
991
+ checkedFiles,
981
992
  summary: {
982
993
  rules: RULES.length,
983
994
  passed: RULES.length - violated,
@@ -987,9 +998,12 @@ function buildReport(files) {
987
998
  results,
988
999
  findings: reported,
989
1000
  message: findings.length ? `규칙 ${RULES.length}개 중 ${violated}개를 어겼습니다(위반 ${findings.length}건). 아래 findings의 fix대로 고친 뒤 다시 검사해주십시오` : `규칙 ${RULES.length}개를 모두 지켰습니다. 정적 검사가 잡지 못하는 것이 있으니 직접 띄워 결제까지 한 번 해보십시오`,
990
- nextSteps: nextSteps(reported)
1001
+ nextSteps: nextSteps(reported, target)
991
1002
  };
992
1003
  }
1004
+
1005
+ //#endregion
1006
+ //#region src/verify.ts
993
1007
  const SKIP = new Set([
994
1008
  "node_modules",
995
1009
  "dist",
@@ -1396,6 +1410,40 @@ const hostingTools = [
1396
1410
  })
1397
1411
  ];
1398
1412
 
1413
+ //#endregion
1414
+ //#region src/tools/storefront-guide.ts
1415
+ /**
1416
+ * 스토어프론트 템플릿을 고칠 때의 안내 — 로컬 `get_scaffold_plan`과 원격 `get_editing_guide`가 같은 값을 준다.
1417
+ * 로컬 사본과 호스팅 작업 트리는 같은 템플릿에서 나오므로 확장 지점·손대지 않을 곳이 같다. Node API를 쓰지 않는다.
1418
+ */
1419
+ /** 디자인을 바꿔도 되는 자리 */
1420
+ const EXTENSION_POINTS = [
1421
+ {
1422
+ what: "브랜드 색·서체·본문 폭",
1423
+ where: "src/theme.css의 @theme"
1424
+ },
1425
+ {
1426
+ what: "헤더·전역 내비",
1427
+ where: "src/components/site-header.tsx"
1428
+ },
1429
+ {
1430
+ what: "상품 카드",
1431
+ where: "src/components/product-card.tsx"
1432
+ },
1433
+ {
1434
+ what: "화면 추가",
1435
+ where: "src/routes/ 에 파일 추가(파일 기반 라우트, routeTree.gen.ts는 dev·build가 다시 만든다)"
1436
+ }
1437
+ ];
1438
+ /** 결제·세션·분석이 조용히 깨지는 자리 — 규칙 검사가 일부를 잡지만 전부는 아니다 */
1439
+ const DO_NOT_TOUCH = [
1440
+ "src/lib/payments.ts·src/lib/payment-options.ts·src/routes/checkout.return.tsx — 결제창 열기, 결제 복귀 결과 확인, 다른 결제수단 재시도(브라우저)",
1441
+ "src/lib/api.server.ts — 테넌트 헤더·토큰 전달·방문 식별 쿠키",
1442
+ "src/lib/session.server.ts·src/start.ts — 구매자 세션 쿠키와 요청마다 한 번 하는 토큰 갱신",
1443
+ "src/lib/analytics.ts — 방문 분석 시작(브라우저 한 번)과 시작 전 이벤트 큐",
1444
+ "라우트 loader가 서버 함수(createServerFn)로 데이터를 받는 구조"
1445
+ ];
1446
+
1399
1447
  //#endregion
1400
1448
  //#region src/tools/local-tools.ts
1401
1449
  const scaffoldTools = [
@@ -1423,31 +1471,8 @@ const scaffoldTools = [
1423
1471
  SAYREN_API_URL: deps.config.storefrontBaseUrl,
1424
1472
  SAYREN_STORE_CODE: "(get_store_context 참고)"
1425
1473
  },
1426
- extensionPoints: [
1427
- {
1428
- what: "브랜드 색·서체·본문 폭",
1429
- where: "src/theme.css의 @theme"
1430
- },
1431
- {
1432
- what: "헤더·전역 내비",
1433
- where: "src/components/site-header.tsx"
1434
- },
1435
- {
1436
- what: "상품 카드",
1437
- where: "src/components/product-card.tsx"
1438
- },
1439
- {
1440
- what: "화면 추가",
1441
- where: "src/routes/ 에 파일 추가(파일 기반 라우트, routeTree.gen.ts는 dev·build가 다시 만든다)"
1442
- }
1443
- ],
1444
- doNotTouch: [
1445
- "src/lib/payments.ts·src/lib/payment-options.ts·src/routes/checkout.return.tsx — 결제창 열기, 결제 복귀 결과 확인, 다른 결제수단 재시도(브라우저)",
1446
- "src/lib/api.server.ts — 테넌트 헤더·토큰 전달·방문 식별 쿠키",
1447
- "src/lib/session.server.ts·src/start.ts — 구매자 세션 쿠키와 요청마다 한 번 하는 토큰 갱신",
1448
- "src/lib/analytics.ts — 방문 분석 시작(브라우저 한 번)과 시작 전 이벤트 큐",
1449
- "라우트 loader가 서버 함수(createServerFn)로 데이터를 받는 구조"
1450
- ],
1474
+ extensionPoints: EXTENSION_POINTS,
1475
+ doNotTouch: DO_NOT_TOUCH,
1451
1476
  rules: RULES.map((rule) => ({
1452
1477
  ...rule,
1453
1478
  docUrl: docUrl(rule.doc)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sayren/mcp",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
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/store-sdk": "^0.19.0",
16
- "@sayren/storefront-sdk": "^0.15.0"
15
+ "@sayren/storefront-sdk": "^0.15.0",
16
+ "@sayren/store-sdk": "^0.19.0"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@biomejs/biome": "^2.5.14",
@@ -0,0 +1,45 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.5.14/schema.json",
3
+ "root": true,
4
+ "vcs": {
5
+ "enabled": true,
6
+ "clientKind": "git",
7
+ "useIgnoreFile": true
8
+ },
9
+ "files": {
10
+ "includes": [
11
+ "**",
12
+ "!**/node_modules",
13
+ "!**/dist",
14
+ "!**/.output",
15
+ "!**/.tanstack",
16
+ "!**/.nitro",
17
+ "!**/.vinxi",
18
+ "!**/.wrangler",
19
+ "!**/routeTree.gen.ts"
20
+ ]
21
+ },
22
+ "formatter": {
23
+ "enabled": true,
24
+ "indentStyle": "space",
25
+ "indentWidth": 2,
26
+ "lineWidth": 100
27
+ },
28
+ "linter": {
29
+ "enabled": true,
30
+ "rules": {
31
+ "preset": "recommended"
32
+ }
33
+ },
34
+ "javascript": {
35
+ "formatter": {
36
+ "quoteStyle": "double",
37
+ "semicolons": "always"
38
+ }
39
+ },
40
+ "css": {
41
+ "parser": {
42
+ "tailwindDirectives": true
43
+ }
44
+ }
45
+ }