CLAUDE.md
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
bundle install # 의존성 설치
bundle exec jekyll serve # 로컬 서버 (http://localhost:4000)
bundle exec jekyll build # 사이트 빌드
bundle exec rake preview # 테마 테스트 (http://localhost:4000/test/)
bundle exec rake js # JS 번들 빌드
bundle exec rake version # 버전 일괄 업데이트
Architecture
이 저장소는 Minimal Mistakes Jekyll 테마 소스(v4.27.3)이자 개인 블로그 https://tigerjk9.github.io 이다.
테마 파일(_layouts, _includes, _sass, assets/)은 gem 대신 프로젝트 내에서 직접 사용된다.
docs/, test/는 업스트림 테마 전용 — _config.yml exclude 목록에 포함되어 블로그 빌드에서 제외된다.
Blog Content
- 포스트:
_posts/YYYY-MM-DD-slug.md— front matter:title,date,categories(배열),tags(배열) 필수 - 이미지:
assets/에 flat 저장 (서브디렉토리 없음), 예:/assets/post-slug-1.jpg - 내비게이션:
_data/navigation.yml— 상단 메뉴 정의 - 사이트 설정:
_config.yml— localeko-KR, dark skin, Giscus 댓글(기본 비활성), Google AnalyticsG-Y8TNBPZQEZ - timezone:
_config.yml에timezone: Asia/Seoul반드시 설정. 미설정 시 KST 당일 포스트가 UTC 기준 future로 판단되어 GitHub Pages에서 숨겨짐.
포스트 기본 레이아웃은 single (author profile, read time, related posts 활성화). 댓글은 기본 비활성; 활성화하려면 front matter에 comments: true 추가.
Custom Features
3D Knowledge Graph (/knowledge-graph/):
- 페이지:
knowledge-graph.md(layoutwide) - 그래프 데이터: Liquid 템플릿
graph-data.json,knowledge-graph.json이 빌드 시 포스트 태그를 집계해 노드/엣지 JSON 생성 - 시각화: Three.js + D3 + 3d-force-graph (CDN). 노드 = 포스트·태그, 엣지 = 태그 관계
Custom Sidebar (_includes/sidebar/):
categories.html— 카테고리별 포스트 수tag_cloud.html— 태그 클라우드_config.yml의sidebar키에서 설정
Theme Customization
파일 탐색 순서: 프로젝트 파일 → gem 파일. _includes/, _layouts/, _sass/, assets/에 놓으면 gem 파일을 덮어씀.
커스텀 스타일 오버라이드: assets/css/main.scss.
주의:
_sass/minimal-mistakes/_sidebar.scss에.sidebar.sticky { max-height: calc(100vh - #{$nav-height} - 2em) }하드코딩 →main.scss오버라이드에!important필수.
Custom UI Features
| 기능 | 주요 파일 |
|---|---|
| 다크/라이트 모드 토글 | assets/js/theme-toggle.js, _includes/masthead.html |
| 모바일 사이드바 테마 토글 | assets/js/sidebar-toggle.js (injectMobileSidebarHeader) |
| 본문 복사 버튼 (모든 포스트) | assets/js/post-copy.js, _layouts/single.html |
| 사이드바 섹션 접기/펼치기 | assets/js/sidebar-toggle.js (initSectionCollapse), _includes/sidebar.html |
다크/라이트 모드: html[data-theme="light"] CSS 레이어 방식. 컴파일된 dark skin 위에 light 오버라이드 덮기. anti-FOUC 인라인 스크립트를 _includes/head.html CSS <link> 이전에 삽입. theme-toggle.js는 이벤트 위임 방식 — masthead와 모바일 사이드바의 .theme-toggle 버튼 모두 처리.
모바일 사이드바: injectMobileSidebarHeader()가 사이드바 최상단에 .sidebar-mobile-header(테마 토글 포함)를 주입. iOS Safari dvh 버그는 height: 100dvh; max-height: 100dvh로 수정.
본문 복사: .page__content DOM 클론 → .sidebar__right, [rel="permalink"], .sr-only 제거 → innerText 복사.
사이드바 섹션 높이: 데스크톱 max-height: calc(50vh - 175px) !important — 두 섹션 합산 시 페이지네이션 라인 근방에서 끝남. 내부 스크롤(얇은 4px 스크롤바) 유지.
JS 번들 주의사항 (CRITICAL)
브라우저는 assets/js/main.min.js 번들을 로드한다. 소스 플러그인 파일(assets/js/plugins/jquery.greedy-navigation.js 등) 직접 편집은 브라우저에 반영되지 않는다.
JS 수정 방법:
- 재빌드 방식 (권장): 소스 파일 편집 후
bundle exec rake js실행 - 직접 패치 (빠른 수정): Python으로
main.min.js문자열 치환 (open/read/replace/write)
Greedy-nav 커스텀 버튼: nav에 커스텀 버튼(.theme-toggle 등)을 추가하면 availableSpace 계산에서 해당 버튼 폭을 빼야 한다. 미적용 시 메뉴 항목이 잘려서 표시됨. main.min.js에 $themeToggle.outerWidth(!0) 차감 패치 적용됨.
PDF 논문 → 블로그 포스트 자동화 (/paper)
scripts/pdf_to_post.py가 PDF 논문을 한국어 Jekyll 포스트로 자동 변환한다.
Claude Code에서는 /paper <PDF경로> 슬래시 커맨드로 호출한다 (.claude/commands/paper.md).
python scripts/pdf_to_post.py _papers/paper.pdf # 변환 + git push
python scripts/pdf_to_post.py _papers/paper.pdf --dry-run
python scripts/pdf_to_post.py _papers/paper.pdf --no-push
- 환경변수:
GEMINI_API_KEY—.env파일에서 자동 로드 (gitignore 등록됨) - 의존성:
google-generativeai,pdfplumber,PyMuPDF - 포스트 구조 (고정): 6개 섹션 (연구목적 → 방법 → 발견 → 결론 → ADD One → 탐구질문) + APA 출처
- Figure 자동 추출: PyMuPDF로 300×200px 이상 이미지 최대 6개 추출 →
assets/저장 → 멀티모달 삽입 - APA 출처: URL/DOI 미포함. Gemini가 생성하는 링크는 신뢰할 수 없으므로 텍스트 출처만 기재한다 (
scripts/prompt_template.txt규칙)
YouTube 영상 → 블로그 포스트 자동화 (/video)
scripts/yt_to_post.py가 YouTube URL을 한국어 Jekyll 포스트로 자동 변환한다.
Claude Code에서는 /video <URL> 스킬로 호출한다.
python scripts/yt_to_post.py <URL> # 변환 + git push
python scripts/yt_to_post.py <URL> --dry-run # 출력만
python scripts/yt_to_post.py <URL> --no-push # 로컬 저장만
python scripts/yt_to_post.py <URL> --lang en # 영어 자막 우선
- 환경변수:
GEMINI_API_KEY—.env파일에서 자동 로드 (gitignore 등록됨) - 의존성:
google-generativeai,yt-dlp,youtube-transcript-api
자막 추출 우선순위
youtube-transcript-api— 수동/자동자막 (ko → en)yt-dlpVTT 자동자막 (SSL 우회 포함)- 영상 description으로 대체
포스트 스타일
- 문체:
~이다,~한다단정체. 존칭/명사형 어미 금지. - 분량: 자막 내용을 빠짐없이 다룸 (생략 없음)
- 구조: 도입부 → 본문(영상 흐름 따라 자유 섹션) → 크로스오버 섹션 → 출처
- 크로스오버: 실행마다 20개 분야 풀에서
random.choice()로 선택 → 프롬프트에 주입- 풀 예시: 신경과학, 행동경제학, 언어학, 음악이론, 요리과학, 스포츠과학, 도시계획, 연극학, 진화생물학, 철학, 인류학, 물리학, 면역학, 정보이론 등
- 슬러그: Gemini가 front matter의
slug:필드로 영문 생성 → 스크립트가 파일명으로 사용 후 필드 제거
파일 구조
scripts/
yt_to_post.py # YouTube → 포스트 변환 스크립트
yt_prompt_template.txt # Gemini 프롬프트 ({CROSSOVER_DOMAIN} 플레이스홀더 포함)
pdf_to_post.py # PDF → 포스트 변환 스크립트
prompt_template.txt # Gemini 프롬프트 (APA 출처 URL 제외 규칙 포함)
requirements.txt # Python 의존성 (pdf + yt 통합)
.env # GEMINI_API_KEY 저장 (gitignore, 두 스크립트 공통)
.env.example # 키 형식 예시 (git 추적됨)
.claude/commands/video.md # /video 슬래시 커맨드
.claude/commands/paper.md # /paper 슬래시 커맨드
알려진 동작 특성
- Gemini가
date:연도를 임의로 바꾸는 버그 있음 → 스크립트가 생성 후 강제 복원 - 한국어 제목에서 슬러그 직접 추출 불가 → Gemini slug 생성으로 해결
- 기업 네트워크 SSL 인증서 오류 →
ssl._create_unverified_context+ requests 세션 패치로 우회
공통: git push 주의사항
원격에 로컬에 없는 커밋이 있으면 push가 실패한다:
git stash
git pull origin main --rebase
git stash pop
git push origin main
공통: 주요 카테고리·태그
카테고리 (빈도순): AI, 교육, 학습과학, AI디지털기반교육혁신, 철학, 인지과학, 바이브코딩, 코딩
태그 (빈도순 상위): 이미지, 논문리뷰, 바이브코딩, AI, 생성형AI, 학습과학, 교육, LLM, 메타인지, AI윤리, 에듀테크, 교육공학, 자기조절학습, 피드백, 프롬프트엔지니어링