@clack-platform/cli 0.1.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.
Files changed (4) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +302 -0
  3. package/dist/cli.js +4810 -0
  4. package/package.json +64 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ MIT 라이선스
2
+
3
+ 저작권 (c) 2026 CLACK Inc.
4
+
5
+ 이 소프트웨어와 관련 문서 파일(이하 "소프트웨어")의 사본을 취득하는 모든 사람에게,
6
+ 소프트웨어의 사용, 복제, 수정, 병합, 발행, 배포, 재라이선스 및 사본 판매 권한을 포함하여
7
+ 제한 없이 소프트웨어를 취급하고 소프트웨어를 제공받은 사람에게도 이를 허용할 권한을
8
+ 아래 조건에 따라 무상으로 부여합니다.
9
+
10
+ 위 저작권 표시와 이 허가 표시는 소프트웨어의 모든 사본 또는 실질적인 부분에 포함되어야 합니다.
11
+
12
+ 소프트웨어는 상품성, 특정 목적 적합성 및 권리 비침해에 대한 보증을 포함하여 명시적이거나
13
+ 묵시적인 어떠한 보증도 없이 "있는 그대로" 제공됩니다. 저작자 또는 저작권자는 계약,
14
+ 불법행위 또는 그 밖의 법적 근거와 관계없이 소프트웨어 또는 그 사용이나 기타 취급으로
15
+ 인하여 발생하거나 이와 관련된 어떠한 청구, 손해 또는 기타 책임도 부담하지 않습니다.
package/README.md ADDED
@@ -0,0 +1,302 @@
1
+ # 클랙 CLI
2
+
3
+ 클랙 계정의 프로필·상품·게시글·크리에이터 채널을 터미널에서 관리한다. 앱과 같은 API·소유권·본인인증·계정 제한을 적용한다. Node.js 20 이상이 필요하다.
4
+
5
+ ```sh
6
+ npm i -g @clack-platform/cli
7
+ clack --help
8
+ ```
9
+
10
+ 설치 없이 한 번만 실행하려면 `npx @clack-platform/cli`를 쓴다. 소스에서 직접 실행하려면 이 저장소 루트에서 `pnpm install --frozen-lockfile && pnpm check && node dist/cli.js --help`를 쓴다.
11
+
12
+ > 외부 도구 연결은 단계적으로 공개 중이며 현재 운영 환경에서는 사용할 수 없다. 테스트 환경 참여자는 `clack config set env dev` 실행 후 로그인한다.
13
+
14
+ ## 연결
15
+
16
+ ```sh
17
+ clack login --scopes profile:read,product:read,product:write
18
+ clack whoami --json
19
+ clack logout
20
+ ```
21
+
22
+ `login`이 표시한 코드를 앱 **마이페이지 → 계정 → 내 정보 수정하기 → 외부 도구 연결 → 코드로 승인**에서 입력한다. 요청한 권한을 확인하고 승인하면 CLI에 연결된다. 기본 요청 권한은 `profile:read` 하나다. `profile`, `product`, `content`, `creator-content`, `skill`, `platform` 묶음은 각각 읽기·쓰기를 모두 요청한다(`creator-content:publish`, `skill:publish`는 별도 명시가 필요하다). `platform`은 내 콘텐츠의 서버 키·공유 문서 관리 전용 권한이다(아래 "플랫폼 전용 PAT 도구" 절 참고). 소셜 로그인 사용자도 앱에서 승인할 수 있다. 웹 승인 화면은 별도 후속 단계이므로 현재는 앱 승인을 사용한다.
23
+
24
+ 수동 발급한 토큰은 `clack login --token`의 숨김 프롬프트에 붙여 넣는다. 비대화형 실행에서는 이 명령의 표준 입력으로 전달할 수 있다. `--token <값>`도 지원하지만 셸 기록을 피하려면 프롬프트나 `CLACK_TOKEN` 환경변수를 사용한다. 토큰 원문은 정상 결과·오류·상세 로그에 출력하지 않는다.
25
+
26
+ 승인 코드·주소는 표준 오류에, 최종 결과는 표준 출력에 기록한다. `--json`에서는 QR과 브라우저 자동 열기를 생략하며, `--no-qr`로 QR만 따로 끌 수 있다(에이전트·비대화형 환경에 적합). 승인이 거부·만료되거나 토큰 교부 응답을 받지 못하면 자동으로 새 연결을 만들지 않는다. 앱에서 기존 연결을 확인한 후 다시 로그인한다.
27
+
28
+ ```sh
29
+ clack login --env dev --scopes profile,product,content --no-browser
30
+ clack token list --json
31
+ clack token revoke 123 --yes
32
+ ```
33
+
34
+ ## 주요 명령
35
+
36
+ 세부 필드·선택지는 각 명령의 `--help`에서 확인한다.
37
+
38
+ | 대상 | 명령 |
39
+ |---|---|
40
+ | 연결 | `login`, `logout`, `whoami`, `doctor`, `token list`, `token revoke` |
41
+ | 프로필 | `me get`, `me update`, `me seller-intro set`, `me password change` |
42
+ | 알림·배송지 | `me notifications set`, `me email send/verify/set`, `me address list/add/update/delete/default` |
43
+ | 상품 | `product list/get/create/update/status/bump/hide/unhide/delete` |
44
+ | 상품 입력 참고 | `product types/categories/shipping-methods` |
45
+ | 글 | `post list/get/create/update/delete/link-products` |
46
+ | 댓글 | `comment list/add/delete` |
47
+ | 크리에이터 채널 | `channel get/create/update`, `channel post list/get/create/update/delete`, `channel series list/create/update/delete` |
48
+ | 이미지 | `upload <파일...>` |
49
+ | 설정 | `config get`, `config set <키> <값>` |
50
+ | HTML 콘텐츠 | `content config/list/status/create/upload/complete/preview/submit/withdraw/publish/unpublish` |
51
+ | 에이전트 연결 | `mcp config`, `skills` |
52
+ | 스킬 패키지·관리 | `skill validate`, `skill push`, `skill complete`, `skill submit`, `skill list`, `skill get`, `skill form`, `skill status`, `skill cancel`, `skill release`, `skill deprecate` |
53
+ | 콘텐츠 서버 키(platform:read/write) | `content server-keys list/revoke` (발급·회전은 크리에이터 센터 전용) |
54
+ | 공유 문서 관리(platform:read/write) | `content shared collections/list/get/hide/delete` |
55
+ | 플랫폼 서버 키 데이터 | `platform usage`, `platform data get`, `platform data list`, `platform data leaderboard`, `platform data put`, `platform data patch`, `platform data delete` |
56
+ | 플랫폼 MCP 도구 | `mcp config --platform`, `mcp serve-platform` |
57
+
58
+ ```sh
59
+ clack product list --status selling --all --json
60
+ clack product create -f product.json --dry-run --json
61
+ clack product create -f product.json --json
62
+ clack product update 123 --price 12000
63
+ clack product status 123 sold --yes
64
+ clack product delete 123 --yes
65
+ clack post create --feed --content '새 글' --images ./photo.png
66
+ clack channel post create --from-markdown draft.md --status draft
67
+ ```
68
+
69
+ 상품 생성에는 `type`, `images`, `name`, `category`, `price`, `description`이 필요하다. `product categories`의 저장용 카테고리를 사용한다. 이미지 경로는 자동 업로드하며 JSON 파일 속 상대 경로는 해당 파일을 기준으로 해석한다. 거래 유형은 `sell`, `buy`, `groupbuy`, `randombox`, `commission`이다. 언어와 통화는 서버의 기존 규칙을 따른다.
70
+
71
+ `product create -f items.json`에 배열을 전달하면 항목별 결과를 반환한다. `--report report.json`으로 저장하고 `--resume report.json`으로 실패 항목을 재개한다. 보고서에는 등록 입력이 포함되므로 개인정보 취급에 주의한다. 서버 응답이 유실된 변경은 앱에서 반영 여부를 확인해야 한다.
72
+
73
+ 배치 중 일부가 실패하면 종료 코드 6과 `ok:false`, `code:BATCH_FAILED`를 반환하고 `data`에 전체 보고서를 포함한다. 이미 성공한 항목과 `OUTCOME_UNKNOWN` 항목은 자동 재개하지 않는다. 보고서는 생성 요청 직전부터 원자적으로 갱신하여 프로세스 중단 후의 중복 등록도 방지한다.
74
+
75
+ 삭제·거래완료 전에는 대화형 확인을 받는다. 비대화형 실행에서는 `--yes`가 필요하다. `--dry-run`은 입력·로컬 이미지 검증과 미리보기만 수행하며 서버 변경이나 업로드를 실행하지 않는다. 보드 유형이나 기존 콘텐츠를 확인하는 읽기 요청은 할 수 있다.
76
+
77
+ 마크다운은 문단·강조·링크·구분선·이미지를 채널 블록으로 변환한다. 제목·목록·인용·코드 등 지원하지 않는 서식은 문단으로 변환하고 안내한다. 로컬 이미지는 업로드하며 원격 이미지는 허용된 CDN에서만 처리한다.
78
+
79
+ ## 설정과 출력
80
+
81
+ 기본 설정은 macOS/Linux의 `~/.config/clack/`, Windows의 `%APPDATA%\\clack\\`에 저장한다. `XDG_CONFIG_HOME`과 별도 격리용 `CLACK_CONFIG_DIR`도 지원한다. 자격 파일 `credentials.json`은 POSIX에서 `0600`, 폴더는 `0700`이다. 프로필마다 연결한 API 원점을 함께 보관하며 다른 주소에 저장된 토큰을 자동 전송하지 않는다.
82
+
83
+ - 프로필: `--profile` → `CLACK_PROFILE` → 기본 프로필(`default`) 순서. `--env`는 프로필을 바꾸지 않는다 — 어떤 프로필이든 그 프로필이 가리키는 환경(주소)만 고른다.
84
+ - API 주소: `--base-url` → `CLACK_API_BASE` → (`--env`가 있으면 그 환경의 기본 주소, 없으면 프로필에 저장된 주소) → 프로필의 `env` 설정(없으면 운영) 기본 주소 순서.
85
+ - 토큰: `CLACK_TOKEN` → 해당 프로필의 저장된 토큰 순서.
86
+ - 설정 키: `env`, `base_url`, `time`(`local`/`utc`), `lang`(`ko`/`en`), `output`(`human`/`json`).
87
+
88
+ `config set env dev` 후 로그인하거나 `login --env dev`로 바로 연결하거나(또는 둘을 섞어도) 같은 기본 프로필의 같은 dev 자격을 쓴다. 이후 명령에 `--env dev`를 붙이거나 떼도 결과가 바뀌지 않는다. 명시적으로 다른 환경(예: `--env prod`)을 고르면 그 환경을 따르며, 그 환경의 자격이 없으면 다시 로그인해야 한다. 여러 계정·환경을 동시에 쓰려면 `--profile <이름>`으로 별도 프로필을 만든다. `config set env dev`처럼 환경을 변경하면 이전에 저장한 `base_url`을 지우고 새 환경의 기본 주소를 사용한다. 기존 토큰의 원점이 다르면 다시 로그인해야 한다. (이전 개발 빌드에서 기본 프로필 이름으로 쓰던 `prod`도 그대로 이어서 인식한다.) `token list --cursor <값>`으로 50개 이후의 연결도 조회할 수 있다.
89
+
90
+ CLI 안내는 한국어다. `lang`은 API 콘텐츠 언어에 사용한다. `--verbose`는 메서드·경로·시간 계약만 표준 오류로 표시한다. `doctor`는 현재 연결·권한·만료와 서버 메타 API의 한도·읽기/쓰기·MCP·디바이스 연결 상태를 검사한다. 메타 조회 실패는 오류로 반환한다.
91
+
92
+ `--json` 성공 결과는 `{ok:true,data,pagination?,time_contract}`, 실패 결과는 `{ok:false,status,code,message,retry_after?}`다. 시간 문자열은 API 원문과 `time_contract`를 함께 유지한다. 사람용 출력은 알려진 시각 필드에 중앙 파서를 적용하며 `--time utc`로 실제 UTC를 표시할 수 있다. 생년월일과 본문은 시간으로 변환하지 않는다.
93
+
94
+ | 종료 코드 | 의미 |
95
+ |---|---|
96
+ | 0 | 성공 |
97
+ | 1 | 네트워크·서버·내부 오류 |
98
+ | 3 | 로그인·토큰 문제 |
99
+ | 4 | 권한·본인인증·계정 제한 |
100
+ | 5 | 대상 없음 |
101
+ | 6 | 입력·충돌·확인 필요 또는 배치 일부 실패 |
102
+ | 7 | 요청 한도 |
103
+ | 8 | 외부 도구 기능 중단(관리자가 끈 상태, 또는 연결한 서버에 아직 배포되지 않음) |
104
+
105
+ `login`(디바이스 코드 발급)·`doctor` 등 첫 연결 경로에서 연결한 서버(API 원점)가 외부 도구 연결 자체를 아직 지원하지 않으면(전용 라우트가 없어 404, 또는 디바이스 코드 발급이 이전 시간 계약만 지원해 406) `code:USER_API_UNAVAILABLE`과 종료 코드 8을 반환한다. 운영(prod)은 아직 배포 전이므로 흔히 이 상황을 만난다 — `clack config set env dev`로 전환한 뒤 다시 로그인한다. 상품·게시글 등 일반 리소스의 404나 다른 요청의 406은 이 매핑의 영향을 받지 않는다.
106
+
107
+ 채팅·주문·결제·탈퇴·계좌·본인인증 실행과 타인 콘텐츠 반응은 제공하지 않는다. 본인인증이 필요하면 앱에서 완료한다. 댓글 수정 API가 없으므로 댓글은 작성·삭제만 제공한다.
108
+
109
+ ## MCP와 에이전트 스킬
110
+
111
+ ```sh
112
+ clack mcp config --print
113
+ clack mcp config --claude
114
+ clack mcp config --codex
115
+ clack mcp config --json
116
+ clack skills --json
117
+ ```
118
+
119
+ `mcp config`는 선택한 API 원점의 `/v4/mcp`와 `CLACK_TOKEN` 환경변수 참조를 출력한다. 로그인이나 네트워크 접근 없이 사용할 수 있고 자격 파일·에이전트 설정을 읽거나 변경하지 않는다. 기본값과 `--print`는 Claude Code의 `.mcp.json` 조각, `--claude`는 POSIX 셸에서 실행할 프로젝트 등록 명령, `--codex`는 Codex의 `config.toml` 조각이다. `--json`은 공통 성공 봉투의 `data`에 두 클라이언트의 설정·등록 명령·안내를 모두 담는다. 사람용 안내는 표준 오류에 기록한다. 기존 설정에 해당 `clack` 항목만 병합하고 다른 서버 항목을 보존한다.
120
+
121
+ 앱에서 작업에 필요한 권한으로 개인 액세스 토큰을 발급하고 에이전트를 실행하는 환경의 `CLACK_TOKEN`에 안전하게 넣는다. 토큰을 대화창·명령 인자·공유 설정 파일에 붙여 넣지 않는다. CLI에 저장된 디바이스 로그인 토큰은 MCP로 자동 전달되지 않는다. CLI 프로필을 바꿔도 이미 등록한 MCP 주소는 그대로이므로 주소와 토큰의 계정을 확인한다. 이 서버는 PAT 인증을 사용하며 OAuth 로그인은 제공하지 않는다. 연결 후 `get_guide` → `whoami` → `get_meta`로 계정·권한·한도를 확인한다.
122
+
123
+ 환경변수 참조 형식은 [Claude Code MCP 문서](https://code.claude.com/docs/en/mcp#environment-variable-expansion-in-mcp-json)와 [Codex MCP 문서](https://developers.openai.com/codex/mcp/)를 따른다. 다른 클라이언트는 해당 제품의 Streamable HTTP·인증 헤더 지원을 확인한다.
124
+
125
+ 원격 MCP는 프로필·상품·게시글·채널 도구 외에 스킬 목록·상세·업로드(`create_skill`→`request_skill_version_upload`→`complete_skill_version`)·심사 제출·공개(`submit_skill_version`, `release_skill_version`, `get_skill_version`), 승인된 HTML 콘텐츠 공개(`publish_creator_content`), 공유 문서 조회·숨김·삭제(`list_shared_documents`, `hide_shared_document`, `delete_shared_document` 등)도 제공한다. 각 도구는 해당 스코프(`skill:*`, `creator-content:publish`, `platform:read`/`platform:write`)를 가진 토큰에만 노출되며, 파괴적 도구는 `confirm:true` 전에는 미리보기만 반환한다. 원격 MCP는 로컬 파일을 읽지 못하므로 스킬 ZIP 전송은 `clack skill push` 또는 로컬 플랫폼 MCP의 `platform_skill_push`를 사용한다.
126
+
127
+ 에이전트 스킬은 별도 공개 저장소 [clack-project/skills](https://github.com/clack-project/skills)에서 `npx skills add clack-project/skills`로 설치한다. 설치·상품·콘텐츠·채널·프로필·MCP 6종을 제공하며 `clack skills`는 안내만 출력한다. 스킬만 선택 설치할 때는 `-s clack-products`, 전역 설치에는 `-g`를 사용한다.
128
+
129
+ ## 검증과 배포
130
+
131
+ ```sh
132
+ pnpm check # typecheck → 스키마 동기화 확인 → 테스트 → 빌드
133
+ npm pack --dry-run
134
+ ```
135
+
136
+ `pnpm check`는 나란히 체크아웃한 클랙 모노레포가 있으면(`CLACK_MONOREPO_DIR`, 기본 `../clack`) MCP 입력 스키마 일치도 함께 확인하고, 없으면 건너뛴다. 배포 전 로컬에서 이 확인을 강제하려면 `pnpm check:release`를 쓴다. `scripts/sync-vendor-types.mjs [--check]`는 `src/vendor/` 아래 복사해 둔 클랙 공개 타입·계약 파일을 같은 방식으로 모노레포와 동기화한다.
137
+
138
+ GitHub Actions는 Linux·macOS·Windows × Node 20·22에서 `pnpm check`와 패키지 설치 스모크를 실행한다(`.github/workflows/ci.yml`). 배포는 `v0.1.0` 형태의 버전 태그를 push하면 `.github/workflows/publish.yml`이 태그와 `package.json` 버전 일치를 확인한 뒤 GitHub Actions의 OIDC 신뢰 게시로 npm에 공개한다.
139
+
140
+
141
+ ## HTML 콘텐츠 개발 테스트
142
+
143
+ 크리에이터 콘텐츠는 기존 게시글·포켓과 별도 권한을 사용합니다. 개발 환경에서 초안 등록·HTML/ZIP 업로드를 검증할 수 있습니다. 앱 확인·AI 심사 후 공개·채팅 제작은 아직 준비 중이며 CLI로 확인 요건을 우회할 수 없습니다.
144
+
145
+ ```bash
146
+ clack login --env dev --scopes creator-content:read,creator-content:write,creator-content:publish
147
+ clack content config --env dev
148
+ clack content create --env dev --title "내 작품" --policy-version 2026-09-22
149
+ clack content upload --env dev <콘텐츠-UUID> ./index.html
150
+ clack content status --env dev <콘텐츠-UUID>
151
+ clack content preview --env dev <콘텐츠-UUID> <버전-UUID>
152
+ ```
153
+
154
+ `content upload`는 최대 30 MiB의 HTML/ZIP을 체크섬과 함께 비공개 저장소에 전송합니다. 전송 후 완료 응답만 실패하면 출력된 `content complete` 명령으로 같은 업로드를 재처리할 수 있습니다. `--dry-run`은 파일·입력 검사만 수행합니다. `creator-content` 약식 scope는 읽기·쓰기만 요청하며 공개 권한은 명시적으로 요청해야 합니다. 정책 내용을 크리에이터 센터에서 확인한 뒤 `--policy-version`으로 동의한 버전을 지정하세요.
155
+
156
+ ZIP에 `clack.content.json` 또는 `.clack/`가 있으면 업로드 전에 선언·경로·크기와 프로필 파일 대응을 확인하고 표준 오류에 경고합니다. 선언이 없는 기존 정적 ZIP도 계속 업로드할 수 있습니다. 경고는 업로드를 막지 않으며 서버의 최종 검증·심사 결과를 대신하지 않습니다. 전송 없이 확인하려면 `content upload ... --dry-run`을 사용하세요.
157
+
158
+ 심사는 승인됐지만 아직 공개하지 않은 버전(크리에이터 센터 등록·게시 중단 후 재공개 등)은 `creator-content:publish` 권한으로 공개합니다. 승인 이력·심사 해시·현재 계정과 권한을 공개 시점에 다시 검사합니다.
159
+
160
+ ```bash
161
+ clack content publish --env dev <콘텐츠-UUID> <버전-UUID>
162
+ ```
163
+
164
+ ## 스킬 패키지 개발 검증
165
+
166
+ `clack.skill.json`과 `SKILL.md`가 있는 디렉터리 또는 ZIP을 검사합니다. 로컬 검증은 로그인 없이 실행할 수 있습니다. 서버 경로는 현재 개발 환경에서 기능 플래그가 켜진 계정과 `skill:write` 권한의 개인 액세스 토큰이 필요합니다.
167
+
168
+ ```sh
169
+ clack skill validate ./my-skill
170
+ clack skill validate ./my-skill.zip --remote --env dev
171
+ clack skill push ./my-skill --env dev
172
+ clack skill push ./my-skill --skill-id <스킬-UUID> --env dev
173
+ clack skill complete <스킬-UUID> <버전-UUID> --env dev
174
+ clack skill list --category character_chat --official true --env dev
175
+ clack skill list --all --env dev
176
+ clack skill get my-skill --env dev
177
+ clack skill form my-skill 1.0.0 --env dev
178
+ clack skill status <스킬-UUID> <버전-UUID> --env dev
179
+ clack skill submit <스킬-UUID> <버전-UUID> --env dev
180
+ clack skill cancel <스킬-UUID> <버전-UUID> --env dev
181
+ clack skill release <스킬-UUID> <버전-UUID> --visibility unlisted --env dev
182
+ clack skill deprecate <스킬-UUID> --env dev
183
+ ```
184
+
185
+ `push`는 서버 사전 검증 후 새 스킬 또는 기존 스킬의 버전을 예약하고, 서명된 URL에 ZIP을 전송한 뒤 완료 처리합니다. 완료 응답만 실패하면 출력된 `skill complete` 명령으로 같은 버전을 재처리합니다. `--dry-run`은 서버를 변경하지 않습니다.
186
+
187
+ `list`·`get`·`form`·`status`는 `skill:read`, `cancel`·`deprecate`는 `skill:write`, `submit`은 `skill:write`와 `skill:publish`, `release`는 `skill:publish` 권한이 필요합니다. 변경 명령은 개인 액세스 토큰(PAT)만 사용합니다. `submit`은 서버에서 검증 완료 상태와 패키지 해시를 조회한 뒤 확인을 받고 심사를 요청합니다. `--dry-run`은 제출 요청 없이 상태만 확인합니다. `release`는 심사를 통과한 버전만 허용하고, `--visibility public`은 별도 라이브러리 등재 승인이 필요합니다. 심사 판정은 관리자 화면에서 처리합니다. `deprecate`는 스킬 전체를 지원 종료 상태로 바꾸며 되돌릴 수 없습니다. 확인 후에만 실행되고(비대화형은 `--yes` 필요), 새 설치·새 제작은 막히지만 기존 콘텐츠가 고정한 버전은 계속 동작합니다.
188
+
189
+ ### 스킬 플러그인 정적 검사(plugin-static-v2)
190
+
191
+ `clack.skill.json`의 `authoring.plugin`으로 제작 화면 플러그인을 선언하면 서버가 번들을 구문 트리(JS·HTML·CSS)로 검사합니다. 위험 기능을 쓰지 않는다고 증명할 수 있는 코드만 통과하고, 판단할 수 없는 코드는 오류로 봅니다. 요약은 다음과 같고 크리에이터 센터 `/creator/skills/help/plugin`에도 같은 안내가 있습니다. 메시지 예제·권한 동의·심사 준비를 포함한 상세 안내의 정본은 크리에이터 가이드 `/guide/reference/templates/editor-plugins`(T09)와 실습 과정 `/guide/courses/center-editor-plugin`(T05)입니다.
192
+
193
+ - 선언: `bundle`(진입 HTML)·`sha256`·`fields`·`permissions`·`purpose`. 권한은 `getFormSchema`·`getFormValues`·`setFormValues`·`listApprovedAssets`·`requestAssetUpload`만 있고, 권한·필드가 늘면 크리에이터에게 다시 동의를 받습니다.
194
+ - 번들: 파일 50개, 파일당 512 KiB, 전체 2 MiB, 코드 합계 512 KiB 이하. 형식은 html·js·mjs·css·json·png·jpg·webp·gif·woff·woff2만 허용합니다.
195
+ - 진입 HTML: CSP 메타를 한 번만 두고 `default-src 'none'`으로 시작합니다. `connect-src`는 `'none'`만, `script-src`·`style-src`는 `'self'` 또는 해시, `img-src`·`font-src`는 `'self'` 또는 `data:`만 씁니다. 인라인 스크립트·인라인 이벤트 속성·meta refresh·외부 URL 참조는 금지이고 `<link>`는 `rel="stylesheet"`만 허용합니다.
196
+ - 스크립트 금지: 동적 코드(`eval`·`Function`·`WebAssembly`), 네트워크(`fetch`·`XMLHttpRequest`·`WebSocket`·`EventSource`·`Worker`·`Image`), 저장소(`localStorage`·`sessionStorage`·`indexedDB`·쿠키), 페이지 이동(`location` 쓰기·`assign`·`replace`·`history`·`open`·`top`), `innerHTML` 같은 위험 DOM 쓰기, 계산된 멤버 접근(`obj[key]`), 전역 별칭(`self`·`globalThis`·`const w = window`), `Reflect`·`Proxy`·`constructor` 반사, `atob`·`escape`·이스케이프 문자열 난독화. `import`는 번들 안 상대 경로 `.js`·`.mjs`만 씁니다.
197
+ - 메시지: `postMessage` 대상은 `https://` 리터럴·받은 이벤트의 `origin`·fragment의 `clack-parent` 값만 허용하고 `'*'`는 금지입니다. 수신 시 `event.origin`·`event.source`를 확인하고 메시지에 `nonce`·`request_id`를 담습니다.
198
+ - 로드 토큰: iframe 주소의 실행 토큰은 300초 동안 유효하고 번들 안 상대 경로 자원도 같은 토큰으로 검사합니다. 센터는 만료 30초 전에 새 토큰으로 플러그인을 다시 엽니다. 필요한 자원은 첫 로드 때 불러오고, 상태는 `setFormValues`로 저장한 뒤 다시 열렸을 때 `getFormValues`로 이어 갑니다.
199
+ - 심사: 업로드는 구조 오류만 422 `SKILL_PLUGIN_INVALID`로 거부하고, 코드 판정은 줄 번호와 함께 심사 근거로 남깁니다. 관리자가 번들 소스를 직접 확인한 뒤 승인하며 플러그인과 결과 콘텐츠는 자동 공개되지 않습니다. 이전 규칙(v1)으로 검사된 대기 플러그인은 승인할 수 없으니(409 `PLUGIN_STATIC_CHECK_STALE`) 새 버전으로 다시 올립니다.
200
+
201
+ ## 플랫폼 전용 PAT 도구(서버 키·공유 문서·콘텐츠 공개)
202
+
203
+ `platform:read`·`platform:write` 스코프의 개인 액세스 토큰(PAT)으로 내 콘텐츠의 서버 키(`csk_`)를 조회·폐기하고, 이용자가 쓴 공유(shared) 문서를 조회·숨김·삭제합니다. `platform:read`는 조회, `platform:write`는 폐기·숨김·삭제입니다. 서버 키 발급·회전은 PAT보다 오래 사는 비밀값을 만들므로 크리에이터 센터 로그인 세션에서만 할 수 있고, `content server-keys issue`·`rotate`는 센터 안내만 출력합니다. 서버 키 원문은 센터의 발급·회전 응답에만 한 번 담깁니다.
204
+
205
+ ```sh
206
+ clack login --env dev --scopes platform
207
+ clack content server-keys list --env dev <콘텐츠-UUID>
208
+ clack content server-keys revoke --env dev <콘텐츠-UUID> <키-ID> --yes
209
+ clack content shared collections --env dev <콘텐츠-UUID>
210
+ clack content shared list --env dev <콘텐츠-UUID> ranking
211
+ clack content shared get --env dev <콘텐츠-UUID> ranking entry-1
212
+ clack content shared hide --env dev <콘텐츠-UUID> ranking entry-1 --yes
213
+ clack content shared delete --env dev <콘텐츠-UUID> ranking entry-1 --yes
214
+ ```
215
+
216
+ 폐기·숨김·삭제 전에는 대화형 확인을 받습니다. 비대화형 실행에는 `--yes`가 필요합니다.
217
+
218
+ ## 플랫폼 서버 키 조회
219
+
220
+ 콘텐츠별 서버 키를 발급받은 뒤 `CLACK_SERVER_KEY` 환경변수에 설정합니다. 키는 명령 인자나 CLI 자격 파일에 저장하지 않습니다. `--env dev`와 `--env prod`로 대상 API를 지정할 수 있으며 서버 키는 발급받은 환경에서만 사용합니다.
221
+
222
+ ```sh
223
+ clack platform usage --from 2026-09-01T00:00:00.000Z --to 2026-09-02T00:00:00.000Z --env dev
224
+ clack platform data get scores slot --env dev
225
+ clack platform data list scores --limit 20 --env dev
226
+ clack platform data leaderboard scores --limit 10 --env dev
227
+ ```
228
+
229
+ `usage`는 서버 키 인증을, 데이터 조회는 `data:read` 스코프를 사용합니다. 시청자 범위 조회에는 `--viewer-id v_…`를 지정합니다. 조회 경로와 타입은 공개 OpenAPI에서 생성한 `@clack/types/platform` 계약을 사용합니다. 서버 키(`csk_`)와 `platform:read|write` PAT는 서로 다른 인증 평면이며 섞어 쓸 수 없습니다. PAT용 개인 도구는 위 "플랫폼 전용 PAT 도구" 절을 참고하세요.
230
+
231
+ 단일 문서 쓰기·수정·삭제는 `data:write` 스코프가 필요합니다. PUT/PATCH 본문은 64 KiB 이하의 JSON 객체 파일로 지정합니다. PUT은 `--if-absent` 또는 현재 개정 번호 `--if-rev` 중 하나, PATCH는 `--if-rev`가 필수입니다. 삭제 API에는 개정 조건이 없으므로 대상 확인을 요청합니다. `--dry-run`은 파일과 조건을 검사하고 메서드·경로·본문 크기·SHA-256만 표시하며, 비대화형 실제 변경에는 `--yes`가 필요합니다.
232
+
233
+ ```sh
234
+ clack platform data put scores slot --file ./score.json --if-absent --env dev
235
+ clack platform data patch scores slot --file ./score-patch.json --if-rev 1 --env dev
236
+ clack platform data delete scores slot --env dev
237
+ ```
238
+
239
+ `clack mcp config --platform --env dev`는 서버 키 조회와 PAT 개인 도구를 함께 쓸 수 있는 로컬 stdio MCP 설정을 출력합니다. 에이전트 실행 환경에 서버 키 도구용 `CLACK_SERVER_KEY`, 스킬·콘텐츠 공개·공유 문서 도구용 `CLACK_TOKEN`(`platform:read`/`platform:write`, 필요 시 `skill:*`·`creator-content:publish`)을 각각 필요한 만큼만 설정합니다. 둘 다 로컬 프로세스 환경변수로만 전달되며 CLI 자격 파일에서 자동으로 읽지 않습니다. Claude 설정 조각은 기본 출력, Codex 설정 조각은 `--codex`로 받습니다. 설정에는 키·토큰 원문이 들어가지 않습니다.
240
+
241
+ ```sh
242
+ clack mcp config --platform --env dev
243
+ clack mcp config --platform --codex --env dev
244
+ ```
245
+
246
+ 서버 키(`CLACK_SERVER_KEY`) 도구는 `platform_usage_get`, `platform_server_data_get/list/leaderboard/put/patch/delete`입니다. PAT(`CLACK_TOKEN`) 도구는 `platform_skill_list/get/push/status/submit/release`, `platform_content_publish`, `platform_shared_collections_list`, `platform_shared_documents_list`, `platform_shared_document_get/hide/delete`입니다. `platform_skill_push`는 `dir`(생략 시 현재 디렉터리)의 로컬 스킬 패키지를 검증·업로드합니다. 파괴적 도구(단일 문서 변경, 스킬 심사 제출·공개, 콘텐츠 공개, 공유 문서 숨김·삭제)는 먼저 미리보기와 `confirmation_required`를 반환하고, 입력에 `confirm: true`를 명시해야 실제 요청을 보냅니다. `mcp serve-platform`은 MCP 클라이언트가 실행하는 명령으로, 표준 출력은 JSON-RPC 메시지 전용입니다. 서버 키·PAT의 인증·스코프·테넌트 검사는 모두 API에서 수행합니다.
247
+
248
+ ## 세계관·공개 홈 꾸미기
249
+
250
+ `page` 명령은 일반 콘텐츠와 별도로 `custom-page:read`, `custom-page:write`, `custom-page:publish` 권한을 사용한다. 페이지 소유자만 편집할 수 있으며 개인 홈의 대상 이용자는 서버가 본인으로 정한다.
251
+
252
+ | 명령 | 필요한 PAT 권한 |
253
+ |---|---|
254
+ | `list`, `status`, `preview` | `custom-page:read` |
255
+ | `create`, `upload`, `complete`, `presentation` | `custom-page:write` |
256
+ | `submit` | `custom-page:write`와 `custom-page:publish` 모두 |
257
+ | `apply`, `restore`, `disable` | `custom-page:publish` |
258
+
259
+ 기능 제공 여부는 대상 환경의 센터와 API 설정에 따른다. 페이지 실행·앱 확인 완료는 같은 계정의 앱에서만 수행하며 CLI가 대신하지 않는다. `clack login --scopes custom-page` 약식은 읽기·쓰기만 요청하므로 제출·적용에는 `custom-page:publish`를 추가해야 한다.
260
+
261
+ ```sh
262
+ clack page create --target profile --policy-version 2026-09-22
263
+ clack page create --target space --space-id WORLD_ID --policy-version 2026-09-22
264
+ clack page list
265
+ clack page upload PAGE_ID page.html --header translucent_scroll_hide --color dark
266
+ clack page preview PAGE_ID VERSION_ID
267
+ # 앱에서 같은 계정으로 열고 확인 완료 후 제출
268
+ clack page submit PAGE_ID VERSION_ID
269
+ clack page status PAGE_ID
270
+ # 승인된 버전과 현재 revision을 확인한 뒤 적용
271
+ clack page apply PAGE_ID VERSION_ID --revision 0
272
+ clack page restore PAGE_ID PREVIOUS_VERSION_ID --revision 1
273
+ clack page disable PAGE_ID --revision 2
274
+ ```
275
+
276
+ 헤더는 `fixed`, `scroll_hide`, `translucent_scroll_hide`, `floating_close` 중 선택한다. 파일과 헤더를 한 버전으로 저장하므로 헤더만 바뀌어도 앱 확인·심사가 필요하다. 승인만으로 자동 적용되지 않으며 복원도 최신 수정 번호가 필요하다. 충돌 시 `status`를 다시 읽고 의도한 버전을 확인한다. 기본 화면 전환은 파일을 삭제하지 않는다. 업로드 완료 요청만 실패하면 오류에 표시된 `clack page complete PAGE_ID UPLOAD_ID`로 재시도할 수 있다.
277
+
278
+ 페이지 파일은 유지하고 헤더만 바꾸려면 `clack page presentation PAGE_ID VERSION_ID --header scroll_hide --color light`를 사용합니다. 새 비공개 버전이 만들어지며 응답의 새 버전 ID로 앱 확인과 심사를 다시 진행합니다. 기존 적용본은 유지됩니다.
279
+
280
+ ```sh
281
+ clack page presentation PAGE_ID SOURCE_VERSION_ID --header scroll_hide --color light
282
+ # 응답 data.id의 새 UUID로 이후 절차를 진행합니다.
283
+ clack page preview PAGE_ID NEW_VERSION_ID
284
+ # 새 버전을 앱에서 확인 완료한 뒤
285
+ clack page submit PAGE_ID NEW_VERSION_ID
286
+ clack page status PAGE_ID
287
+ ```
288
+
289
+ `presentation`은 재호출하면 다른 버전을 만들므로 응답이 유실되면 `status`의 버전 이력을 먼저 확인한다. 같은 업로드를 확정하는 `complete`의 멱등 재시도와 구분한다. 파일은 재사용해도 새 버전은 일일 업로드·논리 저장 한도에 포함된다. 외부 MCP에서도 `revise_custom_page_presentation`으로 같은 작업을 수행하며 상세 계약은 [HTML·페이지 제작 가이드](../clack-developer/content/guide/reference/content/upload-html.md)를 참조한다.
290
+
291
+ ### 이미지 화보·캐릭터 가져오기 제작
292
+
293
+ `clack authoring --input request.json`은 센터와 같은 공개 제작 API를 사용한다. 로컬 MCP는 같은 입력을 `platform_authoring` 도구로 받는다. 개인 액세스 토큰의 `creator-content:write` 권한이 필요하다.
294
+
295
+ - 세션 시작: `{"action":"create","skill_slug":"clack-character-image","skill_version":"1.0.0"}`
296
+ - 조회: `{"action":"get","session_id":"UUID"}`. `save`는 `revision`·`values`, `package`는 `revision`을 함께 보낸다.
297
+ - 업로드: `{"action":"upload","session_id":"UUID","field":"plates","item_index":0,"file":"./portrait.png"}`. 응답 자산 ID를 `plates[0].asset_id`로 저장한다.
298
+ - 견적: `{"action":"quote","session_id":"UUID"}`. 생성은 `action:"image"` 또는 `"image-batch"`, `form_revision`·`asset_slot`·`approved_price_cash`·`idempotency_key`와 `item_index` 또는 `item_indexes`를 보낸다. 같은 요청의 재시도에는 같은 키를 사용한다.
299
+ - 가져오기: `{"action":"import","session_id":"UUID","field":"portrait_source","content_id":"UUID","revision":0}`. 본인 콘텐츠에서 매니페스트가 내보내도록 선언한 값만 복사한다.
300
+ - AI 채우기는 `fill-quote` → `fill` → `fill-status`, 자산 목록은 `assets`, 이미지 작업 조회는 `tool`, 폼 검증은 `validate`를 사용한다.
301
+
302
+ `image_list` 값은 `[{"asset_id":"UUID","scene":"장면","pose":"구도","mood":"분위기","aspect":"1:1"}]`이며 한 번에 최대 8장, 콘텐츠당 최대 24장을 사용한다. 스킬의 `max_calls`와 플랫폼 설정 중 작은 한도를 적용한다. 참조 이미지 생성은 공급자 검증 전 비활성이며 현재 외모·화풍·팔레트 텍스트로 동일성을 안내한다.