Record Extension Demo
mengxi-ream/read-frog
Record polished, evidence-backed demos of the Read Frog extension as MP4 (and optional GIF) by driving real Chrome with the built extension, following captioned scene scripts, asserting extension…
Step-by-step guide for converting Quarkus extensions from the legacy @Record/@Recorder pattern to the ServiceRegistrar service system.
$ npx skills add quarkusio/quarkus --skill converting-recorders-to-services -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install quarkusio/quarkus converting-recorders-to-services --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/quarkusio/quarkus.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/converting-recorders-to-services .claude/skills/converting-recorders-to-services && 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 "converting-recorders-to-services" agent skill from https://github.com/quarkusio/quarkus/tree/main/.agents/skills/converting-recorders-to-services into .claude/skills/converting-recorders-to-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "converting-recorders-to-services", 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/quarkusio/quarkus/tree/main/.agents/skills/converting-recorders-to-servicesType 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 quarkusio/quarkus --skill converting-recorders-to-services -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install quarkusio/quarkus converting-recorders-to-services --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quarkusio/quarkus.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/converting-recorders-to-services .agents/skills/converting-recorders-to-services && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "converting-recorders-to-services" agent skill from https://github.com/quarkusio/quarkus/tree/main/.agents/skills/converting-recorders-to-services into .agents/skills/converting-recorders-to-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "converting-recorders-to-services", 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 quarkusio/quarkus --skill converting-recorders-to-services -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install quarkusio/quarkus converting-recorders-to-services --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quarkusio/quarkus.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/converting-recorders-to-services .cursor/skills/converting-recorders-to-services && 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 "converting-recorders-to-services" agent skill from https://github.com/quarkusio/quarkus/tree/main/.agents/skills/converting-recorders-to-services into .cursor/skills/converting-recorders-to-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "converting-recorders-to-services", 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/quarkusio/quarkus.git --path .agents/skills/converting-recorders-to-services--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 quarkusio/quarkus --skill converting-recorders-to-services -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install quarkusio/quarkus converting-recorders-to-services --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quarkusio/quarkus.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/converting-recorders-to-services .gemini/skills/converting-recorders-to-services && 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 "converting-recorders-to-services" agent skill from https://github.com/quarkusio/quarkus/tree/main/.agents/skills/converting-recorders-to-services into .gemini/skills/converting-recorders-to-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "converting-recorders-to-services", 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 quarkusio/quarkus converting-recorders-to-servicesInstalls 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 quarkusio/quarkus --skill converting-recorders-to-services -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/quarkusio/quarkus.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/converting-recorders-to-services .github/skills/converting-recorders-to-services && 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 "converting-recorders-to-services" agent skill from https://github.com/quarkusio/quarkus/tree/main/.agents/skills/converting-recorders-to-services into .github/skills/converting-recorders-to-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "converting-recorders-to-services", 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 quarkusio/quarkus --skill converting-recorders-to-services -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install quarkusio/quarkus converting-recorders-to-services --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quarkusio/quarkus.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/converting-recorders-to-services .opencode/skills/converting-recorders-to-services && 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 "converting-recorders-to-services" agent skill from https://github.com/quarkusio/quarkus/tree/main/.agents/skills/converting-recorders-to-services into .opencode/skills/converting-recorders-to-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "converting-recorders-to-services", 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.
converting-recorders-to-servicesStep-by-step guide for converting Quarkus extensions from the legacy @Record/@Recorder pattern to the ServiceRegistrar service system.
Converting Recorders To Services is an agent skill from quarkusio/quarkus. Step-by-step guide for converting Quarkus extensions from the legacy @Record/@Recorder pattern to the ServiceRegistrar service system.
Its SKILL.md is about 4.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
The repository describes itself as: Quarkus: Supersonic Subatomic Java. 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 d58d0eb. 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 java).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
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.
Converting Recorders To Services loads about 4.6k tokens when it runs. Until then it costs about 42 tokens; SKILL.md has 1,924 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 quarkusio/quarkus at commit d58d0eb, republished under its Apache-2.0 licence (© quarkusio). 1,924 words, ~4,639 tokens.
.claude/skills/converting-recorders-to-services/SKILL.md (or your agent's skills folder).The ServiceRegistrar service system replaces @Recorder with typed service. Services declare dependencies explicitly and execute in dependency
order, not build step order. The system is designed for incremental
migration — converted and unconverted extensions may coexist.
require(), after(),
before(), or afterBuildItem().@Record call and an ServiceRegistrar
call, the service and recorder are separate nodes with no implicit
ordering between them.ServiceNode,
not through the StartupContext maps (except for recorder proxy bridges).| Kind | Description | Gets step-graph deps? |
|---|---|---|
LEGACY_RECORDER | Recorder chunk from a @Record step | Yes |
ALIAS | Bridges a recorder value to a service key | Yes |
SERVICE | ServiceRegistrar service with a lambda body | No |
RV_WRAPPER | Wraps a service value in RuntimeValue for recorders | No |
CROSS_PHASE_PROXY | Bridges a static-init service to the runtime graph | No |
Legacy recorders and aliases use step-graph ordering for compatibility. Service nodes use only explicit declarations.
Before converting, verify that all runtime dependencies are available as services:
| Dependency Type | Availability |
|---|---|
ArcContainer | Service in ArcProcessor#initializeContainer |
BeanContainer | Service in ArcProcessor#createBeanContainer |
ScheduledExecutorService | Aliased by ThreadPoolSetup |
@ConfigMapping (RUN_TIME) | Auto-registered by ConfigServiceRegistrationStep |
@ConfigMapping (BUILD_AND_RUN_TIME_FIXED) | Auto-registered as static-init |
@ConfigMapping (BUILD_TIME) | Cannot be a service — extract values into locals |
| Other runtime objects | Search for aliasRecorderValue or forService |
For each @Recorder method, determine:
RuntimeValue<X> unwraps
to X. void becomes Void.class with a descriptive name.RuntimeValue<X> params become require(X.class).
Simple values (String, int, boolean, enum) can be captured. Immutable
collections (List.of(), Set.of(), etc.) can be captured.RuntimeValues injected via constructor
become require() dependencies.@Recorder, make methods static,
unwrap RuntimeValue parameters and return types.@Recorder for remaining methods.Before:
@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
ServiceStartBuildItem setup(MyRecorder recorder, SomeBuildItem item) {
recorder.initialize(item.getValue());
return new ServiceStartBuildItem("my-feature");
}After:
@BuildStep
ServiceStartBuildItem setup(ServiceRegistrar serviceRegistrar, SomeBuildItem item) {
serviceRegistrar
.forService("io.quarkus.my-feature.setup")
.onStart(ctx -> MyRecorder.initialize());
return new ServiceStartBuildItem("my-feature");
}Key changes:
@Record(ExecutionTime.*) annotation.ServiceRegistrar serviceRegistrar..atPhase(Phase.STATIC_INIT) for static-init services (default
is runtime-init / Phase.APPLICATION)."io.quarkus.<extension>.<purpose>".Every dependency must be explicit. There is no implicit ordering from the build step graph.
| Old Pattern | New Pattern |
|---|---|
recorder.method(beanContainer.getValue()) | .require(BeanContainer.class) |
recorder.method(someRuntimeValue) | .require(SomeType.class) |
recorder.method(config.maxSize()) | Capture int maxSize = config.maxSize() before lambda |
@Consume(SyntheticBeansRuntimeInitBuildItem.class) on step | .afterBuildItem(SyntheticBeansRuntimeInitBuildItem.class) on service |
afterBuildItem() — bridging to build step orderingWhen a service depends on state produced by a legacy recorder (e.g.,
synthetic beans must be initialized), declare the dependency via
afterBuildItem():
serviceRegistrar
.forService("io.quarkus.arc.lifecycle")
.afterBuildItem(SyntheticBeansRuntimeInitBuildItem.class)
.onStart(ctx -> ArcRecorder.fireLifecycleEvent(new StartupEvent()));This resolves the producing step's nodes (with passthrough resolution for steps that have no service graph nodes) and creates ordering edges.
afterBuildItem() is deprecated — it exists only for recorder
coexistence. Once the producing recorder is converted to a service,
replace with require() or after(), or drop it, as appropriate.
Runtime services can require() static-init services. The framework
automatically creates a CROSS_PHASE_PROXY node that reads the value
from the serviceValues map (populated during static-init and retained
via retainServiceValues()).
// static-init service
serviceRegistrar.forService(ArcContainer.class)
.atPhase(Phase.STATIC_INIT)
.afterBuildItem(ResourcesGeneratedPhaseBuildItem.class)
.onStart(ctx -> Arc.initialize());
// runtime service that depends on it
serviceRegistrar.forService("io.quarkus.my-ext.setup")
.require(ArcContainer.class) // cross-phase: resolved via proxy
.onStart((ctx, container) -> { ... });BUILD_TIME — extract values into locals before the lambda.BUILD_AND_RUN_TIME_FIXED — use .require(ConfigType.class) (resolved
directly from SmallRye Config, no graph edge).RUN_TIME — use .require(ConfigType.class) (same mechanism).before()before(X) declares "X depends on me" — this service starts before X
and stops after X. Use it for cleanup services that must outlive their
dependents:
serviceRegistrar
.forService("io.quarkus.vertx.netty-thread-local-cleanup")
.atPhase(Phase.STATIC_INIT)
.before(IOThreadDetector.class)
.before(ArcContainer.class)
.onStart(ctx -> {
ctx.onStop(() -> InternalThreadLocalMap.remove());
});Build items consumed by unconverted extensions need bridge proxies:
| Build Item Stores | Bridge Method |
|---|---|
RuntimeValue<T> | serviceRegistrar.staticInitServiceAsRuntimeValue(T.class) or serviceRegistrar.serviceAsRuntimeValue(T.class) |
Bare T (interface) | serviceRegistrar.staticInitServiceAsRecorderValue(T.class) or serviceRegistrar.serviceAsRecorderValue(T.class) |
Bare T (concrete) | Use RuntimeValue variant — concrete classes may not be proxyable |
Recorder proxies resolve via startupContext.getServiceValue() (for
__service$$value() proxies) or startupContext.getValue() (for
standard recorder proxies). The service deploy body stores values in
the serviceValues map for this resolution.
Before:
Supplier<MyBean> supplier = recorder.createBeanSupplier(args);
SyntheticBeanBuildItem.configure(MyBean.class).supplier(supplier).done();After:
serviceRegistrar.forService(MyBean.class, "my-bean-name")
.onStart(ctx -> new MyBean(args));
SyntheticBeanBuildItem.configure(MyBean.class)
.serviceValue(MyBean.class, "my-bean-name")
.done();Register cleanup via ctx.onStop(Runnable) or
ctx.onStopAsync(Consumer<AsyncStopContext>). Stop handlers run in
reverse dependency order.
addLastShutdownTask() is deprecated — its per-node "last" semantics
don't provide global ordering. Use before() to ensure your service
stops after the services it cleans up for.
A value-producing service must return a non-null value — the
generated code throws "...returned null; use a void service if no value is produced" otherwise. For a service whose identity is known at build time
but which may be absent at runtime (e.g. a handler gated by
quarkus.log.file.enabled), declare optional() before onStart(). This
flips the service's return type from T to Optional<T>; returning
Optional.empty() marks the service absent (nothing constructed, no side
effects) instead of failing.
serviceRegistrar.forService(Handler.class, "file")
.atPhase(Phase.LOGGING)
.require(LogRuntimeConfig.class)
.optional()
.onStart((ctx, config) -> config.file().enabled()
? Optional.of(buildFileHandler(config.file()))
: Optional.empty());Consuming an optional service:
consumeAll(T.class) skips absent producers (the map omits them).request(T.class) yields Optional.empty() when absent.require(T.class) on an optional service is a build error — a
mandatory dependency cannot depend on a maybe-absent value. Use
request() or consumeAll() instead.Do not return null from a normal (non-optional) service, and do not use a
sentinel value — optional() is the supported mechanism. (The null
tolerance in consumeAll applies only to aliased recorder values that
resolve to null, not to direct services.)
Supported captures:
String, Class, enum valuesList.of(), Set.of(), Map.of(),
Collections.singletonList/Set/Map(), Collections.empty*(),
Collections.unmodifiable*(), Set.copyOf(), List.copyOf(),
Map.copyOf()BUILD_AND_RUN_TIME_FIXED config mappings (via ConfigCaptureInterceptor)Constable values — any type implementing java.lang.constant.Constable
is captured via its describeConstable(). To make a custom value type
capturable, implement Constable with a describeConstable() that
reconstructs it (e.g. a DynamicConstantDesc invoking a static factory),
rather than registering a recorder ObjectSubstitution. Immutable
collections of Constable values (via Map.copyOf/List.copyOf) are
themselves capturable.record values — captured by reconstructing via the canonical
constructor, as long as every component is itself capturable (recursively).
Note this is the capture path; it is unrelated to the proxy path — a
record still cannot be used as an aliased recorder return type (see
"Aliased recorder return types must be proxyable" below).Not capturable:
Set.copyOf() / List.copyOf() firstBUILD_TIME config objects — extract values into localsRUN_TIME config objects — use require() insteadrequire() insteadServices get NO ordering from @Consume/@Produce annotations or
build item parameters on their build step method. Every ordering
dependency must be declared on the service itself.
If a service needs to run after a legacy recorder step, use
afterBuildItem() to depend on a build item that step produces.
staticInitServiceAsRecorderValue(ConcreteClass.class) fails if the
class has a non-trivial constructor. Use
staticInitServiceAsRuntimeValue() instead — RuntimeValue is always
proxyable.
A value published via aliasRecorderValue(T.class, recorderValue) — or any
@Recorder method whose return value is used as a recorder proxy — must have
a proxyable type: an interface or a non-final class. A record is
final, so it fails with "the return type cannot be proxied; use
RuntimeValue to wrap the return value instead". When bridging a bundle of
recorder values into a single service value, make the holder an interface
(with a nested record impl for the runtime value), or wrap it in
RuntimeValue. Abstract JDK types such as java.util.logging.Formatter and
java.util.logging.Handler are already proxyable.
Lambda bytecode runs at runtime but references runtime classes directly. Package-private classes become inaccessible from the generated consolidated class.
Solutions:
.impl subpackage and make it public.Action lambda bytecode (defined inside .onStart(ctx -> { ... })) is executed at runtime. Therefore, the lambda body must never reference, instantiate, or invoke methods on any deployment classes (such as your @BuildStep processor classes). Doing so will compile successfully but will throw a ClassNotFoundException / NoClassDefFoundError at runtime because deployment modules are absent from the runtime classpath.
new MyInterface() {}) inside an instance-method lambda forces javac to generate a constructor that captures EnclosingProcessor.this (via a synthetic this$0 parameter) to bind the inner class to its enclosing processor scope. This turns your lambda into an instance-capturing lambda (throwing a TransliterationException at build time).private static helper method inside your processor class solves the EnclosingProcessor.this capture, but because the compiled lambda still references the static helper method on your deployment processor, it causes a NoClassDefFoundError at runtime.require() instead of Arc.container()Access CDI beans through require(BeanContainer.class) and
beanInstance(). Direct Arc.container() calls bypass the dependency
graph and can cause ordering failures.
Set<String> captured = Set.copyOf(endpoints); // before the lambdaConversion must preserve behavior the recorder model provided implicitly. These are recurring, high-cost regressions — check each when converting a step that touches classloaders, threads, cleanup, or failure handling.
Recorder bytecode always ran with the runtime classloader as the TCCL
(the generated doStart sets it). Any recorder code that captured
Thread.currentThread().getContextClassLoader() for later use — request
handlers, thread factories, config/ServiceLoader lookups — relied on that.
AppClassLoader). A wrong TCCL surfaces as ServiceLoader "not a subtype"
errors or dev-mode failures, not as an obvious classloader bug.QuarkusClassLoader (metaspace growth
across test/dev restarts). Internal/scheduler threads that run no user
code should not hold an app CL. Clean up threads/ThreadLocals your
service owns in onStop; never rely on a global "reset all TCCLs" sweep.Start ordering is explicit (require/after/before) — but so is stop
ordering, and that is the easy thing to lose. The recorder model gave
cleanup incidental ordering from build-step order; a converted service's
onStop runs only in reverse dependency order. If a cleanup implicitly
depended on running before/after another (e.g. bean destruction before a
"last" task, or a listener firing before container teardown), declare it
with before()/after(). Lost teardown ordering surfaces as unrelated
downstream symptoms, so verify shutdown explicitly.
Recorders logged nothing in-band on failure — doStart caught, wrapped
in RuntimeException("Failed to start quarkus", cause), and rethrew. The
service graph rethrows the first failure (concurrent ones attach as
suppressed), so nothing is lost by staying quiet. Do not add ERROR/WARN
logging in service bodies for expected failures — let them propagate. Some
tests assert clean propagation (no WARNING+ log records, no suppressed
exceptions) for a static-init failure, e.g. StaticInitFailureTest.
consumeAll uses indexed accessconsumeAll dependencies expand to multiple consecutive entries in the
ServiceNode's dependency array (one per matching service, sorted by
name). Both ServiceGraphBuilder and LambdaTransliterator compute
the same match list using the same prefix and sort order, ensuring
index alignment.
@Record build steps in the processor@Record, add ServiceRegistrar, register servicesrequire, after, before, afterBuildItem)supplier()/runtimeValue() to serviceValue()./mvnw install the modified modules before running integration tests© quarkusio, 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
Just SKILL.md in .agents/skills/converting-recorders-to-services of quarkusio/quarkus.
Open the folder on GitHubat commit d58d0eb
Converting Recorders To Services 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 |
|---|---|---|---|---|---|---|
| Converting Recorders To Services this skillquarkusio/quarkus | 16k | — | ~4.6k | Automated safety check: Pass | Apache-2.0 | |
| Record Extension Demomengxi-ream/read-frog | 10k | — | ~2.8k | Automated safety check: Pass | GPL-3.0 | |
| Convertremotion-dev/remotion | 63k | — | ~247 | Automated safety check: Pass | Custom licence | |
| Recordingcodewhale-hq/Codewhale | 41k | — | ~540 | Automated safety check: Pass | MIT | |
| Browser Extension Buildersickn33/agentic-awesome-skills | 47k | 2 repos | ~2.3k | Automated safety check: Pass | MIT | |
| Browser Extension Launchsickn33/agentic-awesome-skills | 47k | 1 repos | ~1.4k | Automated safety check: Pass | MIT |
mengxi-ream/read-frog
Record polished, evidence-backed demos of the Read Frog extension as MP4 (and optional GIF) by driving real Chrome with the built extension, following captioned scene scripts, asserting extension…
remotion-dev/remotion
Start the local @remotion/convert app and open it in the Codex browser.
codewhale-hq/Codewhale
Capture screenshots on registered computers, record on macOS or HarmonyOS, and manage saved captures.
sickn33/agentic-awesome-skills
Expert in building browser extensions that solve real problems - Chrome, Firefox, and cross-browser extensions.
sickn33/agentic-awesome-skills
Builds, tests, packages, and prepares Chrome extensions for store launch from a plain-language idea; use for new extensions, fixes, releases, and submission recovery.
sickn33/agentic-awesome-skills
Authorized reverse engineering of Chrome/Firefox extensions: manifest analysis, background workers, content scripts, and extension-based credential or data-exposure research.
quarkusio/quarkus
Maintain @Deprecated code in the Quarkus codebase: remove code that has been deprecated for more than 12 months, add the @Deprecated annotations that were missed when a related element was…
quarkusio/quarkus
How to build and test Quarkus: Maven commands, build flags, incremental builds, justfile aliases, and important build rules.
quarkusio/quarkus
How to build, preview, and verify Quarkus documentation locally: root Maven build, docs rebuild, Roq dev server preview.
quarkusio/quarkus
Quarkus split classloading model, runtime-dev module wiring, conditional dependencies, and common classloading mistakes.
quarkusio/quarkus
How to create a new Quarkus extension: full module layout, package naming, artifact naming, dependency rules, and Dev UI setup.
quarkusio/quarkus
Rules for preparing pull requests and commits in the Quarkus project: title conventions, description format, commit hygiene, labels, and contribution policies.
Step-by-step guide for converting Quarkus extensions from the legacy @Record/@Recorder pattern to the ServiceRegistrar service system. Converting Recorders To Services is an agent skill from quarkusio/quarkus. Step-by-step guide for converting Quarkus extensions from the legacy @Record/@Recorder pattern to the ServiceRegistrar service system.
Run `npx skills add quarkusio/quarkus --skill converting-recorders-to-services -a claude-code`. Or copy the skill folder (.agents/skills/converting-recorders-to-services in quarkusio/quarkus) into .claude/skills/converting-recorders-to-services in your project. Claude Code loads it when a task matches its description.
Run `npx skills add quarkusio/quarkus --skill converting-recorders-to-services -a codex`. Or copy the skill folder (.agents/skills/converting-recorders-to-services in quarkusio/quarkus) into .agents/skills/converting-recorders-to-services 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 quarkusio/quarkus --skill converting-recorders-to-services -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/converting-recorders-to-services, .gemini/skills/converting-recorders-to-services, .github/skills/converting-recorders-to-services and .opencode/skills/converting-recorders-to-services in your project.
SKILL.md names no scripts, command-line tools or credentials: Converting Recorders To Services is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. 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.
Converting Recorders To Services 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 4.6k tokens (SKILL.md is roughly 19k 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 Converting Recorders To Services: Record Extension Demo (mengxi-ream/read-frog, 10k stars), Convert (remotion-dev/remotion, 63k stars), Recording (codewhale-hq/Codewhale, 41k stars) and Browser Extension Builder (sickn33/agentic-awesome-skills, 47k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
quarkusio (a GitHub organization) maintains it in quarkusio/quarkus, which has 15,939 GitHub stars. The repository holds 12 skills in this directory. The repository was last updated on October 9, 2026.
Source: quarkusio/quarkus on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.