This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Chunker is a high-performance text chunking service written in Go that splits text into manageable chunks using various strategies (NLP-based, token-based, word/sentence boundaries). It operates in two modes: HTTP API server and CLI tool with stdin processing.
# Build the binary
make build
# Build and run immediately
make run
# Run server mode (default port 8080)
./bin/chunker -server
# Run server on custom port
PORT=3000 ./bin/chunker -server
# CLI mode (pipe text through stdin)
echo "Your text here" | ./bin/chunker -size 1000 -strategy smart_boundary
cat document.txt | ./bin/chunker -format jsonl# Run all tests
make test
go test -v ./...
# Run tests for a specific package
go test -v ./internal/service/
# Run a specific test
go test -v ./internal/service/ -run TestChunkService_ProcessChunkRequest_Success
go test -v ./cmd/chunker/ -run TestCLIRunner
# Run tests with coverage
go test -cover ./...# Run linter (requires golangci-lint)
make lint
# Download/update dependencies
make deps
go mod tidy# Build for multiple platforms
make build-all # Creates darwin-amd64, linux-amd64, windows-amd64 binariesThe project follows clean architecture with clear separation of concerns:
Domain Layer (internal/domain/)
models.go: Core types (ChunkRequest, ChunkResponse, Chunk, Metadata, Strategy, TokenEncoding)interfaces.go: Business interfaces (Chunker, TokenChunker, ChunkerFactory, ChunkService)- No external dependencies - pure business logic and contracts
Service Layer (internal/service/)
chunk_service.go: Orchestrates chunking operations, coordinates between factory and chunkers- Implements ChunkService interface
- Handles validation and error responses
Chunking Integration (delegated to github.com/dotcommander/reliquary)
internal/service/chunk_service.go: orchestrates chunking; callschunking.NewChunker/chunking.NewTokenChunker, converts results, computes metadatainternal/domain/convert.go: maps between domain and library types (ToLibStrategy,FromLibChunk,FromLibChunks)- Strategy implementations live in reliquary, not in this repo
Handler Layer (internal/handler/)
chunk_handler.go: HTTP handlers for/chunkand/healthendpoints- Validates requests via
domain.ChunkRequest.Validate()(plain Go) - Returns JSON responses with proper error handling
Entry Point (cmd/chunker/)
main.go: Dual-mode detection (server vs CLI based on stdin pipe detection)cli.go: CLI runner implementation with io.Reader/io.Writer dependency injectioncli_test.go: CLI tests with table-driven approach
Strategy Pattern: Different chunking algorithms implement the Chunker interface Factory Pattern: ChunkerFactory creates appropriate chunker based on strategy enum Dependency Injection: All components receive dependencies through constructors (service receives factory, handler receives service, CLI runner receives service + io streams) Interface Segregation: TokenChunker extends Chunker for token-specific operations
github.com/go-chi/chi/v5: HTTP router with middleware supportgithub.com/dotcommander/reliquary: chunking strategies (smart_boundary, token_based, etc.)github.com/pkoukk/tiktoken-go: Token encoding (cl100k_base, o200k_base, p50k_base, r50k_base)
- Standard library
testingpackage - Table-driven tests for chunking strategies
The system supports seven strategies, each delegated to reliquary:
- smart_boundary (default): abbreviation-aware sentence detection (handles "Dr. Smith", "U.S.A.", etc.)
- sentence_boundary: Basic sentence splitting using punctuation (
.!?) - word_boundary: Splits at word boundaries, never breaks words
- paragraph_aware: Prioritizes keeping paragraphs together (splits on
\n\n) - hard_cut: Exact character count, may split mid-word
- token_based: Counts tokens using tiktoken encodings for LLM context limits
- markdown_aware: Preserves markdown structure (headings, code blocks, lists)
All strategies support overlap between chunks for context preservation:
- Overlap is measured in characters (or tokens for token_based strategy)
- Previous chunk's tail overlaps with next chunk's head
- Validation ensures overlap < chunk_size
For token_based strategy, supports multiple encodings:
cl100k_base: GPT-3.5/GPT-4 (default)o200k_base: GPT-4o, GPT-5 modelsp50k_base: Older models (GPT-3 Codex)r50k_base: Legacy models (GPT-2)
The binary automatically determines operation mode:
- Server mode: Explicitly requested with
-serverflag - CLI mode: Stdin is piped (detected via
os.Stdin.Stat()) - Shows help if neither condition is met
Strategies are implemented in reliquary. To surface one here:
- Add the
Strategyconst tointernal/domain/models.go - Update
IsValid()to include the new strategy - Map it in
internal/domain/convert.goif needed - Ensure reliquary's
NewChunkerhandles the strategy
Use table-driven tests with test cases covering:
- Basic chunking (text fits in one chunk)
- Multiple chunks with overlap
- Edge cases (empty text, single word, very long words)
- Boundary conditions (text exactly at chunk size)
Example structure:
tests := []struct {
name string
input string
chunkSize int
overlap int
want int // expected number of chunks
}{
{"empty text", "", 100, 0, 0},
{"single chunk", "short", 100, 0, 1},
// ...
}- Request validation uses
domain.ChunkRequest.Validate()(plain Go) - Custom validation in
ChunkRequest.Validate()for business rules - Factory returns errors for unknown strategies
- HTTP handlers return 400 Bad Request with error messages
- Service layer propagates errors with context
- Logger: Request logging
- Recoverer: Panic recovery
- RequestID: Unique request tracking
- RealIP: Client IP extraction
- Timeout: 60-second request timeout
- Listens for SIGINT/SIGTERM signals
- 30-second shutdown timeout for in-flight requests
- Clean server stop with connection draining
The CLI expects text via stdin and outputs JSON:
# Basic usage
cat file.txt | chunker
# Custom chunk size and strategy
echo "text" | chunker -size 500 -strategy word_boundary -overlap 50
# Token-based chunking for LLM processing
cat code.py | chunker -size 2000 -strategy token_based -encoding cl100k_base
# JSON Lines output for streaming
cat book.txt | chunker -format jsonl | while read line; do echo "$line" | jq .; done
# Pretty-printed JSON
echo "text" | chunker -prettyAll /chunk responses include:
chunks[]: Array of chunk objects with id, text, char_count, word_count, token_count (if applicable)metadata: Summary with total_chunks, total_chars, total_tokens (if applicable), strategy_used, token_encoding (if applicable)
See API.md for complete endpoint documentation and integration examples.
- Use dependency injection (pass dependencies to constructors)
- Return errors, don't panic (except in main initialization)
- Context as first parameter for all chunking operations
- Table-driven tests with descriptive test case names
- Interface-first design (define contracts before implementations)
- Keep domain layer free of external dependencies