정적 분석 · CI · AI 요약 · 원격 Mac · 2026

2026 OpenClaw 프론트 실전:
원격 Mac 게이트웨이에서 ESLint·Stylelint JSON → 단일 PR 요약

2026-04-27 프론트 팀 · CI + AI 요약 약 8분 읽기

대상: 정적 검사를 CI 게이트AI 릴리스 요약에 같이 넣는 프론트 팀. OpenClaw게이트웨이가 Git 옆에서 ESLint JSON·Stylelint JSON만 받아 한 덩어리 PR 요약을 만듭니다. 토큰·시크릿은 E2E 토큰 요약, 수정 플로우는 ESLint·Stylelint 수정 브랜치와 연계하세요. 브라우저 단계 전에 린트 JSON을 두면 단계 분리가 쉽고 Playwright 샤드 병합 글과 순서가 맞습니다. 아래 표와 스크립트만 맞추면 팀마다 같은 재현 절차를 갖습니다.

키워드: OpenClaw · ESLint JSON · Stylelint · 원격 Mac · PR 요약

통증 터미널과 PR 본문이 어긋나면 릴리스 신뢰가 깨집니다. 절대 경로 차이로 게이트가 중복·누락을 냅니다. 429·5xx를 린트 실패와 섞으면 재시도가 엉킵니다. 원격 Mac에 Node 22+를 고정하면 로컬·CI 편차가 줄어듭니다.

신호 하드 실패 PR 한 줄
ESLint severity 2 오류 합 > 0
Stylelint 경고 다수 예산 초과 시만 남은 경고 예산
코멘트 API 429·5xx 아니오 백오프 재시도

00 HowTo: 재현 순서

원격 Mac 셸에서도 동일 순서로 재현하세요.

  1. Node 22+·engines 고정.
  2. ESLint·Stylelint 각각 JSON 파일 출력.
  3. CI가 SHA·PR 번호와 리포트를 게이트웨이로 전달.
  4. 게이트웨이가 병합·임계·exit·Git 댓글 API.
  5. AI 단계는 병합 요약 경로만 읽기.

01 로컬·CI 출력 형식 통일

TTY 기본 포맷 대신 -f json·--formatter json-o로 경로 고정. 게이트웨이에서 REPO_ROOT로 절대→상대 변환하면 PR 줄이 안정적입니다.

package.json 스크립트 (Node 22+)

{
  "engines": { "node": ">=22" },
  "scripts": {
    "lint:eslint:json": "mkdir -p .openclaw/reports && eslint . -f json -o .openclaw/reports/eslint.json",
    "lint:stylelint:json": "mkdir -p .openclaw/reports && stylelint \"**/*.{css,scss}\" --formatter json -o .openclaw/reports/stylelint.json",
    "lint:json:all": "npm run lint:eslint:json && npm run lint:stylelint:json"
  }
}

02 게이트웨이 집계·임계

재실행 없이 JSON 병합 → lint_gate.json·Markdown. 상위 규칙·파일 N개만 노출. 릴리스 브랜치는 경고 예산 엄격히. 게이트웨이에서만 정책을 바꾸면 저장소 설정을 건드리지 않고도 롤아웃 속도를 조절할 수 있습니다.

merge 예시 (Node 22 ESM)

import { readFile, writeFile } from "node:fs/promises";

const root = process.env.REPO_ROOT ?? "";
const strip = (p) => (p && p.startsWith(root) ? p.slice(root.length + 1) : p);

const eslint = JSON.parse(await readFile(".openclaw/reports/eslint.json", "utf8"));
const style = JSON.parse(await readFile(".openclaw/reports/stylelint.json", "utf8"));

const rows = [];
for (const f of Array.isArray(eslint) ? eslint : []) {
  for (const m of f.messages ?? []) {
    rows.push({ tool: "eslint", file: strip(f.filePath), rule: m.ruleId ?? "syntax", sev: m.severity });
  }
}
for (const f of Array.isArray(style) ? style : []) {
  for (const w of f.warnings ?? []) {
    rows.push({ tool: "stylelint", file: strip(f.source), rule: w.rule ?? "unknown", sev: w.severity });
  }
}

const gate = {
  version: 1,
  errors: rows.filter((r) => r.sev === 2 || r.sev === "error").length,
  warnings: rows.filter((r) => r.sev === 1 || r.sev === "warning").length,
  topRules: []
};
await writeFile(".openclaw/reports/lint_gate.json", JSON.stringify(gate, null, 2));

topRules는 팀 리듀서로 채우고 스키마 버전과 AI 프롬프트를 같이 올리세요.

03 재시도·절단

429·5xx만 백오프·지터 재시도. 린트 실패는 재시도 금지. PR 본문은 규칙당 파일·총 줄 상한 후 “절단됨” 한 줄. 로그인형 비공개 preview URL은 쓰지 마세요.

셸 래퍼

#!/usr/bin/env bash
set -euo pipefail
attempt=0 max=4
until node tools/post-pr-lint-summary.mjs; do
  code=$?
  attempt=$((attempt + 1))
  if [[ "$code" -eq 77 ]] && [[ "$attempt" -lt "$max" ]]; then
    sleep $((2 ** attempt + RANDOM % 3))
    continue
  fi
  exit "$code"
done

04 Git 댓글 API (비공개 URL 없음)

issue/review comment + HTML 주석 마커로 멱등 갱신. 본문엔 공개 문서·job id만. 토큰은 게이트웨이 시크릿. OpenClaw는 제공자별 얇은 어댑터로 충분합니다.

한 줄로 정리

경로 계약+JSON 병합을 한곳에 두면 PR 요약이 오류·상위 규칙·절단 목록·통과를 한눈에 보여 CI와 AI가 같은 수치를 봅니다.

· 도움말 · 블로그 목록 · 요금

애플 실리콘 시아이 호스트

Node 22+·OpenClaw 게이트를 전용 원격 Mac에

WebKit 스모크와 린트 JSON을 한 호스트에 두면 경로·바이너리가 안정적입니다. 구매에서 플랜 선택 후 결제를 마치세요. 도움말··블로그는 공개 안내입니다.

린트 게이트용 원격 맥 구매