@@ -307,6 +307,83 @@ has_jq() {
307307 command -v jq > /dev/null 2>&1
308308}
309309
310+ get_invoke_separator () {
311+ local repo_root=" ${1:- $(get_repo_root)} "
312+ if [[ " ${_SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT:- } " == " $repo_root " && -n " ${_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE:- } " ]]; then
313+ printf ' %s\n' " $_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE "
314+ return 0
315+ fi
316+
317+ local integration_json=" $repo_root /.specify/integration.json"
318+ local separator=" ."
319+ local parsed_with_jq=0
320+
321+ if [[ -f " $integration_json " ]]; then
322+ if command -v jq > /dev/null 2>&1 ; then
323+ local jq_separator
324+ if jq_separator=$( jq -r ' (.default_integration // .integration // "") as $k | if $k == "" then "." else (.integration_settings[$k].invoke_separator // ".") end' " $integration_json " 2> /dev/null) ; then
325+ parsed_with_jq=1
326+ case " $jq_separator " in
327+ " ." |" -" ) separator=" $jq_separator " ;;
328+ esac
329+ fi
330+ fi
331+
332+ if [[ " $parsed_with_jq " -eq 0 ]] && command -v python3 > /dev/null 2>&1 ; then
333+ if separator=$( python3 - " $integration_json " << 'PY ' 2>/dev/null
334+ import json
335+ import sys
336+
337+ try:
338+ with open(sys.argv[1], encoding="utf-8") as fh:
339+ state = json.load(fh)
340+ key = state.get("default_integration") or state.get("integration") or ""
341+ settings = state.get("integration_settings")
342+ separator = "."
343+ if isinstance(key, str) and isinstance(settings, dict):
344+ entry = settings.get(key)
345+ if isinstance(entry, dict) and entry.get("invoke_separator") in {".", "-"}:
346+ separator = entry["invoke_separator"]
347+ print(separator)
348+ except Exception:
349+ print(".")
350+ PY
351+ ) ; then
352+ case " $separator " in
353+ " ." |" -" ) ;;
354+ * ) separator=" ." ;;
355+ esac
356+ else
357+ separator=" ."
358+ fi
359+ fi
360+ fi
361+
362+ _SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT=" $repo_root "
363+ _SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE=" $separator "
364+ printf ' %s\n' " $separator "
365+ }
366+
367+ format_speckit_command () {
368+ local command_name=" $1 "
369+ local repo_root=" ${2:- $(get_repo_root)} "
370+ local separator
371+ if [[ " ${_SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT:- } " == " $repo_root " && -n " ${_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE:- } " ]]; then
372+ separator=" $_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE "
373+ else
374+ separator=$( get_invoke_separator " $repo_root " )
375+ _SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT=" $repo_root "
376+ _SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE=" $separator "
377+ fi
378+
379+ command_name=" ${command_name#/ } "
380+ command_name=" ${command_name# speckit.} "
381+ command_name=" ${command_name# speckit-} "
382+ command_name=" ${command_name// ./ $separator } "
383+
384+ printf ' /speckit%s%s\n' " $separator " " $command_name "
385+ }
386+
310387# Escape a string for safe embedding in a JSON value (fallback when jq is unavailable).
311388# Handles backslash, double-quote, and JSON-required control character escapes (RFC 8259).
312389json_escape () {
0 commit comments