c2638668e3
leo 2026-08-20:「同一個 plugin 你用,薄殼也用,保證兩邊同步」
「我要你幫雲端做薄殼,永遠都有問題,你要做的就是這組設定
你自己可以 dogfooding」
搬進來:41 支 hook(51 條註冊)/7 支 command/2 支 skill/23 支腳本。
不搬 .env、wiki、docs——那些是知識不是環境。
51 條 hook 路徑全部從 $CLAUDE_PROJECT_DIR/.claude/hooks/ 改成 ${CLAUDE_PLUGIN_ROOT}/hooks/,
零漏網。那正是薄殼一直壞掉的根:雲端 cwd 不是真身,寫死路徑就斷。
尚未驗證:Claude Code 能不能從私有 Gitea repo 裝 marketplace(要憑證)。
下一步就是在本機實際裝一次,通了才動雲端 bootstrap.sh。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
48 lines
2.8 KiB
Bash
Executable File
48 lines
2.8 KiB
Bash
Executable File
#!/bin/bash
|
||
# component-guard.sh — 零件/service-binding 建立保險(D27/D28,2026-07-06)
|
||
# 背景:AI 一再自建 domain 零件(km_wiki_card_parse)、錯用 service binding(drainer 修 1042)。
|
||
# 靠 wiki 規則防不住(leo:「這規定說幾次都沒用」)→ 仿 D20 github-contact-guard 做硬閘:
|
||
# 把「建零件 / 加 service binding」當武器,平時機械擋(exit 2),要人類跑 scripts/component-arm.sh
|
||
# 顯式解保險(限時,且解時該過 docs/component-pr-review-standard.md)才放行。
|
||
# n8n 哲學(leo):現成零件 + 通用 code 零件 + cypher workflow 就夠了 → 預設根本不碰「建零件」那條路,就不會亂想。
|
||
# 誠實限制(同 github-guard mindset §7):AI 技術上可繞過;本 hook 價值=擋手滑 + 留審計軌跡 + 逼你回頭用積木,
|
||
# 絕不聲稱「不可能繞過」。最後一段靠 D27/D28 鐵律與自律。
|
||
|
||
INPUT=$(cat)
|
||
read_field() { printf '%s' "$INPUT" | python3 -c "import json,sys
|
||
try:
|
||
d=json.load(sys.stdin);ti=d.get('tool_input',{})
|
||
print(ti.get('$1',''))
|
||
except: print('')" 2>/dev/null; }
|
||
|
||
FP=$(read_field file_path)
|
||
[ -z "$FP" ] && exit 0
|
||
BODY="$(read_field content)$(read_field new_string)"
|
||
|
||
PROJ="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
||
ARM="$PROJ/.component-armed"
|
||
# 解保險窗口(限時,仿 github-arm):arm 檔內時間戳,30 分鐘內放行
|
||
if [ -f "$ARM" ]; then
|
||
ARMED=$(tr -dc '0-9' < "$ARM" 2>/dev/null); NOW=$(date +%s)
|
||
if [ -n "$ARMED" ] && [ $(( NOW - ARMED )) -lt 1800 ] 2>/dev/null; then exit 0; fi
|
||
fi
|
||
|
||
HIT=""
|
||
if printf '%s' "$FP" | grep -qiE 'wrangler\.(toml|jsonc?)$' && printf '%s' "$BODY" | grep -qE '\[\[services\]\]|(^|[^_a-zA-Z])services[[:space:]]*='; then
|
||
HIT="service binding([[services]])— D28 禁令:跨-worker 編排走 cypher binding,不走 service binding"
|
||
elif printf '%s' "$FP" | grep -qE 'registry/components/[^/]+/(component\.contract\.ya?ml|main\.(go|ts|mjs))$'; then
|
||
HIT="建/改命名零件(registry/components/…)— D27:一次性邏輯用通用 code 零件,別鑄 domain 零件"
|
||
fi
|
||
[ -z "$HIT" ] && exit 0
|
||
|
||
{
|
||
echo "❌ BLOCKED by component-guard($HIT)"
|
||
echo ""
|
||
echo "預設就用「我給你的積木」:現有零件 + 通用 code 零件(inline JS) + cypher workflow(cypher binding 串多 worker/零件)。"
|
||
echo "這些對絕大多數需求已足夠。碰到這道閘,先回頭問:現成積木真的拼不出來嗎?(多半可以)"
|
||
echo "真的需要新零件 / service binding(罕見)→ 要能過 docs/component-pr-review-standard.md,且人類顯式跑 scripts/component-arm.sh 解保險。"
|
||
} >&2
|
||
LOG="$PROJ/system-dev/docs/3-specs/autonomy-dispatch/component-guard-log.md"
|
||
printf '| %s | 擋(%s) | `%s` |\n' "$(date '+%F %T')" "${HIT%%—*}" "$(printf '%s' "$FP" | head -c 120)" >> "$LOG" 2>/dev/null
|
||
exit 2
|