jpbruinsslot/slack-term
Slack client for your terminal
Stale — last commit 2y ago
weakest axislast commit was 2y ago; top contributor handles 96% of recent commits…
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓3 active contributors
- ✓MIT licensed
- ✓CI configured
Show all 7 evidence items →Show less
- ⚠Stale — last commit 2y ago
- ⚠Small team — 3 contributors active in recent commits
- ⚠Single-maintainer risk — top contributor 96% of recent commits
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days; diversify commit ownership (top <90%)
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/jpbruinsslot/slack-term)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/jpbruinsslot/slack-term on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: jpbruinsslot/slack-term
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/jpbruinsslot/slack-term shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 2y ago
- 3 active contributors
- MIT licensed
- CI configured
- ⚠ Stale — last commit 2y ago
- ⚠ Small team — 3 contributors active in recent commits
- ⚠ Single-maintainer risk — top contributor 96% of recent commits
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live jpbruinsslot/slack-term
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/jpbruinsslot/slack-term.
What it runs against: a local clone of jpbruinsslot/slack-term — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in jpbruinsslot/slack-term | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 774 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of jpbruinsslot/slack-term. If you don't
# have one yet, run these first:
#
# git clone https://github.com/jpbruinsslot/slack-term.git
# cd slack-term
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of jpbruinsslot/slack-term and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "jpbruinsslot/slack-term(\\.git)?\\b" \\
&& ok "origin remote is jpbruinsslot/slack-term" \\
|| miss "origin remote is not jpbruinsslot/slack-term (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "main.go" \\
&& ok "main.go" \\
|| miss "missing critical file: main.go"
test -f "service/slack.go" \\
&& ok "service/slack.go" \\
|| miss "missing critical file: service/slack.go"
test -f "components/chat.go" \\
&& ok "components/chat.go" \\
|| miss "missing critical file: components/chat.go"
test -f "config/config.go" \\
&& ok "config/config.go" \\
|| miss "missing critical file: config/config.go"
test -f "context/context.go" \\
&& ok "context/context.go" \\
|| miss "missing critical file: context/context.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 774 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~744d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/jpbruinsslot/slack-term"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
slack-term is a terminal-based Slack client written in Go that lets users browse channels, read messages, and send replies without leaving the terminal. It uses the Slack API (via slack-go/slack library) and termbox-go for terminal rendering, providing a vim-like interface with keyboard-driven navigation. Modular monolith: main.go is the entry point; components/ contains UI widgets (channels.go, chat.go, input.go, threads.go, message.go); service/slack.go handles all Slack API communication; config/ manages configuration and themes; handlers/event.go processes keyboard/mouse input; context/context.go stores application state.
👥Who it's for
DevOps engineers, systems administrators, and developers who spend most of their time in the terminal and want to manage Slack conversations without switching to a browser or desktop app. Users who prefer keyboard-driven interfaces and minimal resource consumption.
🌱Maturity & risk
This is an actively maintained but mature single-maintainer project. The Go codebase is substantial (~172KB), has proper vendoring, includes a Dockerfile, and supports binary releases. However, the dependency on legacy Go (1.12 in go.mod) and lack of visible test files (no *_test.go in the file list) suggest it's production-ready but not heavily test-driven. Last activity appears ongoing but pace is moderate.
Single-maintainer risk is significant (only erroneousboat listed). The project relies on github.com/erroneousboat/termui (a custom fork of an abandoned upstream) and github.com/slack-go/slack v0.6.3, which may have security gaps if not regularly updated. Go 1.12 is very outdated (current is 1.22+), creating potential compatibility issues. Absence of visible test coverage means refactoring carries risk.
Active areas of work
No visible recent activity data provided in the file structure. The repository has established issue and pull request templates in .github/ suggesting an open-source workflow, but specific PRs or active milestones are not listed in the data provided.
🚀Get running
git clone https://github.com/erroneousboat/slack-term.git
cd slack-term
make build
./slack-term
On first run, it creates a config at ~/.config/slack-term/config. Edit it with your Slack token (get one from https://api.slack.com/authentication/token-types).
Daily commands:
After building, run ./slack-term from the repo root or from /usr/local/bin if installed. The Makefile likely has targets like make build and make run — check the Makefile for full commands. Docker alternative: docker run -it -v ~/.config/slack-term/config:/config erroneousboat/slack-term.
🗺️Map of the codebase
main.go— Entry point that initializes the application, sets up the UI, and starts the event loop—every developer must understand the startup sequenceservice/slack.go— Slack API client wrapper handling all communication with Slack via slack-go/slack SDK—core service layer that all features depend oncomponents/chat.go— Main chat UI component managing message display and interaction—central to the user-facing interfaceconfig/config.go— Configuration loading and management—determines auth tokens, themes, and keybindings at startupcontext/context.go— Global application state holder passing data between components—backbone of application state managementhandlers/event.go— Event dispatch and routing logic—handles all user input and Slack events flowing through the applicationcomponents/mode.go— UI mode system (insert, normal, search)—defines interaction model and modal state transitions
🧩Components & responsibilities
- service/slack.go (slack-go/slack, gorilla/websocket) — Slack API client; manages RTM connection lifecycle, sends/receives messages, fetches users/channels
- Failure mode: Network disconnect or auth failure; will attempt reconnect or prompt for new token
- handlers/event.go (termbox-go (keyboard), context) — Event dispatcher; routes keyboard events and Slack RTM events to state updates and UI changes
- Failure mode: Unhandled event types cause silent drops; edge cases in mode transitions may leave UI in inconsistent state
- components/chat.go & others (termui, components/mode.go) — UI rendering layer; converts context state into terminal grid layout with colors and text
- Failure mode: Rendering errors cause visual corruption; no graceful degradation for unsupported terminal sizes
- context/context.go (Go structs) — Global app state holder; tracks current channel, messages, users, and UI mode
- Failure mode: No synchronization; concurrent writes from event handlers and Slack goroutine could cause data races
- config/config.go (YAML, XDG directories) — Config parser and state; reads YAML, validates token, provides defaults
- Failure mode: Invalid YAML or missing token prevents startup; no migration for schema changes
🔀Data flow
Slack RTM WebSocket→undefined— undefined
🛠️How to make changes
Add a new keybinding or interaction mode
- Define the new mode constant in components/mode.go (
components/mode.go) - Add keyboard handler logic in handlers/event.go to transition to/from the mode (
handlers/event.go) - If a new UI component is needed, create it (e.g., components/myfeature.go) and add rendering to the grid layout (
components/chat.go) - Add config options in config/config.go if the feature needs customization (
config/config.go)
Add a new Slack data type or command
- Add API wrapper method in service/slack.go for the new Slack endpoint (
service/slack.go) - Update the context data structure in context/context.go to hold the new data (
context/context.go) - Add UI component or update existing component (e.g., components/chat.go) to render the new data (
components/chat.go) - Add event handlers in handlers/event.go to trigger the new feature on user input (
handlers/event.go)
Customize the theme or color scheme
- Edit or create a new theme in config/theme.go with color definitions (
config/theme.go) - Add theme name to the config options in config/config.go (
config/config.go) - Apply theme colors in component rendering (e.g., chat.go) using the loaded theme (
components/chat.go)
Add a new configuration option
- Add field to the Config struct in config/config.go (
config/config.go) - Update YAML parsing and defaults in config/config.go (
config/config.go) - Reference and use the config value in relevant components or handlers (
handlers/event.go)
🔧Why these technologies
- termui (fork by erroneousboat) — Provides grid-based terminal UI layout engine; allows responsive TUI rendering without raw termbox complexity
- slack-go/slack — Mature Slack SDK with RTM (Real-Time Messaging) support for WebSocket-based event streaming
- gorilla/websocket — Underlying WebSocket library used by slack-go for maintaining persistent RTM connection
- nsf/termbox-go — Low-level terminal control abstraction; enables cross-platform keyboard input and color rendering
- YAML config (via gopkg.in/yaml.v2) — Human-readable configuration format for tokens, themes, and keybindings
- XDG base directory (OpenPeeDeeP/xdg) — Ensures config files follow Linux/macOS/Windows standards (~/.config, etc.)
⚖️Trade-offs already made
-
RTM (Real-Time Messaging) over Events API
- Why: RTM provides WebSocket-based push events with lower latency for interactive terminal use
- Consequence: RTM is deprecated by Slack but still functional; no support for newer event subscriptions or granular permissions
-
Synchronous event handling in main loop
- Why: Simplifies terminal state consistency and avoids race conditions in TUI rendering
- Consequence: Blocking I/O; large message history or slow network can stall UI responsiveness
-
Single-threaded termui rendering
- Why: Terminal rendering is not thread-safe; simpler architecture without mutex contention
- Consequence: Cannot parallelize expensive operations (e.g., emoji parsing, fuzzy search) without blocking UI
-
Store-and-forward message history in-memory
- Why: Fast local message lookup and search without database dependencies
- Consequence: Message history lost on restart; memory usage grows unbounded for large conversations
🚫Non-goals (don't propose these)
- Does not support real-time message editing or deletion from the terminal UI
- Does not implement file uploads or rich media attachment handling
- Does not provide persistent message history or database backend
- Does not support Slack Enterprise Grid or workspace switching from config
- Does not implement end-to-end encryption or Slack Connect workflows
🪤Traps & gotchas
Token setup is non-obvious: the README links to a wiki page for getting modern (non-legacy) tokens; without this, users will get auth failures. Config path uses XDG: ~/.config/slack-term/config is resolved via xdg library, not hardcoded — may differ on macOS. Termbox-go is synchronous and blocking: terminal I/O will freeze the render loop if Slack API calls block — check for goroutine patterns in service/slack.go. No built-in logging by default: debugging requires understanding how errors propagate through context.go. Threads require manual fetch: switching to a thread view requires fetching reply_count from service and loading thread messages separately.
🏗️Architecture
💡Concepts to learn
- Slack Web API token authentication — slack-term communicates with Slack exclusively via HTTP API tokens; understanding token scopes and refresh mechanics is critical when debugging auth failures or adding new API calls to service/slack.go
- Termbox event-driven input handling — The entire keybinding system in handlers/event.go depends on termbox-go's event loop; knowing how to map termbox events to actions is essential for modifying keyboard shortcuts
- Double-buffered terminal rendering — termui components draw to an off-screen buffer before flushing to screen; understanding this pattern prevents flicker and helps debug rendering issues in components/chat.go and components/channels.go
- XDG Base Directory specification — Config resolution via OpenPeeDeeP/xdg ensures cross-platform config storage (~/.config on Linux, ~/Library on macOS); required to understand where slack-term looks for config files
- Slack message threading model — Threads are separate from main channel messages; service/slack.go must fetch thread metadata separately and components/threads.go displays nested replies; critical for understanding data flow when viewing threaded conversations
- Fuzzy string matching (lithammer/fuzzysearch) — The
/search mode in slack-term likely uses fuzzy matching to find messages; understanding the algorithm helps optimize search performance for large channel histories - Context passing in Go applications — context/context.go holds mutable state across the entire app (current channel, loaded messages, cursor position); all components and handlers read/write to this context; understanding the state machine is crucial for feature additions
🔗Related repos
slack-go/slack— Official Slack Go SDK used by slack-term to communicate with Slack API; understanding its client methods is essential for extending service/slack.gonsf/termbox-go— Low-level terminal library used indirectly via erroneousboat/termui; provides key event handling and screen rendering primitiveserroneousboat/termui— Custom fork of termui used as the UI widget toolkit in slack-term; vendored in the repo and defines block.go, barchart.go rendering logicwee-slack/wee-slack— Alternative Slack client for WeeChat; similar problem space (terminal-based Slack) but different architecture (weechat plugin vs standalone Go app)rauchg/slackin— Slack community invitation server; complementary tool often used in projects that adopt slack-term for team communication infrastructure
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for service/slack.go Slack API wrapper
The repo has no visible test files despite containing critical Slack API integration logic in service/slack.go. This is a high-value addition since the service layer is the bridge between the terminal UI (components/) and Slack's API. Unit tests would catch regressions in message fetching, channel loading, and thread handling—all core features visible in the components/ directory (chat.go, threads.go, message.go).
- [ ] Create service/slack_test.go with table-driven tests for core Slack API methods
- [ ] Mock the slack-go/slack client dependency to avoid requiring actual Slack tokens during testing
- [ ] Add tests for error handling in API calls (e.g., network failures, invalid tokens)
- [ ] Ensure tests cover the data transformations between Slack API responses and internal message/channel structures used in components/
Add GitHub Actions CI workflow for multi-OS builds and linting
The repo has a Makefile and supports multiple platforms (Docker, binary, Go install) but lacks automated CI. There's no .github/workflows/ directory visible. A CI pipeline would catch build failures across Linux/macOS/Windows early, verify the Dockerfile works, and lint Go code—reducing friction for contributors and catching issues before merge.
- [ ] Create .github/workflows/build.yml to run 'go build' on ubuntu-latest, macos-latest, and windows-latest
- [ ] Add 'go fmt' and 'go vet' checks to catch common Go style and logic issues
- [ ] Include a Docker build step to verify the Dockerfile builds successfully
- [ ] Run tests from service/slack_test.go (once added per PR #1) as part of the workflow
Complete incomplete Setup section in README.md and add configuration guide
The README.md Setup section cuts off mid-sentence ('Running slack-term f') and lacks critical user documentation. The repo has config/ directory with config.go, emoji.go, and theme.go, indicating rich configuration options that aren't documented. New contributors won't know how to configure the client, find config file locations, or customize themes.
- [ ] Complete the truncated sentence and document how to obtain and use Slack tokens (link already exists but setup incomplete)
- [ ] Create a CONFIGURATION.md file documenting the config file format, location (likely leveraging OpenPeeDeeP/xdg from vendor/), and all available options
- [ ] Document theme customization by explaining config/theme.go's purpose and provide example theme configurations
- [ ] Add emoji configuration documentation referencing config/emoji.go
- [ ] Include troubleshooting section (e.g., common setup errors, token scopes needed)
🌿Good first issues
- Add integration tests for service/slack.go: mock the Slack API and verify that GetChannels(), GetMessages(), and SendMessage() handle edge cases (empty responses, rate limits, auth failures) correctly. Currently no *_test.go files are visible.
- Document the config schema: create a config/config.md or wiki entry showing all valid fields in ~/.config/slack-term/config (slack_token, keybindings, theme_name, etc.) with examples; README only shows a minimal example.
- Add unit tests for components/input.go: test text editing operations (insert, delete, move cursor) with specific key sequences; ensure message composition works correctly before send.
⭐Top contributors
Click to expand
Top contributors
- @jpbruinsslot — 96 commits
- @mfcochauxlaberge — 3 commits
- @lhanson — 1 commits
📝Recent commits
Click to expand
Recent commits
c19c20a— Update readme (jpbruinsslot)d63dd60— Update nlopes/slack to slack-go/slack (jpbruinsslot)2ee2124— Update readme (jpbruinsslot)c778f6e— Remove snapcraft (jpbruinsslot)541a98e— Update readme (jpbruinsslot)ddbce72— Update running with docker (jpbruinsslot)0d8e8ac— Add xdg configuration support (jpbruinsslot)e17a1cd— Add modules command (jpbruinsslot)ce1d8ce— Respect the XDG Base Directory specification for configs (lhanson)78d1eb5— Update nsf/termbox-go dependency (jpbruinsslot)
🔒Security observations
- High · Outdated Go Version —
go.mod. The project specifies 'go 1.12' in go.mod, which is significantly outdated (released Feb 2019, EOL June 2020). This version lacks critical security patches and bug fixes. Fix: Update to Go 1.21+ (LTS) or the latest stable version. Run 'go mod tidy' after updating. - High · Outdated Dependencies with Known Vulnerabilities —
go.mod, vendor/github.com/slack-go/slack, vendor/github.com/gorilla/websocket, vendor/github.com/erroneousboat/termui. Multiple dependencies use outdated versions vulnerable to known CVEs: slack-go/slack v0.6.3 (latest is v0.12+), gorilla/websocket v1.4.2, and termui from 2017. These likely contain unpatched security issues. Fix: Update all dependencies to latest versions: 'go get -u ./...' and 'go mod tidy'. Specifically update slack-go/slack to v0.12.0+, gorilla/websocket to v1.5.0+. - High · Slack Token Exposure Risk —
README.md, config/config.go. The README instructs users to provide a Slack token for authentication. Without explicit guidance on secure token storage and the presence of a config directory, there's significant risk of tokens being committed to version control or stored insecurely. Fix: Implement secure credential handling: 1) Update README to explicitly warn against committing tokens. 2) Use environment variables or secure credential managers (e.g., os.Getenv for SLACK_TOKEN). 3) Ensure .gitignore properly excludes config files containing tokens. - Medium · Vendor Dependencies in Version Control —
vendor/. The vendor/ directory is committed to the repository, which increases attack surface and makes security updates harder to track. Vendored code may contain unpatched dependencies. Fix: Remove vendor/ from version control. Use 'go mod vendor' only for reproducible builds in CI/CD. Update go.mod/go.sum regularly and audit dependencies with 'go mod graph' and 'go list -m all'. - Medium · Missing Input Validation in Chat Components —
components/chat.go, components/input.go, components/message.go. Components like chat.go, input.go, and message.go process user input and Slack messages without apparent validation. This could enable injection attacks or terminal escape code exploitation. Fix: Implement input sanitization and validation: 1) Validate all user input before processing. 2) Sanitize terminal output to prevent escape sequence injection. 3) Use safe libraries for terminal rendering (ensure termui is updated). - Medium · Dockerfile Security Issues —
Dockerfile. 1) Uses 'alpine:latest' in final stage without version pinning. 2) Runs as root user (ENV USER root). 3) No non-root user defined for running the application. Fix: 1) Pin alpine to specific version (e.g., 'alpine:3.18'). 2) Create non-root user and run as that user. 3) Add 'USER appuser' before ENTRYPOINT. 4) Consider using distroless base images. - Medium · No Configuration Validation —
config/config.go, main.go. The application accepts a config file path without apparent validation. Missing or malformed config files could cause unexpected behavior or security issues. Fix: Implement comprehensive config validation: 1) Validate config file exists and is readable. 2) Validate required fields (Slack token). 3) Implement schema validation. 4) Log validation errors without exposing sensitive data. - Low · Missing Security Headers in Documentation —
README.md, CONTRIBUTING.md. No security guidelines or best practices documented for users regarding token management, network security, or secure deployment. Fix: Add security section to README covering: 1) Never commit Slack tokens. 2) Use environment variables for sensitive data. 3) Recommendations for running in containers with restricted permissions. 4) Security contact/disclosure policy. - Low · undefined —
undefined. undefined Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.