@tyhld/conductor 0.12.114 → 0.12.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/update-guard.sh +126 -0
package/package.json
CHANGED
package/scripts/update-guard.sh
CHANGED
|
@@ -1056,6 +1056,132 @@ print(f"[update-guard] 追記しました(バックアップ: {backup})
|
|
|
1056
1056
|
PYEOF
|
|
1057
1057
|
fi
|
|
1058
1058
|
|
|
1059
|
+
# ─── ①-e4 ホームの禁止の一覧の「効かない形」を効く形へ入れ替える(けいさん決定 2026-10-07・判断6) ──
|
|
1060
|
+
# 【なぜ要るか(実地 2026-10-06・便 6e8d85e6 の重大発見4)】
|
|
1061
|
+
# ホームの ~/.claude/settings.json の禁止 11 件のうち 1 件が「`*` と末尾の `:*` を混ぜた形」だった。
|
|
1062
|
+
# この形は Claude Code が `*` をただの字として読むので【何も止めない】。本体も起動のときに
|
|
1063
|
+
# 「mixes * with the trailing :* prefix syntax, so it is matched as a literal prefix」と警告する。
|
|
1064
|
+
# 実地でも、後ろに語が有っても無くても素通りすることを確かめた(便 6e8d85e6 の 2-A ⑤⑥⑨⑩)。
|
|
1065
|
+
# ところが ④(現場の権限の整理)は各現場の .claude/settings.json しか直さず、ホームは対象外。
|
|
1066
|
+
# =ホームは「効いていない守り」を持ったまま、この先もずっと直らない(便 6e8d85e6 の要判断4)。
|
|
1067
|
+
#
|
|
1068
|
+
# 【やること】
|
|
1069
|
+
# ・ホームの禁止の一覧から【効かない形】だけを外す。★何も止めていない形なので、
|
|
1070
|
+
# 外しても守りは1ミリも落ちない(落ちるものが無い)。
|
|
1071
|
+
# ・外した行と【同じ系統】で、正本に在る【効く形】を足す。系統=その規則の「最初の `*` より
|
|
1072
|
+
# 前にある、固定の語の並び」(例 `git push` / `cat`)。=「壊れた形を、正本どおりの効く形に
|
|
1073
|
+
# 入れ替える」をこの2手で行う。
|
|
1074
|
+
# ・正本に替えが無い系統の効かない形は【外さない】。持ち主がご自分で足した守りの意図が
|
|
1075
|
+
# 黙って消えるのを避けるため、報告だけする(外しても止まる物は増えも減りもしない)。
|
|
1076
|
+
# ・ホームに在る持ち主独自の行(正本に無い行)は1行も消さない・変えない。
|
|
1077
|
+
#
|
|
1078
|
+
# ★正本の禁止を丸ごとは配らない。ホームの禁止は【この1台の全現場に効く】ので、持ち主が選んで
|
|
1079
|
+
# いない広い禁止(`Read(~/…)` など)まで一気に増やすと、どの現場で何が止まるかが変わる。
|
|
1080
|
+
# この段で触るのは「効かない形」と「その替え」だけに限る。
|
|
1081
|
+
# ★触るのは permissions.deny ただ1つ。allow・ask・hooks・sandbox・env・他のキーには触れない。
|
|
1082
|
+
# ★同期モード(無人・1時間ごと)では行わない(①-e3 と同じ理由。権限は人が見ているときだけ)。
|
|
1083
|
+
# ★書き換える前に必ず控えを取る。冪等(2回流しても差分は出ない)。
|
|
1084
|
+
info "①-e4 ホームの禁止の一覧(効かない形を効く形へ): $HOME_SETTINGS"
|
|
1085
|
+
if [[ "$SYNC_ONLY" == "1" ]]; then
|
|
1086
|
+
info " 省略(同期モード。人が APPLY=1 で流したときだけ入れ替えます)"
|
|
1087
|
+
elif [[ ! -f "$HOME_SETTINGS" ]]; then
|
|
1088
|
+
warn "ホームの設定がありません: $HOME_SETTINGS(入れ替えられません)"
|
|
1089
|
+
else
|
|
1090
|
+
APPLY="$APPLY" python3 - "$HOME_SETTINGS" "$SETTINGS_SRC" <<'PYEOF'
|
|
1091
|
+
import json, os, shutil, sys, time
|
|
1092
|
+
|
|
1093
|
+
dst_path, src_path = sys.argv[1], sys.argv[2]
|
|
1094
|
+
apply_mode = os.environ.get("APPLY") == "1"
|
|
1095
|
+
|
|
1096
|
+
def load(p):
|
|
1097
|
+
with open(p, encoding="utf-8") as f:
|
|
1098
|
+
return json.load(f)
|
|
1099
|
+
|
|
1100
|
+
try:
|
|
1101
|
+
dst = load(dst_path)
|
|
1102
|
+
except Exception as e:
|
|
1103
|
+
print(f"[update-guard] 注意: JSON として読めないので触りません: {dst_path} ({e})", file=sys.stderr)
|
|
1104
|
+
sys.exit(0)
|
|
1105
|
+
try:
|
|
1106
|
+
src_deny = [r for r in load(src_path).get("permissions", {}).get("deny", []) if isinstance(r, str)]
|
|
1107
|
+
except Exception as e:
|
|
1108
|
+
print(f"[update-guard] 注意: 正本の禁止を読めないので触りません ({e})", file=sys.stderr)
|
|
1109
|
+
sys.exit(0)
|
|
1110
|
+
|
|
1111
|
+
def inner(rule):
|
|
1112
|
+
"""`Bash(…)` の中身。Bash 以外の規則(Read/Edit/mcp__… )は None=この段の対象外。"""
|
|
1113
|
+
if isinstance(rule, str) and rule.startswith("Bash(") and rule.endswith(")"):
|
|
1114
|
+
return rule[5:-1]
|
|
1115
|
+
return None
|
|
1116
|
+
|
|
1117
|
+
def is_broken(rule):
|
|
1118
|
+
"""★本体が何も止めない形=末尾が `:*` で、その前に `*` を含む(`*` がただの字として読まれる)。"""
|
|
1119
|
+
s = inner(rule)
|
|
1120
|
+
return bool(s) and s.endswith(":*") and "*" in s[:-2]
|
|
1121
|
+
|
|
1122
|
+
def family(rule):
|
|
1123
|
+
"""系統=最初の `*` より前にある、固定の語の並び(例 'git push' / 'cat')。"""
|
|
1124
|
+
s = inner(rule)
|
|
1125
|
+
if not s:
|
|
1126
|
+
return None
|
|
1127
|
+
if s.endswith(":*"):
|
|
1128
|
+
s = s[:-2]
|
|
1129
|
+
words = []
|
|
1130
|
+
for w in s.split():
|
|
1131
|
+
if "*" in w:
|
|
1132
|
+
break
|
|
1133
|
+
words.append(w)
|
|
1134
|
+
return " ".join(words) or None
|
|
1135
|
+
|
|
1136
|
+
cur = dst.get("permissions", {}).get("deny")
|
|
1137
|
+
if not isinstance(cur, list):
|
|
1138
|
+
print("[update-guard] ホームに禁止の一覧がありません(触りません)")
|
|
1139
|
+
sys.exit(0)
|
|
1140
|
+
|
|
1141
|
+
broken = [r for r in cur if is_broken(r)]
|
|
1142
|
+
if not broken:
|
|
1143
|
+
print("[update-guard] 最新です(効かない形はありません)")
|
|
1144
|
+
sys.exit(0)
|
|
1145
|
+
|
|
1146
|
+
drop, add, kept = [], [], []
|
|
1147
|
+
for r in broken:
|
|
1148
|
+
fam = family(r)
|
|
1149
|
+
repl = [s for s in src_deny if not is_broken(s) and family(s) == fam] if fam else []
|
|
1150
|
+
if not repl:
|
|
1151
|
+
kept.append(r)
|
|
1152
|
+
continue
|
|
1153
|
+
drop.append(r)
|
|
1154
|
+
for s in repl:
|
|
1155
|
+
if s not in cur and s not in add:
|
|
1156
|
+
add.append(s)
|
|
1157
|
+
|
|
1158
|
+
for r in kept:
|
|
1159
|
+
print(f"[update-guard] ※ 何も止めていない形ですが、正本に替えが無いので外しません: {r}")
|
|
1160
|
+
if not drop and not add:
|
|
1161
|
+
sys.exit(0)
|
|
1162
|
+
|
|
1163
|
+
new = [r for r in cur if r not in drop] + add
|
|
1164
|
+
print("[update-guard] ★ホームの禁止の一覧を効く形へ入れ替えます")
|
|
1165
|
+
for r in drop:
|
|
1166
|
+
print(f"[update-guard] - 外す(何も止めていない形): {r}")
|
|
1167
|
+
for s in add:
|
|
1168
|
+
print(f"[update-guard] - 足す(正本の効く形) : {s}")
|
|
1169
|
+
print(f"[update-guard] 件数 {len(cur)} → {len(new)}")
|
|
1170
|
+
if not apply_mode:
|
|
1171
|
+
sys.exit(0)
|
|
1172
|
+
|
|
1173
|
+
dst["permissions"]["deny"] = new
|
|
1174
|
+
backup = f"{dst_path}.bak.{time.strftime('%Y%m%d-%H%M%S')}"
|
|
1175
|
+
shutil.copy2(dst_path, backup)
|
|
1176
|
+
tmp = dst_path + ".tmp"
|
|
1177
|
+
with open(tmp, "w", encoding="utf-8") as f:
|
|
1178
|
+
json.dump(dst, f, indent=2, ensure_ascii=False)
|
|
1179
|
+
f.write("\n")
|
|
1180
|
+
os.replace(tmp, dst_path)
|
|
1181
|
+
print(f"[update-guard] 入れ替えました(バックアップ: {backup})")
|
|
1182
|
+
PYEOF
|
|
1183
|
+
fi
|
|
1184
|
+
|
|
1059
1185
|
# ─── ①-f 「直したのに届かない」を無くす自動同期タイマー(★ADR-012 の本体) ──────
|
|
1060
1186
|
# 【なぜ要るか】ここまでの ① と ①-e は、人がこのスクリプトを流したときにしか動かない。
|
|
1061
1187
|
# 実地では2度続けて流されず、直した番人が機体に1文字も届かないまま何時間も誤ったカードが
|