Playground
The Playground imports @agntn/hashes into the page and runs the tool executors there. Every digest, HMAC, verdict and listing is the library's own answer, the same code the CLI and the MCP server run. Nothing is sent anywhere. The worker serves the page and that's the end of its involvement.
| Operation | Runs | Tool |
|---|---|---|
| Hash | hashCompute({ algorithm, input, inputEncoding, encoding, salt, parameters }) | hashes_compute |
| HMAC | hashHmac({ algorithm, input, inputEncoding, key, keyEncoding, encoding, parameters }) | hashes_hmac_compute |
| Verify | hashVerify({ algorithm, input, inputEncoding, expected, encoding, salt, parameters }) | hashes_verify |
| Extend | hashDigestExtend({ algorithm, digest, message, messageEncoding, suffix, suffixEncoding, secretLength, secretLengthMax, parameters }) | hashes_digest_extend |
| Identify | hashDigestIdentify({ digest }) | hashes_digest_identify |
| Search | hashDigestSearch({ digest, encoding, words, minWords, maxWords, joiners, cases, algorithms, rounds, chains }) | hashes_digest_search |
| Algorithms | hashAlgorithms({ family, category }) or ({ algorithm }) | hashes_algorithms |
The parameter fields come from info().options. Pick scrypt and N, r, p and keyLength show up. Pick SHA-256 and they're gone.
Identify ends where verify starts. Every candidate this package computes gets a verify button. It carries the salt, the costs and the digest read out of the string. All that's left to type is your guess.
Search gets a worker
A search can hash for seconds. A tab frozen for seconds feels broken. So Search hands the executor to a Web Worker and the page just listens. The count ticks every 100,000 hashes and you can keep typing. Changed your mind? A new call ends the old one. What lands in Full tool response is still the tool's own text.
The chips are solved puzzles with the words shuffled. The last one never finds anything. It's there so you can watch the count hit the wall.
Every state is a link
The form writes itself into the address: /playground?op=hash&algorithm=keccak256&input=transfer(address,uint256) opens the page on that answer. Paste it to someone and they see what you saw.
Costs are the tool's costs
The playground calls the executors, so it inherits their limits. scrypt with N 1048576 is refused the same way an agent would be refused. The defaults are the real defaults, so PBKDF2 at 600000 rounds of SHA-512 does take a moment in a browser tab. That's the point of a KDF, it isn't the page being slow.
The two snippets
Under the fields the page prints the same call as a CLI line and as a tool invocation in JSON, both with copy buttons. They're built from the form, so what you copy is what you ran. The answer ends in a Full tool response row with the exact text a model would get.