mirror of
https://github.com/HKUDS/CLI-Anything.git
synced 2026-09-01 15:36:07 +08:00
fix: harden Codex skill installer staging
This commit is contained in:
+1
-1
@@ -278,7 +278,7 @@ bash CLI-Anything/codex-skill/scripts/install.sh
|
||||
```
|
||||
|
||||
脚本会把 skill 安装到 `$CODEX_HOME/skills/cli-anything`;如果没有设置 `CODEX_HOME`,则默认安装到 `~/.codex/skills/cli-anything`。
|
||||
安装器还会把权威版本的 `HARNESS.md`、命令规范、按需指南、可复用辅助脚本、skill 模板和 preview 协议复制到已安装 skill 的 `references/`、`scripts/` 和 `assets/` 目录。这样 Codex skill 可以独立工作,同时仍以 `cli-anything-plugin/` 作为唯一权威来源。
|
||||
安装器还会把权威版本的 `HARNESS.md`、命令规范、按需指南、可复用辅助脚本、skill 模板和 preview 协议复制到已安装 skill 的 `references/` 和 `scripts/` 目录。这样 Codex skill 可以独立工作,同时仍以 `cli-anything-plugin/` 作为唯一权威来源。
|
||||
|
||||
安装后重启 Codex,让它重新发现这个 skill。
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ skill so a normal Codex installation is self-contained.
|
||||
| `scripts/repl_skin.py` | Copy into generated harnesses as `utils/repl_skin.py` |
|
||||
| `scripts/preview_bundle.py` | Copy into preview-capable harnesses as `utils/preview_bundle.py` |
|
||||
| `scripts/skill_generator.py` | Generate canonical and packaged CLI skills |
|
||||
| `assets/SKILL.md.template` | Skill generation template |
|
||||
| `scripts/templates/SKILL.md.template` | Skill generation template used by `skill_generator.py` |
|
||||
| `references/docs/PREVIEW_PROTOCOL.md` | Shared preview bundle protocol |
|
||||
|
||||
When reading vendored documents, apply these path remappings instead of resolving
|
||||
@@ -50,7 +50,7 @@ plugin paths against the current working directory:
|
||||
| `cli-anything-plugin/repl_skin.py` | `scripts/repl_skin.py` |
|
||||
| `cli-anything-plugin/preview_bundle.py` | `scripts/preview_bundle.py` |
|
||||
| `cli-anything-plugin/skill_generator.py` | `scripts/skill_generator.py` |
|
||||
| `templates/SKILL.md.template` | `assets/SKILL.md.template` |
|
||||
| `templates/SKILL.md.template` | `scripts/templates/SKILL.md.template` |
|
||||
| `docs/PREVIEW_PROTOCOL.md` | `references/docs/PREVIEW_PROTOCOL.md` |
|
||||
|
||||
## Inputs
|
||||
|
||||
@@ -16,7 +16,7 @@ $codexHome = if ($env:CODEX_HOME) {
|
||||
|
||||
$destRoot = Join-Path $codexHome "skills"
|
||||
$destDir = Join-Path $destRoot "cli-anything"
|
||||
$stagingDir = Join-Path $destRoot ".cli-anything.tmp.$PID"
|
||||
$stagingDir = $null
|
||||
|
||||
if (-not (Test-Path (Join-Path $pluginDir "HARNESS.md"))) {
|
||||
throw "Cannot find canonical CLI-Anything resources at: $pluginDir`nRun this installer from a full CLI-Anything repository checkout."
|
||||
@@ -33,16 +33,18 @@ if (Test-Path $destDir) {
|
||||
}
|
||||
|
||||
try {
|
||||
Copy-Item -Path $skillDir -Destination $stagingDir -Recurse
|
||||
$stagingDir = Join-Path $destRoot (".cli-anything.tmp." + [System.Guid]::NewGuid().ToString("N"))
|
||||
New-Item -ItemType Directory -Path $stagingDir | Out-Null
|
||||
Get-ChildItem -LiteralPath $skillDir -Force | Copy-Item -Destination $stagingDir -Recurse -Force
|
||||
|
||||
$assetDir = Join-Path $stagingDir "assets"
|
||||
$referenceDir = Join-Path $stagingDir "references"
|
||||
$referenceCommands = Join-Path $referenceDir "commands"
|
||||
$referenceDocs = Join-Path $referenceDir "docs"
|
||||
$referenceGuides = Join-Path $referenceDir "guides"
|
||||
$resourceScripts = Join-Path $stagingDir "scripts"
|
||||
$scriptTemplates = Join-Path $resourceScripts "templates"
|
||||
|
||||
New-Item -ItemType Directory -Path $assetDir, $referenceCommands, $referenceDocs, $referenceGuides, $resourceScripts -Force | Out-Null
|
||||
New-Item -ItemType Directory -Path $referenceCommands, $referenceDocs, $referenceGuides, $scriptTemplates -Force | Out-Null
|
||||
|
||||
Copy-Item -Path (Join-Path $pluginDir "HARNESS.md") -Destination (Join-Path $referenceDir "HARNESS.md")
|
||||
Copy-Item -Path (Join-Path $pluginDir "commands/*.md") -Destination $referenceCommands
|
||||
@@ -50,12 +52,12 @@ try {
|
||||
Copy-Item -Path (Join-Path $pluginDir "repl_skin.py") -Destination (Join-Path $resourceScripts "repl_skin.py")
|
||||
Copy-Item -Path (Join-Path $pluginDir "preview_bundle.py") -Destination (Join-Path $resourceScripts "preview_bundle.py")
|
||||
Copy-Item -Path (Join-Path $pluginDir "skill_generator.py") -Destination (Join-Path $resourceScripts "skill_generator.py")
|
||||
Copy-Item -Path (Join-Path $pluginDir "templates/*") -Destination $assetDir
|
||||
Copy-Item -Path (Join-Path $pluginDir "templates/*") -Destination $scriptTemplates
|
||||
Copy-Item -Path $previewProtocol -Destination (Join-Path $referenceDocs "PREVIEW_PROTOCOL.md")
|
||||
|
||||
Move-Item -Path $stagingDir -Destination $destDir
|
||||
} finally {
|
||||
if (Test-Path $stagingDir) {
|
||||
if ($stagingDir -and (Test-Path $stagingDir)) {
|
||||
Remove-Item -Path $stagingDir -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ PLUGIN_DIR="${REPO_ROOT}/cli-anything-plugin"
|
||||
PREVIEW_PROTOCOL="${REPO_ROOT}/docs/PREVIEW_PROTOCOL.md"
|
||||
DEST_ROOT="${CODEX_HOME:-$HOME/.codex}/skills"
|
||||
DEST_DIR="${DEST_ROOT}/cli-anything"
|
||||
STAGING_DIR="${DEST_ROOT}/.cli-anything.tmp.$$"
|
||||
STAGING_DIR=""
|
||||
|
||||
if [[ ! -f "${PLUGIN_DIR}/HARNESS.md" ]]; then
|
||||
echo "Cannot find canonical CLI-Anything resources at: ${PLUGIN_DIR}" >&2
|
||||
@@ -32,17 +32,19 @@ if [[ -e "${DEST_DIR}" ]]; then
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
rm -rf "${STAGING_DIR}"
|
||||
if [[ -n "${STAGING_DIR}" && -d "${STAGING_DIR}" ]]; then
|
||||
rm -rf "${STAGING_DIR}"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
cp -R "${SKILL_DIR}" "${STAGING_DIR}"
|
||||
STAGING_DIR="$(mktemp -d "${DEST_ROOT}/.cli-anything.tmp.XXXXXX")"
|
||||
cp -R "${SKILL_DIR}/." "${STAGING_DIR}/"
|
||||
mkdir -p \
|
||||
"${STAGING_DIR}/assets" \
|
||||
"${STAGING_DIR}/references/commands" \
|
||||
"${STAGING_DIR}/references/docs" \
|
||||
"${STAGING_DIR}/references/guides" \
|
||||
"${STAGING_DIR}/scripts"
|
||||
"${STAGING_DIR}/scripts/templates"
|
||||
|
||||
cp "${PLUGIN_DIR}/HARNESS.md" "${STAGING_DIR}/references/HARNESS.md"
|
||||
cp "${PLUGIN_DIR}/commands/"*.md "${STAGING_DIR}/references/commands/"
|
||||
@@ -50,7 +52,7 @@ cp "${PLUGIN_DIR}/guides/"*.md "${STAGING_DIR}/references/guides/"
|
||||
cp "${PLUGIN_DIR}/repl_skin.py" "${STAGING_DIR}/scripts/repl_skin.py"
|
||||
cp "${PLUGIN_DIR}/preview_bundle.py" "${STAGING_DIR}/scripts/preview_bundle.py"
|
||||
cp "${PLUGIN_DIR}/skill_generator.py" "${STAGING_DIR}/scripts/skill_generator.py"
|
||||
cp "${PLUGIN_DIR}/templates/"* "${STAGING_DIR}/assets/"
|
||||
cp "${PLUGIN_DIR}/templates/"* "${STAGING_DIR}/scripts/templates/"
|
||||
cp "${PREVIEW_PROTOCOL}" "${STAGING_DIR}/references/docs/PREVIEW_PROTOCOL.md"
|
||||
|
||||
mv "${STAGING_DIR}" "${DEST_DIR}"
|
||||
|
||||
@@ -9,6 +9,7 @@ PLUGIN_DIR="${REPO_ROOT}/cli-anything-plugin"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
CODEX_HOME="${TMP_DIR}/codex-home"
|
||||
INSTALLED_DIR="${CODEX_HOME}/skills/cli-anything"
|
||||
STALE_STAGING_DIR="${CODEX_HOME}/skills/.cli-anything.tmp.stale"
|
||||
|
||||
cleanup() {
|
||||
rm -rf "${TMP_DIR}"
|
||||
@@ -32,9 +33,16 @@ assert_tree_same() {
|
||||
diff -qr "$1" "$2" >/dev/null || fail "directories differ: $1 $2"
|
||||
}
|
||||
|
||||
mkdir -p "${STALE_STAGING_DIR}/codex-skill"
|
||||
echo "left over from an interrupted install" > "${STALE_STAGING_DIR}/codex-skill/stale.txt"
|
||||
|
||||
CODEX_HOME="${CODEX_HOME}" bash "${SKILL_DIR}/scripts/install.sh"
|
||||
|
||||
assert_file "${INSTALLED_DIR}/SKILL.md"
|
||||
[[ -d "${STALE_STAGING_DIR}" ]] ||
|
||||
fail "installer reused or removed the stale staging directory"
|
||||
[[ ! -d "${INSTALLED_DIR}/codex-skill" ]] ||
|
||||
fail "installer created a nested codex-skill directory"
|
||||
assert_file "${INSTALLED_DIR}/references/HARNESS.md"
|
||||
assert_file "${INSTALLED_DIR}/references/commands/cli-anything.md"
|
||||
assert_file "${INSTALLED_DIR}/references/commands/refine.md"
|
||||
@@ -47,7 +55,7 @@ assert_file "${INSTALLED_DIR}/references/guides/preview-methodology.md"
|
||||
assert_file "${INSTALLED_DIR}/scripts/repl_skin.py"
|
||||
assert_file "${INSTALLED_DIR}/scripts/preview_bundle.py"
|
||||
assert_file "${INSTALLED_DIR}/scripts/skill_generator.py"
|
||||
assert_file "${INSTALLED_DIR}/assets/SKILL.md.template"
|
||||
assert_file "${INSTALLED_DIR}/scripts/templates/SKILL.md.template"
|
||||
assert_file "${INSTALLED_DIR}/references/docs/PREVIEW_PROTOCOL.md"
|
||||
|
||||
assert_same "${PLUGIN_DIR}/HARNESS.md" "${INSTALLED_DIR}/references/HARNESS.md"
|
||||
@@ -57,7 +65,7 @@ assert_same "${PLUGIN_DIR}/skill_generator.py" "${INSTALLED_DIR}/scripts/skill_g
|
||||
assert_same "${REPO_ROOT}/docs/PREVIEW_PROTOCOL.md" "${INSTALLED_DIR}/references/docs/PREVIEW_PROTOCOL.md"
|
||||
assert_tree_same "${PLUGIN_DIR}/commands" "${INSTALLED_DIR}/references/commands"
|
||||
assert_tree_same "${PLUGIN_DIR}/guides" "${INSTALLED_DIR}/references/guides"
|
||||
assert_tree_same "${PLUGIN_DIR}/templates" "${INSTALLED_DIR}/assets"
|
||||
assert_tree_same "${PLUGIN_DIR}/templates" "${INSTALLED_DIR}/scripts/templates"
|
||||
|
||||
python3 -m py_compile \
|
||||
"${INSTALLED_DIR}/scripts/repl_skin.py" \
|
||||
|
||||
Reference in New Issue
Block a user