关于 pp-slack
pp-slack 是使用 slack-pp-cli 搜索和分析 Slack 对话的技能,支持将内容同步到本地归档,保留超出 Slack 留存期限的消息。它适合查找过往决定、跟进未读动态和检查频道活动。
主要功能
- 01将对话、用户、文件和反应同步到本地
- 02全文检索归档消息
- 03汇总近期动态和待回复内容
- 04查找过期线程并分析频道活动
- 05将 Slack ID 解析为用户信息
适用场景
- 01查找 Slack 历史消息中的决定
- 02跟进提及和未回复的线程
- 03评估频道活动以规划归档
- 04根据 ID 识别 Slack 用户
MCP 相关
所提供的内容介绍了 CLI 用法,但未说明 MCP 集成。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mvanhorn/ printing-press-library --skill pp-slack安装后在 Claude Code 中输入/pp-slack确认已加载。
详细介绍
Slack — Printing Press CLI
由 @mvanhorn(Matt Van Horn)创建。 贡献者: @ChrisGutierrezNet(Chris G. | AI Automation)、@cathrynlavery(Cathryn Lavery)。
前提条件:安装 CLI
此技能通过 slack-pp-cli 二进制文件运行。**在调用此技能中的任何命令前,必须确认 CLI 已安装。**如果尚未安装,请先安装:
- 使用 Printing Press 安装程序进行安装。默认情况下,macOS/Linux 上的二进制文件安装到
$HOME/.local/bin,Windows 上则安装到%LOCALAPPDATA%\Programs\PrintingPress\bin:npx -y @mvanhorn/printing-press-library install slack --cli-only - 验证:
slack-pp-cli --version - 确保所报告的安装目录位于将调用此技能的 Agent/运行时的
$PATH中。
如果 npx 安装失败(没有 Node、离线等),请改用直接 Go 安装(需要 Go 1.26.6 或更高版本)。此方式会安装到 $GOPATH/bin(默认是 $HOME/go/bin),因此请将该目录添加到 $PATH:
go install github.com/mvanhorn/printing-press-library/library/productivity/slack/cmd/slack-pp-cli@latest
如果安装后 --version 报告“command not found”,说明运行时无法在 $PATH 中找到二进制文件所在目录。验证成功前,请勿继续执行技能命令。
Slack 会隐藏超出免费套餐保留期限的消息,并限制只有管理员才能导出。此 CLI 会将对话、用户、文件和回应同步到本地 SQLite 数据库,并支持全文搜索,因此 archive recall 可以找到 Slack 本身已不再提供的决策。在此镜像之上,它还能计算任何端点都不会返回的信息:通过 catchup 查看仍待你处理的事项,通过 threads stale 查找尚未回复的线程,并通过 health 查看哪些频道正在失去活跃度。
何时使用此 CLI
当问题涉及 Slack 内容而非 Slack 应用开发,且答案需要借助历史记录、汇总或重复查询时,请使用此 CLI。它适合查找旧决策、总结你错过的内容、审查哪些频道仍然活跃,以及将不透明的 Slack ID 解析为具体用户。如果你手上只有 bot token,它也很适用,因为本地镜像可以回答搜索类问题,而 Slack 自己的搜索端点不接受 bot token。
不适用场景
请勿将此 CLI 用于:
- 构建、搭建脚手架或部署 Slack 应用;这些是官方 slackapi/slack-cli 的用途。
- 管理 Enterprise Grid;此 CLI 有意排除了 admin.* 方法,普通工作区令牌调用这些方法会失败。
- 将其用作实时 bot 或事件监听器;它是请求-响应工具,不包含 Socket Mode 或 Events API 运行时。
- 读取尚未同步的工作区;每个依赖归档的命令都会报告镜像尚未同步,而不会静默返回空结果。
- 合规或法律导出;Slack 的 Discovery API 和管理员导出功能适用于此类用途,并提供此工具不具备的保障。
独特功能
其他任何面向此 API 的工具都不具备这些功能。
超越 Slack 保留期限的本地归档
-
archive recall— 在本地归档中查找消息,包括 Slack 已隐藏在 90 天保留期限之后的消息。如果答案可能涉及 90 天以前的内容,或者你手上只有 bot token,请使用此功能代替搜索,因为 Slack 的搜索端点会直接拒绝 bot token。
slack-pp-cli archive recall "deploy" --agent --limit 20 -
archive coverage— 显示本地镜像实际保存了各频道哪些日期范围的内容,以及存在的缺口。在相信空的 recall 结果之前,请先检查此项,以便区分确实没有结果和某个日期范围尚未同步。
slack-pp-cli archive coverage --json
关注待办,而非消息量
-
catchup— 查看离开期间发生的事:各频道的新消息、提及你的消息,以及仍在等待你回复的线程。将其作为单次调用,替代手动列出频道、逐个拉取频道历史记录并查找提及。
slack-pp-cli catchup --since 24h --agent -
threads stale— 列出存档中最后一条回复不是你发的、且之后无人回复的线程。当你想了解哪些问题尚未得到回复,而非最近发生了什么时,使用此命令。
slack-pp-cli threads stale --days 3 --json
工作区管理
-
health— 按每日消息数、不同发帖人数、首次回复延迟中位数和闲置天数比较各频道。当你不是工作区管理员,且没有导出功能或管理控制台时,可用此命令决定哪些频道适合归档。
slack-pp-cli health --dying --json -
users activity— 查看某个人在哪些地方发帖、负责哪些线程,以及最近一次活跃时间。在了解某位队友的交接和站会情况时使用此命令,而不是了解你自己的情况。
slack-pp-cli users activity chris --days 30 --json
身份解析
-
users whois— 将不透明的 Slack ID、用户名或电子邮件转换为一张信息卡,显示共同频道、时区、免打扰状态和最近活跃时间。当载荷中出现以 U 或 C 开头的裸 ID 时,立即使用此命令,而不是针对每个标识符分别调用 users info。
slack-pp-cli users whois U04AB9XYZ --agent
命令参考
api-test — 管理 API 测试
slack-pp-cli api-test— 检查 API 调用代码。
auth_api — 测试和管理身份验证
slack-pp-cli auth-api revoke— 撤销当前身份验证令牌slack-pp-cli auth-api test— 测试身份验证令牌并获取身份信息
bots — 获取机器人用户的信息
slack-pp-cli bots— 获取机器人用户的信息
canvases — 创建、编辑、分享和删除 Slack 画布
slack-pp-cli canvases create— 创建画布,可独立创建,也可绑定到频道slack-pp-cli canvases read— 读取画布内容slack-pp-cli canvases edit— 修改现有画布slack-pp-cli canvases delete— 删除画布slack-pp-cli canvases access-set— 授予用户或频道访问画布的权限slack-pp-cli canvases sections— 查找画布中的版块 ID,以便进行定向编辑
需要 canvases:write 和 canvases:read;使用 read 还需要 files:read。read 返回的是
HTML,而非 Markdown(Slack 没有获取画布内容的端点,因此它会下载
底层文件),所以创建后再读取并非无损往返。若要定向编辑,请读取
画布并从 HTML 中获取版块 ID;sections 会返回 ID,但不包含这些版块涵盖的内容。
chat-delete-scheduled-message — 管理聊天定时消息删除
slack-pp-cli chat-delete-scheduled-message— 从队列中删除一条待发送的定时消息。
chat-me-message — 管理聊天中的 me 消息
slack-pp-cli chat-me-message— 在频道中分享一条 me 消息。
chat-post-ephemeral — 管理聊天临时消息
slack-pp-cli chat-post-ephemeral— 向频道中的用户发送一条临时消息。
chat-unfurl — 管理聊天链接展开
slack-pp-cli chat-unfurl— 为用户发布的 URL 提供自定义链接展开行为
conversations — 读取频道历史记录、列出频道并管理频道成员资格
slack-pp-cli conversations archive— 归档频道slack-pp-cli conversations create— 创建新频道slack-pp-cli conversations get— 获取频道信息slack-pp-cli conversations history— 使用--channel ID获取频道历史记录,或使用--user USER_ID和SLACK_USER_TOKEN读取现有私信。查询私信不会创建会话,且需要实时访问;对于以 D 开头的频道和--user,不接受--data-source local。slack-pp-cli conversations invite— 邀请用户加入频道slack-pp-cli conversations list— 列出工作区中的所有频道slack-pp-cli conversations mark— 将频道标记为已读至指定消息slack-pp-cli conversations members— 列出频道成员slack-pp-cli conversations replies— 获取主题中的回复slack-pp-cli conversations set-purpose— 设置频道用途slack-pp-cli conversations set-topic— 设置频道主题slack-pp-cli conversations unarchive— 取消归档频道
conversations-close — 管理关闭会话
slack-pp-cli conversations-close— 关闭私信或多人私信。
conversations-join — 管理加入会话
slack-pp-cli conversations-join— 加入现有会话。
conversations-kick — 管理移除会话成员
slack-pp-cli conversations-kick— 将用户从会话中移除。
conversations-leave — 管理离开会话
slack-pp-cli conversations-leave— 离开会话。
conversations-open — 管理打开会话
slack-pp-cli conversations-open— 打开或恢复私信或多人私信。
conversations-rename — 管理重命名会话
slack-pp-cli conversations-rename— 重命名会话。
dnd — 管理免打扰设置
slack-pp-cli dnd end-dnd— 立即结束当前免打扰会话slack-pp-cli dnd end-snooze— 结束当前免打扰会话slack-pp-cli dnd get— 获取已认证用户的免打扰状态slack-pp-cli dnd set-snooze— 开启免打扰,并指定持续分钟数slack-pp-cli dnd team-info— 获取多位用户的免打扰状态
emoji — 列出工作区中的自定义表情符号
slack-pp-cli emoji— 列出工作区中的所有自定义表情符号
files — 上传、列出和管理文件
slack-pp-cli files delete— 删除文件slack-pp-cli files get— 获取文件信息slack-pp-cli files list— 列出工作区中的文件slack-pp-cli files upload— 将文件上传到 Slack。使用--file <path>,或使用--content和--filename上传内联文本;--channel用于分享文件,--thread-ts用于将文件放入主题中。此命令使用外部上传流程(旧版files.upload已停用)。--channels只能指定一个频道。
files-comments-delete — 管理删除文件评论
slack-pp-cli files-comments-delete— 删除文件上的现有评论。
files-remote-add — 管理添加远程文件
slack-pp-cli files-remote-add— 添加来自远程服务的文件
files-remote-info — 管理获取远程文件信息
slack-pp-cli files-remote-info— 获取已添加到 Slack 的远程文件信息
files-remote-list — 管理列出远程文件
slack-pp-cli files-remote-list— 获取已添加到 Slack 的远程文件信息
files-remote-remove — 管理移除远程文件
slack-pp-cli files-remote-remove— 移除远程文件。
files-remote-share — 管理分享远程文件
slack-pp-cli files-remote-share— 将远程文件分享到频道。
files-remote-update — 管理更新远程文件
slack-pp-cli files-remote-update— 更新现有远程文件。
files-revoke-public-url — 管理撤销文件公共 URL
-
slack-pp-cli files-revoke-public-url— 撤销文件的公开/外部分享权限 files-shared-public-url — 管理文件共享的公开 URL -
slack-pp-cli files-shared-public-url— 启用文件的公开/外部共享。
messages — 在频道和私信中发送、读取、更新和删除消息
slack-pp-cli messages delete-message— 删除消息slack-pp-cli messages get-permalink— 获取消息的永久链接 URLslack-pp-cli messages list-scheduled— 列出已安排的消息slack-pp-cli messages post-message— 向频道、私信或线程发送消息。较旧的post_message拼写仍作为别名保留。slack-pp-cli messages schedule-message— 安排稍后发送的消息slack-pp-cli messages update-message— 更新现有消息
pins — 在频道中置顶和取消置顶消息
slack-pp-cli pins add— 在频道中置顶消息slack-pp-cli pins list— 列出频道中的置顶项slack-pp-cli pins remove— 取消置顶频道中的消息
reactions — 添加和移除消息上的表情回应
slack-pp-cli reactions add— 为消息添加表情回应slack-pp-cli reactions get— 获取消息的表情回应slack-pp-cli reactions list— 列出已验证用户添加的表情回应slack-pp-cli reactions remove— 移除消息上的表情回应
reminders — 创建和管理个人提醒
slack-pp-cli reminders add— 创建新提醒slack-pp-cli reminders complete— 将提醒标记为已完成slack-pp-cli reminders delete— 删除提醒slack-pp-cli reminders get— 获取提醒信息slack-pp-cli reminders list— 列出已验证用户的所有提醒
search_api — 搜索工作区中的消息和文件
slack-pp-cli search-api— 搜索与查询匹配的消息
stars — 为消息和文件加星标或取消星标
slack-pp-cli stars add— 为消息、文件或频道加星标slack-pp-cli stars list— 列出已加星标的项目slack-pp-cli stars remove— 移除项目的星标
team — 获取工作区信息
slack-pp-cli team access-logs— 获取工作区访问日志(需要管理员权限)slack-pp-cli team billable-info— 获取工作区用户的计费信息slack-pp-cli team get— 获取工作区信息
team-integration-logs — 管理团队集成日志
slack-pp-cli team-integration-logs— 获取当前团队的集成日志。
team-profile-get — 管理团队资料获取
slack-pp-cli team-profile-get— 获取团队资料。
usergroups — 管理工作区用户组
slack-pp-cli usergroups create— 创建新用户组slack-pp-cli usergroups list— 列出工作区中的所有用户组slack-pp-cli usergroups update— 更新现有用户组slack-pp-cli usergroups users-list— 列出用户组中的用户slack-pp-cli usergroups users-update— 更新用户组成员
usergroups-disable — 管理用户组停用
slack-pp-cli usergroups-disable— 停用现有用户组
usergroups-enable — 管理用户组启用
slack-pp-cli usergroups-enable— 启用用户组
users — 列出和查找工作区用户
slack-pp-cli users get— 获取用户信息slack-pp-cli users get-presence— 获取用户的在线状态slack-pp-cli users list— 列出工作区中的所有用户slack-pp-cli users lookup-by-email— 通过电子邮件地址查找用户slack-pp-cli users profile-get— 获取用户资料信息slack-pp-cli users profile-set— 设置用户资料字段slack-pp-cli users set-presence— 设置用户状态
users-conversations — 管理用户对话
slack-pp-cli users-conversations— 列出调用用户有权访问的对话。
users-delete-photo — 管理用户照片删除
slack-pp-cli users-delete-photo— 删除用户个人资料照片
users-identity — 管理用户身份
slack-pp-cli users-identity— 获取用户身份信息。
users-set-active — 管理用户活跃状态
slack-pp-cli users-set-active— 将用户标记为活跃。已弃用且无法使用。
users-set-photo — 管理用户照片
slack-pp-cli users-set-photo— 设置用户个人资料照片
查找合适的命令
知道自己想做什么,却不知道该用哪个命令时,可以直接询问 CLI:
slack-pp-cli which "<capability in your own words>"
which 会根据自然语言功能查询,从此 CLI 精选的功能索引中找出最匹配的命令。退出码 0 表示至少有一个匹配项;退出码 2 表示没有足够确定的匹配项——请改用 --help,或缩小查询范围。
使用示例
找出 Slack 遗忘的决策
slack-pp-cli archive recall "deploy" --agent --select results.channel,results.user,results.ts,results.text
搜索本地镜像,并将载荷缩减为值得阅读的字段,避免 Agent 在完整消息对象上消耗上下文。
早间待办检查
slack-pp-cli catchup --since 24h --json
返回各频道新增的消息数量、提及你的消息,以及最后一条回复不是你发送的讨论串。
无需管理员权限,找出适合归档的频道
slack-pp-cli health --dying --json
根据闲置天数和发帖量为你的频道排序,以便你能有据可依地提议归档。
从载荷中解析不透明 ID
slack-pp-cli users whois U04AB9XYZ --agent
一次调用即可将普通的 Slack 用户 ID 转换为共享频道、时区、免打扰状态和最后在线时间。
确认镜像状态,再相信空结果
slack-pp-cli archive coverage --json
显示各频道镜像时间范围,让你能将空的检索结果理解为同步中断,而非内容不存在。
身份验证设置
身份验证使用 bearer token,但 Slack 将功能权限分散在两种令牌类型中,任何权限范围授权都无法跨越这条界限。Bot 令牌(xoxb-,设置为 SLACK_BOT_TOKEN)可访问 conversations、users、files、reactions、usergroups、emoji、team、dnd 和 bots。search、stars 和 reminders 系列命令则需要用户令牌(xoxp-,设置为 SLACK_USER_TOKEN);无论添加哪些权限范围,使用 Bot 令牌都会返回 not_allowed_token_type。运行 doctor 查看已配置的令牌类型,以及可使用的命令系列。另请注意,Slack 对在 Marketplace 之外分发的应用,大幅收紧了 conversations.history 和 conversations.replies 的速率限制;你在自己的工作区中创建并安装的内部应用仍沿用原有限制。
运行 slack-pp-cli doctor 验证设置。
Agent 模式
为任意命令添加 --agent。这相当于:--json --compact --no-input --no-color --yes。
-
可通过管道传递 — JSON 输出到 stdout,错误输出到 stderr
-
可筛选 —
--select保留部分字段。点分路径可深入嵌套结构;数组会逐元素遍历。对于内容冗长的 API,这对缩小上下文至关重要:slack-pp-cli bots --bot example-value --agent --select id,name,status -
可预览 —
--dry-run显示请求,但不会发送 -
支持离线 — 同步和搜索命令可在本地 SQLite 存储可用时使用它
-
非交互式 — 不会发出提示,所有输入均通过标志提供
-
显式重试 — 仅当已存在的创建结果也应视为成功时,才使用
--idempotent
响应封装
从本地存储或 API 读取数据的命令,会将输出包装在来源信息封装中:
{
"meta": {"source": "live" | "local", "synced_at": "...", "reason": "..."},
"results": <data>
}
从 .results 解析数据,并通过 .meta.source 判断数据来自实时 API 还是本地存储。只有当 stdout 连接到终端,且未设置机器格式标志(--json、--csv、--compact、--quiet、--plain、--select)时,才会将便于人类阅读的 N results (live) 摘要输出到 stderr——通过管道使用的调用方、Agent,以及指定了格式的运行都会在 stdout 上获得纯 JSON。
路径和状态
Agent 应将 CLI 的路径解析器视为运行时契约的一部分:
-
使用
--home <dir>指定单次调用的目录,或设置SLACK_HOME=<dir>,将四种路径都重定向到同一个根目录下。 -
仅在需要让某种路径单独采用不同位置时,才使用该类型专属的环境变量:
SLACK_CONFIG_DIR、SLACK_DATA_DIR、SLACK_STATE_DIR、SLACK_CACHE_DIR。 -
解析优先级依次为:类型专属环境变量、
--home、SLACK_HOME、XDG(XDG_CONFIG_HOME、XDG_DATA_HOME、XDG_STATE_HOME、XDG_CACHE_HOME),最后是平台默认值。 -
config存放config.toml、配置文件等设置。data存放credentials.toml、data.db、Cookie 和认证辅助文件。state存放持久化查询、任务和teach.log。cache存放可重新生成的 HTTP/缓存文件。 -
存储的机密信息位于
data目录下的credentials.toml中。为保持兼容性,系统会读取现有旧版config.toml中的机密信息,并在首次写入认证信息时将其移出config.toml。 -
运行
slack-pp-cli doctor --fail-on warn,查看路径和凭证位置警告。agent-context会公开 schema v4 的paths块,供需要已解析目录的 Agent 使用。 -
对于 MCP,请通过 MCP 主机配置传递重定向设置。MCP 二进制文件不会继承 CLI 标志:
{ "mcpServers": { "slack": { "command": "slack-pp-mcp", "env": { "SLACK_HOME": "/srv/slack" } } } }
多机群组优先级:继承的类型专属环境变量会覆盖该类型显式设置的 --home。使用 SLACK_HOME 或类型专属变量作为长期有效的多机群组配置手段;--home 仅用于单次调用。取消设置环境变量无法撤销重定向;清除 SLACK_HOME 前请手动移动文件,否则 doctor 将无法找到留在原根目录下的凭证。
自动学习
此 CLI 内置了一个自动捕获的学习循环。CLI 会自行记录:每次调用都会在本地写入日志;标志使用失败后再修正并重试时,会自动推导出一个 flag_alias 候选项;对没有操作手册的查询类别执行 teach 时,会根据会话日志自动合成一个 playbook_candidate。你只需负责判断:先执行 recall,根据出现的候选项采取行动,执行 teach 记录最终答案,观察到修正时执行 playbook amend。你无需手动记录失败。
第 1 步:开始任何探索前先执行 recall
对于新的用户问题,在执行列表、搜索或深入查询命令前,先运行:
slack-pp-cli recall "<user's question>" --agent
响应封装:
{
"query": "...",
"normalized": "<normalized form>",
"query_entities": ["..."],
"found": true | false,
"match_score": 0.0,
"results": [
{ "resource_id": "...", "resource_type": "...", "venue": "...",
"confidence": 2, "entity_match": "exact|partial|unknown",
"source": "taught|preseed|pattern", "warnings": ["..."] }
],
"mismatches": [ /* only when --debug-mismatches */ ],
"warnings": [ /* top-level */ ],
"candidates": [
{ "id": 12, "class": "flag_alias | playbook_candidate",
"summary": "...", "sightings": 3, "last_seen": "...",
"rationale": "...",
"next_action": ["<trial command>", "slack-pp-cli learnings confirm 12"] }
],
"playbook": {
"query_family": "...",
"playbook": {
"steps": [ { "cmd": "<command with {slot} substitution>", "purpose": "..." } ],
"entity_slots": ["$ENTITY"],
"expected_tool_calls": 3
},
"slots_resolved": { "$ENTITY": { "token": "<live token>", "canonical": "<canonical>" } },
"notes": "<workarounds + gotchas for this query family>"
},
"notes": "<duplicate surface for non-playbook callers>"
}
空存储快速退出:如果存储中尚无学习内容、操作手册或候选项(recall 无结果,且 learnings list 和 learnings candidates 均为空),则本会话剩余时间内跳过 recall,避免每次查询都增加开销;一旦有内容经过 teach 记录,就恢复先执行 recall 的流程。
第 2 步:决策树
按此顺序读取 candidates、playbook、notes、results[0] 和警告:
if Candidates present (warnings include "candidates_present"):
-> candidates are try-then-confirm, never facts. Follow each candidate's
two-step next_action verbatim: run the trial command first, then run
`learnings confirm <id>` only after the trial verified the behavior.
Reject a wrong candidate with `learnings reject <id>`.
-> NEVER re-teach something recall surfaced as a candidate; confirm or
reject that candidate instead of teaching a duplicate.
-> candidates ride alongside playbooks and resource hits, not instead of
them; continue with the branches below after acting on them.
if Playbook present:
-> READ Playbook.notes verbatim FIRST (workarounds + gotchas the CLI surface doesn't expose)
-> replay Playbook.steps in order, substituting Playbook.slots_resolved entries
for the entity slot tokens. If a step's slot is unresolved, fall back to
discovery for that step only.
-> the Playbook's expected_tool_calls is a budget; if you find yourself running
materially more, record the divergence via `slack-pp-cli playbook amend`
at end-of-session.
elif Notes present (no Playbook):
-> read Notes verbatim before any discovery step; they carry known gotchas
for this query family even when no structured choreography exists yet.
elif Found AND Results[0].EntityMatch == "exact" AND Results[0].Confidence >= 2:
-> skip discovery; fetch live data for Results[*].ResourceID in parallel
elif Found AND Results[0].EntityMatch == "partial":
-> candidate hint, NOT a hit; read the resource title to validate before trusting
elif (any row in Mismatches[] when --debug-mismatches was passed):
-> treat as cold start; the stored learning is for a different entity
(different canonical resolved from query_entities)
else: // Found == false, no playbook, no notes
-> cold start; run discovery normally; teach the answer afterward (Step 4).
If the family has no playbook yet, that teach auto-synthesizes a
playbook candidate from this session's journal - you do not need to
record one by hand.
操作手册和 Notes 与逐项资源路径互不影响。recall 响应可以同时包含操作手册和 Results[] 命中项——两者都要用:操作手册会告诉你要执行哪些步骤;资源命中项则可省去特定步骤。默认跳过 mismatches;仅在调查冷启动意外情况时才传入 --debug-mismatches。
候选项判断详情:learnings confirm <id> 会在创建候选项之前打印其完整内容——请检查打印内容是否与已验证的行为相符。learnings reject <id> 会将推导签名标记为已删除,使同一候选项不再出现。封装中仅包含当前值得处理的少数候选项;slack-pp-cli learnings candidates 会列出所有未处理的候选项。
平稳降级:如果 learnings confirm 是未知命令,说明你使用的是较旧的二进制文件——忽略候选项相关说明,并遵循协议的其余部分。
第 3 步:始终读取 warnings
low_confidence:存在confidence<2的行。将其视为提示,而不是跳过发现步骤的命中项。resource_not_in_store:本地存储中没有学习记录指向的资源。匹配验证器无法对实体分类——直接获取并重新评估。cross_alias_match(每条结果):该行是在不同别名下教授的,并通过entity_lookups匹配了实时查询的规范名称(例如,针对「United States」的回忆由针对「USA」的教学满足)。请信任resource_id。similar_shape_different_entity:<canonical>(顶层):存在一条结构匹配的行,但其规范实体与实时查询的不同。按冷启动处理;警告会将冲突的规范名称作为提示,但不会将该行提升到 Results 中。ambiguous_alias(顶层):单个查询实体解析出了多个规范实体(例如,「Cards」→ Arizona Cardinals + St. Louis Cardinals)。在选定资源前,先根据上下文说明存在歧义。candidates_present(顶层):信封包含candidates部分。先按第 2 步中的候选项分支进行处理。lookup_refresh_available(顶层):查询中的实体尚无查找行,但同步数据可能会提供一行。运行slack-pp-cli sync以刷新实体查找信息。- 顶层
no_learnings_for_query_family:表中没有超过 Jaccard 下限的行。属于纯冷启动。
第 4 步:完成回复后始终执行 teach &
教学是无条件的。在解决存储无法回答的查询后,在后台教授最终资源映射——没有调用次数门槛,也不评估学习是否「值得」。教学是整个循环的锚点:对于尚无操作手册的系列,它会触发操作手册合成;相同指代对象的不同表述会合并到同一系列中,因此近似重复的教学不会造成存储碎片化。组装好面向用户的回复后、发送回复前,使用 shell & 执行教学,让调用立即返回:
slack-pp-cli teach --query "<user's question>" --resource-type <type> --resource <id1> --resource <id2>
# (append shell `&` to background it)
成功时不输出任何内容。错误只会写入已解析状态目录下的 teach.log。教学时选择最具体的资源——如果用户提出了宽泛的问题,而你通过父记录找到了具体答案,则教授叶节点 ID,而不是父节点。CLI 会在回忆时使用预置的 entity_lookups 解析跨别名,因此在一个别名下进行教学(例如「Niners」),会自动满足未来使用其他别名(例如「49ers」、「San Francisco」)的查询。
PII 规则:教授结构化问题时,必须去除标识符——绝不要在教学查询或备注中包含姓名、电子邮件地址、电话号码、账户 ID 或其他个人标识符。CLI 会扫描教学查询中明显的电子邮件/电话号码格式并发出警告,但不会阻止操作;请在教学前去除这些信息,而不要依赖警告。
步骤 5:playbook - 可选标记、自动合成
你不必判断某个会话是否“值得”编写 playbook:如果某个类别还没有 playbook,使用该类别进行 teach 会根据会话日志自动合成一个 playbook_candidate,并由下一次会话通过确认/拒绝来判断。只有当你已经掌握值得原样记录的操作流程时,才附加明确的 playbook 标记——例如 CLI 未显示的变通方法(被静默丢弃的标记、未记录的参数、分页技巧、负载问题)。优先使用集成式单次调用形式——在同一次 teach 调用中记录资源学习内容和 playbook:
# Common case: record both the resource learning AND the playbook in one call.
slack-pp-cli teach \
--query "<user's question>" \
--resource <id> \
--playbook-file ~/playbooks/<shape>.json \
--playbook-notes-file ~/playbooks/<shape>-notes.md
# (append shell `&` to background it)
# Alternate: playbook-only (no resource to record alongside).
slack-pp-cli teach-playbook \
--query "<user's question>" \
--playbook-file ~/playbooks/<shape>.json \
--notes-file ~/playbooks/<shape>-notes.md
Playbook 文件是包含 steps、entity_slots、expected_tool_calls 的 JSON 文件。Notes 文件是原样记录问题细节的 Markdown 文件。不使用文件的调用方(仅使用 MCP 的 Agent)可直接内联传入相同内容:在集成式 teach 形式中使用 --playbook-json 和 --playbook-notes,在 teach-playbook 中使用 --playbook-json 和 --notes。在集成式 teach 形式中,playbook 标记是可选的——如果只想 teach 资源,可完全省略这些标记。在独立的 teach-playbook 形式中,必须至少设置 playbook 标记和 notes 标记中的一个;两者都为空时会被拒绝。Playbook 以结构化查询类别(去除实体)为键,因此从一种实体形态的查询中学到的操作步骤适用于同一形态的所有其他查询,并在回忆时通过 slots_resolved 绑定当前查询的规范形式。
如果未来回忆时确实找到 playbook,请将其视为事实依据:使用 slots_resolved 替换项重放步骤,跳过操作流程中已有记录的探索,并在执行任何步骤前阅读 notes。
步骤 6:当调试响应指出需要更正时,使用 playbook amend &
如果你的调试协议响应指出 notes 或 playbook 应记录一项具体更正——例如变通方法、未记录的端点结构、过时的字段名称、观察到的架构漂移、空负载回退方案——请在生成面向用户的响应之前触发 playbook amend。与 teach 一样,采用触发后即不等待结果的方式。
slack-pp-cli playbook amend \
--query "<exact recall query string>" \
--add-note "<your concrete correction>"
# (append shell `&` to background it)
哪些内容值得修订:本次会话中你 OBSERVED 到、且未来的你会受益于了解的行为。值得修订的示例:
- CLI 界面会静默丢弃或调整标记顺序时的变通方法。
- 未记录的端点结构(响应封装在
{meta, results}中,负载嵌套层级比文档所述多两层)。 - 观察到的架构漂移(字段重命名、索引在不同赛季间发生变化、API 现在返回小写的类别标签)。
哪些内容不应写入 notes:
- 用户问题中与年份或实体相关的答案。这是响应内容,不是学习内容。
- playbook 已在运行时获取的团队、运动员或行数据。
- 只是转述现有 notes 内容的陈述。
amend 命令会将内容追加到该类别现有的 notes 中,并附加带时间戳的标记([amend YYYY-MM-DDTHH:MMZ]: <text>)。多次 amend 会累积,且审计记录可见。如果该类别尚无 playbook,amend 会创建一个仅含 notes 的 playbook(因此冷启动时发现的更正也能记录下来)。
amend notes 中的 PII 规范
playbook amend notes 可能会在未来版本的 Printing Press 中作为共享知识向上游传递。请勿在其中包含可识别用户身份的内容,以便保持向上游贡献的渠道畅通,避免之后再进行清理:
- 请勿嵌入用户文件系统路径、个人 API 密钥或令牌、用户电子邮件地址、用户 GitHub 用户名,或与单个用户关联的特定查询历史记录。
- 可以包含:端点结构、未记录的字段名称、API 问题、观察到的架构漂移、CLI 界面的变通方法、可泛化的分页或重试策略。
如果某项更正只有结合用户特定的上下文才有意义,就应写入个人笔记,而不是 playbook amend。
衡量闭环
slack-pp-cli learnings stats 会从本地 learn_events 表中报告召回命中率、教授后复用率、操作手册解决率,以及候选项确认/拒绝次数。分母尚不存在时,相关比率为 null;所有数据都保留在这台机器上。可用它检查这个 CLI 的闭环是否物有所值。
禁用学习功能
- 在单条命令中使用
--no-learn,即可同时跳过recall和teach写入流程。适用于确定性 Agent 工作流,或不得受累积学习结果影响的测试。 - 在环境中设置
SLACK_NO_LEARN=true,即可全局禁用该流程。
Agent 反馈
当你(或 Agent)发现这个 CLI 有什么不对劲时,请记录下来:
slack-pp-cli feedback "the --since flag is inclusive but docs say exclusive"
slack-pp-cli feedback --stdin < notes.txt
slack-pp-cli feedback list --json --limit 10
条目会以 feedback.jsonl 的形式存储在解析后的数据目录中。除非设置了 SLACK_FEEDBACK_ENDPOINT,并且传入 --send 或设置了 SLACK_FEEDBACK_AUTO_SEND=true,否则绝不会通过 POST 发送。默认情况下,反馈仅保存在本地。
记录令你感到意外的地方,而不是提交 Bug 报告。简短、具体,写成一行:这才是能够逐步积累的内容。
输出交付
每条命令都接受 --deliver <sink>。输出会发送到指定的接收目标,同时输出到 stdout,或取代 stdout 输出;因此 Agent 无需手动通过管道即可路由命令结果。支持三种接收目标:
| 接收目标 | 效果 |
|---|---|
stdout | 默认;仅写入 stdout |
file:<path> | 以原子方式将输出写入 <path>(临时文件 + 重命名) |
webhook:<url> | 将输出正文 POST 到该 URL(使用 --compact 时为 application/json 或 application/x-ndjson) |
遇到未知方案时,会拒绝请求并返回结构化错误,指出受支持的方案。Webhook 请求失败时会返回非零状态,并在 stderr 中记录 URL 和 HTTP 状态码。
命名配置
配置文件是一组已保存的标志值,可在多次调用中重复使用。如果定时运行或周期性运行的 Agent 每次输入不同,但都会复用相同的已保存标志,请使用配置文件。
slack-pp-cli profile save briefing --json
slack-pp-cli --profile briefing bots --bot example-value
slack-pp-cli profile list --json
slack-pp-cli profile show briefing
slack-pp-cli profile delete briefing --yes
显式标志始终优先于配置文件中的值;配置文件中的值优先于默认值。agent-context 会在 available_profiles 下列出所有可用配置文件,供具备自省能力的 Agent 在运行时发现。
退出代码
| 代码 | 含义 |
|---|---|
| 0 | 成功 |
| 2 | 用法错误(参数错误) |
| 3 | 未找到资源 |
| 4 | 需要身份验证 |
| 5 | API 错误(上游问题) |
| 7 | 请求过于频繁(等待后重试) |
| 10 | 配置错误 |
参数解析
解析 $ARGUMENTS:
- 为空、
help或--help→ 显示slack-pp-cli --help输出 - 以
install开头 → 以mcp结尾 → 安装 MCP;否则 → 参见上文“先决条件” - 其他任何内容 → 直接使用(以
--agent执行 CLI 命令)
MCP 服务安装
- 安装 MCP 服务:
go install github.com/mvanhorn/printing-press-library/library/productivity/slack/cmd/slack-pp-mcp@latest - 在 Claude Code 中注册:
claude mcp add slack-pp-mcp -- slack-pp-mcp - 验证:
claude mcp list
直接使用
- 检查是否已安装:
which slack-pp-cli如果未找到,请提供安装选项(参见此技能开头的“先决条件”)。 - 根据用户查询,从上文的“独特功能”和“命令参考”中选择最合适的命令。
- 使用
--agent标志执行:slack-pp-cli <command> [subcommand] [args] --agent - 如果有歧义,请查看子命令帮助:
slack-pp-cli <command> --help。