Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Slack Daily Synthesis

ASecurity

Synthesize Slack threads I participated in into the Logseq daily journal. Default mode walks backwards until finding a day already synthesized.

8 stars
0 votes
0 copies
0 views
Added 9/20/2026
researchgoshellbashreactapi

Works with

cliapimcp

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add tstapler/dotfiles --skill slack-daily-synthesis --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Slack Daily Synthesis?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Slack Daily Synthesis
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tstapler-slack-daily-synthesis/badge)](https://www.skillsdirectory.com/skills/tstapler-slack-daily-synthesis)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
description: Synthesize Slack threads I participated in into the Logseq daily journal. Default mode walks backwards until finding a day already synthesized.
---

# Slack Daily Synthesis

Synthesize Slack conversations into the Logseq daily journal entries.

Supports three modes:
- **Default** (no args): walk backwards from today until finding a day already synthesized
- **`--yesterday`**: previous calendar day only (for 9am cron)
- **`--backfill`**: find the last synthesis date and fill in all missing days up to today (same as default but explicit)

## Step 0: Resolve the Logseq Graph Path

Never hardcode the graph location. Resolve it once, path-agnostically, so this works both in an
interactive session and under the launchd cron (where shell functions/exports are not sourced):

```bash
# Prefer $LOGSEQ_PATH (set by the cron agent + shell exports); then the logseq_path helper if
# available; then fall back to filesystem detection. First dir that contains journals/ wins.
GRAPH="${LOGSEQ_PATH:-}"
if [ -z "$GRAPH" ] && command -v logseq_path >/dev/null 2>&1; then GRAPH="$(logseq_path)"; fi
for c in "$GRAPH" "$HOME/Documents/notes" "$HOME/Documents/personal-wiki/logseq"; do
  if [ -n "$c" ] && [ -d "$c/journals" ]; then GRAPH="$c"; break; fi
done
JOURNALS="$GRAPH/journals"
PAGES="$GRAPH/pages"
CACHE="$GRAPH/.slack-thread-cache"   # hidden dir under the graph; ignored by Logseq
echo "Graph: $GRAPH"
```

Use `$JOURNALS`, `$PAGES`, and `$CACHE` throughout — never a literal `personal-wiki` or `notes` path.

## Step 1: Determine Date Range

Use the argument if provided: `{{args}}`

Run this to get today's date:
```bash
date +%Y-%m-%d
```

**If `--yesterday`**: Single date = yesterday. Done.

**Default or `--backfill`**: Walk backwards from today. For each candidate date (today, yesterday, day before, ...):
1. Check if the journal file exists: `$JOURNALS/YYYY_MM_DD.md`
2. If it exists, grep for `[[Slack]] conversations` — if found, **stop here** (this day and everything before is already done)
3. If not found (or file doesn't exist), add this date to the processing queue
4. Continue backwards up to a maximum of 30 days

Process the queue oldest-first so the journal entries read chronologically.

```bash
# Check if a journal day is already synthesized
grep -l "\[\[Slack\]\] conversations" "$JOURNALS/YYYY_MM_DD.md" 2>/dev/null
```

## Step 2: For Each Date in Range, Search Slack Threads

Slack access is the **slack-interactions** script — self-contained (needs only the machine-local
token file), so it works under the launchd cron with no MCP/plugin loading. Resolve it once:

```bash
SLACK_REQ="${SLACK_REQ:-$(ls "$HOME"/ws/*/plugins/slack-interactions-plugin/skills/slack-interactions/scripts/slack_request.py 2>/dev/null | head -1)}"
```

Search for threads *I* participated in. "I" spans my human identity **and** the bot that posts on my
behalf (both represent my conversations in this workspace). Override with env vars:

```bash
SYNTH_USERS="${SYNTH_USERS:-tstapler tylerbot}"   # from: takes a Slack username, not a user ID
SYNTH_MENTION="${SYNTH_MENTION:-U0BCQ0ME13K}"      # my human user ID, for the mention search
```

**Note**: Slack search `before:` is unreliable with `is:thread`. Use only `after:` with the day
*before* the target date, then post-filter to messages whose `ts` falls within the target day.

For each date (`DAY`, with `PREV` = the day before), run these searches, paginating each fully
(`--paginate-through-all`, `sort=timestamp`, `sort_dir=asc`) and collecting every result:

```bash
DAY=YYYY-MM-DD; PREV=YYYY-MM-DD-1
for U in $SYNTH_USERS; do
  # replies I wrote (is:thread), and threads I started (no is:thread)
  "$SLACK_REQ" --endpoint /api/search.messages --param query="from:@$U is:thread after:$PREV" --param sort=timestamp --param sort_dir=asc --paginate-through-all --json-pretty
  "$SLACK_REQ" --endpoint /api/search.messages --param query="from:@$U after:$PREV"            --param sort=timestamp --param sort_dir=asc --paginate-through-all --json-pretty
done
# threads where I was mentioned
"$SLACK_REQ" --endpoint /api/search.messages --param query="<@$SYNTH_MENTION> is:thread after:$PREV" --param sort=timestamp --param sort_dir=asc --paginate-through-all --json-pretty
```

Post-filter: keep only messages whose `ts` is within `DAY`. For the "threads I started" search, keep
only roots (`thread_ts == ts`) or messages with `reply_count > 0`.

**Deduplication**: dedupe all collected messages by `(channel, thread_ts)`. Each unique pair is one
thread to process.

**Search reach**: Slack search only goes back ~90 days; older dates may return empty — skip silently.

## Step 2b: Read Threads (Cache-First)

Before reading any thread via the Slack API, check the local cache:

**Cache path**: `$CACHE/YYYY-MM-DD/{channel_id}__{thread_ts}.md`

For each unique `thread_ts`:
1. Determine its date bucket (from the message timestamp)
2. Check if `$CACHE/YYYY-MM-DD/{channel_id}__{thread_ts}.md` exists
3. If cached: read from file — skip Slack API call
4. If not cached: fetch it with
   `"$SLACK_REQ" --endpoint /api/conversations.replies --param channel=$channel_id --param ts=$thread_ts --pretty`,
   then write the content to the cache file

Cache file format:
```markdown
# Thread: {channel_name} / {thread_ts}
channel_id: {channel_id}
thread_ts: {thread_ts}
permalink: {permalink_url}
date: YYYY-MM-DD

---

{raw thread content — messages in order with author, timestamp, text}
```

Cache directory structure (`$CACHE`):
```
.slack-thread-cache/
└── YYYY-MM-DD/
    └── {channel_id}__{thread_ts}.md
```

This ensures future backfills and re-runs never re-fetch threads already retrieved. The cache is permanent — don't expire or delete entries.

## Step 3: Cluster Threads by Topic

Group the unique threads into thematic clusters. Skip:
- Pure social/reaction threads (no substantive content)
- Incident channel noise with no decision
- Bot-only threads

For each substantive cluster, identify:
- **Topic**: What was being discussed
- **Channel**: Where it happened
- **Participants**: Who else was involved
- **Key points**: What was said / decided / learned
- **Decisions or action items**: Anything that requires follow-up
- **Insights worth keeping**: Technical learnings, strategic thinking, patterns noticed

## Step 4: Write Inline to Today's Logseq Journal

Synthesis goes **directly into the journal** — not a separate Knowledge Synthesis zettel. This keeps everything browsable inline in the daily entry.

Journal path: `$JOURNALS/YYYY_MM_DD.md`
(Use underscores, not hyphens, for the filename)

If the journal file doesn't exist, create it. Always **append** — never overwrite existing content.

**In `--backfill` mode**: Many historical journal files may already exist with personal notes (reading, home, etc.). Append the Slack section at the end — it's additive context for what that day looked like.

Append using Logseq-native nested bullet structure. Each cluster gets a thread permalink so entries are clickable back to the original conversation:

```markdown
- [[Slack]] conversations
	- [Cluster Topic 1] ([#channel-name](permalink-url))
		- Key point 1
		- Key point 2
		- Decision: ...
		- Action item: ... (if any)
		- Related: [[Concept]], [[Tool]], [[Person]]
	- [Cluster Topic 2] ([#channel-name](permalink-url))
		- ...
```

The permalink for each cluster should link to the **root message** of the thread (`thread_ts` = `message_ts` of the first message), not a reply. Use the `Permalink` field from the search results for the earliest message in each thread.

## Step 6: Surface Any Wiki Candidates

For each major concept, tool, person, or decision that came up in the conversations:
- Check if `$PAGES/<Concept>.md` already exists
- If not, note it as a candidate for a future zettel
- Only create stubs for things that are genuinely worth expanding later

Report candidates but don't auto-create unless explicitly asked.

## Output Report

After completing:

```
=== Slack Daily Synthesis Complete ===
Date: YYYY-MM-DD
Threads processed: N
Clusters synthesized: N

Topics:
  - [Cluster 1 topic] (#channel): [1-line summary]
  - [Cluster 2 topic] (#channel): [1-line summary]
  ...

✓ Journal → $JOURNALS/YYYY_MM_DD.md (inline)
○ Wiki candidates: [list if any]
```

---

## Scheduling (launchd)

The durable, always-on scheduler lives in `stapler-scripts/slack-synthesis/`. It is a launchd
agent (`com.tstapler.slack-synthesis`) that runs `claude -p "/knowledge:slack-daily-synthesis
--yesterday"` at 09:10 local each day, with `LOGSEQ_PATH` exported so the graph resolves the same
way it does interactively.

Install / reinstall (idempotent):

```bash
~/dotfiles/stapler-scripts/slack-synthesis/install.sh
```

Manage:

```bash
launchctl kickstart -k gui/$(id -u)/com.tstapler.slack-synthesis   # run now
launchctl print gui/$(id -u)/com.tstapler.slack-synthesis          # status
tail -f ~/Library/Logs/slack-synthesis.log                          # logs
launchctl bootout gui/$(id -u)/com.tstapler.slack-synthesis        # disable
```

To change the schedule or graph path, edit `run.sh` / the plist in that directory and re-run
`install.sh`. Missed runs (laptop asleep) fire on the next wake because `--yesterday` + the
walk-back logic backfill any gap.

Attribution

tstaplertstapler
View sourceMore from tstapler →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Competitor Analysis

This skill provides comprehensive analysis of competitor SEO and GEO strategies, revealing what's working in your market and identifying opportunities to outperform the competition.

1823 votes

Deep Research

Universal deep research agent team. 13-agent pipeline for rigorous academic research on any topic. 7 modes: full research, quick brief, paper review, lit-review, fact-check, Socratic guided research dialogue, and systematic review with optional meta-analysis. Covers research question formulation, Socratic mentoring, methodology design, systematic literature search, source verification, cross-source synthesis, risk of bias assessment, meta-analysis, APA 7.0 report compilation, editorial review...

452202 votes

Paperclip Distill

Use when an operation issue is a Paperclip cursor-window, distill, or backfill — `operationType: "distill"` or `"backfill"` and the body references a Paperclip source bundle for a project or root issue. Turn raw Paperclip activity into a wiki-insightful project page, decisions log, and history note. This skill exists specifically to replace the stiff, datestamp-heavy templated output that the deterministic distiller produces.

805541 votes

Academic Pipeline

Orchestrator for the full academic research pipeline: research -> write -> integrity check -> review -> revise -> re-review -> re-revise -> final integrity check -> finalize. Coordinates deep-research, academic-paper, and academic-paper-reviewer into a seamless 10-stage workflow with mandatory integrity verification, two-stage peer review, and reproducible quality gates. Triggers on: academic pipeline, research to paper, full paper workflow, paper pipeline, end-to-end paper, research-to-publi...

452201 votes

Exa Search

Semantic search, similar content discovery, and structured research using Exa API

304951 votes
View all in research →