MCPcopy Create free account
hub / github.com/JordanCoin/codemap / hookSessionStart

Function hookSessionStart

cmd/hooks.go:249–382  ·  view source on GitHub ↗

hookSessionStart shows project structure, starts daemon, and shows hub warnings

(root string)

Source from the content-addressed store, hash-verified

247
248// hookSessionStart shows project structure, starts daemon, and shows hub warnings
249func hookSessionStart(root string) error {
250 // Handle meta-repo: parent directory containing child git repos.
251 // Check this before the git guard so that non-repo parent directories
252 // still get multi-repo context.
253 childRepos := findChildRepos(root)
254 if len(childRepos) > 1 {
255 return hookSessionStartMultiRepo(root, childRepos)
256 }
257
258 // Guard: require git repo for single-repo analysis
259 gitDir := filepath.Join(root, ".git")
260 if _, err := os.Stat(gitDir); os.IsNotExist(err) {
261 fmt.Println("📍 Not a git repository - skipping project context")
262 fmt.Println(" (codemap hooks work best in git repos)")
263 return nil
264 }
265
266 // Check for previous session context before starting new daemon
267 lastSessionEvents := getLastSessionEvents(root)
268
269 // Restart stale daemons so long-lived background processes do not drift.
270 if shouldRestartDaemon(root, time.Now()) {
271 stopDaemon(root)
272 }
273
274 // Start the watch daemon in background (if not already running)
275 if !watch.IsRunning(root) {
276 startDaemon(root)
277 }
278
279 fmt.Println("📍 Project Context:")
280 fmt.Println()
281
282 // IMPORTANT: Hook output goes directly into Claude's "Messages" context, not system prompt.
283 // This means hook output competes with conversation history for the ~200k token limit.
284 // A 1.3MB output (like a full tree of a 10k file repo) = ~500k tokens = instant context overflow.
285 //
286 // We enforce two limits:
287 // 1. Adaptive depth: larger repos get shallower trees (depth 2-4 based on file count)
288 // 2. Hard cap: 60KB max output (~15k tokens, <10% of context window)
289 //
290 // Future: Consider structured output that Claude Code can format/truncate intelligently.
291 fileCount := 0
292 fileCountKnown := false
293 state := watch.ReadState(root)
294 if state == nil && watch.IsRunning(root) {
295 state = waitForDaemonState(root, 2*time.Second)
296 }
297 if state != nil {
298 fileCount = state.FileCount
299 fileCountKnown = true
300 }
301 projCfg := config.Load(root)
302 structureBudget := projCfg.SessionStartOutputBytes()
303 maxHubs := projCfg.HubDisplayLimit()
304
305 showConfigSetupHint(root)
306

Callers 2

RunHookFunction · 0.85

Calls 15

IsRunningFunction · 0.92
ReadStateFunction · 0.92
LoadFunction · 0.92
AdaptiveDepthFunction · 0.92
TruncateAtLineBoundaryFunction · 0.92
findChildReposFunction · 0.85
getLastSessionEventsFunction · 0.85
shouldRestartDaemonFunction · 0.85
stopDaemonFunction · 0.85
startDaemonFunction · 0.85
waitForDaemonStateFunction · 0.85