@myhpmp/cli 1.1.0

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.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +156 -0
  3. package/README.md +156 -0
  4. package/dist/adapter/claude-adapter.d.ts +9 -0
  5. package/dist/adapter/claude-adapter.js +36 -0
  6. package/dist/adapter/claude-adapter.js.map +1 -0
  7. package/dist/adapter/codex-adapter.d.ts +14 -0
  8. package/dist/adapter/codex-adapter.js +84 -0
  9. package/dist/adapter/codex-adapter.js.map +1 -0
  10. package/dist/adapter/index.d.ts +6 -0
  11. package/dist/adapter/index.js +18 -0
  12. package/dist/adapter/index.js.map +1 -0
  13. package/dist/adapter/provider.d.ts +23 -0
  14. package/dist/adapter/provider.js +6 -0
  15. package/dist/adapter/provider.js.map +1 -0
  16. package/dist/auth/auth-manager.d.ts +15 -0
  17. package/dist/auth/auth-manager.js +34 -0
  18. package/dist/auth/auth-manager.js.map +1 -0
  19. package/dist/auth/oauth.d.ts +6 -0
  20. package/dist/auth/oauth.js +113 -0
  21. package/dist/auth/oauth.js.map +1 -0
  22. package/dist/cli.d.ts +4 -0
  23. package/dist/cli.js +46 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/commands/init.d.ts +1 -0
  26. package/dist/commands/init.js +116 -0
  27. package/dist/commands/init.js.map +1 -0
  28. package/dist/commands/locale.d.ts +1 -0
  29. package/dist/commands/locale.js +40 -0
  30. package/dist/commands/locale.js.map +1 -0
  31. package/dist/commands/setup.d.ts +1 -0
  32. package/dist/commands/setup.js +137 -0
  33. package/dist/commands/setup.js.map +1 -0
  34. package/dist/commands/statusline-toggle.d.ts +1 -0
  35. package/dist/commands/statusline-toggle.js +61 -0
  36. package/dist/commands/statusline-toggle.js.map +1 -0
  37. package/dist/commands/sync.d.ts +1 -0
  38. package/dist/commands/sync.js +29 -0
  39. package/dist/commands/sync.js.map +1 -0
  40. package/dist/commands/usage.d.ts +1 -0
  41. package/dist/commands/usage.js +56 -0
  42. package/dist/commands/usage.js.map +1 -0
  43. package/dist/config.d.ts +2 -0
  44. package/dist/config.js +35 -0
  45. package/dist/config.js.map +1 -0
  46. package/dist/core/exp-calculator.d.ts +1 -0
  47. package/dist/core/exp-calculator.js +3 -0
  48. package/dist/core/exp-calculator.js.map +1 -0
  49. package/dist/core/level-system.d.ts +2 -0
  50. package/dist/core/level-system.js +3 -0
  51. package/dist/core/level-system.js.map +1 -0
  52. package/dist/core/stats-aggregator.d.ts +5 -0
  53. package/dist/core/stats-aggregator.js +35 -0
  54. package/dist/core/stats-aggregator.js.map +1 -0
  55. package/dist/data/auto-sync.d.ts +8 -0
  56. package/dist/data/auto-sync.js +75 -0
  57. package/dist/data/auto-sync.js.map +1 -0
  58. package/dist/data/claude-usage.d.ts +13 -0
  59. package/dist/data/claude-usage.js +82 -0
  60. package/dist/data/claude-usage.js.map +1 -0
  61. package/dist/data/exp-logger.d.ts +1 -0
  62. package/dist/data/exp-logger.js +43 -0
  63. package/dist/data/exp-logger.js.map +1 -0
  64. package/dist/data/local-store.d.ts +16 -0
  65. package/dist/data/local-store.js +41 -0
  66. package/dist/data/local-store.js.map +1 -0
  67. package/dist/data/pending-exp.d.ts +8 -0
  68. package/dist/data/pending-exp.js +42 -0
  69. package/dist/data/pending-exp.js.map +1 -0
  70. package/dist/data/providers/db-interface.d.ts +11 -0
  71. package/dist/data/providers/db-interface.js +2 -0
  72. package/dist/data/providers/db-interface.js.map +1 -0
  73. package/dist/data/providers/supabase.d.ts +16 -0
  74. package/dist/data/providers/supabase.js +84 -0
  75. package/dist/data/providers/supabase.js.map +1 -0
  76. package/dist/data/sync-engine.d.ts +15 -0
  77. package/dist/data/sync-engine.js +67 -0
  78. package/dist/data/sync-engine.js.map +1 -0
  79. package/dist/display/detail-view.d.ts +23 -0
  80. package/dist/display/detail-view.js +36 -0
  81. package/dist/display/detail-view.js.map +1 -0
  82. package/dist/display/status-line.d.ts +12 -0
  83. package/dist/display/status-line.js +17 -0
  84. package/dist/display/status-line.js.map +1 -0
  85. package/dist/hooks/claude/post-tool-use.d.ts +1 -0
  86. package/dist/hooks/claude/post-tool-use.js +82 -0
  87. package/dist/hooks/claude/post-tool-use.js.map +1 -0
  88. package/dist/hooks/claude/session-end.d.ts +1 -0
  89. package/dist/hooks/claude/session-end.js +23 -0
  90. package/dist/hooks/claude/session-end.js.map +1 -0
  91. package/dist/hooks/claude/status-line-updater.d.ts +1 -0
  92. package/dist/hooks/claude/status-line-updater.js +48 -0
  93. package/dist/hooks/claude/status-line-updater.js.map +1 -0
  94. package/dist/hooks/codex/session-end.d.ts +1 -0
  95. package/dist/hooks/codex/session-end.js +40 -0
  96. package/dist/hooks/codex/session-end.js.map +1 -0
  97. package/dist/hooks/common/session-start.d.ts +1 -0
  98. package/dist/hooks/common/session-start.js +34 -0
  99. package/dist/hooks/common/session-start.js.map +1 -0
  100. package/dist/i18n/en.d.ts +26 -0
  101. package/dist/i18n/en.js +26 -0
  102. package/dist/i18n/en.js.map +1 -0
  103. package/dist/i18n/index.d.ts +7 -0
  104. package/dist/i18n/index.js +30 -0
  105. package/dist/i18n/index.js.map +1 -0
  106. package/dist/i18n/ko.d.ts +26 -0
  107. package/dist/i18n/ko.js +26 -0
  108. package/dist/i18n/ko.js.map +1 -0
  109. package/dist/index.d.ts +1 -0
  110. package/dist/index.js +2 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/statusline.d.ts +2 -0
  113. package/dist/statusline.js +103 -0
  114. package/dist/statusline.js.map +1 -0
  115. package/package.json +55 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 imironjin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ko.md ADDED
@@ -0,0 +1,156 @@
1
+ # @myhpmp/cli
2
+
3
+ 한국어 | [English](./README.md)
4
+
5
+ AI 코딩 도구 사용량을 RPG 게임처럼 보여주는 대시보드.
6
+
7
+ AI 코딩 도구 사용을 게임으로 만들어보세요 — 레벨, HP(세션 한도), MP(주간 한도), EXP, 연속 사용일수를 추적하고 칭호를 획득하세요.
8
+
9
+ ## 지원 도구
10
+
11
+ - **Claude Code** — 전체 지원 (실시간 토큰 추적 + 상태 바)
12
+ - **Codex CLI** — 전체 지원 (세션 종료 시 토큰 추적)
13
+
14
+ ## 상태 바 (Claude Code)
15
+
16
+ Claude Code 하단에 항상 표시:
17
+
18
+ ```
19
+ ⚔️ 견습 전사 Lv.9 ★★★ | ❤️ 43% ⏱️2h30m | 💙 76% | 🧠 25% | 🔥7일
20
+ ```
21
+
22
+ ## 상세 보기
23
+
24
+ `myhpmp usage`로 전체 대시보드 확인:
25
+
26
+ ```
27
+ 🎮 ⚔️ 견습 전사 Lv.9 ★★★ 🔥 연속: 7일
28
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
29
+ ❤️ HP ████░░░░░░ 43% ⏱️ 2h30m
30
+ 💙 MP ████████░░ 76%
31
+ 🧠 CTX ███░░░░░░░ 25% (250K / 1.0M context)
32
+ ⭐ EXP ██████░░░░ 62% (186 / 300 → Lv.10)
33
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
34
+ 📊 총 누적 EXP: 2,886 | 총 세션: 47 회
35
+ ```
36
+
37
+ ## 스탯
38
+
39
+ | 스탯 | 설명 |
40
+ |------|------|
41
+ | **❤️ HP** | 5시간 세션 한도 잔여량 (%) + 리셋 시간 |
42
+ | **💙 MP** | 7일 주간 한도 잔여량 (%) |
43
+ | **🧠 CTX** | 현재 컨텍스트 윈도우 사용률 (%) |
44
+ | **🔥 연속** | 연속 사용일수 |
45
+ | **⭐ EXP** | 다음 레벨까지 경험치 |
46
+
47
+ ## 레벨 티어
48
+
49
+ | 레벨 | 칭호 | 레벨당 EXP | 누적 EXP |
50
+ |------|------|-----------|----------|
51
+ | 1-5 | 🌱 초보 모험가 | 100 | 500 |
52
+ | 6-10 | ⚔️ 견습 전사 | 300 | 2,000 |
53
+ | 11-15 | 🛡️ 숙련 기사 | 600 | 5,000 |
54
+ | 16-20 | 🧙 마법사 | 1,200 | 11,000 |
55
+ | 21-30 | 🔮 대마법사 | 3,500 | 46,000 |
56
+ | 31-40 | 👑 아크메이지 | 8,000 | 126,000 |
57
+ | 41-50 | 🐉 전설의 코드드래곤 | 15,000 | 276,000 |
58
+ | 50+ | ⚡ 초월자 | 25,000 | ∞ |
59
+
60
+ 초반 레벨은 빠르게 올라갑니다. 후반 티어는 꾸준한 사용이 필요합니다 — ⚡ 초월자까지 약 8개월 소요.
61
+
62
+ ## EXP 획득 방식
63
+
64
+ | 행동 | EXP |
65
+ |------|-----|
66
+ | 토큰 사용 | 1K 토큰당 1 EXP |
67
+ | 세션 완료 | 25 EXP |
68
+ | 연속 사용 보너스 | 연속일수 × 5 EXP (최대 30일 = 150 EXP) |
69
+ | 주간 70%+ 사용 | 100 EXP |
70
+
71
+ 모든 지원 도구의 EXP는 하나의 총합으로 합산됩니다. Claude와 Codex를 함께 사용해도 모두 누적됩니다.
72
+
73
+ ## 빠른 시작
74
+
75
+ ```bash
76
+ # 글로벌 설치
77
+ npm install -g @myhpmp/cli
78
+
79
+ # 자동 설정 (Claude Code, Codex, 또는 둘 다 선택)
80
+ myhpmp setup
81
+
82
+ # 표시 언어 설정
83
+ myhpmp locale
84
+
85
+ # AI 코딩 도구를 재시작하면 추적이 시작됩니다
86
+ ```
87
+
88
+ 끝! Hook을 통해 EXP가 쌓이기 시작합니다. 상태 바는 Claude Code에서 사용 가능합니다.
89
+
90
+ ## 명령어
91
+
92
+ | 명령어 | 설명 |
93
+ |--------|------|
94
+ | `myhpmp setup` | Hook 자동 설정 (Claude Code / Codex CLI) |
95
+ | `myhpmp usage` | RPG 대시보드 상세 보기 |
96
+ | `myhpmp sync` | 수동으로 클라우드 동기화 |
97
+ | `myhpmp statusline` | 상태 바 켜기/끄기 토글 (Claude Code) |
98
+ | `myhpmp statusline on` | 상태 바 켜기 |
99
+ | `myhpmp statusline off` | 상태 바 끄기 |
100
+ | `myhpmp locale` | 표시 언어 변경 (한국어/English) |
101
+ | `myhpmp init` | 인증 설정 (크로스 디바이스 동기화) |
102
+
103
+ ## 크로스 디바이스 동기화
104
+
105
+ 여러 기기에서 스탯(레벨, EXP, 연속일수)을 동기화:
106
+
107
+ ```bash
108
+ myhpmp init
109
+ ```
110
+
111
+ **GitHub OAuth**와 **Google OAuth** 인증을 지원합니다.
112
+
113
+ ### 동기화 방식
114
+
115
+ | 시점 | 동작 |
116
+ |------|------|
117
+ | 세션 시작 | 클라우드에서 최신 데이터 가져오기 |
118
+ | 5분마다 | 사용 중 자동 동기화 |
119
+ | 세션 종료 | 최종 스탯 클라우드에 저장 |
120
+ | `myhpmp sync` | 수동 즉시 동기화 |
121
+
122
+ 데이터는 `~/.myhpmp/data.json`에 로컬 저장되며 오프라인에서도 동작합니다. 클라우드 동기화에 실패하면 로컬 데이터가 보존되고, 다음 기회에 동기화됩니다. 로컬 EXP가 원격보다 낮으면(재설치 등) 항상 원격 데이터가 보존됩니다.
123
+
124
+ ## 요구 사항
125
+
126
+ - Node.js >= 18
127
+ - 지원되는 AI 코딩 도구 중 하나 이상:
128
+ - Claude Code (Pro/Max 구독)
129
+ - Codex CLI (OpenAI API 키)
130
+
131
+ ## 지원 플랫폼
132
+
133
+ - **Windows**
134
+ - **macOS**
135
+ - **Linux**
136
+
137
+ ## 다국어
138
+
139
+ 한국어와 영어를 지원합니다. `myhpmp locale`로 언어를 설정하거나, 시스템 로캘에서 자동 감지합니다.
140
+
141
+ ```
142
+ KO: ⚔️ 견습 전사 Lv.9 ★★★ | ❤️ 43% ⏱️2h30m | 💙 76% | 🧠 25% | 🔥7일
143
+ EN: ⚔️ Apprentice Warrior Lv.9 ★★★ | ❤️ 43% ⏱️2h30m | 💙 76% | 🧠 25% | 🔥7d
144
+ ```
145
+
146
+ ## 작동 방식
147
+
148
+ 1. **Hook** — 각 지원 도구의 hook 시스템으로 토큰 사용량, 세션, 연속일수 추적
149
+ 2. **어댑터 패턴** — Claude Code와 Codex CLI 각각의 어댑터가 도구별 데이터를 파싱
150
+ 3. **상태 바** — Claude Code가 세션 JSON을 상태 바 스크립트에 전달 → RPG HUD로 렌더링
151
+ 4. **로컬 저장소** — 모든 데이터가 `~/.myhpmp/data.json`에 저장 (오프라인 동작)
152
+ 5. **클라우드 동기화** — Supabase 연동, 자동 동기화. 서버사이드 EXP 검증으로 조작 방지
153
+
154
+ ## 라이선스
155
+
156
+ MIT
package/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # @myhpmp/cli
2
+
3
+ [한국어](./README.ko.md) | English
4
+
5
+ RPG-style gamified usage dashboard for AI coding tools.
6
+
7
+ Turn your AI coding tool usage into a game — track your level, HP (session limit), MP (weekly limit), EXP, streaks, and earn titles as you code.
8
+
9
+ ## Supported Tools
10
+
11
+ - **Claude Code** — full support (real-time token tracking + status line)
12
+ - **Codex CLI** — full support (session-end token tracking)
13
+
14
+ ## Status Line (Claude Code)
15
+
16
+ Always visible at the bottom of Claude Code:
17
+
18
+ ```
19
+ ⚔️ Apprentice Warrior Lv.9 ★★★ | ❤️ 43% ⏱️2h30m | 💙 76% | 🧠 25% | 🔥7d
20
+ ```
21
+
22
+ ## Detail View
23
+
24
+ Run `myhpmp usage` for the full dashboard:
25
+
26
+ ```
27
+ 🎮 ⚔️ Apprentice Warrior Lv.9 ★★★ 🔥 Streak: 7d
28
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
29
+ ❤️ HP ████░░░░░░ 43% ⏱️ 2h30m
30
+ 💙 MP ████████░░ 76%
31
+ 🧠 CTX ███░░░░░░░ 25% (250K / 1.0M context)
32
+ ⭐ EXP ██████░░░░ 62% (186 / 300 → Lv.10)
33
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
34
+ 📊 Total EXP: 2,886 | Total Sessions: 47 sessions
35
+ ```
36
+
37
+ ## Stats
38
+
39
+ | Stat | Description |
40
+ |------|-------------|
41
+ | **❤️ HP** | 5-hour session limit remaining (%) + reset timer |
42
+ | **💙 MP** | 7-day weekly limit remaining (%) |
43
+ | **🧠 CTX** | Current context window usage (%) |
44
+ | **🔥 Streak** | Consecutive days of usage |
45
+ | **⭐ EXP** | Experience points toward next level |
46
+
47
+ ## Level Tiers
48
+
49
+ | Level | Title | EXP/Level | Cumulative |
50
+ |-------|-------|-----------|------------|
51
+ | 1-5 | 🌱 Novice Adventurer | 100 | 500 |
52
+ | 6-10 | ⚔️ Apprentice Warrior | 300 | 2,000 |
53
+ | 11-15 | 🛡️ Skilled Knight | 600 | 5,000 |
54
+ | 16-20 | 🧙 Mage | 1,200 | 11,000 |
55
+ | 21-30 | 🔮 Archmage | 3,500 | 46,000 |
56
+ | 31-40 | 👑 Grand Archmage | 8,000 | 126,000 |
57
+ | 41-50 | 🐉 Legendary Code Dragon | 15,000 | 276,000 |
58
+ | 50+ | ⚡ Transcendent | 25,000 | ∞ |
59
+
60
+ Early levels fly by. Late tiers require serious dedication — expect ~8 months of daily use to reach ⚡ Transcendent.
61
+
62
+ ## EXP Sources
63
+
64
+ | Action | EXP |
65
+ |--------|-----|
66
+ | Token usage | 1 EXP per 1K tokens |
67
+ | Session complete | 25 EXP |
68
+ | Streak bonus | streak days × 5 EXP (cap: 30 days = 150 max) |
69
+ | Weekly 70%+ usage | 100 EXP |
70
+
71
+ EXP from all supported tools is combined into a single total. Use Claude and Codex together — it all adds up.
72
+
73
+ ## Quick Start
74
+
75
+ ```bash
76
+ # Install globally
77
+ npm install -g @myhpmp/cli
78
+
79
+ # Auto-configure (select Claude Code, Codex, or both)
80
+ myhpmp setup
81
+
82
+ # Set your display language
83
+ myhpmp locale
84
+
85
+ # Restart your AI coding tool to start tracking
86
+ ```
87
+
88
+ That's it! EXP tracking starts via hooks. Status line is available for Claude Code.
89
+
90
+ ## Commands
91
+
92
+ | Command | Description |
93
+ |---------|-------------|
94
+ | `myhpmp setup` | Auto-configure hooks (Claude Code / Codex CLI) |
95
+ | `myhpmp usage` | Show detailed RPG dashboard |
96
+ | `myhpmp sync` | Manually sync stats to cloud |
97
+ | `myhpmp statusline` | Toggle status line on/off (Claude Code) |
98
+ | `myhpmp statusline on` | Enable status line |
99
+ | `myhpmp statusline off` | Disable status line |
100
+ | `myhpmp locale` | Change display language (한국어/English) |
101
+ | `myhpmp init` | Set up authentication (cross-device sync) |
102
+
103
+ ## Cross-Device Sync
104
+
105
+ Sync your stats (level, EXP, streaks) across multiple machines:
106
+
107
+ ```bash
108
+ myhpmp init
109
+ ```
110
+
111
+ Supports **GitHub OAuth** and **Google OAuth** authentication.
112
+
113
+ ### How sync works
114
+
115
+ | Timing | Behavior |
116
+ |--------|----------|
117
+ | Session start | Pull latest from cloud → update local |
118
+ | Every 5 minutes | Auto-sync during active use |
119
+ | Session end | Push final stats to cloud |
120
+ | `myhpmp sync` | Manual sync on demand |
121
+
122
+ Data is stored locally at `~/.myhpmp/data.json` and works offline. Cloud sync is best-effort — if it fails, local data is preserved and synced on next opportunity. If local EXP is lower than remote (e.g. after reinstall), remote data is always preserved.
123
+
124
+ ## Requirements
125
+
126
+ - Node.js >= 18
127
+ - One or more supported AI coding tools:
128
+ - Claude Code (Pro/Max subscription)
129
+ - Codex CLI (OpenAI API key)
130
+
131
+ ## Supported Platforms
132
+
133
+ - **Windows**
134
+ - **macOS**
135
+ - **Linux**
136
+
137
+ ## i18n
138
+
139
+ Supports Korean and English. Set your language with `myhpmp locale`, or it auto-detects from your system locale.
140
+
141
+ ```
142
+ KO: ⚔️ 견습 전사 Lv.9 ★★★ | ❤️ 43% ⏱️2h30m | 💙 76% | 🧠 25% | 🔥7일
143
+ EN: ⚔️ Apprentice Warrior Lv.9 ★★★ | ❤️ 43% ⏱️2h30m | 💙 76% | 🧠 25% | 🔥7d
144
+ ```
145
+
146
+ ## How It Works
147
+
148
+ 1. **Hooks** — Each supported tool's hook system tracks token usage, sessions, and streaks
149
+ 2. **Adapter Pattern** — Claude Code and Codex CLI each have their own adapter for parsing tool-specific data
150
+ 3. **Status Line** — Claude Code pipes session JSON to the status line script, rendered as RPG HUD
151
+ 4. **Local Store** — All data saved to `~/.myhpmp/data.json` (works offline)
152
+ 5. **Cloud Sync** — Supabase integration with auto-sync. Server-side EXP validation prevents manipulation
153
+
154
+ ## License
155
+
156
+ MIT
@@ -0,0 +1,9 @@
1
+ import type { ProviderAdapter, ProviderHookConfig } from './provider.js';
2
+ export declare class ClaudeAdapter implements ProviderAdapter {
3
+ readonly name = "claude";
4
+ readonly configDir: string;
5
+ readonly supportsStatusLine = true;
6
+ parseToolUseTokens(stdin: string): number;
7
+ getSessionTokens(): Promise<number>;
8
+ generateHookConfig(distDir: string): ProviderHookConfig;
9
+ }
@@ -0,0 +1,36 @@
1
+ import path from 'node:path';
2
+ import os from 'node:os';
3
+ export class ClaudeAdapter {
4
+ name = 'claude';
5
+ configDir = path.join(os.homedir(), '.claude');
6
+ supportsStatusLine = true;
7
+ parseToolUseTokens(stdin) {
8
+ try {
9
+ const data = JSON.parse(stdin);
10
+ return Number(data?.usage?.total_tokens ?? 0);
11
+ }
12
+ catch {
13
+ return 0;
14
+ }
15
+ }
16
+ async getSessionTokens() {
17
+ // Claude tracks tokens per tool use via hooks, not at session end
18
+ return 0;
19
+ }
20
+ generateHookConfig(distDir) {
21
+ const hook = (file) => `node "${path.join(distDir, 'hooks', file).replace(/\\/g, '/')}"`;
22
+ return {
23
+ settingsPath: path.join(this.configDir, 'settings.json'),
24
+ hooks: {
25
+ PostToolUse: [{ matcher: '', hooks: [{ type: 'command', command: hook('claude/post-tool-use.js') }] }],
26
+ SessionStart: [{ matcher: '', hooks: [{ type: 'command', command: hook('common/session-start.js') }] }],
27
+ Stop: [{ matcher: '', hooks: [{ type: 'command', command: hook('claude/session-end.js') }] }],
28
+ },
29
+ statusLine: {
30
+ type: 'command',
31
+ command: `node "${path.join(distDir, 'statusline.js').replace(/\\/g, '/')}"`,
32
+ },
33
+ };
34
+ }
35
+ }
36
+ //# sourceMappingURL=claude-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-adapter.js","sourceRoot":"","sources":["../../src/adapter/claude-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB,MAAM,OAAO,aAAa;IACf,IAAI,GAAG,QAAQ,CAAC;IAChB,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC/C,kBAAkB,GAAG,IAAI,CAAC;IAEnC,kBAAkB,CAAC,KAAa;QAC9B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/B,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,kEAAkE;QAClE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,kBAAkB,CAAC,OAAe;QAChC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC;QAEjG,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC;YACxD,KAAK,EAAE;gBACL,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC;gBACtG,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC;gBACvG,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,uBAAuB,CAAC,EAAE,CAAC,EAAE,CAAC;aAC9F;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG;aAC7E;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ import type { ProviderAdapter, ProviderHookConfig } from './provider.js';
2
+ export declare class CodexAdapter implements ProviderAdapter {
3
+ readonly name = "codex";
4
+ readonly configDir: string;
5
+ readonly supportsStatusLine = false;
6
+ parseToolUseTokens(_stdin: string): number;
7
+ /**
8
+ * Parse the most recent Codex session JSONL to get total tokens used.
9
+ * Reads token_count events and returns the last total_token_usage.total_tokens.
10
+ */
11
+ getSessionTokens(): Promise<number>;
12
+ private findLatestSession;
13
+ generateHookConfig(distDir: string): ProviderHookConfig;
14
+ }
@@ -0,0 +1,84 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import readline from 'node:readline';
5
+ import { createReadStream } from 'node:fs';
6
+ export class CodexAdapter {
7
+ name = 'codex';
8
+ configDir = path.join(os.homedir(), '.codex');
9
+ supportsStatusLine = false;
10
+ parseToolUseTokens(_stdin) {
11
+ // Codex doesn't provide token data in hook stdin
12
+ return 0;
13
+ }
14
+ /**
15
+ * Parse the most recent Codex session JSONL to get total tokens used.
16
+ * Reads token_count events and returns the last total_token_usage.total_tokens.
17
+ */
18
+ async getSessionTokens() {
19
+ try {
20
+ const sessionFile = await this.findLatestSession();
21
+ if (!sessionFile)
22
+ return 0;
23
+ let totalTokens = 0;
24
+ const stream = createReadStream(sessionFile, 'utf-8');
25
+ const rl = readline.createInterface({ input: stream });
26
+ for await (const line of rl) {
27
+ try {
28
+ const entry = JSON.parse(line);
29
+ if (entry.type === 'event_msg' && entry.payload?.type === 'token_count') {
30
+ const total = entry.payload.info?.total_token_usage?.total_tokens;
31
+ if (typeof total === 'number') {
32
+ totalTokens = total;
33
+ }
34
+ }
35
+ }
36
+ catch {
37
+ // Skip malformed lines
38
+ }
39
+ }
40
+ return totalTokens;
41
+ }
42
+ catch {
43
+ return 0;
44
+ }
45
+ }
46
+ async findLatestSession() {
47
+ const sessionsDir = path.join(this.configDir, 'sessions');
48
+ const isDigits = (s, len) => new RegExp(`^\\d{${len}}$`).test(s);
49
+ try {
50
+ const years = (await fs.readdir(sessionsDir)).filter(d => isDigits(d, 4));
51
+ const latestYear = years.sort().pop();
52
+ if (!latestYear)
53
+ return null;
54
+ const months = (await fs.readdir(path.join(sessionsDir, latestYear))).filter(d => isDigits(d, 2));
55
+ const latestMonth = months.sort().pop();
56
+ if (!latestMonth)
57
+ return null;
58
+ const days = (await fs.readdir(path.join(sessionsDir, latestYear, latestMonth))).filter(d => isDigits(d, 2));
59
+ const latestDay = days.sort().pop();
60
+ if (!latestDay)
61
+ return null;
62
+ const dayDir = path.join(sessionsDir, latestYear, latestMonth, latestDay);
63
+ const files = (await fs.readdir(dayDir)).filter(f => f.endsWith('.jsonl')).sort();
64
+ const latestFile = files.pop();
65
+ if (!latestFile)
66
+ return null;
67
+ return path.join(dayDir, latestFile);
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ }
73
+ generateHookConfig(distDir) {
74
+ const hook = (file) => `node "${path.join(distDir, 'hooks', file).replace(/\\/g, '/')}"`;
75
+ return {
76
+ settingsPath: path.join(this.configDir, 'hooks.json'),
77
+ hooks: {
78
+ SessionStart: [{ matcher: '', hooks: [{ type: 'command', command: hook('common/session-start.js') }] }],
79
+ Stop: [{ matcher: '', hooks: [{ type: 'command', command: hook('codex/session-end.js') }] }],
80
+ },
81
+ };
82
+ }
83
+ }
84
+ //# sourceMappingURL=codex-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../../src/adapter/codex-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export type { ProviderAdapter, ProviderHookConfig } from './provider.js';
2
+ export { ClaudeAdapter } from './claude-adapter.js';
3
+ export { CodexAdapter } from './codex-adapter.js';
4
+ import type { ProviderAdapter } from './provider.js';
5
+ export declare function getProvider(name: string): ProviderAdapter;
6
+ export declare function listProviders(): string[];
@@ -0,0 +1,18 @@
1
+ export { ClaudeAdapter } from './claude-adapter.js';
2
+ export { CodexAdapter } from './codex-adapter.js';
3
+ import { ClaudeAdapter } from './claude-adapter.js';
4
+ import { CodexAdapter } from './codex-adapter.js';
5
+ const PROVIDERS = {
6
+ claude: () => new ClaudeAdapter(),
7
+ codex: () => new CodexAdapter(),
8
+ };
9
+ export function getProvider(name) {
10
+ const factory = PROVIDERS[name];
11
+ if (!factory)
12
+ throw new Error(`Unknown provider: ${name}. Supported: ${Object.keys(PROVIDERS).join(', ')}`);
13
+ return factory();
14
+ }
15
+ export function listProviders() {
16
+ return Object.keys(PROVIDERS);
17
+ }
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,SAAS,GAA0C;IACvD,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,aAAa,EAAE;IACjC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,YAAY,EAAE;CAChC,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,gBAAgB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5G,OAAO,OAAO,EAAE,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Provider adapter interface.
3
+ * Each AI coding tool (Claude Code, Codex, etc.) implements this.
4
+ */
5
+ export interface ProviderAdapter {
6
+ /** Provider name */
7
+ readonly name: string;
8
+ /** Provider config directory (e.g. ~/.claude, ~/.codex) */
9
+ readonly configDir: string;
10
+ /** Whether this provider supports a status line */
11
+ readonly supportsStatusLine: boolean;
12
+ /** Extract token count from PostToolUse stdin JSON. Return 0 if not available. */
13
+ parseToolUseTokens(stdin: string): number;
14
+ /** Get total session tokens at session end (e.g. from JSONL transcript). Return 0 if not available. */
15
+ getSessionTokens(): Promise<number>;
16
+ /** Generate hook configuration for this provider's settings file */
17
+ generateHookConfig(distDir: string): ProviderHookConfig;
18
+ }
19
+ export interface ProviderHookConfig {
20
+ settingsPath: string;
21
+ hooks: Record<string, unknown>;
22
+ statusLine?: unknown;
23
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Provider adapter interface.
3
+ * Each AI coding tool (Claude Code, Codex, etc.) implements this.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/adapter/provider.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,15 @@
1
+ export interface AuthConfig {
2
+ userId: string;
3
+ accessToken: string;
4
+ refreshToken: string;
5
+ provider: 'github' | 'google';
6
+ locale: string;
7
+ }
8
+ export declare class AuthManager {
9
+ private configPath;
10
+ constructor(configDir: string);
11
+ isAuthenticated(): Promise<boolean>;
12
+ loadConfig(): Promise<AuthConfig>;
13
+ saveConfig(config: AuthConfig): Promise<void>;
14
+ getUserId(): Promise<string>;
15
+ }
@@ -0,0 +1,34 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ export class AuthManager {
4
+ configPath;
5
+ constructor(configDir) {
6
+ this.configPath = path.join(configDir, 'config.json');
7
+ }
8
+ async isAuthenticated() {
9
+ try {
10
+ const config = await this.loadConfig();
11
+ return !!config.userId && !!config.accessToken;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ async loadConfig() {
18
+ const raw = await fs.readFile(this.configPath, 'utf-8');
19
+ return JSON.parse(raw);
20
+ }
21
+ async saveConfig(config) {
22
+ const dir = path.dirname(this.configPath);
23
+ await fs.mkdir(dir, { recursive: true });
24
+ await fs.writeFile(this.configPath, JSON.stringify(config, null, 2), {
25
+ encoding: 'utf-8',
26
+ mode: 0o600,
27
+ });
28
+ }
29
+ async getUserId() {
30
+ const config = await this.loadConfig();
31
+ return config.userId;
32
+ }
33
+ }
34
+ //# sourceMappingURL=auth-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-manager.js","sourceRoot":"","sources":["../../src/auth/auth-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAU7B,MAAM,OAAO,WAAW;IACd,UAAU,CAAS;IAE3B,YAAY,SAAiB;QAC3B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACvC,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAkB;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;YACnE,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import type { SupabaseClient, Provider } from '@supabase/supabase-js';
2
+ export declare function signInWithOAuth(supabase: SupabaseClient, provider: Provider): Promise<{
3
+ userId: string;
4
+ accessToken: string;
5
+ refreshToken: string;
6
+ }>;