自己动手
$109 每个平台,一次性付费
WebViewGold 许可证:一个现成的 Xcode 或 Android Studio 项目。粘贴您的 URL,设置名称和图标,开启所需功能,构建并提交。永久免费更新。
在主页查看方案Claude Code
两个小文件就能消除发布中的大部分风险。/release-check 命令让 Claude Code 每次都按同一份清单逐项检查,第一个问题就是这次发布到底需不需要商店构建版本;一个 hook 则会拒绝任何会让 Config.swift 或 Config.java 指向 localhost 的 commit。两者都放在仓库中,所以整个团队和每个云端会话都能用上。
每个平台一次性 $109 起,或由我们的团队全程代劳,$698 起。
自定义命令就是一段保存好的提示词。.claude/commands/release-check.md 这个文件会在该仓库的每个会话中变成 /release-check。Claude Code 已经把命令合并进了技能(skills):位于 .claude/skills/release-check/SKILL.md 的技能会创建同样的命令,还能附带额外文件,而现有的命令文件依然有效。如果只是一份清单,commands 文件夹是最简单的存放位置。
hook(钩子)则完全是另一回事。它是 Claude Code 自身在固定时刻运行的 shell 命令,例如就在某次工具调用之前。模型没有投票权:当 PreToolUse hook 以退出码 2 结束时,这次工具调用就会被阻止,Claude 收到的是您的错误信息。对于那个绝不能到达用户手中的错误,这正是您需要的。
一条实用的规则:指导性内容写进 CLAUDE.md,可重复的流程做成命令,绝对不能发生的事情做成 hook。
保存为 .claude/commands/release-check.md。以 ! 开头的行会在 Claude 看到提示词之前运行,并把输出粘贴进来,所以每次检查都从仓库的真实状态出发。allowed-tools 恰好预先批准检查所需的那些命令,disable-model-invocation 则防止 Claude 自行启动发布检查。
---
description: Pre-release check for the web app and the WebViewGold iOS and Android projects. Starts by deciding whether this release needs a store build.
argument-hint: "[version, for example 1.4.0]"
allowed-tools: Bash(git status *), Bash(git log *), Bash(git describe *), Bash(git diff *), Bash(git ls-files *), Bash(npm run lint), Bash(npm run build), Read, Grep, Glob
disable-model-invocation: true
---
# Release check for version $ARGUMENTS
## Repository state
- Branch and changes: !`git status --short --branch`
- Last release tag (a commit hash if there is no tag yet): !`git describe --tags --abbrev=0 --always`
- Recent commits: !`git log --oneline -20`
## 1. Does this release need a store build?
Run git diff --stat from the last release tag to HEAD. Native changes are files under
native/ios or native/android: Config.swift, Config.java, Info.plist, AndroidManifest.xml,
build.gradle, entitlements, icons and splash images.
- No native changes: report "Web-only release: deploy, no store build needed" and go to step 3.
- Native changes: a new App Store and Google Play build is needed. Continue with step 2.
## 2. Native checks
- Config.swift: host and webviewurl use the production domain over HTTPS.
- Config.java: HOST and HOME_URL match the iOS values.
- Neither file contains localhost, 127.0.0.1, 10.0.2.2, a 192.168.x.x address,
an ngrok or trycloudflare host, or a preview deployment URL.
- iOS: the marketing version is $ARGUMENTS, the build number is higher than the last
uploaded build, and every extension target (for example OneSignalNotificationServiceExtension)
uses the main bundle ID as prefix.
- Android: versionName is $ARGUMENTS and versionCode is higher than the last upload.
Report targetSdk; I will compare it with Google's current requirement.
- Every iOS usage description and every Android permission belongs to a feature we use.
- git ls-files shows no signing material: *.jks, *.keystore, *.p12, *.mobileprovision,
keystore.properties.
## 3. Web app checks
- npm run lint and npm run build pass.
- /privacy, /terms and /delete-account still exist and are linked from settings.
- No new checkout, price or external payment link is visible when isNativeApp() is true.
- No new logging of tokens, email addresses or other personal data.
## Output
One table: check, result (pass, fail, needs me), evidence (file:line or command output).
Then a short list of what I must do by hand: deploy, store uploads, TestFlight,
release notes. Do not fix anything inside this command; I will ask for fixes separately.把这段合并到 .claude/settings.json 中,这是会被提交和共享的项目设置文件(个人调整放在 .claude/settings.local.json 中)。Bash matcher 会在 Claude 想运行的每条 shell 命令之前执行脚本;脚本本身会忽略所有不是 commit 的命令。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/guard-native-config.sh",
"timeout": 30
}
]
}
]
}
}
只要有一个优化良好的Web应用版本,几分钟内您就能拥有一个出色的移动应用。除此之外,客户服务非常友好且乐于助人!我只能说:推荐WebViewGold :-)
保存为 .claude/hooks/guard-native-config.sh 并设为可执行。Claude Code 通过 stdin 以 JSON 形式发送计划中的工具调用;脚本用 jq 读取命令,遇到 commit 时运行共享的检查脚本。退出码 2 会阻止这次 commit,并把 stderr 中的文本交给 Claude,Claude 通常会自行改正 URL。
#!/usr/bin/env bash
# .claude/hooks/guard-native-config.sh
# PreToolUse hook (matcher: Bash). Blocks "git commit" while a staged Config.swift
# or Config.java contains a development URL. Exit 0 = allow, exit 2 = block.
input=$(cat)
cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // empty')
# Not a commit? Allow immediately.
printf '%s' "$cmd" | grep -Eq 'git( -C [^ ]+)? commit' || exit 0
cd "${CLAUDE_PROJECT_DIR:-.}" || exit 0
# "commit -a", "--all" or a "git add" in the same command also commit unstaged
# changes, so check the working tree too.
flag=""
if printf '%s' "$cmd" | grep -Eq 'commit.* (-[a-zA-Z]*a|--all)|git( -C [^ ]+)? add '; then
flag="--include-worktree"
fi
if ! report=$(./scripts/check-native-config.sh $flag 2>&1); then
{
echo "Commit blocked: a native config file points to a development URL."
echo "$report"
echo "Set host and webviewurl (Config.swift) and HOST and HOME_URL (Config.java)"
echo "to the production HTTPS domain, stage the files again and retry the commit."
} >&2
exit 2
fi
exit 0把实际规则放在一个脚本里,让 Claude Code hook 和普通的 Git pre-commit hook 执行同一条规则。保存为 scripts/check-native-config.sh,并设为可执行。10.0.2.2 是 Android 模拟器访问您电脑时用的地址,也是测试后最常见的遗留物。
#!/usr/bin/env bash
# scripts/check-native-config.sh [--include-worktree]
# Exit 1 if a staged Config.swift or Config.java contains a development URL.
# Used by the Claude Code hook and by the Git pre-commit hook.
pattern='localhost|127\.0\.0\.1|0\.0\.0\.0|10\.0\.2\.2|192\.168\.[0-9]+\.[0-9]+|\.ngrok(-free)?\.(app|io|dev)|\.trycloudflare\.com'
# Add the preview hosts you use, for example: |-git-[a-z0-9-]+\.vercel\.app
scan() { # $1 = file, $2 = label; file content on stdin
local hits
hits=$(grep -nE "$pattern" | grep -vE '^[0-9]+:[[:space:]]*(//|\*)')
if [ -n "$hits" ]; then
printf '%s (%s):\n%s\n' "$1" "$2" "$hits"
return 1
fi
}
status=0
for f in $(git diff --cached --name-only --diff-filter=ACMR | grep -E '(^|/)Config\.(swift|java)$'); do
git show ":$f" | scan "$f" "staged" || status=1
done
if [ "$1" = "--include-worktree" ]; then
for f in $(git diff --name-only | grep -E '(^|/)Config\.(swift|java)$'); do
scan "$f" "working tree" < "$f" || status=1
done
fi
exit $status十五分钟,包括一次故意被阻止的 commit。
创建 .claude/commands/release-check.md、.claude/hooks/guard-native-config.sh 和 scripts/check-native-config.sh,然后运行 chmod +x .claude/hooks/guard-native-config.sh scripts/check-native-config.sh。也可以粘贴下方的提示词,让 Claude Code 创建并调整这些文件。
hook 用 jq 解析 JSON(macOS 上用 brew install jq,Debian 或 Ubuntu 上用 sudo apt install jq;云端会话已经预装)。没有 jq,脚本就读不到命令,会放行一切,所以接下来的步骤里包含一次测试。
把这段 JSON 合并到 .claude/settings.json 中,保留已有的设置,然后 commit。在 Claude Code 中运行 /hooks,确认 PreToolUse 条目已经加载。
把 Config.java 中的 HOME_URL 设为 http://10.0.2.2:3000,暂存该文件,然后让 Claude Code 提交。这次 commit 必须被拒绝,并显示您的提示信息。之后恢复生产 URL。
创建 .githooks/pre-commit,写入 #!/usr/bin/env bash 和 exec ./scripts/check-native-config.sh 这两行,设为可执行,并在每个克隆中运行一次 git config core.hooksPath .githooks。这样,来自 Xcode、Android Studio 或终端的 commit 都会碰到同一条规则,Claude 自己的 commit 也一样,而且就在 Git 创建 commit 的那一刻。
每次发布前,输入 /release-check 1.4.0。第一个回答会告诉您,这次发布的是一次部署还是一个商店构建版本;Web 改动与原生改动解释了为什么这个区别对 WebViewGold 应用如此重要。
当您的文件夹结构与示例不同时很有用。Claude 会调整路径,并在保存每个文件之前先给您看。
为这个仓库搭建发布工具。我们的 Web 应用也通过 WebViewGold 发布为 iOS 和 Android 应用;原生项目位于 native/ios 和 native/android(请先检查真实的目录结构,并相应调整)。在写任何内容之前,先找到 Config.swift、Config.java、Info.plist、AndroidManifest.xml 和 app/build.gradle 的实际路径。 1. 创建 .claude/commands/release-check.md:一个带 frontmatter 的发布检查清单命令(description、用于版本号的 argument-hint、只允许只读 git 命令、npm run lint、npm run build、Read、Grep 和 Glob 的 allowed-tools,以及 disable-model-invocation: true)。它必须先判断这次发布是否改动了原生文件、因而需要商店构建版本,然后检查生产 URL、版本号和构建号、权限、被 Git 跟踪的签名文件,以及 /privacy、/terms 和 /delete-account 路由。 2. 创建 scripts/check-native-config.sh:当暂存的 Config.swift 或 Config.java 包含 localhost、127.0.0.1、0.0.0.0、10.0.2.2、192.168.x.x 地址,或者 ngrok、trycloudflare 主机时,以退出码 1 结束。忽略注释行。使用 --include-worktree 时,也检查未暂存的改动。 3. 创建 .claude/hooks/guard-native-config.sh:一个针对 Bash 工具的 PreToolUse hook,用 jq 读取 JSON 输入,忽略 git commit 以外的一切,运行检查脚本(遇到 commit -a、--all 或同一条命令中的 git add 时加上 --include-worktree),检查失败时在 stderr 上输出清晰的信息,并以退出码 2 结束。 4. 在 .claude/settings.json 中注册这个 hook,不要删除任何现有设置。 5. 创建运行同一检查脚本的 .githooks/pre-commit。 把脚本设为可执行,保存前把每个文件都给我看,然后告诉我如何用一个故意写入的 localhost URL 测试这个 hook。
| 规则 | 最佳位置 | 原因 |
|---|---|---|
| 配置文件指向生产环境,绝不指向 localhost | hook 加 Git pre-commit hook | 绝对不能发布出去。一次被阻止的 commit,比用户手中坏掉的应用或被拒的构建版本代价小得多。 |
| 提高版本号和构建号 | /release-check | 需要判断:只有原生发布才需要新的编号,而且上一次上传的构建号并不在仓库里。 |
| 4.2、4.8、5.1.1 和 3.1.1 等商店规则 | CLAUDE.md 加审查子代理 | 编码时给出指导,发布前做严格审查。 |
| Lint 和构建通过 | /release-check 或 CI | 作为每次 commit 都运行的 hook 太慢,非常适合作为清单步骤或必需的状态检查。 |
| 签名文件绝不提交 | .gitignore 加发布检查 | 用 .gitignore 预防,每次发布前用 git ls-files 验证。 |
permissionDecision 设为 deny 的 JSON 回复)才会停止工具调用。退出码 1 只会被报告为 hook 错误,commit 照常进行。.claude/settings.json 和 .claude/hooks/ 的改动;hook 会在每个打开该项目的人的机器上运行。! 行。命令文件中的内联命令需要对应的 allowed-tools 条目。只放简单的只读命令,把管道和逻辑写进指令里,让 Claude 以普通工具调用的方式运行它们。$ARGUMENTS 就是您在命令名后面输入的内容。不带版本号运行 /release-check,检查就没有可比对的对象;argument-hint 正是用来提醒您的。没有,它们被合并进了技能。.claude/commands/ 中的文件依然有效,并会创建同样的 /name 命令。像 .claude/skills/release-check/SKILL.md 这样的技能还能附带支持文件并自动加载;当一个命令超出单个文件时,就改用这种格式。
放在您主目录下的 ~/.claude/commands/ 或 ~/.claude/skills/ 中。它们在您机器上的每个项目中都可用,但不会与团队共享。
它可以改写文件,但悄无声息的改写会掩盖问题。用清晰的信息阻止更安全:Claude 读到信息后会设置生产 URL 并重新提交,而您也能看到发生了什么。
能。云端会话使用仓库中的 .claude/settings.json、命令和技能,而且云端环境已预装 jq。您个人 ~/.claude/settings.json 中的 hook 只留在您自己的机器上。
几乎不会。对于不是 commit 的命令,脚本会立即退出。较新版本的 Claude Code 还支持在 hook 上设置 if 字段,例如 "Bash(git commit *)",这样脚本只会针对匹配的命令启动。
结果相同,只是您需要投入的工作量不同。三种方式都附带审核通过保证和 7×24 小时人工支持。
$109 每个平台,一次性付费
WebViewGold 许可证:一个现成的 Xcode 或 Android Studio 项目。粘贴您的 URL,设置名称和图标,开启所需功能,构建并提交。永久免费更新。
在主页查看方案$349 每个许可证,一次性附加购买
无需 Mac、Xcode 或 Android Studio:在浏览器中完成配置,我们在云端构建两个应用,并将其交付到 App Store Connect 和 Play Console。
Cloud Builder 如何运作 试用免费演示$698 每个平台 $798
把您的 URL 和图标发给我们。我们的团队在 72 小时内完成配置、构建并交付您的应用,白标,附源码项目。两个平台共 $1,158。
Full Service 详情 服务提供方:冬季特惠价格有效期至 2026年12月31日。
App Store & Google Play 审核通过保证 – 否则 14 天内退款
想直接交给我们?Full Service:我们在 72 小时内完成配置、构建并交付,每个平台 $698 起。有疑问?通过 7×24 小时在线聊天联系我们。
退款依据我们 FAQ 中列出的条件:应用因非内容原因被 Apple 和/或 Google 拒审,并在购买后 14 天内提出申请。