Files
teamai-cli/.github/PULL_REQUEST_TEMPLATE.md
T
jeffyxu 547f9e225e feat: 适配 GitHub 开源 - 双 provider + 双渠道发布 (merge request !156)
Squash merge branch 'feat/github-adapt' into 'master'
## 目标

让 `teamai-cli` 同时支持 **GitHub** 和腾讯工蜂(TGit)两种 git provider,并支持双渠道发布到公网 npm (`teamai-cli`) 和内网 tnpm (`@tencent/teamai-cli`)。

## 主要改动

### 1. Provider 抽象
- 新增 `src/providers/github/` 完整实现 GitHubProvider
  - `gh-cli.ts` 支持 `gh` CLI 和 `GITHUB_TOKEN` 两种认证
  - `createRepo` 通过 REST API (`/user/repos` 或 `/orgs/:org/repos`)
  - `createPullRequest` 优先用 gh CLI,fallback 到 REST API
- `registry.ts` 注册 GitHubProvider,bare `owner/repo` 默认改为 github
- `createPullRequest` 接口改为 `Promise<string>`(GitHub REST 异步需要)

### 2. 发布配置
- 主包名改为 `teamai-cli`(公网 npm)
- 删除 `publishConfig.registry`,改由 workflow 控制
- `src/update.ts` 从 `package.json` 动态读包名,按 `@tencent/` 前缀切换 tnpm vs 公网 npm;支持 `TEAMAI_NPM_REGISTRY` 环境变量覆盖
- `.coding-ci.yaml` 发布前用 `npm pkg set name` 改名为 `@tencent/teamai-cli` 再发 tnpm,保留内网镜像包能力
- `package.json` `files` 字段排除 source map,包体积 275KB → 105KB

### 3. CI
- 新增 `.github/workflows/ci.yml`(Node 20/22 × ubuntu/macos 矩阵 + 可选 e2e job)
- 新增 `.github/workflows/release.yml`(tag `v*.*.*` 触发发布到公网 npm)
- 保留 `.coding-ci.yaml` 给腾讯 Coding CI 继续发 tnpm

### 4. 测试
- 新增 30 个 GitHub provider 单元测试,覆盖 URL 解析、token 解析、clone、createRepo、createPR(CLI + API fallback)
- `init.test.ts` TGit 专用用例改用完整 URL,避免被新 github 默认拦截
- `e2e.test.ts` 通过 `TEAMAI_TEST_PROVIDER` 支持 GitHub clone

### 5. 文档 + 开源标配
- README 改开源视角(公网 npm 为主,tnpm 收进折叠块)
- 新增 `docs/providers.md` 详细说明 GitHub / TGit 两个 provider 的差异与认证
- 更新 `CLAUDE.md` 说明双包策略
- 新增 `LICENSE`(MIT)
- 新增 `.github/CONTRIBUTING.md` / PR 模板 / 2 个 issue 模板
- `.gitignore` 增加 `.npmrc` / `.env`

### 6. 其他
- `src/source.ts` 订阅源名字推断改为通用 URL 解析,兼容 github.com 等
- `package.json` 新增 `homepage` / `bugs` / `author` email 字段

## 修复(来自 e2e 测试反馈)

最后一个 commit `9b98edd` 修了端到端测试发现的 3 个 GitHub provider 回归 bug:

| # | 文件 | 问题 | 修复 |
|---|------|------|------|
| 1 | `src/doctor.ts` | 不识别 project scope 配置,永远读 `~/.teamai/config.yaml`,导致 GitHub 项目下 doctor 把 provider 误判为 tgit,触发 "gf CLI is installed/authenticated" 错误检查 | 改用 `detectProjectConfig() ?? loadLocalConfig()` 模式,配置路径标签改为实际路径 |
| 2 | `src/utils/git.ts` + `src/push.ts` + `src/team-push.ts` + `src/roles-cmd.ts` | `master` 分支硬编码 5+ 处。GitHub 默认 `main` 仓 push 100% 失败,PR 创建报 `Base ref must be a branch / No commits between master and...` | 新增 `getDefaultBranch(localPath)` helper(优先 `origin/HEAD`,其次试 `origin/main` → `origin/master`,兜底 `main`),所有调用点统一动态解析。结果按 `localPath` 缓存避免重复 git 调用 |
| 3 | `src/source.ts` | `source add` 直接 `git.clone(source.repo, ...)`,对 owner/repo 短格式或私有 GitHub 仓都会失败 | 改为 `detectProvider() → provider.cloneRepo()`,复用主仓 clone 同一套认证逻辑 |

测试侧同步:
- `git.test.ts` 改造 6 个用例使用参数感知的 revparse mock,新增 1 个 "默认分支为 main" 用例
- `doctor.test.ts` 补 `detectProjectConfig` 的 mock 默认值

## 兼容性

- 现网存量用户的 `teamai.yaml` 里 `provider: tgit` 会继续走 TGit 路径,零影响
- tnpm 包 `@tencent/teamai-cli` 继续发布,腾讯内部用户安装命令不变
- 只有全新 init 且传 bare `owner/repo` 短格式时默认走 github(原来默认 tgit)

## 验证

### 自动化
- `npx tsc --noEmit` — 0 错误
- `npx vitest run` — **834 passed**
- `npm run build` — 成功

### 端到端测试 (人工)

测试环境(完全隔离,零污染本机 ~/.teamai):
```bash
# 1. 打公网包 + 装到隔离 prefix
npm pack
mkdir -p /tmp/teamai-test-install && cd /tmp/teamai-test-install
npm install --no-save /path/to/teamai-cli-0.14.3.tgz
TBIN=/tmp/teamai-test-install/node_modules/.bin/teamai

# 2. 创建 GitHub 私有测试仓
gh repo create hsuchifeng/teamai-cli-test --private --add-readme

# 3. 沙盒目录 + project scope(隔离的关键)
mkdir -p /tmp/teamai-gh-e2e && cd /tmp/teamai-gh-e2e
git init && echo "# sandbox" > README.md && git add . && git commit -m initial

# 4. init(核心:测试 provider 识别 + clone + 注册 member + push main)
$TBIN init --scope project --repo hsuchifeng/teamai-cli-test

# 5. 跑通 14+ 个命令(详见下表)
```

| 命令 | 结果 | 备注 |
|------|------|------|
| `init` | ✅ | provider 自动识别 github,gh CLI 认证,clone + 默认 teamai.yaml + member 注册 + push main |
| `status` / `list` / `members` | ✅ | 读类命令正确显示 project scope |
| `doctor` | ✅ (修 bug 1 后) | 正确识别 GitHub provider,不再误检 gf |
| `push --all` | ✅ (修 bug 2 后) | 创建真实 GitHub PR #1 base=main |
| `pull` | ✅ | 双 scope 同步:user(TGit 78 skills) + project(GitHub 1 skill) |
| `env add/list` + push | ✅ | 创建 GitHub PR #2 |
| `tags add/list/subscribe` | ✅ | 标签管理正常 |
| `source add/list/browse/remove` | ✅ (修 bug 3 后) | GitHub 跨团队订阅 |
| `remove --dry-run` | ✅ | 预览正常;交互模式按设计 cancel |
| `stats` / `digest` / `recall` / `contribute` / `save-session` | ✅ | help 与基本流程通过 |
| `update --check` | ✅ | 正确去 `https://registry.npmjs.org` 查 `teamai-cli`(404 因未发布,验证双 registry 切换) |
| `uninstall --force` | ✅ (有越权 bug,见下方 follow-up B) | 沙盒清理成功 |

测试产物:GitHub 仓 [hsuchifeng/teamai-cli-test](https://github.com/hsuchifeng/teamai-cli-test) PR #1 #2 已 merge,commits 完整保留作为证据。

## 后续待补(不阻塞本次合入)

发布相关:
- [ ] 公网 npm 账号注册 + 首次 `npm publish` 占坑(包名 `teamai-cli` 已确认可用)
- [ ] 生成 npm Automation token 填到 GitHub Secrets `NPM_TOKEN` 供 `release.yml` 使用
- [ ] 确认最终开源 org(当前占位 `github.com/Tencent/teamai-cli`,可一行改)
- [ ] 腾讯开源审批流程(push 到 `github.com/Tencent` 前置)
- [ ] CLA-assistant 集成(接受外部贡献者前)

已知小问题(e2e 测试发现,未在本次修):
- [ ] **A. token 写进 git remote URL** — `gh repo clone` 默认把 `gho_...` token 拼进 origin 的 https URL,建议 clone 完成后 sanitize remote
- [ ] **B. uninstall 越权** — `--force` 在 project scope 下会清理 `~/.zshrc` 里 user 级的 env 注入块(应只清当前 scope 的 sentinel)
- [ ] **C. roles init / tags add 等 admin 操作未自动 push** — 当前需手动 `teamai push`,符合现有设计但首次用户体验不够顺滑
2026-04-19 12:33:43 +00:00

842 B

Summary

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature causing existing behavior to change)
  • Documentation only
  • Refactor / internal cleanup

Test Plan

  • npx tsc --noEmit passes
  • npx vitest run passes
  • Added/updated tests for the change

Notes for Reviewers