Proactive context for Slack conversations.
When a colleague messages you, slackfold already knows what you've been working on together. It pulls context from Slack DMs, channels, Confluence pages, and Jira tickets, ranks it by recency and relevance, and surfaces it alongside the incoming message. You reply in 10 seconds instead of spending 5 minutes searching.
Daily Slack conversations have two interleaving problems:
-
Topic mingling in DMs. You discuss topics T1, T2, T3 with colleague C1 in a single DM thread. Messages about different topics are interleaved chronologically.
-
Topic scattering across channels. The same topic T1 is discussed with C1 in DM, C2 in DM, and in #project-channel. Context is fragmented across 5+ locations.
When C1 messages you about T1, you need to mentally reconstruct context from all these scattered conversations. Today this means: open Slack, search keywords in multiple channels, scroll through DMs, check Confluence, check Jira. Multiple rounds of searching.
Search is reactive. slackfold is proactive. When a message arrives, relevant context from every source is already compiled and waiting.
incoming Slack message
|
v
+-----------------+
| Context Engine | Match artifacts, gather evidence,
| | rank by recency + statement type
+---------+-------+
|
+--------------+--------------+
| | |
+--------v---+ +------v------+ +----v--------+
| Slack Chat | | Confluence | | Jira/GitHub |
| Fragments | | Wiki Pages | | Tickets |
+--------+---+ +------+------+ +----+--------+
| | |
v v v
Fragment Wiki Page Evidence
Classifier + Evidence Records
Extraction
Every piece of knowledge is an evidence record with provenance, timestamp, confidence, and statement type:
| Statement type | Example | Weight |
|---|---|---|
| decision | "We're going with Postgres" | High |
| status | "Migration is 80% done" | Medium |
| proposal | "What if we used DynamoDB?" | Lower |
| speculation | "I wonder if we should cancel it" | Low |
Decisions outweigh proposals. Recency outweighs source authority. A chat message from yesterday saying "we decided X" supersedes a Confluence page from last month saying "we're considering Y."
- Structured sources (Confluence, Jira) compile into wiki pages + evidence records via the LLMKB pattern. Stable, authored content where pre-processing works well.
- Chat data (Slack DMs, group DMs, channels) stays as raw messages with lightweight fragment indexing. JIT synthesis at query time avoids compounding classification errors on ephemeral messages.
Work artifacts are the organizing abstraction. A "work artifact" is a nameable thing people collaborate around: a project, a feature, an incident, a decision.
Content from all sources links to artifacts through three tiers:
- Explicit mapping from config (confidence 1.0)
- Keyword matching via Jaccard similarity (fast, deterministic)
- LLM-assisted for ambiguous content, including proposing new artifacts
+-------------------------------------+
| Tauri Desktop App (React/TypeScript)|
| - Conversation list with context |
| - Context drawer (messages+evidence)|
| - Reply with send |
| - Settings page |
| - Cmd+K quick switch |
+----------------+--------------------+
| localhost:8000
+----------------v--------------------+
| Python Backend (FastAPI) |
| - Slack ingestion (60s poll) |
| - Confluence ingestion (1hr poll) |
| - Fragment classifier (4-stage) |
| - Evidence model + SQLite |
| - Context engine (JIT synthesis) |
| - LLM via OpenAI-compatible API |
+-------------------------------------+
Local-first. All data stays on your machine. No cloud service, no telemetry. The only external calls are to Slack's API (fetching messages) and your LLM provider (classification + synthesis).
- Python 3.11+, uv
- Node.js 20+, npm
- An OpenAI-compatible LLM endpoint (litellm, openrouter, local Ollama, etc.)
- A Slack workspace with a user token
git clone https://github.com/gyang274/slackfold.git
cd slackfold/src/server
# Create .env from template
cp .env.example .env
# Edit .env with your Slack token, LLM endpoint, etc.slackfold uses Slack session cookies (not a bot token) to see what you see:
- Open Slack in your browser (not the desktop app)
- Open DevTools (F12) > Application > Cookies
- Copy
xoxc-...token andxoxd-...cookie - Paste into
.env
Edit config.yaml to specify which channels to follow:
slack:
dms: all # auto-discover all DMs
group_dms: all # auto-discover all group DMs
channels:
- id: C0XXXXX # channel ID from Slack URL
name: "#your-channel"
type: team # or "subject" for focused channelsEdit dat/people.yaml to register the people you work with:
- id: alice
name: Alice Smith
role: eng
slack_user_id: U0XXXXX
team: platformEdit dat/artifacts.yaml to define work artifacts:
- id: api-migration
name: API v3 Migration
type: project
keywords: [api, migration, v3, postgres]
people: [alice, bob]slackfold works with any OpenAI-compatible API. Example with litellm:
# In a separate terminal
litellm --config litellm-config.yaml --port 4000# Terminal 1: backend
cd src/server
uv run python -m slackfold serve
# Terminal 2: frontend
cd src/client
npm install && npm run devOpen http://localhost:1420 (Tauri) or http://localhost:5173 (browser dev).
# Ingest Slack messages
uv run python -m slackfold ingest --source slack
# Ingest Confluence pages (requires CONFLUENCE_TOKEN in .env)
uv run python -m slackfold ingest --source confluenceslackfold ingests Confluence pages as structured wiki pages with automatic artifact linking and evidence extraction.
Configure in dat/raw/confluence/config.yaml:
base_url: https://confluence.example.com
token: ${CONFLUENCE_TOKEN}
projects:
- space: ENG
root_page_id: "12345"
name: "Engineering"
people:
- confluence_username: Alice.Smith
confluence_user_id: Z00ABC
person_id: alicePages are linked to artifacts through the three-tier strategy. The LLM proposes new artifacts for content that doesn't match existing ones. Evidence is extracted using source-specific prompts that understand Confluence page structure.
-
Evidence model as the core. Every fact has provenance, timestamp, confidence, and statement type. Decisions outweigh proposals. Recency outweighs source authority.
-
Dual-layer knowledge base. LLMKB wiki for structured sources, fragment index + JIT for chat. Each source type gets the treatment that fits its nature.
-
Work artifacts as the organizing abstraction. Not topics, not tags. Artifacts are the concrete things people collaborate on, emerging from structured sources and manual creation.
-
Source-specific carryover windows. DM: 24h. Group DM: 48h. Channel: 1h per thread. Thread replies always inherit from parent.
-
Mandatory review before send. Every outgoing message must be confirmed.
-
Local-first. All data on your machine. No cloud dependency beyond Slack API and LLM.
src/
client/ # Tauri v2 + React + TypeScript
src/
App.tsx # Root layout, polling, mark-read
components/
Sidebar.tsx # DMs + Channels sections
ChatThread.tsx # Messages + context + input
ContextDrawer.tsx # Evidence timeline
SettingsPage.tsx # LLM + Slack config
QuickSwitch.tsx # Cmd+K overlay
server/ # Python backend
slackfold/
api/routes.py # FastAPI endpoints
adapter_slack.py # Slack message fetching
adapter_confluence.py # Confluence page ingestion
classifier.py # 4-stage fragment classifier
context.py # JIT context engine
evidence.py # Evidence store + ranking
ingest.py # Ingestion orchestrator
models.py # Pydantic models
dat/
people.yaml # People registry
artifacts.yaml # Work artifacts
raw/ # Raw source data
tests/ # 175 tests
Working prototype. Core loop validated with real Slack data:
- Slack ingestion with incremental cursors and smart polling
- 4-stage fragment classifier with source-specific carryover windows
- Evidence-ranked context cards with conflict detection
- Confluence ingestion with three-tier artifact linking and LLM evidence extraction
- Tauri + React desktop app with mark-read-on-view, context drawer, settings
- 175 backend tests passing
- Jira adapter (status transitions, ticket comments)
- GitHub issues/PRs adapter (merge decisions, review approvals)
- Evidence clustering for cross-source deduplication
-
slackfold init(auto-seed artifacts from all sources) - Reply drafting with personality matching
- Dark mode
