diff --git a/.changes/973-chat-message-time-defaults.md b/.changes/973-chat-message-time-defaults.md new file mode 100644 index 00000000..1a6e5496 --- /dev/null +++ b/.changes/973-chat-message-time-defaults.md @@ -0,0 +1,5 @@ +--- +category: Fixed +--- + +- **Chat message time defaults** (#973) — validates `chat message list-all` time ranges locally and defaults omitted message-query time bounds without creating reversed windows. diff --git a/internal/helpers/chat.go b/internal/helpers/chat.go index a1fef36d..d9352996 100644 --- a/internal/helpers/chat.go +++ b/internal/helpers/chat.go @@ -471,6 +471,17 @@ func chatMessageListAllArgs(cmd *cobra.Command) (map[string]any, error) { if err != nil { return nil, err } + startMs, err := parseISOTimeToMillis("start", startRaw) + if err != nil { + return nil, err + } + endMs, err := parseISOTimeToMillis("end", endRaw) + if err != nil { + return nil, err + } + if err := validateTimeRange(startMs, endMs); err != nil { + return nil, err + } cursor, _ := cmd.Flags().GetString("cursor") return map[string]any{ "startTime": startRaw, diff --git a/internal/helpers/chat_message_pagination_test.go b/internal/helpers/chat_message_pagination_test.go index 8911b5e1..221bffa3 100644 --- a/internal/helpers/chat_message_pagination_test.go +++ b/internal/helpers/chat_message_pagination_test.go @@ -6,6 +6,7 @@ import ( "encoding/json" "io" "reflect" + "strings" "testing" "time" @@ -341,6 +342,41 @@ func TestChatMessagePaginationDefaultsEndFromNowWhenOnlyStartProvided(t *testing } } +func TestChatMessageListAllRejectsInvalidTimeRanges(t *testing.T) { + tests := []struct { + name string + args []string + wantErr string + }{ + { + name: "invalid start", + args: []string{"message", "list-all", "--start", "not-a-time", "--end", "2020-01-01T00:00:00+08:00"}, + wantErr: "cannot parse time for --start", + }, + { + name: "end before start", + args: []string{"message", "list-all", "--start", "2021-01-01T00:00:00+08:00", "--end", "2020-01-01T00:00:00+08:00"}, + wantErr: "--end must be after --start", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + caller := &chatMessagePaginationCaller{} + _, err := executeChatMessagePaginationCommand(t, caller, tt.args...) + if err == nil { + t.Fatal("command succeeded, want validation error") + } + if !strings.Contains(err.Error(), tt.wantErr) { + t.Fatalf("error = %v, want containing %q", err, tt.wantErr) + } + if len(caller.calls) != 0 { + t.Fatalf("calls = %#v, want no MCP call", caller.calls) + } + }) + } +} + func numericArgAsInt64(t *testing.T, value any) int64 { t.Helper() switch v := value.(type) {