88 lines
2.8 KiB
Bash
Executable File
88 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# read-launch-json.sh — read .claude/launch.json from the repo root and emit
|
|
# the selected configuration as JSON on stdout, or a sentinel on failure.
|
|
#
|
|
# Usage:
|
|
# read-launch-json.sh [config-name]
|
|
#
|
|
# Arguments:
|
|
# config-name (optional) — if multiple configurations exist and this arg
|
|
# matches a configuration's `name`, emit that one.
|
|
# If omitted and there are multiple configurations,
|
|
# emit a __MULTIPLE_CONFIGS__ sentinel followed by a
|
|
# JSON array of configuration names on the next line.
|
|
#
|
|
# Output contract:
|
|
# Success: single-line JSON object on stdout representing the chosen
|
|
# configuration. Shape mirrors VS Code's launch.json entry:
|
|
# {name, runtimeExecutable, runtimeArgs, port, cwd, env}.
|
|
# Sentinels (printed to stdout, one per line):
|
|
# __NO_LAUNCH_JSON__ - file not found
|
|
# __INVALID_LAUNCH_JSON__ - file exists but fails JSON parsing
|
|
# __MISSING_CONFIGURATIONS__ - valid JSON but no `configurations` array
|
|
# __MULTIPLE_CONFIGS__ - ambiguity, needs caller disambiguation.
|
|
# Followed by a JSON array of names on line 2.
|
|
# __CONFIG_NOT_FOUND__ - caller-provided name doesn't match any entry
|
|
#
|
|
# The script never exits non-zero for a missing or malformed file -- callers
|
|
# parse the sentinel and decide how to proceed. Exit code 1 is reserved for
|
|
# genuine operational failures (missing `jq`, git root not found).
|
|
|
|
set -u
|
|
|
|
REQUESTED_NAME="${1:-}"
|
|
|
|
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
if [ -z "$REPO_ROOT" ]; then
|
|
echo "ERROR: not in a git repository" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v jq >/dev/null 2>&1; then
|
|
echo "ERROR: jq is required but not installed" >&2
|
|
exit 1
|
|
fi
|
|
|
|
LAUNCH_PATH="$REPO_ROOT/.claude/launch.json"
|
|
|
|
if [ ! -f "$LAUNCH_PATH" ]; then
|
|
echo "__NO_LAUNCH_JSON__"
|
|
exit 0
|
|
fi
|
|
|
|
# Validate JSON. We parse with `jq empty` so malformed JSON is caught
|
|
# before any downstream query runs.
|
|
if ! jq empty "$LAUNCH_PATH" >/dev/null 2>&1; then
|
|
echo "__INVALID_LAUNCH_JSON__"
|
|
exit 0
|
|
fi
|
|
|
|
CONFIG_COUNT=$(jq '(.configurations // []) | length' "$LAUNCH_PATH")
|
|
|
|
if [ "$CONFIG_COUNT" = "0" ]; then
|
|
echo "__MISSING_CONFIGURATIONS__"
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$CONFIG_COUNT" = "1" ]; then
|
|
jq -c '.configurations[0]' "$LAUNCH_PATH"
|
|
exit 0
|
|
fi
|
|
|
|
# Multiple configurations. If the caller named one, emit it. Otherwise, emit
|
|
# the sentinel + name list so the caller can prompt the user.
|
|
if [ -n "$REQUESTED_NAME" ]; then
|
|
MATCH=$(jq -c --arg name "$REQUESTED_NAME" '.configurations[] | select(.name == $name)' "$LAUNCH_PATH")
|
|
if [ -z "$MATCH" ]; then
|
|
echo "__CONFIG_NOT_FOUND__"
|
|
exit 0
|
|
fi
|
|
echo "$MATCH"
|
|
exit 0
|
|
fi
|
|
|
|
echo "__MULTIPLE_CONFIGS__"
|
|
jq -c '[.configurations[].name]' "$LAUNCH_PATH"
|
|
exit 0
|