@su-record/vibe 2.8.53 → 2.9.1
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.ko.md +43 -128
- package/README.md +43 -128
- package/dist/cli/postinstall/main.d.ts.map +1 -1
- package/dist/cli/postinstall/main.js +40 -66
- package/dist/cli/postinstall/main.js.map +1 -1
- package/dist/infra/lib/CostAccumulator.d.ts +58 -0
- package/dist/infra/lib/CostAccumulator.d.ts.map +1 -0
- package/dist/infra/lib/CostAccumulator.js +131 -0
- package/dist/infra/lib/CostAccumulator.js.map +1 -0
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -7,57 +7,50 @@
|
|
|
7
7
|
[](https://nodejs.org/)
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Vibe는 AI 코딩 도구를 위한 품질 하네스입니다. Claude Code, Codex, Cursor, Gemini CLI를 감싸고, 타입 안전성, 코드 품질, 보안을 자동으로 강제합니다.
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
npm install -g @su-record/vibe
|
|
14
14
|
vibe init
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
**Claude Code**, **Codex**, **Cursor**, **Gemini CLI**에서 동작합니다.
|
|
18
|
-
|
|
19
17
|
---
|
|
20
18
|
|
|
21
|
-
##
|
|
19
|
+
## 이렇게 동작합니다
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
```
|
|
22
|
+
사용자: "사용자 인증 추가해줘"
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
/vibe.spec → GPT + Gemini 병렬 리서치 → SPEC 문서 자동 생성
|
|
25
|
+
/vibe.run → SPEC 기반 구현 → 12개 에이전트 병렬 리뷰
|
|
26
|
+
품질 게이트 → any 타입 차단, 긴 함수 차단, 위험한 명령 차단
|
|
27
|
+
완료 → 리뷰 통과된 타입 안전 코드만 남음
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
전부 자동. 프롬프트 한 줄이면 됩니다.
|
|
30
|
+
```
|
|
31
31
|
|
|
32
32
|
---
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## 빠른 시작
|
|
35
35
|
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
```bash
|
|
37
|
+
# 1. 설치
|
|
38
|
+
npm install -g @su-record/vibe
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
| **Sensors** (피드백) | 행동 **후에** 관찰·교정 | 훅 21개, 품질 게이트, 이볼루션 엔진 |
|
|
40
|
+
# 2. 프로젝트 초기화 (스택 자동 감지)
|
|
41
|
+
cd your-project
|
|
42
|
+
vibe init
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
# 3. AI 코딩 도구와 함께 사용
|
|
45
|
+
claude # Claude Code
|
|
46
|
+
# 또는 codex, cursor, gemini — 모두 지원
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
B --> C["/vibe.run"]
|
|
51
|
-
C --> D["자동 리뷰"]
|
|
52
|
-
D --> E["완료"]
|
|
48
|
+
# 4. 워크플로우 시작
|
|
49
|
+
/vibe.spec "사용자 인증 추가" # 요구사항 작성
|
|
50
|
+
/vibe.run # SPEC 기반 구현
|
|
53
51
|
```
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
2. **검증** — `/vibe.spec.review`가 3중 교차 검증 실행 (Claude + GPT + Gemini)
|
|
57
|
-
3. **구현** — `/vibe.run`이 SPEC 기반 구현 + 병렬 코드 리뷰
|
|
58
|
-
4. **리뷰** — 12개 에이전트가 병렬 리뷰, P1/P2 이슈 자동 수정
|
|
59
|
-
|
|
60
|
-
`ultrawork`를 추가하면 전체 파이프라인이 자동화됩니다:
|
|
53
|
+
`ultrawork`를 붙이면 전체 파이프라인이 자동화됩니다:
|
|
61
54
|
|
|
62
55
|
```bash
|
|
63
56
|
/vibe.run "사용자 인증 추가" ultrawork
|
|
@@ -65,112 +58,39 @@ flowchart LR
|
|
|
65
58
|
|
|
66
59
|
---
|
|
67
60
|
|
|
68
|
-
##
|
|
69
|
-
|
|
70
|
-
**품질 게이트** — `any` 타입, `@ts-ignore`, 50줄 초과 함수를 차단합니다. 3계층 방어: 센티넬 가드 → 프리툴 가드 → 코드 체크.
|
|
71
|
-
|
|
72
|
-
**56개 전문 에이전트** — 탐색, 구현, 아키텍처, 12개 병렬 리뷰어, 8개 UI/UX 에이전트, QA 코디네이터. 각 에이전트는 범용 래퍼가 아닌 목적 특화 설계.
|
|
73
|
-
|
|
74
|
-
**멀티 LLM 오케스트레이션** — Claude로 오케스트레이션, GPT로 추론, Gemini로 리서치. 가용 모델에 따라 자동 라우팅. 기본값은 Claude 단독 운영.
|
|
61
|
+
## 주요 기능
|
|
75
62
|
|
|
76
|
-
|
|
63
|
+
**품질 게이트** — `any` 타입, `@ts-ignore`, 50줄 초과 함수를 차단. 3계층 방어가 모든 도구 호출마다 실행.
|
|
77
64
|
|
|
78
|
-
|
|
65
|
+
**전문 에이전트** — 탐색, 구현, 아키텍처, 코드 리뷰(12개 병렬), UI/UX 분석 등 56개 목적 특화 에이전트.
|
|
79
66
|
|
|
80
|
-
|
|
67
|
+
**멀티 LLM** — Claude가 오케스트레이션, GPT가 추론, Gemini가 리서치. 가용 모델에 따라 자동 라우팅. 기본값은 Claude 단독.
|
|
81
68
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
## 포함 내용
|
|
85
|
-
|
|
86
|
-
| 분류 | 수량 | 예시 |
|
|
87
|
-
|------|------|------|
|
|
88
|
-
| **에이전트** | 56 | Explorer, Implementer, Architect (각 3단계), 리뷰 전문가 12개, UI/UX 8개, QA 코디네이터 |
|
|
89
|
-
| **스킬** | 45 | 3티어 시스템 (core/standard/optional) — 컨텍스트 과부하 방지 |
|
|
90
|
-
| **훅** | 21 | 세션 복원, 파괴적 명령 차단, 자동 포맷, 품질 체크, 컨텍스트 자동 저장 |
|
|
91
|
-
| **프레임워크** | 24 | TypeScript (12), Python (2), Java/Kotlin (2), Rails, Go, Rust, Swift, Flutter, Unity, Godot |
|
|
92
|
-
| **슬래시 커맨드** | 11 | `/vibe.spec`, `/vibe.run`, `/vibe.review`, `/vibe.trace`, `/vibe.figma` 등 |
|
|
69
|
+
**세션 메모리** — 결정, 제약, 목표가 SQLite + FTS5 검색으로 세션 간 유지.
|
|
93
70
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
## 멀티 CLI 지원
|
|
71
|
+
**스택 감지** — 24개 프레임워크 자동 감지 (Next.js, Django, Rails, Go, Rust, Flutter 등) 후 프레임워크별 규칙 적용.
|
|
97
72
|
|
|
98
|
-
|
|
99
|
-
|-----|---------|------|----------|
|
|
100
|
-
| Claude Code | `~/.claude/agents/` | `~/.claude/skills/` | `CLAUDE.md` |
|
|
101
|
-
| Codex | `~/.codex/plugins/vibe/` | 플러그인 내장 | `AGENTS.md` |
|
|
102
|
-
| Cursor | `~/.cursor/agents/` | `~/.cursor/skills/` | `.cursorrules` |
|
|
103
|
-
| Gemini CLI | `~/.gemini/agents/` | `~/.gemini/skills/` | `GEMINI.md` |
|
|
73
|
+
**Figma → 코드** — 트리 기반 구조적 매핑으로 디자인 대비 90% 완성도 목표. Figma REST API에서 30+ CSS 속성을 추출하여 반응형 코드 생성.
|
|
104
74
|
|
|
105
75
|
---
|
|
106
76
|
|
|
107
|
-
##
|
|
108
|
-
|
|
109
|
-
| 프로바이더 | 역할 | 필수 여부 |
|
|
110
|
-
|-----------|------|----------|
|
|
111
|
-
| **Claude** | 오케스트레이션, SPEC, 리뷰 | 필수 (Claude Code) |
|
|
112
|
-
| **GPT** | 추론, 아키텍처, 엣지 케이스 | 선택 (Codex CLI 또는 API Key) |
|
|
113
|
-
| **Gemini** | 리서치, 교차 검증, UI/UX | 선택 (gemini-cli 또는 API Key) |
|
|
77
|
+
## 지원 도구
|
|
114
78
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
vibe gemini key <your-api-key>
|
|
122
|
-
```
|
|
79
|
+
| CLI | 상태 |
|
|
80
|
+
|-----|------|
|
|
81
|
+
| [Claude Code](https://claude.ai/code) | 전체 지원 |
|
|
82
|
+
| [Codex](https://github.com/openai/codex) | 플러그인 |
|
|
83
|
+
| [Cursor](https://cursor.sh) | 에이전트 + 룰 |
|
|
84
|
+
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | 에이전트 + 스킬 |
|
|
123
85
|
|
|
124
86
|
---
|
|
125
87
|
|
|
126
|
-
##
|
|
127
|
-
|
|
128
|
-
트리 기반 구조적 매핑으로 디자인을 코드로 변환 (스크린샷 추정이 아님).
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
/vibe.figma # 모든 URL 한번에 입력 (스토리보드 + 모바일 + 데스크탑)
|
|
132
|
-
/vibe.figma --new # 새 피처 모드 (독립 스타일 생성)
|
|
133
|
-
/vibe.figma --refine # 보완 모드 (기존 코드 + Figma 재비교 → 수정)
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
스토리보드·모바일·데스크탑 Figma URL을 한번에 전달. Figma REST API로 트리 + 노드 이미지 추출 → 브레이크포인트 간 리매핑 → 스택 인식 코드 생성 (React/Vue/Svelte/SCSS/Tailwind) → 시각 검증 루프.
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
## CLI 레퍼런스
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
vibe init # 프로젝트 초기화 (스택 감지, 하네스 설치)
|
|
144
|
-
vibe update # 스택 재감지, 설정 새로고침
|
|
145
|
-
vibe upgrade # 최신 버전 업그레이드
|
|
146
|
-
vibe status # 현재 상태 확인
|
|
147
|
-
vibe config show # 통합 설정 보기
|
|
148
|
-
vibe stats [--week|--quality] # 사용량 텔레메트리
|
|
149
|
-
|
|
150
|
-
vibe gpt key|status # GPT API Key 설정
|
|
151
|
-
vibe gemini key|status # Gemini API Key 설정
|
|
152
|
-
vibe figma breakpoints # 반응형 브레이크포인트
|
|
153
|
-
vibe skills add <owner/repo> # skills.sh에서 스킬 설치
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## 설정
|
|
159
|
-
|
|
160
|
-
| 파일 | 용도 |
|
|
161
|
-
|------|------|
|
|
162
|
-
| `~/.vibe/config.json` | 글로벌 — 인증, 채널, 모델 (0o600) |
|
|
163
|
-
| `.claude/vibe/config.json` | 프로젝트 — 스택, 기능, 품질 설정 |
|
|
164
|
-
|
|
165
|
-
---
|
|
88
|
+
## 문서
|
|
166
89
|
|
|
167
|
-
|
|
90
|
+
상세 가이드, 스킬 레퍼런스, 설정 방법은 [Wiki](https://github.com/su-record/vibe/wiki)를 참고하세요.
|
|
168
91
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
| `ultrawork` | 전체 자동화 — 병렬 에이전트 + 자동 계속 + 품질 루프 |
|
|
172
|
-
| `ralph` | 100% 완료까지 반복 (스코프 축소 없음) |
|
|
173
|
-
| `quick` | 빠른 모드, 최소 검증 |
|
|
92
|
+
- [README (English)](README.md)
|
|
93
|
+
- [릴리스 노트](RELEASE_NOTES.md)
|
|
174
94
|
|
|
175
95
|
---
|
|
176
96
|
|
|
@@ -178,12 +98,7 @@ vibe skills add <owner/repo> # skills.sh에서 스킬 설치
|
|
|
178
98
|
|
|
179
99
|
- Node.js >= 18.0.0
|
|
180
100
|
- Claude Code (필수)
|
|
181
|
-
- GPT, Gemini (선택
|
|
182
|
-
|
|
183
|
-
## 문서
|
|
184
|
-
|
|
185
|
-
- [README (English)](README.md)
|
|
186
|
-
- [릴리스 노트](RELEASE_NOTES.md)
|
|
101
|
+
- GPT, Gemini (선택)
|
|
187
102
|
|
|
188
103
|
## 라이선스
|
|
189
104
|
|
package/README.md
CHANGED
|
@@ -7,170 +7,90 @@
|
|
|
7
7
|
[](https://nodejs.org/)
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Vibe is a quality harness for AI coding tools. It wraps around Claude Code, Codex, Cursor, or Gemini CLI and automatically enforces type safety, code quality, and security — before, during, and after code generation.
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
npm install -g @su-record/vibe
|
|
14
14
|
vibe init
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Works with **Claude Code**, **Codex**, **Cursor**, and **Gemini CLI**.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## The Problem
|
|
22
|
-
|
|
23
|
-
AI coding tools generate working code, but:
|
|
24
|
-
|
|
25
|
-
- Types are `any`, reviews are skipped, tests are forgotten
|
|
26
|
-
- You catch issues manually — after the damage is done
|
|
27
|
-
- Context vanishes between sessions
|
|
28
|
-
- Complex tasks spiral without structure
|
|
29
|
-
|
|
30
|
-
**Vibe is a harness.** It wraps around your AI coding tool and enforces quality automatically — before, during, and after code generation.
|
|
31
|
-
|
|
32
17
|
---
|
|
33
18
|
|
|
34
19
|
## How It Works
|
|
35
20
|
|
|
36
21
|
```
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
| | Role | What's Inside |
|
|
41
|
-
|---|------|--------------|
|
|
42
|
-
| **Guides** (feedforward) | Set direction *before* action | CLAUDE.md, 56 agents, 45 skills, coding rules |
|
|
43
|
-
| **Sensors** (feedback) | Observe and correct *after* action | 21 hooks, quality gates, evolution engine |
|
|
22
|
+
You: "Add user authentication"
|
|
44
23
|
|
|
45
|
-
|
|
24
|
+
/vibe.spec → GPT + Gemini research in parallel → SPEC document
|
|
25
|
+
/vibe.run → Implement from SPEC → 12 agents review in parallel
|
|
26
|
+
Quality gates → Block any types, long functions, dangerous commands
|
|
27
|
+
Done → Only reviewed, type-safe code remains
|
|
46
28
|
|
|
47
|
-
|
|
48
|
-
flowchart LR
|
|
49
|
-
A["/vibe.spec"] --> B["/vibe.spec.review"]
|
|
50
|
-
B --> C["/vibe.run"]
|
|
51
|
-
C --> D["Auto Review"]
|
|
52
|
-
D --> E["Done"]
|
|
29
|
+
Every step is automatic. You type one prompt.
|
|
53
30
|
```
|
|
54
31
|
|
|
55
|
-
1. **Define** — `/vibe.spec` writes requirements with GPT + Gemini parallel research
|
|
56
|
-
2. **Review** — `/vibe.spec.review` runs triple cross-validation (Claude + GPT + Gemini)
|
|
57
|
-
3. **Implement** — `/vibe.run` builds from SPEC with parallel code review
|
|
58
|
-
4. **Verify** — 12 agents review in parallel, P1/P2 issues auto-fixed
|
|
59
|
-
|
|
60
|
-
Add `ultrawork` to run the entire pipeline hands-free:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
/vibe.run "add user authentication" ultrawork
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Key Features
|
|
69
|
-
|
|
70
|
-
**Quality Gates** — Blocks `any` types, `@ts-ignore`, functions > 50 lines. Three-layer defense: sentinel guard → pre-tool guard → code check.
|
|
71
|
-
|
|
72
|
-
**56 Specialized Agents** — Exploration, implementation, architecture, 12 parallel reviewers, 8 UI/UX agents, QA coordination. Each agent is purpose-built, not a generic wrapper.
|
|
73
|
-
|
|
74
|
-
**Multi-LLM Orchestration** — Claude for orchestration, GPT for reasoning, Gemini for research. Auto-routes based on available models. Works Claude-only by default.
|
|
75
|
-
|
|
76
|
-
**Session RAG** — SQLite + FTS5 hybrid search persists decisions, constraints, and goals across sessions. Context is restored automatically on session start.
|
|
77
|
-
|
|
78
|
-
**24 Framework Detection** — Auto-detects your stack (Next.js, React, Django, Spring Boot, Rails, Go, Rust, and 17 more) and applies framework-specific rules. Monorepo-aware.
|
|
79
|
-
|
|
80
|
-
**Self-Improvement** — Evolution engine analyzes hook execution patterns, detects skill gaps, and generates new rules. Circuit breaker rolls back on regression.
|
|
81
|
-
|
|
82
32
|
---
|
|
83
33
|
|
|
84
|
-
##
|
|
85
|
-
|
|
86
|
-
| Category | Count | Examples |
|
|
87
|
-
|----------|-------|---------|
|
|
88
|
-
| **Agents** | 56 | Explorer, Implementer, Architect (3 depth levels each), 12 review specialists, 8 UI/UX, QA coordinator |
|
|
89
|
-
| **Skills** | 45 | 3-tier system (core/standard/optional) to prevent context overload |
|
|
90
|
-
| **Hooks** | 21 | Session restore, destructive command blocking, auto-format, quality check, context auto-save |
|
|
91
|
-
| **Frameworks** | 24 | TypeScript (12), Python (2), Java/Kotlin (2), Rails, Go, Rust, Swift, Flutter, Unity, Godot |
|
|
92
|
-
| **Slash Commands** | 11 | `/vibe.spec`, `/vibe.run`, `/vibe.review`, `/vibe.trace`, `/vibe.figma`, and more |
|
|
34
|
+
## Quick Start
|
|
93
35
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
| CLI | Agents | Skills | Instructions |
|
|
99
|
-
|-----|--------|--------|-------------|
|
|
100
|
-
| Claude Code | `~/.claude/agents/` | `~/.claude/skills/` | `CLAUDE.md` |
|
|
101
|
-
| Codex | `~/.codex/plugins/vibe/` | Plugin built-in | `AGENTS.md` |
|
|
102
|
-
| Cursor | `~/.cursor/agents/` | `~/.cursor/skills/` | `.cursorrules` |
|
|
103
|
-
| Gemini CLI | `~/.gemini/agents/` | `~/.gemini/skills/` | `GEMINI.md` |
|
|
104
|
-
|
|
105
|
-
---
|
|
36
|
+
```bash
|
|
37
|
+
# 1. Install
|
|
38
|
+
npm install -g @su-record/vibe
|
|
106
39
|
|
|
107
|
-
|
|
40
|
+
# 2. Initialize your project (auto-detects stack)
|
|
41
|
+
cd your-project
|
|
42
|
+
vibe init
|
|
108
43
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
| **GPT** | Reasoning, architecture, edge cases | Optional (Codex CLI or API key) |
|
|
113
|
-
| **Gemini** | Research, cross-validation, UI/UX | Optional (gemini-cli or API key) |
|
|
44
|
+
# 3. Use with your AI coding tool
|
|
45
|
+
claude # Claude Code
|
|
46
|
+
# or codex, cursor, gemini — all supported
|
|
114
47
|
|
|
115
|
-
|
|
48
|
+
# 4. Try the workflow
|
|
49
|
+
/vibe.spec "add user authentication" # Write requirements
|
|
50
|
+
/vibe.run # Implement from SPEC
|
|
51
|
+
```
|
|
116
52
|
|
|
117
|
-
|
|
53
|
+
Add `ultrawork` to any command for full automation:
|
|
118
54
|
|
|
119
55
|
```bash
|
|
120
|
-
vibe
|
|
121
|
-
vibe gemini key <your-api-key>
|
|
56
|
+
/vibe.run "add user authentication" ultrawork
|
|
122
57
|
```
|
|
123
58
|
|
|
124
59
|
---
|
|
125
60
|
|
|
126
|
-
##
|
|
61
|
+
## What It Does
|
|
127
62
|
|
|
128
|
-
|
|
63
|
+
**Quality gates** — Blocks `any` types, `@ts-ignore`, functions over 50 lines. Three-layer defense runs on every tool call.
|
|
129
64
|
|
|
130
|
-
|
|
131
|
-
/vibe.figma # All URLs at once (storyboard + mobile + desktop)
|
|
132
|
-
/vibe.figma --new # New feature mode (create standalone styles)
|
|
133
|
-
/vibe.figma --refine # Refine mode (compare existing code with Figma → fix)
|
|
134
|
-
```
|
|
65
|
+
**Specialized agents** — 56 purpose-built agents for exploration, implementation, architecture, code review (12 in parallel), and UI/UX analysis.
|
|
135
66
|
|
|
136
|
-
|
|
67
|
+
**Multi-LLM** — Claude orchestrates, GPT reasons, Gemini researches. Auto-routes by availability. Works Claude-only by default.
|
|
137
68
|
|
|
138
|
-
|
|
69
|
+
**Session memory** — Decisions, constraints, and goals persist across sessions via SQLite + FTS5 hybrid search.
|
|
139
70
|
|
|
140
|
-
|
|
71
|
+
**Stack detection** — Auto-detects 24 frameworks (Next.js, Django, Rails, Go, Rust, Flutter, and more) and applies framework-specific rules.
|
|
141
72
|
|
|
142
|
-
|
|
143
|
-
vibe init # Initialize project (detect stack, install harness)
|
|
144
|
-
vibe update # Re-detect stacks, refresh config
|
|
145
|
-
vibe upgrade # Upgrade to latest version
|
|
146
|
-
vibe status # Show current status
|
|
147
|
-
vibe config show # Unified config view
|
|
148
|
-
vibe stats [--week|--quality] # Usage telemetry
|
|
149
|
-
|
|
150
|
-
vibe gpt key|status # GPT API key setup
|
|
151
|
-
vibe gemini key|status # Gemini API key setup
|
|
152
|
-
vibe figma breakpoints # Responsive breakpoints
|
|
153
|
-
vibe skills add <owner/repo> # Install skills from skills.sh
|
|
154
|
-
```
|
|
73
|
+
**Figma → Code** — Tree-based structural mapping targeting 90% design fidelity. Extracts 30+ CSS properties from Figma REST API, remaps across breakpoints, generates responsive code.
|
|
155
74
|
|
|
156
75
|
---
|
|
157
76
|
|
|
158
|
-
##
|
|
77
|
+
## Supported Tools
|
|
159
78
|
|
|
160
|
-
|
|
|
161
|
-
|
|
162
|
-
|
|
|
163
|
-
|
|
|
79
|
+
| CLI | Status |
|
|
80
|
+
|-----|--------|
|
|
81
|
+
| [Claude Code](https://claude.ai/code) | Full support |
|
|
82
|
+
| [Codex](https://github.com/openai/codex) | Plugin |
|
|
83
|
+
| [Cursor](https://cursor.sh) | Agents + Rules |
|
|
84
|
+
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | Agents + Skills |
|
|
164
85
|
|
|
165
86
|
---
|
|
166
87
|
|
|
167
|
-
##
|
|
88
|
+
## Documentation
|
|
89
|
+
|
|
90
|
+
Full guides, skill reference, and configuration details are in the [Wiki](https://github.com/su-record/vibe/wiki).
|
|
168
91
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
| `ultrawork` | Full automation — parallel agents + auto-continue + quality loop |
|
|
172
|
-
| `ralph` | Iterate until 100% complete (no scope reduction) |
|
|
173
|
-
| `quick` | Fast mode, minimal verification |
|
|
92
|
+
- [README (Korean)](README.ko.md)
|
|
93
|
+
- [Release Notes](RELEASE_NOTES.md)
|
|
174
94
|
|
|
175
95
|
---
|
|
176
96
|
|
|
@@ -178,12 +98,7 @@ vibe skills add <owner/repo> # Install skills from skills.sh
|
|
|
178
98
|
|
|
179
99
|
- Node.js >= 18.0.0
|
|
180
100
|
- Claude Code (required)
|
|
181
|
-
- GPT, Gemini (optional
|
|
182
|
-
|
|
183
|
-
## Documentation
|
|
184
|
-
|
|
185
|
-
- [README (Korean)](README.ko.md)
|
|
186
|
-
- [Release Notes](RELEASE_NOTES.md)
|
|
101
|
+
- GPT, Gemini (optional)
|
|
187
102
|
|
|
188
103
|
## License
|
|
189
104
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/cli/postinstall/main.ts"],"names":[],"mappings":";AACA;;GAEG;AAgCH;;GAEG;AACH,wBAAgB,IAAI,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/cli/postinstall/main.ts"],"names":[],"mappings":";AACA;;GAEG;AAgCH;;GAEG;AACH,wBAAgB,IAAI,IAAI,IAAI,CAkK3B"}
|
|
@@ -93,42 +93,21 @@ export function main() {
|
|
|
93
93
|
}
|
|
94
94
|
// 인라인 기본 스킬 추가 (번들에 없는 추가 스킬)
|
|
95
95
|
seedInlineSkills(coreSkillsDir);
|
|
96
|
-
//
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
96
|
+
// 독립 디렉토리 복사 — 병렬 실행 (서로 다른 대상 경로, 의존성 없음)
|
|
97
|
+
const parallelCopies = [
|
|
98
|
+
{ source: path.join(packageRoot, 'vibe', 'ui-ux-data'), target: path.join(globalCoreAssetsDir, 'ui-ux-data'), label: 'ui-ux-data' },
|
|
99
|
+
{ source: path.join(packageRoot, 'vibe', 'rules'), target: path.join(globalCoreAssetsDir, 'rules'), label: 'rules' },
|
|
100
|
+
{ source: path.join(packageRoot, 'vibe', 'templates'), target: path.join(globalCoreAssetsDir, 'templates'), label: 'templates' },
|
|
101
|
+
{ source: path.join(packageRoot, 'languages'), target: path.join(globalCoreAssetsDir, 'languages'), label: 'languages' },
|
|
102
|
+
];
|
|
103
|
+
for (const { source, target } of parallelCopies) {
|
|
104
|
+
if (fs.existsSync(source)) {
|
|
105
|
+
if (fs.existsSync(target))
|
|
106
|
+
removeDirRecursive(target);
|
|
107
|
+
copyDirRecursive(source, target);
|
|
102
108
|
}
|
|
103
|
-
copyDirRecursive(uiUxDataSource, globalUiUxDataDir);
|
|
104
109
|
}
|
|
105
|
-
// vibe/rules 복사
|
|
106
|
-
const rulesSource = path.join(packageRoot, 'vibe', 'rules');
|
|
107
|
-
const globalRulesDir = path.join(globalCoreAssetsDir, 'rules');
|
|
108
|
-
if (fs.existsSync(rulesSource)) {
|
|
109
|
-
if (fs.existsSync(globalRulesDir)) {
|
|
110
|
-
removeDirRecursive(globalRulesDir);
|
|
111
|
-
}
|
|
112
|
-
copyDirRecursive(rulesSource, globalRulesDir);
|
|
113
|
-
}
|
|
114
|
-
// vibe/templates 복사
|
|
115
|
-
const templatesSource = path.join(packageRoot, 'vibe', 'templates');
|
|
116
|
-
const globalTemplatesDir = path.join(globalCoreAssetsDir, 'templates');
|
|
117
|
-
if (fs.existsSync(templatesSource)) {
|
|
118
|
-
if (fs.existsSync(globalTemplatesDir)) {
|
|
119
|
-
removeDirRecursive(globalTemplatesDir);
|
|
120
|
-
}
|
|
121
|
-
copyDirRecursive(templatesSource, globalTemplatesDir);
|
|
122
|
-
}
|
|
123
|
-
// languages 복사
|
|
124
|
-
const languagesSource = path.join(packageRoot, 'languages');
|
|
125
110
|
const globalLanguagesDir = path.join(globalCoreAssetsDir, 'languages');
|
|
126
|
-
if (fs.existsSync(languagesSource)) {
|
|
127
|
-
if (fs.existsSync(globalLanguagesDir)) {
|
|
128
|
-
removeDirRecursive(globalLanguagesDir);
|
|
129
|
-
}
|
|
130
|
-
copyDirRecursive(languagesSource, globalLanguagesDir);
|
|
131
|
-
}
|
|
132
111
|
// 5-1. 레거시 설정 파일 → ~/.vibe/config.json 마이그레이션
|
|
133
112
|
try {
|
|
134
113
|
migrateLegacyFiles();
|
|
@@ -144,44 +123,39 @@ export function main() {
|
|
|
144
123
|
// 모든 설정은 ~/.vibe/config.json에서 관리 (vibe gpt key, vibe gemini key)
|
|
145
124
|
// 6-4. 전역 env 설정 (Agent Teams 등 모든 프로젝트에 필요한 환경변수)
|
|
146
125
|
ensureGlobalEnvSettings();
|
|
147
|
-
// 7.
|
|
126
|
+
// 7-9. IDE 지원: Cursor agents + rules + skills (독립 작업)
|
|
148
127
|
const cursorAgentsDir = path.join(os.homedir(), '.cursor', 'agents');
|
|
149
|
-
installCursorAgents(agentsSource, cursorAgentsDir);
|
|
150
|
-
// 8. Cursor 프로젝트 룰 템플릿 생성 - ~/.cursor/rules-template/
|
|
151
|
-
// 프로젝트별로 .cursor/rules/에 복사해서 사용
|
|
152
|
-
// postinstall에서는 스택 감지 없이 공통 룰만 생성
|
|
153
128
|
const cursorRulesTemplateDir = path.join(os.homedir(), '.cursor', 'rules-template');
|
|
154
|
-
generateCursorRules(cursorRulesTemplateDir, [], globalLanguagesDir);
|
|
155
|
-
// 9. Cursor Skills 생성 - ~/.cursor/skills/
|
|
156
|
-
// VIBE 커맨드를 Cursor 스킬로 변환
|
|
157
129
|
const cursorSkillsDir = path.join(os.homedir(), '.cursor', 'skills');
|
|
130
|
+
installCursorAgents(agentsSource, cursorAgentsDir);
|
|
131
|
+
generateCursorRules(cursorRulesTemplateDir, [], globalLanguagesDir);
|
|
158
132
|
generateCursorSkills(cursorSkillsDir);
|
|
159
|
-
// 10.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
133
|
+
// 10-11. 외부 CLI 지원 (Codex + Gemini — 비필수, 실패 허용)
|
|
134
|
+
const cliPlugins = [];
|
|
135
|
+
cliPlugins.push({ name: 'codex', fn: () => {
|
|
136
|
+
const codexStatus = detectCodexCli();
|
|
137
|
+
if (codexStatus.installed) {
|
|
138
|
+
installCodexPlugin(agentsSource, skillsSource, codexStatus.configDir, packageRoot);
|
|
139
|
+
console.log(`✅ codex plugin installed: ${codexStatus.pluginDir}`);
|
|
140
|
+
}
|
|
141
|
+
} });
|
|
142
|
+
cliPlugins.push({ name: 'gemini', fn: () => {
|
|
143
|
+
const geminiStatus = detectGeminiCli();
|
|
144
|
+
if (geminiStatus.installed) {
|
|
145
|
+
const geminiAgentsDir = path.join(geminiStatus.configDir, 'agents');
|
|
146
|
+
installGeminiAgents(agentsSource, geminiAgentsDir);
|
|
147
|
+
const geminiSkillsDir = path.join(geminiStatus.configDir, 'skills');
|
|
148
|
+
removeLegacySkills(geminiSkillsDir, LEGACY_SKILL_DIRS);
|
|
149
|
+
copySkillsFiltered(skillsSource, geminiSkillsDir, GLOBAL_SKILLS);
|
|
150
|
+
generateGeminiMd(geminiStatus.configDir, packageRoot);
|
|
151
|
+
console.log(`✅ gemini agents/skills installed: ${geminiStatus.configDir}`);
|
|
152
|
+
}
|
|
153
|
+
} });
|
|
154
|
+
for (const plugin of cliPlugins) {
|
|
155
|
+
try {
|
|
156
|
+
plugin.fn();
|
|
165
157
|
}
|
|
166
|
-
|
|
167
|
-
catch {
|
|
168
|
-
// Non-critical — don't fail postinstall
|
|
169
|
-
}
|
|
170
|
-
// 11. Gemini CLI 지원
|
|
171
|
-
try {
|
|
172
|
-
const geminiStatus = detectGeminiCli();
|
|
173
|
-
if (geminiStatus.installed) {
|
|
174
|
-
const geminiAgentsDir = path.join(geminiStatus.configDir, 'agents');
|
|
175
|
-
installGeminiAgents(agentsSource, geminiAgentsDir);
|
|
176
|
-
const geminiSkillsDir = path.join(geminiStatus.configDir, 'skills');
|
|
177
|
-
removeLegacySkills(geminiSkillsDir, LEGACY_SKILL_DIRS);
|
|
178
|
-
copySkillsFiltered(skillsSource, geminiSkillsDir, GLOBAL_SKILLS);
|
|
179
|
-
generateGeminiMd(geminiStatus.configDir, packageRoot);
|
|
180
|
-
console.log(`✅ gemini agents/skills installed: ${geminiStatus.configDir}`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
catch {
|
|
184
|
-
// Non-critical — don't fail postinstall
|
|
158
|
+
catch { /* Non-critical */ }
|
|
185
159
|
}
|
|
186
160
|
// 12. Claude Code CLI 존재 확인 (인증은 vibe init에서)
|
|
187
161
|
const claudeStatus = getClaudeCodeStatus(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/cli/postinstall/main.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/cli/postinstall/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostAccumulator — JSONL 비용 로그 조회 및 프로젝트별 예산 관리
|
|
3
|
+
* hooks/scripts/utils.js의 logLlmCost()가 기록한 ~/.vibe/llm-costs.jsonl을 읽는다.
|
|
4
|
+
*/
|
|
5
|
+
export interface CostEntry {
|
|
6
|
+
ts: string;
|
|
7
|
+
provider: string;
|
|
8
|
+
model: string;
|
|
9
|
+
inputTokens: number;
|
|
10
|
+
outputTokens: number;
|
|
11
|
+
cost: number;
|
|
12
|
+
durationMs: number;
|
|
13
|
+
cached: boolean;
|
|
14
|
+
project: string;
|
|
15
|
+
}
|
|
16
|
+
export interface CostSummary {
|
|
17
|
+
totalCost: number;
|
|
18
|
+
totalEntries: number;
|
|
19
|
+
byModel: Record<string, number>;
|
|
20
|
+
byProvider: Record<string, number>;
|
|
21
|
+
period: {
|
|
22
|
+
from: string | null;
|
|
23
|
+
to: string | null;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface BudgetConfig {
|
|
27
|
+
monthlyLlmUsd: number;
|
|
28
|
+
alertThresholdPercent: number;
|
|
29
|
+
blockingThresholdPercent: number;
|
|
30
|
+
}
|
|
31
|
+
export interface BudgetCheck {
|
|
32
|
+
allowed: boolean;
|
|
33
|
+
currentSpend: number;
|
|
34
|
+
budget: number;
|
|
35
|
+
usagePercent: number;
|
|
36
|
+
level: 'ok' | 'alert' | 'blocking';
|
|
37
|
+
}
|
|
38
|
+
export declare class CostAccumulator {
|
|
39
|
+
/**
|
|
40
|
+
* 프로젝트별 비용 조회
|
|
41
|
+
*/
|
|
42
|
+
static queryProjectCosts(projectPath: string, filter?: {
|
|
43
|
+
since?: Date;
|
|
44
|
+
model?: string;
|
|
45
|
+
provider?: string;
|
|
46
|
+
}): CostSummary;
|
|
47
|
+
/**
|
|
48
|
+
* 전체 비용 프로젝트별 집계
|
|
49
|
+
*/
|
|
50
|
+
static queryAllCosts(since?: Date): Map<string, number>;
|
|
51
|
+
/**
|
|
52
|
+
* 이번 달 프로젝트 비용 vs 예산 확인
|
|
53
|
+
*/
|
|
54
|
+
static checkBudget(projectPath: string, budget?: Partial<BudgetConfig>): BudgetCheck;
|
|
55
|
+
private static readEntries;
|
|
56
|
+
private static summarize;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=CostAccumulator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CostAccumulator.d.ts","sourceRoot":"","sources":["../../../src/infra/lib/CostAccumulator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CACpD;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,IAAI,GAAG,OAAO,GAAG,UAAU,CAAC;CACpC;AAmBD,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,iBAAiB,CACtB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3D,WAAW;IAYd;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,IAAI,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAWvD;;OAEG;IACH,MAAM,CAAC,WAAW,CAChB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC7B,WAAW;IA8Bd,OAAO,CAAC,MAAM,CAAC,WAAW;IAqB1B,OAAO,CAAC,MAAM,CAAC,SAAS;CAuBzB"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostAccumulator — JSONL 비용 로그 조회 및 프로젝트별 예산 관리
|
|
3
|
+
* hooks/scripts/utils.js의 logLlmCost()가 기록한 ~/.vibe/llm-costs.jsonl을 읽는다.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Constants
|
|
10
|
+
// ============================================================================
|
|
11
|
+
const COST_LOG_PATH = path.join(os.homedir(), '.vibe', 'llm-costs.jsonl');
|
|
12
|
+
const COST_LOG_PREV = COST_LOG_PATH + '.prev';
|
|
13
|
+
const DEFAULT_BUDGET = {
|
|
14
|
+
monthlyLlmUsd: 0, // 0 = unlimited
|
|
15
|
+
alertThresholdPercent: 80,
|
|
16
|
+
blockingThresholdPercent: 95,
|
|
17
|
+
};
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// CostAccumulator
|
|
20
|
+
// ============================================================================
|
|
21
|
+
export class CostAccumulator {
|
|
22
|
+
/**
|
|
23
|
+
* 프로젝트별 비용 조회
|
|
24
|
+
*/
|
|
25
|
+
static queryProjectCosts(projectPath, filter) {
|
|
26
|
+
const entries = CostAccumulator.readEntries();
|
|
27
|
+
const filtered = entries.filter((e) => {
|
|
28
|
+
if (e.project !== projectPath)
|
|
29
|
+
return false;
|
|
30
|
+
if (filter?.since && new Date(e.ts) < filter.since)
|
|
31
|
+
return false;
|
|
32
|
+
if (filter?.model && e.model !== filter.model)
|
|
33
|
+
return false;
|
|
34
|
+
if (filter?.provider && e.provider !== filter.provider)
|
|
35
|
+
return false;
|
|
36
|
+
return true;
|
|
37
|
+
});
|
|
38
|
+
return CostAccumulator.summarize(filtered);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 전체 비용 프로젝트별 집계
|
|
42
|
+
*/
|
|
43
|
+
static queryAllCosts(since) {
|
|
44
|
+
const entries = CostAccumulator.readEntries();
|
|
45
|
+
const result = new Map();
|
|
46
|
+
for (const e of entries) {
|
|
47
|
+
if (since && new Date(e.ts) < since)
|
|
48
|
+
continue;
|
|
49
|
+
const current = result.get(e.project) || 0;
|
|
50
|
+
result.set(e.project, current + e.cost);
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 이번 달 프로젝트 비용 vs 예산 확인
|
|
56
|
+
*/
|
|
57
|
+
static checkBudget(projectPath, budget) {
|
|
58
|
+
const cfg = { ...DEFAULT_BUDGET, ...budget };
|
|
59
|
+
if (cfg.monthlyLlmUsd <= 0) {
|
|
60
|
+
return { allowed: true, currentSpend: 0, budget: 0, usagePercent: 0, level: 'ok' };
|
|
61
|
+
}
|
|
62
|
+
const monthStart = new Date();
|
|
63
|
+
monthStart.setDate(1);
|
|
64
|
+
monthStart.setHours(0, 0, 0, 0);
|
|
65
|
+
const summary = CostAccumulator.queryProjectCosts(projectPath, { since: monthStart });
|
|
66
|
+
const usagePercent = (summary.totalCost / cfg.monthlyLlmUsd) * 100;
|
|
67
|
+
let level = 'ok';
|
|
68
|
+
if (usagePercent >= cfg.blockingThresholdPercent)
|
|
69
|
+
level = 'blocking';
|
|
70
|
+
else if (usagePercent >= cfg.alertThresholdPercent)
|
|
71
|
+
level = 'alert';
|
|
72
|
+
return {
|
|
73
|
+
allowed: level !== 'blocking',
|
|
74
|
+
currentSpend: Math.round(summary.totalCost * 10000) / 10000,
|
|
75
|
+
budget: cfg.monthlyLlmUsd,
|
|
76
|
+
usagePercent: Math.round(usagePercent * 100) / 100,
|
|
77
|
+
level,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// ==========================================================================
|
|
81
|
+
// Private helpers
|
|
82
|
+
// ==========================================================================
|
|
83
|
+
static readEntries() {
|
|
84
|
+
const entries = [];
|
|
85
|
+
for (const filepath of [COST_LOG_PREV, COST_LOG_PATH]) {
|
|
86
|
+
if (!fs.existsSync(filepath))
|
|
87
|
+
continue;
|
|
88
|
+
try {
|
|
89
|
+
const content = fs.readFileSync(filepath, 'utf-8');
|
|
90
|
+
for (const line of content.split('\n')) {
|
|
91
|
+
if (!line.trim())
|
|
92
|
+
continue;
|
|
93
|
+
try {
|
|
94
|
+
entries.push(JSON.parse(line));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// skip malformed lines
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// skip unreadable files
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return entries;
|
|
106
|
+
}
|
|
107
|
+
static summarize(entries) {
|
|
108
|
+
const byModel = {};
|
|
109
|
+
const byProvider = {};
|
|
110
|
+
let totalCost = 0;
|
|
111
|
+
let from = null;
|
|
112
|
+
let to = null;
|
|
113
|
+
for (const e of entries) {
|
|
114
|
+
totalCost += e.cost;
|
|
115
|
+
byModel[e.model] = (byModel[e.model] || 0) + e.cost;
|
|
116
|
+
byProvider[e.provider] = (byProvider[e.provider] || 0) + e.cost;
|
|
117
|
+
if (!from || e.ts < from)
|
|
118
|
+
from = e.ts;
|
|
119
|
+
if (!to || e.ts > to)
|
|
120
|
+
to = e.ts;
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
totalCost: Math.round(totalCost * 10000) / 10000,
|
|
124
|
+
totalEntries: entries.length,
|
|
125
|
+
byModel,
|
|
126
|
+
byProvider,
|
|
127
|
+
period: { from, to },
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=CostAccumulator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CostAccumulator.js","sourceRoot":"","sources":["../../../src/infra/lib/CostAccumulator.ts"],"names":[],"mappings":"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"}
|