---
name: chinese-indie-dev
description: >
  处理 1c7/chinese-independent-developer 仓库的项目提交。
  检查 issue #160 新评论、新开的 Issue、新开的 PR，
  将有效项目添加到对应 README，关闭垃圾内容。
  当用户说"处理提交"、"处理 issue"、"跑一下列表"时使用。
metadata:
  author: 1c7
  version: "1.5"
  lang: zh-CN
allowed-tools:
  - Bash
  - Read
  - Edit
  - Write
---

# 中国独立开发者列表：处理项目提交

你的任务是处理 GitHub 仓库 `1c7/chinese-independent-developer` 的项目提交。
检查最近的新评论、新 Issue、新 PR，将有效项目添加到对应 README，关闭垃圾内容。

⚠️ 严格禁止：不得调用添加 reaction 的 API。

⚠️ 严格禁止：不得以任何理由删除或修改 README 中已有的条目。本 skill 的唯一允许操作是**新增**。如果发现疑似重复，只需跳过，绝对不能删除。

⚠️ 关于评论签名（"Generated by Claude Code"）：GitHub 会在通过 API 创建的评论正文末尾自动追加这段签名，本 skill 里每处发评论都要求 POST 后立即 PATCH 覆写去掉它。**这一步不是可选的，也不允许因为已经写了 PATCH 命令就假设它一定生效**——历史运行中出现过 PATCH 没有真正执行、签名遗留在评论里的情况（例如 issue #160 的 4886068668 号评论）。所以每次 PATCH 之后，必须再用 `gh api repos/1c7/chinese-independent-developer/issues/comments/<ID>` GET 一次该评论，用 `jq -r .body` 确认返回内容里不再包含 "Generated by" 字样；如果仍然包含，重新 PATCH 并再验证一次，最多重试 3 次。**不允许在没有验证通过的情况下就认为这一步已完成。**

⚠️ 关于用户名旁边的 "with Claude" 标记：这是 GitHub 基于「哪个 GitHub App 完成了这次 API 调用」自动显示的归属标记（`performed_via_github_app`），和评论正文内容无关，无法通过修改 PATCH 后的 body 去掉。这套自动化现在已经通过 1c7 账号自己的 Personal Access Token 认证（在 Routine 的初始化步骤里 `gh auth login --with-token`），不再挂靠 claude.ai 的 GitHub Connector/官方 "Claude" GitHub App。

⚠️ 严格禁止：本 skill 涉及的所有 GitHub 操作（发评论、开关 issue、合并/关闭 PR、改 reaction 等）**只能通过 Bash 里的 `gh` / `git` 命令行执行**，绝对不能使用任何 GitHub 连接器（Connector）或平台自带的原生 GitHub 工具（例如各种 `add_issue_comment`、`merge_pull_request`、`create_pull_request` 之类的内置工具）去完成，哪怕当前环境里这些工具可用。原因：这些内置工具走的是 claude.ai 官方 "Claude" GitHub App 的身份认证，会导致评论重新出现无法去除的 "with Claude" 标记，且不受本 skill 里 PATCH 去签名逻辑的控制。如果发现当前环境里除 Bash/Read/Edit/Write 之外还暴露了 GitHub 相关工具，直接忽略它们，改用 `gh api` / `gh pr` / `gh issue` 等命令行等价操作。

---

## 预检：快速判断是否有任何新内容

**在做任何实质处理之前**，先并行运行以下三条命令，统计各自的结果数量：

```bash
SINCE=$(date -u -d '7 hours ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-7H +%Y-%m-%dT%H:%M:%SZ)

# 检查一：#160 新评论数
COUNT_COMMENTS=$(gh api "repos/1c7/chinese-independent-developer/issues/160/comments?since=$SINCE&per_page=100" | jq 'length')

# 检查二：新 Issue 数
COUNT_ISSUES=$(gh api "repos/1c7/chinese-independent-developer/issues?state=open&per_page=50" \
  | jq --arg since "$SINCE" '[.[] | select(.number != 160 and .pull_request == null and .created_at >= $since)] | length')

# 检查三：待处理 PR 数（排除 auto-add- 分支）
COUNT_PRS=$(gh api "repos/1c7/chinese-independent-developer/pulls?state=open&per_page=50" \
  | jq '[.[] | select(.head.ref | startswith("auto-add-") | not)] | length')

echo "新评论: $COUNT_COMMENTS  新Issue: $COUNT_ISSUES  待处理PR: $COUNT_PRS"
```

如果三个数字**全部为 0**，立即输出「无新内容，本次运行结束」，然后**停止，不再执行后续任何步骤**。

只要有任意一个数字 > 0，才继续向下执行。

---

## 检查一：issue #160 的新评论

获取最近 7 小时内的评论（每 6 小时运行一次，留 1 小时余量）：

```bash
SINCE=$(date -u -d '7 hours ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-7H +%Y-%m-%dT%H:%M:%SZ)
gh api "repos/1c7/chinese-independent-developer/issues/160/comments?since=$SINCE&per_page=100"
```

对每条评论，从内容中提取产品 URL，检查是否已在任意 README 中：

```bash
grep -rF "<产品完整URL>" README.md pages/README-Programmer-Edition.md pages/README-Game.md
```

⚠️ 去重规则（必须严格遵守）：
- 必须用产品的**完整 URL**（如 `https://example.com`）做精确字符串匹配，使用 `grep -F`（固定字符串，非正则）
- 禁止用产品名称、描述文字或部分关键词判断重复——描述里提到某个工具名不等于该工具已在列表中
- URL 已存在 → 跳过，对 README 不做任何操作
- URL 不存在 → 进入「通用处理流程」
- 当前运行中已通过 PR 合并的条目，视为已存在，不再重复处理

处理完所有检查一的评论后，记录所有成功处理的评论作者用户名（用于最后一步发感谢评论到 #160）。

---

## 检查二：最近 7 小时内开启的新 Issue（非 #160）

```bash
SINCE=$(date -u -d '7 hours ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-7H +%Y-%m-%dT%H:%M:%SZ)
gh api "repos/1c7/chinese-independent-developer/issues?state=open&per_page=50" \
  | jq --arg since "$SINCE" \
    '[.[] | select(.number != 160 and .pull_request == null and .created_at >= $since)]'
```

判断每个 Issue：
- **有效项目提交**（含产品名 + 可访问 URL）→ 进入「通用处理流程」，完成后：
  1. 在**该 issue 本身**（不是 #160！）发感谢评论，立即捕获 ID 并 PATCH 去掉自动追加的署名：
     ```bash
     CLEAN_BODY="@<提交者用户名> 感谢提交，已添加！"
     COMMENT_RESPONSE=$(gh api repos/1c7/chinese-independent-developer/issues/<number>/comments \
       -X POST -f body="$CLEAN_BODY")
     COMMENT_ID=$(echo "$COMMENT_RESPONSE" | jq -r '.id')
     gh api --method PATCH \
       repos/1c7/chinese-independent-developer/issues/comments/$COMMENT_ID \
       -f body="$CLEAN_BODY"
     ```
  3. 关闭 issue：`gh issue close <number>`
- **垃圾广告、无关内容、内容不清晰** → 直接关闭：`gh issue close <number>`

检查二的提交者不需要在最后一步中 @ 到 #160，他们已在各自的 issue 里收到了感谢。

---

## 检查三：所有未关闭的 PR（排除 auto-add- 分支）

直接获取所有 open 状态的 PR（不限时间，确保不遗漏）：

```bash
gh api "repos/1c7/chinese-independent-developer/pulls?state=open&per_page=50" \
  | jq '[.[] | select(.head.ref | startswith("auto-add-") | not)]'
```

判断每个 PR：
- **有效项目提交**（对 README 的修改，含产品名 + URL）→ 直接合并：
  ```bash
  gh pr merge <number> --squash --yes
  ```
  - 如果合并成功：在该 PR 发感谢评论，立即捕获 ID 并 PATCH 去掉署名：
    ```bash
    CLEAN_BODY="@<提交者用户名> 感谢提交，已合并！"
    PR_COMMENT_RESPONSE=$(gh api repos/1c7/chinese-independent-developer/issues/<number>/comments \
      -X POST -f body="$CLEAN_BODY")
    PR_COMMENT_ID=$(echo "$PR_COMMENT_RESPONSE" | jq -r '.id')
    gh api --method PATCH \
      repos/1c7/chinese-independent-developer/issues/comments/$PR_COMMENT_ID \
      -f body="$CLEAN_BODY"
    ```
  - 如果合并失败（如 merge conflict）：**由我们自己解决冲突并合并，绝不要求提交者 rebase**。步骤：
    1. 拉取 PR 分支到本地并尝试合并进 master：
       ```bash
       git fetch origin master
       git fetch origin pull/<number>/head:pr-<number>
       git checkout master && git reset --hard origin/master
       git merge pr-<number> --no-ff -m "合并 PR #<number>：<项目名>"
       ```
    2. 如果出现冲突：冲突几乎必然是 README 里同一个日期区块被多个 PR 同时插入条目导致的。**手动编辑冲突文件**，保留双方新增的条目（不要删除任何一方已有的行），冲突标记全部清理干净，然后：
       ```bash
       git add <冲突文件>
       git commit --no-edit
       ```
    3. 校验 README 格式无误后推送：
       ```bash
       git push origin master
       ```
    4. 因为贡献者的分支落后于 master、GitHub 无法用按钮直接标记该 PR 为 merged，所以改为关闭 PR 并说明已手动合并、保留致谢：
       ```bash
       CLEAN_BODY="@<提交者用户名> 感谢提交，PR 有冲突，已由我们手动合并，内容已生效，谢谢！"
       gh pr close <number> --comment "$CLEAN_BODY"
       ```
    5. 如果冲突内容复杂到无法安全判断该保留什么（例如冲突不只是新增条目，而是修改了已有内容的结构），**不要瞎猜、不要删除任何已有内容**，改为在 PR 里说明具体冲突原因并保持 PR 打开，等待人工介入；但这应是极少数情况，绝大多数「新增条目」型冲突都应该自动解决。
  - **不允许**的做法：连续多次发送「请 rebase / 请解决冲突后重新提交」这类要求人类提交者自己解决冲突的评论。冲突处理是我们的责任，不是提交者的。
- **垃圾广告、无关内容** → 直接关闭：`gh pr close <number>`

⚠️ 严格禁止：检查三的 PR **无冲突时**必须走上面的 `gh pr merge --squash`，不能走通用处理流程（那样会丢失贡献者的 git 归属）。**有冲突时**才使用上面的本地合并步骤，因为 `git merge --no-ff` 会保留贡献者原始 commit 的作者信息，不会丢失归属。

---

## 通用处理流程（适用于检查一和检查二）

### 步骤1：提取信息并格式化

从原始内容智能提取，整理为标准格式。提交格式千奇百怪，需灵活判断：

**必须有（缺则归入拒绝类）：**
- 制作者名字：用户没写则用其 GitHub 用户名代替
- 产品名称 + 可访问的产品 URL（http/https 开头）+ 一句话描述

**可选（有则填，无则略去）：**
- 城市、GitHub 链接、博客链接、更多介绍链接

**标准输出格式：**
```
#### 制作者名字(城市) - [Github](url)
* :white_check_mark: [产品名](url)：一句话描述 - [更多介绍](url)
```

**格式规范：**
- 日期区块标题用北京时间：`TZ=Asia/Shanghai date +"%Y 年 %-m 月 %-d 号添加"`
- 描述末尾不加句号
- 去掉「高效、简洁、强大、快速、好用、一款、一个」等营销废话；「免费」若是核心特征则保留
- 产品名称提升到最前面
- 严禁使用加粗格式（不要用 **）

### 步骤2：分类

| 类别 | 判断标准 | 目标文件 |
|------|---------|----------|
| 主版面 | 打开即用的网站或 App，非游戏 | README.md |
| 程序员版面 | 需要命令行/写代码/安装依赖 | pages/README-Programmer-Edition.md |
| 游戏版面 | 任何游戏类产品 | pages/README-Game.md |
| 拒绝 | 论坛、无 URL、垃圾广告、无法判断 | 不处理 |

### 步骤3：插入文件并批量提交到 master

先用 Read 工具读取目标 README 了解格式，用 Edit 工具插入条目。**新条目插入当天日期区块的最顶部**（紧接日期标题行之后的空行后面）。

如果当天日期区块尚不存在，则在最新日期区块之前新建。

**所有项目的文件修改全部做完后**，统一一次性提交推送到 master：

```bash
git checkout master && git pull origin master
# （用 Edit 工具对各 README 文件做完所有修改）
git add README.md pages/README-Programmer-Edition.md pages/README-Game.md
git commit -m "新增：<项目1名>、<项目2名>、..."
git push origin master
```

- 不建分支，不开 PR，直接推 master
- 所有项目合为一条 commit，commit message 列出所有项目名
- 如果本次没有任何有效项目，跳过 git 操作

---

## 最后一步：发感谢评论并删除 Claude 署名（仅针对检查一的提交者）

所有三个检查都处理完之后，如果检查一中成功合并了至少一个项目，在 issue #160 发一条感谢评论，一次性 @ 所有**来自检查一**的成功处理的提交者：

```bash
gh api repos/1c7/chinese-independent-developer/issues/160/comments \
  -X POST -f body="@user1 @user2 感谢提交，已添加！"
```

- 只发一条，不要逐人发多条
- 检查二的提交者不要 @ 到这里（他们已在各自的 issue 里收到了感谢）
- 如果检查一没有成功处理任何项目，不发评论

Claude Code 会自动在正文末尾追加署名，必须 POST 后立即 PATCH 覆写。用以下模式，把 POST 和 PATCH 写在同一个代码块里确保 ID 被捕获：

```bash
CLEAN_BODY="@user1 @user2 感谢提交，已添加！"
COMMENT_RESPONSE=$(gh api repos/1c7/chinese-independent-developer/issues/160/comments \
  -X POST -f body="$CLEAN_BODY")
COMMENT_ID=$(echo "$COMMENT_RESPONSE" | jq -r '.id')
gh api --method PATCH \
  repos/1c7/chinese-independent-developer/issues/comments/$COMMENT_ID \
  -f body="$CLEAN_BODY"
```

---

## 注意事项

- 幂等性靠 URL grep 检查保证，不依赖 reaction 标记
- 所有文件修改完成后统一一次 commit 推 master，不建分支、不开 PR
- 三个检查都没有新内容时，直接结束
