From teamclco-harness
회의 녹음/텍스트 노트에서 구조화된 회의록을 마크다운 정본 + PDF(Pretendard) + Google Docs 3산출물로 자동 생성한다. 산출물은 프로젝트 meetings/<YYYYMMDD_제목>/ 폴더에 1차 정본으로 저장한다. "회의록 만들어", "회의록 작성", "미팅 정리", "녹음 파일 분석", "회의 정리", "회의 내용 정리", "STT 변환", "화자분리", "액션아이템 추출", "미팅 요약" 같은 요청, 또는 녹음 파일 경로 (.m4a/.wav/.mp3)나 회의 텍스트 노트가 주어지면 다른 도구로 직접 처리하지 말고 반드시 이 스킬을 사용하라. 회의록을 만든 뒤 발송까지 요청되면 이 스킬이 meeting-mail 스킬을 이어서 호출한다.
How this skill is triggered — by the user, by Claude, or both
Slash command
/teamclco-harness:meeting-minutesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> 비유: 회의를 받아 적는 전담 서기. 녹음이든 메모든 받아서, 누구나 읽기 쉬운 정식 회의록으로 정리하고, 인쇄용 PDF와 공유용 Google Docs까지 만들어 회의 폴더에 가지런히 보관한다.
비유: 회의를 받아 적는 전담 서기. 녹음이든 메모든 받아서, 누구나 읽기 쉬운 정식 회의록으로 정리하고, 인쇄용 PDF와 공유용 Google Docs까지 만들어 회의 폴더에 가지런히 보관한다.
회의 입력(녹음 파일 경로 또는 텍스트 노트)을 받아 마크다운 정본 → PDF(Pretendard) → Google Docs 3산출물을 만들고, 프로젝트 meetings/<YYYYMMDD_제목>/ 폴더에 저장한다. 무거운 STT·화자분리는 기존 자산을 재사용하고, 이 스킬은 회의록 구조화 + 2포맷 변환 + 저장 + (선택) 발송 체이닝을 책임진다.
meetings/<날짜_제목>/가 1차 정본 (글로벌 ~/meeting-automation/ 출력 폴더에 산출물을 남기지 않는다 — data-policy.md /meeting 예외).~/meeting-automation/는 미설치일 수 있으므로 Step 1에서 존재를 확인하고 폴백).scripts/)이 스킬의 base directory를 $SKILL_DIR이라 하자 (스킬 로드 시 안내되는 절대경로 = $HOME/팀클코/.claude/skills/meeting-minutes). 아래 두 스크립트는 매번 인라인으로 재작성하지 말고 그대로 호출한다.
$SKILL_DIR/scripts/create_gdoc.py — Google Docs 생성 + gws 출력 오염 방어 파싱(헤더 줄/제어문자) 내장. Step 4에서 사용.$SKILL_DIR/scripts/make_image_pdf.py — 텍스트 PDF → 이미지 PDF(폰트 0). Step 3.5 선택 단계에서 사용.회의록 마크다운 표준 구조는 $SKILL_DIR/references/minutes-template.md에 있다. Step 2에서 참조한다.
입력을 두 갈래로 분류한다.
.m4a/.wav/.mp3) → Step 1a (STT).txt/.md 경로) → Step 1b (STT 건너뜀)날짜·제목을 정하고 저장 폴더를 만든다. 날짜는 암산하지 말고 date로 구한다.
DATE=$(date +%Y%m%d)
TITLE="<회의제목_kebab_또는_한글>" # 예: 아가방-코칭-1회차
OUTDIR="$(pwd)/meetings/${DATE}_${TITLE}"
mkdir -p "$OUTDIR"
echo "저장 폴더: $OUTDIR"
기존 STT 파이프라인을 존재 확인 후 사용한다. 없으면 폴백한다.
if [ -d "$HOME/meeting-automation" ] && [ -f "$HOME/meeting-automation/process_meeting.py" ]; then
echo "STT 파이프라인 발견 — 실행"
WORK_DIR="$OUTDIR/work"; mkdir -p "$WORK_DIR" # 글로벌 출력 금지, OUTDIR 하위 고정
python3 "$HOME/meeting-automation/process_meeting.py" "<음성파일경로>" "$WORK_DIR"
# 산출: $WORK_DIR/transcript.txt (+ speakers.json 있으면 화자 매핑)
else
echo "주의: ~/meeting-automation 파이프라인이 설치되지 않았습니다. 폴백을 선택하세요."
fi
meeting-secretary 에이전트가 존재하면 Agent 도구(subagent_type: meeting-secretary)로 STT·화자분리를 위임하고 반환된 전사를 Step 2로 잇는다.붙여넣은 텍스트(또는 .txt/.md)를 읽어 발화 흐름을 정리한다. 화자 라벨이 있으면 보존한다.
$SKILL_DIR/references/minutes-template.md의 표준 구조로 전사/노트를 정리해 $OUTDIR/minutes.md에 Write로 저장한다. 결론(요약 3줄)을 맨 앞에 둔다.
회의록에 다음 회의·마감·후속 미팅 + 시각이 명시되면, 되묻지 말고 즉시 gws calendar +insert로 Google Calendar에 등록한다(data-policy.md Calendar 의무). 업무 일정은 primary(생략), 개인 키워드면 개인 캘린더 ID. 시간 미확정이면 description에 "(시간 미확정)".
gws calendar +insert --summary '[회의] 후속 미팅' \
--start '2026-07-01T10:00:00+09:00' --end '2026-07-01T11:00:00+09:00' \
--description '안건: ...'
분류기 게이트 (학습 교훈 — 우회 금지): "회의록만" 요청한 맥락에서는, 회의록 본문에서 시각을 추론해 만든 캘린더 이벤트가 Claude Code auto-mode 권한 분류기에 의해 [External System Writes]로 거부될 수 있다(사용자 메시지가 캘린더를 명시 요청하지 않았다고 판단). 이는 정상 분기다 — 무리하게 우회하지 말 것. 거부된 일정은 회의록 본문/
links.txt에 그대로 남겨 추적 가능하게 두고, 최종 보고에 "캘린더 N건 등록, M건 거부(사유)"를 명시한다. 시각 미확정 마감을 09:00 등 임의 시각으로 가설 등록하면 거부 트리거가 높아진다 — 확정 시각이 있는 일정은 통과율이 높다. 사용자가 "일정도 등록해줘"라고 명시하면 분류기가 통과시킨다.
마크다운 정본을 글로벌 변환 스크립트 md-to-docx/convert.py로 DOCX+PDF로 만든다. 이는 Skill이 아니라 Bash로 실행하는 스크립트다(set_korean_font/enforce_fonts/postprocess_zip_fonts 3단으로 Pretendard를 ascii/hAnsi/eastAsia/cs 4속성에 강제). 9종 Pretendard OTF가 ~/Library/Fonts/에 설치돼 LibreOffice가 임베드한다.
python3 $HOME/qjc-office/dotclaude/scripts/md-to-docx/convert.py \
"$OUTDIR/minutes.md" --pdf
# 산출: $OUTDIR/minutes.docx + minutes.pdf (LibreOffice headless = /opt/homebrew/bin/soffice 경유)
정확한 인자(
--out등)는 실행 전python3 .../convert.py --help로 확인한다.
PDF는 weasyprint가 아니라 LibreOffice 경유라 라틴 기호 누락 위험은 낮지만, 검증은 harness Read가 아니라 사용자 실제 렌더러(Quick Look)로 한다(html-to-pdf-fonts.md 교훈).
pdffonts "$OUTDIR/minutes.pdf" # 비-Pretendard 폴백 점검
qlmanage -t -s 1600 -o "$OUTDIR" "$OUTDIR/minutes.pdf" 2>/dev/null # 사용자 뷰어 썸네일
echo "검증: $OUTDIR/minutes.pdf.png 에서 한글/특수문자(%, ₩, →) 정상 표시 확인"
python3 "$SKILL_DIR/scripts/make_image_pdf.py" --pdf "$OUTDIR/minutes.pdf"
# 산출: $OUTDIR/minutes-final.pdf (폰트 0 — 모든 뷰어 동일). 실패해도 rc=0으로 텍스트 PDF 유지.
마크다운 본문으로 Google Docs를 만든다. 번들 스크립트를 사용한다 — gws 출력 오염(keyring 헤더 줄 + 제어문자)을 방어하는 안전 파서가 내장돼, 인라인 파이프의 조용한 실패(빈 documentId → 중복 빈 문서 양산)를 막는다.
DOC_JSON=$(python3 "$SKILL_DIR/scripts/create_gdoc.py" \
--title "[회의록] $TITLE $DATE" --markdown-file "$OUTDIR/minutes.md")
echo "$DOC_JSON" # {"documentId":"...","url":"https://docs.google.com/document/d/.../edit"}
DOC_URL=$(printf '%s' "$DOC_JSON" | python3 -c "import json,sys; print(json.load(sys.stdin)['url'])")
Google Docs는 API로 폰트를 강제 지정할 수 없고 클라이언트가 렌더한다. 수신자 환경에 Pretendard가 없으면 폴백(Noto Sans/Arial)된다. 따라서 **정확한 한글 타이포의 정본은 PDF(minutes.pdf / minutes-final.pdf)**이고, Google Docs는 편집·공유 링크용이다.
cat > "$OUTDIR/links.txt" <<EOF
markdown: $OUTDIR/minutes.md
pdf: $OUTDIR/minutes.pdf
pdf_img: $OUTDIR/minutes-final.pdf (있으면)
gdocs: $DOC_URL
EOF
ls -lh "$OUTDIR"
.gitignore로 제외하고 gdrive:// 경로만 마크다운에 참조한다. 텍스트/PDF는 커밋 가능.사용자가 "발송"/"메일 보내"를 요청하거나 회의록 생성과 함께 발송이 지시된 경우에만, Skill 도구로 meeting-mail 스킬을 이어서 실행한다. 스킬은 메인 세션 인라인 실행이므로 직전 산출물 경로가 그대로 공유된다 — meeting-mail에 다음을 그대로 넘긴다.
$OUTDIR/minutes-final.pdf(있으면) 또는 $OUTDIR/minutes.pdf$DOC_URL$TITLE / $DATEmeeting-mail 기본값([email protected]) 사용meeting-mail은 외부 발송이라 미리보기 → 사용자 명시 승인 게이트를 자체 통과한다. 이 스킬은 발송을 강제하지 않는다(요청 없으면 산출물 경로만 반환).
~/meeting-automation/meeting-output/에 산출물 고립 (프로젝트 폴더 1차 정본 위반)harness Read로 PDF 깨짐 검증 (시스템 폰트로 항상 정상 표시 — qlmanage/pdffonts 사용)--help·test -f로 확인)create_gdoc.py 사용 — 빈 ID/중복 빈 문서 방지)Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub sangrokjung/samsung-gen-ai-260624 --plugin teamclco-harness