10 KiB
10 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 03-hook-server | 01 | execute | 1 |
|
true |
|
|
Purpose: Poser toute la logique de traitement des events Claude Code hooks. Chaque type d'event (Notification, Stop, PostToolUse, PreToolUse) est mappe vers le bon State et WaitType. Output: hook.go avec la logique, hook_test.go avec les tests, protocol.go enrichi avec WaitType.
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/03-hook-server/03-RESEARCH.mdFrom protocol.go:
type SessionInfo struct {
PID int `json:"pid"`
SessionID string `json:"session_id"`
Cwd string `json:"cwd"`
GitBranch string `json:"git_branch"`
State string `json:"state"`
Preview string `json:"preview"`
Workspace string `json:"workspace"`
Label string `json:"label,omitempty"`
WaitingSince *time.Time `json:"waiting_since,omitempty"`
}
From daemon.go:
type TrackedSession struct {
Info SessionInfo
PrevState string
}
type SessionRegistry struct {
mu sync.RWMutex
sessions map[string]*TrackedSession
}
func (r *SessionRegistry) Update(info SessionInfo)
func (r *SessionRegistry) List() []SessionInfo
func (r *SessionRegistry) RemoveStale(activeIDs map[string]bool)
From daemon_test.go:
func newTestDaemon(t *testing.T) *Daemon
NE PAS ajouter le handler HTTP dans cette tache (c'est la tache 2).
NE PAS modifier daemon.go (pas de startHookServer, pas de hookPort).
nix-shell --run "go test -v -run 'TestProcessHook|TestUpdateFromHook|TestSessionInfoWaitType' ./..."
- grep -q 'WaitType.*string.*json:"wait_type' protocol.go
- grep -q 'type HookEvent struct' hook.go
- grep -q 'func.*Daemon.*processHookEvent' hook.go
- grep -q 'func.*SessionRegistry.*UpdateFromHook' hook.go
- grep -q 'TestProcessHookNotificationPermission' hook_test.go
- grep -q 'TestProcessHookStop' hook_test.go
- grep -q 'TestUpdateFromHookCreatesNewEntry' hook_test.go
- grep -q 'TestSessionInfoWaitTypeJSON' protocol_test.go
Les 12 tests passent. HookEvent parse le JSON Claude Code. processHookEvent mappe les 4 types d'events vers le bon State/WaitType. UpdateFromHook gere les nouvelles sessions et les transitions WaitingSince. SessionInfo.WaitType est serialise en JSON.
Task 2: HTTP handler POST /hook avec validation et protection
hook.go, hook_test.go
- hook.go (HookEvent et processHookEvent crees par Task 1)
- daemon_test.go (newTestDaemon, patterns httptest)
- .planning/phases/03-hook-server/03-RESEARCH.md (handler pattern, MaxBytesReader)
- TestHandleHookPostOK: POST /hook avec payload Notification valide retourne 200 et met a jour le registre
- TestHandleHookMethodNotAllowed: GET /hook retourne 405
- TestHandleHookBadJSON: POST /hook avec body invalide retourne 400
- TestHandleHookBodyTooLarge: POST /hook avec body > 64KB retourne 400
1. Ajouter dans hook.go :
- `func (d *Daemon) handleHook(w http.ResponseWriter, r *http.Request)` : verifie Method==POST (sinon 405), applique http.MaxBytesReader(w, r.Body, 64*1024), decode JSON dans HookEvent (sinon 400), appelle processHookEvent, retourne 200 OK.
2. Ajouter les 4 tests dans hook_test.go. Utiliser httptest.NewRequest + httptest.NewRecorder pour tester le handler directement (pas besoin d'ouvrir un port).
3. Pour TestHandleHookPostOK, verifier que le registre contient la session avec le bon WaitType apres l'appel.
4. Pour TestHandleHookBodyTooLarge, generer un body de 65KB.
NE PAS demarrer de serveur HTTP dans cette tache. Le handler est teste unitairement via httptest.
nix-shell --run "go test -v -run 'TestHandleHook' ./..."
- grep -q 'func.*Daemon.*handleHook' hook.go
- grep -q 'MaxBytesReader' hook.go
- grep -q 'StatusMethodNotAllowed' hook.go
- grep -q 'TestHandleHookPostOK' hook_test.go
- grep -q 'TestHandleHookMethodNotAllowed' hook_test.go
- grep -q 'TestHandleHookBadJSON' hook_test.go
- grep -q 'TestHandleHookBodyTooLarge' hook_test.go
Le handler HTTP /hook accepte les POST valides (200), rejette les non-POST (405), rejette le JSON invalide (400), limite la taille du body a 64KB. 4 tests passent.
nix-shell --run "go test -v -run 'TestProcessHook|TestUpdateFromHook|TestHandleHook|TestSessionInfoWaitType' ./..."
nix-shell --run "go vet ./..."
<success_criteria>
- 16 tests passent (12 task 1 + 4 task 2)
- HookEvent struct couvre tous les champs du payload Claude Code
- processHookEvent mappe les 4 types d'events correctement
- UpdateFromHook gere les sessions inconnues et les transitions WaitingSince
- handleHook valide method, body size, et JSON
- SessionInfo.WaitType visible dans le JSON
- Aucune regression sur les tests existants </success_criteria>