sayren Docs

CLI로 호스팅 사이트 고치기

npx sayren init·pull·deploy로 호스팅 사이트를 만들고 소스를 받아 로컬에서 고치고 배포하기

스토어프론트 호스팅으로 운영 중인 사이트의 소스를 내 컴퓨터로 받아 고치고, 명령 하나로 다시 배포할 수 있습니다. 상점 플랫폼 편집·원격 MCP의 AI 편집과 같은 작업 트리를 씁니다. 어느 쪽에서 고쳐도 사이트의 소스는 하나입니다.

npx sayren login                                        # Sayren 계정으로 로그인
npx sayren init                                         # 사이트가 없으면: 템플릿을 골라 만들고 받기
npx sayren pull --project <storeId>                     # 사이트가 있으면: 소스 받기
cd <상점 코드>
npm install --ignore-scripts && npm run dev             # 로컬에서 확인
npx sayren deploy                                       # 검사 → 로컬 빌드 → 올리기 → 빌드 → 발행

직접 호스팅할 쇼핑몰을 새로 만들 때는 MCP로 쇼핑몰 만들기의 템플릿을 씁니다. sayren CLI는 sayren이 호스팅 중인 사이트({slug}.sayren.co)의 소스를 다룹니다.

준비

  • Node.js 20 이상
  • 호스팅 사이트. 없으면 npx sayren init이나 상점 플랫폼 스토어프론트에서 만듭니다
  • Sayren 계정. npx sayren login으로 로그인합니다. storeId는 상점 플랫폼 개발자 › 개요 › 연결 정보 › 스토어프론트 CLI에 명령째 나옵니다
  • sayren CLI 0.3.0 이상(init·배포 전 로컬 빌드는 0.4.0). npx sayren은 최신 버전을 씁니다

Sayren 계정으로 로그인

npx sayren login은 브라우저를 열어 Sayren 계정으로 로그인합니다. 처음에는 CLI가 쓸 권한과 상점 범위를 묻는 화면이 나오고, 허용하면 터미널로 돌아옵니다(인증과 계정 토큰).

npx sayren login            # 브라우저 로그인
npx sayren login --device   # 브라우저가 없는 환경(SSH 등) — 표시된 주소와 코드를 다른 기기에서 입력
npx sayren login --paste    # 액세스 토큰을 입력받아 저장(셸 기록에 남지 않음)
npx sayren whoami           # 로그인한 계정과 상점 범위
npx sayren logout           # 로그아웃(저장한 로그인 정보를 지움)
  • 로그인 정보는 프로젝트 폴더가 아니라 사용자 설정 폴더(~/.config/sayren/credentials.json, Windows는 %APPDATA%\sayren\)에 저장합니다. 파일 권한은 본인만 읽을 수 있게 둡니다.
  • 상점은 --store → SAYREN_STORE_ID 환경 변수 → 이 폴더의 상태 → 계정의 소속 상점 순서로 고릅니다. 소속 상점이 여럿이면 고르라고 묻습니다.
  • 로그인한 폴더의 .mcp.json에는 원격 MCP 주소와 X-Store-Id만 쓰고 토큰은 쓰지 않습니다. AI 도구가 처음 연결할 때 스스로 로그인합니다.
  • CI처럼 브라우저가 없는 곳은 액세스 토큰을 SAYREN_TOKEN에 넣고 SAYREN_STORE_ID를 함께 줍니다. 권한에는 stores:read·store:r·storefront:rw를 넣습니다.
  • 옛 API 토큰(sy_pat_…)은 더 이상 쓸 수 없습니다. 넣으면 CLI가 API에 보내지 않고 로그인하라고 안내합니다.

사이트 만들기 — init

상점에 호스팅 사이트가 없으면 init으로 템플릿을 골라 만들고, 만든 사이트의 소스를 pull과 같은 폴더로 받습니다.

npx sayren init                                  # 템플릿을 고르고 확인한 뒤 만듭니다
npx sayren init my-shop --template basic --yes   # 비대화형(CI·AI 에이전트)
  1. 템플릿 목록(GET /v1/storefront/templates)에서 고릅니다. 대화형이 아니면 --template <id>가 필요합니다.
  2. 만들 내용을 보여 주고 확인을 묻습니다(비대화형은 --yes). 사이트 만들기는 상점당 30일에 3번까지입니다.
  3. 사이트를 만듭니다(POST /v1/storefront/site). 주소는 상점 코드({상점 코드}.sayren.co)이고 오픈 준비중으로 시작합니다.
  4. 소스를 폴더(기본: 상점 코드)로 받고 pull과 같은 .mcp.json·.env·.sayren/state.json을 씁니다.
옵션뜻
[폴더]받을 폴더. 비어 있지 않으면 만들기 전에 멈춥니다
--template <id>템플릿 id. 비대화형은 필수입니다
--store <storeId>사이트를 만들 상점. 소속 상점이 여럿이면 고르라고 묻습니다
--yes만들기 확인을 묻지 않습니다

상점에 이미 사이트가 있으면 만들지 않고 npx sayren pull --project <storeId>를 안내합니다. 상점당 사이트는 하나이고, 템플릿은 만들 때만 고릅니다. 다른 주소로 만들려면 상점 플랫폼 스토어프론트에서 만듭니다. 만들려면 상점 OWNER·ADMIN이어야 하고 토큰에 storefront:rw가 있어야 합니다(npx sayren login의 토큰에는 들어 있습니다).

소스 받기 — pull

npx sayren login
npx sayren pull --project store_abc123

토큰은 --token으로 줄 수도 있지만 셸 기록·프로세스 목록에 남습니다. login이나 SAYREN_TOKEN을 쓰십시오.

지금 사이트의 작업 트리를 폴더(기본: 상점 코드)로 받습니다. 상점 플랫폼 편집 환경이 열려 있으면 그 순간의 내용을 받습니다. 받은 폴더에는 세 파일이 생깁니다. 셋 다 커밋하지 않습니다(pull이 .gitignore에 더합니다). 배포에도 올리지 않습니다.

파일내용
.mcp.jsonsayren 원격 MCP 연결 설정. 주소와 상점 id만 들어 있고 토큰은 없습니다
.env로컬 개발 서버가 읽는 값
.sayren/state.json상점·사이트, 받은 작업 트리(baseRef)
.mcp.json
{
  "mcpServers": {
    "sayren": {
      "type": "http",
      "url": "https://mcp.sayren.app/mcp",
      "headers": { "X-Store-Id": "store_abc123" }
    }
  }
}
# .env
SAYREN_API_URL=https://api.sayren.app/storefront/v1
SAYREN_STORE_CODE=mystore

.mcp.json은 Claude Code 형식입니다. 이 폴더에서 연 AI 에이전트가 처음 연결할 때 Sayren 계정으로 로그인하고 sayren 원격 MCP에 붙습니다. 이미 .mcp.json이 있으면 sayren 항목만 바꾸고 다른 서버는 그대로 둡니다. sayren 항목에 옛 API 토큰(Bearer sy_pat_…) 헤더가 있으면 지웁니다. 직접 넣은 액세스 토큰 헤더는 그대로 둡니다.

--project는 토큰의 상점 범위 안이어야 합니다. 이미 파일이 있는 폴더에는 받지 않습니다. 같은 사이트를 받은 폴더(.sayren/state.json이 있는 폴더)에서 --force를 주면 원격 작업 트리로 다시 받습니다. 지울 파일과 덮어쓸 파일을 먼저 보여 주고 확인을 묻습니다(비대화형은 --yes). .env는 SAYREN_API_URL·SAYREN_STORE_CODE만 갱신하고 다른 줄은 둡니다. .mcp.json은 sayren 항목만 갱신합니다. node_modules는 그대로 둡니다. 원격의 package.json·vite.config.ts가 바뀌었으면 알려 줍니다.

pull은 .gitignore에 .mcp.json·.sayren/을 더합니다. 원격의 .gitignore에 이 줄이 없던 사이트는 받은 직후 .gitignore가 바뀐 상태이고, 다음 deploy가 이 변경도 올립니다.

저장소에서 clone한 폴더

.sayren/state.json은 커밋하지 않으므로 사이트 소스를 git 저장소로 관리하면 clone한 폴더에는 상태 파일이 없고 deploy가 멈춥니다. 이 폴더를 원격 작업 트리에 맞추고 받은 폴더로 쓰려면 아래를 실행합니다. 로컬 변경은 먼저 커밋·백업합니다. 확인을 묻고, 비대화형은 --yes를 줍니다.

npx sayren pull --force --project store_abc123 --dir .

CLI 0.1로 받은 폴더(.sayrenrc, .env의 SAYREN_TOKEN)는 다음 명령을 실행할 때 한 번 정리합니다. .sayrenrc는 .sayren/state.json으로 옮기고, .env의 옛 API 토큰 줄은 지웁니다. git에 커밋된 .sayrenrc는 지우지 않으니 커밋에서 지웁니다.

로컬에서 확인하기

npm install --ignore-scripts && npm run dev로 http://localhost:4010에 띄웁니다. --ignore-scripts는 의존성의 설치 스크립트를 돌리지 않습니다. 다른 사람이나 AI가 바꾼 package.json을 받았을 때 특히 권합니다. 운영 상점의 상품·주문 데이터로 동작합니다. 테스트 결제는 localhost 복귀가 허용됩니다. 계정 토큰은 .env에 없으므로 사이트 코드가 읽을 수 없습니다.

화면 구조와 고칠 때 지킬 규칙은 쇼핑몰 화면 고치기와 같습니다. npx sayren verify로 배포 전과 같은 검사를 미리 돌립니다.

배포 — deploy

npx sayren deploy --message "메인 배너 교체"
  1. 로컬 검사 — 생성 규칙과 경로·크기 한도를 봅니다. 서버 빌드가 실패할 것을 먼저 알립니다.
  2. 로컬 빌드 — 의존성이 설치돼 있으면(node_modules가 있으면) package.json의 build 스크립트(vite build)를 npm run build로 돌립니다. 실패하면 빌드 출력의 마지막 줄들을 보여 주고 올리지 않습니다. 의존성을 설치하지 않은 폴더는 알리고 건너뜁니다. --skip-build로 끕니다.
  3. 올리기 — 바뀐 파일만 올려 작업 트리를 바꿉니다. src/·public/·messages/·루트 설정 파일(vite.config.ts·tsconfig.json 등)· package.json·pnpm-lock.yaml만 올리고 .env·.mcp.json·.sayren/·node_modules·빌드 결과는 올리지 않습니다.
  4. 빌드 — 서버가 규칙 검증 → 타입 검사 → 빌드를 합니다. 로컬 빌드 결과는 쓰지 않습니다. 단계별 진행이 표시되고, 실패하면 실패 단계와 로그 꼬리를 보여 줍니다.
  5. 발행 — 빌드가 끝나면 곧바로 발행하고 주소를 알립니다. 반영까지 1분 안팎이 걸립니다.
옵션뜻
--no-publish버전까지만 만듭니다. 상점 플랫폼 스토어프론트 › 버전에서 발행합니다
--skip-build올리기 전 로컬 빌드를 건너뜁니다. 서버 빌드는 그대로 합니다
--message <메모>버전 메모
--force원격 변경·열린 편집 환경이 있어도 이 폴더 내용으로 덮어씁니다. 확인을 묻습니다
--yes--force의 확인을 묻지 않습니다(CI 등)

종료 코드는 0 성공, 1 실패, 3 발행 승인 대기입니다.

다른 곳에서 고쳤을 때

pull 뒤에 상점 플랫폼이나 AI가 같은 사이트를 고쳤으면 deploy는 덮어쓰지 않고 멈춥니다(SOURCE_CHANGED). 로컬 변경을 커밋·백업한 뒤 npx sayren pull --force로 다시 받아 합치거나, 이 폴더 내용이 맞다면 npx sayren deploy --force로 덮어씁니다.

상점 플랫폼 편집 환경이 열려 있어도 멈춥니다(EDIT_SESSION_OPEN). 편집을 끝내고 다시 시도하거나 --force로 편집 환경을 끄고 진행합니다. 끌 때 그 편집은 작업 트리에 저장되므로, 이어서 SOURCE_CHANGED가 나면 위처럼 합칩니다.

npm 의존성

npm에 공개된 패키지를 자유롭게 더할 수 있습니다. 올릴 때 서버가 설치 트리 전체를 검사하고, 보안 권고(high·critical)나 악성 코드로 알려진 버전, 설치할 패키지를 확인할 수 없는 경우는 올리지 않습니다(409 DEPENDENCY_REJECTED, CLI가 패키지·버전·사유를 보여 줍니다). 경고(moderate 이하 권고, 설치 스크립트 등)는 올리기를 막지 않습니다. 판정 규칙은 스토어프론트 호스팅의 의존성 절을 보십시오.

빌드는 pnpm-lock.yaml대로 설치하므로 의존성 버전을 바꾸면 pnpm install로 잠금 파일을 함께 갱신합니다. npm install만으로 바꾸면 package-lock.json만 바뀌어 빌드의 설치 단계에서 실패합니다. CLI가 배포 전에 이 어긋남을 경고합니다.

AI 에이전트 토큰

AI 에이전트용 액세스 토큰으로 deploy를 돌리면 올리기·빌드는 되고 발행은 승인을 기다립니다. package.json이나 vite.config.ts를 바꾸는 올리기도 승인을 기다립니다. CLI는 승인 요청 링크를 알리고 종료 코드 3으로 끝납니다. 셀러가 상점 플랫폼에서 승인하면 그 버전이 발행되거나(발행) 작업 트리가 바뀝니다(올리기 — 이어서 deploy를 다시 돌리면 빌드·발행합니다).

그 밖의 명령

명령하는 일
npx sayren init템플릿을 골라 사이트를 만들고 소스를 받습니다(사이트 만들기)
npx sayren status사이트 주소·상태, 발행 버전과 만든 경로, 최근 빌드, 편집 환경
npx sayren verify로컬 검사(규칙·경로·크기)만 합니다
npx sayren loginSayren 계정으로 로그인하고 지금 폴더의 .mcp.json을 원격 MCP 설정으로 맞춥니다
npx sayren whoami쓰는 계정, 토큰 종류, 상점 범위
npx sayren logout로그인을 폐기하고 이 컴퓨터의 토큰을 지웁니다

토큰은 --token → SAYREN_TOKEN 환경 변수 → 로그인 정보(npx sayren login) 순서로 읽습니다. .env와 .mcp.json에서는 읽지 않습니다. 상점은 --store → SAYREN_STORE_ID 순서로 고르고, 없으면 폴더 상태나 토큰의 상점 범위로 정합니다. api 주소는 기본 https://api.sayren.app이고, 다른 주소는 https만 받습니다. .env·.sayren/state.json에서 읽은 다른 주소는 토큰이 그곳으로 가므로 확인을 묻고, 비대화형이면 --api-origin으로 명시해야 합니다. 원격 MCP는 기본 api에만 연결되므로 다른 주소를 쓰는 폴더의 .mcp.json은 연결되지 않습니다.

한도

항목값
파일 하나1MiB
작업 트리 전체20MiB·파일 2,000개
배포(작업 트리 바꾸기)상점당 1분에 30번
한 번에 올리는 새 파일800개(넘으면 나눠서 배포)
동시 빌드사이트당 1개

관련 API

CLI는 관리 API를 부릅니다. 직접 만들 때는 아래 순서입니다(관리 API 레퍼런스). init은 먼저 GET /v1/storefront/templates와 POST /v1/storefront/site(templateId)로 사이트를 만듭니다.

  1. GET /v1/storefront/site/source — 지금 작업 트리(sourceRef)와 압축 파일 조각 수
  2. GET /v1/storefront/site/source/archive?sourceRef=&part= — 압축 파일(tar.gz) 조각
  3. PUT /v1/storefront/site/source — 바꾼 뒤 파일 목록(경로·해시·크기)과 package.json·pnpm-lock.yaml 내용(packageJson·lockfile). 서버에 없는 내용은 409 SOURCE_BLOBS_MISSING이 알려 주고, POST /v1/storefront/site/source/blobs로 올린 뒤 다시 보냅니다. expectedBaseRef가 지금과 다르면 409 SOURCE_CHANGED입니다
  4. POST /v1/storefront/site/versions(expectedSourceRef) → GET /v1/storefront/site/builds/{buildId} → POST /v1/storefront/site/versions/{versionId}/publish

이 페이지 목차