Skip to main content

Overview

The handoff module provides utilities for constructing structured handoff objects that package worker results with comprehensive git diff statistics. These handoffs are the primary output format for worker tasks.

Main Function

buildHandoff()

Constructs a complete handoff object with git diff statistics.
export function buildHandoff(
  taskId: string,
  status: Handoff['status'],
  summary: string,
  metrics: Handoff['metrics']
): Handoff
Parameters:
  • taskId - Unique identifier for the task
  • status - Task completion status ('complete', 'failed', 'partial')
  • summary - Human-readable summary of what was accomplished
  • metrics - Performance metrics object containing:
    • tokensUsed - Total LLM tokens consumed
    • toolCallCount - Number of tool invocations
    • durationMs - Task execution duration in milliseconds
Returns: Complete Handoff object with git statistics merged in Example Usage:
import { buildHandoff } from '@longshot/sandbox'

const handoff = buildHandoff(
  'agent-001',
  'complete',
  'Implemented user authentication with JWT tokens',
  {
    tokensUsed: 12450,
    toolCallCount: 23,
    durationMs: 45000
  }
)

// handoff now includes:
// - filesChanged: ['src/auth/login.ts', 'src/auth/jwt.ts']
// - linesAdded: 342
// - linesRemoved: 18
// - filesCreated: 2
// - filesModified: 1

Git Diff Extraction

getGitDiffStat()

Internal function that extracts comprehensive statistics from git diff.
function getGitDiffStat(): DiffStatResult | undefined
Returns: Object containing:
  • filesChanged - Array of file paths that were modified
  • linesAdded - Total lines added across all files
  • linesRemoved - Total lines removed across all files
  • filesCreated - Count of newly created files
  • filesModified - Count of existing files that were modified
Returns undefined if git operations fail. Implementation Details:
interface DiffStatResult {
  filesChanged: string[]
  linesAdded: number
  linesRemoved: number
  filesCreated: number
  filesModified: number
}
The function executes two git commands:
  1. Get numstat for line counts:
git diff --numstat
  1. Detect new files:
git diff --diff-filter=A --name-only
Binary File Handling: Binary files show - in numstat output and are handled gracefully:
if (addedRaw !== '-') linesAdded += parseInt(addedRaw, 10)
if (removedRaw !== '-') linesRemoved += parseInt(removedRaw, 10)

Error Handling

Git Operation Failures

When git commands fail, the function handles it gracefully:
try {
  // git operations
  return { filesChanged, linesAdded, ... }
} catch (error) {
  logger.warn('Failed to compute git diff statistics', { error })
  return undefined
}
When getGitDiffStat() returns undefined, buildHandoff() provides: Default Values:
const normalizedDiffStat = diffStat ?? {
  filesChanged: [],
  linesAdded: 0,
  linesRemoved: 0,
  filesCreated: 0,
  filesModified: 0,
}
Diagnostic Information:
concerns: diffStat ? [] : ['Unable to compute git diff statistics']
suggestions: diffStat ? [] : ['Check git availability and repository state']

Handoff Structure

The complete handoff object returned by buildHandoff():
interface Handoff {
  taskId: string
  status: 'complete' | 'failed' | 'partial'
  summary: string
  diff: string  // Full git diff (empty in this utility)
  filesChanged: string[]
  concerns: string[]
  suggestions: string[]
  metrics: {
    linesAdded: number
    linesRemoved: number
    filesCreated: number
    filesModified: number
    tokensUsed: number
    toolCallCount: number
    durationMs: number
  }
}
Field Descriptions:
  • taskId - Matches the input task identifier
  • status - Final task status
  • summary - Human-readable completion summary
  • diff - Full unified diff (populated elsewhere)
  • filesChanged - List of all modified file paths
  • concerns - Array of warnings or issues encountered
  • suggestions - Recommended next steps or fixes
  • metrics - Combined performance and change metrics

Usage in Worker Pipeline

Typical usage in the worker runner pipeline:
import { buildHandoff } from './handoff'
import { writeFileSync } from 'node:fs'

const handoff = buildHandoff(
  task.id,
  isSuccess ? 'complete' : 'failed',
  lastAssistantMessage || 'No summary available',
  {
    tokensUsed: session.getSessionStats().tokens.total,
    toolCallCount,
    durationMs: Date.now() - startTime
  }
)

writeFileSync(
  '/workspace/result.json',
  JSON.stringify(handoff, null, 2),
  'utf-8'
)

Logging

The module uses structured logging:
import { createLogger } from '@longshot/core'

const logger = createLogger('sandbox-handoff', 'worker')

logger.warn('Failed to compute git diff statistics', { error: errorMessage })
logger.debug('Failed to classify created files', { error: errorMessage })

Buffer Size

Git diff output uses a large buffer to handle repos with many changes:
execSync('git diff --numstat', {
  encoding: 'utf-8',
  maxBuffer: 10 * 1024 * 1024  // 10 MB
})
This prevents truncation errors on large diffs.

Build docs developers (and LLMs) love