Skip to main content

Module facade

Module facade 

Source
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::shared_messages; 🔒
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§

ProdSlackFacade 🔒
Production facade over Weak<Workspace> (weak to avoid a cycle with the MCP server the workspace owns).
ResolveOnDrop 🔒
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.
SlackChannelWatch 🔒
SlackEditRequest 🔒
One message to edit or delete. Both actions are gated like a post.
SlackFetchRequest 🔒
What a caller asked to fetch.
SlackPostOutcome 🔒
What a post did: the ts of 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.
SlackPostRequest 🔒
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.
SlackReactRequest 🔒
One reaction to add or remove.
SlackUploadRequest 🔒
What a caller asked to upload.

Enums§

GateDecision 🔒
How a held draft ended: the reader’s answer, or nothing at all when the asking session went away mid-wait.
SlackAttachmentError 🔒
SlackEditError 🔒
SlackPostError 🔒
Why a post did not happen.
SlackReactError 🔒
SlackReadError 🔒
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.
SlackSubscribeError 🔒
Why slack__subscribe failed.
SlackSubscribeRequest 🔒
What a caller asked to watch, before it becomes records.
SlackUnsubscribeError 🔒
Why slack__unsubscribe failed. 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.
SlackWorkspaceError 🔒
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§

SlackFacade 🔒
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__list does.
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 user answers to needle, 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.