From 91d37aa3af775295eb9649622c2644454347a3ae Mon Sep 17 00:00:00 2001 From: Michael Sitarzewski Date: Wed, 2 Sep 2026 20:04:22 -0500 Subject: [PATCH] fix(scripts): kimi skipped in --parallel, stale progress idx, --path multi-tool guard, rm -rf slug guard (#825) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four install/convert bugs reported by @sunilkumarvalmiki (#817-#820), each verified in a sandbox before and after the change. - convert.sh --tool all --parallel silently skipped kimi: the parallel batch listed 11 tools and the sequential batch 2, so the 14th tool ran in neither (kimi output: 0 files vs 273 for every other tool). Add kimi to the parallel batch — it writes to its own integrations/kimi// dir so it is parallel-safe. (#817) - The sequential batch's progress counter was hardcoded idx=8, stale from an older batch size, printing "aider (8/14)" instead of 12/14. Derive it from the parallel list length so it can never drift again; now prints 13/14 and 14/14. Same root cause as #817. (#818) - --path is a documented single-destination override; with several --tool values every tool resolved to the same directory and clobbered each other. Refuse --path with more than one tool. Deliberately NOT restricting the path itself: the override is the supported way to redirect installs (e.g. to a sandbox), and validating it against an expected dir would break that. (#819) - clean_tool_output runs rm -rf on $OUT_DIR/$1. The tool name is validated upstream so this is not reachable today, but a plain-slug guard on $1 makes a future direct caller unable to steer it outside $OUT_DIR via "../" or "/". A prefix check would not do: "$OUT_DIR/../x" still starts with the prefix. (#820) Fixes #817 Fixes #818 Fixes #819 Fixes #820 Co-authored-by: Claude Fable 5.1 --- scripts/convert.sh | 7 +++++-- scripts/install.sh | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) 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