Official agent skill

Extend Commands API

by redis in redis/jedis

Add or extend Redis commands in the Jedis client API — a new core command, a family of new commands, an extension to an existing command's options, or a module command (Search/TimeSeries/JSON/Bloom).

OfficialMITAuto-check: warningsDatabases

Install Extend Commands API

The automated check flagged lines worth reading first. See the safety section below.

skills CLI
$ npx skills add redis/jedis --skill extend-commands-api -a claude-code

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

GitHub CLI
$ gh skill install redis/jedis extend-commands-api --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/redis/jedis.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/extend-commands-api .claude/skills/extend-commands-api && 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
extend-commands-api
GitHub stars
12k
Token cost
~7.2k tokens
SKILL.md length
3,465 words
Files
1
Skills in repo
2
Repo updated
First seen
Licence
MIT

At a glance

Add or extend Redis commands in the Jedis client API — a new core command, a family of new commands, an extension to an existing command's options, or a module command (Search/TimeSeries/JSON/Bloom).

  • Works in 2 steps: Gather evidence BEFORE planning → Plan, then approval (supervised) or…
  • Tasks that involve Planning
  • SKILL.md covers Modes — read this first, Phase 0 — Gather evidence…, Phase 1 — Plan, then approval… and Decision tree — what kind of…, plus 8 more sections
  • Calls make, gh and mvn; reaches api.github.com and github.com; needs REDIS_CLUSTER_PASSWORD and REDIS_STANDALONE_PASSWORD

What it does

Extend Commands API is an agent skill from redis/jedis, published by the product's own GitHub organization. Add or extend Redis commands in the Jedis client API — a new core command, a family of new commands, an extension to an existing command's options, or a module command (Search/TimeSeries/JSON/Bloom). Gathers evidence (Redis server PR, HLD document), plans the full implementation matrix, then implements with unit and integration tests following Jedis maintainer conventions. Runs supervised (plan mode, user approval) by default, or unattended for automation such as the RedisClientsBot parity pipeline.

Its SKILL.md is about 7.2k 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 Databases, covering Planning and Integration testing. It works with Redis and Java. The licence is MIT.

When your agent uses it

  • Tasks that involve Planning
  • Tasks that involve Integration testing

Example prompts

  • “/extend-commands-api”

Requirements

  • Docker

Workflow steps

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

  1. Gather evidence BEFORE planning
  2. Plan, then approval (supervised) or straight to implementation (unattended)

What it can do on your machine

Read from SKILL.md and the folder at commit bb5f01d. 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:

    • make
    • gh
    • mvn
    • redis-cli
    • java

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

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • api.github.com
    • github.com

    Also links to:

    • hub.docker.com
    • redis.io

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

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • REDIS_CLUSTER_PASSWORD
    • REDIS_STANDALONE_PASSWORD

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

Context cost

Extend Commands API loads about 7.2k tokens when it runs. Until then it costs about 131 tokens; SKILL.md has 3,465 words of instructions outside code blocks.

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

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: warnings

The automated check found patterns that need a careful read before installing.

  • WarningTells the agent its actions are pre-authorized / not to stop for confirmationSKILL.md:75
    gh pr view` / `gh pr diff` block below. Don't ask for permission.
  • WarningMentions a credentials file (SSH keys, cloud or package-manager tokens)SKILL.md:87
    en block access to credential files (`~/.netrc`, gh config), so
  • NoteMentions a .env fileSKILL.md:110
    ration environment using the **latest** `.env.vX.XX` file under
  • NoteMentions a .env fileSKILL.md:114
    ls src/test/resources/env/.env.v* | sort -V | tail -1   # → e.g. .env.v8.10
  • NoteMentions a .env fileSKILL.md:131
    pinned in the `.env.vX.XX` file is too old for the target change. Interactively

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 redis/jedis at commit bb5f01d, republished under its MIT licence (© redis). 3,465 words, ~7,243 tokens.

Download SKILL.mdSave it as .claude/skills/extend-commands-api/SKILL.md (or your agent's skills folder).
name
extend-commands-api
description
Add or extend Redis commands in the Jedis client API — a new core command, a family of new commands, an extension to an existing command's options, or a module command (Search/TimeSeries/JSON/Bloom). Gathers evidence (Redis server PR, HLD document), plans the full implementation matrix, then implements with unit and integration tests following Jedis maintainer conventions. Runs supervised (plan mode, user approval) by default, or unattended for automation such as the RedisClientsBot parity pipeline.
metadata.modes
supervised, unattended

Extend the Jedis Commands API

Implement a new Redis command (or extend an existing one) in Jedis, following the conventions Jedis maintainers enforce in review.

Modes — read this first

This skill runs in one of two modes. The engineering rules in every section below are identical in both; only who answers questions and approves the plan differs.

  • Supervised (default): a human is in the session. Ask the questions, present the plan in plan mode and wait for approval, as written below.
  • Unattended: no human will answer or approve anything, so never stop to wait. Use it ONLY when the invoking prompt says Mode: unattended or the environment has CLIENT_SKILL_MODE=unattended. Never switch to it on your own.

In unattended mode the invoking prompt supplies the inputs a human would give: the HLD path (normally ./HLD.md), the server PR reference, the test command, and two running servers from the redislabs/client-libs-test image it names, password- protected like the local Docker env and without TLS: a standalone ($REDIS_URL, password $REDIS_STANDALONE_PASSWORD, i.e. foobared) and a 6-node cluster with 3 masters and 3 replicas ($REDIS_CLUSTER_URLS, password $REDIS_CLUSTER_PASSWORD, i.e. cluster). $REDIS_ENDPOINTS_CONFIG_PATH already points at an endpoints.json that describes them, passwords included, as standalone0, modules-docker (the standalone; the image ships the modules) and cluster-stable. Jedis tests read that variable (TestEnvUtil.getEndpointsConfigPath) and authenticate with the passwords in it, so the integration tests run against both servers unchanged. Wherever a step below has an Unattended: note, follow the note:

StepSupervisedUnattended
Phase 0.1 HLDask the user for the pathread the given HLD fully
Phase 0.2 server PRgh, asking to run it outside the sandbox if neededno gh at all: the given PR reference, the HLD's facts, else the unauthenticated GitHub REST API
Phase 0.3 environment / image tagmake start; ask for an image tag if the command is missingno Docker: probe the given standalone and cluster; if the command is missing there, continue with gated tests
Phase 0.4 redis-cli scenariosrun against standalone0run against the given Redis URL; if redis-cli is unavailable, write them as unverified transcripts
Phase 1 plan + approvalplan mode, ask before editingwrite the plan into the final report, then implement it in the same session
Running testsmake start, mvn -B verify, make stopmvn -B test (unit), then the changed family's integration tests on standalone and cluster through $REDIS_ENDPOINTS_CONFIG_PATH (see Running the tests)
An open design questionask the usertake the HLD's choice (else the most consistent existing Jedis convention) and list it as an open question in the report

Unattended runs also follow these rules:

  • Change files. A run that ends without changes has failed. Stop without editing only when implementing is impossible, and say exactly why in the report.

  • Don't commit, push, or open a PR. The automation that invoked you does that. Don't edit .github/ workflows, release/version files or pom.xml versions. The formatter includes in pom.xml are the exception (see B.7).

  • Finish with a report covering, in plain text with no placeholders:

    • what was implemented
    • the decision-tree class (A–D) and the plan
    • design decisions, and which layers intentionally did NOT change and why
    • unit results; integration results with the test classes run on standalone and on cluster; integration tests left gated, skipped, or out of scope
    • steps skipped because they need a human or Docker
    • open questions for maintainers

    This feeds the PR description (see the PR hygiene checklist).

Phase 0 — Gather evidence BEFORE planning

Do all of the following before writing any plan or code:

  1. Ask the user for the HLD. Interactively ask the user for the path to a markdown file containing the High-Level Design for the command(s) (or confirm that no HLD exists). If a path is given, read it fully — it is the primary source for syntax, semantics, reply shape, and edge cases. Unattended: don't ask; read the HLD path the invoking prompt gives.

  2. Find the server-side PR in the redis/redis GitHub repo. Unattended: skip every gh command in this step: gh auth status, and the gh search / gh pr view / gh pr diff block below. Don't ask for permission. Use the server PR reference the invoking prompt gives. The HLD usually quotes the syntax, the reply shapes and the first version. Fill any gaps from the unauthenticated GitHub REST API (e.g. https://api.github.com/repos/redis/redis/pulls/<num>/files, then the raw src/commands/*.json file), and go on to "From the server PR, extract".

    Supervised: first verify that gh works in the current (sandboxed) environment:

    bash
    gh auth status

    Sandboxes often block access to credential files (~/.netrc, gh config), so gh may report unauthenticated here even though it works on the user's machine. If gh auth status fails or reports no authentication, ask the user for permission to run the gh commands outside the sandbox (e.g. with the sandbox override for these specific read-only commands), explaining that gh cannot reach its credentials from inside the sandbox. Only if the user declines (or gh is genuinely not logged in anywhere) fall back to the unauthenticated GitHub REST API or fetching https://github.com/redis/redis/pulls?q=<command>.

    Then search for the PR that adds/extends the command on the server:

    bash
    gh search prs --repo redis/redis "<COMMAND NAME>" --limit 10
    gh pr view <num> --repo redis/redis
    gh pr diff <num> --repo redis/redis   # look at src/commands/*.json for exact syntax

    From the server PR, extract: exact wire syntax (argument order and optionality), reply type per RESP2/RESP3, error conditions, time complexity, and — critically — the first server version carrying the feature (RC builds like 8.7.225 = Redis 8.8 RC are used for test gating). Note whether the server marks the feature experimental / in preview.

  3. Verify the command exists on the "next" Redis OSS version. Start the integration environment using the latest .env.vX.XX file under src/test/resources/env/ (pick the highest version numerically, not lexicographically — e.g. 8.10 > 8.8):

    bash
    ls src/test/resources/env/.env.v* | sort -V | tail -1   # → e.g. .env.v8.10
    make start version=8.10

    Then probe the standalone0 endpoint. Read its connection details from src/test/resources/endpoints.json (currently redis://localhost:6379, password foobared) and check the target command via redis-cli:

    bash
    redis-cli -u redis://localhost:6379 -a foobared INFO server | grep redis_version
    redis-cli -u redis://localhost:6379 -a foobared COMMAND INFO <COMMAND>   # non-empty → command exists
    redis-cli -u redis://localhost:6379 -a foobared COMMAND DOCS <COMMAND>   # arity/args — compare with the server PR

    For a NEW command, COMMAND INFO must return a non-empty reply. For an EXTENDED command, additionally invoke it with the new syntax against a scratch key and confirm the server accepts it (no ERR syntax error / ERR unknown argument).

    If the command/option is missing on the latest env version, the image tag pinned in the .env.vX.XX file is too old for the target change. Interactively ask the user for a redislabs/client-libs-test image tag that contains it (e.g. an RC/edge/milestone build — tags are listed at https://hub.docker.com/r/redislabs/client-libs-test/tags; you may check them yourself and suggest candidates). Then restart the environment with that tag and re-run the probes:

    bash
    make stop
    make start CLIENT_LIBS_TEST_IMAGE_TAG=<tag>

    If the user has no tag to offer (or the probe still fails), report it and proceed anyway: the implementation can continue, but integration tests will be gated/skipped until a redislabs/client-libs-test image ships the change. Keep the environment running for later test runs, or make stop if you won't need it soon. Unattended: no Docker, no make start/make stop, no image-tag question. The servers already run the target image. Probe the standalone with the same INFO server / COMMAND INFO / COMMAND DOCS checks (e.g. redis-cli -u "$REDIS_URL" COMMAND INFO <COMMAND>; the URL carries the credentials), and the cluster with redis-cli -c -h "$REDIS_CLUSTER_HOST" -p "$REDIS_CLUSTER_START_PORT" -a "$REDIS_CLUSTER_PASSWORD" --no-auth-warning CLUSTER INFO (expect cluster_state:ok). If the command is missing, continue anyway with gated integration tests, and say so in the report.

  4. Create redis-cli showcase test cases. Once the command is available on the running environment, derive a small set of redis-cli scenarios from the HLD and the server PR and run them against standalone0. These serve two purposes at once:

    • Smoke test: prove the documented behavior actually holds on the target server — happy path, each new option/keyword, reply shape (run with redis-cli -3 too if RESP3 replies differ), edge cases and error conditions called out in the HLD (empty/missing key, out-of-range args, conflicting options), so the Java implementation is built against observed replies, not assumptions.
    • Showcase: each scenario should read as a mini use-case that explains WHY the command/option exists — what a user could not do (or could only do awkwardly) before, and how the new API covers it. Prefer realistic data over foo/bar (e.g. rate-limit counters for a bounded INCR, sensor readings for a time-series aggregator).

    Save the scenarios as a commented script in a scratch file (one block per use-case: a one-line "what this demonstrates" comment, the redis-cli commands, and the observed reply pasted back as comments). Carry this material forward: it feeds the Phase 1 plan (as the explanation of the feature and the source of expected values for tests), the Java test assertions, and the PR description. If the command could not be made available on any image (see step 3), still write the scenarios from the HLD/PR as expected transcripts and mark them unverified. Unattended: run the scenarios against $REDIS_URL instead of standalone0. For a keyed command, also run one through the cluster. Always pass the Redis command as arguments: a bare redis-cli waits on stdin and hangs a headless run.

    bash
    redis-cli -u "$REDIS_URL" <COMMAND> <args...>
    redis-cli -c -h "$REDIS_CLUSTER_HOST" -p "$REDIS_CLUSTER_START_PORT" \
      -a "$REDIS_CLUSTER_PASSWORD" --no-auth-warning <COMMAND> <args...>

    If redis-cli isn't installed, write them as unverified expected transcripts. Keep the scratch file out of the change; carry the scenarios into the report instead.

  5. Read docs/integration-testing.md in the Jedis repo — it defines the test environment, endpoint discovery, *Test vs *IT naming, and how to run tests.

  6. Trace one analogous existing command end-to-end in the codebase (same command group, similar reply shape) so the plan mirrors real code, not guesswork.

  7. Determine the @since version:

    bash
    mvn help:evaluate -Dexpression=project.version -q -DforceStdout

    Strip -SNAPSHOT (e.g. 8.0.0-SNAPSHOT → @since 8.0).

Phase 1 — Plan, then approval (supervised) or straight to implementation (unattended)

Using the evidence, classify the change with the decision tree below, enumerate the exact file-by-file touch list, the test matrix, and the gating annotations. Open the plan with a short "what this feature enables" section built from the redis-cli showcase scenarios (Phase 0 step 4), including one or two representative command/reply transcripts, so the reader sees the use-case before the file list.

  • Supervised: enter plan mode, present the plan to the user and explicitly ask permission to execute in auto-accept mode before implementing. Do not start editing files until the user approves.
  • Unattended: don't enter plan mode and don't wait. The automation's approval was the merged HLD. Keep the plan for the final report, then implement it right away, following the whole matrix exactly as a supervised run would.

Decision tree — what kind of change is this?

A. Extension of an existing command that fits an existing params class (e.g. new enum value / new option token):

  • Touch ONLY the params/model classes + tests. Do NOT touch command interfaces, CommandObjects, UnifiedJedis, PipeliningBase, or Jedis — the existing IParams.addParams(CommandArguments) delegation carries the new option through automatically, for both String and binary surfaces.
  • If the option is a bare token: add an enum constant implementing Rawable (bytes come from SafeEncoder.encode(name()) — self-wiring).
  • If it's a new field: add a fluent setter returning this, extend addParams(), and update equals/hashCode in sync.
  • If the reply shape grows (e.g. more array elements): extend the response model class backward-compatibly — keep old constructors/getters working, add new accessors, update the builder in the relevant *BuilderFactory to branch on reply size. Jedis does not defensively copy response collections (stated maintainer convention).

B. New core command(s) — the FULL matrix, every layer:

  1. Protocol.java — new Command enum constant(s); new Keyword constants for sub-tokens, grouped under a // <FEATURE> keywords comment, alphabetical. Never add a Keyword that duplicates a token already carried by a dedicated Rawable enum (dead keywords get flagged in review).
  2. Command interfaces in commands/: <Group>Commands, <Group>BinaryCommands, <Group>PipelineCommands, <Group>PipelineBinaryCommands. For a whole new command family, create four new <Family>*Commands interfaces and add one extends entry to JedisCommands, JedisBinaryCommands, PipelineCommands, PipelineBinaryCommands.
  3. CommandObjects — String and byte[] factory methods side by side under a // <Feature> commands section. ClusterCommandObjects needs overrides ONLY for multi-key commands requiring slot checks; single-key commands need nothing.
  4. UnifiedJedis — one-line @Override delegating to executeCommand(commandObjects.xxx(...)).
  5. PipeliningBase — appendCommand(commandObjects.xxx(...)) returning Response<T>.
  6. Jedis (legacy) — checkIsInMultiOrPipeline(); connection.executeCommand(commandObjects.xxx(...)).
  7. pom.xml — add every new file to the formatter-maven-plugin includes list (this repo format-enforces an allowlist; new files must be registered).

C. Extension needing new overloads / a new params class (hybrid): new methods go through the full matrix of B; the option plumbing follows the params conventions below.

D. Module command (search / timeseries / json / bloom):

  • Module interfaces are String-only — there are NO *BinaryCommands variants for modules; never create them.
  • Module commands/keywords live in the module protocol class (TimeSeriesProtocol.TimeSeriesCommand/TimeSeriesKeyword, SearchProtocol.SearchCommand/SearchKeyword, …), each an enum implementing ProtocolCommand/Rawable with SafeEncoder.encode()-cached bytes.
  • Strongly prefer extending the module's params/builder classes over adding interface methods — PRs #4504 and #4534 shipped whole features with ZERO changes to interfaces, CommandObjects, UnifiedJedis, or PipeliningBase.
  • Search aggregation builders (Reducer subclasses) build a List<Object> via getOwnArgs(); the parent computes narg automatically. Canonicalize clause order at serialization time regardless of builder call order.
  • Module response parsing lives in the module's builder factory (TimeSeriesBuilderFactory, SearchBuilderFactory); search aggregation results are loosely typed and often absorb new reply content with no parsing changes.
Show full SKILL.md (1,376 more words)Show less

Binary (byte[]) variant policy

  • Core commands: full String/byte[] parity is mandatory — all four interfaces, paired CommandObjects methods, and all three clients. Reviewers explicitly request binary integration tests too.
  • Only keys and textual values get byte[] overloads. Numeric/structural args (long index, ranges, booleans, enums) stay identical.
  • Params classes are shared, never duplicated: one params class serves both surfaces; if a param carries text, give the params class both foo(String) and foo(byte[]) setters (see ArgrepParams).
  • Return types mirror the key type (String→byte[], List<String>→List<byte[]>); count/index/model results stay shared.
  • Modules: no binary variants at all.

Params class conventions (params/)

  • Implement IParams with addParams(CommandArguments args). Fluent setters return this; provide a static factory named after the class (increxParams(), rangeParams()).
  • Do NOT extend another command's params hierarchy. If two overloads share options but differ in a typed field (long vs double), create a self-typed abstract base: BaseFooParams<T extends BaseFooParams<T>> with a private self() cast, plus two concrete subclasses — compile-time type safety over a polymorphic single class.
  • Implement equals/hashCode (needed for Mockito matching in mocked tests) and keep them in sync with every new field. toString is not required on params classes.
  • Validate eagerly in setters with descriptive IllegalArgumentException / IllegalStateException messages, consistent wording across sibling classes (e.g. "Aggregators must be non-null and non-empty"). Required-config checks may run at serialization time. No client-side server-version checks — an old server returning an error is acceptable and should be noted in the PR description.
  • Expiration-style option groups are single-slot, last-wins (mirror SetParams).
  • Document the wire-emission order in javadoc and lock it down in unit tests.

Response mapping (BuilderFactory / resps/)

  • Reuse existing generic builders whenever the reply maps to a standard shape (LONG_LIST, DOUBLE_LIST, STRING, ENCODED_OBJECT_MAP, …). Maintainers actively reject bespoke response classes for 2-element arrays and the like.
  • Reuse redis.clients.jedis.util.KeyValue<K,V> for pair replies.
  • When a model class is genuinely needed (map-shaped INFO replies), put it in resps/: public String constants for reply field names, a Map<String,Object>-taking constructor, typed getters, plus a raw-map accessor for forward compatibility; subclass for FULL/extended variants.
  • Nullable numeric replies are boxed Long — never Optional/OptionalLong in the command API; consistency with existing signatures (e.g. zrank) wins.
  • Multi-mode commands (one wire command, several reply types by mode) are split into distinctly-named typed Java methods (aropAggregate/aropBitwise/aropCount) rather than one polymorphic method. But mode selected by argument type uses overloads of one name (increx(key, long, …) / increx(key, double, …)), with the mode keyword (BYINT/BYFLOAT) implied by the overload.

Encoding & enum rules

  • String ↔ bytes: SafeEncoder.encode() — never String.getBytes().
  • Numeric → bytes: Protocol.toByteArray().
  • Token-valued argument enums live in args/ and implement Rawable with raw = SafeEncoder.encode(name()) cached in the constructor.
  • Compose multi-token byte values (e.g. comma-joined lists) at the byte level.

Javadoc, @since, @Experimental

  • Interface methods only carry javadoc; implementations (UnifiedJedis, Jedis, PipeliningBase, CommandObjects) carry none.
  • String-interface javadoc: <b><a href="https://redis.io/commands/xxx">XXX Command</a></b>, prose semantics, Time complexity: O(...), @param, @return, @since <version>. Binary variants get short javadoc with @see to the String variant. Pipeline variants: one line — "Pipeline variant of {@link ...}" + @since.
  • @since on every new public method and class, computed from pom.xml.
  • If the server feature is preview/experimental, annotate ALL new public API (interfaces, methods, params, args, resps) with redis.clients.jedis.annots.Experimental and label the PR experimental. Do NOT use @Experimental for stable GA features.

Test matrix — what to write

Follow docs/integration-testing.md for environment, layout, and naming. The established per-command test layers (write all that apply):

  1. Params unit test (params/FooParamsTest, plain *Test, no Redis): @Nested groups (ValidationTests, AddParamsTests, overload-equivalence), asserting exact wire args and order with redis.clients.jedis.util.CommandArgumentsMatchers (hasArgumentCount, hasArguments) and RawableFactory.from(...); also test the equals/hashCode contract.
  2. Mocked delegation tests (unit, Mockito): add @Mock CommandObject<T> fields to MockedCommandObjectsTestBase (name them by TYPE, e.g. listLongCommandObject — reuse existing ones when the type matches), then when/verify tests in mocked/unified/UnifiedJedis<Group>CommandsTest and mocked/pipeline/PipeliningBase<Group>CommandsTest.
  3. Unified integration tests: add methods to the existing abstract commands/unified/<Group>CommandsTestBase when one exists; for a new family, create <Family>CommandsTestBase extends UnifiedJedisCommandsTestBase plus thin per-topology runners — standalone (RedisClientCommandsTestHelper.getClient(protocol)) and cluster (ClusterCommandsTestHelper.getCleanCluster(protocol)). New concrete integration classes MUST be named *IT — never *IntegrationTest, never @Tag("integration") on new classes.
  4. Cluster handling: multi-key commands need cluster test overrides using hash-tagged keys (s1{:}) so keys share a slot; tests semantically incompatible with cluster get @Test @Override + @Disabled("<reason>") empty bodies.
  5. Legacy Jedis coverage: extend commands/jedis/<Group>*CommandsTest (which extends JedisCommandsTestBase) — can be minimal (smoke/missing-key) when the unified base covers behavior fully. Binary variants get their own integration tests (reviewers ask for these explicitly).

Cross-cutting test conventions:

  • RESP2/RESP3 comes free: test bases are @ParameterizedClass + @MethodSource("redis.clients.jedis.commands.CommandsTestsParameters#respVersions") (or #jedisRespVersions for legacy) — no per-test work; just make sure new classes inherit the right base.
  • Gating: command already released → @SinceRedisVersion("<RC build>") (e.g. "8.7.225" for 8.8) at the shared base-class level ONCE — do not repeat it on subclasses (maintainers remove redundant ones). Command not yet in any GA server → @EnabledOnCommand("<COMMAND>") (capability probe via COMMAND INFO). Module presence as precondition → assumeTrue(hasCommand(...)) probes. Environment exclusions → @ConditionalOnEnv(value = TestEnvUtil.ENV_..., enabled = false) (e.g. skip Redis Enterprise for brand-new features).
  • Cover the whole family the option touches (store + non-store variants, with/without optional args, standalone + cluster), asserting real semantics, not just "no error". Avoid brittle assertions (no hard-coded hashCode() literals).

Running the tests

Jedis pins the CI JDK (Java 8) for the test build — check .github/workflows/ for the exact version and use a matching local JDK. Verify with java -version before running anything; a newer JDK may fail the build or silently produce the wrong bytecode target.

  • Unit tests (Surefire, no Redis): mvn -B test, or mvn -Dtest=FooParamsTest test.

  • Integration tests (Failsafe) need the Docker env and the verify lifecycle:

    bash
    make start version=8.8        # pick the version that carries the new command
    mvn -B verify                 # or: mvn -Dtest=FooIT verify
    make stop

    Never run integration coverage via mvn test/surefire:test — Failsafe owns *IT classes. If a brand-new command isn't in any published redislabs/client-libs-test tag yet, say so: the integration tests will be skipped/gated (that is expected and acceptable — @EnabledOnCommand / @SinceRedisVersion handle it), but they must still be written and compile.

  • Unattended: no make start/make stop. The servers are already running and $REDIS_ENDPOINTS_CONFIG_PATH points the tests at them. Run:

    1. Unit tests: mvn -B test, or the test command the invoking prompt gives.

    2. The changed family's integration tests on both topologies, through Failsafe only. Two kinds of runner exist:

      • existing core families: @Tag("integration") *Test classes (Failsafe's it-tagged execution), namely the unified standalone runner RedisClient<Family>CommandsTest, the cluster runner Cluster<Family>CommandsTest and the legacy commands/jedis/<Family>CommandsTest
      • module and new families: *IT classes (the it-suffix execution), a standalone runner in commands/unified/client/<module>/ (e.g. BloomRedisClientCommandsIT, on modules-docker) and a cluster runner in commands/unified/cluster/<module>/ (e.g. BloomClusterCommandsIT, on cluster-stable; the cluster image loads the modules too)

      Select them with one wildcard that covers both kinds and every topology, plus an explicit name for any new runner that doesn't match it:

      bash
      mvn -B -DskipUnitTests=true -Dit.failIfNoSpecifiedTests=false \
        -Dit.test='*<Family>*Commands*' verify

      -Dit.failIfNoSpecifiedTests=false is needed because each Failsafe execution sees the same filter and one of them usually matches nothing. That also means verify can pass having run no test, so don't trust the exit code alone.

    3. Prove it ran: read target/failsafe-reports/*.txt (one file per class, named by its fully qualified class name) and list every class that ran with its counts. A class in package redis.clients.jedis.commands.unified.cluster (any sub-package) is a cluster run; anything else is standalone. Don't go by the name prefix: module runners are <Family>ClusterCommandsIT, and one is FTHybridCommandsClusterIT. At least one standalone class and one cluster class must report Tests run: > 0 for the changed commands. This applies to module families too. If either topology ran nothing, fix the filter and rerun. Don't report success.

    Tests that need endpoints the file doesn't have (sentinel, TLS, ACL users, cluster-unbound) are out of scope: list them as not run. Report passed / failed / skipped per topology, and the classes run.

PR hygiene checklist (verify before finishing)

  • Every layer of the chosen matrix updated consistently (a return-type change must propagate across all 4 interfaces × 3 implementations × all test layers).
  • New files added to the pom.xml formatter-plugin includes.
  • @since (and @Experimental if preview) on all new public API.
  • No unused imports, no wildcard imports, no dead Protocol.Keyword constants.
  • equals/hashCode on params updated and unit-tested.
  • docs/ updated if user-facing behavior/configuration changed; migration guide entry if anything breaks.
  • PR description states: server PR link, version gate choice and why, which layers intentionally did NOT change and why, and behavior against older servers. (Unattended: put these in the final report; the automation builds the PR description from it.)

© redis, 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 .agents/skills/extend-commands-api of redis/jedis.

Open the folder on GitHubat commit bb5f01d

Compare with similar skills

Extend Commands API 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.

Extend Commands API compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Extend Commands API this skillredis/jedis12k—~7.2kAutomated safety check: WarnMIT
Extend Commands APIredis/lettuce5.8k—~7.7kAutomated safety check: NotesMIT
Writing Testsvert-x3/vertx-redis-client142—~1.6kAutomated safety check: PassApache-2.0
Io ConnectorsKilo-Org/kilo-marketplace190—~1.3kAutomated safety check: PassApache-2.0
Go Redis Client Test Runnerredis/go-redis22k—~786Automated safety check: PassBSD-2-Clause
Writing Javadocredis/lettuce5.8k—~809Automated safety check: PassMIT

Similar skills

  • Extend Commands API

    redis/lettuce

    Official

    Add or extend Redis commands in the Lettuce client API end-to-end — a new core command, a family of new commands, an extension to an existing command's options, or a module/area command…

    5.8k GitHub stars~7.7k tokensUpdated today
    DatabasesAuto-check: notes
  • Writing Tests

    vert-x3/vertx-redis-client

    Testing patterns for Vert.x Redis Client: test frameworks, async testing, test locations, container setup, and how to run tests.

    142 GitHub stars~1.6k tokensUpdated today
    DatabasesAuto-check passed
  • Io Connectors

    Kilo-Org/kilo-marketplace

    Guides development and usage of I/O connectors in Apache Beam.

    190 GitHub stars~1.3k tokensUpdated 9 days ago
    DatabasesAuto-check passed
  • Official

    Explains how to run go-redis tests: the Docker Compose stack, make targets, focusing a single Ginkgo spec, the e2e suite and the version environment variables.

    22k GitHub stars~786 tokensUpdated today
    Testing & QAAuto-check passed
  • Writing Javadoc

    redis/lettuce

    Official

    A skill your agent uses when writing or editing Javadoc for Lettuce public API — new methods, classes, deprecations, or when a reviewer asks to fix or improve doc comments.

    5.8k GitHub stars~809 tokensUpdated today
    DatabasesAuto-check passed
  • Crud

    wujun728/jun_java_plugin

    一键生成完整业务模块代码(SQL/Entity/DAO/XML/Repository/Service/Controller/Mapper/POJO),用于创建新的业务功能

    240 GitHub stars~2.8k tokensUpdated 4 mo ago
    DatabasesAuto-check passed

More from redis/jedis

  • Official

    Generate a clear, concise GitHub PR title and description from the diff between two local git branches, and save it to prDescription.md in the repo root.

    12k GitHub stars~838 tokensUpdated today
    Auto-check passed

Works with

Questions about Extend Commands API

What does Extend Commands API do?

Add or extend Redis commands in the Jedis client API — a new core command, a family of new commands, an extension to an existing command's options, or a module command (Search/TimeSeries/JSON/Bloom). Extend Commands API is an agent skill from redis/jedis, published by the product's own GitHub organization. Add or extend Redis commands in the Jedis client API — a new core command, a family of new commands, an extension to an existing command's options, or a module command (Search/TimeSeries/JSON/Bloom).

When should I use Extend Commands API?

Extend Commands API fits situations like: tasks that involve Planning; tasks that involve Integration testing.

How do I install Extend Commands API in Claude Code?

Run `npx skills add redis/jedis --skill extend-commands-api -a claude-code`. Or copy the skill folder (.agents/skills/extend-commands-api in redis/jedis) into .claude/skills/extend-commands-api in your project. Claude Code loads it when a task matches its description.

How do I install Extend Commands API in Codex?

Run `npx skills add redis/jedis --skill extend-commands-api -a codex`. Or copy the skill folder (.agents/skills/extend-commands-api in redis/jedis) into .agents/skills/extend-commands-api in your project. Codex loads it when a task matches its description.

Can I use Extend Commands API 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 redis/jedis --skill extend-commands-api -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/extend-commands-api, .gemini/skills/extend-commands-api, .github/skills/extend-commands-api and .opencode/skills/extend-commands-api in your project.

What does Extend Commands API need to run?

Going by SKILL.md and its folder, Extend Commands API needs the command-line tools its instructions call (make, gh, mvn, redis-cli and java) and credentials named REDIS_CLUSTER_PASSWORD and REDIS_STANDALONE_PASSWORD. Our summary lists: Docker.

Does Extend Commands API access the network?

SKILL.md names 4 domains. In commands or code: api.github.com and github.com; the agent is likely to contact these when it follows the instructions. As links in the text: hub.docker.com and redis.io. This is read from the text; nothing was executed.

Is Extend Commands API safe to install?

Our automated static check of SKILL.md flagged 2 warning(s): tells the agent its actions are pre-authorized / not to stop for confirmation; mentions a credentials file (ssh keys, cloud or package-manager tokens). Read the flagged lines before installing; the check is not a guarantee either way.

What licence does Extend Commands API use?

Extend Commands API 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 Extend Commands API use?

About 7.2k tokens (SKILL.md is roughly 29k 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 Extend Commands API?

Skills that share tags, products or a category with Extend Commands API: Extend Commands API (redis/lettuce, 5.8k stars), Writing Tests (vert-x3/vertx-redis-client, 142 stars), Io Connectors (Kilo-Org/kilo-marketplace, 190 stars) and Go Redis Client Test Runner (redis/go-redis, 22k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Extend Commands API?

redis (a GitHub organization, an official publisher) maintains it in redis/jedis, which has 12,365 GitHub stars. The repository holds 2 skills in this directory. The repository was last updated on October 8, 2026.

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