55# One-time, best-effort hint nudging brand-new passthru users to run
66# `/passthru:bootstrap` if they already have native permission rules in
77# their `~/.claude/settings.json` that could be imported. Prints a
8- # stderr message at the start of the Claude Code session (SessionStart
9- # stderr is visible to the user) and touches a marker so the hint does
10- # not fire again.
8+ # single-line plain-text message on stdout, which Claude Code surfaces
9+ # in the session header as "SessionStart:startup says: <text>". Then
10+ # touches a marker so the hint does not fire again.
1111#
1212# Contract:
1313# stdin - JSON envelope from Claude Code (SessionStart hook). We do
1414# not need any of its fields; we still drain stdin defensively
1515# so the writer does not hit SIGPIPE.
16- # stdout - `{}` (no additional context). SessionStart hooks can return
17- # an `additionalContext` field, but we keep the session-log
18- # hint off-session via stderr to avoid nagging inside the
19- # conversation.
20- # exit - always 0. Any error fails open.
16+ # stdout - a single line of plain text when the hint should fire,
17+ # otherwise EMPTY. Per Claude Code docs, SessionStart stdout
18+ # is appended to the session view as
19+ # "SessionStart:startup says: <text>". Anything else (e.g.
20+ # `{}`) would appear verbatim to the user.
21+ # exit - always 0. Any error fails open (empty stdout, exit 0).
2122#
2223# Gating:
2324# - If the marker file `${PASSTHRU_USER_HOME}/.claude/passthru.bootstrap-hint-shown`
2728# marker and exit silently.
2829# - If `~/.claude/settings.json` has no `.permissions.allow` entries,
2930# there is nothing to import - touch the marker and exit silently.
30- # - Otherwise: count the allow entries, emit the hint to stderr , touch
31+ # - Otherwise: count the allow entries, emit the hint on stdout , touch
3132# the marker.
3233#
3334# Paths honor PASSTHRU_USER_HOME and PASSTHRU_PROJECT_DIR so bats tests
4647 _PASSTHRU_COMMON=" ${_PASSTHRU_HANDLER_DIR} /../common.sh"
4748 if [ ! -f " $_PASSTHRU_COMMON " ]; then
4849 # Never block session start, even on a broken install.
49- printf ' {}\n'
5050 exit 0
5151 fi
5252 # shellcheck disable=SC1090
5353 source " $_PASSTHRU_COMMON "
5454fi
5555
5656# ---------------------------------------------------------------------------
57- # Fail-open wrapper: any unexpected error prints {} + exit 0.
57+ # Fail-open wrapper: any unexpected error prints nothing + exit 0.
5858# ---------------------------------------------------------------------------
59- trap ' printf "[passthru] unexpected error in session-start.sh\n" >&2; printf "{}\n"; exit 0' ERR
59+ trap ' printf "[passthru] unexpected error in session-start.sh\n" >&2; exit 0' ERR
6060
6161# ---------------------------------------------------------------------------
6262# Drain stdin defensively so the parent does not see SIGPIPE on its
@@ -74,7 +74,6 @@ MARKER="${USER_HOME}/.claude/passthru.bootstrap-hint-shown"
7474# 1. Marker already set -> silent no-op.
7575# ---------------------------------------------------------------------------
7676if [ -e " $MARKER " ]; then
77- printf ' {}\n'
7877 exit 0
7978fi
8079
8685MARKER_DIR=" $( dirname " $MARKER " ) "
8786if [ ! -d " $MARKER_DIR " ]; then
8887 mkdir -p " $MARKER_DIR " 2> /dev/null || {
89- printf ' {}\n'
9088 exit 0
9189 }
9290fi
@@ -107,7 +105,6 @@ PROJECT_IMPORTED="$(passthru_project_imported_path)"
107105if [ -f " $USER_AUTHORED " ] || [ -f " $USER_IMPORTED " ] \
108106 || [ -f " $PROJECT_AUTHORED " ] || [ -f " $PROJECT_IMPORTED " ]; then
109107 touch_marker
110- printf ' {}\n'
111108 exit 0
112109fi
113110
131128
132129if [ " $COUNT " -eq 0 ]; then
133130 touch_marker
134- printf ' {}\n'
135131 exit 0
136132fi
137133
138134# ---------------------------------------------------------------------------
139- # 4. Emit the one-time hint and persist the marker.
135+ # 4. Emit the one-time hint on stdout and persist the marker.
136+ # Single line keeps the session header readable.
140137# ---------------------------------------------------------------------------
141- printf ' [passthru] Detected %s importable rule(s) in your existing settings.json.\n' " $COUNT " >&2
142- printf ' [passthru] Run /passthru:bootstrap to import them into passthru' \' ' s regex format.\n' >&2
143- printf ' [passthru] This hint only shows once.\n' >&2
138+ printf ' passthru: detected %s importable permission rule(s) in ~/.claude/settings.json. Run /passthru:bootstrap to convert them. This tip only shows once.\n' " $COUNT "
144139
145140touch_marker
146- printf ' {}\n'
147141exit 0
0 commit comments