当 Codex 学会自己建仓库:一次把 Gitea 初始化流程跑通
写完一个项目,最烦的往往不是代码本身,而是收尾那几步:去 Gitea 手动点“新建仓库”、复制 clone 地址、本地git init、配 remote、写.gitignore、补 README、再小心翼翼地完成第一次 push。步骤不复杂,但碎、重复、容易漏。更麻烦的是,很多团队现在用 Codex 这类 Agent 来辅助开发,如果模型通道和 Git 平台 Token 混在一起,排查起来会非常痛苦。
这篇就围绕一个具体场景展开:用 Codex 的 Skills 机制做一个git-one-click-init技能,让 Agent 按SKILL.md的约定调用init_repo.sh,自动完成 Gitea 建私有库、生成基础文件、初始化本地仓库并首次推送。同时把 Codex 的模型通道接到 TaoToken:打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 注册并创建 Key,Base URL 填https://taotoken.net/api,模型 Key 填 TaoToken Key。注意,Gitea 的api_token仍然要从 Gitea 获取,两者不能混用。
一、原问题与场景:手动建库 + 首次推送为什么总是卡
先还原一下没有 Skill 时的真实流程。假设你在本地写完了一个 Python 小项目,目录叫my-awesome-project,现在要把它放到 Gitea 上:
- 打开浏览器登录 Gitea,点“新建仓库”,填名称、选私有、决定要不要初始化 README。
- 创建成功后复制 clone URL。
- 回到终端,
git init、git add .、git commit -m "init"。 git remote add origin <clone_url>。git push -u origin main,如果默认分支是 master 还要再折腾一次。
单次操作大概两三分钟,但问题在于它反复出现:每开一个新模块、每做一个原型、每拆一个微服务,都要重来一遍。团队里如果还要求统一的.gitignore和 README 结构,靠人记就更容易走样。
Codex 的 Skills 机制正好适合接管这类“工具链编排”工作。技能目录放在~/.codex/skills/下,由SKILL.md描述触发条件、参数和执行步骤,Agent 读到用户意图后调用init_repo.sh。脚本负责检查git、curl、jq,生成.gitignore与 README,调用 Gitea 的/api/v1/user/repos建私有库,解析返回的clone_url,最后完成git init/add/commit/remote/push。
这里有一个容易被忽略的边界:Codex 本身要能跑起来,需要模型通道;而脚本访问 Gitea,需要 Gitea 的 API Token。前者走 TaoToken 的 Base URL 和 Key,后者走 Gitea。把这两件事分开,后面排错会轻松很多。
二、TaoToken 前置:先把 Codex 的模型通道配好
在让 Codex Agent 执行这个消耗 Token 的 Skill 之前,先把模型通道准备好。步骤不复杂:
- 打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 注册账号。
- 进入控制台创建 TaoToken Key,也就是后面要填到 Codex 里的模型 Key。
- 记下 Base URL:
https://taotoken.net/api。注意不要带/v1,也不要用带 UTM 参数的官网地址当接口地址。 - 如果你需要管理多个 Key,可以到 API Keys 页面创建和轮换:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
- 接入文档可以参考:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
如果你更习惯命令行方式,也可以用 CLI 快速接入:
npm i -g @taotoken/taotoken taotoken cc -k YOUR_API_KEY -u https://taotoken.net/api -m MODEL_ID这里的YOUR_API_KEY换成刚创建的 TaoToken Key,MODEL_ID换成你要用的模型 ID。CLI 只是帮你把配置写进去,核心还是 Base URL 和 Key 这两项。
再强调一次边界:TaoToken 在这里只负责 Codex 的模型通道 Key 和 Base URL。init_repo.sh里访问 Gitea 所需的api_token必须从 Gitea 获取,不能用 TaoToken Key 代替。两者混用是后面最常见的报错来源之一。
三、可复制配置:SKILL.md 与 init_repo.sh 的关键片段
技能目录结构保持简单:
skills/ └── git-one-click-init/ ├── SKILL.md └── scripts/ └── init_repo.sh把整个git-one-click-init目录放到~/.codex/skills/下,Codex 就能在需要时读取它。
SKILL.md负责告诉 Agent 什么时候用、需要哪些参数、按什么步骤执行。核心内容可以这样写:
# Git One-Click Init Skill ## Description Automates creating a private Gitea repository and pushing the first commit. ## When to Use - User asks to initialize a new project repository on Gitea. - User provides repo name, owner, and Gitea API token. ## Arguments - repo_name: (Required) repository name - owner: (Required) Gitea user or org - api_token: (Required) Gitea API token with repo scope - project_path: (Optional) local project path, default current dir - language: (Optional) python / nodejs / default ## Steps 1. Validate repo_name, owner, api_token. 2. Run scripts/init_repo.sh with the arguments. 3. On failure, report the error and suggest checking the Gitea token or network. 4. On success, confirm the repository URL and push result.init_repo.sh是真正干活的部分。它需要做几件事:检查依赖、生成.gitignore和 README、调用 Gitea API、解析clone_url、执行 Git 操作。关键片段如下。
依赖检查:
check_dependencies() { local deps=("git" "curl" "jq") for dep in "${deps[@]}"; do if ! command -v "$dep" >/dev/null 2>&1; then log_error "依赖工具 '$dep' 未安装。" fi done log_info "所有依赖工具已就绪。" }调用 Gitea API 建私有库:
create_gitea_repo() { local owner=$1 repo_name=$2 api_token=$3 gitea_host=${4:-"gitea.com"} local api_url="https://$gitea_host/api/v1/user/repos" local json_data="{\"name\":\"$repo_name\",\"private\":true,\"auto_init\":false}" local response http_code body response=$(curl -s -w "\n%{http_code}" -X POST "$api_url" \ -H "Authorization: token $api_token" \ -H "Content-Type: application/json" \ -d "$json_data") http_code=$(echo "$response" | tail -n1) body=$(echo "$response" | sed '$d') if [[ "$http_code" -eq 201 ]]; then log_info "仓库创建成功 (HTTP 201)。" echo "$body" | jq -r '.clone_url' return 0 elif [[ "$http_code" -eq 422 ]]; then log_error "仓库已存在或名称无效: $body" else log_error "创建仓库失败 (HTTP $http_code): $body" fi }Git 初始化与首次推送:
init_git_and_push() { local remote_url=$1 [ -d ".git" ] || git init git add . git commit -m "Initial commit: Auto-generated by git-one-click-init skill" if git remote | grep -q "origin"; then git remote set-url origin "$remote_url" else git remote add origin "$remote_url" fi git push -u origin main || { git branch -M master git push -u origin master } }主流程把参数解析、依赖检查、文件生成、建库、推送串起来:
main() { # 解析 --repo-name / --owner / --api-token / --path / --language check_dependencies generate_gitignore "$language" generate_readme "$repo_name" remote_url=$(create_gitea_repo "$owner" "$repo_name" "$api_token") init_git_and_push "$remote_url" } main "$@"给脚本加执行权限:
chmod +x ~/.codex/skills/git-one-click-init/scripts/init_repo.sh到这里,Codex 侧的模型通道和 Skill 侧的脚本都准备好了。接下来验证整条链路。
四、验证请求与成功结果:看到 HTTP 201 和 push 成功
验证方式很直接:在 Codex 里用自然语言触发这个 Skill。示例指令:
请在 Gitea 上为 my-awesome-project 创建仓库,所有者是 myuser, API Token 是 Gitea 的 token,这是 Python 项目。Agent 会读取SKILL.md,解析出repo_name=my-awesome-project、owner=myuser、api_token=<Gitea token>、language=python,然后调用init_repo.sh。
预期输出大致如下:
[INFO] 所有依赖工具已就绪。 [INFO] 正在生成 .gitignore 文件 (语言: python)... [INFO] 正在生成 README.md 文件... [INFO] 正在联系 Gitea API 创建仓库: myuser/my-awesome-project ... [INFO] 仓库创建成功 (HTTP 201)。 [INFO] 正在初始化本地 Git 仓库... [INFO] 正在提交初始代码... [INFO] 正在推送到远程仓库... [INFO] 代码已成功推送到 https://gitea.com/myuser/my-awesome-project.git [INFO] 项目初始化完成!判断成功的两个关键信号:一是脚本输出HTTP 201,说明 Gitea 侧仓库确实创建成功;二是看到 push 成功并打印出仓库地址。如果只看到建库成功但 push 失败,问题通常在本地 Git 配置或分支名,而不是模型通道。
如果你还想单独验证模型通道是否正常,可以到模型对话页面发一条简单请求:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 。能正常返回,说明 Base URL 和 Key 配置没问题,剩下的问题就集中在 Skill 脚本和 Gitea Token 上。
五、本篇常见错排查:Token 混用、Base URL 写错、依赖缺失
这一类自动化链路出错,往往集中在几个固定位置。按下面顺序排查,基本能覆盖大部分情况。
1. 把 TaoToken Key 当成 Gitea api_token 用
这是最典型的混用。表现是脚本调用 Gitea API 返回 401 或 403。记住:TaoToken Key 只用于 Codex 的模型通道,init_repo.sh里的api_token必须是 Gitea 生成的、带 repo 权限的 Token。
2. Base URL 写成带/v1或带 UTM 的官网地址
Codex 的模型配置里,Base URL 应该是https://taotoken.net/api。不要写成https://taotoken.net/api/v1,也不要把带utm_source的官网地址填进去。写错通常表现为模型请求 404 或无法连接。
3. 缺少jq导致解析 clone_url 失败
脚本用jq -r '.clone_url'解析 Gitea 返回的 JSON。如果系统没装jq,check_dependencies会直接报错退出。安装方式:macOS 用brew install jq,Debian/Ubuntu 用apt-get install jq。
4. 仓库已存在返回 422
Gitea 对同名仓库会返回 422。脚本里已经对 422 做了单独提示。遇到时换一个repo_name,或者先去 Gitea 删除旧仓库。
5. 首次 push 分支名不一致
有的 Gitea 实例默认分支是master,本地git init后默认可能是main。脚本里做了兜底:先试main,失败再git branch -M master重试。如果仍然失败,检查远程仓库是否开启了分支保护。
6. Skill 没有被 Codex 识别
确认git-one-click-init目录确实放在~/.codex/skills/下,且SKILL.md文件名大小写正确。目录层级错了,Agent 读不到技能描述,自然不会触发。
7. 权限问题导致脚本无法执行
chmod +x没做的话,Agent 调用脚本会报 permission denied。补上执行权限即可。
如果排查后确认是接入配置问题,可以到 API Keys 页面重新生成 Key:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite ,并对照接入文档检查 Base URL:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。
六、把这条链路固定下来:统一通道 + 明确边界
回到最初的目标:让 Codex 按SKILL.md调init_repo.sh,完成 Gitea 一键建库和首次推送。整条链路里有两个独立的凭证体系,必须分清楚:
- Codex 的模型通道:Base URL 填
https://taotoken.net/api,Key 填 TaoToken Key。从 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 拿到 Key 后配置即可。 - Gitea 的 API 访问:
api_token从 Gitea 获取,带 repo 权限,只用于/api/v1/user/repos调用。
把这两者分开之后,git-one-click-init这个 Skill 就能稳定运行:Agent 负责理解意图和编排,脚本负责建库、生成文件、初始化和推送。每次新项目初始化从几分钟压缩到几秒,而且.gitignore和 README 结构保持一致。
如果你后续要做长期编码或 Agent 类工作流,可以考虑 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。如果只是先验证模型通道,模型对话页面就够用:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 。需要管理多个 Key 时,API Keys 页面在这里:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。
搜索:Codex Skills Gitea 一键建库、Codex init_repo.sh、Gitea API 创建私有仓库、Codex Base URL 配置、TaoToken API 接入