oto/agent-ops/bin/ai-ignore.sh

188 lines
5.5 KiB
Bash
Executable file

#!/usr/bin/env bash
# Shared AI ignore / permission defaults for init and sync flows.
AGENT_OPS_TASK_ARCHIVE_IGNORE_PATTERN="agent-task/archive/**"
AGENT_OPS_ROADMAP_ARCHIVE_IGNORE_PATTERN="agent-ops/roadmap/archive/**"
AGENT_OPS_AI_IGNORE_FILES=(".geminiignore" ".aiexclude" ".cursorignore" ".clineignore")
AGENT_OPS_AI_PERMISSION_FILES=(".claude/settings.json" "opencode.json")
AGENT_OPS_AI_SYNC_FILES=("${AGENT_OPS_AI_IGNORE_FILES[@]}" "${AGENT_OPS_AI_PERMISSION_FILES[@]}")
agent_ops_append_unique_line() {
local file="$1"
local line="$2"
touch "$file"
if ! grep -qxF "$line" "$file"; then
printf "%s\n" "$line" >> "$file"
fi
}
agent_ops_merge_json_with_jq() {
local file="$1"
local filter="$2"
local fallback_note="$3"
local tmp
if ! command -v jq >/dev/null 2>&1; then
echo "$fallback_note"
return
fi
tmp="$(mktemp "$file.tmp.XXXXXX")"
if jq "$filter" "$file" > "$tmp"; then
mv "$tmp" "$file"
else
rm -f "$tmp"
echo "$fallback_note"
fi
}
agent_ops_merge_claude_settings() {
local file="$1"
local filter='
def append_unique($item):
if index($item) then . else . + [$item] end;
def as_array:
if type == "array" then . elif . == null then [] else [.] end;
def as_object:
if type == "object" then . else {} end;
.permissions = ((.permissions // {}) | as_object)
| .permissions.deny = (
(.permissions.deny | as_array)
| append_unique("Read(./agent-task/archive/**)")
| append_unique("Read(./agent-ops/roadmap/archive/**)")
)
'
agent_ops_merge_json_with_jq \
"$file" \
"$filter" \
"Note: .claude/settings.json exists; add Read(./agent-task/archive/**) and Read(./agent-ops/roadmap/archive/**) manually."
}
agent_ops_claude_settings_complete() {
local file="$1"
local filter='
def as_array:
if type == "array" then . elif . == null then [] else [.] end;
(.permissions.deny | as_array)
| index("Read(./agent-task/archive/**)") and index("Read(./agent-ops/roadmap/archive/**)")
'
if command -v jq >/dev/null 2>&1; then
jq -e "$filter" "$file" >/dev/null 2>&1
else
grep -q "agent-task/archive" "$file" && grep -q "agent-ops/roadmap/archive" "$file"
fi
}
agent_ops_merge_opencode_config() {
local file="$1"
local filter='
def append_unique($item):
if index($item) then . else . + [$item] end;
def as_array:
if type == "array" then . elif . == null then [] else [.] end;
def as_object:
if type == "object" then . else {} end;
.permission = ((.permission // {}) | as_object)
| .permission.read = ((.permission.read // {}) | as_object)
| .permission.read["agent-task/archive/**"] = "deny"
| .permission.read["agent-ops/roadmap/archive/**"] = "deny"
| .permission.glob = ((.permission.glob // {}) | as_object)
| .permission.glob["agent-task/archive/**"] = "deny"
| .permission.glob["agent-ops/roadmap/archive/**"] = "deny"
| .watcher = ((.watcher // {}) | as_object)
| .watcher.ignore = (
(.watcher.ignore | as_array)
| append_unique("agent-task/archive/**")
| append_unique("agent-ops/roadmap/archive/**")
)
'
agent_ops_merge_json_with_jq \
"$file" \
"$filter" \
"Note: opencode.json exists; add agent-task/archive/** and agent-ops/roadmap/archive/** read/glob deny and watcher ignore manually."
}
agent_ops_opencode_config_complete() {
local file="$1"
local filter='
def as_array:
if type == "array" then . elif . == null then [] else [.] end;
(.permission.read["agent-task/archive/**"] == "deny")
and (.permission.read["agent-ops/roadmap/archive/**"] == "deny")
and (.permission.glob["agent-task/archive/**"] == "deny")
and (.permission.glob["agent-ops/roadmap/archive/**"] == "deny")
and ((.watcher.ignore | as_array) | index("agent-task/archive/**") and index("agent-ops/roadmap/archive/**"))
'
if command -v jq >/dev/null 2>&1; then
jq -e "$filter" "$file" >/dev/null 2>&1
else
grep -q "agent-task/archive" "$file" && grep -q "agent-ops/roadmap/archive" "$file"
fi
}
ensure_agent_ops_ai_ignore_config() {
local target_dir="$1"
local ignore_file
if [[ -f "$target_dir/.agent-ops-source" ]]; then
echo " AI ignore 보강 건너뜀: .agent-ops-source repo"
return
fi
for ignore_file in "${AGENT_OPS_AI_IGNORE_FILES[@]}"; do
agent_ops_append_unique_line "$target_dir/$ignore_file" "$AGENT_OPS_TASK_ARCHIVE_IGNORE_PATTERN"
agent_ops_append_unique_line "$target_dir/$ignore_file" "$AGENT_OPS_ROADMAP_ARCHIVE_IGNORE_PATTERN"
done
mkdir -p "$target_dir/.claude"
if [[ ! -f "$target_dir/.claude/settings.json" ]]; then
cat > "$target_dir/.claude/settings.json" <<'EOF'
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"deny": [
"Read(./agent-task/archive/**)",
"Read(./agent-ops/roadmap/archive/**)"
]
}
}
EOF
elif ! agent_ops_claude_settings_complete "$target_dir/.claude/settings.json"; then
agent_ops_merge_claude_settings "$target_dir/.claude/settings.json"
fi
if [[ ! -f "$target_dir/opencode.json" ]]; then
cat > "$target_dir/opencode.json" <<'EOF'
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"read": {
"agent-task/archive/**": "deny",
"agent-ops/roadmap/archive/**": "deny"
},
"glob": {
"agent-task/archive/**": "deny",
"agent-ops/roadmap/archive/**": "deny"
}
},
"watcher": {
"ignore": [
"agent-task/archive/**",
"agent-ops/roadmap/archive/**"
]
}
}
EOF
elif ! agent_ops_opencode_config_complete "$target_dir/opencode.json"; then
agent_ops_merge_opencode_config "$target_dir/opencode.json"
fi
}