reborn-sysprompt 1.0.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/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # reborn-sysprompt
2
+
3
+ **유출본을 찾을 일이 아닙니다 — 앤트로픽이 원래 공개합니다.**
4
+
5
+ ```
6
+ npx --yes reborn-sysprompt --check ← 지금 공개된 것을 실제로 세어 봅니다
7
+ npx --yes reborn-sysprompt ← 안내 스킬을 깝니다
8
+ ```
9
+
10
+ ## 이게 무엇인가
11
+
12
+ 인터넷에 「Claude 시스템 프롬프트 유출」이라는 글이 자주 돕니다.
13
+ 그런데 **앤트로픽은 2024년 8월부터 이걸 모델마다 공개해 왔습니다.**
14
+ 주요 AI 회사 중 이걸 공식으로 내놓는 곳은 여기뿐입니다.
15
+
16
+ 이 패키지는 그 공개본을 **읽고 설계를 가져오는 법**을 안내하는 스킬을 깝니다.
17
+
18
+ ★**원문을 담지 않습니다.** 주소만 들고 있고, 받는 것도 여러분 컴퓨터에서 합니다.
19
+ 읽고 배우는 것과 퍼 나르는 것의 경계가 거기입니다.
20
+
21
+ ## `--check` 가 하는 일
22
+
23
+ 문서 사이트에 **직접** 붙어(우리 서버를 안 거칩니다) 지금 공개된 모델 수와
24
+ 합계 길이를 세고, 원장에 적힌 잰 날과 맞대 봅니다.
25
+
26
+ - 못 받으면 **「못 봤다」**고 합니다 — 「그대로다」라고 하지 않습니다
27
+ - 원문은 **저장하지 않습니다.** 길이만 세고 버립니다
28
+ - 이 컴퓨터에서 **원칙을 옮겨 붙일 자리**(CLAUDE.md · 스킬 폴더)도 같이 찾아 줍니다
29
+
30
+ ## ★먼저 아셔야 할 것 두 가지
31
+
32
+ **① 공개본은 API 에 안 붙습니다.**
33
+
34
+ 문서 원문이 이렇게 못 박아 뒀습니다:
35
+
36
+ ```
37
+ These system prompt updates do not apply to the Claude API.
38
+ ```
39
+
40
+ claude.ai 웹·iOS·안드로이드 앱에 쓰는 프롬프트입니다.
41
+ 이걸 모르고 API 에 같은 답을 기대하면 어긋납니다.
42
+
43
+ **② 길이를 함부로 맞대면 안 됩니다.**
44
+
45
+ 4.6 세대 **이전** 모델의 페이지는 여러 날짜가 한 장에 쌓여 있습니다.
46
+ 그 길이를 「프롬프트 하나의 길이」로 읽으면 틀립니다.
47
+ 맞댈 거면 4.6 세대 이후끼리만 맞댑니다.
48
+
49
+ ## 무엇을 가져오나 — 문장이 아니라 설계
50
+
51
+ 그 글은 claude.ai 라는 특정 제품·특정 모델을 위해 쓰인 것이라,
52
+ 통째로 옮기면 내 일에 안 맞는 문장이 대부분입니다.
53
+
54
+ 가져올 것은 이런 것들입니다:
55
+
56
+ - 무엇을 **맨 앞에** 두었나
57
+ - 금지에 **이유가 붙어 있나**
58
+ - **예외를 어디에** 두었나
59
+ - 모호할 때 **무엇을 하라고** 했나
60
+ - ★**판이 올라갈 때 무엇이 바뀌었나** — 바뀐 줄이 그 팀이 실제로 밟은 사고입니다
61
+
62
+ ## 무엇을 깝니까
63
+
64
+ `~/.claude/skills/claude-system-prompt-guide/` 하나뿐입니다.
65
+
66
+ | 파일 | 무엇 |
67
+ |---|---|
68
+ | `SKILL.md` | 클로드가 읽는 안내. 답하는 순서가 여기 있습니다 |
69
+ | `sysprompt.json` | 원장. 모든 사실의 주인 |
70
+
71
+ 깐 뒤 클로드 코드를 다시 시작하고 **「공개본에서 배울 것 정리해 줘」** 라고 하시면 됩니다.
72
+
73
+ ## 명령
74
+
75
+ | 명령 | 무엇 |
76
+ |---|---|
77
+ | `npx --yes reborn-sysprompt` | 안내 스킬을 깝니다 |
78
+ | `npx --yes reborn-sysprompt --check` | **깔지 않고** 공개본을 지금 세어 봅니다 |
79
+ | `npx --yes reborn-sysprompt --dry-run` | 무엇을 할지 보여주기만 합니다 |
80
+ | `npx --yes reborn-sysprompt --local` | 홈이 아니라 현재 폴더에 깝니다 |
81
+ | `npx --yes reborn-sysprompt --self-test` | 자기시험 (네트워크 안 씁니다) |
82
+
83
+ ★`npx` 뒤의 `--yes` 는 빼지 마세요. 없으면 클로드 코드 안에서 물음이 뜨는데
84
+ 그 물음이 화면에 안 보여서 **무음으로 멈춥니다.**
85
+
86
+ ## 인용할 때
87
+
88
+ - 원문을 통째로 옮겨 두지 마세요. 필요한 줄만, 짧게
89
+ - **모델 이름과 문서 주소를 같이** 적으세요. 출처 없이 옮기면 내가 쓴 글로 읽힙니다
90
+
91
+ ## 다 깔고 나면
92
+
93
+ 이 안내 스킬처럼 **먼저 재 주고 무엇이 함정인지 말해 주는** 스킬을
94
+ 같은 방식으로 48종 골라 담아 두었습니다 — 리본랩스 스킬팩(8,900원).
95
+
96
+ https://rebornlabs.kr/skillpack?utm_source=installer&utm_medium=cli&utm_campaign=sysprompt
97
+
98
+ 목록과 직접 까는 명령까지 그 페이지에 그대로 적어 두었습니다. 안 사셔도 됩니다.
99
+
100
+ ## 숫자는 언제 잰 것인가
101
+
102
+ 2026-09-04 에 공식 문서 목록과 각 모델의 원문을 직접 받아
103
+ **프론트매터를 뺀 본문 길이를 세었습니다.** `skill/sysprompt.json` 의 `확인일`·`확인방법` 을 보세요.
104
+
105
+ ---
106
+
107
+ MIT · [REBORN LABS](https://rebornlabs.kr) · 문의 https://mobility.rebornlabs.kr/cs
108
+
109
+ 소개하는 문서는 앤트로픽의 저작물입니다. 우리와 제휴 관계가 없습니다.
package/cli.mjs ADDED
@@ -0,0 +1,341 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * claude-system-prompt-guide 설치기 — **공개본을 실제로 받아 세어 보고**, 안내 스킬을 깐다.
4
+ *
5
+ * npx --yes reborn-sysprompt 안내 스킬을 깐다 (이게 전부다)
6
+ * npx --yes reborn-sysprompt --check ★깔지 않고 **공개본을 실제로 받아 센다**
7
+ * npx --yes reborn-sysprompt --dry-run 무엇을 할지 보여주기만 한다
8
+ * npx --yes reborn-sysprompt --local 홈이 아니라 현재 폴더에 깐다
9
+ * npx --yes reborn-sysprompt --self-test 자기시험 (네트워크 안 씀)
10
+ *
11
+ * ★★왜 우리가 대신 안 읽고 **안내 스킬**을 까나
12
+ * 문서는 공개돼 있고 주소도 한 줄이다. 우리가 대신 열어 준다고 아껴지는 게 없다.
13
+ * 실제로 막히는 자리는 **무엇을 보고 무엇을 옮길지**다 —
14
+ * 18개를 다 읽는 사람은 없고, 읽어도 「그래서 내 프롬프트를 어떻게 고치나」가 안 나온다.
15
+ *
16
+ * ★★★재배포하지 않는다.
17
+ * 이 패키지는 공개본 **원문을 담지 않는다.** 주소만 들고 있고, 받는 것도 **쓰는 사람 컴퓨터**에서
18
+ * 한다. 읽고 배우는 것과 퍼 나르는 것의 경계가 거기다.
19
+ * 그래서 `--check` 도 우리 서버를 안 거친다 — 문서 사이트에 직접 붙는다.
20
+ *
21
+ * ★★--check 가 이 설치기의 존재 이유다
22
+ * 말로 「많습니다」 하지 않는다. **지금** 공개된 모델을 세고, 원장의 잰 날과 맞대 본다.
23
+ * 못 받으면 「못 봤다」고 한다 — 「그대로다」라고 하지 않는다.
24
+ */
25
+ import { execFileSync } from "node:child_process";
26
+ import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync } from "node:fs";
27
+ import { homedir, platform } from "node:os";
28
+ import { dirname, join } from "node:path";
29
+ import { fileURLToPath } from "node:url";
30
+ import { 링크, TAIL, 마지막 } from "./tail.mjs";
31
+
32
+ const HOME = homedir();
33
+ const 여기 = dirname(fileURLToPath(import.meta.url));
34
+ const 인자 = process.argv.slice(2);
35
+ const 확인만 = 인자.includes("--check");
36
+ const 미리보기 = 인자.includes("--dry-run");
37
+ const 여기에 = 인자.includes("--local");
38
+ const 자기시험모드 = 인자.includes("--self-test");
39
+
40
+ const c = { g: "\x1b[32m", r: "\x1b[31m", y: "\x1b[33m", d: "\x1b[90m", cy: "\x1b[36m", b: "\x1b[1m", 0: "\x1b[0m" };
41
+ const 굵게 = (t) => String(t).replace(/\*\*(.+?)\*\*/g, `${c[0]}${c.b}$1${c[0]}${c.d}`);
42
+ const 콤마 = (n) => Number(n).toLocaleString("ko-KR");
43
+
44
+ const 퍼널 = "sysprompt";
45
+ const 스킬이름 = "claude-system-prompt-guide";
46
+ const 원본 = join(여기, "skill");
47
+ const 대상뿌리 = 여기에 ? join(process.cwd(), ".claude", "skills") : join(HOME, ".claude", "skills");
48
+ const 대상 = join(대상뿌리, 스킬이름);
49
+
50
+ /* ══ 원장 ═══════════════════════════════════════════════════════ */
51
+
52
+ function 원장읽기() {
53
+ const p = join(원본, "sysprompt.json");
54
+ if (!existsSync(p)) return { 됨: false, 이유: `원장이 없다 — ${p}` };
55
+ try { return { 됨: true, d: JSON.parse(readFileSync(p, "utf8")) }; }
56
+ catch (e) { return { 됨: false, 이유: `원장을 못 읽는다 — ${e.message}` }; }
57
+ }
58
+
59
+ /** ★조건 없이 단정하는 말 [[kmong-no-unbounded-guarantee]] */
60
+ const 금칙 = [/완전\s*무료/, /무제한/, /평생/, /100\s*%\s*보장/, /누구나\s*바로/, /무조건/,
61
+ /설정\s*없이/, /깔면\s*끝/, /전혀\s*없/, /절대\s*안/];
62
+ const 금칙면제 = /(하지\s*않는다|말하지\s*마라|쓰지\s*않는다|아니다|틀리다|금칙|안\s*된다|하지\s*마라|말하지\s*않는다|은\s*아니다|되지\s*않는다|마라|않는다)/;
63
+ const 인용벗기기 = (s) => String(s).replace(/「[^」]*」/g, "○");
64
+
65
+ function 금칙검사(텍스트, 어디) {
66
+ const 문제 = [];
67
+ for (const 원줄 of String(텍스트).split(/\n|(?<=[.。])\s+/)) {
68
+ const 줄 = 인용벗기기(원줄);
69
+ if (금칙면제.test(줄)) continue;
70
+ for (const re of 금칙) if (re.test(줄)) 문제.push(`${어디}에 조건 없는 단정: ${re.source}`);
71
+ }
72
+ return 문제;
73
+ }
74
+
75
+ function 원장검사(d) {
76
+ const 문제 = [];
77
+ const 있나 = (v) => v !== undefined && v !== null && v !== "" && !(Array.isArray(v) && !v.length);
78
+
79
+ if (!있나(d?.확인일)) 문제.push("확인일이 없다 — 언제 잰 값인지 모르면 사실은 못 쓴다");
80
+ if (!있나(d?.확인방법)) 문제.push("확인방법이 없다 — 어디서 읽었는지 없는 말은 지어낸 것과 구분이 안 된다");
81
+ if (!있나(d?.한글이름)) 문제.push("한글이름이 없다 — 릴스 자막이 이 글자를 읽는다");
82
+
83
+ const S = d?.실측 || {};
84
+ for (const k of ["문서", "공개모델수", "합계자", "합계줄", "최신모델", "최신자", "최신줄",
85
+ "적용범위", "★API는아니다", "★한페이지에_여러날짜", "단일스냅샷모델", "★저작권"]) {
86
+ if (!있나(S[k])) 문제.push(`실측: ${k} 이 없다`);
87
+ }
88
+ if (있나(S.문서) && !/^https:\/\//.test(String(S.문서))) 문제.push("실측: 문서가 https 주소가 아니다");
89
+
90
+ /* ★★API 경고가 빠지면 이 킷이 있을 이유의 절반이 사라진다.
91
+ 공개본은 claude.ai 웹·앱 전용이다 — 그걸 모르고 API 에 같은 답을 기대하면 어긋난다. */
92
+ if (있나(S["★API는아니다"]) && !/API/i.test(String(S["★API는아니다"])))
93
+ 문제.push("실측.★API는아니다 에 API 이야기가 없다 — 문구가 갈아 끼워진 것이다");
94
+
95
+ const 명령 = d?.설치?.["★명령"];
96
+ if (!있나(명령)) 문제.push("설치.★명령 이 없다 — 이 문자열 하나를 릴스·착지·DM 이 같이 읽는다");
97
+ else if (!/^npx\s+--yes\s+reborn-sysprompt$/.test(String(명령)))
98
+ 문제.push(`설치.★명령 이 「npx --yes reborn-sysprompt」 가 아니다 — 지금 값: ${명령}`);
99
+
100
+ if (!Array.isArray(d?.["★공짜의범위"]?.["★따로_드는것"]) || d["★공짜의범위"]["★따로_드는것"].length < 3)
101
+ 문제.push("★공짜의범위.★따로_드는것 이 3줄 미만이다 — 값이 드는 자리를 안 말하면 공짜로 읽힌다");
102
+
103
+ if (!있나(d?.["★영상이_말하지_않은_것"]?.판정)) 문제.push("★영상이_말하지_않은_것.판정 이 없다 — 이 스킬이 있을 이유가 그 한 줄이다");
104
+
105
+ /* ★★재배포 금지 문장은 빼면 안 된다. 이건 편의 문구가 아니라 경계선이다. */
106
+ if (!있나(d?.["★안전"]?.재배포)) 문제.push("★안전.재배포 칸이 없다 — 원문을 담지 않는다는 경계가 사라진다");
107
+ if (!있나(d?.["★안전"]?.출처)) 문제.push("★안전.출처 칸이 없다 — 인용할 때 출처를 적으라는 문장이다");
108
+
109
+ 문제.push(...금칙검사(`${d?.한줄}\n${JSON.stringify(d?.["★영상이_말하지_않은_것"] || {})}`, "원장 본문"));
110
+ return 문제;
111
+ }
112
+
113
+ /* ══ 이 컴퓨터와 문서를 잰다 ════════════════════════════════════ */
114
+
115
+ function 실행파일있나(cmd) {
116
+ const 찾기 = platform() === "win32" ? "where" : "which";
117
+ try { execFileSync(찾기, [cmd], { stdio: "pipe", timeout: 4000 }); return true; }
118
+ catch { return false; }
119
+ }
120
+
121
+ /** 내가 고칠 수 있는 자리가 이 컴퓨터에 있나 — 원칙을 옮길 대상이다. */
122
+ function 내자리() {
123
+ const 후보 = [
124
+ { 이름: "홈 CLAUDE.md", p: join(HOME, ".claude", "CLAUDE.md") },
125
+ { 이름: "이 폴더 CLAUDE.md", p: join(process.cwd(), "CLAUDE.md") },
126
+ { 이름: "홈 스킬 폴더", p: join(HOME, ".claude", "skills") },
127
+ { 이름: "이 폴더 스킬", p: join(process.cwd(), ".claude", "skills") },
128
+ ];
129
+ return 후보.map((x) => ({
130
+ ...x,
131
+ 있나: existsSync(x.p),
132
+ 개수: existsSync(x.p) && statSync(x.p).isDirectory() ? readdirSync(x.p).length : null,
133
+ }));
134
+ }
135
+
136
+ /**
137
+ * ★★공개본을 **지금** 세어 본다. 우리 서버를 안 거치고 문서 사이트에 직접 붙는다.
138
+ * ★원문을 저장하지 않는다 — 길이만 세고 버린다. 그게 「읽는 것」과 「퍼 나르는 것」의 경계다.
139
+ * ★못 받으면 「못 봤다」고 한다. 「그대로다」라고 하지 않는다.
140
+ */
141
+ async function 문서재기(S, 초 = 20) {
142
+ const 결과 = { 됨: false, 이유: "", 모델수: null, 합계자: null, 목록: [] };
143
+ const ac = new AbortController();
144
+ const 타이머 = setTimeout(() => ac.abort(), 초 * 1000);
145
+ try {
146
+ const r = await fetch(`${S.문서}.md`, { signal: ac.signal });
147
+ if (!r.ok) { 결과.이유 = `목록을 못 받았다 (HTTP ${r.status})`; return 결과; }
148
+ const t = await r.text();
149
+ const 아이디 = [...new Set([...t.matchAll(/system-prompts\/(claude-[a-z0-9-]+)/g)].map((m) => m[1]))];
150
+ if (!아이디.length) { 결과.이유 = "목록에서 모델을 못 찾았다 — 문서 구조가 바뀌었을 수 있다"; return 결과; }
151
+ let 합 = 0;
152
+ for (const id of 아이디) {
153
+ try {
154
+ const rr = await fetch(`${S.문서}/${id}.md`, { signal: ac.signal });
155
+ if (!rr.ok) continue;
156
+ const body = (await rr.text()).replace(/^---[\s\S]*?---\n/, "");
157
+ 합 += body.length;
158
+ 결과.목록.push({ id, 자: body.length });
159
+ } catch { /* 한 개를 못 받아도 나머지는 센다 */ }
160
+ }
161
+ 결과.됨 = 결과.목록.length > 0;
162
+ 결과.모델수 = 결과.목록.length;
163
+ 결과.합계자 = 합;
164
+ if (!결과.됨) 결과.이유 = "본문을 하나도 못 받았다";
165
+ } catch (e) {
166
+ 결과.이유 = /abort/i.test(String(e.message)) ? `${초}초 안에 못 받았다` : String(e.message).slice(0, 80);
167
+ } finally { clearTimeout(타이머); }
168
+ return 결과;
169
+ }
170
+
171
+ function 이미깔렸나() {
172
+ const 자리 = [];
173
+ for (const 뿌리 of [join(HOME, ".claude", "skills"), join(process.cwd(), ".claude", "skills")]) {
174
+ const p = join(뿌리, 스킬이름);
175
+ if (existsSync(p) && statSync(p).isDirectory()) 자리.push({ 어디: p, 개수: readdirSync(p).length });
176
+ }
177
+ return 자리;
178
+ }
179
+
180
+ /* ══ 보고 ═══════════════════════════════════════════════════════ */
181
+
182
+ function 환경보고(D, 잰것, 자리, 클로드) {
183
+ const S = D.실측;
184
+ console.log(`\n${c.b}공개본을 지금 세어 봤습니다${c[0]} ${c.d}(원장은 ${D.확인일} 에 잰 값)${c[0]}\n`);
185
+
186
+ if (잰것.됨) {
187
+ const 모델차 = 잰것.모델수 - S.공개모델수;
188
+ const 자차 = 잰것.합계자 - S.합계자;
189
+ console.log(` 공개 모델 ${c.g}${잰것.모델수}개${c[0]} ${c.d}(원장 ${S.공개모델수}개${모델차 ? ` · ${모델차 > 0 ? "+" : ""}${모델차}` : " · 그대로"})${c[0]}`);
190
+ console.log(` 합계 글자 ${c.g}${콤마(잰것.합계자)}자${c[0]} ${c.d}(원장 ${콤마(S.합계자)}자${자차 ? ` · ${자차 > 0 ? "+" : ""}${콤마(자차)}` : " · 그대로"})${c[0]}`);
191
+ const 큰 = 잰것.목록.slice().sort((a, b) => b.자 - a.자).slice(0, 3);
192
+ console.log(` ${c.d}가장 긴 셋 — ${큰.map((x) => `${x.id} ${콤마(x.자)}자`).join(" · ")}${c[0]}`);
193
+ console.log(` ${c.d}★원문은 저장하지 않았습니다. 길이만 세고 버립니다.${c[0]}`);
194
+ } else {
195
+ console.log(` 공개 모델 ${c.y}못 봤습니다${c[0]} ${c.d}${잰것.이유}${c[0]}`);
196
+ console.log(` ${c.d}원장 값(${D.확인일} 실측) — 모델 ${S.공개모델수}개 · 합계 ${콤마(S.합계자)}자 · ${콤마(S.합계줄)}줄${c[0]}`);
197
+ console.log(` ${c.d}★「지금도 그대로다」라고 말하지 않습니다. 못 본 것과 그대로인 것은 다릅니다.${c[0]}`);
198
+ }
199
+
200
+ console.log(`\n${c.b}옮겨 붙일 자리${c[0]} ${c.d}(원칙을 여기에 옮깁니다)${c[0]}`);
201
+ for (const x of 자리) {
202
+ const 표 = x.있나 ? `${c.g}있음${c[0]}` : `${c.d}없음${c[0]}`;
203
+ console.log(` ${String(x.이름).padEnd(16)} ${표}${x.개수 != null ? ` ${c.d}(${x.개수}개)${c[0]}` : ""}`);
204
+ }
205
+ console.log(` ${String("Claude Code").padEnd(16)} ${클로드 ? `${c.g}있음${c[0]}` : `${c.d}없음 — 다른 도구에서도 됩니다${c[0]}`}`);
206
+
207
+ console.log(`\n${c.b}영상이 말하지 않은 것${c[0]}`);
208
+ for (const [k, v] of Object.entries(D["★영상이_말하지_않은_것"])) {
209
+ if (k.startsWith("_") || k === "판정") continue;
210
+ console.log(` ${c.d}${k} ${굵게(String(v))}${c[0]}`);
211
+ }
212
+ console.log(`\n ${c.b}판정${c[0]} ${c.d}${굵게(D["★영상이_말하지_않은_것"].판정)}${c[0]}`);
213
+
214
+ console.log(`\n${c.b}값이 드는 자리${c[0]}`);
215
+ for (const r of D["★공짜의범위"]["★따로_드는것"]) console.log(` ${c.d}· ${r.무엇} — ${r.값} (${r.근거})${c[0]}`);
216
+
217
+ console.log(`\n${c.b}선${c[0]}`);
218
+ for (const [k, v] of Object.entries(D["★안전"])) console.log(` ${c.d}${k} ${굵게(String(v))}${c[0]}`);
219
+
220
+ console.log(`\n${c.d}공개본은 앤트로픽이 자기 문서로 올려 둔 글입니다 — ${S.문서}${c[0]}\n`);
221
+ }
222
+
223
+ function 꼬리(깔았나) {
224
+ if (!깔았나) return;
225
+ const t = TAIL[퍼널];
226
+ console.log();
227
+ for (const 줄 of t.이음) console.log(`${c.d}${굵게(줄)}${c[0]}`);
228
+ console.log(`\n ${c.b}${t.제목}${c[0]} ${c.d}— ${t.한줄}${c[0]}`);
229
+ console.log(` ${c.cy}${링크(퍼널)}${c[0]}`);
230
+ console.log(`${c.d}${마지막}${c[0]}\n`);
231
+ }
232
+
233
+ /* ══ 심기 ═══════════════════════════════════════════════════════ */
234
+
235
+ function 심기() {
236
+ mkdirSync(대상뿌리, { recursive: true });
237
+ cpSync(원본, 대상, { recursive: true });
238
+ for (const f of ["SKILL.md", "sysprompt.json"]) {
239
+ const p = join(대상, f);
240
+ if (!existsSync(p)) throw new Error(`심었는데 ${f} 이 없다 — ${p}`);
241
+ if (readFileSync(p, "utf8").length < 200) throw new Error(`${f} 이 너무 짧다 — 복사가 끊긴 것 같다`);
242
+ }
243
+ const 원장 = JSON.parse(readFileSync(join(대상, "sysprompt.json"), "utf8"));
244
+ if (!원장?.실측?.문서) throw new Error("심은 원장에 문서 주소가 없다 — 복사가 깨졌다");
245
+ return 대상;
246
+ }
247
+
248
+ /* ══ 자기시험 — ★양방향 ═══════════════════════════════════════ */
249
+
250
+ function 자기시험() {
251
+ const 나쁨 = [];
252
+ const r = 원장읽기();
253
+ if (!r.됨) { console.log(`${c.r}✗ ${r.이유}${c[0]}`); process.exit(1); }
254
+ const D = r.d;
255
+
256
+ const 문제 = 원장검사(D);
257
+ if (문제.length) 나쁨.push(...문제.map((m) => `오탐 또는 진짜 문제: ${m}`));
258
+
259
+ const 흉내 = () => JSON.parse(JSON.stringify(D));
260
+ /* 미탐 ① 재배포 경계 문장을 지우면 잡아야 한다 — 이 킷의 경계선이다 */
261
+ { const x = 흉내(); delete x["★안전"].재배포;
262
+ if (!원장검사(x).some((m) => m.includes("재배포"))) 나쁨.push("미탐: 재배포 경계 문장을 지워도 통과한다"); }
263
+ /* 미탐 ② API 경고를 갈아 끼우면 잡아야 한다 */
264
+ { const x = 흉내(); x.실측["★API는아니다"] = "잘 됩니다";
265
+ if (!원장검사(x).some((m) => m.includes("API"))) 나쁨.push("미탐: API 경고를 갈아 끼워도 통과한다"); }
266
+ /* 미탐 ③ npx 에 --yes 가 빠지면 잡아야 한다 */
267
+ { const x = 흉내(); x.설치["★명령"] = "npx reborn-sysprompt";
268
+ if (!원장검사(x).some((m) => m.includes("--yes") || m.includes("★명령"))) 나쁨.push("미탐: --yes 를 빼도 통과한다"); }
269
+ /* 미탐 ④ 조건 없는 단정이 섞이면 잡아야 한다 */
270
+ { const x = 흉내(); x.한줄 = "누구나 바로 됩니다. 설정 없이 깔면 끝입니다.";
271
+ if (!원장검사(x).some((m) => m.includes("단정"))) 나쁨.push("미탐: 조건 없는 단정이 섞여도 통과한다"); }
272
+ /* 미탐 ⑤ 판정 한 줄이 빠지면 잡아야 한다 */
273
+ { const x = 흉내(); x["★영상이_말하지_않은_것"].판정 = "";
274
+ if (!원장검사(x).some((m) => m.includes("판정"))) 나쁨.push("미탐: 판정 한 줄을 지워도 통과한다"); }
275
+
276
+ if (!existsSync(join(원본, "SKILL.md"))) 나쁨.push("skill/SKILL.md 가 패키지에 없다 — 깔아도 빈 폴더가 된다");
277
+ if (!TAIL[퍼널]) 나쁨.push(`tail.mjs 에 「${퍼널}」 문안이 없다`);
278
+
279
+ /* ★★원문을 패키지에 담지 않았는지 **실제로** 본다 — 이 킷의 유일한 금기다.
280
+ 원장에 공개본 문장이 통째로 들어가 있으면 그건 재배포다. */
281
+ for (const f of readdirSync(원본)) {
282
+ const t = readFileSync(join(원본, f), "utf8");
283
+ if (t.length > 60000) 나쁨.push(`${f} 이 ${t.length}자다 — 공개본 원문이 섞여 들어갔는지 보라(재배포 금지)`);
284
+ }
285
+
286
+ if (나쁨.length) { for (const m of 나쁨) console.log(`${c.r}✗${c[0]} ${m}`); process.exit(1); }
287
+ console.log(`${c.g}✓${c[0]} 자기시험 통과 — 확인일 ${D.확인일} · 원장 검사기 미탐 5종 · 재배포 금지 검사 ${readdirSync(원본).length}개 파일`);
288
+ }
289
+
290
+ /* ══ 본체 ═══════════════════════════════════════════════════════ */
291
+
292
+ async function 본체() {
293
+ if (자기시험모드) return 자기시험();
294
+
295
+ const r = 원장읽기();
296
+ if (!r.됨) { console.log(`${c.r}✗ ${r.이유}${c[0]}`); process.exit(1); }
297
+ const D = r.d;
298
+ const 문제 = 원장검사(D);
299
+ if (문제.length) {
300
+ console.log(`${c.r}✗ 원장이 규격에 안 맞습니다 — 화면에 잘못된 사실이 나갈 수 있어 멈춥니다${c[0]}`);
301
+ for (const m of 문제) console.log(` ${c.d}· ${m}${c[0]}`);
302
+ process.exit(1);
303
+ }
304
+
305
+ const 잰것 = await 문서재기(D.실측);
306
+ 환경보고(D, 잰것, 내자리(), 실행파일있나("claude"));
307
+
308
+ if (확인만) {
309
+ console.log(`${c.d}재기만 했습니다 — 아무것도 깔지 않았습니다. 안내 스킬을 깔려면 ${c.cy}${D.설치["★명령"]}${c.d} 를 그냥 실행하세요.${c[0]}\n`);
310
+ return;
311
+ }
312
+
313
+ const 이미 = 이미깔렸나();
314
+ if (이미.length) {
315
+ for (const 자리 of 이미) console.log(`${c.g}✓${c[0]} ${자리.어디} 에 ${c.b}이미 있습니다${c[0]} ${c.d}(파일 ${자리.개수}개) — 또 깔지 마세요${c[0]}`);
316
+ console.log(`${c.d}다시 깔려면 그 폴더를 지우고 실행하세요.${c[0]}\n`);
317
+ return;
318
+ }
319
+
320
+ if (미리보기) {
321
+ console.log(`${c.d}깔 자리: ${대상}${c[0]}`);
322
+ console.log(`${c.d}넣을 것: ${readdirSync(원본).join(", ")}${c[0]}`);
323
+ console.log(`${c.d}미리보기라 아무것도 쓰지 않았습니다.${c[0]}\n`);
324
+ return;
325
+ }
326
+
327
+ let 깔았나 = false;
328
+ try {
329
+ const p = 심기();
330
+ console.log(`${c.g}✓${c[0]} 안내 스킬을 깔았습니다 — ${c.b}${p}${c[0]}`);
331
+ console.log(`${c.d}클로드 코드를 다시 시작하고 「공개본에서 배울 것 정리해 줘」라고 하시면 됩니다.${c[0]}`);
332
+ 깔았나 = true;
333
+ } catch (e) {
334
+ console.log(`${c.r}✗ 못 깔았습니다 — ${e.message}${c[0]}`);
335
+ console.log(`${c.d}문서 주소는 위에 적어 두었습니다. 안내 스킬 없이도 읽으실 수 있습니다.${c[0]}`);
336
+ process.exitCode = 1;
337
+ }
338
+ 꼬리(깔았나);
339
+ }
340
+
341
+ 본체();
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "reborn-sysprompt",
3
+ "version": "1.0.0",
4
+ "description": "앤트로픽이 공식으로 공개해 둔 Claude 시스템 프롬프트를 읽고, 거기서 뽑은 설계를 내 프롬프트·CLAUDE.md·스킬에 옮기게 돕는 안내 스킬입니다. 인터넷에 도는 「유출본」을 찾을 일이 아닙니다 — 2024년 8월부터 모델마다 공개돼 있습니다. --check 가 문서에 직접 붙어 지금 공개된 모델 수와 합계 길이를 세어 주고, 공개본이 claude.ai 웹·앱 전용이라 API 에는 안 붙는다는 것까지 알려 줍니다. 원문은 담지 않습니다.",
5
+ "keywords": [
6
+ "claude",
7
+ "claude-code",
8
+ "system-prompt",
9
+ "anthropic",
10
+ "prompt-engineering",
11
+ "prompting",
12
+ "claude-md",
13
+ "skills",
14
+ "korean"
15
+ ],
16
+ "homepage": "https://rebornlabs.kr/system-prompt?utm_source=installer&utm_medium=cli&utm_campaign=sysprompt",
17
+ "bugs": {
18
+ "url": "https://mobility.rebornlabs.kr/cs"
19
+ },
20
+ "license": "MIT",
21
+ "author": "REBORN LABS",
22
+ "type": "module",
23
+ "bin": {
24
+ "reborn-sysprompt": "cli.mjs"
25
+ },
26
+ "files": [
27
+ "cli.mjs",
28
+ "tail.mjs",
29
+ "skill/",
30
+ "README.md",
31
+ "안내스킬.md"
32
+ ],
33
+ "engines": {
34
+ "node": ">=18"
35
+ },
36
+ "scripts": {
37
+ "test": "node cli.mjs --self-test",
38
+ "check": "node cli.mjs --check"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ }
43
+ }
package/skill/SKILL.md ADDED
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: claude-system-prompt-guide
3
+ description: 앤트로픽이 **공식으로 공개해 둔** Claude 시스템 프롬프트(claude.ai 웹·iOS·안드로이드용)를 읽고, 거기서 뽑은 설계를 사용자의 프롬프트·CLAUDE.md·스킬에 옮기게 돕는다. 유출본이 아니라 공개 문서다. "시스템 프롬프트", "클로드 시스템 프롬프트", "공개본", "프롬프트 유출", "leaked system prompt", "앤트로픽 프롬프트", "프롬프트 잘 쓰는 법", "CLAUDE.md 어떻게 쓰지", "스킬 설명 어떻게 쓰지", "프롬프트 설계" 같은 이야기가 나올 때 쓴다.
4
+ ---
5
+
6
+ # Claude 시스템 프롬프트 공개본 — 읽는 법과 옮기는 법
7
+
8
+ 원장은 같은 폴더의 `sysprompt.json` 이다. **여기 적힌 숫자는 전부 거기서 온다.**
9
+ 이 문서에서 수치를 새로 지어내지 마라 — 원장을 읽고 말해라.
10
+
11
+ ## 0. 먼저 바로잡을 것 — 유출이 아니다
12
+
13
+ 인터넷에 「Claude 시스템 프롬프트 유출」이라는 글이 자주 돈다.
14
+ **앤트로픽은 이걸 원래 공개한다.** 2024년 8월부터 모델마다 올려 왔고,
15
+ 최신 모델도 그 목록에 있다. 주소는 원장 `실측.문서` 다.
16
+
17
+ 그러니 출처 모를 「유출본」을 찾을 일이 아니다 — **공식 문서에 같은 모델이 있으면 그쪽을 본다.**
18
+
19
+ ## 1. 무엇이 공개돼 있고 무엇은 아닌가 — 이 순서를 건너뛰지 마라
20
+
21
+ | | |
22
+ |---|---|
23
+ | **공개된 것** | claude.ai 웹 · iOS 앱 · 안드로이드 앱에 쓰는 시스템 프롬프트 |
24
+ | ★**아닌 것** | **API.** 문서가 못 박아 뒀다 — `These system prompt updates do not apply to the Claude API.` |
25
+
26
+ ★이걸 모르고 「클로드가 이렇게 답하더라」를 API 에 기대면 어긋난다.
27
+ API 로 부르면 이 프롬프트가 **안 붙는다.** 사용자가 API 를 쓰고 있으면 이 이야기를 먼저 한다.
28
+
29
+ ★그리고 길이를 맞댈 때 함정이 하나 더 있다 —
30
+ **4.6 세대 이전 모델의 페이지는 여러 날짜가 한 장에 쌓여 있다.**
31
+ 그 길이를 「프롬프트 하나의 길이」로 읽으면 틀린다.
32
+ 맞댈 거면 원장 `실측.단일스냅샷모델` 안에서만 맞댄다.
33
+
34
+ ## 2. 지금 상태를 먼저 잰다
35
+
36
+ ```
37
+ npx --yes reborn-sysprompt --check
38
+ ```
39
+
40
+ 문서에 직접 붙어 **지금** 공개된 모델 수와 합계 길이를 세고, 원장의 잰 날과 맞대 본다.
41
+ 못 받으면 「못 봤다」고 한다 — **「그대로다」라고 하지 않는다.**
42
+
43
+ ★원문은 저장하지 않는다. 길이만 세고 버린다.
44
+
45
+ ## 3. 무엇을 보나 — 문장이 아니라 설계
46
+
47
+ 사용자가 「그래서 뭘 베끼면 되냐」고 물으면 **거기서 멈추게 한다.**
48
+ 그 글은 claude.ai 라는 특정 제품·특정 모델을 위해 쓰인 것이라
49
+ 그대로 옮기면 내 일에 안 맞는 문장이 대부분이다.
50
+
51
+ 가져올 것은 이런 것들이다:
52
+
53
+ | 무엇을 보나 | 내 것에 어떻게 옮기나 |
54
+ |---|---|
55
+ | **어떤 순서로 말하나** — 무엇을 맨 앞에 두었나 | 내 프롬프트에서도 제일 자주 어기는 것을 맨 앞에 |
56
+ | **금지를 어떻게 쓰나** — 「하지 마라」에 늘 이유가 붙는가 | 이유 없는 금지는 지켜지지 않는다. 왜를 같이 적는다 |
57
+ | **예외를 어디에 두나** — 규칙 옆인가 따로인가 | 예외가 멀면 규칙만 읽고 어긴다 |
58
+ | **모호할 때 무엇을 하라고 하나** | 내 일에서 갈리는 자리를 찾아 같은 자리에 적는다 |
59
+ | **판이 올라갈 때 무엇이 바뀌었나** | 바뀐 줄이 그 팀이 실제로 밟은 사고다. 그게 제일 값지다 |
60
+
61
+ ★★**판 사이의 차이가 가장 값지다.** 같은 모델의 옛 판과 새 판을 맞대 보면
62
+ 「무엇을 겪고 이 줄을 넣었나」가 보인다. 완성본만 읽으면 그게 안 보인다.
63
+
64
+ ## 4. 옮길 자리
65
+
66
+ `--check` 가 이 컴퓨터에서 찾아 준다:
67
+
68
+ - `~/.claude/CLAUDE.md` — 모든 세션에 실린다. **여기에 넣는 것은 값이 비싸다**(호출마다 실림)
69
+ - 프로젝트 `CLAUDE.md` — 그 폴더에서만 실린다. 과제별 규칙은 여기로
70
+ - `~/.claude/skills/` — 필요할 때만 실린다. 긴 절차는 스킬로 내린다
71
+
72
+ ★긴 규칙을 전부 홈 `CLAUDE.md` 에 넣지 마라 — 매 호출 문맥에 실려 값이 든다.
73
+ **필요할 때만 실리는 자리**로 내리는 것 자체가 공개본에서 배울 수 있는 설계다.
74
+
75
+ ## 5. 인용할 때
76
+
77
+ - **원문을 통째로 옮겨 두지 마라.** 필요한 줄만, 짧게.
78
+ - **모델 이름과 문서 주소를 같이 적는다.** 출처 없이 옮기면 내가 쓴 글로 읽힌다.
79
+ - 우리 패키지도 원문을 담지 않는다 — 주소만 들고 있다. 같은 선을 지킨다.
80
+
81
+ ## 6. 안 되면 어디를 보나
82
+
83
+ | 증상 | 볼 곳 |
84
+ |---|---|
85
+ | `--check` 가 「못 봤다」고 한다 | 사내망·프록시. 문서 주소를 브라우저로 직접 열어 본다 |
86
+ | 모델 수가 원장과 다르다 | 정상이다 — 앤트로픽이 모델을 더 올린 것이다. 원장의 확인일을 보라 |
87
+ | API 로 불렀는데 답이 다르다 | §1. 공개본은 API 에 안 붙는다 |
88
+ | 길이가 이상하게 길다 | §1의 둘째 함정 — 4.6 세대 이전 페이지는 여러 판이 쌓여 있다 |
89
+
90
+ ## 7. 출처
91
+
92
+ 공개본은 **앤트로픽이 자기 문서로 올려 둔 글**이다. 원장 `실측.문서` 를 함께 말한다 —
93
+ 사람들이 직접 가서 볼 수 있어야 한다.
@@ -0,0 +1,72 @@
1
+ {
2
+ "_doc": "클로드 공개 시스템 프롬프트 사실 원장 — 릴스·착지·DM·설치기가 전부 이 파일 하나를 본다. 지어낸 숫자·지어낸 이름이 화면에 뜨지 않게 하는 것이 목적이다. 고칠 일이 생기면 여기부터 고친다.",
3
+ "확인일": "2026-09-04",
4
+ "확인방법": "공식 문서 platform.claude.com/docs/en/release-notes/system-prompts 의 목록 페이지를 읽어 공개 모델 18개를 뽑고, 각 모델의 `.md` 원문을 직접 받아 **프론트매터를 뺀 본문 길이를 세었다.** 사람이 기억으로 적은 값은 하나도 없다.",
5
+
6
+ "이름": "Claude 시스템 프롬프트 (공식 공개본)",
7
+ "한글이름": "시스템 프롬프트",
8
+ "한줄": "앤트로픽이 claude.ai·iOS·안드로이드 앱에 쓰는 시스템 프롬프트를 모델마다 공개해 둔 문서. 주요 AI 회사 중 이걸 공식으로 내놓는 곳은 여기뿐이다.",
9
+
10
+ "참고본": {
11
+ "계정": "@nick_saraev",
12
+ "파일": "문제해결/릴스/KakaoTalk_20260825_225643318.mp4",
13
+ "길이": 32.485,
14
+ "말한것": "Claude Fable 5 시스템 프롬프트가 인터넷에 통째로 유출됐다. 12만 자·1,500줄. 그걸 GLM 5.2·Kimi K2.7 같은 값싼 오픈소스 모델에 그대로 주입할 수 있다",
15
+ "★소재를_바꾼_이유": "참고본이 파는 것은 **유출된 사유 프롬프트의 재배포**이고, 그걸 경쟁 모델에 이식하라는 안내다. 라이선스가 없는 무단 공개물이라 무료 배포물로 만들면 우리가 그 배포자가 된다. 2026-09-04 대표 결정 = **소재를 공식 공개본으로 튼다.** 화면·자막 리듬·씬 순서는 참고본 그대로 간다.",
16
+ "★그런데_참고본이_놓친것": "**앤트로픽은 이걸 원래 공개한다.** 2024년 8월부터 모델마다 공개해 왔고 Fable 5 와 Fable 5.1 도 그 목록에 있다. 캘 필요가 없었다 — 문서에 있다."
17
+ },
18
+
19
+ "실측": {
20
+ "문서": "https://platform.claude.com/docs/en/release-notes/system-prompts",
21
+ "공개모델수": 18,
22
+ "합계자": 486045,
23
+ "합계줄": 3259,
24
+ "최신모델": "Claude Fable 5.1",
25
+ "최신자": 27974,
26
+ "최신줄": 194,
27
+ "최신주소": "https://platform.claude.com/docs/en/release-notes/system-prompts/claude-fable-5-1",
28
+ "가장오래된모델": "Claude Haiku 3",
29
+ "가장오래된자": 773,
30
+ "★자란배수": 36,
31
+ "★자란배수근거": "Haiku 3 의 773자에서 Fable 5.1 의 27,974자 — 36배. 둘 다 4.6 세대 이후 규격으로 세면 한 모델 = 한 스냅샷이라 서로 맞대 볼 수 있다",
32
+ "적용범위": "claude.ai 웹 · iOS 앱 · 안드로이드 앱",
33
+ "★API는아니다": "문서 원문: These system prompt updates do not apply to the Claude API. — API 로 부르면 이 프롬프트는 안 붙는다. 이걸 모르고 「클로드가 이렇게 답하더라」를 API 에 기대면 어긋난다",
34
+ "★한페이지에_여러날짜": "문서 원문: Some models have multiple dated entries on their pages. Starting with the Claude 4.6 generation, each model ID is a single fixed snapshot, so those models have one entry. — 그래서 4.6 세대 **이전** 모델의 페이지 길이는 프롬프트 하나의 길이가 아니라 **그 페이지에 쌓인 여러 판의 합**이다. 모델끼리 길이를 맞댈 때는 4.6 세대 이후끼리만 맞댄다",
35
+ "단일스냅샷모델": ["Claude Fable 5.1", "Claude Opus 5", "Claude Fable 5", "Claude Opus 4.8", "Claude Opus 4.7", "Claude Sonnet 4.6", "Claude Opus 4.6"],
36
+ "잰날": "2026-09-04",
37
+ "★저작권": "앤트로픽이 자기 문서로 공개한 글이다. **읽고 배우는 것과 통째로 퍼 나르는 것은 다르다.** 우리 패키지는 원문을 담지 않는다 — 주소만 들고 있고, 받는 것도 쓰는 사람 컴퓨터에서 한다"
38
+ },
39
+
40
+ "설치": {
41
+ "★명령": "npx --yes reborn-sysprompt",
42
+ "★무엇을하나": "공개본 18개를 **쓰는 사람 컴퓨터에서** 받아 ①판마다 무엇이 바뀌었는지 재고 ②거기서 뽑은 설계 원칙을 자기 프롬프트·CLAUDE.md·스킬에 옮기게 안내한다",
43
+ "★왜_우리것을_먼저": "문서는 공개돼 있고 우리가 대신 열어 준다고 아껴지는 게 없다. 실제로 막히는 자리는 **무엇을 보고 무엇을 옮길지**다 — 18개를 다 읽는 사람은 없고, 읽어도 「그래서 내 프롬프트를 어떻게 고치나」가 안 나온다."
44
+ },
45
+
46
+ "★영상이_말하지_않은_것": {
47
+ "유출이아니다": "**앤트로픽이 직접 공개한다.** 2024년 8월부터 모델마다 올려 왔고 Fable 5 와 Fable 5.1 도 그 목록에 있다. 「누가 캐냈다」가 아니라 문서에 있는 것이다.",
48
+ "API에는안붙는다": "공개본은 **claude.ai 웹·앱**에 쓰는 프롬프트다. 문서가 그렇게 못 박아 뒀다 — API 로 부르면 이 프롬프트가 안 붙는다. 이걸 모르고 API 에 같은 답을 기대하면 어긋난다.",
49
+ "길이를맞대는법": "4.6 세대 **이전** 모델 페이지는 여러 날짜가 한 장에 쌓여 있다. 그 길이를 프롬프트 하나의 길이로 읽으면 틀린다 — 맞댈 거면 4.6 세대 이후끼리 맞댄다.",
50
+ "복붙은답이아니다": "**남의 프롬프트를 통째로 옮겨 붙이는 것은 이 문서의 쓸모가 아니다.** 그 글은 claude.ai 라는 특정 제품·특정 모델을 위해 쓰인 것이라 내 일에는 안 맞는 문장이 대부분이다. 가져올 것은 문장이 아니라 **설계**다.",
51
+ "판정": "**남이 캐낸 비밀이 아니라 공개된 교재다.** 통째로 베끼라고 있는 게 아니라 읽고 원리를 가져가라고 있는 것이다. 이 차이를 모르면 복붙하고 결과가 나빠진다."
52
+ },
53
+
54
+ "★공짜의범위": {
55
+ "무료": [
56
+ "공식 문서 — 앤트로픽이 공개해 둔 것이라 값이 없다",
57
+ "우리 설치기와 안내 스킬 — 값이 없다",
58
+ "받아 보는 것 — 쓰는 사람 컴퓨터에서 받는다. 우리 서버를 안 거친다"
59
+ ],
60
+ "★따로_드는것": [
61
+ { "무엇": "읽는 시간", "값": "0원 · 18개 다 읽으면 두세 시간", "근거": "합계 486,045자 · 3,259줄 실측" },
62
+ { "무엇": "내 프롬프트를 고쳐 보는 시간", "값": "0원 · 한 번에 30분씩", "근거": "설계를 옮기는 일이라 한 번에 안 끝난다" },
63
+ { "무엇": "모델을 실제로 부르는 값", "값": "그 서비스 요금", "근거": "문서는 공짜지만 고친 프롬프트를 시험해 보는 호출은 아니다" }
64
+ ]
65
+ },
66
+
67
+ "★안전": {
68
+ "재배포": "**원문을 우리 패키지에 담지 않는다.** 주소만 들고 있고 받는 것도 쓰는 사람 컴퓨터에서 한다 — 읽고 배우는 것과 퍼 나르는 것의 경계가 거기다",
69
+ "출처": "인용할 때는 **모델 이름과 문서 주소**를 같이 적는다. 출처 없이 옮기면 내가 쓴 글로 읽힌다",
70
+ "유출본": "인터넷에 도는 「유출 프롬프트」는 출처도 시점도 확인할 수 없다. **공식 문서에 같은 모델이 있으면 그쪽을 본다** — 이 회차가 그 이야기다"
71
+ }
72
+ }
package/tail.mjs ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 「끝난 뒤 한 칸」 문안 — 정본은 `skillpack/tail_copy.mjs` 다.
3
+ * 사본이 여기 있는 이유는 하나뿐이다: npm 패키지는 폴더 밖을 import 할 수 없다.
4
+ * 고칠 일이 생기면 정본을 먼저 고치고 여기로 옮긴다. 반대로 하지 마라.
5
+ *
6
+ * 규율: ① 끝난 뒤 딱 한 칸 · ② 못 깔았으면 안 띄운다 · ③ 파일을 안 남긴다
7
+ * ④ 고지 블록 금지 · ⑤ 첫 줄은 방금 한 일에서 이어져야 한다
8
+ * ★클로드킷·자비스 풀스택은 여기서 말하지 않는다 — 스킬팩 구매 이후다(2026-08-24 전략).
9
+ */
10
+ export const 랜딩 = "https://rebornlabs.kr/skillpack";
11
+ export const 링크 = (퍼널) => `${랜딩}?utm_source=installer&utm_medium=cli&utm_campaign=${퍼널}`;
12
+
13
+ export const TAIL = {
14
+ sysprompt: {
15
+ 이음: [
16
+ "방금 한 일은 **공개본을 실제로 받아 세어 본 것**입니다 — 몇 개가 공개돼 있고, 얼마나 길고, 무엇이 바뀌었는지.",
17
+ "문서는 공개돼 있습니다. 막히는 자리는 **그래서 내 프롬프트를 어떻게 고치나**입니다.",
18
+ ],
19
+ 제목: "리본랩스 스킬팩",
20
+ 한줄: "같은 방식으로 골라 담은 48종을 한 줄로. 8,900원",
21
+ },
22
+ };
23
+
24
+ export const 마지막 = "목록과 직접 까는 명령까지 그 페이지에 그대로 적어 두었습니다. 안 사셔도 됩니다.";
@@ -0,0 +1,83 @@
1
+ # 안내스킬 — `claude-system-prompt-guide`
2
+
3
+ 이 패키지가 `~/.claude/skills/claude-system-prompt-guide/` 에 심는 것.
4
+
5
+ | 파일 | 무엇 |
6
+ |---|---|
7
+ | `SKILL.md` | 클로드가 읽는 안내. **답하는 순서**가 여기 있다 |
8
+ | `sysprompt.json` | **원장.** 모든 사실의 주인. 여기 없는 숫자·명령은 말하지 않는다 |
9
+
10
+ ★심는 것은 이 폴더 하나뿐이다. **공유 안내스킬에는 손대지 않는다.**
11
+
12
+ ## ★★★이 킷의 유일한 금기 — 원문을 담지 않는다
13
+
14
+ 우리가 소개하는 것은 **남의 저작물**이다. 앤트로픽이 자기 문서로 공개했지만
15
+ 공개했다는 것이 「퍼 날라도 된다」는 뜻은 아니다.
16
+
17
+ 그래서 선을 하나 그었다:
18
+
19
+ | 한다 | 안 한다 |
20
+ |---|---|
21
+ | 문서 **주소**를 들고 다닌다 | 문서 **원문**을 패키지에 담는다 |
22
+ | 쓰는 사람 컴퓨터에서 받아 **길이를 센다** | 받은 원문을 **저장한다** |
23
+ | 필요한 줄을 **출처와 함께** 인용한다 | 통째로 옮겨 붙인다 |
24
+
25
+ ★`cli.mjs --self-test` 가 이걸 **실제로 본다** — `skill/` 안의 파일이
26
+ 60,000자를 넘으면 「원문이 섞여 들어갔는지 보라」로 막는다.
27
+ 사람이 기억해야 하는 절차는 반드시 언젠가 빠진다.
28
+
29
+ ## 왜 원장을 따로 두나
30
+
31
+ 사실을 `SKILL.md` 본문에 적으면 두 곳이 서로 다른 말을 하기 시작한다.
32
+ 공개 모델 수·합계 길이·문서 주소·확인일은 **한 곳에서만** 나온다 [[one-metric-one-owner]].
33
+
34
+ ★특히 **문서 주소**가 그렇다. 릴스 자막·착지 페이지·DM·`--check` 가
35
+ 전부 원장의 `실측.문서` 를 읽어 간다. 손으로 옮겨 적으면 어느 한 곳이 조용히 어긋난다.
36
+
37
+ ## ★이 킷의 존재 이유는 두 문장이다
38
+
39
+ 참고본(그리고 인터넷의 여러 글)은 **「유출됐다」**고 말한다. 그게 이 회차의 출발점이다.
40
+
41
+ - ① **유출이 아니다.** 앤트로픽이 2024년 8월부터 모델마다 공개해 왔다.
42
+ 최신 모델도 그 목록에 있다. 캘 필요가 없었다 — 문서에 있다.
43
+ - ② **통째로 복붙하는 건 답이 아니다.** 그 글은 claude.ai 라는 특정 제품·특정 모델을 위해
44
+ 쓰인 것이라 내 일에는 안 맞는 문장이 대부분이다. 가져올 것은 문장이 아니라 **설계**다.
45
+
46
+ 원장에서 `★영상이_말하지_않은_것.판정` 을 지우면 설치기가 **깔지 않고 멈춘다.**
47
+ 그게 없으면 우리는 인터넷의 다른 글과 똑같은 말만 하는 패키지가 되기 때문이다.
48
+
49
+ ## ★API 경고는 빼면 안 된다
50
+
51
+ 공개본은 **claude.ai 웹·iOS·안드로이드 앱**에 쓰는 프롬프트다.
52
+ 문서 원문이 `These system prompt updates do not apply to the Claude API.` 라고 못 박아 뒀다.
53
+
54
+ 이걸 모르고 API 에 같은 답을 기대하면 어긋난다.
55
+ 원장의 `실측.★API는아니다` 가 비거나 API 이야기가 사라지면 설치기가 막는다.
56
+
57
+ ## ★못 본 것과 그대로인 것은 다르다
58
+
59
+ `--check` 는 문서에 직접 붙어 **지금** 공개된 모델을 센다.
60
+ 사내망·프록시로 못 받는 일이 있다 — 그때는 **「못 봤다」**고 한다.
61
+
62
+ 「원장 값이 있으니 그대로일 것이다」로 넘어가지 않는다.
63
+ 그 한 줄이 [[fail-closed-defaults-must-not-be-reported-as-measurements]] 다 —
64
+ 방어값을 실측치로 보고하면 사람이 잘못된 수를 믿는다.
65
+
66
+ ## ★숫자는 잰 값만 쓴다
67
+
68
+ 2026-09-04 에 공식 문서 목록과 각 모델의 `.md` 원문을 직접 받아
69
+ **프론트매터를 뺀 본문 길이**를 세었다. 기억으로 적은 값은 하나도 없다.
70
+
71
+ ★**길이를 함부로 맞대지 않는다** — 4.6 세대 이전 모델의 페이지는 여러 날짜가 한 장에
72
+ 쌓여 있어서, 그 길이는 프롬프트 하나의 길이가 아니다.
73
+ 원장이 `단일스냅샷모델` 목록을 따로 들고 있는 이유다.
74
+
75
+ ## 자기시험
76
+
77
+ ```
78
+ node cli.mjs --self-test
79
+ ```
80
+
81
+ 원장 검사기를 **양방향으로** 시험하고(오탐 1 + 미탐 5),
82
+ `skill/` 안의 파일 크기를 재서 **원문이 섞여 들어갔는지**까지 본다.
83
+ 전건 통과나 전건 실패는 고장 신호다 [[verifier-must-be-tested-both-ways]].