222 lines
21 KiB
Markdown
222 lines
21 KiB
Markdown
# Superpowers-clurdra
|
||
|
||
把 GitHub 或 Gitea 仓库的工单变成 VS Code 里的看板,每张卡片背后挂着一组 AI 会话(头脑风暴 → 实施 → 审查 → 测试),从建工单到合并 PR 全程在编辑器里完成。
|
||
|
||
- 数据源:**GitHub / Gitea** 仓库工单(主,按工作区 git origin 的 host 区分:`github.com` 是 GitHub,其余都按 Gitea)+ **YouTrack** 工单(可选镜像)
|
||
- 执行者:`claude` CLI 负责规划 / 实施 / 测试 / 提交,`codex` 负责审查
|
||
- 状态存放:工单评论里的一段 state JSON(隐藏注释格式,网页上看不到),多人、多机共享;本机专属字段(会话 id、worktree 路径等)留在本机
|
||
- 联动:仓库 webhook 推回本机,PR 开了自动审查、审查意见自动注入实施终端、合并后自动清 worktree 和分支
|
||
|
||
## 工作流
|
||
|
||
```
|
||
待办 ──拖到进行中──▶ 进行中 ──PR 打开──▶ 审查 ──拖到完成──▶ 完成
|
||
│ │ │ │
|
||
头脑风暴会话 实施会话 审查会话(codex) 插件代为合并 PR
|
||
产出 spec / plan 独立 worktree 意见注入实施终端 关工单 · 删 worktree · 删分支
|
||
+ feature 分支 测试会话可随时开
|
||
```
|
||
|
||
1. **新建工单**:待办列头的 `+` → 写需求(可粘贴截图)→ 开一个 `claude` 头脑风暴会话,它用 `spx issue create` 建工单,再经 `/ecc:grilling` + `/ecc:spec` + `/ecc:plan` 写出设计文档 / 计划并回填两者路径。
|
||
2. **实施**:把卡拖到「进行中」(或点计划文件行的 ▶)。插件创建 `feature/<slug>` 分支 + git worktree,在里面开 `issue-N-实施` 终端并发实施 prompt,实施方对计划跑 `/ecc:tdd`,在 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` 到含 `handoffBundleKey` 的版本,否则移交期间旧 spx 的 state 写入会被 schema 拒绝;两台机器都在命令面板跑过「Superpowers: 配置移交存储」(阿里云 OSS 的 endpoint、bucket、AccessKey ID / Secret,AccessKey 存在 VS Code 的密钥存储里),没配的话移交和接管都会直接提示去配。工单 tab 头部「移交」→ 选同事。插件校验 worktree 已全部 push,关掉该工单的终端,把头脑风暴 / 实施 / 测试的 claude 会话(jsonl + 子目录)和 codex 审查会话打成 xz 压缩的 `issue-N-<时间>.tar.xz`,以私有权限传到 OSS 的 `spx-handoff/<owner>/<repo>/` 下,写 `handoffBundleKey` / `handoffFrom`,把工单指派给对方,最后删本机 worktree 与本地分支(远端分支保留)。对方看板上该卡显示「待接管」,工单 tab 点「接管」:从 OSS 下载会话包、从 origin 重建 worktree(`git worktree add -B <branch> … origin/<branch>`)、把会话文件装到本机 `~/.claude/projects/` 对应目录(先清同 sid 副本)与 `~/.codex/sessions/`、写本机字段、清移交字段并删掉 OSS 上的会话包。两边的进度提示会一步步显示打包 / 上传 / 下载了多少 MB。之后 resume / 合并 / 冲突解决 / 测试与本机实施的工单无异。
|
||
8. **发布**:工具栏「发布」按钮下拉三项。「切新发布」从 `origin/<devBranch>` 切当天的 `<releaseBranchPrefix>YYYY-MM-DD` 并推远端(纯远端,不建本地分支),配了 `jenkinsJob` 会顺带问要不要立刻部署。「摘修复到当期发布」列出 `devBranch` 上还没进发布分支的提交(按文件改动指纹比对,另认 `cherry-pick -x` 留下的「cherry picked from commit」尾注,所以解过冲突、内容已变的复制品也算已摘;手工 pick 请带 `-x`),多选后在发布 worktree(`worktreeDirectory` 模板,目录名为分支名把 `/` 换成 `-`)里按序 `cherry-pick -x` 并推远端,成功后删 worktree。中途冲突则保留冲突现场、远端不变,开 `<发布分支>-冲突解决` 会话让 claude 解冲突、`cherry-pick --continue`、按序摘完剩余提交再推远端;上次冲突还没处理完时再摘会被拒绝。「部署到正式服」选一个发布分支(默认当期,选旧的即回滚)执行 `opencli jks build <jenkinsJob> -p REF=<分支> -p REMOTE_HOST=<jenkinsProdHost>`。
|
||
|
||
其他看板规则:
|
||
|
||
- 待办列里卡片拖到另一张卡上 = 设前置依赖,拖回列头 = 清依赖。前置未完成的卡显示 🔒,不能拖出待办、不能开会话。待办列按依赖链渲染成缩进树。
|
||
- 完成列按合并时间倒序,其余列按工单号倒序。
|
||
- 每张卡首次开会话时随机分配一个颜色,之后该工单所有终端 tab 用同色圆点。
|
||
- 选中卡片会聚焦它的终端(新建 > 实施 > 规划 > 审查 > 测试);点终端 tab 也会反向选中卡片。
|
||
- 键盘:`↑↓←→` 移动选中,`Enter` 恢复实施会话(没有则头脑风暴会话),`Esc` 取消选中。
|
||
- 看板范围:工具栏 👤/👥 在「我创建或指派给我的」与「仓库全部」之间切换。
|
||
|
||
## 环境要求
|
||
|
||
| 工具 | 用途 |
|
||
|---|---|
|
||
| `git` | worktree、分支、fetch / merge |
|
||
| `claude` | 规划、实施、测试、冲突解决、提交、PR 摘要(找不到时会提示常见位置 `~/.local/bin`) |
|
||
| ECC 插件(`ecc@ecc`) | Claude Code 插件,头脑风暴 / 实施会话用它的 `/ecc:grilling` `/ecc:spec` `/ecc:plan` `/ecc:tdd` 和审查子代理 |
|
||
| `codex` | 审查会话(开启自动审查时必需) |
|
||
| `gh` | GitHub 仓库必需:插件和 `spx` 都现取 `gh auth token` 当凭据,先在终端 `gh auth login` |
|
||
| `tea` | Gitea 仓库:`spx` 从 tea 配置(`~/.config/tea/config.yml`,先 `tea login add`)里 host 匹配的 login 取 token |
|
||
| `spx` | 本仓库 `cli/` 里的 Go CLI,提示词里查工单、查 PR、发起 PR、写状态都用它,见下文 |
|
||
| `opencli` | prompts 里统一以 `opencli spx ...` 调用 spx |
|
||
| `tar` | 移交时打包 / 解包会话文件 |
|
||
| `bash` | 执行钩子脚本 |
|
||
|
||
- 支持 github.com 和自建 Gitea(`https://<host>/api/v1`);不支持 GitHub Enterprise,`github.com` 以外的 host 一律按 Gitea 处理。
|
||
- POSIX 环境。删 worktree 前扫 `/proc` 杀占用进程只在 Linux 生效,macOS 上降级为直接删。
|
||
- 依赖内置 `vscode.git` 扩展检测工作区改动(提交按钮)。
|
||
|
||
### 安装 spx
|
||
|
||
```bash
|
||
cd cli && make install # 编译到 bin/spx 并安装到 ~/.local/bin/(这个目录要在 PATH 里)
|
||
```
|
||
|
||
`spx` 按当前目录 git origin 的 host 选仓库:`github.com` 走 GitHub,凭据取 `gh auth token`;其余走 Gitea,凭据取 tea 配置里 host 匹配的 login,没有就报错,要先 `tea login add` 这个 host;login 里没存 token 时(tea 把 token 存在系统钥匙串里)用环境变量 `GITEA_TOKEN` 补上,`GITEA_TOKEN` 不会发给 tea 没登录过的 host。
|
||
|
||
| 命令 | 作用 |
|
||
|---|---|
|
||
| `spx issue create --title T (--body B\|--body-file F) [--spec P] [--plan P] [--state-json J\|--state-file F]` | 建工单;spec / plan 同时写 body marker 和 state JSON |
|
||
| `spx issue view --issue N [--comments]` | 看工单标题、正文、状态、作者、指派人、链接;`--comments` 附带评论(不含 state 评论) |
|
||
| `spx issue marker --issue N --type spec\|plan\|prototype --value P` | 更新 body 里的 `<!-- spx:spec=... -->` 等 marker 并同步 state |
|
||
| `spx issue state get --issue N` | 读 state JSON |
|
||
| `spx issue state merge --issue N (--state-json J\|--state-file F)` | 浅合并写回(按 schema 校验) |
|
||
| `spx pr view --pr N` | 看 PR 标题、正文、状态、是否已合并、head / base 分支与 SHA、作者、链接 |
|
||
| `spx pr create --title T (--body B\|--body-file F) --head BRANCH [--base BRANCH]` | 发起 PR,`--base` 缺省为仓库默认分支;描述里写 `Closes #N` 看板才能把 PR 关联到工单 |
|
||
| `spx pr review-comment --pr N (--body B\|--body-file F)` | 发审查评论,自动加 `<!-- spx:review=1 -->` 标记 |
|
||
|
||
全局 flag:`--repo OWNER/REPO`、`--host`(默认都从 origin 推断)、`--json`、`--cwd`。
|
||
|
||
### 仓库与 webhook 配置
|
||
|
||
1. 认证:
|
||
- GitHub 仓库:终端里 `gh auth login` 即可,插件每次现取 `gh auth token`,自己不存 GitHub token。
|
||
- Gitea 仓库:打开看板 → 设置 → 认证,填 Personal Access Token(存 VS Code SecretStorage)。Gitea 邮箱和 `git config user.email` 不一致时会警告。
|
||
- 状态栏常驻显示当前身份 `spx: <login>`,凭据失效变红。
|
||
2. 在仓库上配一个 webhook 指向本机的 `http://<公网地址>/webhook`(本机默认监听 `17421`,通常经 frp 之类反代暴露)。Content type 必须选 **application/json**,表单编码的请求会被拒收(返回 415,日志里有提示)。建议设置 Secret 并在插件设置的 `webhookSecret` 里同填,插件按 `X-Hub-Signature-256: sha256=<HMAC-SHA256>` 校验,不填则不校验签名。
|
||
- **GitHub**:仓库 Settings → Webhooks → Add webhook。Payload URL 填上面的地址,Content type 选 `application/json`,Secret 同插件设置;事件选「Let me select individual events」,勾 **Issues、Issue comments、Pull requests、Pushes**。保存后 GitHub 发一个 `ping`,Recent Deliveries 里是 200 就通了。
|
||
- **Gitea**:仓库设置 → Web 钩子 → 添加 Gitea 钩子。目标 URL 填上面的地址,HTTP 方法 `POST`,POST Content Type 选 `application/json`,密钥文本同插件设置(Gitea 同样发 `X-GitHub-Event` 和 `X-Hub-Signature-256`);触发条件选自定义事件,勾 **Issues、Issue Comment、Pull Request、Push**。
|
||
3. 一个公网地址可以给多个仓库共用。本机开着多个 VS Code 窗口时只有一个窗口占得到端口,它把验过签的事件转给其余窗口,每个窗口只处理自己工作区 origin 对应仓库的事件;占端口的窗口关掉后,其余窗口几秒内接手端口。
|
||
4. webhook 会广播到每个开发者的机器,只有工单 assignee 所在的机器执行副作用(写状态、触发审查、注入终端),其他机器只刷新 UI。实施即认领,所以正常情况下不用手动指派。
|
||
|
||
### YouTrack(可选)
|
||
|
||
设置 → YouTrack 填 base URL、Permanent Token、项目 shortName 后,工具栏出现「导入 YouTrack 工单」,QuickPick 多选后镜像到看板(卡片 id 形如 `youtrack:LXF-12`)。状态同样以评论形式存在 YouTrack 工单上;拖到完成列执行 `youtrackCloseCommand`(留空则自动取项目第一个已解决状态)。
|
||
|
||
## 面板
|
||
|
||
编辑器主区的 webview = 顶部工具栏 + 四列看板 + 底部四个 tab。
|
||
|
||
**工具栏**:发布(切发布分支 · 摘修复 · 触发正式服部署,见工作流第 8 条;角标 = `devBranch` 上未发布的提交数)· `.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`。单个会话可以「交接」给同事:会话包打成 xz 包、以私有权限传到移交存储(同工单移交,没配会直接提示去跑「配置移交存储」)里对方的收件箱 `spx-handoff/<owner>/<repo>/session/<对方>/`;对方会话 tab 顶部「待接收」列出自己收件箱里的包,点「接收」下载装好会话、删掉 OSS 上的包。同一会话再交给同一人只保留最新一份;两边进度提示一步步显示打包 / 上传 / 下载了多少 MB。
|
||
|
||
**改动 tab**:PR 文件审阅。左侧文件树 + 统计(可过滤 `tests/`),右侧内联 diff(统一 / 分栏),「已查看」按文件变更指纹失效,每个文件可用 deepseek 生成一句话改动说明。
|
||
|
||
也可以从外部拉起会话:`vscode://clurdra.superpowers-vscode-clurdra/create-session?profile=<名>&name=<tab名>&prompt=<提示词>&cwd=<路径>`(参数需两层 urlencode)。
|
||
|
||
从 env 文件配置移交存储:`vscode://clurdra.superpowers-vscode-clurdra/configure-handoff-store?envFile=<env 文件绝对路径>`(参数同样两层 urlencode),读文件里的 `OSS_ENDPOINT` / `OSS_BUCKET_NAME` / `OSS_ACCESS_KEY` / `OSS_SECRET_KEY`,四项齐了就保存,缺项或读不到只报错、什么都不改。
|
||
|
||
## 会话与 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 `--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 一起安装,改完即生效,也可在设置 → 提示词里覆盖。模板走 Handlebars:变量写 `{{name}}`,分支写 `{{#if name}}…{{else}}…{{/if}}`。上下文是工单 state JSON 的全部字段(`planFile` `specFile` `prototypeFile` `branch` `pr` `worktreePath` `prototypeSessionId` …)外加下表这几个:
|
||
|
||
| 文件 | 额外变量 |
|
||
|---|---|
|
||
| `brainstorm.md` | `issueNumber`(有 = 续聊已有工单,无 = 新建工单)、`userRequest`、`nonce` |
|
||
| `implement-plan.md` | `issueNumber`、`planFile` |
|
||
| `review.md` | `issueNumber`、`prNumber` |
|
||
| `test.md` | `issueNumber`、`prRef` |
|
||
| `prototype.md` | `issueNumber` |
|
||
|
||
`brainstorm.md` 一份管三件事:`{{#if issueNumber}}` 走续聊(其中 `{{#if prototypeFile}}` 嵌原型段落),`{{else}}` 走新建工单。老版本里 `{issueNumber}` 这种单花括号写法不再支持;升级后首次启动会自动把存量自定义提示词改写成双花括号,并把「续聊」「续聊·原型段落」两份并进 `brainstormPrompt`,改写前会把 `settings.json` 备份成 `settings.json.bak-<时间戳>`。
|
||
|
||
## 设置
|
||
|
||
全部在看板的设置弹窗里(存 globalState),不走 VS Code 原生 settings。
|
||
|
||
| 分组 | 键 | 默认 | 说明 |
|
||
|---|---|---|---|
|
||
| 认证 | `devBranch` | `main` | 日常开发分支 |
|
||
| | `releaseBranchPrefix` | `release/` | 发布分支前缀;远端该前缀下名字最大的分支即当期发布点 |
|
||
| | `jenkinsJob` | 空 | 正式服部署的 Jenkins 任务名;空 = 不显示「部署到正式服」 |
|
||
| | `jenkinsProdHost` | `正式服` | 触发 Jenkins 时 `REMOTE_HOST` 参数的值 |
|
||
| | `conflictResolutionProfilePath` | 空 | 冲突解决会话 profile |
|
||
| | `commitProfilePath` | `deepseek-v4-pro` | 「提交代码」用的 profile;未配置时提交直接失败 |
|
||
| | `prDiffSummaryProfilePath` | `deepseek-v4-pro` | 「改动」说明 / PR 变更摘要用的 profile;未配置时生成失败 |
|
||
| | `codexModel` / `codexReasoningEffort` | 空 | 审查会话的 codex `-c` 覆盖;空 = 用 codex 自己的 config |
|
||
| 网络 | `webhookPort` | `17421` | 本机 webhook 端口 |
|
||
| | `webhookSecret` | 空 | 仓库 webhook 的 Secret(GitHub / Gitea 通用,校验 `X-Hub-Signature-256`),空 = 不校验签名 |
|
||
| | `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` | 工单级自动审查开关 |
|
||
| `handoffBundleKey` / `handoffFrom` | 移交中:会话包在 OSS 上的对象 key 与发起人;接管后清空 |
|
||
| `sessionId` / `implementSessionId` / `reviewSessionId` / `testSessionId` | 各会话 id |
|
||
| `profilePath` / `brainstormProfilePath` / `testProfilePath` | 各会话 profile |
|
||
| `worktreePath` / `prDiffFile` | 本机路径 |
|
||
|
||
最后两行(会话 id、profile、路径共 9 个字段)是**本机字段**,只存在 VS Code workspaceState 里,不写进共享评论,所以同一工单在不同机器上可以各自有会话。
|
||
|
||
## 工作区约定
|
||
|
||
```
|
||
.claude/specs/<stem>.md # 设计文档,即工单的 spec marker
|
||
.claude/plans/<stem>.md # 实施计划,即 plan marker
|
||
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 取计划文件名的 stem(`.claude/plans/<stem>.md` 里的 stem),与设计文档同名。
|
||
|
||
## 开发
|
||
|
||
```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 4(webview)、esbuild、Vitest;CLI 为 Go + cobra。
|
||
|
||
## 许可证
|
||
|
||
MIT
|