Krahnie is our conversation-first Slack assistant for Salesforce delivery
work. Talk to it in plain English in the assistant pane, a DM, or with a mention — a fast
orchestrator routes your ask to one of ~40 in-process tools that read and write Salesforce,
search Slack, and render the answer back as a Block Kit card. This page is the fastest way
to get oriented.
Slack Socket ModePydantic-AI agent loopClaude Haiku + SonnetSalesforce REST (read + write)searches only what you can seestores nothing externally
A standalone agent that owns its own Slack app — not a plugin.
Krahnie is the successor to the Hermes krahnie-slack plugin: same business
logic, but it now owns its own agent loop instead of running inside Hermes. The two
coexist — Hermes keeps Discord; Krahnie owns the Slack app.
The loop is provider-agnostic (Pydantic-AI). It defaults to Claude Haiku for
orchestration (cheap, fast routing) and Claude Sonnet for the parts that write prose —
summaries, card enrichment, status reports.
Its edge is conversation: beyond Salesforce records, Krahnie grounds answers in
Slack threads via Slack's Real-Time Search (RTS) API — so it reasons over where
blockers, decisions, and client asks actually live, not just card fields.
Everything it tells you is rendered as a Slack Block Kit card with buttons —
refresh, confirm/edit/cancel on writes, per-card ⋯ menus, and modals.
How it works
One message → routed → a tool runs → a card comes back.
Slack
You type in the assistant pane / DM / @mention
Assistant-pane events also carry a short-lived action_token — your personal, scoped search credential.
▼ message event
Gateway · slack_gateway.py
Socket Mode transport → builds RequestContext
Fast-ack, slash commands, modals, all button/select interactivity. Captures your action_token for this turn.
▼ agent.run_turn(text, ctx)
Orchestrator · Pydantic-AI (Haiku)
Routes your plain-English ask to one tool
Built-in tools stripped, thinking disabled — a lean ~3K-token context for cheap, fast routing.
▼
krahnie/tools/* · in-process MCP tools
The tool does the work
Queries / writes Salesforce over REST, optionally searches Slack via RTS, and writes prose with Sonnet where needed.
▼ Block Kit
Slack
Card posted back to your thread / DM / Home
Why RTS is safe & cheap: searches are scoped to what you can already see (the
action_token), RTS stores no customer data externally, and the search call itself costs
zero LLM tokens — only re-feeding hits to Sonnet costs anything, and most tools either
reuse an existing call or feed none.
What you can ask
Just talk naturally — Krahnie figures out the rest. Or type help in Slack for the live version of this. Try the chips below verbatim.
🗓️ Your work
Your week-at-a-glance digest (load bar + Refresh/Snooze) — what's my week
Your full assigned backlog — all my cards
Time you've logged — how am I looking this week
This week's individual work-log entries — show my logs
Days you forgot to log to, with a one-click Log-time button — what days am I missing time
🔎 Find cards
A client / project / board's cards — what's going on with <client>
Filtered views — overdue cards I haven't logged to
By creator / assignee — cards assigned to <name>
One card's full detail — show me CARD-001234
Ranked "what next" shortlist — what should I work on
Cards gone quiet, so nothing rots new — what cards are stale
✍️ Do things (writes always confirm first)
Log time (confident match → confirm card; else picker) — log 90 min to <card>
Correct/move an entry (before→after diff) — that should've been Tuesday
Create a card — new card for <client>: <task>
Edit one — close the <x> card · move <card> to Test
Comment on a card new — add a note to <card>: …
Reassign / re-status many at once — reassign these to me
Spin a request into draft cards new — draft cards from this
Personal reminders — remind me in an hour to email Dan
📈 Leadership & metrics
Throughput + request→done time — team velocity · cycle time
Hours per person vs capacity — utilization
On-time delivery % by client — are we hitting due dates
Client KPI scorecard — how's <client> doing
Team rollups — what's outstanding this week · who logged time yesterday
How busy the team is right now new — team capacity
One client's heartbeat new — client pulse for <client>
💬 Search the conversation
Topical RTS — workspace-wide semantic search, grounded answer + linked sources — search slack for what we decided about <X>
Channel catch-up — recent activity in one channel (bot must be in it) — what's happening in #channel lately
Card recaps fold in Slack context — summarize the work on <card>
🚀 Handoff & version control
Hand a card to a coding agent (Claude Code deep link, or autonomous Codex draft-PR), brief grounded in Slack — hand off <card> to an agent
Move a card to Test → pick the metadata you changed → Krahnie opens a PR with AI-written QA notes.
Move a card to Done → Krahnie drafts functional + technical docs.
📊 Usage & admin
Top users by activity — leaderboard
Krahnie spend — show me my cost
Paste-ready client update — status report for <client>
Admins:map @person to <SF name> · set <name>'s capacity to 30
🎉 Ops & fun
Tell the team what went sideways so we sharpen the tools — log feedback
Send a teammate some appreciation — warm fuzzy for @person
The RTS-powered swear-jar leaderboard (fines in 🌮) — swear jar
A couple of easter eggs hide in here. Try tell me about yourself.
Where to use it
Krahnie meets you on Slack's native surfaces — not just one chat box.
Conversational surfaces
Assistant pane — opens with suggested prompts; the only surface with RTS (carries your action_token).
DMs & @mentions — including group DMs, where it stays mention-gated.
App Home tab — your personal dashboard: a "Start here" priority band + open cards, each with a ⋯ menu (Log time / Summarize / Edit) and quick-action buttons.
Message shortcuts (right-click a message): Summarize this thread and Create card from message.
Modals with searchable pickers for guided log-time, new-card, feedback, and handoff flows.
The bigger machinery
A few subsystems do more than answer a single question.
🔁 VC capture → PR pipeline
Card enters Test → "Track metadata changes" card. Dev ticks the components changed, confirms a feature branch.
gitops.py keeps a clean managed clone, cuts feature/CARD-####-slug from the client's base branch, retrieves only the tracked components, and opens a PR via gh.
🤖 Codex first-pass
An autonomous attempt at a card that opens a draft PR. Krahnie spins up a locked-down Docker container (docker/codex-runner/) and runs codex exec against the repo clone inside it (codexwork.py).
The container is the isolation boundary: only the repo clone + scoped ChatGPT/Salesforce-sandbox auth are mounted — never host secrets. Deliberately conservative: repo allowlist, each repo pinned to a SF sandbox, hard prod denylist, draft-only, wall-clock timeout.
🔗 Cross-org ticket sync
ticketsync.py — pulls client tickets → idempotently upserts Card__c, pushes crosswalked status + a client-visible note back. No middleware/Apex in the client org; has a loop guard.
Recent work: hybrid retrieval (channel history around hits), Haiku query-expansion, and context-window prioritization so windows survive the synthesis cap.
Run it locally
Krahnie runs in production as a systemd user service. Here's setup + the day-to-day commands.
2 · Slack scopes — standard bot scopes plus, for RTS: search:read.public,
search:read.files, search:read.users. Add in the app's OAuth & Permissions and
reinstall — Slack only injects the action_token once these are installed. Semantic
search needs a Business+ / Enterprise+ workspace.
3 · Run as the service (it coexists with Hermes — Hermes's Slack platform is off, so the two never contend for the connection):
systemctl --user status krahnie.service # health
journalctl --user -u krahnie.service -f # live logs
systemctl --user restart krahnie.service # after a code change
Manual run (debugging) — stop the service first so two clients don't both hold the socket:
clients.yaml is re-read fresh per use, so client-registry edits (nicknames,
channels, default boards, repo/ticketing config) don't need a restart. Everything else does.
Add a tool
The architecture's payoff: a new workflow is small and local — the gateway/agent core stays untouched.
1. Write a new module in krahnie/tools/ — a factory make_<x>_tool(get_ctx)
that returns an @tool(...) handler. It reads the turn's context via get_ctx(), does its
work, and posts Block Kit via slackio.
2. Add one line to the list in krahnie/tools/__init__.py.
3. Add a routing hint in prompts.py so the orchestrator knows when to pick it.
Tools are exposed as mcp__krahnie__<tool_name> and are framework-portable:
the same objects run under the Claude Agent SDK MCP server and the Pydantic-AI loop. See an existing
module like tools/week.py or one of the recent five (cardcomment, clientpulse,
capacity, stalecards, draftcards) as a template.