buildGrid method

List<List<GridSquare>> buildGrid({
  1. required List<ContextCategory> categories,
  2. required int contextWindow,
  3. int? terminalWidth,
})

Build the grid visualization from categories.

Implementation

List<List<GridSquare>> buildGrid({
  required List<ContextCategory> categories,
  required int contextWindow,
  int? terminalWidth,
}) {
  final isNarrowScreen = terminalWidth != null && terminalWidth < 80;
  final gridWidth = contextWindow >= 1000000
      ? (isNarrowScreen ? 5 : 20)
      : (isNarrowScreen ? 5 : 10);
  final gridHeight = contextWindow >= 1000000
      ? 10
      : (isNarrowScreen ? 5 : 10);
  final totalSquares = gridWidth * gridHeight;

  // Filter out deferred categories
  final nonDeferred = categories.where((c) => !c.isDeferred).toList();

  // Calculate squares per category
  final categorySquares = nonDeferred.map((cat) {
    final squares = cat.name == 'Free space'
        ? ((cat.tokens / contextWindow) * totalSquares).round()
        : max(1, ((cat.tokens / contextWindow) * totalSquares).round());
    final percentage = ((cat.tokens / contextWindow) * 100).round();
    return (category: cat, squares: squares, percentage: percentage);
  }).toList();

  // Build grid squares
  final gridSquares = <GridSquare>[];

  // Separate reserved category
  final reservedCat = categorySquares
      .where(
        (c) =>
            c.category.name == _reservedCategoryName ||
            c.category.name == _manualCompactBufferName,
      )
      .firstOrNull;
  final nonReservedCats = categorySquares
      .where(
        (c) =>
            c.category.name != _reservedCategoryName &&
            c.category.name != _manualCompactBufferName &&
            c.category.name != 'Free space',
      )
      .toList();

  // Add non-reserved squares
  for (final cat in nonReservedCats) {
    final exactSquares = (cat.category.tokens / contextWindow) * totalSquares;
    final wholeSquares = exactSquares.floor();
    final fractionalPart = exactSquares - wholeSquares;

    for (
      int i = 0;
      i < cat.squares && gridSquares.length < totalSquares;
      i++
    ) {
      double squareFullness = 1.0;
      if (i == wholeSquares && fractionalPart > 0) {
        squareFullness = fractionalPart;
      }
      gridSquares.add(
        GridSquare(
          color: cat.category.color,
          isFilled: true,
          categoryName: cat.category.name,
          tokens: cat.category.tokens,
          percentage: cat.percentage,
          squareFullness: squareFullness,
        ),
      );
    }
  }

  // Fill with free space
  final reservedSquareCount = reservedCat?.squares ?? 0;
  final freeSpaceTarget = totalSquares - reservedSquareCount;
  final freeSpaceCat = categories
      .where((c) => c.name == 'Free space')
      .firstOrNull;

  while (gridSquares.length < freeSpaceTarget) {
    gridSquares.add(
      GridSquare(
        color: 'promptBorder',
        isFilled: true,
        categoryName: 'Free space',
        tokens: freeSpaceCat?.tokens ?? 0,
        percentage: freeSpaceCat != null
            ? ((freeSpaceCat.tokens / contextWindow) * 100).round()
            : 0,
        squareFullness: 1.0,
      ),
    );
  }

  // Add reserved squares at the end
  if (reservedCat != null) {
    for (
      int i = 0;
      i < reservedCat.squares && gridSquares.length < totalSquares;
      i++
    ) {
      gridSquares.add(
        GridSquare(
          color: reservedCat.category.color,
          isFilled: true,
          categoryName: reservedCat.category.name,
          tokens: reservedCat.category.tokens,
          percentage: reservedCat.percentage,
          squareFullness: 1.0,
        ),
      );
    }
  }

  // Convert to rows
  final gridRows = <List<GridSquare>>[];
  for (int i = 0; i < gridHeight; i++) {
    final start = i * gridWidth;
    final end = min(start + gridWidth, gridSquares.length);
    if (start < gridSquares.length) {
      gridRows.add(gridSquares.sublist(start, end));
    }
  }

  return gridRows;
}