Official agent skill

C Extensions With Bocpy

by microsoft in microsoft/bocpy

Write a C extension whose custom types can live inside a bocpy Cown and travel between worker sub-interpreters.

OfficialMITAuto-check passedDevelopment

Install C Extensions With Bocpy

skills CLI
$ npx skills add microsoft/bocpy --skill c-extensions-with-bocpy -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install microsoft/bocpy c-extensions-with-bocpy --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/microsoft/bocpy.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.github/skills/c-extensions-with-bocpy .claude/skills/c-extensions-with-bocpy && rm -rf skills-src

Use ~/.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/

Facts

Skill name
c-extensions-with-bocpy
GitHub stars
201
Token cost
~5.1k tokens
SKILL.md length
2,040 words
Files
1
Skills in repo
9
Repo updated
First seen
Licence
MIT

At a glance

Write a C extension whose custom types can live inside a bocpy Cown and travel between worker sub-interpreters.

  • Works in 5 steps: The impl struct → The Python wrapper, as a heap type with… → The producer callback — declare with… → …
  • : writing a native type (matrix
  • SKILL.md covers When you need this skill, The proto-Region mental model, Required scaffolding and The lifecycle: a Counter-sized…, plus 3 more sections
  • Calls pip

What it does

C Extensions With Bocpy is an agent skill from microsoft/bocpy, published by the product's own GitHub organization. Write a C extension whose custom types can live inside a bocpy Cown and travel between worker sub-interpreters. Use when: writing a native type (matrix, buffer, GPU handle, opaque C resource) that needs to round-trip through @when, send/receive, or any other bocpy primitive that crosses interpreter boundaries; designing the producer/consumer XIData callbacks; implementing proto-Region ownership semantics; setting up multi-phase init and per-interpreter type registration. Covers the bocpy public C ABI (bocpy.h…

Its SKILL.md is about 5.1k 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, covering Project scaffolding. The repository describes itself as: Behavior-Oriented Concurrency in Python. The licence is MIT.

When your agent uses it

  • : writing a native type (matrix
  • Opaque C resource) that needs to round-trip through @when
  • Any other bocpy primitive that crosses interpreter boundaries
  • Designing the producer/consumer XIData callbacks

Example prompts

  • “/c-extensions-with-bocpy”

Requirements

  • Python 3

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. The impl struct
  2. The Python wrapper, as a heap type with per-module state
  3. The producer callback — declare with XIDATA_GETDATA_FUNC
  4. The consumer callback — new_object reconstruction
  5. Module init — multi-phase, per-interpreter-GIL aware

What it can do on your machine

Read from SKILL.md and the folder at commit c8f3ceb. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    Shell commands in SKILL.md call:

    • pip

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pip, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

C Extensions With Bocpy loads about 5.1k tokens when it runs. Until then it costs about 174 tokens; SKILL.md has 2,040 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~174
When it runs · the whole SKILL.md, loaded when a task matches
~5.1k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from microsoft/bocpy at commit c8f3ceb, republished under its MIT licence (© microsoft). 2,040 words, ~5,144 tokens.

Download SKILL.mdSave it as .claude/skills/c-extensions-with-bocpy/SKILL.md (or your agent's skills folder).
name
c-extensions-with-bocpy
description
Write a C extension whose custom types can live inside a bocpy Cown and travel between worker sub-interpreters. Use when: writing a native type (matrix, buffer, GPU handle, opaque C resource) that needs to round-trip through @when, send/receive, or any other bocpy primitive that crosses interpreter boundaries; designing the producer/consumer XIData callbacks; implementing proto-Region ownership semantics; setting up multi-phase init and per-interpreter type registration. Covers the bocpy public C ABI (bocpy.h, xidata.h, BOCPY_NO_OWNER, bocpy_interpid, XIDATA_REGISTERCLASS, XIDATA_GETDATA_FUNC, XIDATA_INIT), the setup.py boilerplate, and the worker-import contract.

Writing C extensions with the bocpy public C ABI

This skill is for writing a downstream C extension whose custom types must travel through bocpy's runtime — placed inside a Cown, scheduled with @when, or shipped via send/receive across worker sub-interpreters.

Read thinking-in-boc first. The C ABI does not change the BOC mental model. Your C type is still wrapped in a Cown, behaviors are still scheduled with @when, and ordering still comes from the cown graph — not from anything you do in C. The C ABI only buys you a safe, zero-copy way to cross the interpreter boundary; the choreography between behaviors is unchanged.

When you need this skill

You need a C extension that uses the bocpy public C ABI only when all three of the following are true:

  1. Your type wraps a native C resource (large buffer, matrix, GPU handle, file descriptor, FFI pointer, etc.) that you do not want to copy or pickle every time it crosses interpreter boundaries.
  2. You want instances of that type to live inside a Cown and be acquired by @when behaviors on worker sub-interpreters.
  3. You want isolation guarantees: at most one interpreter may read or write the resource at a time, and any stale wrapper left behind in the previous owner cannot observe the resource any more.

If your type is pure-Python, pickleable, or you are happy with a copy on each interpreter crossing, you do not need this skill — Cown(my_obj) already works. Read the BOC primer in the project copilot instructions and stop here.

The canonical worked example shipped by bocpy lives in templates/c_abi_consumer/ of the bocpy source tree — copy it as the starting point for a new extension. The Matrix type in src/bocpy/_math.c is the in-tree reference implementation.

The proto-Region mental model

A bocpy-aware C type implements proto-Region ownership: a single atomic owner field on the impl identifies the interpreter that may read or write the payload. The producer-side XIData callback CASes that field from bocpy_interpid() to BOCPY_NO_OWNER; the consumer-side callback CASes it back from BOCPY_NO_OWNER to bocpy_interpid(). Any data accessor that reads or writes the payload first asserts bocpy_interpid() == atomic_load(&impl->owner) and raises RuntimeError otherwise.

This is not the full Lungfish region model — there are no nested regions, no freeze, no merge, no borrow tracking — but it is enough to turn "a shareable pointer" into "a resource owned by exactly one interpreter at a time", which is what BOC needs.

What the proto-Region contract gives you in practice:

  • A stale wrapper held in a producer interpreter after the handoff cannot read or write the impl — every accessor raises RuntimeError until ownership returns. This catches races that pointer-only sharing would miss.
  • The CAS in the producer callback fails if the calling interpreter is not the current owner. A behavior that tries to send a cown's value somewhere it should not go is rejected at the boundary, not silently corrupted.

Required scaffolding

setup.py

Use bocpy.get_include() for the header search path and bocpy.get_sources() for the MSVC out-of-line atomics shim (no-op elsewhere). Copy this verbatim from templates/c_abi_consumer/setup.py and change the module name:

python
from setuptools import Extension, setup
import bocpy

setup(
    ext_modules=[
        Extension(
            "_your_extension",
            sources=["src/_your_extension.c"] + bocpy.get_sources(),
            include_dirs=[bocpy.get_include()],
        ),
    ],
)
pyproject.toml

Declare bocpy in both [build-system].requires (so an isolated PEP 517 build can satisfy import bocpy in setup.py) and [project].dependencies (so installing your wheel installs bocpy at runtime).

Always install with pip install --no-build-isolation so the build resolves headers against the bocpy install actually being tested, not whatever PyPI happens to publish.

Header include
c
#include <bocpy/bocpy.h>

/* Compile-time guard: bocpy.h must not leak Py_BUILD_CORE. */
#ifdef Py_BUILD_CORE
#error "Py_BUILD_CORE leaked from bocpy.h"
#endif

Rules:

  • <bocpy/bocpy.h> includes <Python.h> internally. It is order-insensitive with respect to <Python.h> itself.
  • It must appear before any system header (<stdio.h>, <string.h>, ...) in the same translation unit, the same way <Python.h> must — CPython forbids system headers before Python.h.
  • C only. <bocpy/bocpy.h> is not supported from C++ in this release. C++ consumers must wrap the ABI in a thin C translation unit.
Public ABI surface — what you may use

Everything below is exposed by <bocpy/bocpy.h>. Treat anything else under the bocpy package directory as private.

SymbolPurpose
BOCPY_ABIInteger macro. Gate code on BOCPY_ABI >= N if you need a minimum revision.
BOCPY_NO_OWNERSentinel -2 meaning "no interpreter owns this impl right now". Use as initial / in-flight value of the owner field.
bocpy_interpid()static inline int_least64_t. Returns the running interpreter's ID, pre-typed for the atomic CAS parameter list. Must be called with the GIL held / attached.
atomic_int_least64_t64-bit atomic integer type. Sequentially consistent on every supported target.
atomic_load(p), atomic_store(p, v), atomic_fetch_add(p, v), atomic_compare_exchange_strong(p, &exp, des)The four atomic ops you will need. SC on every supported MSVC target (x86, x64, ARM64); plain <stdatomic.h> elsewhere.
thread_localMacro for thread-local storage. Use to cache the per-interpreter LOCAL_STATE so callbacks don't walk PyModule_GetState every call.
XIDATA_TOpaque struct holding a serialised cross-interpreter handoff.
XIDATA_NEW(), XIDATA_GETXIDATA(value, xidata), XIDATA_FREE(xidata), XIDATA_SET_FREE(xidata, fn)Lifecycle ops. You normally only call XIDATA_INIT from your producer callback; the rest is called by bocpy.
XIDATA_INIT(xidata, interp, data, obj, new_object)Initialise an XIDATA_T. interp must be the interpreter that currently owns data. Buffer must be freshly allocated.
XIDATA_NEWOBJECTType alias for the consumer-side reconstruction callback.
XIDATA_REGISTERCLASS(type, cb)Register a Python type as cross-interpreter shareable with producer callback cb. Per-interpreter — call from the exec slot.
XIDATA_GETDATA_FUNC(name)Macro that declares a producer callback with a portable (tstate, obj, xidata) signature. Hides the legacy-CPython signature change.

Internal headers and surfaces (boc_compat.h, boc_cown.h, boc_sched.h, boc_tags.h, boc_terminator.h, boc_noticeboard.h, the typed atomics, the BOC mutex/condvar types, boc_yield, boc_now_*, boc_sleep_ns, etc.) are not public. Do not depend on them.

The lifecycle: a Counter-sized walkthrough

The full annotated source is templates/c_abi_consumer/src/_bocpy_probe.c. The skeleton below shows the five places you must get right.

1. The impl struct

A heap-allocated C struct that lives outside any single Python object's lifetime. Carries its own atomic refcount and its atomic owner field.

c
typedef struct {
    atomic_int_least64_t refcount;   /* number of wrappers holding this impl */
    atomic_int_least64_t owner;      /* interpreter ID, or BOCPY_NO_OWNER in flight */
    /* ... your payload here ... */
} your_impl;

static your_impl *your_impl_new(void) {
    your_impl *impl = PyMem_RawMalloc(sizeof(*impl));
    if (impl == NULL) return NULL;
    atomic_store(&impl->refcount, 1);
    atomic_store(&impl->owner, bocpy_interpid());   /* born owned */
    return impl;
}

static void your_impl_incref(your_impl *impl) {
    atomic_fetch_add(&impl->refcount, 1);
}

static void your_impl_decref(your_impl *impl) {
    if (atomic_fetch_add(&impl->refcount, -1) == 1) {
        /* last holder, free the payload */
        PyMem_RawFree(impl);
    }
}

static bool your_impl_check_acquired(your_impl *impl, bool set_error) {
    if (bocpy_interpid() != atomic_load(&impl->owner)) {
        if (set_error)
            PyErr_SetString(PyExc_RuntimeError,
                            "the current interpreter does not own this type");
        return false;
    }
    return true;
}

Refcounting and ownership are independent. Any interpreter holding a wrapper drops its ref on dealloc, regardless of who currently owns the impl. The proto-Region check guards data accessors, not the lifetime of the impl itself.

2. The Python wrapper, as a heap type with per-module state

Use PyType_FromModuleAndSpec (not the static-type pattern). Store the type on per-module state and cache it in a thread_local LOCAL_STATE so callbacks can find it without walking module state.

c
typedef struct {
    PyTypeObject *your_type;
} your_module_state;

static thread_local your_module_state *LOCAL_STATE;

typedef struct {
    PyObject_HEAD
    your_impl *impl;
} YourObject;

Data accessors must call your_impl_check_acquired before reading the payload. Identity-only accessors (e.g. an address getter that returns (uintptr_t)impl) may skip the check — printing the address of a Region handle without being inside the Region is allowed.

3. The producer callback — declare with XIDATA_GETDATA_FUNC

Runs on the interpreter that currently owns the impl, every time something asks XIData to package one of your objects. CAS the owner field from this interpreter to BOCPY_NO_OWNER, then call XIDATA_INIT. Failing the CAS surfaces as a RuntimeError and aborts the handoff.

c
XIDATA_GETDATA_FUNC(_your_shared) {
    YourObject *self = (YourObject *)obj;
    your_impl *impl = self->impl;
    if (impl == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "type not initialised");
        return -1;
    }

    int_least64_t expected = bocpy_interpid();
    int_least64_t desired  = BOCPY_NO_OWNER;
    if (!atomic_compare_exchange_strong(&impl->owner, &expected, desired)) {
        PyErr_Format(PyExc_RuntimeError,
                     "cannot share: owned by interpreter %lld",
                     (long long)expected);
        return -1;
    }

    XIDATA_INIT(xidata, tstate->interp, impl, obj, _new_your_object);
    return 0;
}

Why XIDATA_GETDATA_FUNC and not a hand-written signature? On older CPython the callback is (obj, xidata) only — no tstate. The macro emits a small trampoline so the body is portable across every supported CPython.

4. The consumer callback — new_object reconstruction

Runs on the interpreter that is taking ownership. CAS the owner from BOCPY_NO_OWNER to bocpy_interpid(), allocate a fresh wrapper from the local heap type, and bump the impl refcount.

c
static PyObject *_new_your_object(XIDATA_T *xidata) {
    your_impl *impl = (your_impl *)xidata->data;

    int_least64_t expected = BOCPY_NO_OWNER;
    int_least64_t desired  = bocpy_interpid();
    if (!atomic_compare_exchange_strong(&impl->owner, &expected, desired)) {
        PyErr_Format(PyExc_RuntimeError,
                     "cannot acquire (expected BOCPY_NO_OWNER, observed %lld)",
                     (long long)expected);
        return NULL;
    }

    PyTypeObject *type = LOCAL_STATE->your_type;
    YourObject *self = (YourObject *)type->tp_alloc(type, 0);
    if (self == NULL) {
        /* CRITICAL: roll the owner back so a retry can succeed and
         * the impl is not stranded with us as owner without a wrapper. */
        atomic_store(&impl->owner, BOCPY_NO_OWNER);
        return NULL;
    }
    self->impl = impl;
    your_impl_incref(impl);
    return (PyObject *)self;
}

The wrapper-allocation rollback is easy to forget and impossible to recover from at runtime. Write it the same time you write the success path.

Show full SKILL.md (847 more words)Show less
5. Module init — multi-phase, per-interpreter-GIL aware

XIDATA_REGISTERCLASS registers into a per-interpreter registry. It must run in every interpreter that will reconstruct one of your objects — which means every worker sub-interpreter, not just the main one. Single-phase PyModule_Create modules load in the main interpreter but cannot satisfy Py_MOD_PER_INTERPRETER_GIL_SUPPORTED, and the registration never runs in worker interpreters; the consumer callback then dereferences a NULL LOCAL_STATE and segfaults.

Use multi-phase init with a Py_mod_exec slot:

c
static int _your_module_exec(PyObject *module) {
    your_module_state *state =
        (your_module_state *)PyModule_GetState(module);

    state->your_type = (PyTypeObject *)PyType_FromModuleAndSpec(
        module, &YourType_Spec, NULL);
    if (state->your_type == NULL) return -1;
    if (PyModule_AddType(module, state->your_type) < 0) return -1;

    if (XIDATA_REGISTERCLASS(state->your_type, _your_shared)) {
        PyErr_SetString(PyExc_RuntimeError,
                        "could not register type for cross-interpreter sharing");
        return -1;
    }

    LOCAL_STATE = state;   /* prime the thread-local cache */
    return 0;
}

static PyModuleDef_Slot _your_module_slots[] = {
    {Py_mod_exec, (void *)_your_module_exec},
#if PY_VERSION_HEX >= 0x030C0000
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
#endif
#if PY_VERSION_HEX >= 0x030D0000
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
#endif
    {0, NULL},
};

Also implement m_traverse, m_clear, and m_free to manage the type stored on per-module state — this is standard multi-phase hygiene, not bocpy-specific.

Hard rules

  1. Top-level import of your extension in every Python file that schedules @when bodies which observe your types. The transpiler propagates module-scope import statements into the exported per-worker module. Runtime helpers like importlib.import_module(...), __import__(...), or pytest.importorskip(...) are invisible to the transpiler — a worker without your extension loaded will skip the exec slot and the consumer callback will dereference a NULL LOCAL_STATE.
  2. XIDATA_REGISTERCLASS belongs in Py_mod_exec, never in PyInit. The registry is per-interpreter.
  3. Always pair the producer CAS with the consumer CAS. Producer: bocpy_interpid() -> BOCPY_NO_OWNER. Consumer: BOCPY_NO_OWNER -> bocpy_interpid(). Anything else strands the impl.
  4. Roll back the owner field on consumer-side wrapper allocation failure. Otherwise the impl is owned-but-unreferenced and no future handoff can succeed.
  5. Inside an @when, never send("tag", c.value) of a proto-Region resource. send would atomically move the impl out of the cown mid-behavior and leave the worker unable to release the cown afterwards. Send a copy (c.value.copy()) or send primitive summary data (c.value.address, a hash, a slice). The cown itself is the right primitive for handing the resource to another behavior — schedule a downstream @when on the same cown.
  6. The cown graph still orders your work. The C ABI gives you safe transport; ordering between behaviors still comes from @when. If you find yourself reaching for a threading.Event, atomic flag, or polling loop to coordinate two behaviors on the same C type, re-read thinking-in-boc.
  7. No Py_BUILD_CORE leakage. Guard for it with #error at the top of your translation unit; a future bocpy refactor that forgets the #undef should fail your build loudly, not at runtime.
  8. No C++. Wrap the ABI in a thin C TU if your project needs C++.

Common pitfalls

PitfallSymptomFix
Single-phase PyModule_CreateLoads in main interpreter; segfaults in worker.Switch to multi-phase init with Py_mod_exec and declare Py_MOD_PER_INTERPRETER_GIL_SUPPORTED.
XIDATA_REGISTERCLASS in PyInitConsumer callback sees no type registered in its registry.Move to the exec slot.
Forgetting to roll back owner on alloc failureImpl stranded with no wrapper; future handoffs fail their CAS.Add atomic_store(&impl->owner, BOCPY_NO_OWNER); before returning NULL from the consumer callback.
pytest.importorskip("_your_ext") instead of top-level importWorkers skip the exec slot; consumer dereferences NULL LOCAL_STATE.Use a plain top-level import _your_ext in any file that schedules @when bodies.
send("tag", c.value) of a proto-Region objectWorker cannot release the cown afterwards; runtime stalls.Send a copy or summary data.
Reading the payload outside a @whenRuntimeError: the current interpreter does not own this type.Read inside a @when that holds the cown, or use an identity-only accessor (.address).
Identity-only getter calling the ownership check.address raises RuntimeError from interpreters that hold a stale wrapper.Skip the ownership check on identity/lifetime accessors.
Static-type pattern (PyTypeObject MyType = {...})Type cannot be per-interpreter; LOCAL_STATE cache pattern won't fit.Use PyType_FromModuleAndSpec and store the type on per-module state.
Including <stdio.h> before <bocpy/bocpy.h>Compile error on some toolchains; Python.h ordering rule.Move <bocpy/bocpy.h> to the very top of the translation unit.
Hand-written (obj, xidata) producer callbackCompile error on CPython <3.12 (legacy (tstate, obj, xidata)) or vice versa.Declare the callback with XIDATA_GETDATA_FUNC(name).
Building without --no-build-isolationWheel resolves against PyPI bocpy headers instead of your local install.Always pip install --no-build-isolation ..
Refcount and ownership conflated__dealloc__ raises RuntimeError from interpreters that hold a stale wrapper.Keep refcount independent of ownership — drop refs on dealloc regardless of who owns the impl.

Verification checklist

Before declaring a bocpy-aware C extension done, verify all of:

  • setup.py uses bocpy.get_include() and bocpy.get_sources().
  • pyproject.toml lists bocpy in both [build-system].requires and [project].dependencies.
  • Translation unit includes <bocpy/bocpy.h> at the top, with an #error guard against Py_BUILD_CORE leakage.
  • Module uses multi-phase init and declares Py_MOD_PER_INTERPRETER_GIL_SUPPORTED.
  • Type is heap-allocated via PyType_FromModuleAndSpec and stored on per-module state.
  • XIDATA_REGISTERCLASS is called from the Py_mod_exec slot.
  • Producer callback declared with XIDATA_GETDATA_FUNC.
  • Producer callback CASes owner from bocpy_interpid() to BOCPY_NO_OWNER before XIDATA_INIT.
  • Consumer callback CASes owner from BOCPY_NO_OWNER to bocpy_interpid() before allocating the wrapper.
  • Consumer callback rolls owner back to BOCPY_NO_OWNER if wrapper allocation fails.
  • Data-reading accessors call an _check_acquired-style helper and raise RuntimeError on mismatch.
  • Identity/lifetime accessors do not call the check.
  • A pytest test imports the extension at module scope (not via importorskip) and exercises a @when chain that round-trips a cown carrying one of your types through at least one worker. Use the testing-with-boc send/receive assertion pattern.
  • Tests pass when installed with pip install --no-build-isolation.

See templates/c_abi_consumer/test/test_consumer.py in the bocpy source tree for the canonical test pattern — a tail-recursive @when chain that ships a counter cown between workers, with assertions fired back via send / receive.

© microsoft, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .github/skills/c-extensions-with-bocpy of microsoft/bocpy.

Open the folder on GitHubat commit c8f3ceb

Compare with similar skills

C Extensions With Bocpy 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.

C Extensions With Bocpy compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
C Extensions With Bocpy this skillmicrosoft/bocpy201—~5.1kAutomated safety check: PassMIT
Nx Generatenomcopter/react-mosaic4.8k7 repos~1.9kAutomated safety check: PassCustom licence
PonytailDavidObando/gsharp5648 repos~1.7kAutomated safety check: PassMIT
Run Nx Generatornrwl/nx29k2 repos~592Automated safety check: NotesMIT
Conductor Setupgemini-cli-extensions/conductor3.8k—~4.2kAutomated safety check: PassApache-2.0
Mirage VFS Adapter Authoringstrukto-ai/mirage3.7k—~2.5kAutomated safety check: PassApache-2.0

Similar skills

  • Nx Generate

    nomcopter/react-mosaic

    Generate code using nx generators. An agent skill from nomcopter/react-mosaic.

    4.8k GitHub starsUsed in 7 repos~1.9k tokens
    DevelopmentAuto-check passed
  • Ponytail

    DavidObando/gsharp

    Forces the laziest solution that actually works, simplest, shortest, most minimal.

    564 GitHub starsUsed in 8 repos~1.7k tokens
    DevelopmentAuto-check passed
  • Run Nx generators with prioritization for workspace-plugin generators.

    29k GitHub starsUsed in 2 repos~592 tokens
    DevelopmentAuto-check: notes
  • Conductor Setup

    gemini-cli-extensions/conductor

    Scaffolds the project and sets up the Conductor environment.

    3.8k GitHub stars~4.2k tokensUpdated 1 mo ago
    DevelopmentAuto-check passed
  • Builds or extends a custom Mirage virtual filesystem adapter for an API, database, object store or app data, with a working mount configuration and filesystem tests.

    3.7k GitHub stars~2.5k tokensUpdated today
    DevelopmentAuto-check passed
  • Enforces this repository's TypeScript backend module architecture under server/: feature folders, barrel exports, and where shared types and utilities belong.

    14k GitHub stars~1.2k tokensUpdated yesterday
    DevelopmentAuto-check passed

More from microsoft/bocpy

All 9 skills in this repo
  • Branch Review

    microsoft/bocpy

    Official

    Multi-perspective code review for a branch before merging. An agent skill from microsoft/bocpy.

    201 GitHub stars~3.2k tokensUpdated 10 days ago
    Auto-check passed
  • Official

    Follow bocpy commenting and documentation conventions. An agent skill from microsoft/bocpy.

    201 GitHub stars~3.3k tokensUpdated 10 days ago
    Auto-check passed
  • Finalize PR

    microsoft/bocpy

    Official

    Finalize a feature branch for merge. An agent skill from microsoft/bocpy.

    201 GitHub stars~3.5k tokensUpdated 10 days ago
    Auto-check passed
  • Multi Perspective Plan

    microsoft/bocpy

    Official

    Multi-perspective planning with rebuttal rounds and adversarial review loop.

    201 GitHub stars~2.8k tokensUpdated 10 days ago
    Auto-check passed
  • Testing Message Queue

    microsoft/bocpy

    Official

    Write tests for the bocpy message queue — the lock-free tag-based MPSC ring buffer.

    201 GitHub stars~2.3k tokensUpdated 10 days ago
    Auto-check passed
  • Thinking In Boc

    microsoft/bocpy

    Official

    Think in Behavior-Oriented Concurrency, not threads-and-locks.

    201 GitHub stars~2.6k tokensUpdated 10 days ago
    Auto-check passed

Categories

Questions about C Extensions With Bocpy

What does C Extensions With Bocpy do?

Write a C extension whose custom types can live inside a bocpy Cown and travel between worker sub-interpreters. C Extensions With Bocpy is an agent skill from microsoft/bocpy, published by the product's own GitHub organization. Write a C extension whose custom types can live inside a bocpy Cown and travel between worker sub-interpreters.

When should I use C Extensions With Bocpy?

C Extensions With Bocpy fits situations like: : writing a native type (matrix; opaque C resource) that needs to round-trip through @when; any other bocpy primitive that crosses interpreter boundaries; designing the producer/consumer XIData callbacks.

How do I install C Extensions With Bocpy in Claude Code?

Run `npx skills add microsoft/bocpy --skill c-extensions-with-bocpy -a claude-code`. Or copy the skill folder (.github/skills/c-extensions-with-bocpy in microsoft/bocpy) into .claude/skills/c-extensions-with-bocpy in your project. Claude Code loads it when a task matches its description.

How do I install C Extensions With Bocpy in Codex?

Run `npx skills add microsoft/bocpy --skill c-extensions-with-bocpy -a codex`. Or copy the skill folder (.github/skills/c-extensions-with-bocpy in microsoft/bocpy) into .agents/skills/c-extensions-with-bocpy in your project. Codex loads it when a task matches its description.

Can I use C Extensions With Bocpy in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add microsoft/bocpy --skill c-extensions-with-bocpy -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/c-extensions-with-bocpy, .gemini/skills/c-extensions-with-bocpy, .github/skills/c-extensions-with-bocpy and .opencode/skills/c-extensions-with-bocpy in your project.

What does C Extensions With Bocpy need to run?

Going by SKILL.md and its folder, C Extensions With Bocpy needs the command-line tools its instructions call (pip). Our summary lists: Python 3.

Does C Extensions With Bocpy access the network?

SKILL.md contains no URLs. Its commands use pip, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is C Extensions With Bocpy safe to install?

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.

What licence does C Extensions With Bocpy use?

C Extensions With Bocpy is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does C Extensions With Bocpy use?

About 5.1k tokens (SKILL.md is roughly 21k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to C Extensions With Bocpy?

Skills that share tags, products or a category with C Extensions With Bocpy: Nx Generate (nomcopter/react-mosaic, 4.8k stars), Ponytail (DavidObando/gsharp, 564 stars), Run Nx Generator (nrwl/nx, 29k stars) and Conductor Setup (gemini-cli-extensions/conductor, 3.8k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains C Extensions With Bocpy?

microsoft (a GitHub organization, an official publisher) maintains it in microsoft/bocpy, which has 201 GitHub stars. The repository holds 9 skills in this directory. The repository was last updated on September 28, 2026.

Source: microsoft/bocpy on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.