feat: add the /meow command - #104
Open
thc1006 wants to merge 1 commit into
Open
Conversation
thc1006
force-pushed
the
feat/meow-command
branch
7 times, most recently
from
August 26, 2026 16:27
9c7225c to
93f4346
Compare
Adds a /meow command that replies with a random cat image (cncf#78). It matches only a standalone /meow line, so /meowvie and prose mentioning /meow do not trigger it. The image is fetched from the cat api with the global fetch (no new dependency) under a request timeout and a small bounded retry, the response is validated, and the url is embedded with the angle bracket markdown form. A cat api outage degrades to a short note rather than failing the workflow; only the github write fails the action. An optional cat-api-key input is sent as the x-api-key header when set. Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
thc1006
force-pushed
the
feat/meow-command
branch
from
August 26, 2026 16:35
93f4346 to
deb0b50
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds a
/meowcommand that replies with a random cat image, requested in #78.It matches only a standalone
/meowline, so/meowvie(a real upstream command) and prose or urls that merely mention/meowdo not trigger it. The image is fetched from the cat API with the globalfetch, so it adds no dependencies, and is posted through the existingcreateCommenthelper, following the shape of the other issue comment commands.Closes #78
Behavior
/meowalone would also fire on/meowvie,/meow-debug, and text likeplease run /meow. The command guards itself with/^[\t ]*\/meow[\t ]*$/mand returns early otherwise. Reworking the shared command parser is out of scope here.AbortSignal.timeoutand the command retries at most three times, only for a network failure or a 5xx. Timeout errors, 429 responses, other 4xx responses, invalid responses, and the GitHub write are not retried; retryable network failures and 5xx responses can each consume up to their own per-attempt deadline, so the total wall-clock time is bounded by the attempt count rather than a single deadline. A 429 is a rate limit, so it falls back rather than sending the same request again. Every non-2xx response has its body cancelled before the retry or fallback, so undici releases the connection instead of leaving it for the garbage collector.parseCatImagechecks the payload is a non-empty array whose firsturlis a string, bounds its length, parses it withnew URL, and requireshttpswith no embedded credentials. The url is embedded with the angle bracket formon the normalized href, so a parenthesis or other reserved character in a valid url renders correctly and an unexpected response cannot break out of the image./meowis enabled per repository and open to anyone, so a cat API outage should not turn a repository's workflow red. A failed fetch logscore.warningand leaves a short note; only a failed GitHub comment write fails the Action.cat-api-keyinput is sent as thex-api-keyheader when set, withredirect: 'manual'so a redirect is refused rather than followed and the header cannot reach another origin. Anonymous requests are best effort and share a rate limit. The key comes from a repository secret and is registered withcore.setSecretfor runner masking before the request, and is never intentionally included in the request URL or a GitHub comment.Scope
This intentionally implements only the bare
/meowcommand./meowvieand category arguments (/meow <category>) remain out of scope. The exact matching is a correctness fix rather than an enhancement, since without it/meowvieis wrongly executed as/meow. Command detection otherwise inherits the existing substring dispatcher, so a/meowline inside a code fence is still matched like any other command; reworking that shared parser is out of scope here. Issue #66 tracks ignoring code blocks and #81 tracks multi-command parsing behavior, and both apply to every command rather than being specific to/meow, so this change does not close either. Because/meowcalls a third party and anyone can invoke it, it is kept out of the default Quickstart command list and documented as an opt-in command with its own example in the commands docs; enabling it in this repository's own workflow is left as a follow-up for the maintainers. This touches the same dispatch switch as #103, so if #103 merges first this rebases onto it, keeping every.catch(normalizeError)and adding the/meowcase, withdist/index.jsregenerated from a clean install rather than hand-merged. That regeneration also brings the bundled transitivebrace-expansionin sync with the unchanged lockfile; no dependency versions changed.Testing
npm run allpasses (build, lint, pack, test): 106 passing, 6 skippedmeow.test.tsruns withonUnhandledRequest: 'error'so a missed mock cannot reach the live cat API or GitHub, and spiescreateCommentso no real write escapes/meow, a url with parentheses, the four forms that must not trigger it (/meowvie,/meow-debug,/meow cat, prose), a CRLF comment where the standalone/meowstill matches exactly once, a transient retry then success, a network error retried to the attempt limit, a persistent failure over three attempts, a rate limit that is not retried, a timeout that is not retried, an empty response, a first item without a url, an unparseable url, an over-length url, a non-https url, a credential url, a refused redirect that is not followed, a response body cancelled on both a retry and a non-retry, the request query, the API key header both set and absent, the key registered for masking, and a failed GitHub write that fails the ActionChecklist:
npm run allto lint and build my code