refactor(import): centralize imported-Kind checks and token merge · Entire
refactor(import): centralize imported-Kind checks and token merge
e139821→main·
computermode·1w ago·9 files·+84 added/-47 removed
- Add Kind.IsImported() alongside IsReview/IsInvestigate and route all imported special-cases (staleness, orphan cleanup, resume filter, list/info labels, JSON field) through it, killing the scattered string-literal checks. - Add types.AddTokenUsage (canonical, nil-safe, recursive) and use it in the importer instead of a hand-rolled fold. - Drop the single-use pluralizeImportedSessions helper and a redundant local.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Sessions
01KX4F2HAMHPF9FYCTD17VN18RView transcript
[?
Fix Imported Sessions Handling in CLIClaude Code·Opus 4.8·8 steps](/content/gh/entireio/cli/session/91fa7c44-6634-48ab-ae5f-d394502f50d5#timeline-01KX4F2HAMHPF9FYCTD17VN18R/index.html)
Changes
9
cmd/entire/cli
agent/types
Mtoken_usage.go+29
Atoken_usage_test.go+32
agentimport
Magentimport.go+4/-24
Mresume_picker.go+3/-11
Mresume_picker_test.go-6
session
Mstate.go+11/-1
Msessions.go+3/-3
strategy
Mcleanup.go+1/-1
Mmanual_commit_session.go+1/-1
15 unmodified lines
// SubagentTokens contains token usage from spawned subagents (if any)
SubagentTokens *TokenUsage `json:"subagent_tokens,omitempty"`
}
// AddTokenUsage returns the sum of a and b, recursing into subagent usage.
// Either operand may be nil (treated as zero); the result is nil only when both
// are. Neither input is mutated.
func AddTokenUsage(a, b *TokenUsage) *TokenUsage {
if a == nil && b == nil {
return nil
}
sum := &TokenUsage{}
var aSub, bSub *TokenUsage
if a != nil {
sum.InputTokens = a.InputTokens
sum.CacheCreationTokens = a.CacheCreationTokens
sum.CacheReadTokens = a.CacheReadTokens
sum.OutputTokens = a.OutputTokens
sum.APICallCount = a.APICallCount
aSub = a.SubagentTokens
}
if b != nil {
sum.InputTokens += b.InputTokens
sum.CacheCreationTokens += b.CacheCreationTokens
sum.CacheReadTokens += b.CacheReadTokens
sum.OutputTokens += b.OutputTokens
sum.APICallCount += b.APICallCount
bSub = b.SubagentTokens
}
sum.SubagentTokens = AddTokenUsage(aSub, bSub)
return sum
}
Mcmd/entire/cli/agent/types/token_usage.go+29
package types
import "testing"
func TestAddTokenUsage(t *testing.T) {
t.Parallel()
if got := AddTokenUsage(nil, nil); got != nil {
t.Errorf("AddTokenUsage(nil, nil) = %+v, want nil", got)
}
only := &TokenUsage{InputTokens: 3}
if got := AddTokenUsage(nil, only); got == nil || got.InputTokens != 3 {
t.Errorf("AddTokenUsage(nil, x) = %+v, want a copy of x", got)
}
if got := AddTokenUsage(only, nil); got == only {
t.Error("AddTokenUsage must not return an input pointer (would alias caller state)")
}
a := &TokenUsage{InputTokens: 1, OutputTokens: 2, APICallCount: 1, SubagentTokens: &TokenUsage{InputTokens: 10}}
b := &TokenUsage{InputTokens: 4, OutputTokens: 5, APICallCount: 2, SubagentTokens: &TokenUsage{InputTokens: 20}}
got := AddTokenUsage(a, b)
if got.InputTokens != 5 || got.OutputTokens != 7 || got.APICallCount != 3 {
t.Errorf("top-level sum = %+v", got)
}
if got.SubagentTokens == nil || got.SubagentTokens.InputTokens != 30 {
t.Errorf("subagent sum = %+v, want InputTokens 30", got.SubagentTokens)
}
if a.InputTokens != 1 || a.SubagentTokens.InputTokens != 10 {
t.Error("AddTokenUsage mutated an input")
}
}
Acmd/entire/cli/agent/types/token_usage_test.go+32
package types_test
import "testing"
func TestCountImportedSessions(t *testing.T) {
states := []*SessionState{{Kind: KindImported}, {Kind: KindImported}, {Kind: KindNormal}}
if got := countImportedSessions(states); got != 2 {
t.Fatalf("countImportedSessions = %d, want 2", got)
}
if got := pluralizeImportedSessions(1); got != "1 imported session is" {
t.Errorf("singular = %q", got)
}
if got := pluralizeImportedSessions(3); got != "3 imported sessions are" {
t.Errorf("plural = %q", got)
}
}