Skip to content

slack-leave-devopsinc: leave PagerDuty incident channels on demand (CLI + Spotlight app) - #57

Closed
kriswill wants to merge 3 commits into
mainfrom
claude/eager-albattani-ugsvje
Closed

kriswill wants to merge 3 commits into
mainfrom
claude/eager-albattani-ugsvje

Conversation

@kriswill

@kriswill kriswill commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

Replaces the keystroke-driven leave-devopsinc.applescript with a Slack Web API tool you can launch from Spotlight. It finds the channels by itself, so you don't type channel numbers, Slack doesn't need focus, and no Accessibility permission is required.

  • pkgs/slack-leave-devopsinc.{sh,nix}: a writeShellApplication (curl, jq). It pages through users.conversations (public and private channels, archived ones excluded), keeps names matching devopsinc-<digits> with N ≥ 1000 (the same guard as the original script), and calls conversations.leave on each. If one channel fails (e.g. last_member), it reports that and carries on; exit status is 1 at the end. curl --retry 5 waits out 429s using Retry-After. Flags: -n/--dry-run, --notify.
  • Token: a Slack user token (xoxp-…) from $SLACK_LEAVE_TOKEN, or else the login Keychain item slack-leave-devopsinc. It is passed to curl via printf | curl --config -, the same way cbissue does it, so it never appears in argv.
  • Spotlight: the same derivation ships Applications/Leave devopsinc Channels.app. It's an LSUIElement bundle (no Dock icon) whose executable is a makeBinaryWrapper that runs the CLI with --notify, so the result shows up as a macOS notification.
  • modules/darwin/slack-leave-devopsinc.nix: universal (all Macs). It uses environment.systemPackages because nix-darwin only copies systemPackages apps into /Applications/Nix Apps, which Spotlight indexes.
  • Wired through modules/packages.nix (aarch64-darwin guard) and overlays/ + modules/overlays.nix.
  • Knowledge bundle: package and module catalog docs, a decision record (decisions/slack-leave-devopsinc-api.md), and log entries. okf validate passes with 0 errors and 0 warnings.

One-time setup (per Mac)

  1. In your workspace, create a Slack app at api.slack.com/apps and add the User Token Scopes channels:read, groups:read, channels:write, groups:write. Install it (or "Request to Install" if the workspace needs admin approval) and copy the User OAuth Token (xoxp-…).
  2. security add-generic-password -U -a "$USER" -s slack-leave-devopsinc -w (paste the token at the prompt).
  3. Rebuild, then run slack-leave-devopsinc -n for a dry run, or open Spotlight and run "Leave devopsinc Channels".

Test plan

  • ShellCheck 0.11 clean, both standalone and through writeShellApplication's build-time check
  • Built the derivation against the locked nixpkgs (x86_64-linux with the platform check relaxed). Bundle layout, Info.plist, binary wrapper (--notify) and the bin/ link all look right.
  • Mocked Slack API (fake curl, security and osascript): pagination via cursor; filtering skips devopsinc-999, devopsinc-abc, devopsinc-1500-old and general; a last_member failure is reported and the other leaves still go through (exit 1); missing_scope names the scope it needs; no-matches exits 0; a missing token and a curl transport failure both fail cleanly; notifications fire only with --notify, with the message passed as an argv item.
  • Checked scopes, error codes and limit against Slack's OpenAPI spec. users.conversations is sent as GET (-G), as the spec lists it.
  • nixfmt / statix / deadnix clean on the new files
  • CI darwin-k build (the first real darwin build of the package) and nixos-nebula: green
  • On a Mac (k): Slack app created from a manifest with the four user scopes and installed after admin approval; token stored in the Keychain; nrs rebuild put the CLI on PATH and the app in /Applications/Nix Apps
  • Live run: -n listed 43 devopsinc-N channels (1473 to 1520) and nothing else; the real run left all 43 with no failures; a dry run afterwards reports none left
  • Spotlight launch of "Leave devopsinc Channels" (nothing left to leave yet; try it on the next incident channel)

https://claude.ai/code/session_01PZ3r25VNh276wrx6Z1GwRS

Summary by CodeRabbit

  • New Features
    • Added a macOS tool, available from Spotlight, to find and leave eligible devopsinc-1000 and higher Slack channels.
    • Supports a dry run, uses a Slack token from the login Keychain or an environment variable, and reports results with macOS notifications.
    • Added setup and usage documentation.

claude added 3 commits October 2, 2026 17:19
New darwin package + universal module. The CLI finds every Slack
channel named devopsinc-N (N >= 1000) that you're in, via
users.conversations, and leaves each one with conversations.leave. This
replaces the AppleScript that drove Slack.app's Cmd+K switcher, which
needed channel numbers by hand, a focused Slack window and Accessibility
permission.

- pkgs/slack-leave-devopsinc.{sh,nix}: writeShellApplication (curl, jq).
  It reads a Slack user token from $SLACK_LEAVE_TOKEN or the login
  Keychain item "slack-leave-devopsinc". curl --retry handles 429s. The
  package also ships "Leave devopsinc Channels.app", an LSUIElement
  bundle whose executable is a makeBinaryWrapper around the CLI with
  --notify, which reports the result as a macOS notification.
- modules/darwin/slack-leave-devopsinc.nix: adds the package to
  environment.systemPackages on all Macs. Only systemPackages apps are
  copied into /Applications/Nix Apps, where Spotlight indexes them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZ3r25VNh276wrx6Z1GwRS
Package and module catalog docs; a decision record covering why the
PagerDuty incident channels are left via the Slack Web API (Keychain user
token, Spotlight .app with a binary-wrapper executable, systemPackages for
/Applications/Nix Apps) rather than the keystroke-driven AppleScript; log
entries in the packages/modules/decisions bundles; regenerated indexes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZ3r25VNh276wrx6Z1GwRS
Resolves the knowledge/modules/log.md conflict: both sides added
2026-10-02 entries; kept main's two noctalia/nh updates and this
branch's slack-leave-devopsinc creation under the same date heading.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZ3r25VNh276wrx6Z1GwRS
@kriswill
kriswill marked this pull request as ready for review October 5, 2026 17:00
@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0cd4bb23-ec9e-44b6-9078-d2b411cfb8cf
📥 Commits

Reviewing files that changed from the base of the PR and between 0c46c88 and 96f10ab.

📒 Files selected for processing (15)
  • knowledge/decisions/index.md
  • knowledge/decisions/log.md
  • knowledge/decisions/slack-leave-devopsinc-api.md
  • knowledge/modules/index.md
  • knowledge/modules/log.md
  • knowledge/modules/slack-leave-devopsinc.md
  • knowledge/packages/index.md
  • knowledge/packages/log.md
  • knowledge/packages/slack-leave-devopsinc.md
  • modules/darwin/slack-leave-devopsinc.nix
  • modules/overlays.nix
  • modules/packages.nix
  • overlays/slack-leave-devopsinc.nix
  • pkgs/slack-leave-devopsinc.nix
  • pkgs/slack-leave-devopsinc.sh
 __________________________________________
< Dollars to donuts, you didn't test this. >
 ------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@kriswill

kriswill commented Oct 5, 2026

Copy link
Copy Markdown
Owner Author

Landed on main as 3c4635e and 4d7a775.

@kriswill kriswill closed this Oct 5, 2026
@kriswill
kriswill deleted the claude/eager-albattani-ugsvje branch October 5, 2026 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants