diff --git a/internal/skillscheck/state.go b/internal/skillscheck/state.go index eddab1cf3..e6a51f02d 100644 --- a/internal/skillscheck/state.go +++ b/internal/skillscheck/state.go @@ -27,6 +27,7 @@ type SkillsState struct { UpdatedSkills []string `json:"updated_skills"` AddedOfficialSkills []string `json:"added_official_skills"` SkippedDeletedSkills []string `json:"skipped_deleted_skills"` + SuiteSkills []string `json:"suite_skills,omitempty"` UpdatedAt string `json:"updated_at"` } diff --git a/internal/skillscheck/state_test.go b/internal/skillscheck/state_test.go index d69b74635..b82173394 100644 --- a/internal/skillscheck/state_test.go +++ b/internal/skillscheck/state_test.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "reflect" + "strings" "testing" ) @@ -137,3 +138,57 @@ func TestReadSyncedVersionFromState(t *testing.T) { t.Fatalf("ReadSyncedVersion() = (%q, %v), want (\"\", false) for empty version", got, ok) } } + +func TestSkillsStateSuiteRoundTrip(t *testing.T) { + dir := t.TempDir() + t.Setenv("LARKSUITE_CLI_CONFIG_DIR", dir) + + if err := WriteState(SkillsState{ + Version: "1.2.3", + SuiteSkills: []string{"lark-calendar", "lark-im"}, + UpdatedAt: "2026-06-26T10:00:00Z", + }); err != nil { + t.Fatalf("WriteState() err = %v, want nil", err) + } + + got, ok, err := ReadState() + if err != nil || !ok || got == nil { + t.Fatalf("ReadState() = (_, %v, %v), want readable state", ok, err) + } + if !reflect.DeepEqual(got.SuiteSkills, []string{"lark-calendar", "lark-im"}) { + t.Fatalf("SuiteSkills = %#v, want [lark-calendar lark-im]", got.SuiteSkills) + } +} + +func TestSkillsStateSuiteBackCompat(t *testing.T) { + dir := t.TempDir() + t.Setenv("LARKSUITE_CLI_CONFIG_DIR", dir) + // Old state file without suite_skills field. + old := `{"version":"1.0.0","official_skills":["lark-im"],"updated_at":"2026-01-01T00:00:00Z"}` + if err := os.WriteFile(filepath.Join(dir, stateFile), []byte(old), 0o644); err != nil { + t.Fatal(err) + } + + got, ok, err := ReadState() + if err != nil || !ok || got == nil { + t.Fatalf("ReadState() = (_, %v, %v), want readable", ok, err) + } + if got.SuiteSkills != nil { + t.Fatalf("SuiteSkills = %#v, want nil for old state without the field", got.SuiteSkills) + } +} + +func TestWriteStateOmitsEmptySuite(t *testing.T) { + dir := t.TempDir() + t.Setenv("LARKSUITE_CLI_CONFIG_DIR", dir) + if err := WriteState(SkillsState{Version: "1.0.0"}); err != nil { + t.Fatal(err) + } + raw, err := os.ReadFile(filepath.Join(dir, stateFile)) + if err != nil { + t.Fatal(err) + } + if strings.Contains(string(raw), "suite_skills") { + t.Fatalf("empty suite must be omitted from JSON, got: %s", raw) + } +}