| name | htools-htask-slack-commitment-sync |
| description | One-way sync of commitments you made in Slack into the htask database — finds messages from the last day where you said you'd do something, captures the message plus its thread context, and creates a task per commitment keyed by the message permalink. Use when asked to sync Slack commitments, pull promises from Slack, or check Slack for things you said you'd do. |
htools-htask-slack-commitment-sync
Slack is the source of truth for commitment-sourced tasks; the local db follows.
Create-only and idempotent — run it as often as you like. The join key is the
task's source ref, the message permalink. This skill never edits, completes,
or archives an existing task; closing out a commitment is your job in htask.
Access
These steps use the connected claude.ai Slack MCP server. If the only
Slack tool present is mcp__claude_ai_Slack__authenticate, the connector isn't
authed yet: call it, share the authorization URL with me, and once I've
authorized, pass the callback URL to complete_authentication. Then
re-discover the now-live Slack tools (ToolSearch slack) before continuing.
Pick tools by capability — search, conversation history / thread replies,
permalink, and "who am I" — from whatever the server exposes; exact names vary.
Gather
Slack side. Resolve your own user first (the authed identity) so you can
keep only messages you wrote. Then search your last-day messages — Slack query
syntax, narrowed by date and author:
from:@me after:<yesterday, YYYY-MM-DD>
If the connector doesn't resolve @me, use your handle (from:@hirad).
after: filters by whole day, so it returns a bit more than 24h — keep only
hits whose timestamp is within the last 24 hours. If the result set comes back
at the tool's limit, narrow the window or raise the limit and say so: a
truncated page must never be read as "that's everything."
For each hit that reads like a commitment (see Detect), pull just enough
context to know what was promised and to whom — the thread it sits in (replies)
or a few surrounding messages, plus the channel / DM name. Get the canonical
permalink for the message; that's the join key.
htask side. Live and archived slack-sourced tasks:
htask ls --source slack --json
htask ls --source slack --archived --json
Each object carries short_id, title, description, status, and
source.ref (the permalink). Collect the permalinks across both lists —
that's everything already synced.
Detect
Count a message only as a concrete commitment: a clear, personal, future
action you took on — "I'll fix the timeout", "I'll send Sam the API doc",
"I'll look into the flaky test by Friday".
Leave out:
- vague or hypothetical musings ("we should maybe…", "might be worth…");
- obligations that aren't yours ("can you…", "we'll need to…") — only your
commitments;
- a promise the message itself already fulfills ("done — here's the PR"): not
an open action.
When the message is elliptical ("yep, I'll handle it"), the thread context is
what tells you what "it" is — fold that into the title. If one message bundles
several deliverables, keep it as one task and list them in the description; the
permalink stays a single clean key.
Reconcile
For each concrete commitment whose permalink is not already in the synced
set:
htask add --title <action paraphrase> --desc <body> <permalink>
--title is a short paraphrase of the action ("Send Sam the API doc"), taken
literally so a colon in it isn't peeled off as a tag.
--desc is your verbatim Slack line, then a one-line context — the channel /
DM and who or what it's about (and the thread gist if the line alone is
opaque).
- the bare permalink token sets the Slack source. Normalize it to the canonical
…/archives/<C>/p<ts> form (drop any ?thread_ts=…&cid=… query tail) so
re-runs match and don't double-create.
Permalink already in the set (live or archived) → skip, untouched. An
archived one means you filed it away on purpose; don't resurrect it. Never edit,
complete, or archive an existing task here — create-only.
Report
End with one compact line per bucket — created / skipped (already synced) /
rejected (candidates that didn't clear the commitment bar) — plus anything odd:
connector needed auth, search truncated, an ambiguous "I'll do it" left out for
lack of context. Nothing else.