diff --git a/scripts/convert.sh b/scripts/convert.sh index 230433ac..d557a0c7 100755 --- a/scripts/convert.sh +++ b/scripts/convert.sh @@ -614,6 +614,9 @@ HEREDOC # but never pruned stale output). Preserves the committed README.md — the only # tracked file under integrations// for conversion targets. clean_tool_output() { + # Defensive: tool names are plain slugs; refuse anything else so a future + # caller can never steer this rm -rf outside $OUT_DIR via "../" or "/". + [[ "$1" =~ ^[a-z0-9-]+$ ]] || { echo "ERROR: clean_tool_output: refusing non-slug tool name '$1'" >&2; return 1; } local dir="$OUT_DIR/$1" [[ -d "$dir" ]] || return 0 find "$dir" -mindepth 1 -maxdepth 1 ! -name 'README.md' -exec rm -rf {} + @@ -717,7 +720,7 @@ main() { if $use_parallel && [[ "$tool" == "all" ]]; then # Tools that write to separate dirs can run in parallel; buffer output so each tool's output stays together - local parallel_tools=(antigravity gemini-cli opencode cursor openclaw qwen zcode codex osaurus hermes vibe) + local parallel_tools=(antigravity gemini-cli opencode cursor openclaw qwen zcode kimi codex osaurus hermes vibe) local parallel_out_dir parallel_out_dir="$(mktemp -d)" info "Converting: ${#parallel_tools[@]}/${n_tools} tools in parallel (output buffered per tool)..." @@ -729,7 +732,7 @@ main() { [[ -f "$parallel_out_dir/$t" ]] && cat "$parallel_out_dir/$t" done rm -rf "$parallel_out_dir" - local idx=8 + local idx=$(( ${#parallel_tools[@]} + 1 )) for t in aider windsurf; do progress_bar "$idx" "$n_tools" printf "\n" diff --git a/scripts/install.sh b/scripts/install.sh index 00fbd528..dfc430da 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1258,6 +1258,12 @@ main() { $duplicate || _cleaned+=("$_t") done _tool_list=("${_cleaned[@]}") + # --path is a single-destination override; with several tools every one of + # them would land in the same directory and clobber each other. + if [[ -n "$OVERRIDE_PATH" && ${#_tool_list[@]} -gt 1 ]]; then + err "--path sets ONE destination; use it with exactly one --tool (got ${#_tool_list[@]}: ${_tool_list[*]})." + exit 1 + fi fi # Decide whether to show interactive UI