Compare commits

..

4 Commits

Author SHA1 Message Date
minsung
15234ac04d docs: add CLAUDE.md and drop PROJECT_ANALYSIS.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 09:18:07 +09:00
minsung
cb5efd591f chore: update project docs and add local config
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 09:08:35 +09:00
minsung
68d4012f11 docs: add project analysis and hooks documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 11:25:46 +09:00
minsung
e09c019568 test: empty test commit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 08:54:07 +09:00
6 changed files with 218 additions and 1 deletions

View File

@@ -0,0 +1,9 @@
{
"enabled": true,
"app_key": "A-SH-7756143445",
"aptabase_host": "https://aptabase.hmac.kr",
"user_name": "김민성",
"git_repositories": [
"D:/MYCLAUDE_PROJECT/workhistory"
]
}

38
.claude/settings.json Normal file
View File

@@ -0,0 +1,38 @@
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "t=$(mktemp);cat>\"$t\";e=./.claude/hooks/token-usage/claude-hook.exe;[ -x \"$e\" ] && \"$e\" session-context \"$t\";rm -f \"$t\"",
"timeout": 5
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "t=$(mktemp);cat>\"$t\";e=./.claude/hooks/token-usage/claude-hook.exe;[ -x \"$e\" ] && \"$e\" stop-record \"$t\";rm -f \"$t\"",
"timeout": 5
}
]
}
],
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "t=$(mktemp);cat>\"$t\";e=./.claude/hooks/token-usage/claude-hook.exe;[ -x \"$e\" ] && \"$e\" aptabase-commit \"$t\";rm -f \"$t\"",
"timeout": 15
}
],
"matcher": "Bash"
}
]
}
}

2
.usage/token/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
job-commit-pool.json
job-send-pool.json

19
CLAUDE.md Normal file
View File

@@ -0,0 +1,19 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Repository purpose
Personal work-log / scratch repo. Primary function is serving as a testbed for `.claude/` hooks (Aptabase token-usage tracking) rather than containing application code. There is no build, lint, or test suite.
## Hook architecture
All automation runs through a single Go binary at `.claude/hooks/token-usage/claude-hook.exe`, dispatched by subcommand from `.claude/settings.json`:
- `UserPromptSubmit``claude-hook.exe session-context` — injects job-history context into the prompt (visible as the "Job History Context" system reminder).
- `Stop``claude-hook.exe stop-record` — records session end.
- `PostToolUse` (matcher `Bash`) → `claude-hook.exe aptabase-commit` — detects git commits and flushes token-usage events to Aptabase.
Each hook reads the Claude Code JSON event from stdin via a tempfile. Config/state lives in `.claude/hooks/token-usage/aptabase.json`. The `.exe` binary is checked in and is the authoritative source — there is no Go source in this repo.
When modifying hook behavior, edit `.claude/settings.json` to adjust dispatch, but the actual logic changes must happen in whatever external project builds `claude-hook.exe`.

150
SKILLS.md Normal file
View File

@@ -0,0 +1,150 @@
# Skills 문서
> 작성: 2026-04-08
> 대상: `workhistory` 저장소의 `.claude/skills/` 하위 프로젝트 스킬
---
## 1. Skills 란?
Claude Code 의 **Skill** 은 특정 상황에서 Claude 가 자동으로(또는 사용자가 슬래시 커맨드로) 참조하는 **작업 지식 꾸러미**다. `SKILL.md` 파일의 YAML 프론트매터에 `name``description` 을 선언하면, Claude 는 사용자의 메시지가 그 description 과 매칭될 때 해당 스킬 문서를 컨텍스트로 끌어온다.
- **설치 위치**: `.claude/skills/<skill-name>/SKILL.md` (프로젝트 단위) 또는 `~/.claude/skills/` (전역)
- **트리거 방식**
- 자동: `description` 키워드와 사용자 메시지 매칭 시 Claude 가 자발적으로 로드
- 수동: `/skill-name` 슬래시 커맨드로 사용자가 직접 호출
- **형식**: 프론트매터 + 본문 마크다운
```markdown
---
name: my-skill
description: <어떤 상황에서 써야 하는지 한 줄 설명>
---
# 본문 (절차, 설정, 트러블슈팅 등)
```
---
## 2. 이 저장소에 등록된 스킬
| 스킬 | 경로 | 트리거 키워드 |
|---|---|---|
| `aptabase` | [.claude/skills/aptabase/SKILL.md](.claude/skills/aptabase/SKILL.md) | "aptabase 설정", "aptabase 테스트", "토큰 기록 확인", "누적 토큰" |
현재 프로젝트 스킬은 `aptabase` 하나뿐이다.
---
## 3. `aptabase` 스킬
### 3.1 목적
Aptabase 커밋 기준 토큰 기록 훅(`.claude/hooks/` 하위)의 **설치·검증·디버깅 절차**를 Claude 가 필요할 때 즉시 참조할 수 있도록 묶어둔 운영 가이드다.
사용자가 다음과 같은 요청을 하면 Claude 가 이 스킬을 자동 로드한다:
- "aptabase 설정 해줘"
- "aptabase 연결 테스트해봐"
- "토큰 기록이 제대로 되고 있는지 확인해줘"
- "누적 토큰이 얼마나 쌓였어?"
또는 수동으로 `/aptabase` 를 입력해도 동일하게 호출된다.
### 3.2 스킬 문서가 담고 있는 내용
[SKILL.md](.claude/skills/aptabase/SKILL.md) 는 다음 섹션으로 구성되어 있다:
1. **구조** — `.claude/hooks/`, `.claude/state/`, `.git/hooks/` 의 파일 구성
2. **동작 방식** — Stop / PostToolUse(Bash) / post-commit 세 진입점의 역할표와 순서도
3. **설정** — `aptabase.json` 의 각 키 의미 (`enabled`, `app_key`, `aptabase_host`, `user_name`)
4. **settings.json 등록 방법** — Stop 훅과 PostToolUse(Bash) 훅 예시
5. **git post-commit 훅 설치** — `install-git-hook.sh` 사용법, `--force` / `--uninstall` 옵션
6. **전송 payload** — `claude_commit` 이벤트의 `systemProps` / `props` 필드 스키마
7. **연결 테스트 3단계** — curl 직접 POST → Stop 훅 수동 실행 → 실제 E2E
8. **누적 상태 파일 포맷** — `aptabase-accum.json` 의 필드 설명
9. **트러블슈팅** — `accum` 이 0 으로 고정되는 경우, 커밋했는데 Aptabase 에 안 뜨는 경우, 첫 커밋이 무시되는 경우, 기준점 초기화 명령
### 3.3 실제 활용 시나리오
**시나리오 A — 신규 프로젝트에 훅 설치**
사용자: "이 프로젝트에 aptabase 훅 붙여줘"
→ Claude 가 `aptabase` 스킬을 로드 → SKILL.md 의 "1. 설정" ~ "2-1. git post-commit 훅 설치" 절차를 따라 파일 복사, `aptabase.json` 작성, `settings.json` 수정, `install-git-hook.sh` 실행까지 자동 수행.
**시나리오 B — 기록이 안 되는 것 같을 때**
사용자: "토큰 기록이 안 되는데 확인해줘"
→ Claude 가 스킬을 로드 → SKILL.md 의 "연결 테스트 3단계" 를 순서대로 실행(curl 도달성 → Stop 훅 수동 → state 파일 확인) → "트러블슈팅" 체크리스트와 대조해 원인 보고.
**시나리오 C — 누적 상태 확인**
사용자: "지금 누적 토큰 얼마야?"
→ Claude 가 스킬을 로드 → `.claude/state/aptabase-accum.json` 을 읽고 필드별(input / cache_creation / cache_read / output / consumed) 로 요약.
---
## 4. 새 스킬 추가 절차
이 저장소에 스킬을 하나 더 추가하려면:
1. **디렉터리 생성**
```bash
mkdir -p .claude/skills/<skill-name>
```
2. **SKILL.md 작성** — 프론트매터 필수
```markdown
---
name: <skill-name>
description: <한 줄로 "어떤 요청이 왔을 때 써야 하는지" 명확히 서술. 이 문장이 자동 트리거의 유일한 근거다.>
---
# 본문
...
```
> `description` 은 **Claude 가 스킬을 언제 부를지 판단하는 유일한 힌트**다. 모호한 문구("유용한 도구")는 트리거가 잘 안 되고, 키워드("X 설정", "Y 디버깅")를 명시할수록 잘 걸린다.
3. **본문 작성 가이드**
- 사용자가 요청할 만한 상황을 먼저 나열
- 그 상황에서 따라야 할 **구체적 절차** (명령, 경로, 체크리스트)
- 자주 발생하는 실패 케이스와 대응
- 관련 파일 경로를 상대 링크로 걸어 Claude 가 바로 읽을 수 있게
4. **커밋** — `.claude/skills/` 는 버전 관리 대상. 팀원/다음 세션이 동일하게 쓸 수 있도록 커밋한다.
5. **테스트** — 다음 세션에서 description 에 적힌 키워드로 질문해 자동 로드되는지 확인하거나, `/skill-name` 으로 직접 호출.
---
## 5. 사용자 invocation — 슬래시 커맨드
시스템 프롬프트에 "user-invocable skills" 로 등록된 스킬은 사용자가 `/name` 형태로 직접 호출할 수 있다. 이 저장소의 `aptabase` 스킬도 `/aptabase` 로 호출 가능하다.
Claude 입장에서는:
- 사용자가 `/aptabase` 를 입력 → Skill 툴을 통해 해당 스킬을 명시적으로 로드
- 자동 매칭보다 우선순위가 높음
- 이미 로드된 스킬을 또 호출하지 않음
---
## 6. 스킬 vs 훅 vs 메모리 — 구분
혼동하기 쉬운 세 가지 퍼시스턴스 메커니즘:
| 구분 | 저장 위치 | 트리거 | 목적 |
|---|---|---|---|
| **Skill** | `.claude/skills/<name>/SKILL.md` | description 매칭 또는 `/name` | **작업 절차/도메인 지식** — Claude 가 어떤 일을 *어떻게* 해야 하는지 |
| **Hook** | `.claude/settings.json` + 스크립트 | 특정 이벤트 (Stop, PostToolUse 등) | **자동 실행** — Claude 와 무관하게 이벤트 발생 시 시스템이 스크립트 구동 |
| **Memory** | `~/.claude/projects/.../memory/` | 관련성 / 명시 요청 | **지속 기억** — 사용자·프로젝트·피드백·외부 참조 정보 |
> `aptabase` 는 **스킬(운영 가이드)** + **훅(자동 기록 실행)** 의 조합으로 동작한다.
> 스킬은 "Claude 가 사람처럼 절차를 따라야 할 때" 읽는 문서이고, 훅은 "시스템이 이벤트마다 기계적으로 실행" 하는 스크립트다. 서로 교체 불가능하며 상호보완적이다.
---
## 7. 참고
- 현재 이 저장소의 스킬 구성은 [.claude/skills/aptabase/SKILL.md](.claude/skills/aptabase/SKILL.md) 한 개만 있다.
- 전역 스킬(다른 프로젝트에서도 쓰는 것) 은 `~/.claude/skills/` 또는 플러그인(`ouroboros:*` 등)으로 제공된다.
- Aptabase 훅 자체의 상세 구현/설정은 [.claude/hooks/usage.md](.claude/hooks/usage.md) 를 참조.

View File

@@ -1 +0,0 @@
aptabase hook dry-run fixture