extract-my-action-items by casper-studios/casper-marketplace
npx skills add https://github.com/casper-studios/casper-marketplace --skill extract-my-action-items使用并行子智能体从 Fireflies 转录稿中提取行动项。捕捉自动摘要遗漏的项目。
两种模式:
解析用户的调用:
从调用中提取搜索条件(日期、关键词或转录稿 ID)。
转录稿 API 返回一个 JSON 数组(或包含该数组的 MCP 包装器)。在分块之前提取为纯文本。
你应该检查用户的本地钩子配置,避免运行被钩子阻止的命令。
mkdir -p .claude/scratchpad
node -e "
const fs = require('fs');
let data = JSON.parse(fs.readFileSync(process.argv[1], 'utf8'));
// 处理 MCP 包装器:如果顶层数组有一个包含真实转录稿的 .text 字段,则解析该字段
if (data.length === 1 && typeof data[0]?.text === 'string') {
// 从文本内容中提取发言者行
const lines = data[0].text.split('\n').filter(l => l.match(/^[A-Za-z].*?:/));
fs.writeFileSync('.claude/scratchpad/transcript.txt', lines.join('\n'));
const speakers = [...new Set(lines.map(l => l.split(':')[0].trim()))].sort();
console.log('Speakers:', JSON.stringify(speakers));
console.log('Total lines:', lines.length);
} else {
// 标准数组,包含 {speaker_name, text} 对象
const lines = data.map(e => (e.speaker_name || 'Unknown') + ': ' + (e.text || ''));
fs.writeFileSync('.claude/scratchpad/transcript.txt', lines.join('\n'));
const speakers = [...new Set(data.map(e => e.speaker_name).filter(Boolean))].sort();
console.log('Speakers:', JSON.stringify(speakers));
console.log('Total lines:', lines.length);
}
" [TRANSCRIPT_JSON_FILE]
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
如果转录稿 JSON 被 MCP 客户端保存到工具结果文件,请将该文件路径作为参数传递。
关键:协调器不得直接调用任何 Fireflies MCP 工具。所有与 Fireflies 的交互都发生在此子智能体内部。
使用以下提示启动一个 general-purpose 子智能体:
搜索 Fireflies 中匹配以下条件的转录稿:[SEARCH_CRITERIA]
1. 调用 `mcp__fireflies__fireflies_get_transcripts` 来查找转录稿(按日期、关键词或 ID)。
2. 并行调用 `mcp__fireflies__fireflies_get_summary` 和 `mcp__fireflies__fireflies_get_transcript` 来获取匹配转录稿的摘要和内容。
3. 转录稿 API 返回一个 JSON 数组。提取为纯文本:
- 使用 jq:jq -r '.[].text' < raw_transcript.json > .claude/scratchpad/transcript.txt
- 备用方案:python3 -c "import json,sys; print('\n'.join(e['text'] for e in json.load(sys.stdin)))" < raw_transcript.json > .claude/scratchpad/transcript.txt
4. 统计行数:wc -l < .claude/scratchpad/transcript.txt
5. 从转录稿 JSON 中提取不同的发言者列表:
python3 -c "import json,sys; data=json.load(sys.stdin); print('\n'.join(sorted(set(e.get('speaker_name','') for e in data if e.get('speaker_name')))))" < raw_transcript.json
请准确返回以下内容(不要添加其他文本):
- meeting_title: <标题>
- meeting_date: <日期>
- transcript_id: <ID>
- transcript_path: .claude/scratchpad/transcript.txt
- line_count: <数字>
- speakers: <逗号分隔的列表>
- summary: <Fireflies 摘要文本>
等待子智能体完成。解析其返回的值 — 这些是后续阶段的输入。
分块大小: 每个块 ceil(total_lines / 5) 行,最少 200 行。调整块数量,确保没有块少于 200 行。
为每个块启动一个 general-purpose 子智能体。
读取文件 [FILE_PATH] 的第 [START] 到 [END] 行。
查找 [TARGET_PERSON] 的所有行动项。按以下格式返回每一项:
- **项目**:他们承诺要做什么
- **引述**:来自转录稿的准确措辞
- **上下文**:涉及的其他人员、任何截止日期
除了明显的承诺("我会做 X"),还要捕捉以下非明显模式:
- 自我备注:"我会记下来要...", "让我记下..."
- 暗示需要赶上的承认:"我在 X 上搞砸了", "我还没读 X"
- 变成承诺的条件性提议:"如果我们有时间,我很乐意..."
- 自愿:"我想我会自愿去..."
- 探索任务:"让我花几个小时研究一下"
- 给外部方的问题/话题:"我需要问 [人员/公司] 关于 X", "要与 [方] 讨论的事情"
读取文件 [FILE_PATH] 的第 [START] 到 [END] 行。
会议与会者是:[SPEAKER_LIST]
查找每位与会者的所有行动项。按人员分组。为每个项目返回:
- **人员**:谁拥有此行动项
- **项目**:他们承诺要做什么
- **引述**:来自转录稿的准确措辞
- **上下文**:涉及的其他人员、任何截止日期
除了明显的承诺("我会做 X"),还要捕捉以下非明显模式:
- 自我备注:"我会记下来要...", "让我记下..."
- 暗示需要赶上的承认:"我在 X 上搞砸了", "我还没读 X"
- 变成承诺的条件性提议:"如果我们有时间,我很乐意..."
- 自愿:"我想我会自愿去..."
- 探索任务:"让我花几个小时研究一下"
- 给外部方的问题/话题:"我需要问 [人员/公司] 关于 X", "要与 [方] 讨论的事情"
- 委派:"[人员],你能处理 X 吗?", "我会把那个留给 [人员]"
合并子智能体的结果,去重并分类。仅包含有项目的类别。
单人模式 — 写入 .claude/scratchpad/[name]-action-items-YYYY-MM-DD.md:
# [姓名] 行动项 — [会议标题]
**日期:** [日期]
**Fireflies 链接:** https://app.fireflies.ai/view/[TRANSCRIPT_ID]
## [类别名称]
- [ ] **项目标题**
- 上下文和详细信息
- > "准确引述"
## 快速参考 — 有时限的
1. [带有截止日期或预定时间的项目]
所有与会者模式 — 写入 .claude/scratchpad/action-items-YYYY-MM-DD.md:
# 行动项 — [会议标题]
**日期:** [日期]
**Fireflies 链接:** https://app.fireflies.ai/view/[TRANSCRIPT_ID]
## [人员姓名]
### [类别名称]
- [ ] **项目标题**
- 上下文和详细信息
- > "准确引述"
## 快速参考 — 有时限的
1. [人员] — [带有截止日期或预定时间的项目]
AskUserQuestion:"通过 Slack 向每个人发送行动项私信吗?" — 选项:"发送私信", "跳过 — 仅保留文件".claude/slack-users.local.json 文件:
node [SKILL_DIR]/scripts/fetch-slack-users.mjs(需要具有 users:read 权限的 SLACK_BOT_TOKEN),将输出呈现给用户审查,然后保存到 .claude/slack-users.local.json(被 **/.claude/**/*.local.json gitignore 忽略)node [SKILL_DIR]/scripts/slack-post.mjs [OUTPUT_FILE_PATH]
该脚本通过 conversations.open 和 chat.postMessage 向每个人发送 Block Kit 格式的私信。需要环境变量 SLACK_BOT_TOKEN(具有 chat:write 和 im:write 权限)。
按模式的行为:
slack-users.local.json 中匹配的每个人都会收到一条仅包含其行动项的私信。无法解析的名称将被跳过并发出警告。名称解析支持精确匹配和模糊的名字匹配(例如,"Jelvin" 解析为 "Jelvin Base")。脚本运行后,向用户报告任何跳过的名称。
transcript.txt、行动项 Markdown 文件以及在此工作流期间写入 .claude/scratchpad/ 的任何其他临时文件。/extract-my-action-items — 所有与会者,最近一次会议/extract-my-action-items standup — 所有与会者,搜索 "standup"/extract-my-action-items for Basti from yesterday — 单人/extract-my-action-items 01KFY1RSEVVQW7MB1TKG4N2D20 — 所有与会者,特定转录稿每周安装次数
104
仓库
GitHub 星标数
9
首次出现
2026年2月18日
安全审计
安装于
opencode104
codex104
cursor104
claude-code103
windsurf100
github-copilot99
Extract action items from a Fireflies transcript using parallel subagents. Catches items automated summaries miss.
Two modes:
Parse the user's invocation:
Extract the search criteria (date, keyword, or transcript ID) from the invocation.
The transcript API returns a JSON array (or an MCP wrapper containing one). Extract to plain text before chunking.
You should inspect the user's local hooks config and avoid running commands that are blocked by the hooks.
mkdir -p .claude/scratchpad
node -e "
const fs = require('fs');
let data = JSON.parse(fs.readFileSync(process.argv[1], 'utf8'));
// Handle MCP wrapper: if top-level array has a .text field containing the real transcript, parse that
if (data.length === 1 && typeof data[0]?.text === 'string') {
// Extract speaker lines from the text content
const lines = data[0].text.split('\n').filter(l => l.match(/^[A-Za-z].*?:/));
fs.writeFileSync('.claude/scratchpad/transcript.txt', lines.join('\n'));
const speakers = [...new Set(lines.map(l => l.split(':')[0].trim()))].sort();
console.log('Speakers:', JSON.stringify(speakers));
console.log('Total lines:', lines.length);
} else {
// Standard array of {speaker_name, text} objects
const lines = data.map(e => (e.speaker_name || 'Unknown') + ': ' + (e.text || ''));
fs.writeFileSync('.claude/scratchpad/transcript.txt', lines.join('\n'));
const speakers = [...new Set(data.map(e => e.speaker_name).filter(Boolean))].sort();
console.log('Speakers:', JSON.stringify(speakers));
console.log('Total lines:', lines.length);
}
" [TRANSCRIPT_JSON_FILE]
If the transcript JSON was saved to a tool-results file by the MCP client, pass that file path as the argument.
CRITICAL: The orchestrator MUST NOT call any Fireflies MCP tools directly. ALL Fireflies interaction happens inside this subagent.
Launch a single general-purpose subagent with this prompt:
Search Fireflies for a transcript matching: [SEARCH_CRITERIA]
1. Call `mcp__fireflies__fireflies_get_transcripts` to find the transcript (by date, keyword, or ID).
2. Call `mcp__fireflies__fireflies_get_summary` and `mcp__fireflies__fireflies_get_transcript` in parallel for the matched transcript.
3. The transcript API returns a JSON array. Extract to plain text:
- With jq: jq -r '.[].text' < raw_transcript.json > .claude/scratchpad/transcript.txt
- Fallback: python3 -c "import json,sys; print('\n'.join(e['text'] for e in json.load(sys.stdin)))" < raw_transcript.json > .claude/scratchpad/transcript.txt
4. Count lines: wc -l < .claude/scratchpad/transcript.txt
5. Extract the distinct speaker list from the transcript JSON:
python3 -c "import json,sys; data=json.load(sys.stdin); print('\n'.join(sorted(set(e.get('speaker_name','') for e in data if e.get('speaker_name')))))" < raw_transcript.json
Return EXACTLY this (no other text):
- meeting_title: <title>
- meeting_date: <date>
- transcript_id: <id>
- transcript_path: .claude/scratchpad/transcript.txt
- line_count: <number>
- speakers: <comma-separated list>
- summary: <the Fireflies summary text>
Wait for the subagent to finish. Parse its returned values — these are the inputs for the remaining phases.
Chunk sizing: ceil(total_lines / 5) lines per chunk, minimum 200. Adjust chunk count so no chunk is under 200 lines.
Launch one general-purpose subagent per chunk.
Read lines [START] to [END] of [FILE_PATH].
Find ALL action items for [TARGET_PERSON]. Return each as:
- **Item**: what they committed to
- **Quote**: exact words from transcript
- **Context**: who else involved, any deadline
Beyond obvious commitments ("I'll do X"), catch these non-obvious patterns:
- Self-notes: "I'll make a note to...", "let me jot down..."
- Admissions implying catch-up: "I dropped the ball on X", "I still haven't read X"
- Conditional offers that became commitments: "If we have time, I'm happy to..."
- Volunteering: "I guess I'll volunteer to..."
- Exploration tasks: "Let me spend a few hours with it"
- Questions/topics for external parties: "I need to ask [person/firm] about X", "thing to discuss with [party]"
Read lines [START] to [END] of [FILE_PATH].
The meeting attendees are: [SPEAKER_LIST]
Find ALL action items for EVERY attendee. Group by person. For each item return:
- **Person**: who owns the action item
- **Item**: what they committed to
- **Quote**: exact words from transcript
- **Context**: who else involved, any deadline
Beyond obvious commitments ("I'll do X"), catch these non-obvious patterns:
- Self-notes: "I'll make a note to...", "let me jot down..."
- Admissions implying catch-up: "I dropped the ball on X", "I still haven't read X"
- Conditional offers that became commitments: "If we have time, I'm happy to..."
- Volunteering: "I guess I'll volunteer to..."
- Exploration tasks: "Let me spend a few hours with it"
- Questions/topics for external parties: "I need to ask [person/firm] about X", "thing to discuss with [party]"
- Delegations: "[Person], can you handle X?", "I'll leave that to [person]"
Merge subagent results, deduplicate, and categorize. Only include categories that have items.
Single-person mode — Write to .claude/scratchpad/[name]-action-items-YYYY-MM-DD.md:
# [Name] Action Items — [Meeting Title]
**Date:** [Date]
**Fireflies Link:** https://app.fireflies.ai/view/[TRANSCRIPT_ID]
## [Category Name]
- [ ] **Item title**
- Context and details
- > "Exact quote"
## Quick Reference — Time-Sensitive
1. [Item with deadline or scheduled time]
All-attendees mode — Write to .claude/scratchpad/action-items-YYYY-MM-DD.md:
# Action Items — [Meeting Title]
**Date:** [Date]
**Fireflies Link:** https://app.fireflies.ai/view/[TRANSCRIPT_ID]
## [Person Name]
### [Category Name]
- [ ] **Item title**
- Context and details
- > "Exact quote"
## Quick Reference — Time-Sensitive
1. [Person] — [Item with deadline or scheduled time]
AskUserQuestion: "DM action items to each person on Slack?" — options: "Send DMs", "Skip — just keep the file".claude/slack-users.local.json exists in the project root:
node [SKILL_DIR]/scripts/fetch-slack-users.mjs (requires SLACK_BOT_TOKEN with users:read scope), present the output to the user for review, then save to .claude/slack-users.local.json (gitignored by **/.claude/**/*.local.json)node [SKILL_DIR]/scripts/slack-post.mjs [OUTPUT_FILE_PATH]
The script sends Block Kit–formatted DMs to each person via conversations.open + chat.postMessage. Requires env var SLACK_BOT_TOKEN (with chat:write and im:write scopes).
Behavior by mode:
slack-users.local.json receives a DM with only their action items. Unresolvable names are skipped with a warning.Name resolution supports exact match and fuzzy first-name match (e.g., "Jelvin" resolves to "Jelvin Base"). After the script runs, report any skipped names to the user.
transcript.txt, the action items markdown file, and any other temp files written to .claude/scratchpad/ during this workflow./extract-my-action-items — all attendees, most recent meeting/extract-my-action-items standup — all attendees, search for "standup"/extract-my-action-items for Basti from yesterday — single person/extract-my-action-items 01KFY1RSEVVQW7MB1TKG4N2D20 — all attendees, specific transcriptWeekly Installs
104
Repository
GitHub Stars
9
First Seen
Feb 18, 2026
Security Audits
Gen Agent Trust HubWarnSocketPassSnykWarn
Installed on
opencode104
codex104
cursor104
claude-code103
windsurf100
github-copilot99
Azure RBAC 权限管理工具:查找最小角色、创建自定义角色与自动化分配
127,200 周安装