[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6JGSMBABA9ZSZJ5QZSW1MYT":3,"skill-same:01M6JGSMBABA9ZSZJ5QZSW1MYT":111},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":59,"commitSha":60,"skillDirectory":61,"forksCount":62,"repositoryHtmlUrl":63,"repositoryHomepageUrl":6,"ownerHtmlUrl":64,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":65,"install":66,"resources":79},"01M6JGSMBABA9ZSZJ5QZSW1MYT","golang-samber-ro",null,"Reactive streams and event-driven programming in Golang using samber\u002Fro — ReactiveX implementation with 150+ type-safe operators, cold\u002Fhot observables, 5 subject types (Publish, Behavior, Replay, Async, Unicast), declarative pipelines via Pipe, 40+ plugins (HTTP, cron, fsnotify, JSON, logging), automatic backpressure, error propagation, and Go context integration. Apply when using or adopting samber\u002Fro, when the codebase imports github.com\u002Fsamber\u002Fro, or when building asynchronous event-driven pipelines, real-time data processing, streams, or reactive architectures in Go. Not for finite slice transforms (-> See golang-samber-lo skill).","muratovv\u002Fai-hats","muratovv","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F7502801?v=4","01M6JGCBN4KEJX012GPJVSH04T","Fedor Muratov","01M6JGCBSNMN7CW3RGTPPE0MN2",3,"MIT","https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"golang","golang samber ro","query","imports","streams","types","processing","cold","error","false","operators","time","MCP","pipe","projects","Bash","publish","asynchronous","code","ai coding agents","2026-11-10 10:12:30",false,"---\nname: golang-samber-ro\ndescription: >-\n  Reactive streams and event-driven programming in Golang using samber\u002Fro\n  — ReactiveX implementation with 150+ type-safe operators, cold\u002Fhot\n  observables, 5 subject types (Publish, Behavior, Replay, Async,\n  Unicast), declarative pipelines via Pipe, 40+ plugins (HTTP, cron,\n  fsnotify, JSON, logging), automatic backpressure, error propagation, and\n  Go context integration. Apply when using or adopting samber\u002Fro, when the\n  codebase imports github.com\u002Fsamber\u002Fro, or when building asynchronous\n  event-driven pipelines, real-time data processing, streams, or reactive\n  architectures in Go. Not for finite slice transforms (-> See\n  golang-samber-lo skill).\nuser-invocable: false\nlicense: MIT\ncompatibility: Designed for Claude Code or similar AI coding agents, and for projects using Golang.\nmetadata:\n  author: samber\n  version: \"1.0.3\"\nallowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent mcp__context7__resolve-library-id mcp__context7__query-docs AskUserQuestion\n---\n\n**Persona:** You are a Go engineer who reaches for reactive streams when data flows asynchronously or infinitely. You use samber\u002Fro to build declarative pipelines instead of manual goroutine\u002Fchannel wiring, but you know when a simple slice + samber\u002Flo is enough.\n\n**Thinking mode:** Use `ultrathink` when designing advanced reactive pipelines or choosing between cold\u002Fhot observables, subjects, and combining operators. Wrong architecture leads to resource leaks or missed events.\n\n# samber\u002Fro — Reactive Streams for Go\n\nGo implementation of [ReactiveX](https:\u002F\u002Freactivex.io\u002F). Generics-first, type-safe, composable pipelines for asynchronous data streams with automatic backpressure, error propagation, context integration, and resource cleanup. 150+ operators, 5 subject types, 40+ plugins.\n\n**Official Resources:**\n\n- [github.com\u002Fsamber\u002Fro](https:\u002F\u002Fgithub.com\u002Fsamber\u002Fro)\n- [ro.samber.dev](https:\u002F\u002Fro.samber.dev)\n- [pkg.go.dev\u002Fgithub.com\u002Fsamber\u002Fro](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fsamber\u002Fro)\n\nThis skill is not exhaustive. Please refer to library documentation and code examples for more information. Context7 can help as a discoverability platform.\n\n## Why samber\u002Fro (Streams vs Slices)\n\nGo channels + goroutines become unwieldy for complex async pipelines: manual channel closures, verbose goroutine lifecycle, error propagation across nested selects, and no composable operators. `samber\u002Fro` solves this with declarative, chainable stream operators.\n\n**When to use which tool:**\n\n| Scenario | Tool | Why |\n| --- | --- | --- |\n| Transform a slice (map, filter, reduce) | `samber\u002Flo` | Finite, synchronous, eager — no stream overhead needed |\n| Simple goroutine fan-out with error handling | `errgroup` | Standard lib, lightweight, sufficient for bounded concurrency |\n| Infinite event stream (WebSocket, tickers, file watcher) | `samber\u002Fro` | Declarative pipeline with backpressure, retry, timeout, combine |\n| Real-time data enrichment from multiple async sources | `samber\u002Fro` | CombineLatest\u002FZip compose dependent streams without manual select |\n| Pub\u002Fsub with multiple consumers sharing one source | `samber\u002Fro` | Hot observables (Share\u002FSubjects) handle multicast natively |\n\n**Key differences: lo vs ro**\n\n| Aspect | `samber\u002Flo` | `samber\u002Fro` |\n| --- | --- | --- |\n| Data | Finite slices | Infinite streams |\n| Execution | Synchronous, blocking | Asynchronous, non-blocking |\n| Evaluation | Eager (allocates intermediate slices) | Lazy (processes items as they arrive) |\n| Timing | Immediate | Time-aware (delay, throttle, interval, timeout) |\n| Error model | Return `(T, error)` per call | Error channel propagates through pipeline |\n| Use case | Collection transforms | Event-driven, real-time, async pipelines |\n\n## Installation\n\n```bash\ngo get github.com\u002Fsamber\u002Fro\n```\n\n## Core Concepts\n\nFour building blocks:\n\n1. **Observable** — a data source that emits values over time. Cold by default: each subscriber triggers independent execution from scratch\n2. **Observer** — a consumer with three callbacks: `onNext(T)`, `onError(error)`, `onComplete()`\n3. **Operator** — a function that transforms an observable into another observable, chained via `Pipe`\n4. **Subscription** — the connection between observable and observer. Call `.Wait()` to block or `.Unsubscribe()` to cancel\n\n```go\nobservable := ro.Pipe2(\n    ro.RangeWithInterval(0, 5, 1*time.Second),\n    ro.Filter(func(x int) bool { return x%2 == 0 }),\n    ro.Map(func(x int) string { return fmt.Sprintf(\"even-%d\", x) }),\n)\n\nobservable.Subscribe(ro.NewObserver(\n    func(s string) { fmt.Println(s) },      \u002F\u002F onNext\n    func(err error) { log.Println(err) },    \u002F\u002F onError\n    func() { fmt.Println(\"Done!\") },         \u002F\u002F onComplete\n))\n\u002F\u002F Output: \"even-0\", \"even-2\", \"even-4\", \"Done!\"\n\n\u002F\u002F Or collect synchronously:\nvalues, err := ro.Collect(observable)\n```\n\n## Cold vs Hot Observables\n\n**Cold** (default): each `.Subscribe()` starts a new independent execution. Safe and predictable — use by default.\n\n**Hot**: multiple subscribers share a single execution. Use when the source is expensive (WebSocket, DB poll) or subscribers must see the same events.\n\n| Convert with | Behavior |\n| --- | --- |\n| `Share()` | Cold → hot with reference counting. Last unsubscribe tears down |\n| `ShareReplay(n)` | Same as Share + buffers last N values for late subscribers |\n| `Connectable()` | Cold → hot, but waits for explicit `.Connect()` call |\n| Subjects | Natively hot — call `.Send()`, `.Error()`, `.Complete()` directly |\n\n| Subject | Constructor | Replay behavior |\n| --- | --- | --- |\n| `PublishSubject` | `NewPublishSubject[T]()` | None — late subscribers miss past events |\n| `BehaviorSubject` | `NewBehaviorSubject[T](initial)` | Replays last value to new subscribers |\n| `ReplaySubject` | `NewReplaySubject[T](bufferSize)` | Replays last N values |\n| `AsyncSubject` | `NewAsyncSubject[T]()` | Emits only last value, only on complete |\n| `UnicastSubject` | `NewUnicastSubject[T](bufferSize)` | Single subscriber only |\n\nFor subject details and hot observable patterns, see [Subjects Guide](.\u002Freferences\u002Fsubjects-guide.md).\n\n## Operator Quick Reference\n\n| Category | Key operators | Purpose |\n| --- | --- | --- |\n| Creation | `Just`, `FromSlice`, `FromChannel`, `Range`, `Interval`, `Defer`, `Future` | Create observables from various sources |\n| Transform | `Map`, `MapErr`, `FlatMap`, `Scan`, `Reduce`, `GroupBy` | Transform or accumulate stream values |\n| Filter | `Filter`, `Take`, `TakeLast`, `Skip`, `Distinct`, `Find`, `First`, `Last` | Selectively emit values |\n| Combine | `Merge`, `Concat`, `Zip2`–`Zip6`, `CombineLatest2`–`CombineLatest5`, `Race` | Merge multiple observables |\n| Error | `Catch`, `OnErrorReturn`, `OnErrorResumeNextWith`, `Retry`, `RetryWithConfig` | Recover from errors |\n| Timing | `Delay`, `DelayEach`, `Timeout`, `ThrottleTime`, `SampleTime`, `BufferWithTime` | Control emission timing |\n| Side effect | `Tap`\u002F`Do`, `TapOnNext`, `TapOnError`, `TapOnComplete` | Observe without altering stream |\n| Terminal | `Collect`, `ToSlice`, `ToChannel`, `ToMap` | Consume stream into Go types |\n\nUse typed `Pipe2`, `Pipe3` ... `Pipe25` for compile-time type safety across operator chains. The untyped `Pipe` uses `any` and loses type checking.\n\nFor the complete operator catalog (150+ operators with signatures), see [Operators Guide](.\u002Freferences\u002Foperators-guide.md).\n\n## Common Mistakes\n\n| Mistake | Why it fails | Fix |\n| --- | --- | --- |\n| Using `ro.OnNext()` without error handler | Errors are silently dropped — bugs hide in production | Use `ro.NewObserver(onNext, onError, onComplete)` with all 3 callbacks |\n| Using untyped `Pipe()` instead of `Pipe2`\u002F`Pipe3` | Loses compile-time type safety, errors surface at runtime | Use `Pipe2`, `Pipe3`...`Pipe25` for typed operator chains |\n| Forgetting `.Unsubscribe()` on infinite streams | Goroutine leak — the observable runs forever | Use `TakeUntil(signal)`, context cancellation, or explicit `Unsubscribe()` |\n| Using `Share()` when cold is sufficient | Unnecessary complexity, harder to reason about lifecycle | Use hot observables only when multiple consumers need the same stream |\n| Using `samber\u002Fro` for finite slice transforms | Stream overhead (goroutines, subscriptions) for a synchronous operation | Use `samber\u002Flo` — it's simpler, faster, and purpose-built for slices |\n| Not propagating context for cancellation | Streams ignore shutdown signals, causing resource leaks on termination | Chain `ContextWithTimeout` or `ThrowOnContextCancel` in the pipeline |\n\n## Best Practices\n\n1. **Always handle all three events** — use `NewObserver(onNext, onError, onComplete)`, not just `OnNext`. Unhandled errors cause silent data loss\n2. **Use `Collect()` for synchronous consumption** — when the stream is finite and you need `[]T`, `Collect` blocks until complete and returns the slice + error\n3. **Prefer typed Pipe functions** — `Pipe2`, `Pipe3`...`Pipe25` catch type mismatches at compile time. Reserve untyped `Pipe` for dynamic operator chains\n4. **Bound infinite streams** — use `Take(n)`, `TakeUntil(signal)`, `Timeout(d)`, or context cancellation. Unbounded streams leak goroutines\n5. **Use `Tap`\u002F`Do` for observability** — log, trace, or meter emissions without altering the stream. Chain `TapOnError` for error monitoring\n6. **Prefer `samber\u002Flo` for simple transforms** — if the data is a finite slice and you need Map\u002FFilter\u002FReduce, use `lo`. Reach for `ro` when data arrives over time, from multiple sources, or needs retry\u002Ftimeout\u002Fbackpressure\n\n## Plugin Ecosystem\n\n40+ plugins extend ro with domain-specific operators:\n\n| Category | Plugins | Import path prefix |\n| --- | --- | --- |\n| Encoding | JSON, CSV, Base64, Gob | `plugins\u002Fencoding\u002F...` |\n| Network | HTTP, I\u002FO, FSNotify | `plugins\u002Fhttp`, `plugins\u002Fio`, `plugins\u002Ffsnotify` |\n| Scheduling | Cron, ICS | `plugins\u002Fcron`, `plugins\u002Fics` |\n| Observability | Zap, Slog, Zerolog, Logrus, Sentry, Oops | `plugins\u002Fobservability\u002F...`, `plugins\u002Fsamber\u002Foops` |\n| Rate limiting | Native, Ulule | `plugins\u002Fratelimit\u002F...` |\n| Data | Bytes, Strings, Sort, Strconv, Regexp, Template | `plugins\u002Fbytes`, `plugins\u002Fstrings`, etc. |\n| System | Process, Signal | `plugins\u002Fproc`, `plugins\u002Fsignal` |\n\nFor the full plugin catalog with import paths and usage examples, see [Plugin Ecosystem](.\u002Freferences\u002Fplugin-ecosystem.md).\n\nFor real-world reactive patterns (retry+timeout, WebSocket fan-out, graceful shutdown, stream combination), see [Patterns](.\u002Freferences\u002Fpatterns.md).\n\nIf you encounter a bug or unexpected behavior in samber\u002Fro, open an issue at [github.com\u002Fsamber\u002Fro\u002Fissues](https:\u002F\u002Fgithub.com\u002Fsamber\u002Fro\u002Fissues).\n\n## Cross-References\n\n- → See `samber\u002Fcc-skills-golang@golang-samber-lo` skill for finite slice transforms (Map, Filter, Reduce, GroupBy) — use lo when data is already in a slice\n- → See `samber\u002Fcc-skills-golang@golang-samber-mo` skill for monadic types (Option, Result, Either) that compose with ro pipelines\n- → See `samber\u002Fcc-skills-golang@golang-samber-hot` skill for in-memory caching (also available as an ro plugin)\n- → See `samber\u002Fcc-skills-golang@golang-concurrency` skill for goroutine\u002Fchannel patterns when reactive streams are overkill\n- → See `samber\u002Fcc-skills-golang@golang-observability` skill for monitoring reactive pipelines in production\n","**Persona:** You are a Go engineer who reaches for reactive streams when data flows asynchronously or infinitely. You use samber\u002Fro to build declarative pipelines instead of manual goroutine\u002Fchannel wiring, but you know when a simple slice + samber\u002Flo is enough.\n\n**Thinking mode:** Use `ultrathink` when designing advanced reactive pipelines or choosing between cold\u002Fhot observables, subjects, and combining operators. Wrong architecture leads to resource leaks or missed events.\n\n# samber\u002Fro — Reactive Streams for Go\n\nGo implementation of [ReactiveX](https:\u002F\u002Freactivex.io\u002F). Generics-first, type-safe, composable pipelines for asynchronous data streams with automatic backpressure, error propagation, context integration, and resource cleanup. 150+ operators, 5 subject types, 40+ plugins.\n\n**Official Resources:**\n\n- [github.com\u002Fsamber\u002Fro](https:\u002F\u002Fgithub.com\u002Fsamber\u002Fro)\n- [ro.samber.dev](https:\u002F\u002Fro.samber.dev)\n- [pkg.go.dev\u002Fgithub.com\u002Fsamber\u002Fro](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fsamber\u002Fro)\n\nThis skill is not exhaustive. Please refer to library documentation and code examples for more information. Context7 can help as a discoverability platform.\n\n## Why samber\u002Fro (Streams vs Slices)\n\nGo channels + goroutines become unwieldy for complex async pipelines: manual channel closures, verbose goroutine lifecycle, error propagation across nested selects, and no composable operators. `samber\u002Fro` solves this with declarative, chainable stream operators.\n\n**When to use which tool:**\n\n| Scenario | Tool | Why |\n| --- | --- | --- |\n| Transform a slice (map, filter, reduce) | `samber\u002Flo` | Finite, synchronous, eager — no stream overhead needed |\n| Simple goroutine fan-out with error handling | `errgroup` | Standard lib, lightweight, sufficient for bounded concurrency |\n| Infinite event stream (WebSocket, tickers, file watcher) | `samber\u002Fro` | Declarative pipeline with backpressure, retry, timeout, combine |\n| Real-time data enrichment from multiple async sources | `samber\u002Fro` | CombineLatest\u002FZip compose dependent streams without manual select |\n| Pub\u002Fsub with multiple consumers sharing one source | `samber\u002Fro` | Hot observables (Share\u002FSubjects) handle multicast natively |\n\n**Key differences: lo vs ro**\n\n| Aspect | `samber\u002Flo` | `samber\u002Fro` |\n| --- | --- | --- |\n| Data | Finite slices | Infinite streams |\n| Execution | Synchronous, blocking | Asynchronous, non-blocking |\n| Evaluation | Eager (allocates intermediate slices) | Lazy (processes items as they arrive) |\n| Timing | Immediate | Time-aware (delay, throttle, interval, timeout) |\n| Error model | Return `(T, error)` per call | Error channel propagates through pipeline |\n| Use case | Collection transforms | Event-driven, real-time, async pipelines |\n\n## Installation\n\n```bash\ngo get github.com\u002Fsamber\u002Fro\n```\n\n## Core Concepts\n\nFour building blocks:\n\n1. **Observable** — a data source that emits values over time. Cold by default: each subscriber triggers independent execution from scratch\n2. **Observer** — a consumer with three callbacks: `onNext(T)`, `onError(error)`, `onComplete()`\n3. **Operator** — a function that transforms an observable into another observable, chained via `Pipe`\n4. **Subscription** — the connection between observable and observer. Call `.Wait()` to block or `.Unsubscribe()` to cancel\n\n```go\nobservable := ro.Pipe2(\n    ro.RangeWithInterval(0, 5, 1*time.Second),\n    ro.Filter(func(x int) bool { return x%2 == 0 }),\n    ro.Map(func(x int) string { return fmt.Sprintf(\"even-%d\", x) }),\n)\n\nobservable.Subscribe(ro.NewObserver(\n    func(s string) { fmt.Println(s) },      \u002F\u002F onNext\n    func(err error) { log.Println(err) },    \u002F\u002F onError\n    func() { fmt.Println(\"Done!\") },         \u002F\u002F onComplete\n))\n\u002F\u002F Output: \"even-0\", \"even-2\", \"even-4\", \"Done!\"\n\n\u002F\u002F Or collect synchronously:\nvalues, err := ro.Collect(observable)\n```\n\n## Cold vs Hot Observables\n\n**Cold** (default): each `.Subscribe()` starts a new independent execution. Safe and predictable — use by default.\n\n**Hot**: multiple subscribers share a single execution. Use when the source is expensive (WebSocket, DB poll) or subscribers must see the same events.\n\n| Convert with | Behavior |\n| --- | --- |\n| `Share()` | Cold → hot with reference counting. Last unsubscribe tears down |\n| `ShareReplay(n)` | Same as Share + buffers last N values for late subscribers |\n| `Connectable()` | Cold → hot, but waits for explicit `.Connect()` call |\n| Subjects | Natively hot — call `.Send()`, `.Error()`, `.Complete()` directly |\n\n| Subject | Constructor | Replay behavior |\n| --- | --- | --- |\n| `PublishSubject` | `NewPublishSubject[T]()` | None — late subscribers miss past events |\n| `BehaviorSubject` | `NewBehaviorSubject[T](initial)` | Replays last value to new subscribers |\n| `ReplaySubject` | `NewReplaySubject[T](bufferSize)` | Replays last N values |\n| `AsyncSubject` | `NewAsyncSubject[T]()` | Emits only last value, only on complete |\n| `UnicastSubject` | `NewUnicastSubject[T](bufferSize)` | Single subscriber only |\n\nFor subject details and hot observable patterns, see [Subjects Guide](.\u002Freferences\u002Fsubjects-guide.md).\n\n## Operator Quick Reference\n\n| Category | Key operators | Purpose |\n| --- | --- | --- |\n| Creation | `Just`, `FromSlice`, `FromChannel`, `Range`, `Interval`, `Defer`, `Future` | Create observables from various sources |\n| Transform | `Map`, `MapErr`, `FlatMap`, `Scan`, `Reduce`, `GroupBy` | Transform or accumulate stream values |\n| Filter | `Filter`, `Take`, `TakeLast`, `Skip`, `Distinct`, `Find`, `First`, `Last` | Selectively emit values |\n| Combine | `Merge`, `Concat`, `Zip2`–`Zip6`, `CombineLatest2`–`CombineLatest5`, `Race` | Merge multiple observables |\n| Error | `Catch`, `OnErrorReturn`, `OnErrorResumeNextWith`, `Retry`, `RetryWithConfig` | Recover from errors |\n| Timing | `Delay`, `DelayEach`, `Timeout`, `ThrottleTime`, `SampleTime`, `BufferWithTime` | Control emission timing |\n| Side effect | `Tap`\u002F`Do`, `TapOnNext`, `TapOnError`, `TapOnComplete` | Observe without altering stream |\n| Terminal | `Collect`, `ToSlice`, `ToChannel`, `ToMap` | Consume stream into Go types |\n\nUse typed `Pipe2`, `Pipe3` ... `Pipe25` for compile-time type safety across operator chains. The untyped `Pipe` uses `any` and loses type checking.\n\nFor the complete operator catalog (150+ operators with signatures), see [Operators Guide](.\u002Freferences\u002Foperators-guide.md).\n\n## Common Mistakes\n\n| Mistake | Why it fails | Fix |\n| --- | --- | --- |\n| Using `ro.OnNext()` without error handler | Errors are silently dropped — bugs hide in production | Use `ro.NewObserver(onNext, onError, onComplete)` with all 3 callbacks |\n| Using untyped `Pipe()` instead of `Pipe2`\u002F`Pipe3` | Loses compile-time type safety, errors surface at runtime | Use `Pipe2`, `Pipe3`...`Pipe25` for typed operator chains |\n| Forgetting `.Unsubscribe()` on infinite streams | Goroutine leak — the observable runs forever | Use `TakeUntil(signal)`, context cancellation, or explicit `Unsubscribe()` |\n| Using `Share()` when cold is sufficient | Unnecessary complexity, harder to reason about lifecycle | Use hot observables only when multiple consumers need the same stream |\n| Using `samber\u002Fro` for finite slice transforms | Stream overhead (goroutines, subscriptions) for a synchronous operation | Use `samber\u002Flo` — it's simpler, faster, and purpose-built for slices |\n| Not propagating context for cancellation | Streams ignore shutdown signals, causing resource leaks on termination | Chain `ContextWithTimeout` or `ThrowOnContextCancel` in the pipeline |\n\n## Best Practices\n\n1. **Always handle all three events** — use `NewObserver(onNext, onError, onComplete)`, not just `OnNext`. Unhandled errors cause silent data loss\n2. **Use `Collect()` for synchronous consumption** — when the stream is finite and you need `[]T`, `Collect` blocks until complete and returns the slice + error\n3. **Prefer typed Pipe functions** — `Pipe2`, `Pipe3`...`Pipe25` catch type mismatches at compile time. Reserve untyped `Pipe` for dynamic operator chains\n4. **Bound infinite streams** — use `Take(n)`, `TakeUntil(signal)`, `Timeout(d)`, or context cancellation. Unbounded streams leak goroutines\n5. **Use `Tap`\u002F`Do` for observability** — log, trace, or meter emissions without altering the stream. Chain `TapOnError` for error monitoring\n6. **Prefer `samber\u002Flo` for simple transforms** — if the data is a finite slice and you need Map\u002FFilter\u002FReduce, use `lo`. Reach for `ro` when data arrives over time, from multiple sources, or needs retry\u002Ftimeout\u002Fbackpressure\n\n## Plugin Ecosystem\n\n40+ plugins extend ro with domain-specific operators:\n\n| Category | Plugins | Import path prefix |\n| --- | --- | --- |\n| Encoding | JSON, CSV, Base64, Gob | `plugins\u002Fencoding\u002F...` |\n| Network | HTTP, I\u002FO, FSNotify | `plugins\u002Fhttp`, `plugins\u002Fio`, `plugins\u002Ffsnotify` |\n| Scheduling | Cron, ICS | `plugins\u002Fcron`, `plugins\u002Fics` |\n| Observability | Zap, Slog, Zerolog, Logrus, Sentry, Oops | `plugins\u002Fobservability\u002F...`, `plugins\u002Fsamber\u002Foops` |\n| Rate limiting | Native, Ulule | `plugins\u002Fratelimit\u002F...` |\n| Data | Bytes, Strings, Sort, Strconv, Regexp, Template | `plugins\u002Fbytes`, `plugins\u002Fstrings`, etc. |\n| System | Process, Signal | `plugins\u002Fproc`, `plugins\u002Fsignal` |\n\nFor the full plugin catalog with import paths and usage examples, see [Plugin Ecosystem](.\u002Freferences\u002Fplugin-ecosystem.md).\n\nFor real-world reactive patterns (retry+timeout, WebSocket fan-out, graceful shutdown, stream combination), see [Patterns](.\u002Freferences\u002Fpatterns.md).\n\nIf you encounter a bug or unexpected behavior in samber\u002Fro, open an issue at [github.com\u002Fsamber\u002Fro\u002Fissues](https:\u002F\u002Fgithub.com\u002Fsamber\u002Fro\u002Fissues).\n\n## Cross-References\n\n- → See `samber\u002Fcc-skills-golang@golang-samber-lo` skill for finite slice transforms (Map, Filter, Reduce, GroupBy) — use lo when data is already in a slice\n- → See `samber\u002Fcc-skills-golang@golang-samber-mo` skill for monadic types (Option, Result, Either) that compose with ro pipelines\n- → See `samber\u002Fcc-skills-golang@golang-samber-hot` skill for in-memory caching (also available as an ro plugin)\n- → See `samber\u002Fcc-skills-golang@golang-concurrency` skill for goroutine\u002Fchannel patterns when reactive streams are overkill\n- → See `samber\u002Fcc-skills-golang@golang-observability` skill for monitoring reactive pipelines in production\n",{"name":5,"license":15,"metadata":54,"description":7,"allowed-tools":57,"compatibility":58,"user-invocable":50},{"author":55,"version":56},"samber","1.0.3","Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent mcp__context7__resolve-library-id mcp__context7__query-docs AskUserQuestion","Designed for Claude Code or similar AI coding agents, and for projects using Golang.","master","b4819add93efbaf4d80627118ec34680406b309b","packages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro",1,"https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats","https:\u002F\u002Fgithub.com\u002Fmuratovv","2026-11-05 20:59:10",{"source":8,"skillName":5,"commands":67,"prompt":77,"zipAvailable":78},[68,71,74],{"tool":69,"command":70},"npx","npx skills add muratovv\u002Fai-hats --skill golang-samber-ro",{"tool":72,"command":73},"bunx","bunx skills add muratovv\u002Fai-hats --skill golang-samber-ro",{"tool":75,"command":76},"pnpm","pnpm dlx skills add muratovv\u002Fai-hats --skill golang-samber-ro","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro\u002FSKILL.md",true,[80,86,91,95,99,103,107],{"path":81,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":84,"sourceHtmlUrl":85},"evals\u002Fevals.json","REFERENCE","参考文档",16569,"https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro\u002Fevals\u002Fevals.json",{"path":87,"resourceType":87,"resourceTypeDesc":88,"sizeBytes":89,"sourceHtmlUrl":90},"LICENSE","许可证",1070,"https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro\u002FLICENSE",{"path":92,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":93,"sourceHtmlUrl":94},"metadata.yaml",654,"https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro\u002Fmetadata.yaml",{"path":96,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":97,"sourceHtmlUrl":98},"references\u002Foperators-guide.md",14184,"https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro\u002Freferences\u002Foperators-guide.md",{"path":100,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":101,"sourceHtmlUrl":102},"references\u002Fpatterns.md",7312,"https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro\u002Freferences\u002Fpatterns.md",{"path":104,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":105,"sourceHtmlUrl":106},"references\u002Fplugin-ecosystem.md",6307,"https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro\u002Freferences\u002Fplugin-ecosystem.md",{"path":108,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":109,"sourceHtmlUrl":110},"references\u002Fsubjects-guide.md",5836,"https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fusage\u002Fskills\u002Fgolang-samber-ro\u002Freferences\u002Fsubjects-guide.md",[112,138,162,181,205,219],{"skillNo":113,"name":114,"nameZh":6,"description":115,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":118,"publishedAt":49},"01M6PVFB1SM738R2SRSRSF7CY6","tool-evaluation-protocol","Time-bounded protocol for evaluating new tools, libraries, or methodologies before adoption. Use when evaluating a candidate dependency for the project, researching a methodology (e.g. ML\u002FLLM frameworks, testing approaches), or following up on a hype-driven recommendation.","https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fexperimental\u002Fusage\u002Fskills\u002Ftool-evaluation-protocol\u002FSKILL.md",[],[119,120,121,122,123,124,125,126,127,128,129,130,131,132,40,133,134,135,136,137],"protocol","Evaluation","tool","tool evaluation protocol","testing","ml","libraries","adoption","methodology","Tools","use","dependency","up","frameworks","project","recommendation","for","bounded","candidate",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":144,"publishedAt":49},"01M6PVF7HATBEX1G7N50E2QT57","systematic-debugging","4-phase bug-fix protocol (evidence, pattern, hypothesis, verify). Use when investigating any error, failure, or unexpected behavior, handling bug reports from users or monitoring, or diagnosing test failures with non-obvious causes.","https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fexperimental\u002Fusage\u002Fskills\u002Fsystematic-debugging\u002FSKILL.md",[],[145,146,147,148,119,149,150,151,152,153,129,154,155,156,157,158,37,159,160,161],"systematic debugging","debugging","systematic","test","monitoring","hypothesis","verify","behavior","fix","evidence","bug","reports","pattern","users","with","bug-fix","phase",{"skillNo":163,"name":164,"nameZh":6,"description":165,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":166,"categories":167,"keywords":169,"publishedAt":49},"01M6PVF3MTQN3RPF73AN34856J","skill-template","Canonical template and validation guide for ai-hats skills. Use when creating a new skill, reviewing an existing one for structural compliance, or deciding which pattern fits a new behavior.","https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fexperimental\u002Fusage\u002Fskills\u002Fskill-template\u002FSKILL.md",[168],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[170,171,172,173,174,152,175,129,176,157,177,178,179,135,180],"template","skill template","validation","compliance","hats","guide","new skill","structural","canonical","which","Existing",{"skillNo":182,"name":183,"nameZh":6,"description":184,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":185,"categories":186,"keywords":188,"publishedAt":49},"01M6PVF06SCV28QARM5MQPANC9","skill-optimization","Audit and refactor library components to eliminate redundancy and staleness. Use during periodic library maintenance, after adding multiple new skills or rules, when a role's token budget is too high, or after retrospectives identify component issues.","https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fexperimental\u002Fusage\u002Fskills\u002Fskill-optimization\u002FSKILL.md",[187],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[189,190,191,192,193,194,195,196,197,198,129,199,200,201,202,203,204],"Optimization","skill optimization","components","component","issues","library","audit","refactor","Budget","Rules","periodic","maintenance","token","token budget","role","high",{"skillNo":206,"name":207,"nameZh":6,"description":208,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":209,"categories":210,"keywords":211,"publishedAt":49},"01M6PVEXM9717016T9MW82HDCT","silent-fallback-gate","PreToolUse hook — refuses an Edit or Write that adds an inert broad except. Use when a Python edit was blocked for a silent fallback.","https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fexperimental\u002Fusage\u002Fskills\u002Fsilent-fallback-gate\u002FSKILL.md",[],[212,213,214,215,216,217,129,218,135],"gate","fallback","silent fallback gate","python","write","edit","hook",{"skillNo":220,"name":221,"nameZh":6,"description":222,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":223,"categories":224,"keywords":226,"publishedAt":49},"01M6PVESM49C5NT7SB7N3F76VS","retro-to-framework","Convert an observation about agent behavior — from a retrospective or from a single incident — into a framework-level change (hook, rule, skill, skill update). Use after a retrospective identifies problems that are not project-specific, after an incident where an agent misapplied a component it had read, when CLAUDE.md band-aids accumulate (more than 3 per-project rules that could be generic), or when the same problem recurs across multiple projects.","https:\u002F\u002Fgithub.com\u002Fmuratovv\u002Fai-hats\u002Fblob\u002Fmaster\u002Fpackages\u002Fai-hats-library\u002Fsrc\u002Fai_hats_library\u002Fexperimental\u002Fusage\u002Fskills\u002Fretro-to-framework\u002FSKILL.md",[225],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[227,228,229,230,192,231,43,232,198,152,129,233,234,133,235,236,237,238,239,240],"framework","retro","retro to framework","change","retrospective","convert","incident","across","problem","about","more","skill update","single","generic"]