Expand description
SlackFacade - the seam between the Slack MCP tools and workspace
state. The production impl (ProdSlackFacade) resolves the
caller’s workspace from its project’s config binding and drives that
workspace’s client; the mock returns preloaded results so the tool
tests can assert argument handling and error surfacing without a real
workspace.
Re-exports§
use std::collections::HashMap;🔒use std::sync::Arc;🔒use std::sync::Weak;🔒use std::time::SystemTime;🔒use forge_connectors::slack::AuthTest;🔒use forge_connectors::slack::MENTION_CURSOR;🔒use forge_connectors::slack::SlackApi;🔒use forge_connectors::slack::SlackError;🔒use forge_connectors::slack::SlackHistoryMessage;🔒use forge_connectors::slack::flatten_mrkdwn;🔒use forge_connectors::slack::mention_ids;🔒use forge_connectors::slack::one_line_excerpt;🔒use forge_connectors::slack::read_thread;🔒use forge_connectors::slack::thread_parent;🔒use forge_connectors::slack::user_display_name;🔒use forge_primitives::slack::SlackBookmark;🔒use forge_primitives::slack::SlackConversation;🔒use forge_primitives::slack::SlackDraft;🔒use forge_primitives::slack::SlackPerson;🔒use forge_primitives::slack::SlackPin;🔒use forge_primitives::slack::SlackSearchMatch;🔒use forge_primitives::slack::SlackSubscription;🔒use forge_primitives::slack::SlackSubscriptionTarget;🔒use forge_primitives::slack::SlackThreadName;🔒use forge_primitives::slack::SlackUser;🔒use forge_primitives::slack::SlackWatchMode;🔒use uuid::Uuid;🔒use crate::SessionSlot;🔒use crate::mcp::caller_context::caller_context;🔒use crate::mcp::gotify::facade::resolve_identity;🔒use crate::workspace::Workspace;🔒
Structs§
- Prod
Slack 🔒Facade - Production facade over
Weak<Workspace>(weak to avoid a cycle with the MCP server the workspace owns). - Resolve
OnDrop 🔒 - Resolves the draft if the awaiting future is dropped before the reader answers - the calling session died mid-wait. Without this the registry entry and its oneshot sender outlive everyone who could answer them.
- Slack
Channel 🔒Watch - Slack
Edit 🔒Request - One message to edit or delete. Both actions are gated like a post.
- Slack
Fetch 🔒Request - What a caller asked to fetch.
- Slack
Post 🔒Outcome - What a post did: the
tsof each message it sent, in the order they went out, the conversation it landed in (the name, or the id when the lookup failed), and how many parts the text was split into. A draft past the truncation point is split and posted in sequence, so a long one is several messages a reply can attach to. - Slack
Post 🔒Request - What a caller asked to post. Composed here, not in the connector, so the draft can be held for the user’s decision before anything is sent.
- Slack
React 🔒Request - One reaction to add or remove.
- Slack
Upload 🔒Request - What a caller asked to upload.
Enums§
- Gate
Decision 🔒 - How a held draft ended: the reader’s answer, or nothing at all when the asking session went away mid-wait.
- Slack
Attachment 🔒Error - Slack
Edit 🔒Error - Slack
Post 🔒Error - Why a post did not happen.
- Slack
React 🔒Error - Slack
Read 🔒Error - Why a read-only lookup failed. Shared by every read tool because their failure sets are identical; the per-operation error convention exists where the sets differ (post, edit and react each fail differently), and two names for one set would be duplication.
- Slack
Subscribe 🔒Error - Why
slack__subscribefailed. - Slack
Subscribe 🔒Request - What a caller asked to watch, before it becomes records.
- Slack
Unsubscribe 🔒Error - Why
slack__unsubscribefailed. The last two are the two cases a refusal keeps apart: an id the project holds under another session reads differently from one the project never had. - Slack
Workspace 🔒Error - Why resolving a tool’s workspace failed. One shape for every Slack
tool, so the wording is the same whichever tool was called. The scope
is the caller’s slot, so the cases are a file with no
[[slack]]section at all, a project with nothing bound to it, and a binding to a workspace whose entry was added or renamed since boot.
Constants§
- BINDING_
KEYS 🔒 - MAX_
SEARCH_ 🔒FILTER_ PAGES - How many search pages a conversation filter scans. A named conversation is narrowed server-side and usually answers on the first page; an unnamed DM is filtered locally, and five pages is where a sparse hit stops being worth another call against the token’s allowance.
Traits§
- Slack
Facade 🔒 - The Slack tools’ view of the workspace.
Functions§
- format_
workspace_ 🔒error - The one wording for a refused workspace, so every Slack tool answers
this case the way
slack__listdoes. - resolve_
in 🔒 - The workspace
caller’s project acts in, and the client for it: the project’s binding, else its org’s, both resolved at load. - safe_
file_ 🔒name - A file name that came from Slack is untrusted input: it is whatever the
uploader chose to call the file. Take only the final path component,
refuse
.and.., and fall back to the file id when nothing usable is left - so the result can only ever be one name inside the directory the caller asked for. - slack_
ts_ 🔒now - The current instant as a Slack
ts, so a new subscription can start from now rather than from the channel’s history. - user_
matches 🔒 - Whether
useranswers toneedle, which is already lowercase: a case-insensitive substring over the handle, the real name and the display name, which is the one people actually type.