hookSessionStartMultiRepo handles meta-repos containing multiple child repos. Output is capped to MaxContextOutputBytes to prevent context blowup.
(root string, childRepos []string)
| 1481 | // hookSessionStartMultiRepo handles meta-repos containing multiple child repos. |
| 1482 | // Output is capped to MaxContextOutputBytes to prevent context blowup. |
| 1483 | func hookSessionStartMultiRepo(root string, childRepos []string) error { |
| 1484 | fmt.Println("📍 Multi-Repo Project Context:") |
| 1485 | fmt.Printf(" %d repositories in %s\n", len(childRepos), filepath.Base(root)) |
| 1486 | fmt.Println() |
| 1487 | |
| 1488 | exe, err := hookExecutablePath() |
| 1489 | if err != nil { |
| 1490 | return err |
| 1491 | } |
| 1492 | |
| 1493 | // Budget: divide total budget across repos, with a per-repo cap |
| 1494 | totalBudget := limits.MaxContextOutputBytes |
| 1495 | perRepoBudget := totalBudget / len(childRepos) |
| 1496 | if perRepoBudget < 2000 { |
| 1497 | perRepoBudget = 2000 // minimum useful output per repo |
| 1498 | } |
| 1499 | totalUsed := 0 |
| 1500 | |
| 1501 | for _, repo := range childRepos { |
| 1502 | if totalUsed >= totalBudget { |
| 1503 | fmt.Printf(" ... and %d more repos (output budget reached)\n", len(childRepos)-indexOf(childRepos, repo)) |
| 1504 | break |
| 1505 | } |
| 1506 | |
| 1507 | repoPath := filepath.Join(root, repo) |
| 1508 | projCfg := config.Load(repoPath) |
| 1509 | showConfigSetupHint(repoPath) |
| 1510 | |
| 1511 | depth := 2 |
| 1512 | if projCfg.Depth > 0 { |
| 1513 | depth = projCfg.Depth |
| 1514 | } |
| 1515 | |
| 1516 | args := []string{"--depth", strconv.Itoa(depth)} |
| 1517 | if len(projCfg.Only) > 0 { |
| 1518 | args = append(args, "--only", strings.Join(projCfg.Only, ",")) |
| 1519 | } |
| 1520 | if len(projCfg.Exclude) > 0 { |
| 1521 | args = append(args, "--exclude", strings.Join(projCfg.Exclude, ",")) |
| 1522 | } |
| 1523 | args = append(args, repoPath) |
| 1524 | cmd := hookExecCommand(exe, args...) |
| 1525 | |
| 1526 | // Capture and budget output instead of piping directly to stdout |
| 1527 | buf := newCappedStringWriter(perRepoBudget + diffCaptureSlackBytes) |
| 1528 | cmd.Stdout = buf |
| 1529 | cmd.Stderr = os.Stderr |
| 1530 | cmd.Run() |
| 1531 | |
| 1532 | output := buf.String() |
| 1533 | if len(output) > perRepoBudget || buf.Truncated() { |
| 1534 | output = limits.TruncateAtLineBoundary(output, perRepoBudget, |
| 1535 | "\n ... (repo output truncated)\n") |
| 1536 | } |
| 1537 | fmt.Print(output) |
| 1538 | fmt.Println() |
| 1539 | totalUsed += len(output) |
| 1540 | } |