This public repository owns the screenRIG marketplace, the canonical skill
source, plugin metadata, and the generated bundle that contains the
screenrig/cli main CLI. It does not own the CLI source, Players, backend or
site. This is a maintainer guide; the optional workspace AGENTS.md adds shared
operational rules. The npm screenrig package is the developer-shell
distribution, never a substitute for the bundled launcher in an agent workflow.
Every marketplace install clones the whole repository and copies one plugin
folder, so every file and byte counts. Each folder and the repository have a
budget. Add no file, dependency, asset or binary without a clear need. Before
each commit run python3 scripts/validate-plugin.py --budget (CI runs it too)
and put the before and after counts in the commit message. The limits live in
that script; raising them is the operator's decision.
Two generated folders carry the same skills and bundled CLI:
| Folder | Installed by | Reads |
|---|---|---|
plugins/screenrig |
Claude and Grok (.claude-plugin/marketplace.json) |
.claude-plugin/plugin.json with the inline mcpServers |
plugins/screenrig-agents |
Codex (.agents/plugins/marketplace.json), OpenClaw |
.codex-plugin/plugin.json and .mcp.json, portable plugin.json and mcp.json, openclaw.plugin.json, assets/logo.png |
Codex would fall back to the Claude index without .agents/plugins/marketplace.json,
so that index exists. Grok has no index of its own: it reads the Claude index,
which keeps installs registered under plugins/screenrig updating. The Claude
plugin directory scans plugins/screenrig and holds any image or font a
command, hook, script or manifest names, so that folder holds no image or font
but the listing icon .claude-plugin/icon.png (the logo, at the path the
directory looks for, named by nothing), and no manifest but
.claude-plugin/plugin.json, which names no icon (validate-plugin.py fails on
either). Codex needs ./-relative logo paths
inside its folder, which is why the logo lives in the agents folder.
- Canonical inputs:
skills/, the root marketplace manifests and root public files. Plugin metadata, listing and review cases live inscripts/build-plugin.py, which generates both plugin folders and their manifests. Never editplugins/by hand: change inputs and regenerate. Documentation-only change:scripts/build-plugin.py --docs-only(verify with--docs-only --check); it preserves the CLI, manifests and provenance. - Locally the builder packs sibling
../cliwhen present; CI packshttps://github.com/screenrig/climain.components.lock.jsonis provenance of the tarball just packed (filename, SHA-256, commit), not a pin to fetch. release-version-files.jsoninventories every version-bearing file in both folders; add new ones there when you generate them. Versions are CalVerYY.MM.SERIAL(UTC);maincarries the released version and the workspace release stamps and tags it. CI neither versions nor tags; do not hand-edit versions.- The launcher preflights Node.js 22.23.4+, 24.22.1+, or 26.12.1+ (excluding 23.x and 25.x) and nothing else, prefers the
package-relative
cli/dist/bin.js, then the host's*_PLUGIN_ROOTvariable (a source checkout setsSCREENRIG_PLUGIN_ROOT), never searches parent directories, adds no global npm resolution, and is silent on success (clean JSON on stdout, empty stderr). - The bundled CLI is the minified
cli/dist/bin.jsand the flatcli/dist/*.jschunks it loads per command group, itscli/assets/files,package.json, the runtime lock andTHIRD_PARTY_NOTICES: no source maps,node_modules, native modules or executables. The only image binary is the listing PNG fromassets/logo.svg, inplugins/screenrig-agentsonly. - The Claude plugin directory reads at most 256 KiB of any script or document
and holds a larger one for review;
validate-plugin.py --budgetfails on one. Nothing in the plugin may download and run code (the CLI fetches no renderer or other binary). - The directory scan reads these as a credential taken from the environment or
as download-and-execute: a script that hands over, copies or iterates
process.envor readsprocess.env[name], a bearer header example, a credential variable such as$X_TOKEN,curl ... | sh,printenv, and the word "pass" (the pass password manager). Scripts read each variable by literal name (process.env.CLAUDE_PLUGIN_ROOT), spawn children without anenvoption and setprocess.env.SCREENRIG_INSTALL_SOURCEbefore spawning; skills and docs word these without the phrases ("give", "supply", "bearer credential").validate-plugin.pychecks the patterns. - Do not commit, push, tag or publish unless asked.
skills/screenrig/SKILL.mdis the operative skill: launcher, first-use state, task paths, errors and verification. CLI help and the public docs own command detail; keep the skill andreferences/to workflow and rules help text cannot carry.README.mdaddresses prospective users; neither defines API or billing behavior.- Install is the plugin (Claude, Codex, Grok with
--trustnamed). After install,screenrig-plugin-freshness --bootstrap --jsonverifies registration; agents call the CLI through its--run. Do not teachnpm i -g screenrig, exportingSR, a token flag or a pasted bearer. - Operational commands return JSON envelopes by default;
--humanis for manual text and never combines with--json. Keep explicit--jsononly for the freshness helper. - The plugin declares the public backend MCP endpoint with host-managed OAuth,
generated per platform in
build-plugin.py. Bundle no MCP server code, credential helper, token, private origin or account setting. - Keep skill text generic: no operator host paths or internal tooling names. Native platform names are not download or store claims. Add a demo URL only for a real recording.
scripts/test.py holds every test. The public/reproducibility boundary is
scripts/validate-plugin.py and scripts/check-public-repo.py.
validate-plugin.py fails when a skill or reference writes, as code, a
screenrig command path missing from the bundled CLI's help --all, or an MCP
tool name missing from scripts/mcp-tools.json. That list is the backend's
public tool list, vendored by contracts.toml (rig contracts sync plugin; CI
runs sha256sum --strict -c contracts.sha256), so every run checks tool names
and a missing or malformed list fails. The check judges names only, not flags,
arguments, prose or a path written without its group (update|pause after
"campaign").
python3 scripts/validate-plugin.py --budget
python3 scripts/check-public-repo.py
python3 scripts/build-plugin.py --check --cli-artifact <current-cli-tarball>
python3 scripts/validate-plugin.py --cli-artifact <current-cli-tarball>
python3 scripts/test.pyThese gates do not prove marketplace installation or live API use.