Saleor Port Changes
saleor/saleor
Forward-ports or backports a single PR or branch onto the currently checked-out Saleor branch, handling GraphQL version markers and migration numbering along the way.
Port a new ballerina/<name stdlib package from jBallerina to this Go-native interpreter.
$ npx skills add ballerina-nutcracker/ballerina --skill add-stdlib-support -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ballerina-nutcracker/ballerina add-stdlib-support --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/ballerina-nutcracker/ballerina.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/add-stdlib-support .claude/skills/add-stdlib-support && 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 "add-stdlib-support" agent skill from https://github.com/ballerina-nutcracker/ballerina/tree/main/.agents/skills/add-stdlib-support into .claude/skills/add-stdlib-support/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-stdlib-support", 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/ballerina-nutcracker/ballerina/tree/main/.agents/skills/add-stdlib-supportType 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 ballerina-nutcracker/ballerina --skill add-stdlib-support -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ballerina-nutcracker/ballerina add-stdlib-support --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ballerina-nutcracker/ballerina.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/add-stdlib-support .agents/skills/add-stdlib-support && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "add-stdlib-support" agent skill from https://github.com/ballerina-nutcracker/ballerina/tree/main/.agents/skills/add-stdlib-support into .agents/skills/add-stdlib-support/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-stdlib-support", 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 ballerina-nutcracker/ballerina --skill add-stdlib-support -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ballerina-nutcracker/ballerina add-stdlib-support --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ballerina-nutcracker/ballerina.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/add-stdlib-support .cursor/skills/add-stdlib-support && 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 "add-stdlib-support" agent skill from https://github.com/ballerina-nutcracker/ballerina/tree/main/.agents/skills/add-stdlib-support into .cursor/skills/add-stdlib-support/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-stdlib-support", 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/ballerina-nutcracker/ballerina.git --path .agents/skills/add-stdlib-support--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 ballerina-nutcracker/ballerina --skill add-stdlib-support -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ballerina-nutcracker/ballerina add-stdlib-support --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ballerina-nutcracker/ballerina.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/add-stdlib-support .gemini/skills/add-stdlib-support && 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 "add-stdlib-support" agent skill from https://github.com/ballerina-nutcracker/ballerina/tree/main/.agents/skills/add-stdlib-support into .gemini/skills/add-stdlib-support/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-stdlib-support", 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 ballerina-nutcracker/ballerina add-stdlib-supportInstalls 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 ballerina-nutcracker/ballerina --skill add-stdlib-support -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/ballerina-nutcracker/ballerina.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/add-stdlib-support .github/skills/add-stdlib-support && 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 "add-stdlib-support" agent skill from https://github.com/ballerina-nutcracker/ballerina/tree/main/.agents/skills/add-stdlib-support into .github/skills/add-stdlib-support/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-stdlib-support", 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 ballerina-nutcracker/ballerina --skill add-stdlib-support -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install ballerina-nutcracker/ballerina add-stdlib-support --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ballerina-nutcracker/ballerina.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/add-stdlib-support .opencode/skills/add-stdlib-support && 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 "add-stdlib-support" agent skill from https://github.com/ballerina-nutcracker/ballerina/tree/main/.agents/skills/add-stdlib-support into .opencode/skills/add-stdlib-support/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "add-stdlib-support", 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.
add-stdlib-supportPort a new ballerina/<name stdlib package from jBallerina to this Go-native interpreter.
Add Stdlib Support is an agent skill from ballerina-nutcracker/ballerina. Port a new ballerina/<name stdlib package from jBallerina to this Go-native interpreter. Use when the user asks to migrate, port, or add a Ballerina standard library module that does not yet exist under lib/stdlibs/ballerina/. For filling gaps in an existing stdlib, use fill-stdlib-gap instead.
Its SKILL.md is about 6.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including reference files (for example `references/native-state.md`, `references/pal.md` and `references/parity-risks.md`).
The repository describes itself as: Native Ballerina Interpreter. The licence is Apache-2.0.
10 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 0cefa3f. 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.
Shell commands in SKILL.md call:
gomakegitFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.
From 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.
Add Stdlib Support loads about 6.3k tokens when it runs, and up to ~8.8k if it reads all its reference files. Until then it costs about 80 tokens; SKILL.md has 3,095 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 ballerina-nutcracker/ballerina at commit 0cefa3f, republished under its Apache-2.0 licence (© ballerina-nutcracker). 3,095 words, ~6,325 tokens.
.claude/skills/add-stdlib-support/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.End-to-end workflow for porting a ballerina/<name> package from jBallerina (Java) into this repo. Follow the steps in order; do not skip the gates.
| Step | Purpose | Gate |
|---|---|---|
| 1 | Acquire the jBallerina reference | blocked until user provides the path |
| 2 | Resolve imports, check existing stdlib coverage | — |
| 3 | Cross-check language support | — |
| 4 | Propose plan + showcase .bal | user approval required |
| 5 | Behavioural parity analysis | parity table required |
| 6 | Evaluate Go libraries (if any) | user approval before touching go.mod |
| 7 | Implement | — |
| 8 | Tests + coverage | subset choice needs user confirmation |
| 9 | README + docs | — |
| 10 | Verify | full checklist, incl. validate-stdlib-contract PASS |
All coding rules and the PAL constraint live in AGENTS.md at the repo root — read it before implementing. This skill encodes the process, not the rules. Supporting files in this skill's directory (templates/, references/) hold the manifest/source templates and shared patterns — read each one when its step tells you to.
Golden rule: two things must hold when this port is done — (1) the Ballerina public interface must stay identical to jBallerina's (never break customer code — see validate-stdlib-contract), and (2) if the jBallerina reference root ships a docs/spec/spec.md, its prose must exactly match the Go implementation's actual behaviour for every in-scope feature. A spec sentence describing behaviour the Go code doesn't have, or silent on a divergence the Go code does have, is a defect to resolve (by fixing the implementation to match intended design, or by recording the divergence) before the port is done — not something to leave unreconciled.
If the user wants to fix a gap in a stdlib that already exists under lib/stdlibs/ballerina/<name>/, use fill-stdlib-gap instead — this skill is heavyweight by design.
Ask the user for the path to the corresponding jBallerina library implementation root, e.g. ~/github/ballerina-platform/module-ballerina-<name>/. Do not proceed without it.
That root should contain:
ballerina/ — the Ballerina-side source (public API, type declarations, extern function signatures).native/ (optional) — the Java native implementation backing the extern functions. Pure-Ballerina libraries do not have this directory; that's fine, just note it.docs/spec/spec.md (optional) — the package's specification, if the jBallerina repo ships one. Prose written for humans; often states intent, edge-case handling, and constraints that neither .bal signatures nor Java code spell out. Read it alongside ballerina/ and native/, not as a substitute for either.Then:
.bal file under <root>/ballerina/, excluding tests/ and build/, to enumerate the full jBallerina feature set and identify which functions are external.<root>/native/ exists, read the Java sources backing those extern functions. This is the authoritative source of truth for runtime semantics — error wording, edge-case handling, parsing rules, numeric behaviour — and is what the Go natives must match for parity (see Step 5). Don't infer behaviour from .bal signatures alone when Java source is available.<root>/docs/spec/spec.md exists, read it in full and note every behavioural claim it makes for features in scope. Treat divergences between the spec and the Java/.bal source as a flag to raise with the user (Step 4), not something to silently resolve one way.Scan the jBallerina source for import ballerina/<X> statements.
<X> not already present under lib/stdlibs/ballerina/<X>/: tell the user that dependency must be implemented first. If they ask to continue anyway, narrow the plan to only features that don't depend on <X>.<X> already present: read lib/stdlibs/ballerina/<X>/0.0.1/go1.27/README.md and note every row whose status is Not Yet Supported, Partially Supported, or Cannot Support, plus anything under Notable Behavioural Changes. If our in-scope features depend on any of those gaps or divergences, surface them in the plan (Step 4) under a Dependency Limitations section.ballerina/jballerina.java.arrays will not get a Go equivalent. Plan to replace its uses with Go-native equivalents inside the native/ layer.Dependencies.toml — see templates/manifests.md for the format and why missing entries cause Unknown import: ballerina/<dep> at runtime..bal source imports a langlib (import ballerina/lang.<x>;), that import only resolves through the isLangImport switch in semantics/symbol_resolver.go — check the langlib in question is wired there before assuming it works.Do not silently drop features because of a missing import or inherited dependency gap — always flag and confirm.
If a dependency's README claims a feature is Supported but it actually diverges from its own documented behaviour — a bug, not a catalogued gap — that's separate from the check above: follow references/reporting-limitations.md.
Read AGENTS.md (root) in full, especially the Interpreter stages and Coding style sections. If a planned feature uses a construct known to fail in this interpreter (distinct error subtypes, readonly & intersections, stream type, XML, full typedesc parameter handling), drop or defer the feature and note it in the plan.
When the interpreter panics or emits compile errors that are not explained by AGENTS.md, stop and present the developer with these options — do not silently pick one:
Unexpected language limitation found:
<construct>is not supported (panic: <message>).Options:
- Fix the interpreter — implement this construct in the compiler/BIR pipeline. Requires a separate change.
- Work around in Ballerina — rewrite the Ballerina source to avoid the construct.
- Move to Go native — replace the Ballerina function body with
= externaland implement the logic innative/.- Scope out this feature — mark it
Not Yet Supportedin the README and move on.Which option do you prefer?
After the developer responds, apply the chosen resolution before continuing. Regardless of which option is chosen, this is a language limitation worth tracking upstream independently of the local workaround — draft an issue per references/reporting-limitations.md and point the developer to https://github.com/ballerina-nutcracker/ballerina/issues.
.bal file (GATE: wait for user approval)Produce both:
ballerina/<X> package we import (per Step 2)..bal file — a small program that exercises every feature in scope end-to-end. Use @output markers for expected output.Wait for the user to approve both the plan and the showcase file before touching any Go code.
The Go-native behaviour must match the jBallerina (JVM) behaviour for every supported feature. Users migrating from jBallerina must not observe breaking changes. Before writing any Go code, produce a parity table for each in-scope feature:
| Feature | Known Go/JVM divergence risk | Avoidable? | Resolution |
|---|---|---|---|
| ... | ... | ... | ... |
Read references/parity-risks.md for the hot-spots to investigate (decimal precision, UTF-8 vs UTF-16, error-message rules, numeric edge cases) plus a domain-specific example. Where a row's behaviour is verifiable by running code, verify it with the run-jballerina skill (bal run the probe on jBallerina, compare against this interpreter) rather than reasoning from documentation.
docs/spec/spec.md exists)Add a row to the parity table for every behavioural claim the spec makes about an in-scope feature, and verify the planned Go implementation will match it exactly — same edge-case handling, same defaults, same error conditions. A spec/implementation mismatch is treated the same as a spec/Java mismatch: raise it with the user rather than picking a side silently. This check is repeated against the actual implementation in Step 10 — Step 5 catches mismatches before code is written, Step 10 catches drift introduced while writing it.
references/reporting-limitations.md to get it tracked upstream.go.mod)Only if external Go dependencies are needed. For each external functionality, evaluate 2–3 candidate Go libraries on:
| Axis | What to check |
|---|---|
| Availability | Active maintenance, last release within ~12 months, owner responsive |
| Licensing | Prefer MIT / Apache-2.0 / BSD. Flag GPL/AGPL/LGPL — needs explicit user sign-off |
| Stability | v1.x+, release cadence, open-issue health |
| Dependency footprint | Transitive dep count, binary-size impact, CGo |
Present as a small table with a recommendation. Wait for user approval before adding the dependency to go.mod. If no external deps are needed, skip this step.
lib/stdlibs/ballerina/<name>/0.0.1/go1.27/
├── Ballerina.toml # package manifest
├── Bala.toml # build/platform manifest
├── Dependencies.toml # package dependencies
├── README.md # via stdlib-readme-format skill
├── <name>.bal # public API surface
└── native/ # OPTIONAL — omit if pure Ballerina
└── <name>.go # Go native implementationsMulti-file .bal and multi-file native/ are both supported — see exemplars below. For dotted names like math.vector, the single .bal file is named math.vector.bal.
Real Ballerina submodules (a package with a root module plus genuine sub-modules, matching jBallerina's own multi-module packages) use a modules/<localSubmoduleName>/ directory per sub-module, each with its own .bal file(s) — module discovery is purely filesystem-based (no [[modules]] declaration needed in Ballerina.toml). See lib/stdlibs/ballerina/protobuf/0.0.1/go1.27/ for the exemplar: root protobuf.bal plus modules/types.any/, modules/types.duration/, etc. Prefer this over registering each sub-module as an independent flat top-level package — a package with real sub-modules is one thing with one Ballerina.toml/Bala.toml/Dependencies.toml/version, not several.
Templates:
Ballerina.toml, Bala.toml, Dependencies.toml with/without cross-stdlib deps) — templates/manifests.md..bal with license header, native/<name>.go) — templates/source-files.md.Shared patterns — read the relevant file only when the situation applies:
references/pal.md. Three files must change; missing TestPal = nil-pointer panics in corpus tests.references/native-state.md. Never add fields to values.Map for this.values.BalToGoJSON / values.GoToBalValue; never duplicate the conversion per-stdlib.lib/rt/libs.go — add a blank import so the init() in the native package runs at binary start:
_ "ballerina/lib/stdlibs/ballerina/<name>/0.0.1/go1.27/native"Without this, all = external functions produce "function not found" at runtime even though the binary compiles cleanly. Skip this line if your stdlib has no native/ directory.
test_util/testphases/phases.go — append an entry to builtinStdlibs. This list is consumed only by the hand-rolled per-stage corpus drivers (ast/bir/desugar/cfg/etc. corpus_*_test.go, which discover tests under corpus/bal/) — cli/cmd run and the real project pipeline (including corpus/lib/'s TestLibIntegration) resolve ballerina/* imports via lib/stdlibs/ballerina/ on disk regardless of this list. Without an entry here, those specific corpus drivers cannot resolve import ballerina/<name> even though go run ./cli/cmd run works fine.
flatEntry("<name>", "0.0.1", "go1.27").flatEntry for the root module, then one subModuleEntry("<pkg>", "<localSubmoduleDir>", "0.0.1", "go1.27") per sub-module — root before its sub-modules, since each entry's ResolveSymbols call sees only previously-listed entries' exported symbols.Dependencies.toml — if the .bal source imports any other stdlib (import ballerina/<dep>;), declare it per templates/manifests.md. Without this, the full project resolver will not discover the dependency and every user .bal file importing this stdlib will fail with Unknown import: ballerina/<dep>.
projects/module_resolver.go — usually no change, even for a dotted 2-level sub-module name (math.vector-style dotted names, <pkg>.<submodule> sub-module names): the existing packageNameCandidates already reduces either shape to the right package name. Read it once to confirm the import in question is covered — and if you're tempted to generalize it further, verify the change is actually load-bearing by reverting it and re-testing before keeping it; it's easy to "fix" a case that was already handled.
Follow AGENTS.md (root) — Coding style, Symbols, and PAL sections. Do not restate or re-derive them; when in doubt, re-read the file.
| Exemplar | Use when |
|---|---|
lib/stdlibs/ballerina/url/0.0.1/go1.27/ | Smallest viable stdlib — 2 extern functions, 1 native file. |
lib/stdlibs/ballerina/io/0.0.1/go1.27/ | Single .bal file, multi-file native/ (io.go + file_io.go + more). |
lib/stdlibs/ballerina/time/0.0.1/go1.27/ | Heavy native implementation with PAL usage and documented behavioural divergences. |
lib/stdlibs/ballerina/http/0.0.1/go1.27/ | Class-based stdlib (Client init wrapper). |
lib/stdlibs/ballerina/math.vector/0.0.1/go1.27/ | Pure Ballerina — no native/ directory at all. |
lib/stdlibs/ballerina/protobuf/0.0.1/go1.27/ | Package with real sub-modules (modules/types.any/, etc.) — one root + six sub-module builtinStdlibs entries, native code in one sub-module only. |
Corpus tests for a stdlib port go under corpus/lib/subset<N>/ — a flat directory of <name>-<suffix>.bal files, e.g. corpus/lib/subset2/crypto-hash1-v.bal. This is a sibling of corpus/bal/ (the generic language-feature subsets, corpus/bal/subset1/ … corpus/bal/subset9/, each internally split into NN-category/ subfolders like 08-network/) and of corpus/project/ — do not put library tests under corpus/bal/.
Each lib/subset<N> is a released library-support milestone, documented in doc/library/subset<N>.md (the language-feature milestones in doc/lang/subset<N>.md are an unrelated numbering track — lib/subset2 and lang/subset2 are not the same milestone).
Ask the developer which subset this port's tests belong in before writing any test file — this is a release-scoping decision, not something to infer:
subset2) — the new module joins that release milestone, alongside corpus/lib/subset2/'s existing files.subset<N+1>, one past the highest existing lib/subsetN directory) — create doc/library/subset<N+1>.md following subset2.md's intro-paragraph pattern ("Subset N extends the released subset N-1 with …").corpus/lib/ has its own end-to-end pipeline, TestLibIntegration in corpus/integration_test.go, validated against corpus/integration/lib/subset<N>/*.txtar — mirroring corpus/project/'s TestProjectIntegration. It carries no per-stage goldens under corpus/ast/, corpus/bir/, corpus/cfg/ or corpus/desugared/: those goldens hold only the test file's own compilation unit — the library itself stays opaque — so they add nothing for a library. The per-stage drivers do not run library tests at all: discovery for those walks corpus/bal/ only, so moving library tests out of it left every stage test file unchanged. Their compiler-stage coverage comes from TestLibIntegration running the whole pipeline per test -- and the same import/extern paths are already exercised densely by corpus/bal/, 1686 of whose tests import a stdlib.
AGENTS.md: *-v.bal (valid, end-to-end with @output markers), *-e.bal (compile-time errors, @error markers), *-p.bal (runtime panics, @panic markers), *-f{v|e|p}.bal (future, scope-deferred).print1-v.bal, not print01-v.bal).*-v.bal tests must produce empty stderr. If the stdlib writes to stderr (e.g. logging), structure the test to avoid it — for log-style modules, use filtered log levels so nothing is emitted.manage-corpus-tests skill:go test ./corpus -updategit diff corpus/ before committing (and revert any unrelated golden drift -update introduces — see manage-corpus-tests).Targeting ≥80% coverage of the new Go code under native/.
This is a real CI gate, not a suggestion. .github/workflows/native-ci.yml runs make test-coverage and uploads the resulting profiles to Codecov (flags: native); codecov.yml sets coverage.status.patch.default.target: 80%, which fails the PR check if patch coverage (coverage of just the lines added/changed in the diff) drops below 80%. For a brand-new stdlib, essentially every line under native/ is new, so the whole-package coverage number below is a reliable local stand-in for that patch-coverage check.
Measure it locally before declaring done — this mirrors what CI does, without the full 2h suite:
go test -count=1 -coverpkg=./lib/stdlibs/ballerina/<name>/... \
-coverprofile=/tmp/<name>-coverage.out -covermode=atomic \
./corpus/... ./lib/stdlibs/ballerina/<name>/...
go tool cover -func=/tmp/<name>-coverage.out | grep totalIf the total is below 80%, find the gaps with go tool cover -func=/tmp/<name>-coverage.out (sort by the trailing % column) or go tool cover -html=/tmp/<name>-coverage.out for an annotated view, then add corpus .bal cases to exercise the missing branches — repeat until ≥80%. Do not move on to Step 9 with a known shortfall.
Drive coverage from .bal, not Go unit tests. The coverage harness runs ./corpus/... under -coverpkg=./lib/stdlibs/..., so a corpus test that calls your extern functions exercises and measures the native Go through the full compiler → BIR → interpreter pipeline. Reach for a Go unit test (native/<name>_test.go) only for branches genuinely unreachable from Ballerina — defensive type/arity guards, nil guards, interface-contract paths — and keep them minimal with a comment stating why they cannot be hit from .bal. Do not add a wrong-type extern arg guard at all (the type checker rejects wrong types at compile time; use x, _ := args[i].(T)). See the manage-corpus-tests skill's "Test philosophy" section.
Author lib/stdlibs/ballerina/<name>/0.0.1/go1.27/README.md using the stdlib-readme-format skill. Load that skill now and run its validation checklist before saving the file. Copy every unavoidable divergence from the Step 5 parity table into Notable Behavioural Changes — these must be present before merge.
Then update the top-level aggregator lib/stdlibs/ballerina/README.md (same stdlib-readme-format skill): add the new package row (alphabetical), recompute the Total footer, and mirror this package's behavioural changes into a ### <name> subsection (only if it has any).
Separately, confirm Step 8's doc/library/subset<N>.md update is done — it documents released library-feature milestones and is independent of the per-package README.md (which tracks jBallerina-parity status, not release scoping).
Before declaring done, check every box:
make build — no compilation errors in any workspace module.make vet — no vet warnings in any workspace module.go test ./corpus/... — all corpus tests pass.go run ./cli/cmd run <showcase>.bal (or ./bal run <showcase>.bal if the binary is built) — output matches the @output markers exactly.git diff corpus/ reviewed; every regenerated golden-file line is intentional.corpus/lib/subset<N>/ (the subset confirmed with the developer in Step 8), not the generic corpus/bal/subset1..9/ tree.native/ package is ≥80% (Step 8's go tool cover -func=... | grep total command). This is what Codecov's patch-coverage check in CI (native-ci.yml + codecov.yml) will otherwise fail the PR on.run-jballerina skill.validate-stdlib-contract skill on the new package — the verdict must be PASS (or PASS with notes, each note reviewed). This is the final public-interface gate.docs/spec/spec.md exists in the jBallerina reference root: every in-scope behavioural claim it makes matches the shipped Go implementation exactly. Any mismatch found during implementation (not just at Step 5's planning stage) has been resolved — implementation fixed, or the divergence explicitly documented — not left unreconciled.lib/stdlibs/ballerina/<name>/0.0.1/go1.27/README.md support table reflects current implementation (no stale Not Yet Supported rows for things just implemented).lib/stdlibs/ballerina/README.md aggregator updated (new row, recomputed Total footer, behavioural changes mirrored).stdlib-readme-format validation checklist passes.doc/library/subset<N>.md (the subset agreed with the developer in Step 8) documents this module's newly-supported surface — created fresh if it's a new subset, extended if existing.lib/rt/libs.go blank import added (skip only if pure Ballerina).test_util/testphases/phases.go builtinStdlibs entry/entries added (one flatEntry, or one flatEntry + one subModuleEntry per sub-module); placed after any stdlib dependencies in the list.Dependencies.toml declares every import ballerina/<dep> that appears in the .bal source (only needed when cross-stdlib imports exist; omit otherwise).palnative/ and wired into TestPal.Summarise:
native/ coverage % from Step 8's verify command.validate-stdlib-contract verdict.corpus/lib/subset<N>/ the tests were added to (new or existing) and confirmation doc/library/subset<N>.md was updated.references/reporting-limitations.md, and whether the developer filed it.© ballerina-nutcracker, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 6 other files (references) in .agents/skills/add-stdlib-support of ballerina-nutcracker/ballerina.
Open the folder on GitHubat commit 0cefa3f
Add Stdlib Support 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 |
|---|---|---|---|---|---|---|
| Add Stdlib Support this skillballerina-nutcracker/ballerina | 120 | — | ~6.3k | Automated safety check: Pass | Apache-2.0 | |
| Saleor Port Changessaleor/saleor | 23k | — | ~969 | Automated safety check: Pass | BSD-3-Clause | |
| Porthashgraph-online/awesome-codex-plugins | 1.2k | — | ~3.6k | Automated safety check: Pass | Apache-2.0 | |
| Platform PortFastLED/FastLED | 7.5k | — | ~580 | Automated safety check: Pass | MIT | |
| Detecting Port Scanning With Fail2banmukul975/Anthropic-Cybersecurity-Skills | 34k | — | ~3.2k | Automated safety check: Notes | Apache-2.0 | |
| PlotJuggler 3 to 4 PortingPlotJuggler/PlotJuggler | 6.2k | — | ~1.1k | Automated safety check: Pass | MPL-2.0 |
saleor/saleor
Forward-ports or backports a single PR or branch onto the currently checked-out Saleor branch, handling GraphQL version markers and migration numbering along the way.
hashgraph-online/awesome-codex-plugins
Make an existing single-player web game multiplayer in a Homie studio.
FastLED/FastLED
Guide porting FastLED to new MCU platforms, including int.h types, clockless drivers, SPI implementations, and platform detection.
mukul975/Anthropic-Cybersecurity-Skills
Configures Fail2ban with custom filters and actions to detect port scanning activity, SSH brute force attempts, and network reconnaissance, automatically banning offending IP addresses and alerting…
PlotJuggler/PlotJuggler
Directs porting of widgets, dialogs, panels and transforms from PlotJuggler 3 to PlotJuggler 4 by lifting the original files intact and rebinding only the data paths.
cursor/plugins
Plans the port of an existing GitHub App to a Cursor Origin App.
ballerina-nutcracker/ballerina
Authoritative format contract for lib/stdlibs/ballerina/<name/0.0.1/go1.27/README.md files.
ballerina-nutcracker/ballerina
Fill a gap in an existing ballerina/<name stdlib — implement a function marked Not Yet Supported, promote a Partially Supported row, or fix a behavioural divergence.
ballerina-nutcracker/ballerina
Validate that a ballerina/<name stdlib's Go public contract does not break the jBallerina public interface.
ballerina-nutcracker/ballerina
Run a given Ballerina source file with jBallerina to compare behaviour against this interpreter
ballerina-nutcracker/ballerina
A skill your agent uses when you are asked to fill in a subset doc (./doc/lang/subset.md)
ballerina-nutcracker/ballerina
Creating/updating corpus tests
Port a new ballerina/<name stdlib package from jBallerina to this Go-native interpreter. Add Stdlib Support is an agent skill from ballerina-nutcracker/ballerina. Port a new ballerina/<name stdlib package from jBallerina to this Go-native interpreter.
Add Stdlib Support fits situations like: the user asks to migrate; add a Ballerina standard library module that does not yet exist under lib/stdlibs/ballerina/.
Run `npx skills add ballerina-nutcracker/ballerina --skill add-stdlib-support -a claude-code`. Or copy the skill folder (.agents/skills/add-stdlib-support in ballerina-nutcracker/ballerina) into .claude/skills/add-stdlib-support in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ballerina-nutcracker/ballerina --skill add-stdlib-support -a codex`. Or copy the skill folder (.agents/skills/add-stdlib-support in ballerina-nutcracker/ballerina) into .agents/skills/add-stdlib-support 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 ballerina-nutcracker/ballerina --skill add-stdlib-support -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/add-stdlib-support, .gemini/skills/add-stdlib-support, .github/skills/add-stdlib-support and .opencode/skills/add-stdlib-support in your project.
Going by SKILL.md and its folder, Add Stdlib Support needs the command-line tools its instructions call (go, make and git).
SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. 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.
Add Stdlib Support is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.3k tokens (SKILL.md is roughly 25k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.5k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Add Stdlib Support: Saleor Port Changes (saleor/saleor, 23k stars), Port (hashgraph-online/awesome-codex-plugins, 1.2k stars), Platform Port (FastLED/FastLED, 7.5k stars) and Detecting Port Scanning With Fail2ban (mukul975/Anthropic-Cybersecurity-Skills, 34k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
ballerina-nutcracker (a GitHub organization) maintains it in ballerina-nutcracker/ballerina, which has 120 GitHub stars. The repository holds 7 skills in this directory. The repository was last updated on October 8, 2026.
Source: ballerina-nutcracker/ballerina on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.