Skills › Compound Engineering › ce-polish › read-launch-json.sh
read-launch-json.sh
87 lines · skills/ce-polish/scripts/read-launch-json.sh at 3449230
1#!/usr/bin/env bash
2#
3# read-launch-json.sh — read .claude/launch.json from the repo root and emit
4# the selected configuration as JSON on stdout, or a sentinel on failure.
5#
6# Usage:
7# read-launch-json.sh [config-name]
8#
9# Arguments:
10# config-name (optional) — if multiple configurations exist and this arg
11# matches a configuration's `name`, emit that one.
12# If omitted and there are multiple configurations,
13# emit a __MULTIPLE_CONFIGS__ sentinel followed by a
14# JSON array of configuration names on the next line.
15#
16# Output contract:
17# Success: single-line JSON object on stdout representing the chosen
18# configuration. Shape mirrors VS Code's launch.json entry:
19# {name, runtimeExecutable, runtimeArgs, port, cwd, env}.
20# Sentinels (printed to stdout, one per line):
21# __NO_LAUNCH_JSON__ - file not found
22# __INVALID_LAUNCH_JSON__ - file exists but fails JSON parsing
23# __MISSING_CONFIGURATIONS__ - valid JSON but no `configurations` array
24# __MULTIPLE_CONFIGS__ - ambiguity, needs caller disambiguation.
25# Followed by a JSON array of names on line 2.
26# __CONFIG_NOT_FOUND__ - caller-provided name doesn't match any entry
27#
28# The script never exits non-zero for a missing or malformed file -- callers
29# parse the sentinel and decide how to proceed. Exit code 1 is reserved for
30# genuine operational failures (missing `jq`, git root not found).
32set -u
34REQUESTED_NAME="${1:-}"
36REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
37if [ -z "$REPO_ROOT" ]; then
38 echo "ERROR: not in a git repository" >&2
39 exit 1
40fi
42if ! command -v jq >/dev/null 2>&1; then
43 echo "ERROR: jq is required but not installed" >&2
44 exit 1
45fi
47LAUNCH_PATH="$REPO_ROOT/.claude/launch.json"
49if [ ! -f "$LAUNCH_PATH" ]; then
50 echo "__NO_LAUNCH_JSON__"
51 exit 0
52fi
54# Validate JSON. We parse with `jq empty` so malformed JSON is caught
55# before any downstream query runs.
56if ! jq empty "$LAUNCH_PATH" >/dev/null 2>&1; then
57 echo "__INVALID_LAUNCH_JSON__"
58 exit 0
59fi
61CONFIG_COUNT=$(jq '(.configurations // []) | length' "$LAUNCH_PATH")
63if [ "$CONFIG_COUNT" = "0" ]; then
64 echo "__MISSING_CONFIGURATIONS__"
65 exit 0
66fi
68if [ "$CONFIG_COUNT" = "1" ]; then
69 jq -c '.configurations[0]' "$LAUNCH_PATH"
70 exit 0
71fi
73# Multiple configurations. If the caller named one, emit it. Otherwise, emit
74# the sentinel + name list so the caller can prompt the user.
75if [ -n "$REQUESTED_NAME" ]; then
76 MATCH=$(jq -c --arg name "$REQUESTED_NAME" '.configurations[] | select(.name == $name)' "$LAUNCH_PATH")
77 if [ -z "$MATCH" ]; then
78 echo "__CONFIG_NOT_FOUND__"
79 exit 0
80 fi
81 echo "$MATCH"
82 exit 0
83fi
85echo "__MULTIPLE_CONFIGS__"
86jq -c '[.configurations[].name]' "$LAUNCH_PATH"
87exit 0