Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add feral-file/ff-cli --skill ff-controlgit clone --depth 1 https://github.com/feral-file/ff-cliWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/feral-file/ff-cli/ff-control)<a href="https://agentmods.dev/skills/feral-file/ff-cli/ff-control"><img src="https://agentmods.dev/badge/skills/feral-file/ff-cli/ff-control/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/feral-file/ff-cli/ff-control"><img src="https://agentmods.dev/badge/skills/feral-file/ff-cli/ff-control.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00104 | $0.03568 |
| Opus 5.5 | $0.00042 | $0.01427 |
| Sonnet 5.5 | $0.00021 | $0.00714 |
| Haiku 4.5 | $0.00010 | $0.00357 |
Grade D, and why
ff-control scanned grade D with 3 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured today.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Asks for rootmediumPrivilege escalation
A mod that escalates privileges can change anything on the machine, not only the project.
- `ff-cli ssh enable --ttl …` and `ff-cli ssh disable` manage temporary support SSH on port 22. They neither establish nor revoke the owner's persistent grant on port 2222. On newer FF OS a claimed FF1 rejects them until Downloads and executes remote codehighSupply chain
curl | sh runs whatever the server returns today, which is not necessarily what it returned when this was reviewed.
- Install or upgrade, every time: `npm i -g @feralfile/cli` (needs Node.js 22+). An older install can pass `ff-cli status` and still lack flags used here. If the global install is refused for permissions, run `set -o pip Makes network callslowCapability
Not a fault in itself. Listed so you know the mod talks to something, and to what.
- Install or upgrade, every time: `npm i -g @feralfile/cli` (needs Node.js 22+). An older install can pass `ff-cli status` and still lack flags used here. If the global install is refused for permissions, run `set -o pip How it starts
The opening of the file, as written. The whole thing — 85 lines — stays where its author put it; the contents beside it link to each section on GitHub.
You run ff-cli end to end with full autonomy. Do not ask for final confirmation before send or publish.
Context:
- The Art Computer is Feral File's instrument for daily playback in The Digital Art System.
- This skill uses ff-cli to build DP-1 playlists and send/publish them.
- Prioritize reliable execution and clear failure reporting over explanation.
Keep it simple. Prefer deletion over added process.
Do not invent new requirements.
A non-zero exit means what was asked did not happen; report the command and its output. A zero exit can still carry a partial result: find and build print how many items they saved and which tokens could not be resolved, so report those too. A question with no terminal to answer it fails with exit 1 and names the flag that answers it; pass that flag rather than piping an answer.
Bootstrap:
- Install or upgrade, every time:
npm i -g @feralfile/cli(needs Node.js 22+). An older install can passff-cli statusand still lack flags used here. If the global install is refused for permissions, runset -o pipefail; curl -fsSL https://feralfile.com/ff-cli-install | bash && export PATH="$HOME/.local/bin:$PATH"; it installs the same package under~/.localwithout sudo. - Then check that
ff-cli --versionmatchesnpm view @feralfile/cli version. If it does not, an older copy comes first on PATH:command -v ff-clishows which; remove it or put the new one first. - If
ff-cli statusthen succeeds, setup is done. Otherwise configure non-interactively (never rely on prompts; they cannot be driven by an agent):ff-cli setup --non-interactive --device-host http://<device-ip>:1111 --device-name "<name>"- setup generates a signing key (base64 PKCS#8 DER) when none is configured and keeps one that is. To use a specific key, pass
--key "<value>"(base64 PKCS#8 DER, 32-byte seed as hex/base64, or PEM). - setup refuses to replace a signing key that is already configured: that key owns every playlist the user published. Never add
--forceunless the user explicitly asks to replace their key. - Skip mDNS discovery entirely — it is unreliable across subnets. Always pass
--device-host. Add more devices withff-cli device add --host http://<ip>:1111 --name "<name>".
- setup generates a signing key (base64 PKCS#8 DER) when none is configured and keeps one that is. To use a specific key, pass
- A signed playlist hosted at any public HTTPS URL plays directly (
ff-cli play "<url>"); a feed server is only needed for discovery/curation, not for playback.
Flow:
- ff-cli status
- ff-cli config validate
- Build playlist (ff-cli has no chat — you are the natural-language layer; translate the request into one of these yourself):
- a web page, media file, or hosted playlist URL needs no build: run
ff-cli play "<url>"and skip to reporting. Marketplace links (Art Blocks, OpenSea, objkt, fxhash, Feral File, …) are sent tofind, which plays the artwork; when the user wants the page itself, runff-cli play --web "<url>". - for a single artwork or a collection from a URL or on-chain coords:
ff-cli find "<input>" -o playlist.json -y(add--playto build and play in one step).-yskips the prompts, which is safe when the input names one work or one series.-ywithout-oor--publishplays the playlist on a device (the scripted default); add--no-playto build and save without casting, e.g.ff-cli find "<input>" -y --no-play. findon a wallet address does not build from everything the wallet holds: it resolves the address to one artist and picks one artwork, and-ypicks the first without asking. Ask the user which work they mean and runfindon that work's URL or coordinate. When they want a playlist of what a wallet holds, usebuildwith aquery_addressrequirement, which is what it is for. The params file is a whole document, not a bare requirement:{"requirements": [{"type": "query_address", "ownerAddress": "<address>", "quantity": <n>}], "playlistSettings": {"title": "<title>"}}.- on-chain coordinates are
ethereum:<contract>:<tokenId>ortezos:<contract>:<tokenId>. When Raster knows the work,findexpands the coordinate to its whole series, and a large series indexes for minutes; when Raster does not know it or cannot be reached,findbuilds a one-token playlist. Pass-l <n>unless the user asked for the whole series, so the expanded case never runs away. - otherwise turn the request into structured params and run
ff-cli build <params.json> -o playlist.json -v.ff-cli build --helplists every requirement type.buildexits 1 when a requirement finds nothing, named token ids do not all resolve, or the send fails; it still saves the playlist when it collected anything, so report what is missing. findandbuildsign the playlist ascuratorwith the configured key and declare it incurators[]; that is what lets the feed accept it and what lets you take it back later.
- a web page, media file, or hosted playlist URL needs no build: run
ff-cli validate playlist.json- If requested, run:
- send:
ff-cli play playlist.json(or with-d "Device Name") - if it fails with reachability errors (
fetch failed,No route to host, resolver timeout), report the exact failing command and error and that the Art Computer is unreachable from this network. For an explicitly enrolled Tailscale connection, use its recorded address as described below; otherwise do not invent tunnels or change addresses - publish:
ff-cli publish playlist.json -s <index>. Runff-cli config showfirst; it lists the effective feed servers as<index>: <url>, whichever source configured them. With more than one configured, the command prompts for one and a prompt cannot be driven by an agent, so pass-s <index>for the feed the user named. If the user did not name a feed and more than one is configured, stop and ask which; never pick index 0 on your own, it is usually production. Use that same index for every later fetch, replace, or unpublish of that playlist. Publishing sends no API key; the feed accepts the playlist on its own signatures. - if both are requested: send first, then publish
- send:
What ships with it
1 file beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- today Changed · +10 lines · +31 tokens per session 7f5ed0a77333
- yesterday Changed · +7 lines 16661943e7c0
- 6d ago Changed · +4 lines scan B → D 49528cf769eb
- 19d ago Changed · +9 lines scan A → B 3e742ef2b534
- 21d ago Changed 0693e97ffc96
- 1mo ago Changed · +9 lines 9117c7e5194e
- 2mo ago First seen · 46 lines · 73 tokens per session scan A 248a5dc928d2
ff-control is a skill published in the GitHub repository feral-file/ff-cli (5 stars, last pushed today), licensed MIT. It adds 104 tokens to every session and 3,568 once invoked, about $0.0004 per session on Opus 5.5. A static security scan graded it D with 3 findings (asks for root, downloads and executes remote code, makes network calls). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
gke-compute-classes
Configures, optimizes, and troubleshoots GKE ComputeClasses. Use when configuring Spot VMs with on-demand fallback, targeting specific accelerators (GPUs/TPUs) or machine families, restricting ComputeClass access, or debugging pending pods related to node pool auto-creation. Do not use for cluster-level Node Auto…
jetson-diagnostic
Read-only Jetson health snapshot for identity, memory, GPU, thermal, power, storage, services, and top processes.
holoscan-install-wheel
Install Holoscan SDK 5.x CUDA 13 Python wheels in an isolated environment, choosing the full stack or version-matched components.
offensive-z-wave
Z-Wave attack methodology — sniffing with Z-Force / EZ-Wave / RTL-SDR + ZniffMobile, S0 (legacy) network-key derivation flaw and key reuse, S2 (modern) ECDH commissioning analysis, replay/injection on unauthenticated nodes, default-key brute-force on test deployments, and home-automation hub pivots. Use when targeting…
doca-socket-relay
Use this skill when the operator is driving the DOCA Socket Relay to bridge a socket-oriented host application onto a BlueField DPU peer without rewriting it — picking the deployment shape (in-process, sidecar, or BlueField service container), configuring the host-side socket and the DPU-side forwarding endpoint…
hsb-flash
Flash the FPGA on an HSB board connected to an NVIDIA devkit. Supports HSB Lattice boards (FPGA versions 2407, 2412, 2507, 2510) and Leopard Imaging VB1940 "all-in-one" cameras (FPGA versions 2507, 2510). Uses release-specific YAML manifests and board-type-specific program commands. Lattice and VB1940 commands must…