kakaotalk-chat-analyzer 0.16.1 → 0.16.3
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 +126 -232
- package/dist/src/aggregator.d.ts +5 -1
- package/dist/src/aggregator.js +14 -6
- package/dist/src/aggregator.js.map +1 -1
- package/dist/src/analysis-profile.d.ts +10 -0
- package/dist/src/analysis-profile.js +23 -0
- package/dist/src/analysis-profile.js.map +1 -0
- package/dist/src/analysis.d.ts +7 -0
- package/dist/src/analysis.js +37 -10
- package/dist/src/analysis.js.map +1 -1
- package/dist/src/analyze-pool.js +5 -0
- package/dist/src/analyze-pool.js.map +1 -1
- package/dist/src/analyze-worker.js.map +1 -1
- package/dist/src/cli.js +4 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/keyword-merge.d.ts +1 -1
- package/dist/src/keyword-merge.js +2 -2
- package/dist/src/keyword-merge.js.map +1 -1
- package/dist/src/keyword-rank.js +2 -0
- package/dist/src/keyword-rank.js.map +1 -1
- package/dist/src/semantic-keywords.d.ts +1 -0
- package/dist/src/semantic-keywords.js +7 -6
- package/dist/src/semantic-keywords.js.map +1 -1
- package/dist/src/semantic-policy.d.ts +2 -1
- package/dist/src/semantic-policy.js +26 -13
- package/dist/src/semantic-policy.js.map +1 -1
- package/dist/src/version.d.ts +2 -2
- package/dist/src/version.js +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,33 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
# KakaoTalk Chat Analyzer
|
|
4
4
|
|
|
5
|
-
### 카카오톡 CSV 보내기 →
|
|
5
|
+
### 카카오톡 CSV 보내기 → 터미널 한 줄 → 브라우저 리포트 링크
|
|
6
6
|
|
|
7
7
|
[](./LICENSE)
|
|
8
8
|
[](https://nodejs.org/)
|
|
9
9
|
[](https://claudianus.github.io/kakaotalk-chat-analyzer/)
|
|
10
10
|
[](https://www.npmjs.com/package/kcachat)
|
|
11
|
-
[](https://www.npmjs.com/package/kakaotalk-chat-analyzer)
|
|
12
11
|
|
|
13
|
-
[**랜딩 (GitHub Pages)**](https://claudianus.github.io/kakaotalk-chat-analyzer/) · [
|
|
14
|
-
|
|
15
|
-
카카오톡 **CSV 보내기** → 터미널 **한 줄** → 브라우저에서 읽는 Wrapped·차트 리포트 링크.
|
|
12
|
+
[**랜딩 (GitHub Pages)**](https://claudianus.github.io/kakaotalk-chat-analyzer/) · [**소스**](https://github.com/claudianus/kakaotalk-chat-analyzer) · [**이슈**](https://github.com/claudianus/kakaotalk-chat-analyzer/issues)
|
|
16
13
|
|
|
17
14
|
```bash
|
|
18
15
|
npx kcachat@latest
|
|
19
16
|
```
|
|
20
17
|
|
|
21
|
-
[Node.js 22+](https://nodejs.org/) ·
|
|
18
|
+
[Node.js 22+](https://nodejs.org/) · 설치 없이 `npx` · CSV 경로 생략 가능 · [`--local`](#업로드-없이-내-pc에만)
|
|
22
19
|
|
|
23
20
|
<table>
|
|
24
21
|
<tr>
|
|
25
|
-
<td align="center" width="33%"><strong>Wrapped</strong><br><img src="docs/assets/demo/wrapped.png" alt="Wrapped
|
|
26
|
-
<td align="center" width="33%"><strong>차트</strong><br><img src="docs/assets/demo/charts.png" alt="
|
|
27
|
-
<td align="center" width="33%"><strong>키워드</strong><br><img src="docs/assets/demo/keywords.png" alt="키워드
|
|
22
|
+
<td align="center" width="33%"><strong>Wrapped</strong><br><img src="docs/assets/demo/wrapped.png" alt="Wrapped 요약" width="100%" /></td>
|
|
23
|
+
<td align="center" width="33%"><strong>차트</strong><br><img src="docs/assets/demo/charts-viz.png" alt="차트" width="100%" /></td>
|
|
24
|
+
<td align="center" width="33%"><strong>키워드</strong><br><img src="docs/assets/demo/keywords.png" alt="키워드" width="100%" /></td>
|
|
28
25
|
</tr>
|
|
29
26
|
</table>
|
|
30
27
|
|
|
31
|
-
<p><sub
|
|
28
|
+
<p><sub><a href="https://claudianus.github.io/kakaotalk-chat-analyzer/#demo">리포트 미리보기 전체</a> (12장 · 탭하면 크게 보기)</sub></p>
|
|
32
29
|
|
|
33
30
|
</div>
|
|
34
31
|
|
|
@@ -36,318 +33,219 @@ npx kcachat@latest
|
|
|
36
33
|
|
|
37
34
|
## 목차
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
- [핵심 기능](#핵심-기능)
|
|
41
|
-
- [대용량·속도](#대용량속도)
|
|
42
|
-
- [리포트 UX](#리포트-ux)
|
|
43
|
-
- [카카오톡에서 CSV 보내기](#카카오톡에서-csv-보내기)
|
|
44
|
-
- [빠른 시작](#빠른-시작)
|
|
45
|
-
- [생성되는 리포트](#생성되는-리포트)
|
|
46
|
-
- [프라이버시 기본값](#프라이버시-기본값)
|
|
47
|
-
- [아키텍처 한눈에](#아키텍처-한눈에)
|
|
48
|
-
- [개발](#개발)
|
|
49
|
-
- [문서 사이트 (GitHub Pages)](#문서-사이트-github-pages)
|
|
50
|
-
- [기여하기](#기여하기)
|
|
36
|
+
**처음 쓰는 분**
|
|
51
37
|
|
|
52
|
-
|
|
38
|
+
- [3분 안에 시작하기](#3분-안에-시작하기)
|
|
39
|
+
- [리포트에서 볼 수 있는 것](#리포트에서-볼-수-있는-것)
|
|
40
|
+
- [개인정보·공유 전에](#개인정보공유-전에)
|
|
41
|
+
- [자주 묻는 질문](#자주-묻는-질문)
|
|
53
42
|
|
|
54
|
-
|
|
43
|
+
**더 쓰고 싶을 때**
|
|
55
44
|
|
|
56
|
-
|
|
57
|
-
|
|
45
|
+
- [옵션·고급](#옵션고급)
|
|
46
|
+
- [최근 업데이트](#최근-업데이트)
|
|
58
47
|
|
|
59
|
-
|
|
48
|
+
**개발자**
|
|
60
49
|
|
|
61
|
-
|
|
50
|
+
- [개발·기여](#개발기여)
|
|
51
|
+
- [문서 사이트 (GitHub Pages)](#문서-사이트-github-pages)
|
|
62
52
|
|
|
63
53
|
---
|
|
64
54
|
|
|
65
|
-
##
|
|
55
|
+
## 3분 안에 시작하기
|
|
66
56
|
|
|
67
|
-
|
|
68
|
-
|------|------|
|
|
69
|
-
| **인코딩** | UTF-8 BOM, UTF-8, CP949/EUC-KR 등 보내기 인코딩 자동 감지 |
|
|
70
|
-
| **파싱** | `Date,User,Message` 헤더 기반 CSV + 멀티라인 메시지 처리 |
|
|
71
|
-
| **리포트** | Wrapped·**ECharts**·**주제 맵**(c-TF-IDF)·**Kiwi+BM25** 키워드 120개·잔디·인사이트 등 **집계 전용** 시각화 |
|
|
72
|
-
| **성능** | 줄 단위 스트림 파싱 · 단일 패스 집계 · 3MB+ Worker · 진행률 **기본 ON** (`--no-progress`로 끔) |
|
|
73
|
-
| **배포** | BrewPage(기본) / TempFile / Cloudflare 등 **TTL 기반** 임시 호스팅 · iframe 공유 링크 안전 처리 |
|
|
74
|
-
| **npx** | 짧은 별칭 **[`kcachat`](https://www.npmjs.com/package/kcachat)** 또는 본체 **`kakaotalk-chat-analyzer`** |
|
|
75
|
-
| **프라이버시** | 원문 미포함, 참여자 **부분 마스킹 표시명**(기본), URL은 **도메인**만 집계 |
|
|
57
|
+
### 1. 카카오톡에서 CSV 보내기
|
|
76
58
|
|
|
77
|
-
|
|
59
|
+
1. PC 카카오톡에서 채팅방 열기
|
|
60
|
+
2. **더보기(≡)** → **대화 보내기** → **CSV 보내기**
|
|
78
61
|
|
|
79
|
-
|
|
62
|
+
파일명은 보통 `KakaoTalk_Chat_…` 형태입니다. **원문이 들어 있는 파일**이므로 다른 사람에게 보내기 전에 내용을 확인하세요.
|
|
80
63
|
|
|
81
|
-
|
|
64
|
+
### 2. 터미널에서 한 줄 실행
|
|
82
65
|
|
|
83
|
-
|
|
84
|
-
|------|------|
|
|
85
|
-
| **스트리밍 파싱** | 파일 전체를 문자열/배열로 펼치지 않음 |
|
|
86
|
-
| **단일 패스 집계** | `Map`·히스토그램·온라인 통계(간격 P90 등)만 유지 |
|
|
87
|
-
| **Worker (≥3MB)** | 대용량일 때 메인 스레드 멈춤 완화 |
|
|
88
|
-
| **키워드** | **Kiwi** 한국어 형태소(+방별·glossary userWords) + **BM25**·PMI + **한국어 방 자동 시맨틱**(다국어 임베딩) |
|
|
89
|
-
| **kcachat@latest** | 실행 시 `kakaotalk-chat-analyzer@latest` 본체를 받아 최신 CLI 사용 |
|
|
66
|
+
[Node.js 22+](https://nodejs.org/)가 설치되어 있어야 합니다.
|
|
90
67
|
|
|
91
|
-
|
|
68
|
+
**공유 링크까지 (기본)** — 저장 폴더에서 **가장 최근** CSV를 자동으로 고릅니다:
|
|
92
69
|
|
|
93
70
|
```bash
|
|
94
|
-
|
|
95
|
-
npx kcachat@latest "./KakaoTalk_Chat_....csv" --no-progress
|
|
96
|
-
|
|
97
|
-
# 한국어 방은 시맨틱 키워드가 기본 ON (multilingual-e5-small, 끄려면 --no-semantic-keywords)
|
|
98
|
-
# 영어 위주 방에서 강제: --semantic-keywords
|
|
99
|
-
# 이전 MiniLM: KCA_SEMANTIC_MODEL=Xenova/paraphrase-multilingual-MiniLM-L12-v2
|
|
100
|
-
|
|
101
|
-
# 단계별 ms (Worker 끔)
|
|
102
|
-
npx kcachat@latest "./KakaoTalk_Chat_....csv" --profile --no-worker
|
|
103
|
-
|
|
104
|
-
# 개발용 벤치
|
|
105
|
-
npm run bench:stream -- 100000
|
|
71
|
+
npx kcachat@latest
|
|
106
72
|
```
|
|
107
73
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## 리포트 UX
|
|
74
|
+
**내 PC에만 저장** (인터넷 업로드 없음):
|
|
113
75
|
|
|
114
|
-
|
|
76
|
+
```bash
|
|
77
|
+
npx kcachat@latest --local
|
|
78
|
+
```
|
|
115
79
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
- **숫자·인사이트**: 지니·리듬 점수·응답 간격(초/분)·하이라이트·시스템 알림 분리
|
|
121
|
-
- **키워드**: **Kiwi** + **BM25/PMI** + 한국어 방 **자동 시맨틱**(e5-small), 오픈채팅·잡음어 필터
|
|
122
|
-
- **참여자**: 말풍선 맵 + 마스킹 닉네임 + 랭킹 테이블
|
|
123
|
-
- **생성 메타 (0.13.3+)**: 사이드 카드 **생성 도구**(`kca` 버전), 접기 **리포트 정보**, `#kca-provenance` JSON — BrewPage 링크로 **어떤 kca로 만들었는지** 확인 가능
|
|
124
|
-
- **BrewPage**: iframe 섹션 점프·외부 링크 안전 처리
|
|
125
|
-
- **테마**: 라이트 / 다크 / 시스템 · **OLED glass** 비주얼
|
|
80
|
+
| OS | 자동으로 찾는 폴더 |
|
|
81
|
+
|----|-------------------|
|
|
82
|
+
| **Windows** | `문서\카카오톡 받은 파일` (없으면 `문서\카카오톡` → `다운로드`) |
|
|
83
|
+
| **Mac** | `다운로드` (Downloads) |
|
|
126
84
|
|
|
127
|
-
|
|
85
|
+
다른 폴더를 쓰려면: `KCA_CSV_DIR=~/Desktop npx kcachat@latest`
|
|
128
86
|
|
|
129
|
-
###
|
|
87
|
+
### 3. 링크 열기
|
|
130
88
|
|
|
131
|
-
|
|
132
|
-
|------|------|
|
|
133
|
-
| **0.16.1** | Windows 기본 CSV 경로 `Documents\카카오톡 받은 파일` 자동 탐색 |
|
|
134
|
-
| **0.16.0** | **최신 CSV 자동**(`npx kcachat`·`latest --list/--pick`)·진행률 추정·30분 세션 gap·topicModel provenance·Facts/Wrapped DOM 정렬 |
|
|
135
|
-
| **0.15.0** | Trust UX(조건부 네비·참여자 카드)·키워드 RRF·burst MAD·Kiwi 1×CSV read·오픈채팅 인사이트·임베딩 주제 옵션 |
|
|
136
|
-
| **0.13.8** | burst 활동일 스케일·대용량 gap exact quantile·주제맵 PMI/약한 edge·벤치 **추정** UI·회귀 fixture |
|
|
137
|
-
| **0.13.7** | **BM25** 키워드·**담화어** 통합 lexicon·주제맵 discourse 게이트·시맨틱 k-means++/coherence·타임라인 meme **peakDate** |
|
|
138
|
-
| **0.13.6** | 활동 그리드 일별 셀·dyad 전체 숫자·주제맵 품질·키워드 요약 펼침·샵검색 집계·시스템 테마 |
|
|
139
|
-
| **0.13.5** | 키워드 **순위 목록** 통합(ECharts 막대+표 → 인라인 막대 표) · ② 요약 상위 12·접기 기본 |
|
|
140
|
-
| **0.13.4** | Worker 분석 시 provenance **`kiwiAvailable`** 정확 표시 (`kiwiAvailableAtAnalysis`) |
|
|
141
|
-
| **0.13.3** | HTML **provenance**: `kca` 버전·`#kca-provenance` JSON·**리포트 정보** `<details>`·`kcachat` → `KCA_INVOKER` |
|
|
142
|
-
| **0.13.2** | 키워드 막대 insideLeft·상위 3색, **활동 기간 그리드**(compact), 주제 테마/기간 분리, dyad visualMap |
|
|
143
|
-
| **0.13.1** | 생성 시각·소요, 이벤트 스파인, 히트맵/참여 pie, 주제맵·키워드 UX |
|
|
144
|
-
| **0.13.0** | dyad·타임라인·내러티브·기간 탐색(혁신 레이어) |
|
|
145
|
-
| **0.12.0** | OLED glassmorphism 리포트 비주얼 |
|
|
146
|
-
| **0.11.2** | lazy charts·Playwright `report:screenshots` |
|
|
147
|
-
| **0.11.1** | ECharts 반응형 grid·모바일 말풍선·`npm run report:viewport` |
|
|
148
|
-
| **0.11.0** | 반응형 6레이어·ResizeObserver·스크롤 리빌 |
|
|
149
|
-
| **0.10.x** | Open Props CSS 번들·테마 대비·Pretendard ([Releases](https://github.com/claudianus/kakaotalk-chat-analyzer/releases)에서 0.10.0–0.10.2) |
|
|
150
|
-
| **0.9.x** | e5-small 시맨틱 기본·스크롤 스파이 네비 ([Releases](https://github.com/claudianus/kakaotalk-chat-analyzer/releases)) |
|
|
151
|
-
| **0.3–0.8** | Kiwi·BM25·주제 맵·한국어 시맨틱·스트림 2단계 등 — [Releases](https://github.com/claudianus/kakaotalk-chat-analyzer/releases) 참고 |
|
|
89
|
+
터미널에 나온 **URL**을 브라우저에서 열면 Wrapped·차트·키워드가 있는 리포트를 볼 수 있습니다.
|
|
152
90
|
|
|
153
|
-
|
|
91
|
+
- **최초 1회**는 한국어 분석 모델 다운로드로 **1~3분** 걸릴 수 있습니다.
|
|
92
|
+
- 이미 올린 예전 링크는 **다시 실행·업로드**해야 UI가 바뀝니다.
|
|
154
93
|
|
|
155
|
-
|
|
94
|
+
### 파일을 직접 고르고 싶을 때
|
|
156
95
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
96
|
+
```bash
|
|
97
|
+
npx kcachat@latest latest --list # 후보 목록
|
|
98
|
+
npx kcachat@latest latest --pick 1 # 두 번째로 최근 파일
|
|
99
|
+
npx kcachat@latest "C:\경로\KakaoTalk_Chat_....csv"
|
|
100
|
+
```
|
|
160
101
|
|
|
161
|
-
>
|
|
102
|
+
> 카카오 **공식 앱이 아닙니다.** 보내기 CSV 형식이 바뀌면 동작이 깨질 수 있으니 중요한 대화는 백업해 두세요.
|
|
162
103
|
|
|
163
104
|
---
|
|
164
105
|
|
|
165
|
-
##
|
|
166
|
-
|
|
167
|
-
### 요구 사항
|
|
106
|
+
## 리포트에서 볼 수 있는 것
|
|
168
107
|
|
|
169
|
-
|
|
108
|
+
브라우저만 있으면 되는 **단일 HTML**입니다. **대화 원문은 파일에 넣지 않습니다.**
|
|
170
109
|
|
|
171
|
-
|
|
110
|
+
| 구역 | 내용 |
|
|
111
|
+
|------|------|
|
|
112
|
+
| **Wrapped** | 한 장면 요약, 활동 달력, 페르소나·하이라이트 |
|
|
113
|
+
| **차트** | 워드클라우드, 요일·시간대, 주제 맵 |
|
|
114
|
+
| **키워드** | 상위 단어 순위 (한국어 형태소 + 통계) |
|
|
115
|
+
| **참여자** | 말풍선·랭킹 (이름은 **일부만** 보이게 마스킹) |
|
|
116
|
+
| **테마** | 라이트 / 다크 / 시스템 |
|
|
172
117
|
|
|
173
|
-
|
|
118
|
+
공유 링크(BrewPage 등)로 열어도 되고, `--local`로 만든 `index.html`을 더블클릭해도 됩니다.
|
|
174
119
|
|
|
175
|
-
|
|
176
|
-
|------|------------------------|
|
|
177
|
-
| 최초 `npx` + Kiwi 모델 | 1~3분 (1회) |
|
|
178
|
-
| 2천 건 · `--local` · 시맨틱 끔 | 수 초 |
|
|
179
|
-
| 9만 건 · Kiwi ON · 시맨틱 ON | 수십 초~2분 |
|
|
120
|
+
---
|
|
180
121
|
|
|
181
|
-
|
|
122
|
+
## 개인정보·공유 전에
|
|
182
123
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
124
|
+
- 메시지 **본문은 리포트 HTML에 저장하지 않습니다** (집계에만 사용).
|
|
125
|
+
- 참여자 이름은 기본적으로 **앞·뒤만 남기고 가운데 마스킹**합니다.
|
|
126
|
+
- URL은 **도메인**만 집계합니다.
|
|
127
|
+
- 그래도 **키워드·통계**만으로 방 분위기가 드러날 수 있습니다. 링크를 보내기 전에 한 번 훑어 보세요.
|
|
128
|
+
- `--local`을 쓰면 기본적으로 **외부 업로드 없이** 내 PC에만 저장합니다.
|
|
187
129
|
|
|
188
|
-
|
|
130
|
+
---
|
|
189
131
|
|
|
190
|
-
|
|
191
|
-
|----|-----------|
|
|
192
|
-
| Windows | `%USERPROFILE%\Documents\카카오톡 받은 파일` |
|
|
193
|
-
| macOS 등 | `~/Downloads` |
|
|
132
|
+
## 자주 묻는 질문
|
|
194
133
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
npx kcachat@latest latest --list # 후보 10개 목록
|
|
198
|
-
npx kcachat@latest latest --pick 1 # 두 번째로 최근 파일
|
|
199
|
-
KCA_CSV_DIR=~/Desktop npx kcachat@latest
|
|
200
|
-
```
|
|
134
|
+
**Q. Node.js가 없어요.**
|
|
135
|
+
→ [nodejs.org](https://nodejs.org/)에서 LTS(22+) 설치 후 터미널을 다시 엽니다.
|
|
201
136
|
|
|
202
|
-
|
|
137
|
+
**Q. CSV를 못 찾는다고 해요.**
|
|
138
|
+
→ 위 [OS별 폴더](#2-터미널에서-한-줄-실행)에 파일이 있는지 확인하거나, 경로를 직접 넣으세요.
|
|
203
139
|
|
|
204
|
-
|
|
140
|
+
**Q. 첫 실행이 너무 느려요.**
|
|
141
|
+
→ Kiwi 한국어 모델을 **처음 한 번** 받는 중입니다. 이후에는 훨씬 빨라집니다.
|
|
205
142
|
|
|
206
|
-
|
|
143
|
+
**Q. 친구에게 링크만내면 되나요?**
|
|
144
|
+
→ 네. 다만 통계·키워드가 방 성격을 드러낼 수 있으니 공유 범위는 스스로 판단하세요.
|
|
207
145
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
```
|
|
146
|
+
**Q. 예전에 만든 링크 UI가 옛날이에요.**
|
|
147
|
+
→ 그 링크는 업로드 당시 HTML이 고정됩니다. CSV로 **다시 실행**해 새 링크를 받으세요.
|
|
211
148
|
|
|
212
|
-
|
|
149
|
+
**Q. `kcachat`와 `kakaotalk-chat-analyzer` 차이?**
|
|
150
|
+
→ 같은 프로그램입니다. `kcachat`는 짧은 `npx` 이름입니다.
|
|
213
151
|
|
|
214
|
-
|
|
215
|
-
npx github:claudianus/kakaotalk-chat-analyzer "./KakaoTalk_Chat_....csv" --local
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### 로컬 클론 개발
|
|
219
|
-
|
|
220
|
-
```bash
|
|
221
|
-
git clone https://github.com/claudianus/kakaotalk-chat-analyzer.git
|
|
222
|
-
cd kakaotalk-chat-analyzer
|
|
223
|
-
npm install
|
|
224
|
-
npm run build
|
|
225
|
-
npm test
|
|
226
|
-
```
|
|
152
|
+
---
|
|
227
153
|
|
|
228
|
-
|
|
154
|
+
## 옵션·고급
|
|
229
155
|
|
|
230
|
-
|
|
156
|
+
<details>
|
|
157
|
+
<summary><strong>CLI 전체 옵션 (펼치기)</strong></summary>
|
|
231
158
|
|
|
232
159
|
```bash
|
|
233
160
|
# 기본: HTML 생성 후 BrewPage 업로드
|
|
234
161
|
kca ./KakaoTalk_Chat_....csv
|
|
235
162
|
|
|
236
163
|
# 업로드 없이 로컬만
|
|
237
|
-
kca ./
|
|
164
|
+
kca ./chat.csv --local -o ./report
|
|
238
165
|
|
|
239
166
|
# 업로드 생략(드라이런)
|
|
240
|
-
kca ./
|
|
167
|
+
kca ./chat.csv --dry-run
|
|
241
168
|
|
|
242
|
-
#
|
|
169
|
+
# 다른 호스트
|
|
243
170
|
kca ./chat.csv --host tempfile --ttl 30
|
|
244
171
|
|
|
245
|
-
# 보내기 구조 점검(원문 출력
|
|
246
|
-
kca inspect ./
|
|
172
|
+
# 보내기 구조 점검(원문 출력 없음)
|
|
173
|
+
kca inspect ./chat.csv
|
|
247
174
|
|
|
248
|
-
# 진행률 끄기
|
|
175
|
+
# 진행률 끄기 / 프로파일
|
|
249
176
|
kca ./chat.csv --no-progress
|
|
250
177
|
kca ./chat.csv --profile --no-worker
|
|
251
178
|
|
|
252
|
-
#
|
|
179
|
+
# 날짜 필터
|
|
253
180
|
kca ./chat.csv --since 2025-01-01
|
|
254
181
|
|
|
255
182
|
kca --help
|
|
256
183
|
```
|
|
257
184
|
|
|
258
|
-
업로드가 실패해도 **로컬 `index.html`은
|
|
259
|
-
|
|
260
|
-
---
|
|
261
|
-
|
|
262
|
-
## 생성되는 리포트
|
|
185
|
+
업로드가 실패해도 **로컬 `index.html`은 남습니다.**
|
|
263
186
|
|
|
264
|
-
|
|
265
|
-
- **원문 미저장**: 메시지 본문은 통계 계산에만 사용되며 HTML에 남기지 않습니다.
|
|
266
|
-
- **provenance (CLI)**: `kca` 버전·분석 옵션·HTML 크기·생성 소요가 **생성 도구** / **리포트 정보** / `#kca-provenance`에 기록됩니다.
|
|
267
|
-
- **재업로드 안내**: 예전 BrewPage 링크는 생성 시점 HTML이 고정됩니다. UI·버그 수정 후에는 **다시 업로드**해야 반영됩니다.
|
|
268
|
-
- 자세한 화면 구성은 [리포트 UX](#리포트-ux)를 참고하세요.
|
|
187
|
+
</details>
|
|
269
188
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
## 프라이버시 기본값
|
|
189
|
+
<details>
|
|
190
|
+
<summary><strong>성능·키워드·벤치 (개발·파워유저)</strong></summary>
|
|
273
191
|
|
|
274
|
-
-
|
|
275
|
-
-
|
|
276
|
-
-
|
|
277
|
-
-
|
|
192
|
+
- **스트리밍 파싱**: 대용량 CSV도 RAM에 통째로 올리지 않음
|
|
193
|
+
- **진행률**: 기본 ON (`--no-progress`로 끔)
|
|
194
|
+
- **시맨틱 키워드**: 한국어 방 기본 ON (`--no-semantic-keywords`로 끔)
|
|
195
|
+
- CSV 옆 **`.kca-glossary.txt`**(한 줄에 한 단어) → Kiwi 사용자 사전 반영
|
|
278
196
|
|
|
279
197
|
```bash
|
|
280
|
-
|
|
281
|
-
|
|
198
|
+
npx kcachat@latest "./chat.csv" --profile --no-worker
|
|
199
|
+
npm run bench:stream -- 100000 # 저장소 클론 후
|
|
282
200
|
```
|
|
283
201
|
|
|
284
|
-
|
|
202
|
+
</details>
|
|
285
203
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
```
|
|
289
|
-
CSV 파일 (스트림 read)
|
|
290
|
-
→ 인코딩 샘플(512KB) + 줄 단위 Kakao 파서
|
|
291
|
-
→ ReportAggregator (단일 패스 · 메시지 본문 비보관)
|
|
292
|
-
├─ [≥3MB] Worker 스레드 (선택)
|
|
293
|
-
└─ Gap/키워드 온라인 통계
|
|
294
|
-
→ report.ts (단일 HTML, 다크/라이트)
|
|
295
|
-
→ [선택] providers → BrewPage / TempFile / Cloudflare
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
`kcachat`는 npm에서 **짧은 이름**으로 위 파이프라인을 실행하는 래퍼입니다.
|
|
299
|
-
|
|
300
|
-
---
|
|
204
|
+
**버전 고정:** `npx kakaotalk-chat-analyzer@0.16.1` · 최신은 `kcachat@latest`가 매번 본체를 받습니다. 리포트 사이드 카드·`#kca-provenance`로 실제 생성 버전을 확인할 수 있습니다.
|
|
301
205
|
|
|
302
|
-
|
|
206
|
+
**로컬 개발:**
|
|
303
207
|
|
|
304
208
|
```bash
|
|
305
|
-
|
|
306
|
-
npm
|
|
307
|
-
npm test
|
|
209
|
+
git clone https://github.com/claudianus/kakaotalk-chat-analyzer.git
|
|
210
|
+
cd kakaotalk-chat-analyzer && npm install && npm run build && npm test
|
|
308
211
|
```
|
|
309
212
|
|
|
310
|
-
유용한 스크립트: `npm run report:qa` · `report:qa:serve` · `report:screenshots` · `docs:capture-demo` · `keyword:audit` · `bench:stream` · Pages pill `node scripts/sync-docs-version.mjs`
|
|
311
|
-
|
|
312
213
|
---
|
|
313
214
|
|
|
314
|
-
##
|
|
315
|
-
|
|
316
|
-
### Kiwi 모델·환경 변수
|
|
317
|
-
|
|
318
|
-
- **최초 실행** 시 GitHub에서 Kiwi 한국어 모델을 **무료**로 받아 `~/.cache/kakaotalk-chat-analyzer/kiwi-base/`에 둡니다.
|
|
319
|
-
- **`KCA_NO_KIWI=1`**: 형태소 없이 휴리스틱만(빠름, 품질↓).
|
|
320
|
-
- **진행률**: 기본으로 stderr에 `대화 분석 42% (…)` 표시. 끄려면 `--no-progress`.
|
|
321
|
-
- **키워드 비교**: `npm run keyword:diff -- ./KakaoTalk_Chat_....csv 30`
|
|
322
|
-
- LGPL 고지: [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)
|
|
215
|
+
## 최근 업데이트
|
|
323
216
|
|
|
324
|
-
|
|
217
|
+
| 버전 | 요약 |
|
|
218
|
+
|------|------|
|
|
219
|
+
| **0.16.3** | 기본 **품질 우선** 프로필(메인 스레드·시맨틱 샘플 확대·RRF 완화·임베딩 주제). 가속은 `--worker` / `--fast` |
|
|
220
|
+
| **0.16.1** | Windows 기본 CSV 폴더 `문서\카카오톡 받은 파일` |
|
|
221
|
+
| **0.16.0** | 경로 생략·`latest --list/--pick`·진행률 추정·세션 gap |
|
|
222
|
+
| **0.15.0** | 모바일 참여자 카드·키워드 RRF·오픈채팅 인사이트 |
|
|
223
|
+
| **0.13.8** | burst·주제맵·벤치 UI |
|
|
224
|
+
| **0.13.3** | 리포트에 `kca` 버전(provenance) 표시 |
|
|
325
225
|
|
|
326
|
-
|
|
327
|
-
- **워크플로:** [`.github/workflows/pages.yml`](.github/workflows/pages.yml)
|
|
226
|
+
이전 버전: [Releases](https://github.com/claudianus/kakaotalk-chat-analyzer/releases)
|
|
328
227
|
|
|
329
|
-
|
|
228
|
+
---
|
|
330
229
|
|
|
331
|
-
|
|
332
|
-
2. **Build and deployment → Source:** **GitHub Actions** 선택
|
|
333
|
-
3. `main`에 푸시하면 **Deploy GitHub Pages** 워크플로가 `docs/`를 게시합니다. (최초 1회는 Actions 탭에서 권한/환경 승인이 필요할 수 있습니다.)
|
|
230
|
+
## 개발·기여
|
|
334
231
|
|
|
335
|
-
|
|
232
|
+
```bash
|
|
233
|
+
npm install && npm run build && npm test
|
|
234
|
+
```
|
|
336
235
|
|
|
337
|
-
|
|
236
|
+
유용한 스크립트: `report:qa` · `report:screenshots` · `docs:capture-demo` · `bench:stream`
|
|
338
237
|
|
|
339
|
-
이슈·PR
|
|
238
|
+
이슈·PR 환영합니다. 민감한 CSV·토큰은 이슈에 첨부하지 마세요.
|
|
340
239
|
|
|
341
|
-
|
|
342
|
-
2. `npm test` 통과
|
|
343
|
-
3. PR 설명에 **동기(왜)** 와 **테스트 방법**을 적어 주세요.
|
|
240
|
+
**아키텍처 (요약):** CSV 스트림 → 집계(본문 비보관) → 단일 HTML → [선택] BrewPage 등 업로드.
|
|
344
241
|
|
|
345
242
|
---
|
|
346
243
|
|
|
347
|
-
##
|
|
244
|
+
## 문서 사이트 (GitHub Pages)
|
|
348
245
|
|
|
349
|
-
|
|
350
|
-
|
|
246
|
+
- **공개 URL:** [https://claudianus.github.io/kakaotalk-chat-analyzer/](https://claudianus.github.io/kakaotalk-chat-analyzer/)
|
|
247
|
+
- [`docs/index.html`](docs/index.html) — 시작 명령·OS별 폴더·짧은 팁
|
|
248
|
+
- `main`에 `docs/` 푸시 시 Actions가 배포 · pill 버전: `node scripts/sync-docs-version.mjs`
|
|
351
249
|
|
|
352
250
|
---
|
|
353
251
|
|
|
@@ -355,12 +253,8 @@ npm test
|
|
|
355
253
|
|
|
356
254
|
[MIT License](./LICENSE)
|
|
357
255
|
|
|
358
|
-
---
|
|
359
|
-
|
|
360
256
|
<div align="center">
|
|
361
257
|
|
|
362
258
|
**Made with care for safer chat analytics** · [@claudianus](https://github.com/claudianus)
|
|
363
259
|
|
|
364
|
-
⭐ 이 프로젝트가 도움이 되었다면 스타 한 번 부탁드립니다.
|
|
365
|
-
|
|
366
260
|
</div>
|
package/dist/src/aggregator.d.ts
CHANGED
|
@@ -8,7 +8,11 @@ export interface FinalizeSourceMeta {
|
|
|
8
8
|
export interface FinalizeOptions {
|
|
9
9
|
usedSemanticKeywords?: boolean;
|
|
10
10
|
koreanPrimary?: boolean;
|
|
11
|
+
useEmbeddingTopics?: boolean;
|
|
12
|
+
semanticSupplementRrfWeight?: number;
|
|
11
13
|
}
|
|
14
|
+
/** 시맨틱 supplement messageHits 상한 — RRF 독점 방지 */
|
|
15
|
+
export declare function semanticSupplementHitCap(corpusMessages: number): number;
|
|
12
16
|
export interface AggregatorOptions {
|
|
13
17
|
/** 시맨틱 키워드용 메시지 샘플 수집 */
|
|
14
18
|
semanticSamples?: boolean;
|
|
@@ -89,7 +93,7 @@ export declare class ReportAggregator {
|
|
|
89
93
|
label: string;
|
|
90
94
|
messageHits: number;
|
|
91
95
|
score?: number;
|
|
92
|
-
}[]): void;
|
|
96
|
+
}[], corpusMessages: number): void;
|
|
93
97
|
consume(record: ChatRecord, opts?: {
|
|
94
98
|
keywordsOnly?: boolean;
|
|
95
99
|
skipKeywords?: boolean;
|
package/dist/src/aggregator.js
CHANGED
|
@@ -10,6 +10,7 @@ import { buildTopicStopwords } from "./topic-stopwords.js";
|
|
|
10
10
|
import { MessageReservoir } from "./message-reservoir.js";
|
|
11
11
|
import { semanticReservoirCap, semanticSampleCap, subsampleSemanticMessages } from "./semantic-policy.js";
|
|
12
12
|
import { mergeKeywordRankings } from "./keyword-merge.js";
|
|
13
|
+
import { isNoiseKeyword } from "./keyword-quality.js";
|
|
13
14
|
import { formatCompactNumber, formatReplyGapMinutes } from "./report-util.js";
|
|
14
15
|
import { KeywordCounter } from "./keyword-counter.js";
|
|
15
16
|
import { RepeatPhraseCounter } from "./repeat-phrase-counter.js";
|
|
@@ -47,6 +48,10 @@ const EMOJI_RE = /\p{Extended_Pictographic}/u;
|
|
|
47
48
|
const LAUGH_RE = /(?:ㅋ{2,}|ㅎ{2,}|ㅠ+|ㅜ+|ㅇㅇ|ㅋㅋ|ㅎㅎ|ㅋㅎ|ㅎㅋ)/;
|
|
48
49
|
const LINK_HINT_RE = /https?:\/\/|www\./i;
|
|
49
50
|
const HAS_TOKEN_CHAR_RE = /[가-힣A-Za-z]/;
|
|
51
|
+
/** 시맨틱 supplement messageHits 상한 — RRF 독점 방지 */
|
|
52
|
+
export function semanticSupplementHitCap(corpusMessages) {
|
|
53
|
+
return Math.min(24, 4 + Math.floor(Math.sqrt(Math.max(corpusMessages, 1))));
|
|
54
|
+
}
|
|
50
55
|
export class ReportAggregator {
|
|
51
56
|
filePath;
|
|
52
57
|
privacy;
|
|
@@ -156,14 +161,17 @@ export class ReportAggregator {
|
|
|
156
161
|
if (this.semanticReservoir && messageLength >= 12)
|
|
157
162
|
this.semanticReservoir.push(msg);
|
|
158
163
|
}
|
|
159
|
-
applySemanticKeywordBoost(items) {
|
|
160
|
-
|
|
164
|
+
applySemanticKeywordBoost(items, corpusMessages) {
|
|
165
|
+
const hitCap = semanticSupplementHitCap(corpusMessages);
|
|
166
|
+
const valid = items.filter((item) => !isNoiseKeyword(item.label));
|
|
167
|
+
this.semanticThemeCandidates = valid.map((item) => ({
|
|
161
168
|
label: item.label,
|
|
162
169
|
messageHits: item.messageHits,
|
|
163
170
|
score: item.score ?? item.messageHits,
|
|
164
171
|
}));
|
|
165
|
-
for (const item of
|
|
166
|
-
|
|
172
|
+
for (const item of valid) {
|
|
173
|
+
const hits = Math.max(2, Math.min(item.messageHits, hitCap));
|
|
174
|
+
this.keywordSupplement.addHits(item.label, hits);
|
|
167
175
|
}
|
|
168
176
|
}
|
|
169
177
|
consume(record, opts) {
|
|
@@ -445,9 +453,9 @@ export class ReportAggregator {
|
|
|
445
453
|
limit: keywordLimit,
|
|
446
454
|
minDocFreq: adaptiveMinCount(total, finalizeOpts?.koreanPrimary !== false),
|
|
447
455
|
});
|
|
448
|
-
const keywords = mergeKeywordRankings(wordRankItems, this.keywordSupplement, keywordLimit);
|
|
456
|
+
const keywords = mergeKeywordRankings(wordRankItems, this.keywordSupplement, keywordLimit, finalizeOpts?.semanticSupplementRrfWeight ?? 0.5);
|
|
449
457
|
let topics = this.topicMap.buildTopics(total, buildTopicStopwords());
|
|
450
|
-
if (
|
|
458
|
+
if (finalizeOpts?.useEmbeddingTopics && this.semanticThemeCandidates.length > 0) {
|
|
451
459
|
topics = mergeEmbeddingThemes(topics, this.semanticThemeCandidates, total);
|
|
452
460
|
}
|
|
453
461
|
const burstDetectionMethod = resolveBurstDetectionMethod();
|