CC Workflow Studio 的 Slack 工作流共享集成:从 VS Code 一键分享到团队 Slack 的完整方案
CC Workflow Studio 的 Slack 工作流共享集成:从 VS Code 一键分享到团队 Slack 的完整方案
CC Workflow Studio(cc-wf-studio)是一款面向开发者的工作流可视化编排工具,而 001-slack-workflow-sharing 功能规格为它引入了「Slack 集成型工作流共享」能力:开发者可以在 VS Code 内把编排好的工作流定义(JSON)直接发布到团队 Slack 频道,队友则能在 Slack 消息卡片上一键把它导入自己的 VS Code。本文以 spec.md 为骨架,结合仓库内的 API 契约、数据模型、技术调研、快速上手 以及 extension 侧的真实实现,完整还原该功能的用户故事、功能需求、消息协议、安全设计与源码级实现原理,帮助你理解或复现一套「VS Code ↔ Slack」的端到端工作流协作方案。
一、功能定位与整体设计
1.1 为什么需要 Slack 共享
在原型阶段,团队成员经常需要快速分发、复用工作流定义。传统做法是「手动下载文件 → 放到目录 → 用编辑器打开」,链路长、易出错;而引入 Git 版本管理流程又过于「重」。该规格的原始需求描述明确了目标:
开发者在 VS Code 上创建的工作流定义文件(JSON),可以直接共享到团队 Slack 频道;共享后以富文本消息卡片呈现,工作流名称、作者、说明等元数据一目了然;其他成员从 Slack 消息点击一次即可把工作流导入自己的 VS Code。
由此带来两个核心价值:
- 快速分享:绕过下载/拷贝/打开的繁琐步骤,做一次「轻量级、临时性」的分享(ad-hoc sharing);
- 知识沉淀:历史分享记录变成团队可检索的「工作流知识库」,支持后续复用。
1.2 技术选型(来自调研文档)
research.md 记录了四个关键的技术决策:
| 组件 | 选型 | 理由 |
|---|---|---|
| Slack API 客户端 | @slack/web-api 7.x |
Slack 官方 Node.js SDK,TypeScript 类型完善,内置自动重试 |
| OAuth 认证 | 手动实现 OAuth 2.0 流程(不使用 @slack/oauth) |
@slack/oauth 依赖 Express.js,对 VS Code 扩展过重 |
| 本地回调服务器 | Node.js 标准库 http 模块(不用 Express) |
回调仅一次性、逻辑简单,零额外依赖 |
| 令牌存储 | VS Code context.secrets(Secret Storage) |
由 OS 级 Keychain / Credential Manager 加密保管,禁止明文 |
调研中还排除了「Webview 内嵌认证」(Slack OAuth 禁止 iframe、存在 CORS 问题)、「ML/AI 检测机敏信息」(过度设计)等备选方案。
实现细节提示:调研文档设计的是「Bot User Token + 本地 OAuth 回调」,而当前仓库源码已演进为以 User OAuth Token(
xoxp-开头)为主的手动输入 +auth.test校验模式(见 slack-connect-manual.ts)。下文会分别说明规格与当前实现,阅读时请注意这一演进。
二、四条用户故事与验收场景
规格把功能拆成 4 条带优先级的用户故事,每一条都有独立的验收场景(接受条件),构成整个功能验收的基线。
2.1 用户故事 1:VS Code → Slack 共享工作流(P1)
开发者在 VS Code 中打开工作流定义,执行「共享到 Slack」,流程包含机敏信息检测与警告。
验收场景要点(完整继承自 spec.md):
- 打开工作流文件 → 执行「Share to Slack」命令 → 弹出共享频道选择对话框;
- 选定频道 → 执行共享 → 工作流以富文本消息卡片发布到频道;
- 若工作流含 API Key 或认证 Token → 弹出机敏信息警告对话框,可选择继续或中止;
- 选择「继续」→ Slack 消息上追加「可能包含机敏信息」的注意说明;
- 若令牌未配置 → 弹出令牌输入对话框;
- 若工作流定义文件格式非法 → 显示错误并中止共享。
2.2 用户故事 2:Slack → VS Code 一键导入(P1)
团队成员从 Slack 消息直接导入工作流,无需手动下载、放置、打开。
验收场景要点(spec.md):
- 点击消息卡片上的「在 VS Code 中打开」按钮 → VS Code 启动并自动导入打开工作流;
- 若已存在同名工作流文件 → 弹出覆盖确认对话框;
- VS Code 未启动时 → 自动拉起 VS Code 并完成导入;
- 工作流文件损坏 → 报错并中止导入。
2.3 用户故事 3:VS Code 内检索与复用历史共享(P2)
支持按频道名、工作流名、作者、共享时间等维度过滤检索,从结果中直接导入复用(spec.md)。
2.4 用户故事 4:令牌管理(P3)
首次使用时输入令牌,系统自动校验有效性;支持查看(掩码显示)与重新设置;VS Code 重启后无需重新输入(spec.md)。
三、功能需求清单(FR-001 ~ FR-023)
规格将需求划分为四组,逐条落实:
3.1 共享功能
- FR-001:支持从 VS Code 选择工作流并共享到 Slack 频道;
- FR-002:共享前校验工作流定义合法性,格式非法时报错;
- FR-003:共享时允许开发者选择目标频道;
- FR-004:消息卡片必须包含元数据:工作流名、作者名、说明、共享时间、「在 VS Code 中打开」按钮;
- FR-005:检测 API Key、认证 Token、密码、私钥等机敏信息并警告;
- FR-006:警告后允许用户显式继续(仅警告、不强制阻断);
- FR-007:共享含机敏信息的流程时,消息中追加注意说明。
3.2 导入功能
- FR-008:共享消息展示「在 VS Code 中打开」按钮;
- FR-009:点击按钮后自动启动 VS Code 并导入;
- FR-010:导入到
.vscode/workflows/目录; - FR-011:导入后自动在编辑器中打开;
- FR-012:导入时校验文件合法性;
- FR-013 / FR-014:同名文件先弹覆盖确认,覆盖或取消分别处理。
3.3 检索与复用
- FR-015 ~ FR-018:VS Code 内检索历史共享,支持按工作流名、作者名、共享时间范围、频道名过滤;结果按共享时间降序;可选中直接导入。
3.4 认证与令牌管理
- FR-019:首次使用提示输入令牌并校验有效性;
- FR-020:工作流文件以 Slack 消息附件形式保存(不依赖外部存储);
- FR-021:令牌必须存入 VS Code Secret Storage(禁止明文);
- FR-022:检测到令牌失效时提示重新输入;
- FR-023:在 VS Code UI 中显示当前连接的 Slack 工作区名。
四、源码级实现:共享流程的 7 个步骤
extension 侧的共享入口是 slack-share-workflow.ts 的 handleShareWorkflowToSlack,它处理来自 Webview 的 SHARE_WORKFLOW_TO_SLACK 消息,其执行链路与规格的 FR-004/005/006/007 一一对应:
- 机敏信息检测(未显式覆盖警告时):对序列化后的
JSON.stringify(workflow, null, 2)运行detectSensitiveData,发现命中则向 Webview 发送SENSITIVE_DATA_WARNING并中断等待用户确认——这正是 FR-006「仅警告、不强制阻断」的体现; - 提取元数据:计算节点数
workflow.nodes.length; - 获取工作区名:调用
slackApiService.getWorkspaces()找到对应workspaceId的工作区名,用于 deep link; - 发布富文本消息卡片:
postWorkflowMessage使用 Block Kit 构建消息(见下文「消息卡片结构」),返回messageTs与permalink; - 上传工作流文件到消息线程:
uploadWorkflowFile以 JSON 附件形式上传到该消息的 thread(FR-020「附件保存」); - 更新消息补全 deep link:上传拿到
fileId后,用updateWorkflowMessage重新渲染卡片,把「Import to」链接补齐; - 发送成功事件:向 Webview 发送
SHARE_WORKFLOW_SUCCESS(含permalink),并弹出原生通知,点击「View in Slack」即打开消息直链。
从源码可以推断:消息卡片分两阶段发布——先发主体卡片,等文件上传成功后再更新出完整的导入链接,避免出现「无法点击的占位按钮」。
4.1 消息卡片结构(Slack Block Kit)
slack-message-builder.ts 的 buildWorkflowMessageBlocks 是卡片构造器,核心结构:
- header 块:工作流名称;
- section 块:说明文字(如有)+ divider 分隔线;
- context 块:导入链接区,包含多编辑器入口:
📥 Import to: VS Code · Cursor · Windsurf · Kiro · Antigravity
导入链接通过 buildImportUri 生成,采用自定义 URI scheme deep link:
{scheme}://breaking-brake.cc-wf-studio/import?workflowId=...&fileId=...&workspaceId=...&channelId=...&messageTs=...&workspaceName={base64}
其中 scheme 对应当前支持的编辑器:vscode、cursor、windsurf、kiro、antigravity;workspaceName 会做 Base64 编码,用于导入失败时在错误对话框里显示来源工作区。这条 deep link 正是「从 Slack 一键打开 VS Code」的落地点。
4.2 机敏信息检测:正则模式集
spec.md 定义了「机敏信息模式(Sensitive Data Patterns)——用于检测 API Key、认证 Token、密码、私钥的正则模式集,含类型、严重级别与说明」。其实现位于 sensitive-data-detector.ts,内置 8 类模式:
类型(SensitiveDataType) |
正则核心 | 严重级别 |
|---|---|---|
AWS_ACCESS_KEY |
AKIA + 16 位大写字母数字 |
high |
AWS_SECRET_KEY |
aws_secret_access_key 等键名 + 40 位 Base64 风格串 |
high |
SLACK_TOKEN |
xoxb- / xoxp- / xoxa- / xoxo- 前缀 |
high |
GITHUB_TOKEN |
ghp_ + 36 位字符 |
high |
PRIVATE_KEY |
-----BEGIN ... PRIVATE KEY----- |
high |
API_KEY |
api_key / apikey 键名 + ≥20 位字符 |
medium |
TOKEN |
token / auth_token / access_token 键名 + ≥20 位字符 |
medium |
PASSWORD |
password / passwd / pwd 键名 + ≥8 位字符 |
low |
每条命中记录包含:type(类型)、maskedValue(仅显示首 4 位与末 4 位,如 AKIA...X7Z9)、position(字符偏移)、context(前后各 50 字符的上下文,命中处替换为 [REDACTED])、severity(级别)。检测结果只保留掩码值,原始值不落地,呼应了数据模型中的安全约束。
规格中的成功标准 SC-003 要求该检测对 AWS、GitHub、Slack、OpenAI 等常见模式的命中率 ≥ 90%,SC-008 要求令牌以加密形式保存、明文保存为零。
五、导入链路与覆盖确认
导入入口是 slack-import-workflow.ts 的 handleImportWorkflowFromSlack,处理 IMPORT_WORKFLOW_FROM_SLACK 消息,执行链路为:
- 下载文件:
downloadWorkflowFile(workspaceId, fileId)先调files.info取url_private,再带Authorization: Bearer {token}拉取内容; - 校验 + 迁移:用 core 包的
validateWorkflowFile校验格式,再用migrateWorkflow做向后兼容迁移(FR-012); - 选择保存工作区:单工作区自动使用;多工作区弹 QuickPick 让用户选择(取消则静默停止);
- 确定路径:
<工作区>/.vscode/workflows/{name}.json,文件名中的非法字符替换为_;目录不存在时用vscode.workspace.fs.createDirectory自动创建(FR-010); - 覆盖确认:非覆盖模式下若
fileExists为真,弹模态警告框「Overwrite」/取消,取消则发送IMPORT_WORKFLOW_CANCELLED(FR-013/014); - 写盘:
fileService.writeFile落盘; - 回发成功:发送
IMPORT_WORKFLOW_SUCCESS(含workflow对象用于直接载入画布)并显示原生通知,指示文件落盘位置。
规格中的 ImportStatus 状态机(pending → downloading → validating → writing → completed/failed)完整描述了该链路的每一步。
六、搜索与复用:基于 Slack 消息搜索
SlackApiService.searchWorkflows(slack-api-service.ts)实现了检索能力(FR-015~018):
let query = 'workflow filename:*.json'; // 固定限定工作流 JSON
if (options.query) query = `${options.query} ${query}`;
if (options.channelId) query = `${query} in:<#${options.channelId}>`; // 频道限定
底层调用 client.search.messages({ query, count: min(count||20, 100), sort }),从匹配结果的 files[0] 中取出 fileId、fileName、url_private 等用于后续导入。规格的 SEARCH_SLACK_WORKFLOWS 命令还支持 authorName、fromDate、toDate 过滤,并在 Webview 侧按共享时间降序展示(SC-005/006:检索结果 2 秒内呈现、100 条共享检索 3 秒内完成)。
七、认证与令牌安全(FR-019 ~ FR-023)
7.1 两种接入方式
- OAuth 流程(slack-connect-oauth.ts):
initiateOAuthFlow注册会话 → 浏览器打开授权 URL → 轮询授权码 → 兑换令牌 →tokenManager.storeConnection加密保存; - 手动令牌输入(slack-connect-manual.ts,当前主路径):Input Box 输入
xoxp-开头的 User Token →client.auth.test()校验并自动取得team_id/team→storeManualConnection保存。校验规则:必须以xoxp-开头且长度 ≥ 40(validateUserTokenFormat)。
7.2 Secret Storage 密钥设计
slack-token-manager.ts 按工作区生成隔离密钥:
| 类型 | 密钥格式 |
|---|---|
| Bot 令牌 | slack-oauth-{workspaceId} |
| User 令牌 | slack-user-oauth-{workspaceId} |
| 工作区元数据 | slack-workspace-{workspaceId} |
| 工作区列表 | slack-workspace-list |
工作区元数据(名称、teamId、scope、授权时间等)以 JSON 存入 Secret Storage,令牌与元数据分离存储,并支持多工作区列表维护、单工作区清理与全量登出。底层依赖 VS Code 1.53.0+ 的 context.secrets,即 macOS Keychain / Windows Credential Manager / Linux libsecret。
7.3 Slack API 契约中的安全要求
slack-api-contracts.md 的「Security Requirements」明确:
- 令牌加密存储、禁止明文与硬编码;
- 令牌最小权限(仅申请必要 Scopes);
- 保存前用
auth.test校验、运行期与出错时再校验; - 上传前扫描工作流 JSON;
- 日志禁止输出令牌与工作流内容;
- UI 展示令牌仅部分掩码(如
xoxb-****...****1234); - 共享前必须弹确认对话框。
八、消息契约:Webview ↔ Extension Host
extension-host-api-contracts.md 定义了完整的消息传递协议,类型定义已落地于 slack-messages.ts 与 messages.ts。
8.1 Webview → Extension(命令)
| 消息类型 | 载荷要点 |
|---|---|
SLACK_CONNECT / SLACK_DISCONNECT |
空对象 |
GET_SLACK_CHANNELS |
includePrivate?(默认 true)、onlyMember?(默认 true) |
SHARE_WORKFLOW_TO_SLACK |
workflowId、workflowName、channelId、description?、overrideSensitiveWarning?(默认 false) |
IMPORT_WORKFLOW_FROM_SLACK |
workflowId、fileId、messageTs、channelId、overwriteExisting?(默认 false) |
SEARCH_SLACK_WORKFLOWS |
query?、channelId?、authorName?、fromDate?、toDate?、limit?(默认 20,最大 100) |
8.2 Extension → Webview(事件)
成功/失败成对出现:SLACK_CONNECT_SUCCESS/FAILED、GET_SLACK_CHANNELS_SUCCESS/FAILED、SHARE_WORKFLOW_SUCCESS/FAILED、IMPORT_WORKFLOW_SUCCESS/FAILED(另有 IMPORT_WORKFLOW_CONFIRM_OVERWRITE、IMPORT_WORKFLOW_CANCELLED)、SEARCH_SLACK_WORKFLOWS_SUCCESS/FAILED,以及关键的交互事件 SENSITIVE_DATA_WARNING。
8.3 两条典型消息流
含机敏信息的共享流:
Webview SHARE_WORKFLOW_TO_SLACK
→ Extension 机敏信息检测
→ Webview SENSITIVE_DATA_WARNING
→ 用户选择「继续」
→ Webview SHARE_WORKFLOW_TO_SLACK (overrideSensitiveWarning: true)
→ Extension 调用 Slack API
→ Webview SHARE_WORKFLOW_SUCCESS
带覆盖确认的导入流:
Webview IMPORT_WORKFLOW_FROM_SLACK
→ Extension 文件存在性检查
→ Webview IMPORT_WORKFLOW_CONFIRM_OVERWRITE
→ 用户选择「覆盖」
→ Webview IMPORT_WORKFLOW_FROM_SLACK (overwriteExisting: true)
→ Extension 下载并保存
→ Webview IMPORT_WORKFLOW_SUCCESS
九、Slack Web API 契约与错误处理
9.1 使用到的 API(Slack Web API v2)
| 用途 | 方法 | Endpoint |
|---|---|---|
| 令牌校验 | POST | auth.test |
| 频道列表 | POST | conversations.list |
| 富文本卡片 | POST | chat.postMessage |
| 文件上传 | POST | files.uploadV2 |
| 消息检索 | POST | search.messages |
规格为 chat.postMessage 给出了完整的 Block Kit 示例载荷:header(🔧 Workflow: {name})、section 元数据字段(Author / Version / Nodes / Created)、section 说明、actions 按钮(📥 Import to VS Code,action_id: import_workflow)。files.uploadV2 的响应中需从嵌套结构 response.files[0].files[0] 取 file.id、url_private、permalink——这正是 slack-api-service.ts 中 uploadWorkflowFile 的实现细节。
9.2 Rate Limit 策略
规格给出 Slack Web API 的分层限流(Tier 1: chat.postMessage、files.upload;Tier 2: conversations.list、search.messages;Tier 3: auth.test;Tier 4: 其他),并约定对策:依赖 @slack/web-api 自动重试、尊重 Retry-After 头、按指数退避重试。
9.3 统一错误处理
slack-error-handler.ts 把 Slack 错误码映射为 i18n key 与建议动作,核心映射表:
| 错误码 | 场景 | 建议动作 |
|---|---|---|
invalid_auth / not_authed / account_inactive |
令牌无效/失效 | 重新连接 |
missing_scope |
缺少权限 | 补授权后重装 App |
rate_limited |
超限 | 等待 Retry-After 秒后重试 |
channel_not_found |
频道不存在 | 检查频道 ID |
not_in_channel |
Bot 不在频道 | 邀请 Bot 入频道 |
file_too_large |
文件超限 | 缩小文件 |
msg_too_long |
消息超 40000 字符 | 精简说明 |
internal_error |
Slack 内部错误 | 指数退避重试 |
工具函数还提供了 isRecoverableError、isAuthenticationError、isPermissionError、isRateLimitError 等判定与 getRetryDelay(指数退避 + 20% 抖动)供重试策略使用。
十、数据模型与存储设计
data-model.md 定义了 5 个核心实体,均已落地于 slack-integration-types.ts:
- SlackWorkspaceConnection:
workspaceId、workspaceName、teamId、accessToken(仅 Secret Storage 访问)、userAccessToken、tokenScope、userId、botUserId、authorizedAt、lastValidatedAt; - SharedWorkflowMetadata:
id(UUID v4)、name(1-100 字符)、description(≤500)、version(SemVer)、authorName、sharedAt、channelId/Name、messageTs(1234567890.123456格式)、fileId、fileUrl、nodeCount(0-1000)、tags(≤10 个)、hasSensitiveData、sensitiveDataOverride; - SensitiveDataFinding:
type、maskedValue(首 4 尾 4)、position、context(≤100 字符)、severity; - SlackChannel:
id(C+ 8-11 位)、name、isPrivate、isMember、memberCount、purpose、topic;只有isMember === true的频道可作为共享目标; - WorkflowImportRequest:
workflowId、sourceMessageTs、sourceChannelId、fileId(F+ 8-11 位)、targetDirectory(必须为绝对路径且位于.vscode/workflows/内)、overwriteExisting、requestedAt、status(ImportStatus 状态机)、errorMessage。
存储设计上,令牌走 Secret Storage(密钥 slack-oauth-* 系列,卸载扩展时自动清除),工作流文件落在本地 .vscode/workflows/*.json,可选的共享历史缓存为 .vscode/workflow-sharing-history.json(含 version、lastSyncedAt、sharedWorkflows[])。
十一、边缘场景与边界处理
规格单列了 6 类边缘场景及其对策(spec.md):
- 网络断开:显示错误并提示检查连接;离线时禁用共享/导入(灰显);
- Rate Limit:检测限流错误、提示等待时间、实现自动重试;
- 超大文件(如 ≥10MB):事前检查文件大小并警告;参考 Slack 附件限制(通常 100MB)设置合适上限;
- 无频道访问权限:共享目标仅列出有权限的频道;权限错误给出明确提示;
- 文件被删除/不可访问:以附件形式保存(不依赖独立存储);附件删除时报错并中止导入;检索结果中对已删除项给出警告;
- 同一工作流多次共享:记录共享时间与消息 ID 以区分多版本,检索结果优先展示最新版本。
十二、验收与性能基准
规格的成功标准(SC-001 ~ SC-010)既是产品验收口径,也可作为你复现或测试时的量化指标:
- 操作时间:共享 ≤ 30 秒;导入 ≤ 10 秒;令牌输入与校验 ≤ 30 秒(SC-001/002/007);
- 检测精度:常见 API Key/Token 模式命中率 ≥ 90%(SC-003);
- 流程完整性:共享→导入全链路无需手动下载/放置/打开(SC-004);
- 检索性能:结果 ≤ 2 秒;100 条历史共享的检索 ≤ 3 秒(SC-005/006);
- 安全:认证信息全部加密保存、明文保存为零(SC-008);
- 易用性:90% 用户首次尝试即成功完成共享与导入;团队内工作流再利用率提升 ≥ 50%(SC-009/010)。
quickstart.md 还提供了 6 组手工 E2E 用例(T001~T006,覆盖令牌设置、共享、机敏检测、导入、覆盖确认、检索)与 3 组错误用例(E001~E003:令牌未设、频道无权限、网络错误),以及性能测试目标(共享 < 3s、导入 < 2s、检测 < 500ms@100KB)。排障章节涵盖:令牌校验失败(检查 xoxb- 前缀与 chat:write、files:write、channels:read、groups:read 四个 Scopes)、令牌存不进 Secret Storage(检查 Keychain / Credential Manager / libsecret)、消息不显示(/invite Bot 入频道)、Rate Limit 处理等。
十三、总结
001-slack-workflow-sharing 规格为 CC Workflow Studio 定义了一套完整的「工作流即消息」协作闭环:VS Code 内共享 → Slack 富文本卡片呈现 → 一键导入 → 历史检索复用,并围绕安全(机敏信息检测 + Secret Storage 令牌管理)与健壮性(错误码映射、限流退避、边缘场景对策)做了系统设计。从仓库源码可以确认,规格中的核心链路均已落地:共享的 7 步编排(slack-share-workflow.ts)、导入的 7 步编排(slack-import-workflow.ts)、Block Kit 卡片构建(slack-message-builder.ts)、正则检测模式集(sensitive-data-detector.ts)、Secret Storage 令牌管理(slack-token-manager.ts)与统一错误处理(slack-error-handler.ts)。如果你想在自己的扩展中实现同类能力,按「Slack App 配置 → 令牌接入 → 共享/导入命令 → 消息契约 → 错误处理」的顺序推进,并以上述 FR/SC 作为验收基线即可。