Vercel Composition Patterns
supabase/supabase
React composition patterns that scale. An agent skill from supabase/supabase.
Testing streaming io buffers with gbytes — gbytes.NewBuffer() (an io.Writer also returned by gexec sessions), the Say(regexp) matcher that forward-scans from a moving read cursor, the canonical…
$ npx skills add onsi/gomega --skill gbytes -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install onsi/gomega gbytes --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/onsi/gomega.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/gomega/skills/gbytes .claude/skills/gbytes && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "gbytes" agent skill from https://github.com/onsi/gomega/tree/master/plugins/gomega/skills/gbytes into .claude/skills/gbytes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gbytes", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/onsi/gomega/tree/master/plugins/gomega/skills/gbytesType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add onsi/gomega --skill gbytes -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install onsi/gomega gbytes --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/onsi/gomega.git skills-src && mkdir -p .agents/skills && cp -r skills-src/plugins/gomega/skills/gbytes .agents/skills/gbytes && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "gbytes" agent skill from https://github.com/onsi/gomega/tree/master/plugins/gomega/skills/gbytes into .agents/skills/gbytes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gbytes", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add onsi/gomega --skill gbytes -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install onsi/gomega gbytes --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/onsi/gomega.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/plugins/gomega/skills/gbytes .cursor/skills/gbytes && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "gbytes" agent skill from https://github.com/onsi/gomega/tree/master/plugins/gomega/skills/gbytes into .cursor/skills/gbytes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gbytes", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/onsi/gomega.git --path plugins/gomega/skills/gbytes--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add onsi/gomega --skill gbytes -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install onsi/gomega gbytes --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/onsi/gomega.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/plugins/gomega/skills/gbytes .gemini/skills/gbytes && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "gbytes" agent skill from https://github.com/onsi/gomega/tree/master/plugins/gomega/skills/gbytes into .gemini/skills/gbytes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gbytes", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install onsi/gomega gbytesInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add onsi/gomega --skill gbytes -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/onsi/gomega.git skills-src && mkdir -p .github/skills && cp -r skills-src/plugins/gomega/skills/gbytes .github/skills/gbytes && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "gbytes" agent skill from https://github.com/onsi/gomega/tree/master/plugins/gomega/skills/gbytes into .github/skills/gbytes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gbytes", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add onsi/gomega --skill gbytes -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install onsi/gomega gbytes --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/onsi/gomega.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/plugins/gomega/skills/gbytes .opencode/skills/gbytes && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "gbytes" agent skill from https://github.com/onsi/gomega/tree/master/plugins/gomega/skills/gbytes into .opencode/skills/gbytes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gbytes", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
gbytesTesting streaming io buffers with gbytes — gbytes.NewBuffer() (an io.Writer also returned by gexec sessions), the Say(regexp) matcher that forward-scans from a moving read cursor, the canonical…
Gbytes is an agent skill from onsi/gomega. Testing streaming io buffers with gbytes — gbytes.NewBuffer() (an io.Writer also returned by gexec sessions), the Say(regexp) matcher that forward-scans from a moving read cursor, the canonical Eventually(buffer).Should(Say(...)) streaming pattern, sequential cursor-advancing Say calls, Contents(), BufferWithBytes/BufferReader, buffer.Detect for branching, and TimeoutReader/Writer/Closer for testing blocking io.Reader/Writer/Closer. Use when asserting on streaming or incremental output (process stdout/stderr, API…
Its SKILL.md is about 1.5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development. The repository describes itself as: Ginkgo's Preferred Matcher Library. The licence is MIT.
Read from SKILL.md and the folder at commit 37fa900. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are go).
From the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
onsi.github.ioFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Gbytes loads about 1.5k tokens when it runs. Until then it costs about 144 tokens; SKILL.md has 517 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from onsi/gomega at commit 37fa900, republished under its MIT licence (© onsi). 517 words, ~1,495 tokens.
.claude/skills/gbytes/SKILL.md (or your agent's skills folder).gbytes provides *gbytes.Buffer, an in-memory io.Writer (and io.Reader/io.Closer) that captures everything written to it, plus the Say matcher for making ordered assertions against streaming data as it arrives. Pairs naturally with gomega:async (poll with Eventually) and gomega:gexec (a session's .Out/.Err are *gbytes.Buffers, and the session itself is a BufferProvider). Docs: https://onsi.github.io/gomega/#gbytes-testing-streaming-buffers.
import (
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
)gbytes.NewBuffer() returns an empty *gbytes.Buffer. Hand it to anything that wants an io.Writer and it accumulates the bytes:
buffer := gbytes.NewBuffer()
go client.AttachToDataStream(buffer) // client writes to buffer concurrentlygbytes.BufferWithBytes(b []byte) — seed a buffer with already-captured bytes.buffer.Contents() []byte — all bytes ever written, regardless of cursor position. Use this for whole-buffer assertions (Expect(buffer.Contents()).To(ContainSubstring(...))).buffer.Close() / buffer.Closed() — mark a buffer done. Writes to a closed buffer error. A closed buffer tells Eventually to give up (see below).Say matchergbytes.Say(pattern, args...) takes a regular expression (optionally fmt.Sprintf-formatted with args) and matches against the buffer's unread portion:
Expect(buffer).To(gbytes.Say(`hello \w+`))Say is cursor-based, not whole-buffer. Each buffer carries an opaque read cursor you cannot access. When Say matches, it fast-forwards the cursor to just past the match. The next Say only sees bytes after that point. This is what makes ordered assertions work — and the gotcha below.
Eventually + SayStreaming output arrives over time, so poll the buffer with Eventually (gomega:async). Each successful Say advances the cursor, so successive Says assert on successive output in order:
Eventually(buffer).Should(gbytes.Say(`Attached as client \d+`))
client.ReticulateSplines()
Eventually(buffer).Should(gbytes.Say(`reticulating splines`))
client.EncabulateRetros(7)
Eventually(buffer).Should(gbytes.Say(`encabulating 7 retros`))Because the cursor only moves forward, this counts repeats correctly — these two assertions pass only if reticulating splines appears twice:
client.ReticulateSplines()
Eventually(buffer).Should(gbytes.Say(`reticulating splines`))
client.ReticulateSplines()
Eventually(buffer).Should(gbytes.Say(`reticulating splines`))And consequently this (counterintuitively) passes — the first Say consumed the match:
Eventually(buffer).Should(gbytes.Say(`reticulating splines`))
Consistently(buffer).ShouldNot(gbytes.Say(`reticulating splines`))Say works on a *gbytes.Buffer or any BufferProvider (anything with a Buffer() *gbytes.Buffer method, e.g. a gexec.Session), so Eventually(session).Should(gbytes.Say(...)) works directly.
When the test must react to whichever output arrives, use buffer.Detect(regexp, args...), which returns a channel that fires once on match (and fast-forwards the cursor). Always CancelDetects() to clean up the spawned goroutines:
client.Authorize()
select {
case <-buffer.Detect("You are not logged in"):
client.Login()
case <-buffer.Detect("Success"):
// carry on
case <-time.After(time.Second):
Fail("timed out waiting for output")
}
buffer.CancelDetects()io.Reader/io.Writer/io.CloserThese interfaces are expected to block, so calling Read/Write/Close directly in a test risks hanging forever. Wrap them with timeouts; the wrappers return gbytes.ErrTimeout if the operation doesn't complete in time:
p := make([]byte, 5)
_, err := gbytes.TimeoutReader(reader, time.Second).Read(p)
Expect(err).NotTo(HaveOccurred())gbytes.TimeoutReader, gbytes.TimeoutWriter, and gbytes.TimeoutCloser each wrap the matching interface. To use Say against an io.Reader, wrap it with gbytes.BufferReader(reader) — it launches an io.Copy goroutine into a fresh buffer (closed when the copy completes). Because the copy is async you must use Eventually:
Eventually(gbytes.BufferReader(reader)).Should(gbytes.Say("abcde"))(, ), ., [, +, ?, \d, etc. are regex syntax. To match a literal splines (v2) write gbytes.Say(splines (v2)). The pattern is compiled with regexp.MustCompile, so a bad pattern panics.Say already consumed. If you need to assert on the whole buffer, use buffer.Contents() with a string matcher (gomega:matchers) instead of Say.Say with Eventually for live streams; use plain Expect only on an already-complete buffer. A bare Expect(buffer).To(Say(...)) checks the buffer once, right now — it will flake if the data hasn't arrived yet.Eventually early. Once Close() is called, a pending Say can never succeed on new data, so the matcher signals Eventually/Consistently to stop polling and fail immediately rather than wait out the timeout.© onsi, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in plugins/gomega/skills/gbytes of onsi/gomega.
Open the folder on GitHubat commit 37fa900
Gbytes next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Gbytes this skillonsi/gomega | 2.4k | — | ~1.5k | Automated safety check: Pass | MIT | |
| Vercel Composition Patternssupabase/supabase | 111k | 59 repos | ~726 | Automated safety check: Pass | MIT | |
| Finishing a Development Branchobra/superpowers | 296k | 5 repos | ~1.9k | Automated safety check: Pass | MIT | |
| Typescript Advanced Typesrolling-scopes/rsschool-app | 10k | 25 repos | ~4.2k | Automated safety check: Pass | MPL-2.0 | |
| PR Babysitteropeninterpreter/openinterpreter | 69k | 3 repos | ~4.2k | Automated safety check: Pass | Apache-2.0 | |
| Code Review ChecklistshareAI-lab/learn-claude-code | 78k | 5 repos | ~1.1k | Automated safety check: Pass | MIT |
supabase/supabase
React composition patterns that scale. An agent skill from supabase/supabase.
obra/superpowers
Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.
rolling-scopes/rsschool-app
Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications.
openinterpreter/openinterpreter
Watches an open GitHub pull request until it merges, handling review comments, diagnosing CI failures and retrying flaky checks along the way.
shareAI-lab/learn-claude-code
Reviews code against a five-part checklist covering security, correctness, performance, maintainability and testing, and reports findings in a fixed format.
onyx-dot-app/onyx
Iteratively improves a PR (GitHub), MR (GitLab), or shelved changelist (Perforce) until Greptile gives it a 5/5 confidence score with zero unresolved comments.
onsi/gomega
Write correct synchronous Gomega assertions — Expect/Ω notation, the To/NotTo/ToNot/Should/ShouldNot equivalences, the multi-return error idiom, Succeed vs HaveOccurred, the .Error() chaining form…
onsi/gomega
Polling assertions in Gomega — Eventually (poll until it passes) and Consistently (must keep passing), the func(g Gomega) callback idiom, WithTimeout/WithPolling/Within/ProbeEvery, WithContext and…
onsi/gomega
Build compound Gomega assertions by combining matchers — And/SatisfyAll (all pass), Or/SatisfyAny (any pass), Not (negate), WithTransform to map the actual before matching, Satisfy for an ad-hoc…
onsi/gomega
Writing your own Gomega matchers — the GomegaMatcher interface (Match/FailureMessage/NegatedFailureMessage), gcustom.MakeMatcher with message templates and template data, the format package helpers…
onsi/gomega
Testing external processes with gexec — compile binaries with Build/BuildWithEnvironment/BuildIn and CleanupBuildArtifacts, start them with Start returning a Session, await exit with the Exit…
onsi/gomega
The ghttp test HTTP server for testing HTTP clients — NewServer/NewTLSServer, AppendHandlers, the Verify assertions (VerifyRequest/VerifyHeader/VerifyHeaderKV/VerifyJSON/VerifyForm/VerifyBasicAuth/Ve…
Categories
Testing streaming io buffers with gbytes — gbytes.NewBuffer() (an io.Writer also returned by gexec sessions), the Say(regexp) matcher that forward-scans from a moving read cursor, the canonical…. Gbytes is an agent skill from onsi/gomega.Reader/Writer/Closer.
Gbytes fits situations like: asserting on streaming; incremental output (process stdout/stderr; io.Readers) rather than a complete value.
Run `npx skills add onsi/gomega --skill gbytes -a claude-code`. Or copy the skill folder (plugins/gomega/skills/gbytes in onsi/gomega) into .claude/skills/gbytes in your project. Claude Code loads it when a task matches its description.
Run `npx skills add onsi/gomega --skill gbytes -a codex`. Or copy the skill folder (plugins/gomega/skills/gbytes in onsi/gomega) into .agents/skills/gbytes in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add onsi/gomega --skill gbytes -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/gbytes, .gemini/skills/gbytes, .github/skills/gbytes and .opencode/skills/gbytes in your project.
SKILL.md names no scripts, command-line tools or credentials: Gbytes is instructions for the agent only.
SKILL.md names 1 domain. As links in the text: onsi.github.io. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Gbytes is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 1.5k tokens (SKILL.md is roughly 6k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Gbytes: Vercel Composition Patterns (supabase/supabase, 111k stars), Finishing a Development Branch (obra/superpowers, 296k stars), Typescript Advanced Types (rolling-scopes/rsschool-app, 10k stars) and PR Babysitter (openinterpreter/openinterpreter, 69k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
onsi (a GitHub user) maintains it in onsi/gomega, which has 2,357 GitHub stars. The repository holds 12 skills in this directory. The repository was last updated on September 24, 2026.
Source: onsi/gomega on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.