feat(skills): add browser control installer skill
This commit is contained in:
parent
447b57e46a
commit
ac038867d2
45
.claude/skills/install-browser-control/SKILL.md
Normal file
45
.claude/skills/install-browser-control/SKILL.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
name: install-browser-control
|
||||||
|
description: 在新 Mac 上为 Codex 和 Claude 全局安装或整理真实 Chrome/Chromium 调试能力时使用;适用于需要 connect-chrome、browse、setup-browser-cookies 三个入口、可见浏览器接管、DOM 操作、network/console 检查与 cookie 导入支持的场景。
|
||||||
|
---
|
||||||
|
|
||||||
|
# Install Browser Control
|
||||||
|
|
||||||
|
当用户要求在新机器上把浏览器接管调试能力装完整时,直接执行本 skill。
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
- 自动识别 `CODEX_HOME`,默认回退到 `~/.codex`
|
||||||
|
- 在 Codex / Claude 两侧全局目录补齐或标准化:
|
||||||
|
- `connect-chrome`
|
||||||
|
- `browse`
|
||||||
|
- `setup-browser-cookies`
|
||||||
|
- 优先复用现有等价能力;缺失时从公开官方来源安装
|
||||||
|
- 生成本地说明文件:`$CODEX_HOME/browser-control-setup.md`
|
||||||
|
- 做真实验证:可见 Chromium 窗口、`https://example.com`、DOM 读取、network/console、cookie 导入入口调用
|
||||||
|
|
||||||
|
## 执行
|
||||||
|
|
||||||
|
先运行安装脚本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
bash "$SCRIPT_DIR/install-browser-control.sh"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 交付
|
||||||
|
|
||||||
|
安装脚本结束后,读取并引用:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
|
||||||
|
sed -n '1,240p' "$CODEX_HOME/browser-control-setup.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
汇报时只保留高信号结果:
|
||||||
|
|
||||||
|
- 是否安装完成
|
||||||
|
- 3 个入口的最终路径
|
||||||
|
- 本地说明文件路径
|
||||||
|
- 实际验证结果
|
||||||
|
- 如果未完成,唯一阻塞点
|
||||||
433
.claude/skills/install-browser-control/install-browser-control.sh
Executable file
433
.claude/skills/install-browser-control/install-browser-control.sh
Executable file
@ -0,0 +1,433 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
|
||||||
|
CLAUDE_HOME="${CLAUDE_HOME:-$HOME/.claude}"
|
||||||
|
GSTACK_REPO_URL="${GSTACK_REPO_URL:-https://github.com/garrytan/gstack.git}"
|
||||||
|
VERIFY_URL="${VERIFY_URL:-https://example.com}"
|
||||||
|
SETUP_DOC="$CODEX_HOME/browser-control-setup.md"
|
||||||
|
|
||||||
|
TMP_DIR="$(mktemp -d)"
|
||||||
|
cleanup() {
|
||||||
|
rm -rf "$TMP_DIR"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
log() {
|
||||||
|
printf '[install-browser-control] %s\n' "$*" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
printf '[install-browser-control] ERROR: %s\n' "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_macos() {
|
||||||
|
local os_name
|
||||||
|
os_name="$(uname -s)"
|
||||||
|
if [[ "$os_name" != "Darwin" ]]; then
|
||||||
|
fail "当前脚本仅支持 macOS,检测到: $os_name"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_dir() {
|
||||||
|
mkdir -p "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_codex_install() {
|
||||||
|
if command -v codex >/dev/null 2>&1; then
|
||||||
|
command -v codex
|
||||||
|
else
|
||||||
|
printf 'not-found'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_claude_install() {
|
||||||
|
if command -v claude >/dev/null 2>&1; then
|
||||||
|
command -v claude
|
||||||
|
else
|
||||||
|
printf 'not-found'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
have_equivalent_gstack() {
|
||||||
|
local target="$1"
|
||||||
|
[[ -f "$target/connect-chrome/SKILL.md" ]] \
|
||||||
|
&& [[ -f "$target/setup-browser-cookies/SKILL.md" ]] \
|
||||||
|
&& [[ -f "$target/browse/src/cli.ts" || -x "$target/browse/dist/browse" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
clone_seed() {
|
||||||
|
local seed_dir="$TMP_DIR/gstack-seed"
|
||||||
|
if [[ -d "$seed_dir" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
log "cloning gstack from $GSTACK_REPO_URL"
|
||||||
|
git clone --depth 1 "$GSTACK_REPO_URL" "$seed_dir" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_path() {
|
||||||
|
local path="$1"
|
||||||
|
if [[ -e "$path" ]]; then
|
||||||
|
mv "$path" "$path.local.bak.$(date +%Y%m%d%H%M%S)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_gstack_home() {
|
||||||
|
local home_root="$1"
|
||||||
|
local target="$home_root/skills/gstack"
|
||||||
|
|
||||||
|
ensure_dir "$home_root/skills"
|
||||||
|
|
||||||
|
if have_equivalent_gstack "$target"; then
|
||||||
|
printf '%s' "$target"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e "$target" ]]; then
|
||||||
|
backup_path "$target"
|
||||||
|
fi
|
||||||
|
|
||||||
|
clone_seed
|
||||||
|
cp -R "$TMP_DIR/gstack-seed" "$target"
|
||||||
|
printf '%s' "$target"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_bun() {
|
||||||
|
if command -v bun >/dev/null 2>&1; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v brew >/dev/null 2>&1; then
|
||||||
|
log "installing bun with Homebrew"
|
||||||
|
brew install bun >/dev/null
|
||||||
|
else
|
||||||
|
log "installing bun from bun.sh"
|
||||||
|
curl -fsSL https://bun.sh/install | bash >/dev/null
|
||||||
|
export BUN_INSTALL="${BUN_INSTALL:-$HOME/.bun}"
|
||||||
|
export PATH="$BUN_INSTALL/bin:$PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
command -v bun >/dev/null 2>&1 || fail "bun 安装失败"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_browse_runtime() {
|
||||||
|
local gstack_root="$1"
|
||||||
|
local browse_bin="$gstack_root/browse/dist/browse"
|
||||||
|
|
||||||
|
if [[ ! -x "$browse_bin" ]]; then
|
||||||
|
ensure_bun
|
||||||
|
log "building browse binary in $gstack_root"
|
||||||
|
(
|
||||||
|
cd "$gstack_root"
|
||||||
|
bun install >/dev/null
|
||||||
|
bun run build >/dev/null
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -x "$browse_bin" ]] || fail "browse binary 不可用: $browse_bin"
|
||||||
|
|
||||||
|
ensure_bun
|
||||||
|
log "ensuring Playwright Chromium runtime"
|
||||||
|
(
|
||||||
|
cd "$gstack_root"
|
||||||
|
bunx playwright install chromium >/dev/null 2>&1 || true
|
||||||
|
)
|
||||||
|
|
||||||
|
printf '%s' "$browse_bin"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_skill_entry() {
|
||||||
|
local home_root="$1"
|
||||||
|
local skill_name="$2"
|
||||||
|
local dest="$home_root/skills/$skill_name"
|
||||||
|
|
||||||
|
if [[ -L "$dest" ]]; then
|
||||||
|
printf '%s' "$dest"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$dest/SKILL.md" ]] && grep -q "^name: $skill_name\$" "$dest/SKILL.md"; then
|
||||||
|
printf '%s' "$dest"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e "$dest" ]]; then
|
||||||
|
backup_path "$dest"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ln -sfn "gstack/$skill_name" "$dest"
|
||||||
|
printf '%s' "$dest"
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_browser_apps() {
|
||||||
|
local apps=()
|
||||||
|
[[ -d "/Applications/Google Chrome.app" ]] && apps+=("Google Chrome")
|
||||||
|
[[ -d "/Applications/Chromium.app" ]] && apps+=("Chromium")
|
||||||
|
[[ -d "/Applications/Microsoft Edge.app" ]] && apps+=("Microsoft Edge")
|
||||||
|
[[ -d "/Applications/Brave Browser.app" ]] && apps+=("Brave Browser")
|
||||||
|
[[ -d "/Applications/Arc.app" ]] && apps+=("Arc")
|
||||||
|
|
||||||
|
if [[ ${#apps[@]} -eq 0 ]]; then
|
||||||
|
printf 'none-detected'
|
||||||
|
else
|
||||||
|
local joined=""
|
||||||
|
local app
|
||||||
|
for app in "${apps[@]}"; do
|
||||||
|
if [[ -n "$joined" ]]; then
|
||||||
|
joined+=", "
|
||||||
|
fi
|
||||||
|
joined+="$app"
|
||||||
|
done
|
||||||
|
printf '%s' "$joined"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
visible_browser_processes() {
|
||||||
|
/usr/bin/osascript -e 'tell application "System Events" to get the name of every process whose visible is true' 2>/dev/null \
|
||||||
|
| tr ',' '\n' \
|
||||||
|
| sed 's/^ *//' \
|
||||||
|
| grep -E 'Chrome|Chromium' \
|
||||||
|
| paste -sd ', ' - \
|
||||||
|
|| true
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_browser_control() {
|
||||||
|
local browse_bin="$1"
|
||||||
|
local verify_tmp="$TMP_DIR/verify"
|
||||||
|
local connect_out
|
||||||
|
local newtab_out
|
||||||
|
local title_out
|
||||||
|
local heading_out
|
||||||
|
local network_out
|
||||||
|
local console_out
|
||||||
|
local status_out
|
||||||
|
local cookie_out=""
|
||||||
|
local cookie_rc=0
|
||||||
|
local visible_out=""
|
||||||
|
local cookie_status=""
|
||||||
|
|
||||||
|
mkdir -p "$verify_tmp"
|
||||||
|
"$browse_bin" stop >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
"$browse_bin" connect >"$verify_tmp/connect.log" 2>&1
|
||||||
|
sleep 2
|
||||||
|
"$browse_bin" newtab "$VERIFY_URL" >"$verify_tmp/newtab.log" 2>&1
|
||||||
|
"$browse_bin" js 'document.title' >"$verify_tmp/title.log" 2>&1
|
||||||
|
"$browse_bin" text h1 >"$verify_tmp/heading.log" 2>&1
|
||||||
|
"$browse_bin" reload >/dev/null 2>&1 || true
|
||||||
|
"$browse_bin" wait --load >/dev/null 2>&1 || true
|
||||||
|
"$browse_bin" network >"$verify_tmp/network.log" 2>&1
|
||||||
|
"$browse_bin" console >"$verify_tmp/console.log" 2>&1
|
||||||
|
"$browse_bin" status >"$verify_tmp/status.log" 2>&1
|
||||||
|
visible_out="$(visible_browser_processes)"
|
||||||
|
|
||||||
|
"$browse_bin" cookie-import-browser chrome --domain example.com >"$verify_tmp/cookie.log" 2>&1 || cookie_rc=$?
|
||||||
|
|
||||||
|
connect_out="$(cat "$verify_tmp/connect.log")"
|
||||||
|
newtab_out="$(cat "$verify_tmp/newtab.log")"
|
||||||
|
title_out="$(cat "$verify_tmp/title.log")"
|
||||||
|
heading_out="$(cat "$verify_tmp/heading.log")"
|
||||||
|
network_out="$(cat "$verify_tmp/network.log")"
|
||||||
|
console_out="$(cat "$verify_tmp/console.log")"
|
||||||
|
status_out="$(cat "$verify_tmp/status.log")"
|
||||||
|
cookie_out="$(cat "$verify_tmp/cookie.log" 2>/dev/null || true)"
|
||||||
|
|
||||||
|
if [[ $cookie_rc -eq 0 ]]; then
|
||||||
|
cookie_status="callable"
|
||||||
|
elif [[ "$cookie_out" == *"Keychain"* ]]; then
|
||||||
|
cookie_status="callable-requires-keychain-access"
|
||||||
|
elif [[ "$cookie_out" == *"No Chromium browsers found"* ]]; then
|
||||||
|
cookie_status="callable-no-cookie-source-browser"
|
||||||
|
else
|
||||||
|
cookie_status="error"
|
||||||
|
fi
|
||||||
|
|
||||||
|
BROWSE_CONNECT_OUT="$connect_out"
|
||||||
|
BROWSE_NEWTAB_OUT="$newtab_out"
|
||||||
|
BROWSE_TITLE_OUT="$title_out"
|
||||||
|
BROWSE_HEADING_OUT="$heading_out"
|
||||||
|
BROWSE_NETWORK_OUT="$network_out"
|
||||||
|
BROWSE_CONSOLE_OUT="$console_out"
|
||||||
|
BROWSE_STATUS_OUT="$status_out"
|
||||||
|
BROWSE_VISIBLE_OUT="$visible_out"
|
||||||
|
COOKIE_VERIFY_OUT="$cookie_out"
|
||||||
|
COOKIE_VERIFY_STATUS="$cookie_status"
|
||||||
|
}
|
||||||
|
|
||||||
|
write_setup_doc() {
|
||||||
|
local codex_connect="$1"
|
||||||
|
local codex_browse="$2"
|
||||||
|
local codex_cookie="$3"
|
||||||
|
local claude_connect="$4"
|
||||||
|
local claude_browse="$5"
|
||||||
|
local claude_cookie="$6"
|
||||||
|
local codex_gstack="$7"
|
||||||
|
local claude_gstack="$8"
|
||||||
|
local browse_bin="$9"
|
||||||
|
local codex_install="${10}"
|
||||||
|
local claude_install="${11}"
|
||||||
|
local browser_apps="${12}"
|
||||||
|
|
||||||
|
ensure_dir "$CODEX_HOME"
|
||||||
|
|
||||||
|
cat >"$SETUP_DOC" <<EOF
|
||||||
|
# Browser Control Setup
|
||||||
|
|
||||||
|
## 实际安装来源
|
||||||
|
|
||||||
|
- 官方上游:$GSTACK_REPO_URL
|
||||||
|
- Codex 当前 gstack 根目录:$codex_gstack
|
||||||
|
- Claude 当前 gstack 根目录:$claude_gstack
|
||||||
|
- Codex 安装入口:$codex_install
|
||||||
|
- Claude 安装入口:$claude_install
|
||||||
|
- 本机已检测到的系统浏览器:$browser_apps
|
||||||
|
- 运行时浏览器:Playwright Chromium(由 $browse_bin 驱动)
|
||||||
|
|
||||||
|
## 最终技能路径
|
||||||
|
|
||||||
|
### Codex
|
||||||
|
|
||||||
|
- connect-chrome: $codex_connect
|
||||||
|
- browse: $codex_browse
|
||||||
|
- setup-browser-cookies: $codex_cookie
|
||||||
|
|
||||||
|
### Claude
|
||||||
|
|
||||||
|
- connect-chrome: $claude_connect
|
||||||
|
- browse: $claude_browse
|
||||||
|
- setup-browser-cookies: $claude_cookie
|
||||||
|
|
||||||
|
## 如何调用
|
||||||
|
|
||||||
|
### Codex
|
||||||
|
|
||||||
|
- \`connect-chrome\`
|
||||||
|
- \`browse\`
|
||||||
|
- \`setup-browser-cookies\`
|
||||||
|
- \`install-browser-control\`
|
||||||
|
|
||||||
|
### Claude
|
||||||
|
|
||||||
|
- \`/connect-chrome\`
|
||||||
|
- \`/browse\`
|
||||||
|
- \`/setup-browser-cookies\`
|
||||||
|
- \`/install-browser-control\`
|
||||||
|
|
||||||
|
## 如何验证
|
||||||
|
|
||||||
|
1. 运行 \`connect-chrome\`,确认出现 headed Chromium 窗口。
|
||||||
|
2. 运行 \`browse newtab https://example.com\`。
|
||||||
|
3. 运行 \`browse js 'document.title'\` 与 \`browse text h1\`,确认可读取 DOM。
|
||||||
|
4. 运行 \`browse network\` 与 \`browse console\`,确认能读取请求和控制台信息。
|
||||||
|
5. 运行 \`browse cookie-import-browser chrome --domain example.com\`,确认 cookie 导入入口可被调用;首次读取 Chrome Cookie 时,macOS 可能弹出 Keychain 授权框。
|
||||||
|
|
||||||
|
## 本机最近一次真实验证
|
||||||
|
|
||||||
|
### connect
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_CONNECT_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### newtab + DOM
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_NEWTAB_OUT
|
||||||
|
$BROWSE_TITLE_OUT
|
||||||
|
$BROWSE_HEADING_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### network
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_NETWORK_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### console
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_CONSOLE_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### status
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_STATUS_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### visible browser processes
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
${BROWSE_VISIBLE_OUT:-not-detected}
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### cookie import verification
|
||||||
|
|
||||||
|
- status: $COOKIE_VERIFY_STATUS
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$COOKIE_VERIFY_OUT
|
||||||
|
\`\`\`
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local codex_gstack
|
||||||
|
local claude_gstack
|
||||||
|
local browse_bin
|
||||||
|
local claude_browse_bin
|
||||||
|
local codex_connect
|
||||||
|
local codex_browse
|
||||||
|
local codex_cookie
|
||||||
|
local claude_connect
|
||||||
|
local claude_browse
|
||||||
|
local claude_cookie
|
||||||
|
local browser_apps
|
||||||
|
local codex_install
|
||||||
|
local claude_install
|
||||||
|
|
||||||
|
ensure_macos
|
||||||
|
|
||||||
|
codex_install="$(detect_codex_install)"
|
||||||
|
claude_install="$(detect_claude_install)"
|
||||||
|
|
||||||
|
codex_gstack="$(ensure_gstack_home "$CODEX_HOME")"
|
||||||
|
claude_gstack="$(ensure_gstack_home "$CLAUDE_HOME")"
|
||||||
|
browse_bin="$(ensure_browse_runtime "$codex_gstack")"
|
||||||
|
claude_browse_bin="$(ensure_browse_runtime "$claude_gstack")"
|
||||||
|
|
||||||
|
[[ -x "$claude_browse_bin" ]] || fail "Claude browse binary 不可用: $claude_browse_bin"
|
||||||
|
|
||||||
|
codex_connect="$(ensure_skill_entry "$CODEX_HOME" "connect-chrome")"
|
||||||
|
codex_browse="$(ensure_skill_entry "$CODEX_HOME" "browse")"
|
||||||
|
codex_cookie="$(ensure_skill_entry "$CODEX_HOME" "setup-browser-cookies")"
|
||||||
|
|
||||||
|
claude_connect="$(ensure_skill_entry "$CLAUDE_HOME" "connect-chrome")"
|
||||||
|
claude_browse="$(ensure_skill_entry "$CLAUDE_HOME" "browse")"
|
||||||
|
claude_cookie="$(ensure_skill_entry "$CLAUDE_HOME" "setup-browser-cookies")"
|
||||||
|
|
||||||
|
browser_apps="$(detect_browser_apps)"
|
||||||
|
|
||||||
|
verify_browser_control "$browse_bin"
|
||||||
|
|
||||||
|
write_setup_doc \
|
||||||
|
"$codex_connect" "$codex_browse" "$codex_cookie" \
|
||||||
|
"$claude_connect" "$claude_browse" "$claude_cookie" \
|
||||||
|
"$codex_gstack" "$claude_gstack" "$browse_bin" \
|
||||||
|
"$codex_install" "$claude_install" "$browser_apps"
|
||||||
|
|
||||||
|
printf 'DONE\n'
|
||||||
|
printf 'CODEX_HOME=%s\n' "$CODEX_HOME"
|
||||||
|
printf 'CLAUDE_HOME=%s\n' "$CLAUDE_HOME"
|
||||||
|
printf 'SETUP_DOC=%s\n' "$SETUP_DOC"
|
||||||
|
printf 'CODEX_CONNECT=%s\n' "$codex_connect"
|
||||||
|
printf 'CODEX_BROWSE=%s\n' "$codex_browse"
|
||||||
|
printf 'CODEX_COOKIE=%s\n' "$codex_cookie"
|
||||||
|
printf 'CLAUDE_CONNECT=%s\n' "$claude_connect"
|
||||||
|
printf 'CLAUDE_BROWSE=%s\n' "$claude_browse"
|
||||||
|
printf 'CLAUDE_COOKIE=%s\n' "$claude_cookie"
|
||||||
|
printf 'COOKIE_VERIFY_STATUS=%s\n' "$COOKIE_VERIFY_STATUS"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
@ -42,6 +42,7 @@
|
|||||||
- `issue`: 查看当前仓库或任意 Gitea 仓库的 issue 列表和单条详情,支持自动识别 git origin、用户指定仓库和格式化输出。 (file: `./.codex/skills/issue/SKILL.md`)
|
- `issue`: 查看当前仓库或任意 Gitea 仓库的 issue 列表和单条详情,支持自动识别 git origin、用户指定仓库和格式化输出。 (file: `./.codex/skills/issue/SKILL.md`)
|
||||||
- `issue-drive`: 归集证据并把问题拆成 1 到多张 Gitea issue,支持从当前仓库 origin 自动识别仓库或用户显式指定。 (file: `./.codex/skills/issue-drive/SKILL.md`)
|
- `issue-drive`: 归集证据并把问题拆成 1 到多张 Gitea issue,支持从当前仓库 origin 自动识别仓库或用户显式指定。 (file: `./.codex/skills/issue-drive/SKILL.md`)
|
||||||
- `changelog`: 一键发版:生成更新日志 → commit → 打 tag,全流程自动化。 (file: `./.codex/skills/changelog/SKILL.md`)
|
- `changelog`: 一键发版:生成更新日志 → commit → 打 tag,全流程自动化。 (file: `./.codex/skills/changelog/SKILL.md`)
|
||||||
|
- `install-browser-control`: 在新 Mac 上为 Codex 和 Claude 全局安装或整理真实 Chrome/Chromium 调试能力,统一补齐 connect-chrome、browse、setup-browser-cookies 入口并做实机验证。 (file: `./.codex/skills/install-browser-control/SKILL.md`)
|
||||||
|
|
||||||
### How to use skills
|
### How to use skills
|
||||||
|
|
||||||
|
|||||||
45
.codex/skills/install-browser-control/SKILL.md
Normal file
45
.codex/skills/install-browser-control/SKILL.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
name: install-browser-control
|
||||||
|
description: 在新 Mac 上为 Codex 和 Claude 全局安装或整理真实 Chrome/Chromium 调试能力时使用;适用于需要 connect-chrome、browse、setup-browser-cookies 三个入口、可见浏览器接管、DOM 操作、network/console 检查与 cookie 导入支持的场景。
|
||||||
|
---
|
||||||
|
|
||||||
|
# Install Browser Control
|
||||||
|
|
||||||
|
当用户要求在新机器上把浏览器接管调试能力装完整时,直接执行本 skill。
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
- 自动识别 `CODEX_HOME`,默认回退到 `~/.codex`
|
||||||
|
- 在 Codex / Claude 两侧全局目录补齐或标准化:
|
||||||
|
- `connect-chrome`
|
||||||
|
- `browse`
|
||||||
|
- `setup-browser-cookies`
|
||||||
|
- 优先复用现有等价能力;缺失时从公开官方来源安装
|
||||||
|
- 生成本地说明文件:`$CODEX_HOME/browser-control-setup.md`
|
||||||
|
- 做真实验证:可见 Chromium 窗口、`https://example.com`、DOM 读取、network/console、cookie 导入入口调用
|
||||||
|
|
||||||
|
## 执行
|
||||||
|
|
||||||
|
先运行安装脚本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
bash "$SCRIPT_DIR/install-browser-control.sh"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 交付
|
||||||
|
|
||||||
|
安装脚本结束后,读取并引用:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
|
||||||
|
sed -n '1,240p' "$CODEX_HOME/browser-control-setup.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
汇报时只保留高信号结果:
|
||||||
|
|
||||||
|
- 是否安装完成
|
||||||
|
- 3 个入口的最终路径
|
||||||
|
- 本地说明文件路径
|
||||||
|
- 实际验证结果
|
||||||
|
- 如果未完成,唯一阻塞点
|
||||||
433
.codex/skills/install-browser-control/install-browser-control.sh
Executable file
433
.codex/skills/install-browser-control/install-browser-control.sh
Executable file
@ -0,0 +1,433 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
|
||||||
|
CLAUDE_HOME="${CLAUDE_HOME:-$HOME/.claude}"
|
||||||
|
GSTACK_REPO_URL="${GSTACK_REPO_URL:-https://github.com/garrytan/gstack.git}"
|
||||||
|
VERIFY_URL="${VERIFY_URL:-https://example.com}"
|
||||||
|
SETUP_DOC="$CODEX_HOME/browser-control-setup.md"
|
||||||
|
|
||||||
|
TMP_DIR="$(mktemp -d)"
|
||||||
|
cleanup() {
|
||||||
|
rm -rf "$TMP_DIR"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
log() {
|
||||||
|
printf '[install-browser-control] %s\n' "$*" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
printf '[install-browser-control] ERROR: %s\n' "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_macos() {
|
||||||
|
local os_name
|
||||||
|
os_name="$(uname -s)"
|
||||||
|
if [[ "$os_name" != "Darwin" ]]; then
|
||||||
|
fail "当前脚本仅支持 macOS,检测到: $os_name"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_dir() {
|
||||||
|
mkdir -p "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_codex_install() {
|
||||||
|
if command -v codex >/dev/null 2>&1; then
|
||||||
|
command -v codex
|
||||||
|
else
|
||||||
|
printf 'not-found'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_claude_install() {
|
||||||
|
if command -v claude >/dev/null 2>&1; then
|
||||||
|
command -v claude
|
||||||
|
else
|
||||||
|
printf 'not-found'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
have_equivalent_gstack() {
|
||||||
|
local target="$1"
|
||||||
|
[[ -f "$target/connect-chrome/SKILL.md" ]] \
|
||||||
|
&& [[ -f "$target/setup-browser-cookies/SKILL.md" ]] \
|
||||||
|
&& [[ -f "$target/browse/src/cli.ts" || -x "$target/browse/dist/browse" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
clone_seed() {
|
||||||
|
local seed_dir="$TMP_DIR/gstack-seed"
|
||||||
|
if [[ -d "$seed_dir" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
log "cloning gstack from $GSTACK_REPO_URL"
|
||||||
|
git clone --depth 1 "$GSTACK_REPO_URL" "$seed_dir" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_path() {
|
||||||
|
local path="$1"
|
||||||
|
if [[ -e "$path" ]]; then
|
||||||
|
mv "$path" "$path.local.bak.$(date +%Y%m%d%H%M%S)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_gstack_home() {
|
||||||
|
local home_root="$1"
|
||||||
|
local target="$home_root/skills/gstack"
|
||||||
|
|
||||||
|
ensure_dir "$home_root/skills"
|
||||||
|
|
||||||
|
if have_equivalent_gstack "$target"; then
|
||||||
|
printf '%s' "$target"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e "$target" ]]; then
|
||||||
|
backup_path "$target"
|
||||||
|
fi
|
||||||
|
|
||||||
|
clone_seed
|
||||||
|
cp -R "$TMP_DIR/gstack-seed" "$target"
|
||||||
|
printf '%s' "$target"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_bun() {
|
||||||
|
if command -v bun >/dev/null 2>&1; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v brew >/dev/null 2>&1; then
|
||||||
|
log "installing bun with Homebrew"
|
||||||
|
brew install bun >/dev/null
|
||||||
|
else
|
||||||
|
log "installing bun from bun.sh"
|
||||||
|
curl -fsSL https://bun.sh/install | bash >/dev/null
|
||||||
|
export BUN_INSTALL="${BUN_INSTALL:-$HOME/.bun}"
|
||||||
|
export PATH="$BUN_INSTALL/bin:$PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
command -v bun >/dev/null 2>&1 || fail "bun 安装失败"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_browse_runtime() {
|
||||||
|
local gstack_root="$1"
|
||||||
|
local browse_bin="$gstack_root/browse/dist/browse"
|
||||||
|
|
||||||
|
if [[ ! -x "$browse_bin" ]]; then
|
||||||
|
ensure_bun
|
||||||
|
log "building browse binary in $gstack_root"
|
||||||
|
(
|
||||||
|
cd "$gstack_root"
|
||||||
|
bun install >/dev/null
|
||||||
|
bun run build >/dev/null
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -x "$browse_bin" ]] || fail "browse binary 不可用: $browse_bin"
|
||||||
|
|
||||||
|
ensure_bun
|
||||||
|
log "ensuring Playwright Chromium runtime"
|
||||||
|
(
|
||||||
|
cd "$gstack_root"
|
||||||
|
bunx playwright install chromium >/dev/null 2>&1 || true
|
||||||
|
)
|
||||||
|
|
||||||
|
printf '%s' "$browse_bin"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_skill_entry() {
|
||||||
|
local home_root="$1"
|
||||||
|
local skill_name="$2"
|
||||||
|
local dest="$home_root/skills/$skill_name"
|
||||||
|
|
||||||
|
if [[ -L "$dest" ]]; then
|
||||||
|
printf '%s' "$dest"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$dest/SKILL.md" ]] && grep -q "^name: $skill_name\$" "$dest/SKILL.md"; then
|
||||||
|
printf '%s' "$dest"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e "$dest" ]]; then
|
||||||
|
backup_path "$dest"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ln -sfn "gstack/$skill_name" "$dest"
|
||||||
|
printf '%s' "$dest"
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_browser_apps() {
|
||||||
|
local apps=()
|
||||||
|
[[ -d "/Applications/Google Chrome.app" ]] && apps+=("Google Chrome")
|
||||||
|
[[ -d "/Applications/Chromium.app" ]] && apps+=("Chromium")
|
||||||
|
[[ -d "/Applications/Microsoft Edge.app" ]] && apps+=("Microsoft Edge")
|
||||||
|
[[ -d "/Applications/Brave Browser.app" ]] && apps+=("Brave Browser")
|
||||||
|
[[ -d "/Applications/Arc.app" ]] && apps+=("Arc")
|
||||||
|
|
||||||
|
if [[ ${#apps[@]} -eq 0 ]]; then
|
||||||
|
printf 'none-detected'
|
||||||
|
else
|
||||||
|
local joined=""
|
||||||
|
local app
|
||||||
|
for app in "${apps[@]}"; do
|
||||||
|
if [[ -n "$joined" ]]; then
|
||||||
|
joined+=", "
|
||||||
|
fi
|
||||||
|
joined+="$app"
|
||||||
|
done
|
||||||
|
printf '%s' "$joined"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
visible_browser_processes() {
|
||||||
|
/usr/bin/osascript -e 'tell application "System Events" to get the name of every process whose visible is true' 2>/dev/null \
|
||||||
|
| tr ',' '\n' \
|
||||||
|
| sed 's/^ *//' \
|
||||||
|
| grep -E 'Chrome|Chromium' \
|
||||||
|
| paste -sd ', ' - \
|
||||||
|
|| true
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_browser_control() {
|
||||||
|
local browse_bin="$1"
|
||||||
|
local verify_tmp="$TMP_DIR/verify"
|
||||||
|
local connect_out
|
||||||
|
local newtab_out
|
||||||
|
local title_out
|
||||||
|
local heading_out
|
||||||
|
local network_out
|
||||||
|
local console_out
|
||||||
|
local status_out
|
||||||
|
local cookie_out=""
|
||||||
|
local cookie_rc=0
|
||||||
|
local visible_out=""
|
||||||
|
local cookie_status=""
|
||||||
|
|
||||||
|
mkdir -p "$verify_tmp"
|
||||||
|
"$browse_bin" stop >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
"$browse_bin" connect >"$verify_tmp/connect.log" 2>&1
|
||||||
|
sleep 2
|
||||||
|
"$browse_bin" newtab "$VERIFY_URL" >"$verify_tmp/newtab.log" 2>&1
|
||||||
|
"$browse_bin" js 'document.title' >"$verify_tmp/title.log" 2>&1
|
||||||
|
"$browse_bin" text h1 >"$verify_tmp/heading.log" 2>&1
|
||||||
|
"$browse_bin" reload >/dev/null 2>&1 || true
|
||||||
|
"$browse_bin" wait --load >/dev/null 2>&1 || true
|
||||||
|
"$browse_bin" network >"$verify_tmp/network.log" 2>&1
|
||||||
|
"$browse_bin" console >"$verify_tmp/console.log" 2>&1
|
||||||
|
"$browse_bin" status >"$verify_tmp/status.log" 2>&1
|
||||||
|
visible_out="$(visible_browser_processes)"
|
||||||
|
|
||||||
|
"$browse_bin" cookie-import-browser chrome --domain example.com >"$verify_tmp/cookie.log" 2>&1 || cookie_rc=$?
|
||||||
|
|
||||||
|
connect_out="$(cat "$verify_tmp/connect.log")"
|
||||||
|
newtab_out="$(cat "$verify_tmp/newtab.log")"
|
||||||
|
title_out="$(cat "$verify_tmp/title.log")"
|
||||||
|
heading_out="$(cat "$verify_tmp/heading.log")"
|
||||||
|
network_out="$(cat "$verify_tmp/network.log")"
|
||||||
|
console_out="$(cat "$verify_tmp/console.log")"
|
||||||
|
status_out="$(cat "$verify_tmp/status.log")"
|
||||||
|
cookie_out="$(cat "$verify_tmp/cookie.log" 2>/dev/null || true)"
|
||||||
|
|
||||||
|
if [[ $cookie_rc -eq 0 ]]; then
|
||||||
|
cookie_status="callable"
|
||||||
|
elif [[ "$cookie_out" == *"Keychain"* ]]; then
|
||||||
|
cookie_status="callable-requires-keychain-access"
|
||||||
|
elif [[ "$cookie_out" == *"No Chromium browsers found"* ]]; then
|
||||||
|
cookie_status="callable-no-cookie-source-browser"
|
||||||
|
else
|
||||||
|
cookie_status="error"
|
||||||
|
fi
|
||||||
|
|
||||||
|
BROWSE_CONNECT_OUT="$connect_out"
|
||||||
|
BROWSE_NEWTAB_OUT="$newtab_out"
|
||||||
|
BROWSE_TITLE_OUT="$title_out"
|
||||||
|
BROWSE_HEADING_OUT="$heading_out"
|
||||||
|
BROWSE_NETWORK_OUT="$network_out"
|
||||||
|
BROWSE_CONSOLE_OUT="$console_out"
|
||||||
|
BROWSE_STATUS_OUT="$status_out"
|
||||||
|
BROWSE_VISIBLE_OUT="$visible_out"
|
||||||
|
COOKIE_VERIFY_OUT="$cookie_out"
|
||||||
|
COOKIE_VERIFY_STATUS="$cookie_status"
|
||||||
|
}
|
||||||
|
|
||||||
|
write_setup_doc() {
|
||||||
|
local codex_connect="$1"
|
||||||
|
local codex_browse="$2"
|
||||||
|
local codex_cookie="$3"
|
||||||
|
local claude_connect="$4"
|
||||||
|
local claude_browse="$5"
|
||||||
|
local claude_cookie="$6"
|
||||||
|
local codex_gstack="$7"
|
||||||
|
local claude_gstack="$8"
|
||||||
|
local browse_bin="$9"
|
||||||
|
local codex_install="${10}"
|
||||||
|
local claude_install="${11}"
|
||||||
|
local browser_apps="${12}"
|
||||||
|
|
||||||
|
ensure_dir "$CODEX_HOME"
|
||||||
|
|
||||||
|
cat >"$SETUP_DOC" <<EOF
|
||||||
|
# Browser Control Setup
|
||||||
|
|
||||||
|
## 实际安装来源
|
||||||
|
|
||||||
|
- 官方上游:$GSTACK_REPO_URL
|
||||||
|
- Codex 当前 gstack 根目录:$codex_gstack
|
||||||
|
- Claude 当前 gstack 根目录:$claude_gstack
|
||||||
|
- Codex 安装入口:$codex_install
|
||||||
|
- Claude 安装入口:$claude_install
|
||||||
|
- 本机已检测到的系统浏览器:$browser_apps
|
||||||
|
- 运行时浏览器:Playwright Chromium(由 $browse_bin 驱动)
|
||||||
|
|
||||||
|
## 最终技能路径
|
||||||
|
|
||||||
|
### Codex
|
||||||
|
|
||||||
|
- connect-chrome: $codex_connect
|
||||||
|
- browse: $codex_browse
|
||||||
|
- setup-browser-cookies: $codex_cookie
|
||||||
|
|
||||||
|
### Claude
|
||||||
|
|
||||||
|
- connect-chrome: $claude_connect
|
||||||
|
- browse: $claude_browse
|
||||||
|
- setup-browser-cookies: $claude_cookie
|
||||||
|
|
||||||
|
## 如何调用
|
||||||
|
|
||||||
|
### Codex
|
||||||
|
|
||||||
|
- \`connect-chrome\`
|
||||||
|
- \`browse\`
|
||||||
|
- \`setup-browser-cookies\`
|
||||||
|
- \`install-browser-control\`
|
||||||
|
|
||||||
|
### Claude
|
||||||
|
|
||||||
|
- \`/connect-chrome\`
|
||||||
|
- \`/browse\`
|
||||||
|
- \`/setup-browser-cookies\`
|
||||||
|
- \`/install-browser-control\`
|
||||||
|
|
||||||
|
## 如何验证
|
||||||
|
|
||||||
|
1. 运行 \`connect-chrome\`,确认出现 headed Chromium 窗口。
|
||||||
|
2. 运行 \`browse newtab https://example.com\`。
|
||||||
|
3. 运行 \`browse js 'document.title'\` 与 \`browse text h1\`,确认可读取 DOM。
|
||||||
|
4. 运行 \`browse network\` 与 \`browse console\`,确认能读取请求和控制台信息。
|
||||||
|
5. 运行 \`browse cookie-import-browser chrome --domain example.com\`,确认 cookie 导入入口可被调用;首次读取 Chrome Cookie 时,macOS 可能弹出 Keychain 授权框。
|
||||||
|
|
||||||
|
## 本机最近一次真实验证
|
||||||
|
|
||||||
|
### connect
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_CONNECT_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### newtab + DOM
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_NEWTAB_OUT
|
||||||
|
$BROWSE_TITLE_OUT
|
||||||
|
$BROWSE_HEADING_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### network
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_NETWORK_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### console
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_CONSOLE_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### status
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$BROWSE_STATUS_OUT
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### visible browser processes
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
${BROWSE_VISIBLE_OUT:-not-detected}
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### cookie import verification
|
||||||
|
|
||||||
|
- status: $COOKIE_VERIFY_STATUS
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$COOKIE_VERIFY_OUT
|
||||||
|
\`\`\`
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local codex_gstack
|
||||||
|
local claude_gstack
|
||||||
|
local browse_bin
|
||||||
|
local claude_browse_bin
|
||||||
|
local codex_connect
|
||||||
|
local codex_browse
|
||||||
|
local codex_cookie
|
||||||
|
local claude_connect
|
||||||
|
local claude_browse
|
||||||
|
local claude_cookie
|
||||||
|
local browser_apps
|
||||||
|
local codex_install
|
||||||
|
local claude_install
|
||||||
|
|
||||||
|
ensure_macos
|
||||||
|
|
||||||
|
codex_install="$(detect_codex_install)"
|
||||||
|
claude_install="$(detect_claude_install)"
|
||||||
|
|
||||||
|
codex_gstack="$(ensure_gstack_home "$CODEX_HOME")"
|
||||||
|
claude_gstack="$(ensure_gstack_home "$CLAUDE_HOME")"
|
||||||
|
browse_bin="$(ensure_browse_runtime "$codex_gstack")"
|
||||||
|
claude_browse_bin="$(ensure_browse_runtime "$claude_gstack")"
|
||||||
|
|
||||||
|
[[ -x "$claude_browse_bin" ]] || fail "Claude browse binary 不可用: $claude_browse_bin"
|
||||||
|
|
||||||
|
codex_connect="$(ensure_skill_entry "$CODEX_HOME" "connect-chrome")"
|
||||||
|
codex_browse="$(ensure_skill_entry "$CODEX_HOME" "browse")"
|
||||||
|
codex_cookie="$(ensure_skill_entry "$CODEX_HOME" "setup-browser-cookies")"
|
||||||
|
|
||||||
|
claude_connect="$(ensure_skill_entry "$CLAUDE_HOME" "connect-chrome")"
|
||||||
|
claude_browse="$(ensure_skill_entry "$CLAUDE_HOME" "browse")"
|
||||||
|
claude_cookie="$(ensure_skill_entry "$CLAUDE_HOME" "setup-browser-cookies")"
|
||||||
|
|
||||||
|
browser_apps="$(detect_browser_apps)"
|
||||||
|
|
||||||
|
verify_browser_control "$browse_bin"
|
||||||
|
|
||||||
|
write_setup_doc \
|
||||||
|
"$codex_connect" "$codex_browse" "$codex_cookie" \
|
||||||
|
"$claude_connect" "$claude_browse" "$claude_cookie" \
|
||||||
|
"$codex_gstack" "$claude_gstack" "$browse_bin" \
|
||||||
|
"$codex_install" "$claude_install" "$browser_apps"
|
||||||
|
|
||||||
|
printf 'DONE\n'
|
||||||
|
printf 'CODEX_HOME=%s\n' "$CODEX_HOME"
|
||||||
|
printf 'CLAUDE_HOME=%s\n' "$CLAUDE_HOME"
|
||||||
|
printf 'SETUP_DOC=%s\n' "$SETUP_DOC"
|
||||||
|
printf 'CODEX_CONNECT=%s\n' "$codex_connect"
|
||||||
|
printf 'CODEX_BROWSE=%s\n' "$codex_browse"
|
||||||
|
printf 'CODEX_COOKIE=%s\n' "$codex_cookie"
|
||||||
|
printf 'CLAUDE_CONNECT=%s\n' "$claude_connect"
|
||||||
|
printf 'CLAUDE_BROWSE=%s\n' "$claude_browse"
|
||||||
|
printf 'CLAUDE_COOKIE=%s\n' "$claude_cookie"
|
||||||
|
printf 'COOKIE_VERIFY_STATUS=%s\n' "$COOKIE_VERIFY_STATUS"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
@ -148,6 +148,7 @@
|
|||||||
- `issue`: 查看当前仓库或任意 Gitea 仓库的 issue 列表和单条详情,支持自动识别 git origin、用户指定仓库和格式化输出。 (file: `./.codex/skills/issue/SKILL.md`)
|
- `issue`: 查看当前仓库或任意 Gitea 仓库的 issue 列表和单条详情,支持自动识别 git origin、用户指定仓库和格式化输出。 (file: `./.codex/skills/issue/SKILL.md`)
|
||||||
- `issue-drive`: 归集证据并把问题拆成 1 到多张 Gitea issue,支持从当前仓库 origin 自动识别仓库或用户显式指定。 (file: `./.codex/skills/issue-drive/SKILL.md`)
|
- `issue-drive`: 归集证据并把问题拆成 1 到多张 Gitea issue,支持从当前仓库 origin 自动识别仓库或用户显式指定。 (file: `./.codex/skills/issue-drive/SKILL.md`)
|
||||||
- `changelog`: 一键发版:生成更新日志 → commit → 打 tag,全流程自动化。 (file: `./.codex/skills/changelog/SKILL.md`)
|
- `changelog`: 一键发版:生成更新日志 → commit → 打 tag,全流程自动化。 (file: `./.codex/skills/changelog/SKILL.md`)
|
||||||
|
- `install-browser-control`: 在新 Mac 上为 Codex 和 Claude 全局安装或整理真实 Chrome/Chromium 调试能力,统一补齐 connect-chrome、browse、setup-browser-cookies 入口并做实机验证。 (file: `./.codex/skills/install-browser-control/SKILL.md`)
|
||||||
|
|
||||||
### How to use skills
|
### How to use skills
|
||||||
|
|
||||||
|
|||||||
@ -148,6 +148,7 @@
|
|||||||
- `issue`: 查看当前仓库或任意 Gitea 仓库的 issue 列表和单条详情,支持自动识别 git origin、用户指定仓库和格式化输出。 (file: `./.codex/skills/issue/SKILL.md`)
|
- `issue`: 查看当前仓库或任意 Gitea 仓库的 issue 列表和单条详情,支持自动识别 git origin、用户指定仓库和格式化输出。 (file: `./.codex/skills/issue/SKILL.md`)
|
||||||
- `issue-drive`: 归集证据并把问题拆成 1 到多张 Gitea issue,支持从当前仓库 origin 自动识别仓库或用户显式指定。 (file: `./.codex/skills/issue-drive/SKILL.md`)
|
- `issue-drive`: 归集证据并把问题拆成 1 到多张 Gitea issue,支持从当前仓库 origin 自动识别仓库或用户显式指定。 (file: `./.codex/skills/issue-drive/SKILL.md`)
|
||||||
- `changelog`: 一键发版:生成更新日志 → commit → 打 tag,全流程自动化。 (file: `./.codex/skills/changelog/SKILL.md`)
|
- `changelog`: 一键发版:生成更新日志 → commit → 打 tag,全流程自动化。 (file: `./.codex/skills/changelog/SKILL.md`)
|
||||||
|
- `install-browser-control`: 在新 Mac 上为 Codex 和 Claude 全局安装或整理真实 Chrome/Chromium 调试能力,统一补齐 connect-chrome、browse、setup-browser-cookies 入口并做实机验证。 (file: `./.codex/skills/install-browser-control/SKILL.md`)
|
||||||
|
|
||||||
### How to use skills
|
### How to use skills
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user