What shipped in SlackCLI v0.11.0
The release where most of the code came from somebody else. Four new command groups, a shared rate limiter, and what it took to make outside contributions mergeable.
v0.11.0 is sixteen merged pull requests, and the notable thing about it is not the feature list. It is that most of the features were written by people who had never touched the repository before.
Three first-time contributors and one returning one landed four new command groups between them. Here is what they built, and then the part that interests me more: what had to be true for that to work.
Four new command groups
emoji (Travis Mack, #149).
emoji list enumerates the workspace’s custom emoji, emoji get resolves one
name to its image URL and follows aliases.
team (Travis Mack, #148).
team info prints the workspace identity: id, domain, name, icon.
usergroups (same author, #148
and #156).
This one grew teeth. list and read are read-only, then create, update,
add, remove, enable and disable write. Every write goes through the same
confirmation gate: --yes proceeds, a terminal prompts, and a non-interactive
shell without --yes refuses rather than guessing. That rule was already
written down, so the pull request arrived with it implemented.
files (Minh Duc, #161).
files info inspects a file, files read streams a text file to stdout, and
files download saves it. All three accept a Slack file URL wherever they
accept an id.
Two changes you will not see
The two most consequential commits in the release do not add a command.
Every Slack call is now paced. A process-wide rate limiter allows at most
two requests in flight, at least 200ms apart, for both authentication modes
(#151). The bug it fixes is
worse than it sounds. Commands that resolve many names, like
conversations unread or saved list, fired one users.info per user and one
conversations.info per channel as fast as the network allowed. That pattern
trips Slack’s unexpected_api_call_volume anomaly detection, and on Enterprise
Grid the consequence is that your browser session gets signed out. A tool that
logs you out of Slack for using it is not a tool. Large workspaces are slower
now, which is the correct trade.
--json reaches further. conversations list gained it
(Ajay Raho, #153),
and messages send, edit and draft gained both --json and --message-file
(Rafael Yure, #152).
--message-file matters more than it looks: it is how you send a message
containing quotes, newlines or a code block without fighting your shell’s
quoting rules, and how an agent sends one without building a command string.
There is also a fix worth singling out because of who it was blocking. Ajay
found that findBrowser() used the host’s path separator when asked to simulate
another operating system (#155).
No user could ever hit it. What it broke was the test suite on Windows, which
meant the mandatory pre-commit hook failed, which meant nobody on Windows could
contribute at all. A bug in nothing but the contributor experience, found by a
contributor.
The boring part that made it work
The same release cycle added a section to CLAUDE.md that reads like a
constitution: an issue before every pull request, a ready-for-pr label before
any code is written, issue and pull request templates, tests required including
edge cases, signed commits, no bypassing hooks, and documentation updated in the
same change as the code.
That is a lot of process for a small CLI, and the honest reason for it is that most contributions now arrive with an AI agent somewhere in the loop, including mine. An agent will follow a convention it can read and invent one it cannot. Writing the rules down converted “please match the house style” from a review comment into an input.
The result is visible in the diffs. The usergroups write commands shipped with
the confirmation gate already correct. The files commands accepted Slack URLs
without being asked. Every group came with --json and its own test file. None
of that was negotiated in review, because none of it was a surprise.
What the rules cost is real: a contributor has to open an issue and wait for a label before writing code. What they buy is that the code, once written, gets merged instead of rewritten.
Get it
brew tap shaharia-lab/tapbrew install slackclislackcli updateFull notes are in the release and the changelog. The new commands are documented under emoji, team, usergroups and files.
If you want to build the next one, the contributing guide starts with opening an issue. That is not a formality. It is the whole system.