关于 contacts
contacts 是用于在本地 Vault 中维护联系人的技能,记录以带 YAML frontmatter 的 Markdown 文件保存。它支持手动创建和基于索引来源的资料补充,并为 VIP 联系人提供深入补充与监控流程。
主要功能
- 01以 Markdown 文件保存联系人
- 02记录别名、职位和组织
- 03从索引来源补充资料
- 04创建和更新联系人笔记
- 05为 VIP 联系人标记深入补充
适用场景
- 01使用已知标识添加联系人
- 02更新现有联系人记录
- 03通过 Vault 笔记链接整理联系人
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ joelhooks/ joelclaw --skill contacts安装后在 Claude Code 中输入/contacts确认已加载。
详细介绍
联系人
在 ~/Vault/Contacts/ 中管理联系人。每位联系人的信息都存储在一个带有 YAML frontmatter 的 Markdown 文件中。
联系人文件位置
~/Vault/Contacts/<Name>.md
索引文件:~/Vault/Contacts/index.md — 包含所有联系人的维基链接列表。
Frontmatter 架构
---
name: Full Name
aliases: [nickname, handle]
role: Current Role / Title
organizations: [Org1, Org2]
vip: true # or false
slack_user_id: U0XXXXXXX
slack_dm_channel: D0XXXXXXX # null if unknown
website: https://example.com
github: username
twitter: handle
email: [email protected]
tags: [vip, instructor, creator, family, employee]
---
章节
# Name
## Contact Channels
- Slack, email, social handles, website
## Projects
- Active projects, courses, collaborations
## Key Context
- Relationship notes, working style, history
## Recent Activity
- YYYY-MM-DD | channel | summary
完整的丰富示例请参见 ~/Vault/Contacts/Matt Pocock.md。
添加联系人
选项 1:运行信息补全流水线(首选)
发送 Inngest 事件。contact-enrich 函数会并行调用 Slack、Roam、网页/GitHub、Granola、基于 Brain 的记忆检索及其他已索引数据源,使用 LLM 综合信息,并写入 Vault 文件。
# Via curl (CLI has OTEL import bug under Bun v1.3.9)
curl -s -X POST "http://localhost:8288/e/$INNGEST_EVENT_KEY" \
-H "Content-Type: application/json" \
-d '[{
"name": "contact/enrich.requested",
"data": {
"name": "Person Name",
"depth": "full",
"hints": {
"slack_user_id": "U0XXXXXXX",
"github": "username",
"twitter": "handle",
"email": "[email protected]",
"website": "https://example.com"
}
},
"ts": EPOCH_MS
}]'
深度模式:
full(约 60 秒,约 $0.05):全部 7 个数据源 + LLM 综合。适用于新联系人或定期更新。quick(约 10 秒,约 $0.01):仅 Slack + 记忆。适用于实时识别 VIP。
**提示信息为可选项,但有助于提高效果:**任何已知标识符(Slack ID、GitHub、电子邮件、Twitter、网站)都可以作为搜索起点并改善结果。
选项 2:快速手动创建
对于无需进行信息补全的简单联系人:
---
name: Person Name
aliases: []
role: Role
organizations: [Org]
vip: false
slack_user_id: null
website: null
github: null
twitter: null
email: null
tags: [tag1]
---
# Person Name
## Contact Channels
- ...
## Key Context
- ...
写入 ~/Vault/Contacts/Person Name.md,并将 [[Person Name]] 添加到 index.md。
更新联系人
使用现有的 vault 路径重新运行信息补全:
{
"name": "contact/enrich.requested",
"data": {
"name": "Person Name",
"vault_path": "Contacts/Person Name.md",
"depth": "full"
}
}
综合器会将新数据与现有内容合并;除非现有事实被证伪,否则不会将其删除。
VIP 联系人(ADR-0151)
在 frontmatter 中标记 vip: true。VIP 联系人会获得深度信息补全 + 持续监控。
深度信息补全操作指南(一次性)
每位 VIP 联系人都会接受全面的信息补全。以下是我们在 2026 年 2 月 26 日为 Kent C. Dodds 所做的工作:
| 步骤 | 来源 | 要采集的信息 |
|---|---|---|
| 1. 网络信息 | 使用 {name} + {org} 进行网络搜索 | 简介、职位、所在地、个人信息 |
| 2. 播客/采访 | 使用 {name} podcast interview 进行网络搜索 | 出演清单、自有播客、受众 |
| 3. 与 Joel 的合作 | 对方网站、出演页面 | 联合播客、共同组织的活动、合作项目 |
| 4. 职业时间线 | 用 Defuddle 处理 2-3 份重要采访文字稿 | 成长经历、职业轨迹、关键决策、价值观 |
| 5. GitHub 个人资料 | GitHub API 或网页 | 仓库、关注者、组织、贡献模式 |
| 6. X/Twitter 个人资料 | X API v2(使用 x-api 技能) | 简介、关注者、近期推文、互动情况 |
| 7. 重要关系 | 交叉参考文字稿和联系人 | 对方的合作对象、提及对象以及共同认识的人 |
| 8. 内容目录 | 网站抓取(defuddle) | 课程、博客文章、开源项目 |
| 9. 受众覆盖范围 | 播客数量、社交媒体关注者 | 会议活动、社区影响力 |
信息补全后索引至 Typesense:
- 将出演/内容批量导入
discoveries集合(NDJSON,action=upsert) - 为所有文档添加此人的姓名 slug 标签(例如
kent-c-dodds),以便筛选 - 字段:
id、title、url、summary、tags[]、timestamp - 编写
Vault/Resources/{name}-media-appearances.md参考文档,并链接回联系人页面
Vault 笔记中的输出章节:
- 背景与故事(成长经历、职业时间线)
- 教学/工作理念(或非教育工作者的相应内容)
- 重要关系(使用
[[wikilinks]]交叉链接到其他联系人) - 受众与影响力
- 内容/产品
- 与 Joel 的播客/合作历史
- 近期动态(带时间戳)
持续监控(ADR-0151 的第 2-4 阶段)
| 渠道 | 工具 | 信号 |
|---|---|---|
| Google Alerts | joelclawbot Google 账号 | 新闻、博客、媒体中的姓名提及 |
| X/Twitter 列表 | joelclaw X 账号 | 推文、互动情况 |
| GitHub 动态 | GitHub API(轮询) | 新仓库、新发布版本 |
| 播客 RSS | Feed 监控 | 新剧集 |
| 网站变更 | 定期运行 defuddle 并比较差异 | 博客文章、发布内容、简介变更 |
高信号(立即处理):课程发布、职位变动、提及 Joel/egghead/Skill、筹款。 低信号(每日/每周摘要):常规推文、博客文章、OSS 动态。
当前 VIP
- 丰富资料后,通过 gateway 通知 Joel
- 通过计划任务 cron 每周刷新
- 在渠道情报流水线中享有优先级(ADR-0131、ADR-0132)
- 实施 ADR-0151 Phase 2+ 后,进行持续监控
Roam Research 资料丰富
Joel 的 Roam 归档(~/Code/joelhooks/egghead-roam-research/)包含 egghead 时期的完整图谱(2019-2024)。许多联系人在那里都有丰富的历史记录。
快速搜索(Python 正则表达式)
cd ~/Code/joelhooks/egghead-roam-research
python3 -c "
import re
with open('egghead-2026-01-19-13-09-38.edn', 'r') as f:
content = f.read()
pattern = r':block/string\s+\"([^\"]*?)\"'
matches = []
for m in re.findall(pattern, content):
if '[[SEARCH_TAG]]' in m.lower():
matches.append(m)
print(f'Found {len(matches)} blocks')
for m in matches[:30]:
print(f' - {m[:200]}')
"
人员分类
Roam 中的人员使用关系前缀进行标记:
[[collaborator/Name]]— 战略合作伙伴(Ian Jones、Alex Hillman)[[client/Name]]— egghead 讲师(Matt Pocock、Jacob Paris)[[staff/Name]]— egghead 团队成员(Will Johnson、Daniel Miller、Maggie Appleton)[[name]](无前缀)— 非正式提及(Zac 对应[[zac]])
页面标题搜索
python3 -c "
import re
with open('egghead-2026-01-19-13-09-38.edn', 'r') as f:
content = f.read()
pattern = r':node/title\s+\"([^\"]*?SEARCH_TERM[^\"]*?)\"'
for m in re.findall(pattern, content):
print(f' page: {m}')
"
添加到联系人
从 Roam 提取人员数据时,将 roam_tag 添加到 frontmatter:
roam_tag: "[[collaborator/Ian Jones]]"
这样便可在未来重新查询和交叉引用。
Datalog 查询(高级)
EDN 文件采用 Datomic 风格。scripts/ 中提供了用于结构化分析的 Clojure 脚本。完整的 Datalog 模式请参阅 roam-research 技能。
解析未知人员
遇到 Slack 用户 ID(<@U0XXXXXXX>)时:
# Lease token and look up profile
SLACK_USER=$(secrets lease slack_user_token --ttl 5m)
curl -s "https://slack.com/api/users.info?user=U0XXXXXXX" \
-H "Authorization: Bearer $SLACK_USER" | jq '.user.real_name, .user.profile.email'
# Revoke only the exact lease ids acquired by this task; never all sessions’ leases.
然后使用解析出的姓名和提示触发资料丰富。
Inngest 函数
- 函数:
contact-enrich(packages/system-bus/src/inngest/functions/contact-enrich.ts) - 事件:
contact/enrich.requested - ADR:
~/Vault/docs/decisions/0133-contact-enrichment-pipeline.md - 并发:最多 3 个
- 来源:Slack、Slack Connect、Roam 归档、GitHub/网页、Granola 会议、基于 Brain 的回忆以及其他已索引来源
隐私
- 联系人文件位于 Vault 中(私有,不在公共仓库中)
- Slack 数据保持私有 — 绝不在公开内容中展示
- 电子邮件/电话仅供 Joel 参考