Not in the top 1,000 by GitHub stars
Hyaxia/blogwatcher
stay on top of your favorite blogs
History
Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.
View weekly changes
SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → 58acfeb16258
No earlier version was observed for comparison.
skills/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → 58acfeb16258
No earlier version was observed for comparison.
Verified commit 58acfeb16258bd0e64d72f8f977ae8143cae5fa3
git clone --filter=blob:none --no-checkout https://github.com/Hyaxia/blogwatcher.git .hotskills/hyaxia-blogwatcher && git -C .hotskills/hyaxia-blogwatcher checkout --detach 58acfeb16258bd0e64d72f8f977ae8143cae5fa3
# Copy each selected skill directory from .hotskills/hyaxia-blogwatcher into .claude/skills/<skill-name>/git clone --filter=blob:none --no-checkout https://github.com/Hyaxia/blogwatcher.git .hotskills/hyaxia-blogwatcher && git -C .hotskills/hyaxia-blogwatcher checkout --detach 58acfeb16258bd0e64d72f8f977ae8143cae5fa3
# Copy each selected skill directory from .hotskills/hyaxia-blogwatcher into .agents/skills/<skill-name>/Heat
0.4- Star growth, last 7 daysNot available
- Star growth, last 24 hoursNot available
- Rank movement, last 7 daysNot available
- Commits, last 30 daysNot available
- Accounts asking about it through MCP, last 7 daysNot available
- Hot votes this weekNot available
Heat never changes the order by stars, and sponsorship never touches it. How heat works
Stars over time
30-day change not yet available: not enough history.
Individual skills in this repository
- blogwatcher-cli
/ - blogwatcher
skills
How it works
blogwatcher-cli
When your agent uses it
Use when managing or interacting with favorite blogs via the BlogWatcher CLI—adding/removing blogs, scanning for new posts, listing articles, marking read/unread, or modifying related CLI behavior, scanning, storage, and tests.
What it loads into context
Frontmatter
54 tokensAlways available to the agent
SKILL.md
517 tokensWhen the skill is activated
Reference documents
2,445 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Quick Orientation
- Run Commands
- Change Workflow
- Test Guidance
- Output Conventions
Scripts executed separately
cmd/blogwatcher/main.gointernal/cli/commands.gointernal/cli/errors.gointernal/cli/metadata.gointernal/cli/metadata_test.gointernal/cli/root.gointernal/controller/controller.gointernal/controller/controller_test.gointernal/model/model.gointernal/rss/rss.gointernal/rss/rss_test.gointernal/scanner/scanner.gointernal/scanner/scanner_test.gointernal/scraper/scraper.gointernal/scraper/scraper_test.gointernal/storage/database.gointernal/storage/database_test.gointernal/version/version.go
Files
.github/workflows/release.ymlasset736 bytes.gitignoreasset86 bytes.goreleaser.yamlasset1,049 bytesAGENTS.mddoc2,245 bytesCLAUDE.mddoc863 bytesLICENSEasset1,056 bytesREADME.mddoc7,677 bytesSKILL.mdcore2,215 bytescmd/blogwatcher/main.goruns98 bytesgo.modasset1,269 bytesgo.sumasset14,057 bytesinternal/cli/commands.goruns12,165 bytesinternal/cli/errors.goruns330 bytesinternal/cli/metadata.goruns2,459 bytesinternal/cli/metadata_test.goruns7,239 bytesinternal/cli/root.goruns900 bytesinternal/controller/controller.goruns3,584 bytesinternal/controller/controller_test.goruns2,378 bytesinternal/model/model.goruns451 bytesinternal/rss/rss.goruns10,047 bytesinternal/rss/rss_test.goruns11,161 bytesinternal/scanner/scanner.goruns5,756 bytesinternal/scanner/scanner_test.goruns7,765 bytesinternal/scraper/scraper.goruns2,901 bytesinternal/scraper/scraper_test.goruns882 bytesinternal/storage/database.goruns13,141 bytesinternal/storage/database_test.goruns15,990 bytesinternal/version/version.goruns37 bytes
Read SKILL.md
# BlogWatcher CLI
## Quick Orientation
- Use the Cobra entry point in `cmd/blogwatcher/main.go` and `internal/cli/`.
- Route business logic through `internal/controller` and persistence through `internal/storage`.
- Use scanning pipeline packages in `internal/scanner`, `internal/rss`, and `internal/scraper`.
- Remember the default SQLite path is `~/.blogwatcher/blogwatcher.db` (override with `BLOGWATCHER_DB`) and is created on demand.
## Run Commands
- Run locally with `go run ./cmd/blogwatcher ...`.
- Build with `go build ./cmd/blogwatcher`.
## Change Workflow
1. Add or adjust CLI commands in `internal/cli/commands.go` (Cobra options, arguments, output formatting).View the complete source on GitHubblogwatcher
When your agent uses it
Monitor blogs and RSS/Atom feeds for updates using the blogwatcher CLI.
What it loads into context
Frontmatter
24 tokensAlways available to the agent
SKILL.md
276 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
Files
SKILL.mdcore945 bytes
Read SKILL.md
# blogwatcher
Track blog and RSS/Atom feed updates with the `blogwatcher` CLI.
Install
- Go: `go install github.com/Hyaxia/blogwatcher/cmd/blogwatcher@latest`
Quick start
- `blogwatcher --help`
Common commands
View the complete source on GitHubSkills included
- blogwatcher-cli
- blogwatcher
Repository facts
- License
- MIT
- Created
- Dec 23, 2025
- Last pushed
- Aug 31, 2026
- Forks
- 25
- Open issues
- 0
- Project activity
- Slowing
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 4, 2026
- No broad tool permissions
- 1 dangerous shell commandin 1 file: .github/workflows/release.yml:25
- 156 network referencesin 11 files: internal/storage/database_test.go:28 internal/scanner/scanner_test.go:18 internal/rss/rss_test.go:15 and 8 more
- No hidden or obfuscated text
- 5 instruction override signalsin 1 file: internal/cli/commands.go:80
- 18 executable scriptsin 18 files: cmd/blogwatcher/main.go:1 internal/cli/commands.go:1 internal/cli/errors.go:1 and 15 more
- 1 reference to secretsin 1 file: .goreleaser.yaml:46
- No requests to vote in Hot
Show all 181 signals by file
.github/workflows/release.yml
- Dangerous shell operationline 25
run: sudo apt-get update && sudo apt-get install -y mingw-w64
.goreleaser.yaml
- Network accessline 39
- name: blogwatcher description: "Track blog articles and detect new posts." homepage: "https://github.com/Hyaxia/blogwatcher" - Network accessline 40
description: "Track blog articles and detect new posts." homepage: "https://github.com/Hyaxia/blogwatcher" license: "MIT" - Network accessline 41
homepage: "https://github.com/Hyaxia/blogwatcher" - Access to secretsline 46
[Credential-related source omitted]
README.md
- Network accessline 35
# Add a blog (auto-discovers RSS feed) blogwatcher add "My Favorite Blog" https://example.com/blog - Network accessline 36
blogwatcher add "My Favorite Blog" https://example.com/blog - Network accessline 38
# Add with explicit feed URL blogwatcher add "Tech Blog" https://techblog.com --feed-url https://techblog.com/rss.xml - Network accessline 39
blogwatcher add "Tech Blog" https://techblog.com --feed-url https://techblog.com/rss.xml - Network accessline 41
# Add with HTML scraping selector (for blogs without feeds) blogwatcher add "No-RSS Blog" https://norss.com --scrape-selector "article h2 a" - Network accessline 42
blogwatcher add "No-RSS Blog" https://norss.com --scrape-selector "article h2 a" - Network accessline 44
# Add with per-blog User-Agent override blogwatcher add "Blocked Blog" https://blocked.example --feed-url https://blocked.example/feed --user-agent "Mozilla/5.0 ..." - Network accessline 45
blogwatcher add "Blocked Blog" https://blocked.example --feed-url https://blocked.example/feed --user-agent "Mozilla/5.0 ..."
SKILL.md
- Network accessline 39
[12] [new] Understanding Click Contexts Blog: Real Python URL: https://realpython.com/click-context/ - Network accessline 40
Blog: Real Python URL: https://realpython.com/click-context/ Published: 2025-11-02 - Network accessline 41
URL: https://realpython.com/click-context/ - Network accessline 44
[13] [new] Async IO in Practice Blog: Test & Code URL: https://testandcode.com/async-io-in-practice/ - Network accessline 46
URL: https://testandcode.com/async-io-in-practice/
cmd/blogwatcher/main.go
- Executable scriptline 1
Executable file
internal/cli/commands.go
- Executable scriptline 1
Executable file - Instruction override signalline 80
}, } cmd.Flags().BoolVarP(&yes, "yes", "y", false, "Skip confirmation prompt") - Instruction override signalline 81
} cmd.Flags().BoolVarP(&yes, "yes", "y", false, "Skip confirmation prompt") return cmd - Instruction override signalline 82
cmd.Flags().BoolVarP(&yes, "yes", "y", false, "Skip confirmation prompt") - Instruction override signalline 339
cmd.Flags().StringVarP(&blogName, "blog", "b", "", "Only mark articles from this blog") cmd.Flags().BoolVarP(&yes, "yes", "y", false, "Skip confirmation prompt") - Instruction override signalline 340
cmd.Flags().BoolVarP(&yes, "yes", "y", false, "Skip confirmation prompt")
internal/cli/errors.go
- Executable scriptline 1
Executable file
internal/cli/metadata.go
- Executable scriptline 1
Executable file
internal/cli/metadata_test.go
- Executable scriptline 1
Executable file - Network accessline 122
published := time.Date(2026, 8, 25, 0, 0, 0, 0, time.UTC) article := model.Article{ ID: 7, Title: "Title", URL: "https://example.com/article", PublishedDate: &published, - Network accessline 123
article := model.Article{ ID: 7, Title: "Title", URL: "https://example.com/article", PublishedDate: &published, Description: "Stored metadata must stay hidden.", Keywords: "one,two", - Network accessline 124
ID: 7, Title: "Title", URL: "https://example.com/article", PublishedDate: &published, - Network accessline 128
want := " [7] [new] Title\n" + " Blog: Example\n" + " URL: https://example.com/article\n" + - Network accessline 129
" Blog: Example\n" + " URL: https://example.com/article\n" + " Published: 2026-08-25\n\n" - Network accessline 130
" URL: https://example.com/article\n" + - Network accessline 137
func TestPrintArticleMetadataFlagsAreIndependent(t *testing.T) { description := strings.Repeat("complete description ", 8) article := model.Article{ID: 1, Title: "Title", URL: "https://example.com/1", Description: description, Keywords: " - Network accessline 139
article := model.Article{ID: 1, Title: "Title", URL: "https://example.com/1", Description: description, Keywords: "one,two"}
internal/cli/root.go
- Executable scriptline 1
Executable file
internal/controller/controller.go
- Executable scriptline 1
Executable file
internal/controller/controller_test.go
- Executable scriptline 1
Executable file - Network accessline 15
blog, err := AddBlog(db, "Test", "https://example.com", "", "", "") - Network accessline 20
if _, err := AddBlog(db, "Test", "https://other.com", "", "", ""); err == nil { - Network accessline 24
if _, err := AddBlog(db, "Other", "https://example.com", "", "", ""); err == nil { - Network accessline 37
blog, err := AddBlog(db, "Test", "https://example.com", "", "", "") - Network accessline 39
t.Fatalf("add blog: %v", err) } article, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Title", URL: "https://example.com/1"}) - Network accessline 40
} article, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Title", URL: "https://example.com/1"}) if err != nil { - Network accessline 41
article, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Title", URL: "https://example.com/1"}) - Network accessline 67
blog, err := AddBlog(db, "Test", "https://example.com", "", "", "") - Network accessline 69
t.Fatalf("add blog: %v", err) } _, err = db.AddArticle(model.Article{BlogID: blog.ID, Title: "Title", URL: "https://example.com/1"}) - Network accessline 70
} _, err = db.AddArticle(model.Article{BlogID: blog.ID, Title: "Title", URL: "https://example.com/1"}) if err != nil { - Network accessline 71
_, err = db.AddArticle(model.Article{BlogID: blog.ID, Title: "Title", URL: "https://example.com/1"})
internal/model/model.go
- Executable scriptline 1
Executable file
internal/rss/rss.go
- Executable scriptline 1
Executable file - Network accessline 62
client := &http.Client{Timeout: timeout} - Network accessline 275
func DiscoverFeedURL(blogURL string, timeout time.Duration, userAgent string) (string, error) { client := &http.Client{Timeout: timeout} - Network accessline 276
client := &http.Client{Timeout: timeout} - Network accessline 355
func isValidFeed(feedURL string, timeout time.Duration, userAgent string) (bool, error) { client := &http.Client{Timeout: timeout} - Network accessline 356
client := &http.Client{Timeout: timeout} - Network accessline 375
func getWithOptionalUserAgent(client *http.Client, targetURL string, userAgent string) (*http.Response, error) {
internal/rss/rss_test.go
- Executable scriptline 1
Executable file - Network accessline 15
<item> <title>First</title> <link>https://example.com/1</link> - Network accessline 16
<title>First</title> <link>https://example.com/1</link> <pubDate>Mon, 02 Jan 2006 15:04:05 GMT</pubDate> - Network accessline 17
<link>https://example.com/1</link> - Network accessline 22
<item> <title>Second</title> <link>https://example.com/2</link> - Network accessline 23
<title>Second</title> <link>https://example.com/2</link> </item> - Network accessline 24
<link>https://example.com/2</link> - Network accessline 51
func TestParseFeedMetadataOptionsAreIndependent(t *testing.T) { feed := `<?xml version="1.0"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel> - Network accessline 52
feed := `<?xml version="1.0"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel> - Network accessline 53
<title>Metadata</title><item><title>First</title><link>https://example.com/1</link> - Network accessline 91
feed := `<?xml version="1.0"?><rss version="2.0"><channel>` + `<title>Large feed</title><item><title>Kept</title>` + `<link>https://example.com/kept</link><keyword>omitted</keyword><description>` + - Network accessline 92
`<title>Large feed</title><item><title>Kept</title>` + `<link>https://example.com/kept</link><keyword>omitted</keyword><description>` + largeDescription + `</description></item></channel></rss>` - Network accessline 93
`<link>https://example.com/kept</link><keyword>omitted</keyword><description>` + - Network accessline 188
func TestParseFeedKeywordAlignment(t *testing.T) { feed := `<?xml version="1.0"?><feed xmlns="http://www.w3.org/2005/Atom"> - Network accessline 189
feed := `<?xml version="1.0"?><feed xmlns="http://www.w3.org/2005/Atom"> - Network accessline 190
<title>Alignment</title> <entry><title>Skipped</title><keyword>first</keyword></entry> <entry><title>Kept</title><link href="https://example.com/kept"/><keyword>second</keyword></entry> - Network accessline 191
<entry><title>Skipped</title><keyword>first</keyword></entry> <entry><title>Kept</title><link href="https://example.com/kept"/><keyword>second</keyword></entry> </feed>` - Network accessline 192
<entry><title>Kept</title><link href="https://example.com/kept"/><keyword>second</keyword></entry> - Network accessline 209
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/feed+json") _, _ = w.Write([]byte(`{"version":"https://jsonfeed.org/version/1.1","title":"JSON","it - Network accessline 210
w.Header().Set("Content-Type", "application/feed+json") _, _ = w.Write([]byte(`{"version":"https://jsonfeed.org/version/1.1","title":"JSON","items":[{"id":"1","url":"https://example.com/1","title":"One"}]}`)) })) - Network accessline 211
_, _ = w.Write([]byte(`{"version":"https://jsonfeed.org/version/1.1","title":"JSON","items":[{"id":"1","url":"https://example.com/1","title":"One"}]}`))
internal/scanner/scanner.go
- Executable scriptline 1
Executable file
internal/scanner/scanner_test.go
- Executable scriptline 1
Executable file - Network accessline 18
<item> <title>First</title> <link>https://example.com/1</link> - Network accessline 19
<title>First</title> <link>https://example.com/1</link> </item> - Network accessline 20
<link>https://example.com/1</link> - Network accessline 22
<item> <title>Second</title> <link>https://example.com/2</link> - Network accessline 23
<title>Second</title> <link>https://example.com/2</link> </item> - Network accessline 24
<link>https://example.com/2</link> - Network accessline 29
const metadataFeed = `<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0"><channel><title>Metadata Feed</title><item> <title>Metadata article</title><link>https://example.com/metadata</link> - Network accessline 30
<rss version="2.0"><channel><title>Metadata Feed</title><item> <title>Metadata article</title><link>https://example.com/metadata</link> <description><![CDATA[<p>Stored description.</p>]]></description> - Network accessline 31
<title>Metadata article</title><link>https://example.com/metadata</link> - Network accessline 46
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com", FeedURL: server.URL}) - Network accessline 74
db := openTestDB(t) defer db.Close() blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com", FeedURL: server.URL}) - Network accessline 75
defer db.Close() blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com", FeedURL: server.URL}) if err != nil { - Network accessline 76
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com", FeedURL: server.URL}) - Network accessline 113
db := openTestDB(t) defer db.Close() blog, err := db.AddBlog(model.Blog{Name: test.name, URL: "https://example.com/" + test.name, FeedURL: server.URL}) - Network accessline 114
defer db.Close() blog, err := db.AddBlog(model.Blog{Name: test.name, URL: "https://example.com/" + test.name, FeedURL: server.URL}) if err != nil { - Network accessline 115
blog, err := db.AddBlog(model.Blog{Name: test.name, URL: "https://example.com/" + test.name, FeedURL: server.URL}) - Network accessline 141
db := openTestDB(t) defer db.Close() blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com", FeedURL: server.URL}) - Network accessline 142
defer db.Close() blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com", FeedURL: server.URL}) if err != nil { - Network accessline 143
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com", FeedURL: server.URL}) - Network accessline 145
t.Fatalf("add blog: %v", err) } article, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Metadata article", URL: "https://example.com/metadata"}) - Network accessline 146
} article, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Metadata article", URL: "https://example.com/metadata"}) if err != nil { - Network accessline 147
article, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Metadata article", URL: "https://example.com/metadata"}) - Network accessline 214
for i, name := range []string{"TestA", "TestB"} { _, err := db.AddBlog(model.Blog{Name: name, URL: "https://example.com/" + name, FeedURL: server.URL}) - Network accessline 215
_, err := db.AddBlog(model.Blog{Name: name, URL: "https://example.com/" + name, FeedURL: server.URL}) - Network accessline 250
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com", FeedURL: server.URL}) - Network accessline 255
_, err = db.AddArticle(model.Article{BlogID: blog.ID, Title: "First", URL: "https://example.com/1", DiscoveredDate: ptrTime(time.Now())})
internal/scraper/scraper.go
- Executable scriptline 1
Executable file - Network accessline 28
func ScrapeBlog(blogURL string, selector string, timeout time.Duration, userAgent string) ([]ScrapedArticle, error) { client := &http.Client{Timeout: timeout} - Network accessline 29
client := &http.Client{Timeout: timeout} - Network accessline 106
func getWithOptionalUserAgent(client *http.Client, targetURL string, userAgent string) (*http.Response, error) {
internal/scraper/scraper_test.go
- Executable scriptline 1
Executable file
internal/storage/database.go
- Executable scriptline 1
Executable file
internal/storage/database_test.go
- Executable scriptline 1
Executable file - Network accessline 28
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com"}) - Network accessline 44
articles := []model.Article{ {BlogID: blog.ID, Title: "One", URL: "https://example.com/1"}, - Network accessline 45
{BlogID: blog.ID, Title: "One", URL: "https://example.com/1"}, - Network accessline 46
{BlogID: blog.ID, Title: "Two", URL: "https://example.com/2"}, - Network accessline 140
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com"}) - Network accessline 145
_, err = db.AddArticle(model.Article{BlogID: blog.ID, Title: "One", URL: "https://example.com/1"}) - Network accessline 150
existing, err := db.GetExistingArticleURLs([]string{"https://example.com/1", "https://example.com/2"}) - Network accessline 152
t.Fatalf("get existing: %v", err) } if _, ok := existing["https://example.com/1"]; !ok { - Network accessline 153
} if _, ok := existing["https://example.com/1"]; !ok { t.Fatalf("expected existing url") - Network accessline 154
if _, ok := existing["https://example.com/1"]; !ok { - Network accessline 155
t.Fatalf("expected existing url") } if _, ok := existing["https://example.com/2"]; ok { - Network accessline 156
} if _, ok := existing["https://example.com/2"]; ok { t.Fatalf("did not expect url") - Network accessline 157
if _, ok := existing["https://example.com/2"]; ok { - Network accessline 171
if _, err := db.AddArticle(model.Article{BlogID: 9999, Title: "Orphan", URL: "https://example.com/orphan"}); err == nil { - Network accessline 185
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com"}) - Network accessline 212
blog, err := db.AddBlog(model.Blog{ Name: "Test", URL: "https://example.com", - Network accessline 213
Name: "Test", URL: "https://example.com", LastScanned: &now, - Network accessline 214
URL: "https://example.com", - Network accessline 242
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com"}) - Network accessline 249
BlogID: blog.ID, Title: "Title", URL: "https://example.com/1", - Network accessline 250
Title: "Title", URL: "https://example.com/1", PublishedDate: &published, - Network accessline 251
URL: "https://example.com/1", - Network accessline 280
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com"}) - Network accessline 282
t.Fatalf("add blog: %v", err) } plain, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Plain", URL: "https://example.com/plain"}) - Network accessline 283
} plain, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Plain", URL: "https://example.com/plain"}) if err != nil { - Network accessline 284
plain, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Plain", URL: "https://example.com/plain"}) - Network accessline 296
metadata, err := db.AddArticle(model.Article{ BlogID: blog.ID, Title: "Metadata", URL: "https://example.com/metadata", - Network accessline 297
BlogID: blog.ID, Title: "Metadata", URL: "https://example.com/metadata", - Network accessline 311
_, err = db.AddArticlesBulk([]model.Article{{ BlogID: blog.ID, Title: "Bulk", URL: "https://example.com/bulk", - Network accessline 312
BlogID: blog.ID, Title: "Bulk", URL: "https://example.com/bulk", - Network accessline 322
foundBulk := false for _, article := range listed { if article.URL == "https://example.com/bulk" { - Network accessline 323
for _, article := range listed { if article.URL == "https://example.com/bulk" { foundBulk = article.Description == "Bulk description." && article.Keywords == "bulk,test" - Network accessline 324
if article.URL == "https://example.com/bulk" { - Network accessline 342
blogA, err := db.AddBlog(model.Blog{Name: "A", URL: "https://a.example.com"}) - Network accessline 344
t.Fatalf("add blog: %v", err) } blogB, err := db.AddBlog(model.Blog{Name: "B", URL: "https://b.example.com"}) - Network accessline 345
} blogB, err := db.AddBlog(model.Blog{Name: "B", URL: "https://b.example.com"}) if err != nil { - Network accessline 346
blogB, err := db.AddBlog(model.Blog{Name: "B", URL: "https://b.example.com"}) - Network accessline 354
first, err := db.AddArticle(model.Article{BlogID: blogA.ID, Title: "Old", URL: "https://a.example.com/old", DiscoveredDate: &t1}) - Network accessline 356
t.Fatalf("add article: %v", err) } second, err := db.AddArticle(model.Article{BlogID: blogA.ID, Title: "New", URL: "https://a.example.com/new", DiscoveredDate: &t2}) - Network accessline 357
} second, err := db.AddArticle(model.Article{BlogID: blogA.ID, Title: "New", URL: "https://a.example.com/new", DiscoveredDate: &t2}) if err != nil { - Network accessline 358
second, err := db.AddArticle(model.Article{BlogID: blogA.ID, Title: "New", URL: "https://a.example.com/new", DiscoveredDate: &t2}) - Network accessline 360
t.Fatalf("add article: %v", err) } _, err = db.AddArticle(model.Article{BlogID: blogB.ID, Title: "Other", URL: "https://b.example.com/1", DiscoveredDate: &t2}) - Network accessline 361
} _, err = db.AddArticle(model.Article{BlogID: blogB.ID, Title: "Other", URL: "https://b.example.com/1", DiscoveredDate: &t2}) if err != nil { - Network accessline 362
_, err = db.AddArticle(model.Article{BlogID: blogB.ID, Title: "Other", URL: "https://b.example.com/1", DiscoveredDate: &t2}) - Network accessline 409
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com"}) - Network accessline 418
_, err = db.AddArticle(model.Article{BlogID: blog.ID, Title: "Existing", URL: "https://example.com/existing"}) - Network accessline 423
dupArticles := []model.Article{ {BlogID: blog.ID, Title: "Dup", URL: "https://example.com/dup"}, - Network accessline 424
{BlogID: blog.ID, Title: "Dup", URL: "https://example.com/dup"}, - Network accessline 425
{BlogID: blog.ID, Title: "Dup2", URL: "https://example.com/dup"}, - Network accessline 450
t.Fatalf("expected missing blog by name") } if blog, err := db.GetBlogByURL("https://missing.example.com"); err != nil || blog != nil { - Network accessline 451
} if blog, err := db.GetBlogByURL("https://missing.example.com"); err != nil || blog != nil { t.Fatalf("expected missing blog by url") - Network accessline 452
if blog, err := db.GetBlogByURL("https://missing.example.com"); err != nil || blog != nil { - Network accessline 456
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com"}) - Network accessline 458
t.Fatalf("add blog: %v", err) } article, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Title", URL: "https://example.com/1"}) - Network accessline 459
} article, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Title", URL: "https://example.com/1"}) if err != nil { - Network accessline 460
article, err := db.AddArticle(model.Article{BlogID: blog.ID, Title: "Title", URL: "https://example.com/1"}) - Network accessline 469
t.Fatalf("expected article to exist") } if exists, err := db.ArticleExists("https://example.com/missing"); err != nil || exists { - Network accessline 470
} if exists, err := db.ArticleExists("https://example.com/missing"); err != nil || exists { t.Fatalf("expected missing article to not exist") - Network accessline 471
if exists, err := db.ArticleExists("https://example.com/missing"); err != nil || exists { - Network accessline 543
blog, err := db.AddBlog(model.Blog{Name: "Test", URL: "https://example.com", UserAgent: "MyBot/1.0"}) - Network accessline 553
} article, err := db.AddArticle(model.Article{ BlogID: blog.ID, Title: "Migrated", URL: "https://example.com/migrated", - Network accessline 554
article, err := db.AddArticle(model.Article{ BlogID: blog.ID, Title: "Migrated", URL: "https://example.com/migrated", Description: "Migrated description.", Keywords: "migration,test", - Network accessline 555
BlogID: blog.ID, Title: "Migrated", URL: "https://example.com/migrated",
internal/version/version.go
- Executable scriptline 1
Executable file
How the signals fit together
Facts from a static read of the files at the pinned commit. They describe what the code does, not why.
Some files could not be read; the facts below still hold.
Signal confidence: 176 facts
- Network access in code of documentationREADME.md:35Low confidence
- Network access in code of documentationREADME.md:36Low confidence
- Network access in code of documentationREADME.md:38Low confidence
- Network access in code of documentationREADME.md:39Low confidence
- Network access in code of documentationREADME.md:41Low confidence
- Network access in code of documentationREADME.md:42Low confidence
- Network access in code of documentationREADME.md:44Low confidence
- Network access in code of documentationREADME.md:45Low confidence
- Network access in code of the SKILL.mdSKILL.md:39High confidence
- Network access in code of the SKILL.mdSKILL.md:40High confidence
- Network access in code of the SKILL.mdSKILL.md:41High confidence
- Network access in code of the SKILL.mdSKILL.md:44High confidence
- Network access in code of the SKILL.mdSKILL.md:46High confidence
- Executable script in code of a file that runscmd/blogwatcher/main.go:1High confidence
- Executable script in code of a file that runsinternal/cli/commands.go:1High confidence
- Instruction override signal in code of a file that runsinternal/cli/commands.go:80Low confidence
- Instruction override signal in code of a file that runsinternal/cli/commands.go:81Low confidence
- Instruction override signal in code of a file that runsinternal/cli/commands.go:82Low confidence
- Instruction override signal in code of a file that runsinternal/cli/commands.go:339Low confidence
- Instruction override signal in code of a file that runsinternal/cli/commands.go:340Low confidence
- Executable script in code of a file that runsinternal/cli/errors.go:1High confidence
- Executable script in code of a file that runsinternal/cli/metadata.go:1High confidence
- Executable script in code of a testinternal/cli/metadata_test.go:1Low confidence
- Network access in code of a testinternal/cli/metadata_test.go:122Low confidence
- Network access in code of a testinternal/cli/metadata_test.go:123Low confidence
- Network access in code of a testinternal/cli/metadata_test.go:124Low confidence
- Network access in code of a testinternal/cli/metadata_test.go:128Low confidence
- Network access in code of a testinternal/cli/metadata_test.go:129Low confidence
- Network access in code of a testinternal/cli/metadata_test.go:130Low confidence
- Network access in code of a testinternal/cli/metadata_test.go:137Low confidence
- Network access in code of a testinternal/cli/metadata_test.go:139Low confidence
- Executable script in code of a file that runsinternal/cli/root.go:1High confidence
- Executable script in code of a file that runsinternal/controller/controller.go:1High confidence
- Executable script in code of a testinternal/controller/controller_test.go:1Low confidence
- Network access in code of a testinternal/controller/controller_test.go:15Low confidence
- Network access in code of a testinternal/controller/controller_test.go:20Low confidence
- Network access in code of a testinternal/controller/controller_test.go:24Low confidence
- Network access in code of a testinternal/controller/controller_test.go:37Low confidence
- Network access in code of a testinternal/controller/controller_test.go:39Low confidence
- Network access in code of a testinternal/controller/controller_test.go:40Low confidence
- Network access in code of a testinternal/controller/controller_test.go:41Low confidence
- Network access in code of a testinternal/controller/controller_test.go:67Low confidence
- Network access in code of a testinternal/controller/controller_test.go:69Low confidence
- Network access in code of a testinternal/controller/controller_test.go:70Low confidence
- Network access in code of a testinternal/controller/controller_test.go:71Low confidence
- Executable script in code of a file that runsinternal/model/model.go:1High confidence
- Executable script in code of a file that runsinternal/rss/rss.go:1High confidence
- Network access in code of a file that runsinternal/rss/rss.go:62High confidence
- Network access in code of a file that runsinternal/rss/rss.go:275High confidence
- Network access in code of a file that runsinternal/rss/rss.go:276High confidence
and 126 more
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Native | Path CLAUDE.md | .claude/skills/<skill-name>/ |
| Codex | Native | Manifest AGENTS.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Compatible | Standard SKILL.md SKILL.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md SKILL.md | .opencode/skills/<skill-name>/ |
- Native The repository ships a manifest, folder or frontmatter field for this agent.
- Compatible A standard SKILL.md that this agent can read.
- Unknown No evidence either way.
Derived automatically from paths, manifests and frontmatter. Not tested on each agent.