Files

202 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Superpowers-clurdra
把 Gitea 工单变成 VS Code 里的看板,每张卡片背后挂着一组 AI 会话(头脑风暴 → 实施 → 审查 → 测试),从建工单到合并 PR 全程在编辑器里完成。
- 数据源:**Gitea** 工单(主)+ **YouTrack** 工单(可选镜像)
- 执行者:`claude` CLI 负责规划 / 实施 / 测试 / 提交,`codex` 负责审查
- 状态存放:工单评论里的一段 state JSON,多人、多机共享;本机专属字段(会话 id、worktree 路径等)留在本机
- 联动:Gitea webhook 推回本机,PR 开了自动审查、审查意见自动注入实施终端、合并后自动清 worktree 和分支
## 工作流
```
待办 ──拖到进行中──▶ 进行中 ──PR 打开──▶ 审查 ──拖到完成──▶ 完成
│ │ │ │
头脑风暴会话 实施会话 审查会话(codex) 插件代为合并 PR
产出 spec / plan 独立 worktree 意见注入实施终端 关工单 · 删 worktree · 删分支
+ feature 分支 测试会话可随时开
```
1. **新建工单**:待办列头的 `+` → 写需求(可粘贴截图)→ 开一个 `claude` 头脑风暴会话,它用 `spx issue create` 建工单并回填 spec / plan 路径。
2. **实施**:把卡拖到「进行中」(或点计划文件行的 ▶)。插件创建 `feature/<slug>` 分支 + git worktree,在里面开 `issue-N-实施` 终端并发实施 prompt;实施方在 PR body 里写 `Closes #N`
3. **审查**PR opened / synchronize 的 webhook 到达后,插件自动开 `issue-N-审查`codex);审查意见通过 `spx pr review-comment` 发到 PR,webhook 再把意见注入实施终端形成闭环。
4. **测试**:工单面板里 ▶ 开 `issue-N-测试` 会话(`/pr-acceptance-testing`)。
5. **完成**:拖到「完成」列。有 PR 就由插件合并(冲突时开 `issue-N-冲突解决` 会话,解决后再拖一次),然后关工单、把会话记录拷回主仓库、删 worktree、删 feature 分支。
6. **回退**:进行中 / 审查中的卡可「重置为待办」,关 PR、删 worktree、清分支和实施痕迹,spec / plan 保留。
7. **移交**:前置条件:两台机器的 spx 都已 `cd cli && make install` 到含 `handoffAttachmentId` 的版本,否则移交期间旧 spx 的 state 写入会被 schema 拒绝。工单 tab 头部「移交」→ 选同事。插件校验 worktree 已全部 push,关掉该工单的终端,把头脑风暴 / 实施 / 测试的 claude 会话(jsonl + 子目录)和 codex 审查会话打成 `spx-handoff-issue-N.tgz` 挂到工单附件,写 `handoffAttachmentId` / `handoffFrom`,把工单指派给对方,最后删本机 worktree 与本地分支(远端分支保留)。对方看板上该卡显示「待接管」,工单 tab 点「接管」:从 origin 重建 worktree`git worktree add -B <branch> … origin/<branch>`)、把会话文件装到本机 `~/.claude/projects/` 对应目录(先清同 sid 副本)与 `~/.codex/sessions/`、写本机字段、清移交字段并删附件。之后 resume / 合并 / 冲突解决 / 测试与本机实施的工单无异。
其他看板规则:
- 待办列里卡片拖到另一张卡上 = 设前置依赖,拖回列头 = 清依赖。前置未完成的卡显示 🔒,不能拖出待办、不能开会话。待办列按依赖链渲染成缩进树。
- 完成列按合并时间倒序,其余列按工单号倒序。
- 每张卡首次开会话时随机分配一个颜色,之后该工单所有终端 tab 用同色圆点。
- 选中卡片会聚焦它的终端(新建 > 实施 > 规划 > 审查 > 测试);点终端 tab 也会反向选中卡片。
- 键盘:`↑↓←→` 移动选中,`Enter` 恢复实施会话(没有则头脑风暴会话),`Esc` 取消选中。
- 看板范围:工具栏 👤/👥 在「我创建或指派给我的」与「仓库全部」之间切换。
## 环境要求
| 工具 | 用途 |
|---|---|
| `git` | worktree、分支、fetch / merge |
| `claude` | 规划、实施、测试、冲突解决、提交、PR 摘要(找不到时会提示常见位置 `~/.local/bin` |
| `codex` | 审查会话(开启自动审查时必需) |
| `tea` | `spx``~/.config/tea/config.yml` 读取 Gitea host + token;审查 prompt 也用 `tea pulls` 看 PR |
| `spx` | 本仓库 `cli/` 里的 Go CLI,见下文 |
| `opencli` | prompts 里统一以 `opencli spx ...` 调用 spx |
| `tar` | 移交时打包 / 解包会话文件 |
| `bash` | 执行钩子脚本 |
- 仅支持 Gitea`https://<host>/api/v1`),不支持 GitHub。
- POSIX 环境。删 worktree 前扫 `/proc` 杀占用进程只在 Linux 生效,macOS 上降级为直接删。
- 依赖内置 `vscode.git` 扩展检测工作区改动(提交按钮)。
### 安装 spx
```bash
cd cli && make install # 编译到 bin/spx 并安装到 ~/.local/bin/
```
`spx` 命令:
| 命令 | 作用 |
|---|---|
| `spx issue create --title ... [--body-file F] [--spec P] [--plan P] [--state-json J]` | 建工单并认领;spec / plan 同时写 body marker 和 state JSON |
| `spx issue marker --issue N --type spec\|plan --value P` | 更新 body 里的 `<!-- spx:spec=... -->` / `<!-- spx:plan=... -->` 并同步 state |
| `spx issue state get --issue N` | 读 state JSON |
| `spx issue state merge --issue N --state-json J` | 浅合并写回(按 schema 校验) |
| `spx pr review-comment --pr N --body-file F` | 发审查评论,自动加 `<!-- spx:review=1 -->` 标记 |
全局 flag`--repo OWNER/REPO`(默认从 origin 推断)、`--host``--json``--cwd`。tea 用 keyring 存 token 时需设 `GITEA_TOKEN` 环境变量。
### Gitea 配置
1. 打开看板 → 设置 → 认证,填 Gitea host 和 Personal Access Token(存 VS Code SecretStorage)。状态栏会常驻显示当前身份 `spx: <login>`token 失效变红;Gitea 邮箱和 `git config user.email` 不一致时会警告。
2. 在仓库上配一个 webhook 指向本机的 `http://<公网地址>/webhook`(本机默认监听 `17421`,通常经 frp 之类反代暴露),事件至少勾选 **Issues、Issue Comment、Pull Request、Push**。建议设置 secret 并在插件设置里同填,否则不校验签名。
3. webhook 会广播到每个开发者的机器,只有工单 assignee 所在的机器执行副作用(写状态、触发审查、注入终端),其他机器只刷新 UI。实施即认领,所以正常情况下不用手动指派。
### YouTrack(可选)
设置 → YouTrack 填 base URL、Permanent Token、项目 shortName 后,工具栏出现「导入 YouTrack 工单」,QuickPick 多选后镜像到看板(卡片 id 形如 `youtrack:LXF-12`)。状态同样以评论形式存在 YouTrack 工单上;拖到完成列执行 `youtrackCloseCommand`(留空则自动取项目第一个已解决状态)。
## 面板
编辑器主区的 webview = 顶部工具栏 + 四列看板 + 底部四个 tab。
**工具栏**:分支同步(把远端 `autoBuildBranch` 快进到 `devBranch`,纯远端、从不 force push)· `.env*` 文件锁(批量 chmod 只读,首次启动默认锁定)· 提交代码(有未提交改动时才显示,后台跑无头 `claude` 提交)· 导入 YouTrack 工单 · 看板范围 · 刷新 · 设置。
**工单 tab**:state JSON 的属性网格。会话 id 行双击恢复会话、▶ 新开、✕ 关 tab;spec / plan 行双击打开文件,plan 行 ▶ 实施;PR 行双击打开浏览器、▶ 生成 PR 变更摘要(写到 `docs/pr-diff/`);分支行 🔀 本地预合并;工作树行双击用 VS Code / PyCharm 打开、🗑 删除。顶部有重置为待办、移交 / 接管(见上文工作流第 7 条)、关闭工单、删除工单(关 tab → 删 worktree → 关 PR → 删分支 → 删 issue)、查看日志。
**Profile tab**:工作区级 KV 表(行 = key,列 = dev / prod 等),值可多行、可贴图,落盘 `.spx/profiles.json`
**会话 tab**:项目级 Claude 会话管理器——新建(可指定 profile 和首条 prompt)、重命名、恢复、导入已 `/rename` 的会话。落盘 `.spx/session-names.json`
**改动 tab**:PR 文件审阅。左侧文件树 + 统计(可过滤 `tests/`),右侧内联 diff(统一 / 分栏),「已查看」按文件变更指纹失效,每个文件可用 deepseek 生成一句话改动说明。
也可以从外部拉起会话:`vscode://clurdra.superpowers-vscode-clurdra/create-session?profile=<名>&name=<tab名>&prompt=<提示词>&cwd=<路径>`(参数需两层 urlencode)。
## 会话与 profile
| 会话 | 终端名 | CLI | 工作目录 | profile |
|---|---|---|---|---|
| 新建工单 | `issue-new-<nonce>-规划` | claude | 主仓库 | 弹窗里选 |
| 头脑风暴(续) | `issue-N-规划` | claude | 主仓库 | 工单 `brainstormProfilePath` |
| 实施 | `issue-N-实施` | claude `--effort high` | worktree | 工单 `profilePath` |
| 审查 | `issue-N-审查` | codex | worktree | 设置里的 `codexModel` / `codexReasoningEffort` |
| 测试 | `issue-N-测试` | claude | worktree | 工单 `testProfilePath` |
| 冲突解决 | `issue-N-冲突解决` | claude `--effort high` | worktree | 设置 `conflictResolutionProfilePath` |
所有终端固定开在编辑器第二分组。claude 会话统一以 `--settings <profile.json> --dangerously-skip-permissions` 启动,后台无头调用会剥掉 `ANTHROPIC_*` 环境变量,让 profile 成为唯一鉴权来源。
profile 是 Claude 的 settings JSON 文件。目录按 `$SUPERPOWERS_PROFILES_DIR` → 设置 `profilesDirectory``~/Sources/cruldra-profile/claude-config/profiles` / `~/.claude/profile-settings` / `~/.claude/profiles` 顺序探测;三种会话 profile 留空时各自回落默认 profile(`offical.json` / `official.json`),互不回退。跨机器的绝对路径按文件名重新映射。
prompts 在 `prompts/*.md`,随 VSIX 一起安装,改完即生效,也可在设置 → 提示词里覆盖:
| 文件 | 占位符 |
|---|---|
| `brainstorm.md` | `{userRequest}` `{nonce}` |
| `brainstorm-continue.md` | `{issueNumber}` |
| `implement-plan.md` | `{planFile}` `{issueNumber}` |
| `review.md` | `{prNumber}` |
## 设置
全部在看板的设置弹窗里(存 globalState),不走 VS Code 原生 settings。
| 分组 | 键 | 默认 | 说明 |
|---|---|---|---|
| 认证 | `devBranch` | `main` | 日常开发分支 |
| | `autoBuildBranch` | 空 | Jenkins 等监听的分支;空 = 与 `devBranch` 相同,分支同步按钮禁用 |
| | `conflictResolutionProfilePath` | 空 | 冲突解决会话 profile |
| | `commitProfilePath` | `deepseek-v4-pro` | 「提交代码」用的 profile;未配置时提交直接失败 |
| | `prDiffSummaryProfilePath` | `deepseek-v4-pro` | 「改动」说明 / PR 变更摘要用的 profile;未配置时生成失败 |
| | `codexModel` / `codexReasoningEffort` | 空 | 审查会话的 codex `-c` 覆盖;空 = 用 codex 自己的 config |
| 网络 | `webhookPort` | `17421` | 本机 webhook 端口 |
| | `webhookSecret` | 空 | Gitea webhook secret,空 = 不校验签名 |
| | `autoReview` | `true` | 全局自动审查;工单级 `autoReview` 可覆盖 |
| | `profilesDirectory` | 空 | Claude profiles 目录,空 = 自动探测 |
| YouTrack | `youtrackBaseUrl` / `youtrackProjectShortName` / `youtrackCloseCommand` | 空 | 见上文 |
| 钩子 | `worktreeDirectory` | `~/Sources/worktree/$project_name/$feature_name` | 占位符 `$project_root` `$project_name` `$feature_name` |
| | `worktreeOpenWith` / `pycharmCommand` | `vscode` / `pycharm` | 工作树行双击的打开方式 |
| | `worktreePostCreateScript` | `.spx/worktree-post-create.sh` | worktree 创建后 |
| | `worktreePreRemoveScript` | `.spx/worktree-pre-remove.sh` | worktree 删除前 |
| | `implTabPreCreateScript` | `.spx/impl-tab-pre-create.sh` | 实施 / 测试 / 冲突解决 tab 创建前(复用 tab 不触发) |
| | `implTabPostCloseScript` | `.spx/impl-tab-post-close.sh` | 实施 tab 关闭后 |
钩子用 `bash <script>` 执行,cwd 为 worktree,超时 30s,脚本不存在静默跳过,失败只告警不阻断。可用环境变量:`WORKTREE_PATH` `WORKSPACE_ROOT` `BRANCH` `ISSUE_NUMBER` `MAIN_BRANCH`
## 工单上的 state JSON
以工单最后一条 state 评论为准,写入是读 → 浅合并 → 追加新评论,带一次乐观并发重放。schema 在 `schemas/state-json.schema.json``spx` 写入前按它校验)。
| 字段 | 说明 |
|---|---|
| `column` | `todo` / `in-progress` / `review` / `done` |
| `specFile` / `planFile` | 相对主仓库的 md 路径 |
| `branch` / `pr` / `prMerged` / `prMergedAt` | 实施分支与 PR 状态 |
| `implementStatus` | `running` / `done` / `failed` |
| `color` | 终端 tab 颜色 |
| `autoReview` | 工单级自动审查开关 |
| `handoffAttachmentId` / `handoffFrom` | 移交中:会话包附件 id 与发起人;接管后清空 |
| `sessionId` / `implementSessionId` / `reviewSessionId` / `testSessionId` | 各会话 id |
| `profilePath` / `brainstormProfilePath` / `testProfilePath` | 各会话 profile |
| `worktreePath` / `prDiffFile` | 本机路径 |
最后两行(会话 id、profile、路径共 9 个字段)是**本机字段**,只存在 VS Code workspaceState 里,不写进共享评论,所以同一工单在不同机器上可以各自有会话。
## 工作区约定
```
docs/superpowers/specs/<slug>/spec.md
docs/superpowers/plans/<slug>/plan.md
docs/pr-diff/pr-<pr>-issue-<n>.md # PR 变更摘要
.spx/profiles.json # Profile tab
.spx/session-names.json # 会话 tab
.spx/pr-review-confirmed.json # 改动 tab 已查看态
.spx/pr-file-summaries.json # 改动 tab 文件说明
.spx/youtrack-imported.json # YouTrack 导入集
.spx/profile-assets/ # Profile 值里粘贴的图片
.spx/*.sh # 钩子脚本
```
实施分支名 `feature/<slug>`slug 取 plan 路径里 `plans/` 后的一段。
## 开发
```bash
pnpm install
pnpm dev # webview (Vite) + 扩展 (esbuild) 双 watch,配合 .vscode/launch.json 的 Extension 调试
pnpm test # vitest,只测不依赖 vscode API 的纯逻辑模块
pnpm lint
pnpm typecheck
pnpm ext:package # 构建并打 VSIX,产物在本目录
```
安装本地包:`code --install-extension superpowers-vscode-clurdra-<ver>.vsix --force`(用了 VS Code profile 的窗口要加 `--profile <name>`)。
技术栈:TypeScript、VS Code Extension API、React 19 + Tailwind 4webview)、esbuild、VitestCLI 为 Go + cobra。
## 许可证
MIT