Fishjam JS Server SDK
software-mansion-labs/skills
Node.js / TypeScript server SDK for Fishjam — backends that create rooms, mint peer tokens, listen to server notifications, and run agents.
A skill your agent uses when building or operating a plain Node.js / Express 5 backend service: project layout, async correctness, central error middleware, fail-fast config, graceful shutdown on…
$ npx skills add ericrisco/rsc-harness --skill nodejs -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ericrisco/rsc-harness nodejs --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/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/nodejs .claude/skills/nodejs && 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 "nodejs" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/nodejs into .claude/skills/nodejs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "nodejs", 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/ericrisco/rsc-harness/tree/main/skills/nodejsType 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 ericrisco/rsc-harness --skill nodejs -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ericrisco/rsc-harness nodejs --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/nodejs .agents/skills/nodejs && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "nodejs" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/nodejs into .agents/skills/nodejs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "nodejs", 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 ericrisco/rsc-harness --skill nodejs -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ericrisco/rsc-harness nodejs --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/nodejs .cursor/skills/nodejs && 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 "nodejs" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/nodejs into .cursor/skills/nodejs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "nodejs", 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/ericrisco/rsc-harness.git --path skills/nodejs--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 ericrisco/rsc-harness --skill nodejs -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ericrisco/rsc-harness nodejs --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/nodejs .gemini/skills/nodejs && 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 "nodejs" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/nodejs into .gemini/skills/nodejs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "nodejs", 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 ericrisco/rsc-harness nodejsInstalls 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 ericrisco/rsc-harness --skill nodejs -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/nodejs .github/skills/nodejs && 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 "nodejs" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/nodejs into .github/skills/nodejs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "nodejs", 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 ericrisco/rsc-harness --skill nodejs -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install ericrisco/rsc-harness nodejs --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/nodejs .opencode/skills/nodejs && 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 "nodejs" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/nodejs into .opencode/skills/nodejs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "nodejs", 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.
nodejsA skill your agent uses when building or operating a plain Node.js / Express 5 backend service: project layout, async correctness, central error middleware, fail-fast config, graceful shutdown on…
Nodejs is an agent skill from ericrisco/rsc-harness. Use when building or operating a plain Node.js / Express 5 backend service: project layout, async correctness, central error middleware, fail-fast config, graceful shutdown on SIGTERM. NOT DI modules/providers/guards (that is nestjs), NOT the type system or tsconfig (that is typescript), NOT REST contract design (that is api-design).
Its SKILL.md is about 3.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/express5-migration.md`).
It sits in Backend & APIs, covering API design. It works with Node.js, TypeScript and NestJS. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.
5 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit e3d5b33. 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.
Ships 1 file in scripts/ (Shell), which the agent can run.
Shell commands in SKILL.md call:
nodeFrom 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.
Nodejs loads about 3.2k tokens when it runs, and up to ~4.7k if it reads all its reference files. Until then it costs about 87 tokens; SKILL.md has 1,086 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); the scripts in this folder are not scanned.
The full file from ericrisco/rsc-harness at commit e3d5b33, republished under its MIT licence (© ericrisco). 1,086 words, ~3,188 tokens.
.claude/skills/nodejs/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.Stand up a plain Node.js HTTP/JSON service — node:http or Express 5 — that a person can read, test, and operate without a DI framework. This skill is about the runtime and the request lifecycle: how to lay out the code, how to keep async correct, how errors become status codes, how config fails fast, and how the process dies cleanly. The contract shape, the type system, and the data layer live elsewhere (see the boundary below).
@Module / @Injectable / DI providers, guards, interceptors, pipes, exception filters → nestjs. Nest starts the moment the DI container appears; route away then, do not half-build it here.tsconfig → typescript. This skill uses TS but does not teach types.api-design. This skill wires the handlers; api-design decides the contract. Cross-cutting error taxonomy → error-handling.postgresdb / prisma-orm / drizzle-orm. Calling a repository stays here; designing the table does not.docker / deployment. Choosing the logging/metrics/tracing stack → observability. This skill emits structured logs and a shutdown hook; it does not own the pipeline.Pick the runtime shape before writing code — the wrong choice is expensive to undo.
| Situation | Choice | Why |
|---|---|---|
| Needs DI/modules, large team, heavy cross-cutting | route to nestjs | Don't reinvent a DI container by hand |
| Small/medium JSON API, want middleware + routing | Express 5 | Mature, async errors auto-forward (v5) |
| One tiny endpoint, zero deps, a healthcheck | node:http | No dependency surface to maintain |
| A library, not a server | not this skill | No request lifecycle to manage |
Defaults for a new service: pin Node 24 (Active LTS) in engines.node; Node 22 is Maintenance LTS; Node 26 is Current (released 2026-05-05, enters LTS Oct 2026) — adopt it only if you want Temporal/V8 14.6 and can track Current. Write ESM for new code ("type": "module"), CommonJS only when a hard dependency forces it.
// package.json
{
"type": "module",
"engines": { "node": ">=24" },
"scripts": {
"dev": "node --watch src/server.ts",
"test": "node --test"
}
}Concrete tree. The names are conventions, not magic — but the split is load-bearing.
src/
app.ts # build + return the Express app; NEVER calls listen()
server.ts # imports app, listens, owns SIGTERM/shutdown
config/
env.ts # validate process.env once, export a typed `config`
routes/
users.ts # router only: path → controller
controllers/
users.ts # parse request, call service, shape response
services/
users.ts # business logic, no req/res objects
repositories/
users.ts # data access; the only layer that touches the DB
errors/
app-error.ts # AppError/HttpError with status + codeRule — separate app construction from listen(). app.ts builds and returns the app; server.ts binds the port and owns shutdown. Why: tests import app and exercise routes in-process without binding a port, so they run fast and in parallel.
// Bad: index.ts listens at import time — untestable, double-binds in tests
const app = express();
app.get("/health", (_req, res) => res.json({ ok: true }));
app.listen(3000); // side effect on import
// Good: app.ts
export function buildApp() {
const app = express();
app.get("/healthz", (_req, res) => res.json({ ok: true }));
return app; // no listen here
}Every async mistake here is a latent production incident, not a style nit.
util.promisify or fs/promises) and stay in promises after that. Half-converted code swallows errors.Promise.all for independent work; sequential await only for true dependencies. Awaiting independent calls one by one wastes wall-clock time.AbortSignal.timeout(ms) for per-operation deadlines and thread the signal into fetch/DB/long ops. Compose with AbortController so shutdown can cancel in-flight work (see graceful shutdown).unhandledRejection handler as control flow. Log and exit there if anything; do not use it to keep running.// Bad: forgotten await — the rejection floats and crashes later, error lost
function handler(req, res) {
saveAudit(req.body); // returns a promise nobody awaits
res.json({ ok: true }); // responds before save resolves/rejects
}
// Good: await it (Express 5 forwards a throw to the error middleware)
async function handler(req, res) {
await saveAudit(req.body);
res.json({ ok: true });
}This is the core, and the most common bug. In Express 5 an async handler that rejects or throws is auto-forwarded to the error middleware — no try/catch + next(err) wrapper, no asyncHandler. Source: Express 5 migration guide and the framework's own router tests (a value-less Promise.reject() becomes an Error with message Rejected promise).
AppError (or HttpError) carrying status and code. Throw it from services; controllers don't translate.(err, req, res, next) error middleware, LAST, after every route. Arity is what makes Express treat it as an error handler — a 3-arg function is a normal middleware no matter what you name it. Order still matters in v5.// errors/app-error.ts
export class AppError extends Error {
constructor(public status: number, public code: string, message: string) {
super(message);
}
}
// app.ts — registration ORDER (routes → 404 → error handler)
app.use("/users", usersRouter);
app.use((_req, res) => res.status(404).json({ code: "not_found" }));
// LAST, exactly 4 args — this is the error handler
app.use((err, _req, res, _next) => {
const status = err instanceof AppError ? err.status : 500;
const code = err instanceof AppError ? err.code : "internal_error";
if (status >= 500) logger.error({ err }, "unhandled");
res.status(status).json({
code,
message: status < 500 ? err.message : "Internal Server Error",
...(process.env.NODE_ENV !== "production" && { stack: err.stack }),
});
});// Bad: the symptom "async route throws but client gets 200 empty body"
app.use((err, _req, res, _next) => { /* error handler */ }); // registered FIRST
app.get("/users/:id", async (req, res) => {
const u = await findUser(req.params.id); // throws NotFound
res.json(u); // never reached; no handler after → hangs/empties
});The error handler placed before the route never sees the throw, so the response is whatever was half-written. Put it last. See references/express5-migration.md for the full v4→5 breaking-change checklist, the middleware-order diagram, and the legacy v4 asyncHandler wrapper.
Validate process.env once at boot, fail fast, and export a typed config object. A missing variable should crash at startup, not at 3am on first use. Ban scattered process.env.X reads throughout the codebase — they hide the contract and defeat the boot check.
// config/env.ts — hand-rolled or zod/envalid; the point is one gate
import { z } from "zod";
const schema = z.object({
PORT: z.coerce.number().default(3000),
DATABASE_URL: z.string().url(),
NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
});
export const config = schema.parse(process.env); // throws → process won't startOn SIGTERM the orchestrator gives you a brief window to finish. Drop nothing.
server.close() — stop accepting new connections, let in-flight requests finish.AbortController (the signal you threaded into ops).process.exit(0), with a force-exit timer as a backstop if drain stalls.Expose /healthz (liveness — is the process up) separately from /readyz (readiness — should it receive traffic). They answer different questions; conflating them causes both false restarts and dropped requests during deploys. The complete copy-pasteable server.ts — signal handlers, AbortController, readiness gate, force-exit backstop — lives in references/graceful-shutdown.md.
// server.ts (sketch — full version in references/)
const controller = new AbortController();
const server = buildApp().listen(config.PORT);
function shutdown() {
ready = false; // /readyz now 503
server.close(() => process.exit(0)); // drain, then exit
controller.abort(); // cancel in-flight long ops
setTimeout(() => process.exit(1), 10_000).unref(); // backstop
}
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);Node 24 ships a built-in test runner — node:test with node --test — so a backend needs no external runner for unit/integration tests, and node --watch for dev. Import app from app.ts and hit it directly (supertest or undici); never start the live server in a test. That is exactly why app.ts doesn't call listen().
import { test } from "node:test";
import assert from "node:assert/strict";
import request from "supertest";
import { buildApp } from "../src/app.ts";
test("404 returns the error contract", async () => {
const res = await request(buildApp()).get("/nope");
assert.equal(res.status, 404);
assert.equal(res.body.code, "not_found");
});| Anti-pattern | Why it bites | Do instead |
|---|---|---|
Floating promise (no await/return) | Unhandled rejection crashes the process (Node 15+), error detached | Await or return every promise |
| Error middleware with 3 args or not last | Express never treats it as an error handler; throws fall through | 4 args (err,req,res,next), registered LAST |
Reading process.env.X everywhere | Missing var fails at 3am, contract is invisible | Validate once in config/env.ts, export typed config |
listen() inside app.ts | Side effect on import; tests bind a port / double-listen | app.ts returns app, server.ts listens |
catch (e) {} then continue | Swallows the failure, masks the bug | Re-throw, or map to an AppError |
process.exit() without draining | Drops in-flight requests on deploy | SIGTERM → server.close() → abort → exit |
Global unhandledRejection as control flow | Hides bugs, leaves process in a bad state | Log + exit there; fix the floating promise |
| Assuming Express 4 defaults | v5: urlencoded extended:false, static dotfiles:"ignore" | Read references/express5-migration.md |
| Leaking stack/message in prod | Information disclosure | Stack only when NODE_ENV !== "production" |
scripts/verify.sh statically lints a produced repo for these rules (4-arg error handler last, no listen() in app.ts, engines.node supported, floating-promise heuristic). Advisory; hard-fails only on listen() in app.ts or a missing error handler.
© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 5 other files (scripts, references) in skills/nodejs of ericrisco/rsc-harness.
Open the folder on GitHubat commit e3d5b33
Nodejs 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 |
|---|---|---|---|---|---|---|
| Nodejs this skillericrisco/rsc-harness | 167 | — | ~3.2k | Automated safety check: Pass | MIT | |
| Fishjam JS Server SDKsoftware-mansion-labs/skills | 291 | — | ~1.4k | Automated safety check: Pass | MIT | |
| Typescript Security Reviewgiuseppe-trisciuoglio/developer-kit | 355 | — | ~2.4k | Automated safety check: Notes | MIT | |
| Node Backend Development Guidelinesdiet103/claude-code-infrastructure-showcase | 10k | 2 repos | ~2k | Automated safety check: Pass | MIT | |
| Nodejs Backend Patternsever-works/ever-works | 158 | 18 repos | ~4k | Automated safety check: Pass | AGPL-3.0 | |
| Twenty Syncable Entity Validationtwentyhq/twenty | 58k | — | ~3.3k | Automated safety check: Pass | Custom licence |
software-mansion-labs/skills
Node.js / TypeScript server SDK for Fishjam — backends that create rooms, mint peer tokens, listen to server notifications, and run agents.
giuseppe-trisciuoglio/developer-kit
Provides security review capability for TypeScript/Node.js applications, validates code against XSS, injection, CSRF, JWT/OAuth2 flaws, dependency CVEs, and secrets exposure.
diet103/claude-code-infrastructure-showcase
Sets layered architecture and coding rules for Node.js, Express and TypeScript microservices, covering routes, controllers, services, repositories, Prisma, Sentry and Zod.
ever-works/ever-works
Build production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices.
twentyhq/twenty
Contributor guide for step three of adding a syncable entity to the Twenty server: write the validator, the migration action builder and the orchestrator wiring.
hellangleZ/burn-in-cceverywhere-ralph
Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes.
ericrisco/rsc-harness
A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…
ericrisco/rsc-harness
A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…
ericrisco/rsc-harness
A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…
ericrisco/rsc-harness
A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…
ericrisco/rsc-harness
A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…
ericrisco/rsc-harness
A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.
Works with
Categories
A skill your agent uses when building or operating a plain Node.js / Express 5 backend service: project layout, async correctness, central error middleware, fail-fast config, graceful shutdown on…. Nodejs is an agent skill from ericrisco/rsc-harness.js / Express 5 backend service: project layout, async correctness, central error middleware, fail-fast config, graceful shutdown on SIGTERM.
Nodejs fits situations like: operating a plain Node.js / Express 5 backend service: project layout; async correctness; central error middleware; fail-fast config.
Run `npx skills add ericrisco/rsc-harness --skill nodejs -a claude-code`. Or copy the skill folder (skills/nodejs in ericrisco/rsc-harness) into .claude/skills/nodejs in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ericrisco/rsc-harness --skill nodejs -a codex`. Or copy the skill folder (skills/nodejs in ericrisco/rsc-harness) into .agents/skills/nodejs 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 ericrisco/rsc-harness --skill nodejs -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/nodejs, .gemini/skills/nodejs, .github/skills/nodejs and .opencode/skills/nodejs in your project.
Going by SKILL.md and its folder, Nodejs needs a shell for the scripts in its folder and the command-line tools its instructions call (node). Our summary lists: Node.js; A Bash shell; Docker.
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. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Nodejs is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.2k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.5k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Nodejs: Fishjam JS Server SDK (software-mansion-labs/skills, 291 stars), Typescript Security Review (giuseppe-trisciuoglio/developer-kit, 355 stars), Node Backend Development Guidelines (diet103/claude-code-infrastructure-showcase, 10k stars) and Nodejs Backend Patterns (ever-works/ever-works, 158 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 167 GitHub stars. The repository holds 227 skills in this directory. The repository was last updated on October 7, 2026.
Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.