seogitan 1.4.0 → 1.4.2

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.
@@ -7,55 +7,76 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
7
7
  const BUNDLED_SKILLS_DIR = join(__dirname, "..", "..", "skills");
8
8
  // 설치 대상: ~/.claude/skills/
9
9
  const TARGET_SKILLS_DIR = join(homedir(), ".claude", "skills");
10
- const SEOGITAN_SKILLS = ["record", "meetings", "summary", "upload"];
10
+ const SEOGITAN_SKILLS = ["record", "meetings", "summary", "upload", "doctor"];
11
11
  export function registerSetupCommand(program) {
12
12
  program
13
13
  .command("setup")
14
14
  .description("Claude Code 스킬을 설치합니다")
15
15
  .option("--force", "기존 스킬을 덮어씁니다")
16
+ .option("--debug", "디버그 정보 출력", false)
16
17
  .action(async (opts) => {
17
- console.log("🔧 Seogitan 설치를 시작합니다...\n");
18
- // 1. 스킬 설치
19
- if (!existsSync(BUNDLED_SKILLS_DIR)) {
20
- console.error(" 번들된 스킬을 찾을 수 없습니다. 패키지가 손상되었을 수 있습니다.");
21
- process.exit(1);
22
- }
23
- mkdirSync(TARGET_SKILLS_DIR, { recursive: true });
24
- let installed = 0;
25
- let skipped = 0;
26
- for (const skill of SEOGITAN_SKILLS) {
27
- const src = join(BUNDLED_SKILLS_DIR, skill);
28
- const dest = join(TARGET_SKILLS_DIR, `seogitan-${skill}`);
29
- if (!existsSync(src)) {
30
- console.log(` ⚠ ${skill} 스킬을 찾을 수 없습니다 (건너뜀)`);
31
- continue;
18
+ try {
19
+ console.log("Seogitan setup\n");
20
+ if (opts.debug) {
21
+ console.log("[debug] skills dir:", BUNDLED_SKILLS_DIR);
22
+ console.log("[debug] target dir:", TARGET_SKILLS_DIR);
23
+ console.log("[debug] skills dir exists:", existsSync(BUNDLED_SKILLS_DIR));
32
24
  }
33
- if (existsSync(dest) && !opts.force) {
34
- console.log(` ✓ seogitan-${skill} (이미 설치됨)`);
35
- skipped++;
36
- continue;
25
+ // 1. 스킬 설치
26
+ if (!existsSync(BUNDLED_SKILLS_DIR)) {
27
+ console.error("ERROR: 번들된 스킬을 찾을 수 없습니다.");
28
+ console.error("패키지가 손상되었을 수 있습니다. npm i -g seogitan@latest 로 재설치하세요.");
29
+ if (opts.debug)
30
+ console.error("[debug] expected path:", BUNDLED_SKILLS_DIR);
31
+ process.exit(1);
37
32
  }
38
- cpSync(src, dest, { recursive: true });
39
- console.log(` ✓ seogitan-${skill} 설치 완료`);
40
- installed++;
41
- }
42
- console.log(`\n📦 스킬 설치: ${installed}개 설치, ${skipped}개 기존 유지`);
43
- // 2. ffmpeg 확인
44
- try {
45
- const { checkFfmpegInstalled } = await import("../lib/audio.js");
46
- checkFfmpegInstalled();
47
- console.log("\n✓ ffmpeg 사용 가능");
33
+ mkdirSync(TARGET_SKILLS_DIR, { recursive: true });
34
+ let installed = 0;
35
+ let skipped = 0;
36
+ for (const skill of SEOGITAN_SKILLS) {
37
+ const src = join(BUNDLED_SKILLS_DIR, skill);
38
+ const dest = join(TARGET_SKILLS_DIR, `seogitan-${skill}`);
39
+ if (!existsSync(src)) {
40
+ console.log(` [skip] ${skill}`);
41
+ continue;
42
+ }
43
+ if (existsSync(dest) && !opts.force) {
44
+ console.log(` [ok] seogitan-${skill} (already installed)`);
45
+ skipped++;
46
+ continue;
47
+ }
48
+ cpSync(src, dest, { recursive: true });
49
+ console.log(` [ok] seogitan-${skill} installed`);
50
+ installed++;
51
+ }
52
+ console.log(`\nSkills: ${installed} installed, ${skipped} skipped`);
53
+ // 2. ffmpeg 확인
54
+ try {
55
+ const { checkFfmpegInstalled } = await import("../lib/audio.js");
56
+ checkFfmpegInstalled();
57
+ console.log("[ok] ffmpeg available");
58
+ }
59
+ catch {
60
+ console.log("[warn] ffmpeg not found. Required for recording.");
61
+ if (process.platform === "darwin")
62
+ console.log(" brew install ffmpeg");
63
+ else if (process.platform === "win32")
64
+ console.log(" winget install ffmpeg OR choco install ffmpeg");
65
+ else
66
+ console.log(" sudo apt install ffmpeg");
67
+ }
68
+ // 3. 로그인 안내
69
+ console.log("\nNext steps:");
70
+ console.log(" 1. seogitan login -- Google login");
71
+ console.log(" 2. seogitan record -- Start recording");
72
+ console.log(" 3. Use /seogitan-record, /seogitan-meetings, /seogitan-summary in Claude Code");
73
+ console.log("");
48
74
  }
49
- catch {
50
- console.log("\n⚠ ffmpeg를 찾을 없습니다. 녹음 기능을 사용하려면 설치가 필요합니다.");
51
- console.log(" macOS: brew install ffmpeg");
52
- console.log(" Ubuntu/Debian: sudo apt install ffmpeg");
75
+ catch (err) {
76
+ console.error("Setup failed:", err instanceof Error ? err.message : String(err));
77
+ if (opts.debug && err instanceof Error)
78
+ console.error(err.stack);
79
+ process.exit(1);
53
80
  }
54
- // 3. 로그인 안내
55
- console.log("\n📋 다음 단계:");
56
- console.log(" 1. seogitan login — Google 계정으로 로그인");
57
- console.log(" 2. seogitan record — 회의 녹음 시작");
58
- console.log(" 3. Claude Code에서 /seogitan-record, /seogitan-meetings, /seogitan-summary 사용 가능");
59
- console.log("");
60
81
  });
61
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seogitan",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "seogitan": "dist/index.js"
@@ -19,7 +19,7 @@
19
19
  "commander": "^13.0.0",
20
20
  "ffmpeg-static": "^5.3.0",
21
21
  "open": "^10.0.0",
22
- "seogitan-core": "^1.1.0",
22
+ "seogitan-core": "^1.1.1",
23
23
  "zod": "^3.24.3"
24
24
  },
25
25
  "devDependencies": {
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: doctor
3
+ description: "서기탄이 시스템의 에러를 진단하고 해결합니다. 녹음/전사/요약/업로드 중 에러가 발생했을 때, 또는 사용자가 '에러', '오류', '안돼', '실패', 'doctor', '진단' 등을 언급할 때 사용. 다른 서기탄이 스킬에서 에러 발생 시 이 스킬로 위임됩니다."
4
+ ---
5
+
6
+ # /doctor — 서기탄이 에러 진단
7
+
8
+ ## 진단 절차
9
+
10
+ 1. 로그 확인: `tail -20 /tmp/seogitan-record.log`
11
+ 2. 에러 메시지를 아래 매뉴얼에서 매칭
12
+ 3. 해결 방법 안내
13
+
14
+ ## 에러 매뉴얼
15
+
16
+ ### 인증/토큰
17
+ | 에러 메시지 | 원인 | 해결 |
18
+ |------------|------|------|
19
+ | "로그인이 필요합니다" | 미로그인 또는 토큰 만료 | `seogitan login` 실행 |
20
+ | "Invalid token" / "Invalid JWT" | 토큰 만료 | `seogitan login` 실행 |
21
+ | "Google token refresh failed" | Google 인증 만료 | `seogitan login`으로 재인증 |
22
+ | "Unauthorized" / "401" | 권한 없음 | `seogitan login` 실행 |
23
+
24
+ **주의: `seogitan auth`라는 명령어는 존재하지 않음. 반드시 `seogitan login`**
25
+
26
+ ### 녹음/ffmpeg
27
+ | 에러 메시지 | 원인 | 해결 |
28
+ |------------|------|------|
29
+ | "ffmpeg가 설치되어 있지 않습니다" | ffmpeg 미설치 | `seogitan setup` 실행 |
30
+ | "No such device" / "Device not found" | 오디오 장치 없음 | `seogitan record --list-devices`로 확인 후 `--device <index>` 지정 |
31
+ | "ffmpeg 응답 없음, 강제 종료" | ffmpeg 비정상 종료 | 재시도. 반복되면 `brew install ffmpeg`로 시스템 ffmpeg 설치 |
32
+
33
+ ### 전사/n8n
34
+ | 에러 메시지 | 원인 | 해결 |
35
+ |------------|------|------|
36
+ | "Edge Function 호출 실패 (401)" | Supabase JWT 만료 | `seogitan login` 실행 |
37
+ | "Edge Function 호출 실패 (500)" | Edge Function 서버 에러 | 잠시 후 재시도 |
38
+ | 전사가 안 됨 (로그에 에러 없음) | n8n 워크플로우 비활성화 | n8n 대시보드에서 워크플로우 활성 상태 확인 |
39
+
40
+ ### 삭제
41
+ | 에러 메시지 | 원인 | 해결 |
42
+ |------------|------|------|
43
+ | "회의 삭제 실패" | RLS 정책 (본인 회의만 삭제 가능) | 본인이 생성한 회의만 삭제 가능 |
44
+ | "Direct deletion from storage tables" | Storage 트리거 문제 | CLI `seogitan meetings delete <id>` 사용 |
45
+
46
+ ### 설치
47
+ | 에러 메시지 | 원인 | 해결 |
48
+ |------------|------|------|
49
+ | "EACCES: permission denied" | npm 글로벌 설치 권한 없음 | `sudo npm i -g seogitan` 또는 nvm 사용 |
50
+ | "번들된 스킬을 찾을 수 없습니다" | 패키지 손상 | `npm i -g seogitan@latest` 재설치 |
51
+
52
+ ## CLI 명령어 레퍼런스
53
+
54
+ ```
55
+ seogitan login # Google OAuth 로그인
56
+ seogitan logout # 로그아웃
57
+ seogitan setup # 스킬 설치 + ffmpeg 확인
58
+ seogitan record [title] # 녹음 시작
59
+ seogitan upload <file> # 파일 업로드
60
+ seogitan meetings list # 회의 목록
61
+ seogitan meetings show <id> # 상세 조회
62
+ seogitan meetings delete <id> # 삭제
63
+ seogitan meetings tag <id> <tags...> # 태그 설정
64
+ seogitan summarize <id> # 요약 생성
65
+ ```
66
+
67
+ ## 진단이 안 되는 경우
68
+
69
+ 위 매뉴얼에 없는 에러면:
70
+ 1. `seogitan --version`으로 버전 확인 → 최신이 아니면 `npm i -g seogitan@latest`
71
+ 2. `seogitan setup --force`로 재설정
72
+ 3. 그래도 안 되면 에러 메시지 전문을 사용자에게 보여주고 GitHub 이슈로 안내
@@ -30,3 +30,7 @@ seogitan meetings search "키워드" --json
30
30
  ## 결과 처리
31
31
 
32
32
  JSON 결과에서 각 회의의 ID, 제목, 날짜, 상태를 추출하여 보기 좋게 정리해서 보여준다.
33
+
34
+ ## 에러 대응
35
+
36
+ 에러 발생 시 `/doctor` 스킬을 호출하여 진단합니다.
@@ -5,15 +5,16 @@ description: "터미널에서 회의 녹음을 시작합니다. ffmpeg로 마이
5
5
 
6
6
  # /record — 회의 녹음 시작
7
7
 
8
- $ARGUMENTS가 제공되면 회의 제목으로 사용합니다.
8
+ ## 핵심 원칙: 녹음은 즉시 시작
9
9
 
10
- ## 실행 전: 캘린더 확인
10
+ 녹음 요청을 받으면 **질문 없이 바로 실행**합니다. 회의는 기다려주지 않습니다.
11
11
 
12
- **반드시** 녹음 시작 전에 사용자에게 캘린더 연결 여부를 물어보세요:
13
- - "캘린더 일정에 자동 연결할까요, 아니면 제목을 직접 지정할까요?"
14
- - 자동 연결 → 제목 없이 `seogitan record` 실행 (진행 중인 일정 자동 매칭)
15
- - 제목 지정 사용자가 알려준 제목으로 `seogitan record "제목"` 실행
16
- - 빠르게 시작하고 싶다면 → 제목 없이 실행 (캘린더 자동 연결)
12
+ ## 캘린더 연결 판단 (녹음 시작 전, 질문하지 않음)
13
+
14
+ 사용자의 요청 문맥에서 판단:
15
+ - "회의 녹음해줘", "스터디 녹음" **일정과 연관된 언급** 제목 없이 실행 (캘린더 자동 연결)
16
+ - "녹음해줘", "녹음 시작" 등 **단순 녹음 요청** → 제목 "새 녹음"으로 실행 (캘린더 연결 안 됨)
17
+ - $ARGUMENTS에 명시적 제목이 있으면 → 그 제목으로 실행
17
18
 
18
19
  ## 실행
19
20
 
@@ -31,16 +32,31 @@ nohup seogitan record "제목" > /tmp/seogitan-record.log 2>&1 &
31
32
  echo "PID: $!"
32
33
  ```
33
34
 
35
+ 실행 직후 3초 대기 후 로그 확인:
36
+ ```bash
37
+ sleep 3 && cat /tmp/seogitan-record.log
38
+ ```
39
+
34
40
  실행 후 사용자에게 알려줄 내용:
35
41
  - "녹음이 백그라운드에서 시작되었습니다"
36
42
  - "종료하려면 별도 터미널에서 `kill -INT <PID>` 실행"
37
43
  - "로그 확인: `tail -f /tmp/seogitan-record.log`"
38
44
  - 녹음 중에도 대화를 계속할 수 있습니다
39
45
 
40
- ## 녹음 종료 후 확인
46
+ ## 녹음 종료 후
41
47
 
42
48
  사용자가 녹음을 종료했다고 하면:
43
49
  ```bash
44
50
  tail -5 /tmp/seogitan-record.log
45
51
  ```
46
- 로그에서 Meeting ID를 찾아 `/summary` 스킬로 요약을 조회합니다.
52
+
53
+ 1. 로그에서 Meeting ID를 찾는다
54
+ 2. 캘린더 자동 연결이 된 경우, 사용자에게 **연결 유지할지 확인**:
55
+ - "캘린더 [일정명]에 연결되었습니다. 유지할까요?"
56
+ - 유지 → 그대로 둠
57
+ - 연결 해제 → `seogitan meetings link <id> ""` 로 calendar_event_id 제거
58
+ 3. `/summary` 스킬로 요약 조회
59
+
60
+ ## 에러 대응
61
+
62
+ 로그에서 에러가 발견되면 `/doctor` 스킬을 호출하여 진단합니다.
@@ -33,3 +33,7 @@ seogitan meetings show "$ARGUMENTS" --full --json
33
33
  - "레퍼럴 관련 결정사항 자세히 알려줘" → 1단계 후 2단계 (전사록에서 관련 부분 찾기)
34
34
  - "누가 뭐라고 했는지 알려줘" → 바로 2단계 (전사록 필요)
35
35
  - "액션아이템 담당자 누구야?" → 2단계 (전사록에서 맥락 파악)
36
+
37
+ ## 에러 대응
38
+
39
+ 에러 발생 시 `/doctor` 스킬을 호출하여 진단합니다.
@@ -41,3 +41,7 @@ seogitan upload "<파일>" --calendar-search "레퍼럴" --calendar-index 1
41
41
  ```
42
42
 
43
43
  검색 결과가 여러 개면 목록을 보여주고 사용자에게 번호를 물어본 후 `--calendar-index`로 재실행.
44
+
45
+ ## 에러 대응
46
+
47
+ 에러 발생 시 `/doctor` 스킬을 호출하여 진단합니다.