Documentation
¶
Overview ¶
Package smith manages Claude Code CLI process spawning for Smith workers.
Each Smith is a Claude Code process running in a worktree directory, executing autonomously against a bead's description/prompt.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Process ¶
type Process struct {
// Cmd is the underlying exec.Cmd (nil after completion).
Cmd *exec.Cmd
// LogPath is the path to the session log file.
LogPath string
// PID is the process ID once started.
PID int
// contains filtered or unexported fields
}
Process represents a running or completed Smith (Claude Code) process.
func NewProcessForTest ¶
NewProcessForTest creates a Process that has already completed and whose Wait() immediately returns the provided result. Intended for use in tests of packages that depend on smith without needing to spawn a real process.
func Spawn ¶
func Spawn(ctx context.Context, worktreePath, promptText, logDir string, extraFlags []string) (*Process, error)
Spawn starts a Claude Code process in the given worktree directory. This is a convenience wrapper around SpawnWithProvider using provider.Claude.
logDir is where the session log file is written.
func SpawnWithProvider ¶
func SpawnWithProvider(ctx context.Context, worktreePath, promptText, logDir string, pv provider.Provider, extraFlags []string) (*Process, error)
SpawnWithProvider starts an AI coding agent process for the given provider. The provider determines which binary is executed and how arguments are built.
logDir is where the session log file is written.
func (*Process) Done ¶
func (p *Process) Done() <-chan struct{}
Done returns a channel that is closed when the process completes.
type RateLimitInfo ¶
type RateLimitInfo struct {
Status string `json:"status"`
ResetAt string `json:"reset_at,omitempty"` // RFC3339 timestamp from Claude
ResetsAt int64 `json:"resetsAt,omitempty"` // Unix epoch seconds (observed in real rate_limit_event payloads)
RequestsRemaining int `json:"requests_remaining,omitempty"`
RequestsLimit int `json:"requests_limit,omitempty"`
RequestsReset string `json:"requests_reset,omitempty"` // RFC3339 or similar
TokensRemaining int `json:"tokens_remaining,omitempty"`
TokensLimit int `json:"tokens_limit,omitempty"`
TokensReset string `json:"tokens_reset,omitempty"`
}
RateLimitInfo is the payload of a Claude rate_limit_event.
type Result ¶
type Result struct {
// ExitCode is the process exit code.
ExitCode int
// Duration is how long the process ran.
Duration time.Duration
// Output is the raw stdout collected.
Output string
// ErrorOutput is the raw stderr collected.
ErrorOutput string
// Summary is extracted from the stream-json output (last assistant message).
Summary string
// FullOutput is the complete text response from the AI (from the result event).
FullOutput string
// CostUSD is the total cost if extractable from output.
CostUSD float64
// TokensIn is the total input tokens if extractable.
TokensIn int
// TokensOut is the total output tokens if extractable.
TokensOut int
// RateLimited is true when the provider refused the request due to quota.
RateLimited bool
// IsError is true when the result event had is_error:true (session aborted,
// e.g. hard rate-limit rejection). A success subtype with is_error:true
// means Claude returned the rate-limit message as the "result" text, and we
// must NOT treat this as a successful session.
IsError bool
// ResultSubtype is the stream-json result event subtype (e.g. "success",
// "error_max_turns", "error_rate_limit_exceeded").
ResultSubtype string
// ProviderUsed records which provider produced this result.
ProviderUsed provider.Kind
// Quota contains the latest known quota information from the provider.
Quota *provider.Quota
// GeminiStats holds the raw stats block from a Gemini result event.
// Nil for non-Gemini providers or when no stats were emitted.
GeminiStats *StreamStats
}
Result captures the outcome of a Smith session.
type StreamEvent ¶
type StreamEvent struct {
Type string `json:"type"`
Subtype string `json:"subtype,omitempty"`
Message json.RawMessage `json:"message,omitempty"`
Content string `json:"content,omitempty"`
// Role is present on Gemini delta message events (role: "assistant" or "user").
Role string `json:"role,omitempty"`
// Fields present when type == "result":
Result string `json:"result,omitempty"`
IsError bool `json:"is_error,omitempty"`
TotalCostUSD float64 `json:"total_cost_usd,omitempty"`
Usage *StreamUsage `json:"usage,omitempty"`
// Stats from Gemini result event
Stats *StreamStats `json:"stats,omitempty"`
// rate_limit_event fields
RateLimitInfo *RateLimitInfo `json:"rate_limit_info,omitempty"`
}
StreamEvent represents a single event from a provider's stream-json output.
type StreamStats ¶
type StreamStats struct {
TotalTokens int `json:"total_tokens,omitempty"`
InputTokens int `json:"input_tokens,omitempty"`
OutputTokens int `json:"output_tokens,omitempty"`
Cached int `json:"cached,omitempty"`
Input int `json:"input,omitempty"`
DurationMs int `json:"duration_ms,omitempty"`
ToolCalls int `json:"tool_calls,omitempty"`
RequestsLimit int `json:"requests_limit,omitempty"`
RequestsUsed int `json:"requests_used,omitempty"`
RequestsResetMs int `json:"requests_reset_ms,omitempty"`
TokensLimit int `json:"tokens_limit,omitempty"`
TokensUsed int `json:"tokens_used,omitempty"`
TokensResetMs int `json:"tokens_reset_ms,omitempty"`
}
StreamStats from Gemini result event.
type StreamUsage ¶
type StreamUsage struct {
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
}
StreamUsage holds token counts from the result event.