RunSetup configures codemap for the recommended hooks-first workflow. By default it creates: - /.codemap/config.json (if missing) - /.claude/settings.local.json codemap hook entries Use --global to target ~/.claude/settings.json for hooks.
(args []string, defaultRoot string)
| 56 | // |
| 57 | // Use --global to target ~/.claude/settings.json for hooks. |
| 58 | func RunSetup(args []string, defaultRoot string) { |
| 59 | fs := flag.NewFlagSet("setup", flag.ContinueOnError) |
| 60 | fs.SetOutput(io.Discard) |
| 61 | useGlobalHooks := fs.Bool("global", false, "Install hooks into ~/.claude/settings.json instead of project-local .claude/settings.local.json") |
| 62 | skipConfig := fs.Bool("no-config", false, "Skip creating .codemap/config.json") |
| 63 | skipHooks := fs.Bool("no-hooks", false, "Skip writing Claude hook settings") |
| 64 | if err := fs.Parse(args); err != nil { |
| 65 | if errors.Is(err, flag.ErrHelp) { |
| 66 | fmt.Println("Usage: codemap setup [--global] [--no-config] [--no-hooks] [path]") |
| 67 | return |
| 68 | } |
| 69 | fmt.Fprintf(os.Stderr, "Error: %v\n", err) |
| 70 | fmt.Fprintln(os.Stderr, "Usage: codemap setup [--global] [--no-config] [--no-hooks] [path]") |
| 71 | os.Exit(2) |
| 72 | } |
| 73 | if fs.NArg() > 1 { |
| 74 | fmt.Fprintln(os.Stderr, "Usage: codemap setup [--global] [--no-config] [--no-hooks] [path]") |
| 75 | os.Exit(1) |
| 76 | } |
| 77 | |
| 78 | root := defaultRoot |
| 79 | if fs.NArg() == 1 { |
| 80 | root = fs.Arg(0) |
| 81 | } |
| 82 | absRoot, err := filepath.Abs(root) |
| 83 | if err != nil { |
| 84 | fmt.Fprintf(os.Stderr, "Error resolving path: %v\n", err) |
| 85 | os.Exit(1) |
| 86 | } |
| 87 | |
| 88 | if !*skipConfig { |
| 89 | if _, err := os.Stat(filepath.Join(absRoot, ".git")); os.IsNotExist(err) { |
| 90 | fmt.Fprintf(os.Stderr, "Warning: %s is not a git repository root; continuing setup anyway.\n", absRoot) |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | fmt.Println("codemap setup") |
| 95 | fmt.Printf("Project: %s\n", absRoot) |
| 96 | fmt.Println() |
| 97 | |
| 98 | if *skipConfig { |
| 99 | fmt.Println("Config: skipped (--no-config)") |
| 100 | } else { |
| 101 | cfgResult, err := initProjectConfig(absRoot) |
| 102 | switch { |
| 103 | case errors.Is(err, errConfigExists): |
| 104 | fmt.Printf("Config: already exists (%s)\n", config.ConfigPath(absRoot)) |
| 105 | case err != nil: |
| 106 | fmt.Fprintf(os.Stderr, "Config: failed (%v)\n", err) |
| 107 | os.Exit(1) |
| 108 | default: |
| 109 | if len(cfgResult.TopExts) == 0 { |
| 110 | fmt.Printf("Config: created %s (no code extensions detected)\n", cfgResult.Path) |
| 111 | } else { |
| 112 | fmt.Printf("Config: created %s (only=%s)\n", cfgResult.Path, strings.Join(cfgResult.TopExts, ",")) |
| 113 | } |
| 114 | } |
| 115 | } |