claude-code-kr 0.3.16 → 0.3.18

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/bin/cc-kr.js CHANGED
@@ -6,6 +6,7 @@ const { execSync } = require('child_process');
6
6
  const patcher = require('../lib/patcher');
7
7
  const mappings = require('../lib/mappings');
8
8
  const hooks = require('../lib/hooks');
9
+ const commands = require('../lib/commands');
9
10
  const pkg = require('../package.json');
10
11
 
11
12
  // 실제로 설치된 cckr 디렉토리가 쓰기 가능한지 체크
@@ -60,29 +61,12 @@ switch (cmd) {
60
61
  console.log(`📦 cckr 버전: ${pkg.version}`);
61
62
  console.log(`🔷 CC 버전: ${s.ccVersion || '알 수 없음'}`);
62
63
 
63
- // 현재 세션의 in-memory 버전
64
- // !cckr status: claude (C) → bash (PPID=C) → node (PPID=bash)
65
- // 세션 파일은 claude PID로 저장되므로 grandparent를 찾아야 함
66
- function getGrandparentPid(pid) {
67
- try {
68
- if (process.platform === 'linux') {
69
- const stat = fs.readFileSync(`/proc/${pid}/status`, 'utf8');
70
- const m = stat.match(/^PPid:\s*(\d+)/m);
71
- return m ? m[1] : null;
72
- } else if (process.platform === 'darwin') {
73
- return execSync(`ps -o ppid= -p ${pid}`, { encoding: 'utf8' }).trim();
74
- }
75
- } catch {}
76
- return null;
77
- }
64
+ // 현재 세션의 in-memory 버전 — ancestor 체인에서 claude 찾기
78
65
  try {
79
- // process.ppid (bash) grandparent (claude) 둘 다 시도
80
- const candidates = [process.ppid.toString()];
81
- const grand = getGrandparentPid(process.ppid);
82
- if (grand) candidates.push(grand);
83
-
84
- for (const pid of candidates) {
85
- const sessionFile = `/tmp/cckr-session-${pid}.json`;
66
+ const { findClaudePid } = require('../lib/findClaude');
67
+ const claudePid = findClaudePid();
68
+ if (claudePid) {
69
+ const sessionFile = `/tmp/cckr-session-${claudePid}.json`;
86
70
  if (fs.existsSync(sessionFile)) {
87
71
  const session = JSON.parse(fs.readFileSync(sessionFile, 'utf8'));
88
72
  const inSession = session.sessionCckrVersion;
@@ -92,7 +76,6 @@ switch (cmd) {
92
76
  } else {
93
77
  console.log(`🎯 이 세션: cckr ${inSession} ⚠️ (디스크: ${installed} — 새 세션 시작 시 변경 적용)`);
94
78
  }
95
- break;
96
79
  }
97
80
  }
98
81
  } catch {}
@@ -116,6 +99,9 @@ switch (cmd) {
116
99
  break;
117
100
  }
118
101
  if (result.ok) {
102
+ // hook 자동 재설치 — restore로 제거됐을 수 있음
103
+ try { hooks.install(); } catch {}
104
+
119
105
  console.log(`🎉 ${result.count}개 커맨드 한글화 완료`);
120
106
  console.log(`✅ 안정 패치: ${result.stable.applied}/${result.stable.total}`);
121
107
  console.log(`⚡ 가변 패치: ${result.fragile.applied}/${result.fragile.total}`);
@@ -162,6 +148,13 @@ switch (cmd) {
162
148
  const result = patcher.restore();
163
149
  if (result.ok) {
164
150
  console.log('✅ 원본 복원 완료');
151
+ // hook 제거 — 새 세션에서 자동 재패치 안 되도록
152
+ try {
153
+ hooks.uninstall();
154
+ console.log('✅ 자동 재패치 hook 제거 (다시 적용하려면 cckr apply)');
155
+ } catch (e) {
156
+ console.log(`⚠️ hook 제거 스킵: ${e.message}`);
157
+ }
165
158
  } else {
166
159
  console.error(`❌ ${result.error}`);
167
160
  process.exit(1);
@@ -0,0 +1,44 @@
1
+ // 자기 ancestor 프로세스 체인에서 'claude' 프로세스를 찾아 PID 반환.
2
+ // hook이든 !cckr status든, 둘 다 호출 시점에 ancestor에 claude가 있음.
3
+ // 같은 함수를 양쪽이 사용하면 같은 PID를 얻음 → 세션 파일 매칭 가능.
4
+ const fs = require('fs');
5
+ const { execSync } = require('child_process');
6
+
7
+ function getParentPid(pid) {
8
+ try {
9
+ if (process.platform === 'linux') {
10
+ const stat = fs.readFileSync(`/proc/${pid}/status`, 'utf8');
11
+ const m = stat.match(/^PPid:\s*(\d+)/m);
12
+ return m ? parseInt(m[1], 10) : null;
13
+ } else if (process.platform === 'darwin') {
14
+ const out = execSync(`ps -o ppid= -p ${pid}`, { encoding: 'utf8' }).trim();
15
+ return out ? parseInt(out, 10) : null;
16
+ }
17
+ } catch {}
18
+ return null;
19
+ }
20
+
21
+ function getProcessName(pid) {
22
+ try {
23
+ if (process.platform === 'linux') {
24
+ return fs.readFileSync(`/proc/${pid}/comm`, 'utf8').trim();
25
+ } else if (process.platform === 'darwin') {
26
+ return execSync(`ps -o comm= -p ${pid}`, { encoding: 'utf8' }).trim().split('/').pop();
27
+ }
28
+ } catch {}
29
+ return null;
30
+ }
31
+
32
+ // 자기 ancestor 체인에서 'claude' 프로세스 PID 찾기
33
+ // 못 찾으면 null
34
+ function findClaudePid(startPid = process.ppid) {
35
+ let pid = startPid;
36
+ for (let i = 0; i < 12 && pid && pid > 1; i++) {
37
+ const name = getProcessName(pid);
38
+ if (name === 'claude') return pid;
39
+ pid = getParentPid(pid);
40
+ }
41
+ return null;
42
+ }
43
+
44
+ module.exports = { findClaudePid, getParentPid, getProcessName };
package/lib/hooks.js CHANGED
@@ -3,7 +3,7 @@ const path = require('path');
3
3
  const os = require('os');
4
4
 
5
5
  const SETTINGS_PATH = path.join(os.homedir(), '.claude', 'settings.json');
6
- const HOOK_COMMAND = 'CCKR_SESSION_PPID=$PPID cckr apply 2>/dev/null || true';
6
+ const HOOK_COMMAND = 'cckr apply 2>/dev/null || true';
7
7
  const HOOK_ID = 'cckr-auto-patch';
8
8
 
9
9
  function readSettings() {
package/lib/patcher.js CHANGED
@@ -121,17 +121,18 @@ function apply(cliJs, { force = false } = {}) {
121
121
  const ccVersion = getCliVersion(cliJs);
122
122
 
123
123
  // 세션 시작 시점 캡처 — 마커 스킵보다 먼저 (스킵돼도 세션 정보는 항상 기록)
124
- // SessionStart hook이 CCKR_SESSION_PPID env로 호출
125
- // 패치 직전의 marker = 세션이 메모리에 로드한 cli.js 버전
126
- const sessionPpid = process.env.CCKR_SESSION_PPID;
127
- if (sessionPpid && /^\d+$/.test(sessionPpid)) {
124
+ // ancestor 체인에서 claude 프로세스 PID 찾기
125
+ // 같은 PID를 cckr status가 사용하므로 매칭됨
126
+ const { findClaudePid } = require('./findClaude');
127
+ const claudePid = findClaudePid();
128
+ if (claudePid) {
128
129
  let preMarker = null;
129
130
  try {
130
131
  preMarker = JSON.parse(fs.readFileSync(markerPath, 'utf8'));
131
132
  } catch {}
132
133
  const sessionInfo = {
133
134
  capturedAt: new Date().toISOString(),
134
- claudePid: sessionPpid,
135
+ claudePid: String(claudePid),
135
136
  ccVersion: ccVersion,
136
137
  // 이 세션이 로드한 cli.js의 cckr 버전 (패치 직전)
137
138
  // marker 없으면 cli.js가 unpatched 상태였음
@@ -139,7 +140,7 @@ function apply(cliJs, { force = false } = {}) {
139
140
  installedCckrVersion: pkg.version,
140
141
  };
141
142
  try {
142
- fs.writeFileSync(`/tmp/cckr-session-${sessionPpid}.json`, JSON.stringify(sessionInfo, null, 2));
143
+ fs.writeFileSync(`/tmp/cckr-session-${claudePid}.json`, JSON.stringify(sessionInfo, null, 2));
143
144
  // 7일 이상 된 세션 파일 정리
144
145
  const tmpFiles = fs.readdirSync('/tmp').filter(f => /^cckr-session-\d+\.json$/.test(f));
145
146
  const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-kr",
3
- "version": "0.3.16",
3
+ "version": "0.3.18",
4
4
  "description": "Claude Code 한글 패치 CLI — /btw → /근데, /help → /도움, /compact → /압축",
5
5
  "main": "./index.js",
6
6
  "bin": {