* fix(scripts): harden bash scripts with escape, compat, and cleanup fixes
- common.sh: complete RFC 8259 JSON escape (\b, \f, strip control chars)
- common.sh: distinguish python3 success-empty vs failure in resolve_template
- check-prerequisites.sh: escape doc names through json_escape in fallback path
- create-new-feature.sh: remove duplicate json_escape (already in common.sh)
- create-new-feature.sh: warn on stderr when spec template is not found
- update-agent-context.sh: move nested function to top-level for bash 3.2 compat
* fix(scripts): explicit resolve_template return code and best-effort agent updates
- common.sh: resolve_template now returns 1 when no template is found,
making the "not found" case explicit instead of relying on empty stdout
- setup-plan.sh, create-new-feature.sh: add || true to resolve_template
calls so set -e does not abort on missing templates (non-fatal)
- update-agent-context.sh: accumulate errors in update_all_existing_agents
instead of silently discarding them — all agents are attempted and the
composite result is returned, matching the PowerShell equivalent behavior
* style(scripts): add clarifying comment in resolve_template preset branch
* fix(scripts): wrap python3 call in if-condition to prevent set -e abort
Move the python3 command substitution in resolve_template into an
if-condition so that a non-zero exit (e.g. invalid .registry JSON)
does not abort the function under set -e. The fallback directory
scan now executes as intended regardless of caller errexit settings.
* fix(scripts): track agent file existence before update and avoid top-level globals
- _update_if_new now records the path and sets _found_agent before calling
update_agent_file, so that failures do not cause duplicate attempts on
aliased paths (AMP/KIRO/BOB -> AGENTS_FILE) or false "no agent files
found" fallback triggers
- Remove top-level initialisation of _updated_paths and _found_agent;
they are now created exclusively inside update_all_existing_agents,
keeping the script side-effect free when sourced
- Replace eval of unquoted get_feature_paths output with safe pattern:
capture into variable, check return code, then eval quoted result
- Use printf '%q' in get_feature_paths to safely emit shell assignments,
preventing injection via paths containing quotes or metacharacters
- Add json_escape() helper for printf JSON fallback paths, handling
backslash, double-quote, and control characters when jq is unavailable
- Use jq -cn for safe JSON construction with proper escaping when
available, with printf + json_escape() fallback
- Replace declare -A (bash 4+) with indexed array for bash 3.2
compatibility (macOS default)
- Use inline command -v jq check in create-new-feature.sh since it
does not source common.sh
- Guard trap cleanup against re-entrant invocation by disarming traps
at entry
- Use printf '%q' for shell-escaped branch names in user-facing output
- Return failure instead of silently returning wrong path on ambiguous
spec directory matches
- Deduplicate agent file updates via realpath to prevent multiple writes
to the same file (e.g. AGENTS.md aliased by multiple variables)