Skip to content

Commit e1f085c

Browse files
kostyayclaude
andauthored
feat: add Opus 4.6 context support, debug logging, and task cache (#16)
* feat: add debug logging and remove task caching Add debug logging for workspace diagnosis to help identify when Claude Code sends incorrect workDir. Remove task caching to simplify the codebase - tasks are now fetched directly from providers on each call. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: cache task stats and next task per workDir with TTL Task provider results (stats + next task) now cached per-workDir with configurable TTL, matching the existing cache pattern for git/GitHub data. Includes old-entry eviction (>1 week) and debug logging to file. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: update context window references for Opus 4.6 support Add Opus 4.6 to context window documentation and test coverage. Update CLAUDE.md, token comments, and changelog. Fix whitespace alignment in test files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 497186f commit e1f085c

File tree

8 files changed

+43
-9
lines changed

8 files changed

+43
-9
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## feat/debug-logging-remove-task-cache
4+
5+
Debug logging for workspace diagnosis and task caching removal (#16).
6+
Stdin parsing now logs workDir, sessionID, and model to stderr for
7+
troubleshooting. Task results are fetched directly from providers instead
8+
of going through the cache layer, simplifying the data path. Context
9+
window documentation updated to reflect Opus 4.6 support alongside
10+
Sonnet 4.5 and Sonnet 4 for the [1m] beta.
11+
312
## Unreleased
413

514
### Added

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ The binary reads JSON from stdin containing model, workspace, version, and trans
3939

4040
- Dependency injection via interfaces (Commander, HTTPClient, TokenGetter, Clock) for testing
4141
- Cache invalidation keyed on file mtimes: `.git/HEAD` for branch, `.git/index` for status
42-
- Model-aware context limits: 1M tokens for Sonnet 4.5 [1m], 200k for others
42+
- Model-aware context limits: 1M tokens for Opus 4.6/Sonnet 4.5/Sonnet 4 [1m], 200k for others
4343

4444
### File Locations (XDG)
4545

cmd/claude-status/main.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ func main() {
3333
return
3434
}
3535

36-
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, nil)))
36+
// Log to file for debugging
37+
logFile, err := os.OpenFile("/tmp/claude-status-debug.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
38+
if err == nil {
39+
slog.SetDefault(slog.New(slog.NewTextHandler(logFile, &slog.HandlerOptions{Level: slog.LevelDebug})))
40+
defer logFile.Close()
41+
} else {
42+
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelDebug})))
43+
}
3744
os.Exit(runMain())
3845
}
3946

@@ -73,6 +80,11 @@ func run() error {
7380
}
7481
}
7582

83+
slog.Debug("received input",
84+
"workDir", input.Workspace.CurrentDir,
85+
"sessionID", input.SessionID,
86+
"model", input.Model.ID)
87+
7688
// Build status data
7789
builder, err := status.NewBuilder(&cfg, input.Workspace.CurrentDir, input.SessionID)
7890
if err != nil {

internal/claudetasks/claudetasks_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func TestClient_GetStats(t *testing.T) {
5151
{ID: "2", Subject: "Task 2", Status: "in_progress"},
5252
{ID: "3", Subject: "Task 3", Status: "pending", BlockedBy: []string{"1"}}, // not blocked (1 is completed)
5353
{ID: "4", Subject: "Task 4", Status: "pending", BlockedBy: []string{"2"}}, // blocked (2 is in_progress)
54-
{ID: "5", Subject: "Task 5", Status: "pending"}, // ready
54+
{ID: "5", Subject: "Task 5", Status: "pending"}, // ready
5555
}
5656

5757
for i, task := range tasks {

internal/kt/kt.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ func (c *Client) GetStats() (tasks.Stats, error) {
9898
}
9999
}
100100

101+
slog.Debug("kt stats result", "workDir", c.workDir, "total", stats.TotalIssues, "ready", stats.ReadyIssues)
101102
return stats, nil
102103
}
103104

internal/tasks/registry_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ type mockProvider struct {
3333
available bool
3434
}
3535

36-
func (m *mockProvider) Name() string { return m.name }
37-
func (m *mockProvider) Available() bool { return m.available }
38-
func (m *mockProvider) GetStats() (Stats, error) { return Stats{}, nil }
39-
func (m *mockProvider) GetNextTask() (string, error) { return "", nil }
36+
func (m *mockProvider) Name() string { return m.name }
37+
func (m *mockProvider) Available() bool { return m.available }
38+
func (m *mockProvider) GetStats() (Stats, error) { return Stats{}, nil }
39+
func (m *mockProvider) GetNextTask() (string, error) { return "", nil }
4040

4141
func TestSelectProvider_Priority(t *testing.T) {
4242
// Save and restore original registry

internal/tokens/tokens.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ type Metrics struct {
1919

2020
// ContextConfig holds model-specific context limits.
2121
type ContextConfig struct {
22-
MaxTokens int64 // Maximum context window (1M for Sonnet 4.5 [1m], 200k otherwise)
22+
MaxTokens int64 // Maximum context window (1M for Opus 4.6/Sonnet 4.5/Sonnet 4 [1m], 200k otherwise)
2323
UsableTokens int64 // Usable context before auto-compact (80% of max)
2424
}
2525

2626
// GetContextConfig returns context limits based on model ID.
27-
// Only models with "[1m]" suffix have 1M context, all others have 200k.
27+
// Models with "[1m]" suffix (Opus 4.6, Sonnet 4.5, Sonnet 4) have 1M context, all others have 200k.
2828
func GetContextConfig(modelID string) ContextConfig {
2929
if strings.Contains(strings.ToLower(modelID), "[1m]") {
3030
return ContextConfig{

internal/tokens/tokens_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ func TestGetContextConfig(t *testing.T) {
3131
wantMax: 1_000_000,
3232
wantUsable: 800_000,
3333
},
34+
{
35+
name: "Opus 4.6 (200k default)",
36+
modelID: "claude-opus-4-6",
37+
wantMax: 200_000,
38+
wantUsable: 160_000,
39+
},
40+
{
41+
name: "Opus 4.6 with [1m] suffix",
42+
modelID: "claude-opus-4-6[1m]",
43+
wantMax: 1_000_000,
44+
wantUsable: 800_000,
45+
},
3446
{
3547
name: "Standard model",
3648
modelID: "claude-opus-4-5-20251101",

0 commit comments

Comments
 (0)