Skip to content
This repository was archived by the owner on Apr 2, 2026. It is now read-only.

Commit de189b2

Browse files
greynewellclaude
andcommitted
feat: auto-install Claude Code hooks after auth login
After successful authentication, automatically offer to install the Claude Code hooks so the entire setup is a single command. Previously users had to run 'uncompact auth login' then 'uncompact install' separately; now auth login handles both steps. If hooks are already installed, confirms silently. If not, shows the diff and prompts for confirmation before writing — matching the behaviour of 'uncompact install' but without requiring a separate command. Co-Authored-By: Grey Newell <greyshipscode@gmail.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent de9e8a9 commit de189b2

1 file changed

Lines changed: 57 additions & 2 deletions

File tree

cmd/auth.go

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"bufio"
45
"context"
56
"crypto/rand"
67
"encoding/hex"
@@ -16,6 +17,7 @@ import (
1617
"github.com/supermodeltools/uncompact/internal/api"
1718
"github.com/supermodeltools/uncompact/internal/cache"
1819
"github.com/supermodeltools/uncompact/internal/config"
20+
"github.com/supermodeltools/uncompact/internal/hooks"
1921
"golang.org/x/term"
2022
)
2123

@@ -277,7 +279,8 @@ func authLoginManual(cfg *config.Config) error {
277279
return saveAndCacheKey(cfg, key)
278280
}
279281

280-
// saveAndCacheKey encrypts and saves the key, then updates the auth cache.
282+
// saveAndCacheKey encrypts and saves the key, updates the auth cache, then
283+
// automatically installs the Claude Code hooks so auth login is a one-step setup.
281284
func saveAndCacheKey(cfg *config.Config, key string) error {
282285
if os.Getenv(config.EnvAPIKey) != "" {
283286
fmt.Println()
@@ -304,11 +307,63 @@ func saveAndCacheKey(cfg *config.Config, key string) error {
304307
} else {
305308
fmt.Println("\nAPI key saved.")
306309
}
310+
311+
// Auto-install hooks so auth login is a complete one-step setup.
307312
fmt.Println()
308-
fmt.Println("Next: run 'uncompact install' to add hooks to Claude Code.")
313+
autoInstallHooks()
309314
return nil
310315
}
311316

317+
// autoInstallHooks installs the Claude Code hooks as part of the auth login
318+
// flow. If already installed it confirms silently. If not, it shows the diff,
319+
// prompts for confirmation, and applies — matching the behaviour of
320+
// `uncompact install` but without requiring a separate command.
321+
func autoInstallHooks() {
322+
settingsPath, err := hooks.FindSettingsFile()
323+
if err != nil {
324+
fmt.Println("Could not find Claude Code settings.json — run 'uncompact install' manually.")
325+
return
326+
}
327+
328+
result, err := hooks.Install(settingsPath, true) // dry-run to get diff
329+
if err != nil {
330+
fmt.Printf("Could not check hook status: %v\n", err)
331+
fmt.Println("Run 'uncompact install' manually.")
332+
return
333+
}
334+
335+
if result.AlreadySet {
336+
fmt.Println("✓ Claude Code hooks already installed.")
337+
return
338+
}
339+
340+
fmt.Println("The following changes will be made to Claude Code settings.json:")
341+
fmt.Println()
342+
fmt.Println(result.Diff)
343+
fmt.Print("Install hooks now? [y/N]: ")
344+
345+
scanner := bufio.NewScanner(os.Stdin)
346+
if !scanner.Scan() {
347+
fmt.Println("Skipped. Run 'uncompact install' to add hooks later.")
348+
return
349+
}
350+
answer := strings.TrimSpace(strings.ToLower(scanner.Text()))
351+
if answer != "y" && answer != "yes" {
352+
fmt.Println("Skipped. Run 'uncompact install' to add hooks later.")
353+
return
354+
}
355+
356+
if _, err := hooks.Install(settingsPath, false); err != nil {
357+
fmt.Printf("Hook install failed: %v\n", err)
358+
fmt.Println("Run 'uncompact install' manually.")
359+
return
360+
}
361+
362+
fmt.Println()
363+
fmt.Println("✓ Claude Code hooks installed.")
364+
fmt.Println(" Uncompact will now reinject context automatically after compaction.")
365+
}
366+
312367
func authStatusHandler(cmd *cobra.Command, args []string) error {
313368
cfg, err := config.Load(apiKey)
314369
if err != nil {

0 commit comments

Comments
 (0)