diff --git a/examples/upstream-registry.json b/examples/upstream-registry.json index 689d4c70..0469be9a 100644 --- a/examples/upstream-registry.json +++ b/examples/upstream-registry.json @@ -1185,6 +1185,38 @@ } } } + ], + "skills": [ + { + "namespace": "com.xquik", + "name": "tweetclaw", + "description": "Search tweets, scrape tweet replies, post tweets and replies, export followers, manage media, monitor tweets, deliver webhooks, run giveaway draws, and use direct messages from OpenClaw with approval-aware X/Twitter workflows.", + "version": "1.6.32", + "status": "active", + "title": "TweetClaw", + "license": "MIT", + "compatibility": "OpenClaw 2026.6.1 or newer with the TweetClaw plugin installed from npm.", + "allowedTools": [ + "explore", + "tweetclaw" + ], + "repository": { + "url": "https://github.com/Xquik-dev/tweetclaw", + "type": "git" + }, + "packages": [ + { + "registryType": "git", + "url": "https://github.com/Xquik-dev/tweetclaw", + "commit": "7113d9e534a94f8279438b1373f741343c39523a", + "subfolder": "skills/tweetclaw" + } + ], + "metadata": { + "npmPackage": "@xquik/tweetclaw", + "openclawInstall": "openclaw plugins install npm:@xquik/tweetclaw" + } + } ] } } diff --git a/internal/sources/types_test.go b/internal/sources/types_test.go index 93e9a065..751f7ce8 100644 --- a/internal/sources/types_test.go +++ b/internal/sources/types_test.go @@ -270,12 +270,15 @@ func TestExampleFiles(t *testing.T) { name string filename string expectedServers int + expectedSkills int validateServerName func(*testing.T, *toolhivetypes.UpstreamRegistry) + validateSkillName func(*testing.T, *toolhivetypes.UpstreamRegistry) }{ { name: "upstream-registry.json", filename: "upstream-registry.json", expectedServers: 12, + expectedSkills: 1, validateServerName: func(t *testing.T, reg *toolhivetypes.UpstreamRegistry) { t.Helper() // Verify some expected servers are present @@ -294,6 +297,17 @@ func TestExampleFiles(t *testing.T) { assert.True(t, serverNames[name], "Expected server %s not found", name) } }, + validateSkillName: func(t *testing.T, reg *toolhivetypes.UpstreamRegistry) { + t.Helper() + require.Len(t, reg.Data.Skills, 1) + skill := reg.Data.Skills[0] + assert.Equal(t, "com.xquik", skill.Namespace) + assert.Equal(t, "tweetclaw", skill.Name) + require.NotEmpty(t, skill.Packages) + assert.Equal(t, "git", skill.Packages[0].RegistryType) + assert.Equal(t, "7113d9e534a94f8279438b1373f741343c39523a", skill.Packages[0].Commit) + assert.Equal(t, "skills/tweetclaw", skill.Packages[0].Subfolder) + }, }, } @@ -315,6 +329,8 @@ func TestExampleFiles(t *testing.T) { // Verify expected server count assert.Len(t, reg.Data.Servers, tt.expectedServers, "Example file %s has unexpected server count", tt.filename) + assert.Len(t, reg.Data.Skills, tt.expectedSkills, + "Example file %s has unexpected skill count", tt.filename) // Verify all servers have required fields for i, server := range reg.Data.Servers { @@ -330,6 +346,9 @@ func TestExampleFiles(t *testing.T) { if tt.validateServerName != nil { tt.validateServerName(t, reg) } + if tt.validateSkillName != nil { + tt.validateSkillName(t, reg) + } // Verify metadata is present assert.NotEmpty(t, reg.Version, "Example file %s has no version", tt.filename)