샌드박스 플러그인에는 모두 루트 디렉터리에 emdash-plugin.jsonc 파일이 있습니다. 플러그인이 npm 패키지이기도 하다면 package.json 옆에 둡니다. 매니페스트는 플러그인을 식별하고, 필요한 접근 권한과 스토리지를 선언하며, 레지스트리 목록과 릴리스에 쓰이는 정보를 제공합니다. 플러그인 CLI는 검증, 빌드, 번들링, 게시, 자동 릴리스 준비 시 이 파일을 읽습니다.
이 파일은 주석을 허용하는 JSON(JSONC)을 사용하므로 주석과 후행 쉼표를 쓸 수 있습니다. emdash-plugin init이 만든 $schema 속성은 그대로 두세요. 편집기는 생성된 스키마로 자동 완성을 제공하고, 전체 검사는 emdash-plugin validate가 수행합니다.
다음 예제에는 모든 필드 그룹이 들어 있습니다.
{
"$schema": "./node_modules/@emdash-cms/plugin-cli/schemas/emdash-plugin.schema.json",
"slug": "gallery",
"publisher": "did:plc:abc123def456",
"license": "MIT",
"author": { "name": "Jane Doe", "url": "https://example.com" },
"security": { "email": "[email protected]" },
"name": "Gallery",
"description": "Image galleries for EmDash content.",
"keywords": ["gallery", "images"],
"sections": {
"installation": { "file": "./docs/installation.md" },
"faq": { "file": "./docs/faq.md" },
},
"capabilities": ["content:read"],
"allowedHosts": [],
"storage": {
"galleries": { "indexes": ["contentId"] },
},
"admin": {
"pages": [{ "path": "/gallery", "label": "Gallery", "icon": "image" }],
},
"repo": "https://github.com/example/plugin-gallery",
"release": {
"requires": { "env:emdash": ">=0.37.0" },
"artifacts": {
"icon": { "file": "./images/icon.png" },
"screenshots": [{ "file": "./images/editor.png", "lang": "en" }],
},
},
}
식별 정보와 버전
| 필드 | 필수 | 규칙 |
|---|---|---|
slug | 예 | 소문자로 시작하고, 이후에는 소문자, 숫자, -, _를 사용할 수 있습니다. 최대 64자. |
publisher | 예 | Atmosphere 계정의 DID 또는 핸들. 핸들은 소유자가 바뀔 수 있으므로 DID를 권장합니다. |
version | 경우에 따라 | 빌드 메타데이터가 없는 Semver 2.0. package.json이 버전을 제공하면 생략할 수 있습니다. |
게시자와 슬러그가 레지스트리에서 패키지를 식별합니다. 슬러그는 플러그인 라우트 URL에도 쓰이므로 npm 패키지 이름이 아닙니다. @example/plugin-gallery 같은 패키지에는 gallery를 사용하세요.
버전 값은 한 곳에서만 관리
빌드는 version을 package.json#version과 대조합니다.
- 두 파일 모두 버전을 설정했다면 값이 일치해야 합니다.
- 한 파일만 버전을 설정했다면 빌드는 그 값을 사용합니다.
- 두 파일 모두 버전을 설정하지 않았다면 빌드가 실패합니다.
npm 패키지라면 버전은 package.json에 두고 매니페스트에서는 생략하세요. package.json이 없는 레지스트리 전용 플러그인은 매니페스트에 version을 설정해야 합니다.
패키지 프로필
패키지 프로필은 릴리스 전반에 걸쳐 표시되는 고정된 정보를 제공합니다.
| 필드 | 필수 | 규칙 |
|---|---|---|
license | 예 | 비어 있지 않은 SPDX 표현식. 최대 256자. |
author 또는 authors | 예 | 한 가지 형식만 사용하세요. author는 최대 64 문자소(grapheme)의 name과 선택적인 url 또는 email을 가집니다. authors는 1–32개 항목을 받습니다. |
security 또는 securityContacts | 예 | 한 가지 형식만 사용하세요. 각 연락처에는 email, url 또는 둘 다 있어야 하며, 목록은 1–8개 항목을 받습니다. |
name | 아니요 | 표시 이름. 최대 100 문자소. 없으면 슬러그가 사용됩니다. |
description | 아니요 | 짧은 설명. 최대 140 문자소. |
keywords | 아니요 | 비어 있지 않은 문자열 최대 5개. 각각 64 문자소 이하. |
sections | 아니요 | description, installation, faq, changelog, security용 긴 CommonMark 섹션. |
각 섹션은 인라인 문자열이거나 매니페스트를 기준으로 한 상대 경로의 파일 참조일 수 있습니다.
"sections": {
"description": "A longer description written in CommonMark.",
"installation": { "file": "./docs/installation.md" },
"security": { "file": "./SECURITY.md" },
}
확인된 각 섹션은 20,000바이트와 2,000 문자소로 제한됩니다. 파일 참조는 매니페스트 디렉터리 안에 있어야 하며, 절대 경로나 디렉터리를 벗어나는 .. 경로는 거부됩니다.
publish는 첫 릴리스에서 패키지 프로필을 만듭니다. 이후 릴리스는 프로필 필드를 교체하지 않습니다. 게시된 프로필을 편집하려면 emdash-plugin update-package를 사용하세요. 이 명령은 기본적으로 변경 사항을 미리 보여 주기만 하고, --yes를 지정할 때만 기록합니다.
신뢰 계약
신뢰 계약은 capabilities, allowedHosts, storage로 이루어집니다. 이 필드들은 플러그인이 무엇에 접근할 수 있고 어떤 플러그인 소유 컬렉션을 만드는지를 운영자에게 알려 줍니다.
다음 선언은 콘텐츠 읽기를 허용하고, 하나의 API와 그 하위 도메인으로의 요청을 허용하며, 스토리지 컬렉션 하나를 만듭니다.
"capabilities": ["content:read", "network:request"],
"allowedHosts": ["api.example.com", "*.cdn.example.com"],
"storage": {
"events": {
"indexes": ["savedAt", ["collection", "savedAt"]],
"uniqueIndexes": ["eventId"],
},
}
Capability와 호스트
세 필드 모두 기본값은 비어 있습니다. 스캐폴드는 빈 값을 명시적으로 기록하므로, 검토자는 플러그인이 추가 접근 권한이나 컬렉션을 요청하지 않는다는 것을 알 수 있습니다.
network:request에는 allowedHosts에 와일드카드 없는 호스트 이름이 하나 이상 필요합니다. network:request:unrestricted는 의도적으로 모든 공개 호스트를 허용하므로 빈 목록이어야 합니다. Capability와 보안은 모든 capability, 그 영향, 호스트 패턴, 런타임 강제 적용에 대한 기준 참조 문서입니다.
스토리지
storage의 각 키는 플러그인 소유 컬렉션 하나를 지정합니다. indexes와 uniqueIndexes가 플러그인이 어떤 필드로 필터링하거나 정렬할 수 있는지를 결정합니다. 스토리지에서 컬렉션 이름, 인덱스 설계, 쿼리, 페이지네이션을 설명합니다.
신뢰 계약의 어느 부분이든 바꾸려면 새 플러그인 버전이 필요합니다. 이미 설치한 사이트는 이전 선언에 동의했기 때문입니다. 계약을 넓힐 때는 메이저 버전을 올리세요.
관리자 페이지와 위젯
샌드박스 플러그인은 Block Kit으로 관리자 페이지와 대시보드 위젯을 렌더링합니다. 매니페스트에서 이들이 나타날 위치를 선언합니다.
"admin": {
"pages": [{ "path": "/settings", "label": "Settings", "icon": "settings" }],
"widgets": [{ "id": "recent-events", "title": "Recent events", "size": "half" }],
}
페이지 경로는 /로 시작하며 문자, 숫자, /, _, -를 포함할 수 있습니다. 위젯 ID는 플러그인 슬러그와 같은 소문자 식별자 문자를 사용합니다. 위젯 크기는 full, half, third 중 하나입니다.
페이지에는 group을 설정하여 접을 수 있는 사이드바 폴더에 넣을 수도 있습니다. 일치 여부는 대소문자를 구분하며 앞뒤 공백은 무시됩니다. 사이드바에 표시되는 컬렉션의 그룹과 일치하는 그룹을 지정하면 해당 페이지가 그 폴더에 들어갑니다. 그 밖의 같은 그룹을 공유하는 페이지는 어떤 플러그인의 것이든 Plugins 섹션에서 그 레이블의 폴더를 구성합니다.
페이지나 위젯을 선언한 플러그인은 src/plugin.ts에 admin이라는 이름의 라우트를 정의해야 합니다. 이 라우트가 없으면 EmDash가 Block Kit 응답을 얻기 위해 호출할 대상이 없으므로 번들 검사가 실패합니다.
릴리스 필드
release는 특정 버전을 설명합니다. 최상위 repo URL은 릴리스 레코드에 기록되며, 자동 릴리스 설정에서도 패키지 프로필을 GitHub 리포지토리에 연결하는 데 쓰입니다.
| 필드 | 용도 |
|---|---|
repo | 소스 리포지토리의 HTTPS URL. 자동 릴리스 설정에는 표준 형식의 공개 GitHub 리포지토리 URL이 필요합니다. |
release.requires | 호스트 요구 사항. 키는 env:<name> 또는 패키지 DID이고, 값은 semver 범위입니다. |
release.artifacts.icon | 릴리스 아이콘으로 표시되는 이미지. |
release.artifacts.banner | 릴리스 목록용 배너 이미지. |
release.artifacts.screenshots | 최대 8개 항목의 순서가 있는 스크린샷 갤러리. |
env:emdash와 env:astro로 해당 릴리스를 설치할 수 있는 EmDash와 Astro 버전 범위를 설정합니다.
"release": {
"requires": {
"env:emdash": ">=0.37.0",
"env:astro": ">=5.0.0 <7.0.0",
},
}
EmDash는 설치 전에 이러한 요구 사항을 확인합니다. 잘못된 범위는 매니페스트 검증에 실패하며, 호환되지 않는 릴리스는 설치되지 않습니다.
아티팩트 파일 경로는 매니페스트 기준의 상대 경로이며 해당 디렉터리 안에 있어야 합니다. PNG, JPEG, WebP를 지원합니다. 각 파일은 1 MiB, 가로·세로 각각 8,192픽셀 이하로 제한됩니다. 선택적인 lang 속성은 BCP 47 언어 태그로 현지화된 이미지를 식별합니다. 게시할 때 이 파일들은 플러그인 번들과 별도로 업로드되며, 측정된 유형, 크기, 체크섬, 개인 데이터 서버(PDS) blob 참조가 기록됩니다.
퍼블리셔 고정
publisher는 잘못된 Atmosphere 계정에서 실수로 게시하는 것을 막아 줍니다. 계정의 DID를 쓰는 것이 좋습니다.
"publisher": "did:plc:abc123def456", // jane.example.com
게시하거나 자동 릴리스를 준비하기 전에 CLI는 매니페스트의 퍼블리셔를 현재 세션과 비교합니다. 핸들은 비교를 위해 현재 DID로 확인됩니다. 일치하지 않으면 MANIFEST_PUBLISHER_MISMATCH로 실패하며, 이를 무시하는 플래그는 없습니다.
잘못된 세션이 활성화되어 있다면 emdash-plugin whoami를 실행한 다음 고정된 계정으로 전환하세요.
emdash-plugin switch did:plc:abc123def456
패키지를 다른 계정으로 이전할 때만 매니페스트의 퍼블리셔를 변경하세요.
매니페스트 검증
빌드하거나 게시하기 전에 매니페스트를 검증하세요.
emdash-plugin validate
다른 매니페스트를 검증하려면 파일이나 디렉터리를 전달하세요.
emdash-plugin validate ./packages/plugin-gallery
검증은 오프라인으로 수행됩니다. 중복된 속성, 알 수 없는 필드, 잘못된 값, 함께 쓸 수 없는 형식, 그리고 allowedHosts 목록이 비어 있는데 network:request를 쓴 경우처럼 여러 필드에 걸친 오류를 보고합니다.