@pratik7368patil/signald
v1.2.0
Published
Local-first Slack coworker assistant daemon.
Maintainers
Readme
SignalDesk
SignalDesk is a local-first Slack coworker assistant. The Slack app lives in Slack, but the backend runs on your machine as signald. It listens over Bolt JS Socket Mode, gathers Slack and repo context, asks local context tools like anchor, runs a configured CLI agent, and sends you a private DM draft.
SignalDesk never posts a public Slack reply automatically. The only public post path is the explicit Post as Me button on a private draft.
For npm users:
npm install -g @pratik7368patil/signald
sig init
sig setup open
sig doctorThe npm package is scoped as @pratik7368patil/signald; the installed command names remain sig and signald.
Setup
- Install dependencies:
npm install- Create a Slack app from
slack-app-manifest.yaml.
In Slack's app dashboard, click Create New App, choose From an app manifest, select your workspace, choose YAML, and paste slack-app-manifest.yaml.
Then copy these values into .env:
SLACK_CLIENT_ID:Basic Information->App Credentials->Client IDSLACK_CLIENT_SECRET:Basic Information->App Credentials->Client SecretSLACK_APP_TOKEN:Basic Information->App-Level Tokens-> generate a token withconnections:write
Required MVP scopes:
app_mentions:readcommandschat:writeusers:readchannels:historyreactions:writeim:write
Optional personal mention mode also needs the matching history scopes:
groups:historympim:historyim:history
- Configure environment:
cp .env.example .envSet SLACK_APP_TOKEN, SLACK_CLIENT_ID, and SLACK_CLIENT_SECRET. Then run sig slack login to install the app and store bot/user tokens locally. SLACK_BOT_TOKEN and SLACK_USER_TOKEN are still supported as optional fallbacks.
If you are on http://127.0.0.1:31337/slack/oauth/callback without first running sig slack login, close that tab. The callback URL is only used after Slack redirects back to SignalDesk during login.
- Configure SignalDesk:
cp assistant.config.example.yaml assistant.config.yaml
npx tsx src/cli/sig.ts config validate
npx tsx src/cli/sig.ts slack login- Run locally:
npm run devAfter building, the production commands are:
npm run build
sig dev
signaldCLI
sig init: create or migrate local config and print setup next stepssig setup open: open the local dashboard athttp://127.0.0.1:31337sig doctor: check Slack, OAuth, SQLite, Anchor, repos, docs, agent, and daemon healthsig dev: runsignaldin the foregroundsig start: startsignaldin the backgroundsig stop: stop the background daemonsig status: show daemon statussig slack login: install SignalDesk to Slack with OAuth and store the bot token locallysig slack status: show local Slack installation statussig slack logout: delete the local Slack installationsig github setup: select GitHub repositories withgh, add them to config, and index themsig repos discover/add/list/index/sync/map-channel: configure repositories and Anchor indexessig docs add/list/index: configure and index local docs into SQLite FTSsig inbox: list attention items for mentions, watched threads, batched FYIs, and pending draftssig inbox show/dismiss/snooze/draft: inspect and manage attention itemssig watch <slack-link>: privately watch a Slack thread for follow-up signalssig watch list/stop: inspect or stop watched threadssig profile edit: update role, tone, uncertainty language, and writing-style notessig profile examples add: add a local writing-style examplesig tools add-mcp/list/test: configure read-only MCP context toolssig service install/start/stop/logs: install or inspect local service helperssig audit: inspect local audit logssig index: compatibility alias for repository Anchor indexingsig anchor status: show Anchor index healthsig mcp list: compatibility command to list tools from a configured MCP serversig mcp call: call an allowed read-only MCP toolsig test: run testssig config validate: validateassistant.config.yamlsig config migrate: migrate older configs toconfig_version: 2
Local Dashboard
signald serves a dependency-light local dashboard on 127.0.0.1:31337 when dashboard.enabled is true:
sig start
sig setup openThe dashboard shows setup steps, daemon/Slack/agent status, the Attention Inbox, recent drafts, and audit logs. It never exposes Slack tokens. If you open /slack/oauth/callback directly, the page explains that the callback only works during sig slack login.
Docs
Anchor
SignalDesk supports pratik7368patil/anchor, which is a local-first MCP server for merged GitHub PR-history context. Anchor does not index source files for SignalDesk; it builds a local .anchor/index.sqlite from GitHub pull request history and exposes sanitized evidence through MCP tools.
npm install -g @pratik7368patil/anchor
gh auth login
cd ~/code/payments-service
anchor index --repo your-org/payments-service --limit 200At draft time SignalDesk starts Anchor with:
anchor serveThen it calls the read-only MCP tool:
anchor_get_contextThe returned PR-history evidence is added to the agent prompt as repository context. If anchor is missing, the MCP server fails, or .anchor/index.sqlite does not exist, SignalDesk still creates a Slack-only draft and records the degraded context in assumptions.
Configure Anchor per repository:
repositories:
- id: payments
path: "~/code/payments-service"
github_repo: "your-org/payments-service"
channels: ["C012PAYMENTS"]
anchor:
enabled: true
command: ["anchor", "serve"]
index_limit: 200
sync_on_index: false
env_allowlist:
- HOME
- PATH
- GITHUB_TOKEN
- GH_TOKENsig repos index runs anchor index or anchor sync from each repository path. It does not pass source include/exclude globs to Anchor because Anchor indexes GitHub PR history, not working-tree source files. Secret-like source patterns are therefore never sent to Anchor as indexing inputs.
Helpful commands:
sig github setup ~/code
sig github setup ~/code --owner your-org
sig repos index
sig anchor status paymentssig github setup uses your local GitHub CLI login. Run gh auth login first. The setup flow lists repositories in the terminal, lets you select by number, supports a to add/clone a repo that is not shown, updates assistant.config.yaml, and auto-runs Anchor indexing. If SignalDesk needs a token for indexing, it reads gh auth token and passes it only to the indexing subprocess as GH_TOKEN; it is not stored or printed.
MCP Tools
SignalDesk has a small generic MCP client layer in src/mcp. It is designed for read-only local context tools, so new integrations can be added without coupling them to Slack or draft generation.
Add a server to config:
mcp:
enabled: true
servers:
- id: docs
enabled: true
command: ["my-local-mcp", "serve"]
cwd: "~/code/payments-service"
env_allowlist: ["HOME", "PATH"]
timeout_seconds: 30
local_only: true
read_only: true
allowed_tools: ["docs_search"]Inspect and call configured tools:
sig mcp list docs
sig mcp call docs docs_search '{"query":"retry policy"}'The generic registry enforces configured allowed_tools, passes only allowlisted environment variables, and treats MCP output as untrusted context evidence.
Agent Contract
Agents receive JSON on stdin and must return JSON only:
{
"draft": "...",
"confidence": 0.0,
"assumptions": [],
"sources": [],
"needs_human_review": true
}SignalDesk passes only a minimal environment allowlist to agents. It does not assume every local CLI is backed by a local model; when allow_network_for_agents is false, configured agents must be marked local_only: true.
Slack Behavior
- MVP trigger:
app_mention - Optional trigger: personal mentions of
<@USER_ID>when enabled in config - Bot and self messages are ignored
- Drafts are sent by DM using
chat.postMessage Edit,Regenerate,Post as Me,Explain Sources, andDismissare interactiveEdituses a Slack modalPost as Mesends to the original thread withchannelandthread_ts, using the Slack user token when available- Event handling does not post to the original channel
- Low-priority items can be batched into
sig inboxinstead of interrupting you immediately - Watched threads notify privately only when SignalDesk detects a mention, review/approval ask, incident language, or a reopened thread
Verification
npm test
npm run typecheck
npm run lint