@skillsmith/cli 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/commands/__meta__/telemetry-coverage.test.d.ts +20 -0
- package/dist/src/commands/__meta__/telemetry-coverage.test.d.ts.map +1 -0
- package/dist/src/commands/__meta__/telemetry-coverage.test.js +118 -0
- package/dist/src/commands/__meta__/telemetry-coverage.test.js.map +1 -0
- package/dist/src/commands/ab-test.d.ts +1 -0
- package/dist/src/commands/ab-test.d.ts.map +1 -1
- package/dist/src/commands/ab-test.js +17 -8
- package/dist/src/commands/ab-test.js.map +1 -1
- package/dist/src/commands/analyze.d.ts +1 -0
- package/dist/src/commands/analyze.d.ts.map +1 -1
- package/dist/src/commands/analyze.js +32 -23
- package/dist/src/commands/analyze.js.map +1 -1
- package/dist/src/commands/audit-collisions.d.ts +1 -4
- package/dist/src/commands/audit-collisions.d.ts.map +1 -1
- package/dist/src/commands/audit-collisions.js +32 -23
- package/dist/src/commands/audit-collisions.js.map +1 -1
- package/dist/src/commands/audit-sources.action.d.ts +37 -0
- package/dist/src/commands/audit-sources.action.d.ts.map +1 -0
- package/dist/src/commands/audit-sources.action.js +300 -0
- package/dist/src/commands/audit-sources.action.js.map +1 -0
- package/dist/src/commands/audit-sources.d.ts +37 -0
- package/dist/src/commands/audit-sources.d.ts.map +1 -0
- package/dist/src/commands/audit-sources.js +55 -0
- package/dist/src/commands/audit-sources.js.map +1 -0
- package/dist/src/commands/audit-sources.test.d.ts +9 -0
- package/dist/src/commands/audit-sources.test.d.ts.map +1 -0
- package/dist/src/commands/audit-sources.test.js +228 -0
- package/dist/src/commands/audit-sources.test.js.map +1 -0
- package/dist/src/commands/audit.d.ts +2 -6
- package/dist/src/commands/audit.d.ts.map +1 -1
- package/dist/src/commands/audit.js +52 -31
- package/dist/src/commands/audit.js.map +1 -1
- package/dist/src/commands/author/index.d.ts +2 -1
- package/dist/src/commands/author/index.d.ts.map +1 -1
- package/dist/src/commands/author/index.js +4 -1
- package/dist/src/commands/author/index.js.map +1 -1
- package/dist/src/commands/author/init.action.d.ts +29 -0
- package/dist/src/commands/author/init.action.d.ts.map +1 -0
- package/dist/src/commands/author/init.action.js +131 -0
- package/dist/src/commands/author/init.action.js.map +1 -0
- package/dist/src/commands/author/init.d.ts +0 -14
- package/dist/src/commands/author/init.d.ts.map +1 -1
- package/dist/src/commands/author/init.js +3 -87
- package/dist/src/commands/author/init.js.map +1 -1
- package/dist/src/commands/author/mcp-init.d.ts +1 -0
- package/dist/src/commands/author/mcp-init.d.ts.map +1 -1
- package/dist/src/commands/author/mcp-init.js +21 -13
- package/dist/src/commands/author/mcp-init.js.map +1 -1
- package/dist/src/commands/author/subagent.d.ts +1 -0
- package/dist/src/commands/author/subagent.d.ts.map +1 -1
- package/dist/src/commands/author/subagent.js +23 -15
- package/dist/src/commands/author/subagent.js.map +1 -1
- package/dist/src/commands/author/transform.d.ts +1 -0
- package/dist/src/commands/author/transform.d.ts.map +1 -1
- package/dist/src/commands/author/transform.js +23 -15
- package/dist/src/commands/author/transform.js.map +1 -1
- package/dist/src/commands/config.d.ts +2 -0
- package/dist/src/commands/config.d.ts.map +1 -1
- package/dist/src/commands/config.js +43 -28
- package/dist/src/commands/config.js.map +1 -1
- package/dist/src/commands/create.d.ts +1 -0
- package/dist/src/commands/create.d.ts.map +1 -1
- package/dist/src/commands/create.js +28 -19
- package/dist/src/commands/create.js.map +1 -1
- package/dist/src/commands/diff.d.ts +4 -0
- package/dist/src/commands/diff.d.ts.map +1 -1
- package/dist/src/commands/diff.js +57 -42
- package/dist/src/commands/diff.js.map +1 -1
- package/dist/src/commands/diff.test.js +30 -0
- package/dist/src/commands/diff.test.js.map +1 -1
- package/dist/src/commands/import-local.d.ts +7 -0
- package/dist/src/commands/import-local.d.ts.map +1 -1
- package/dist/src/commands/import-local.js +43 -34
- package/dist/src/commands/import-local.js.map +1 -1
- package/dist/src/commands/import.d.ts +6 -0
- package/dist/src/commands/import.d.ts.map +1 -1
- package/dist/src/commands/import.js +23 -14
- package/dist/src/commands/import.js.map +1 -1
- package/dist/src/commands/index.d.ts +1 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +2 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/info.d.ts +7 -0
- package/dist/src/commands/info.d.ts.map +1 -1
- package/dist/src/commands/info.js +77 -68
- package/dist/src/commands/info.js.map +1 -1
- package/dist/src/commands/install-skill.d.ts +3 -0
- package/dist/src/commands/install-skill.d.ts.map +1 -1
- package/dist/src/commands/install-skill.js +23 -15
- package/dist/src/commands/install-skill.js.map +1 -1
- package/dist/src/commands/install.d.ts +21 -0
- package/dist/src/commands/install.d.ts.map +1 -1
- package/dist/src/commands/install.js +154 -139
- package/dist/src/commands/install.js.map +1 -1
- package/dist/src/commands/login.d.ts +4 -0
- package/dist/src/commands/login.d.ts.map +1 -1
- package/dist/src/commands/login.js +56 -47
- package/dist/src/commands/login.js.map +1 -1
- package/dist/src/commands/logout.d.ts +1 -0
- package/dist/src/commands/logout.d.ts.map +1 -1
- package/dist/src/commands/logout.js +36 -27
- package/dist/src/commands/logout.js.map +1 -1
- package/dist/src/commands/manage.d.ts +3 -9
- package/dist/src/commands/manage.d.ts.map +1 -1
- package/dist/src/commands/manage.js +69 -45
- package/dist/src/commands/manage.js.map +1 -1
- package/dist/src/commands/merge.d.ts +7 -0
- package/dist/src/commands/merge.d.ts.map +1 -1
- package/dist/src/commands/merge.js +117 -108
- package/dist/src/commands/merge.js.map +1 -1
- package/dist/src/commands/pin.d.ts +2 -0
- package/dist/src/commands/pin.d.ts.map +1 -1
- package/dist/src/commands/pin.js +88 -73
- package/dist/src/commands/pin.js.map +1 -1
- package/dist/src/commands/recommend.d.ts +1 -0
- package/dist/src/commands/recommend.d.ts.map +1 -1
- package/dist/src/commands/recommend.js +35 -27
- package/dist/src/commands/recommend.js.map +1 -1
- package/dist/src/commands/search-formatters.d.ts +1 -0
- package/dist/src/commands/search-formatters.d.ts.map +1 -1
- package/dist/src/commands/search-formatters.js +3 -0
- package/dist/src/commands/search-formatters.js.map +1 -1
- package/dist/src/commands/search.action.d.ts +16 -0
- package/dist/src/commands/search.action.d.ts.map +1 -0
- package/dist/src/commands/search.action.js +384 -0
- package/dist/src/commands/search.action.js.map +1 -0
- package/dist/src/commands/search.d.ts +3 -0
- package/dist/src/commands/search.d.ts.map +1 -1
- package/dist/src/commands/search.js +5 -343
- package/dist/src/commands/search.js.map +1 -1
- package/dist/src/commands/sync.action.d.ts +39 -0
- package/dist/src/commands/sync.action.d.ts.map +1 -0
- package/dist/src/commands/sync.action.js +353 -0
- package/dist/src/commands/sync.action.js.map +1 -0
- package/dist/src/commands/sync.d.ts +3 -0
- package/dist/src/commands/sync.d.ts.map +1 -1
- package/dist/src/commands/sync.js +8 -310
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/telemetry.action.d.ts +38 -0
- package/dist/src/commands/telemetry.action.d.ts.map +1 -0
- package/dist/src/commands/telemetry.action.js +350 -0
- package/dist/src/commands/telemetry.action.js.map +1 -0
- package/dist/src/commands/telemetry.d.ts +30 -0
- package/dist/src/commands/telemetry.d.ts.map +1 -0
- package/dist/src/commands/telemetry.helpers.d.ts +58 -0
- package/dist/src/commands/telemetry.helpers.d.ts.map +1 -0
- package/dist/src/commands/telemetry.helpers.js +173 -0
- package/dist/src/commands/telemetry.helpers.js.map +1 -0
- package/dist/src/commands/telemetry.helpers.test.d.ts +15 -0
- package/dist/src/commands/telemetry.helpers.test.d.ts.map +1 -0
- package/dist/src/commands/telemetry.helpers.test.js +240 -0
- package/dist/src/commands/telemetry.helpers.test.js.map +1 -0
- package/dist/src/commands/telemetry.js +65 -0
- package/dist/src/commands/telemetry.js.map +1 -0
- package/dist/src/commands/telemetry.test.d.ts +18 -0
- package/dist/src/commands/telemetry.test.d.ts.map +1 -0
- package/dist/src/commands/telemetry.test.js +401 -0
- package/dist/src/commands/telemetry.test.js.map +1 -0
- package/dist/src/commands/whoami.d.ts +1 -0
- package/dist/src/commands/whoami.d.ts.map +1 -1
- package/dist/src/commands/whoami.js +29 -21
- package/dist/src/commands/whoami.js.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/utils/manifest.d.ts +75 -0
- package/dist/src/utils/manifest.d.ts.map +1 -1
- package/dist/src/utils/manifest.js +78 -0
- package/dist/src/utils/manifest.js.map +1 -1
- package/dist/src/utils/manifest.test.d.ts +20 -0
- package/dist/src/utils/manifest.test.d.ts.map +1 -0
- package/dist/src/utils/manifest.test.js +344 -0
- package/dist/src/utils/manifest.test.js.map +1 -0
- package/dist/src/utils/open-database.d.ts +10 -2
- package/dist/src/utils/open-database.d.ts.map +1 -1
- package/dist/src/utils/open-database.js +15 -2
- package/dist/src/utils/open-database.js.map +1 -1
- package/dist/src/utils/skills-directory.d.ts.map +1 -1
- package/dist/src/utils/skills-directory.js +5 -1
- package/dist/src/utils/skills-directory.js.map +1 -1
- package/dist/tests/e2e/audit-sources-apply.test.d.ts +13 -0
- package/dist/tests/e2e/audit-sources-apply.test.d.ts.map +1 -0
- package/dist/tests/e2e/audit-sources-apply.test.js +166 -0
- package/dist/tests/e2e/audit-sources-apply.test.js.map +1 -0
- package/dist/tests/e2e/audit-sources-recovery.test.d.ts +15 -0
- package/dist/tests/e2e/audit-sources-recovery.test.d.ts.map +1 -0
- package/dist/tests/e2e/audit-sources-recovery.test.js +179 -0
- package/dist/tests/e2e/audit-sources-recovery.test.js.map +1 -0
- package/dist/tests/e2e/audit-sources-roundtrip.test.d.ts +23 -0
- package/dist/tests/e2e/audit-sources-roundtrip.test.d.ts.map +1 -0
- package/dist/tests/e2e/audit-sources-roundtrip.test.js +107 -0
- package/dist/tests/e2e/audit-sources-roundtrip.test.js.map +1 -0
- package/dist/tests/e2e/utils/source-recovery-fixture.d.ts +49 -0
- package/dist/tests/e2e/utils/source-recovery-fixture.d.ts.map +1 -0
- package/dist/tests/e2e/utils/source-recovery-fixture.js +106 -0
- package/dist/tests/e2e/utils/source-recovery-fixture.js.map +1 -0
- package/dist/tests/embedding-probe-stdio.test.d.ts +11 -0
- package/dist/tests/embedding-probe-stdio.test.d.ts.map +1 -0
- package/dist/tests/embedding-probe-stdio.test.js +58 -0
- package/dist/tests/embedding-probe-stdio.test.js.map +1 -0
- package/dist/tests/init.test.js +2 -1
- package/dist/tests/init.test.js.map +1 -1
- package/dist/tests/install-quarantine.test.d.ts +10 -0
- package/dist/tests/install-quarantine.test.d.ts.map +1 -0
- package/dist/tests/install-quarantine.test.js +86 -0
- package/dist/tests/install-quarantine.test.js.map +1 -0
- package/package.json +5 -5
- package/templates/skill-telemetry.cmd +16 -0
- package/templates/skill-telemetry.sh +199 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
# Skillsmith skill-invocation telemetry hook (SMI-5012 / SMI-5020 W3.S1).
|
|
3
|
+
#
|
|
4
|
+
# Invoked from ~/.claude/settings.json PreToolUse + PostToolUse matchers on
|
|
5
|
+
# the `Skill` tool. Captures skill-invocation latency telemetry for the
|
|
6
|
+
# Skillsmith /functions/v1/events endpoint.
|
|
7
|
+
#
|
|
8
|
+
# PRIVACY INVARIANTS (DO NOT WEAKEN):
|
|
9
|
+
# - NEVER reads `.tool_input.args` from the hook stdin payload. EVER.
|
|
10
|
+
# Only `.session_id` and `.tool_input.skill` are extracted.
|
|
11
|
+
# - NEVER captures absolute paths, cwd, env vars, or file contents.
|
|
12
|
+
# - NEVER blocks the user. Exits 0 in every code path. No `set -e`.
|
|
13
|
+
# - Curl is fire-and-forget (backgrounded + output redirected).
|
|
14
|
+
#
|
|
15
|
+
# CROSS-PLATFORM:
|
|
16
|
+
# - POSIX `sh` only (NOT bash). Runs on macOS /bin/sh (dash-equiv),
|
|
17
|
+
# Linux /bin/sh (dash/bash), and Git Bash on Windows (via .cmd shim).
|
|
18
|
+
# - `date +%s%3N` (GNU) falls back to `date +%s` (BSD/macOS) for second-
|
|
19
|
+
# precision when millisecond precision is unavailable.
|
|
20
|
+
#
|
|
21
|
+
# STATE:
|
|
22
|
+
# - Start files: $HOME/.skillsmith/run/skill-$SESSION-$SKILL.start
|
|
23
|
+
# Per M8: lives under ~/.skillsmith/run (NOT /tmp) so files survive
|
|
24
|
+
# reboot; orphans GC'd by next pre-call's 1h sweep.
|
|
25
|
+
#
|
|
26
|
+
# OPT-IN GATES (both must pass; checked before parsing stdin):
|
|
27
|
+
# 1. SKILLSMITH_TELEMETRY_DISABLE != "1" (panic switch env var)
|
|
28
|
+
# 2. ~/.skillsmith/config.json `.telemetry.enabled == true`
|
|
29
|
+
#
|
|
30
|
+
# VERIFICATION (1000-iteration micro-bench):
|
|
31
|
+
# PAYLOAD='{"session_id":"abc","tool_input":{"skill":"search"}}'
|
|
32
|
+
# for i in $(seq 1 1000); do
|
|
33
|
+
# printf '%s' "$PAYLOAD" | time \
|
|
34
|
+
# sh packages/cli/templates/skill-telemetry.sh pre
|
|
35
|
+
# done
|
|
36
|
+
# # Target: <25ms p95 EXCLUDING the backgrounded curl in `post`.
|
|
37
|
+
#
|
|
38
|
+
# Claude Code hook stdin contract:
|
|
39
|
+
# https://code.claude.com/docs/en/hooks.md
|
|
40
|
+
|
|
41
|
+
set -u
|
|
42
|
+
|
|
43
|
+
MODE="${1:-}"
|
|
44
|
+
|
|
45
|
+
# ---- Gate 1: panic switch ----
|
|
46
|
+
if [ "${SKILLSMITH_TELEMETRY_DISABLE:-}" = "1" ]; then
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# ---- Gate 2: jq availability (defensive; required by other Skillsmith hooks) ----
|
|
51
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
52
|
+
|
|
53
|
+
# ---- Gate 3: opt-in config (single jq invocation for all three reads) ----
|
|
54
|
+
CONFIG="${HOME}/.skillsmith/config.json"
|
|
55
|
+
if [ ! -f "$CONFIG" ]; then
|
|
56
|
+
exit 0
|
|
57
|
+
fi
|
|
58
|
+
# Output is newline-separated: enabled-bool, endpoint, anonymousId.
|
|
59
|
+
# `jq -e` here would require a separate call; we instead check the first
|
|
60
|
+
# line for "true" via `case`. One jq fork instead of three.
|
|
61
|
+
CFG_OUT="$(jq -r '
|
|
62
|
+
(.telemetry.enabled // false),
|
|
63
|
+
(.telemetry.endpoint // "https://vrcnzpmndtroqxxoqkzy.supabase.co/functions/v1/events"),
|
|
64
|
+
(.telemetry.anonymousId // "")
|
|
65
|
+
' "$CONFIG" 2>/dev/null)"
|
|
66
|
+
# POSIX line-extraction without spawning awk/sed.
|
|
67
|
+
CFG_ENABLED="${CFG_OUT%%
|
|
68
|
+
*}"
|
|
69
|
+
CFG_REST="${CFG_OUT#*
|
|
70
|
+
}"
|
|
71
|
+
ENDPOINT="${CFG_REST%%
|
|
72
|
+
*}"
|
|
73
|
+
ANON_ID="${CFG_REST#*
|
|
74
|
+
}"
|
|
75
|
+
case "$CFG_ENABLED" in
|
|
76
|
+
true) ;;
|
|
77
|
+
*) exit 0 ;;
|
|
78
|
+
esac
|
|
79
|
+
|
|
80
|
+
# ---- Parse Claude Code hook stdin payload (single jq for both reads) ----
|
|
81
|
+
# IMPORTANT: only `.session_id` and `.tool_input.skill` are extracted.
|
|
82
|
+
# `.tool_input.args` is NEVER read. See privacy invariants above.
|
|
83
|
+
PAYLOAD="$(cat 2>/dev/null || printf '%s' '{}')"
|
|
84
|
+
STDIN_OUT="$(printf '%s' "$PAYLOAD" | jq -r '(.session_id // ""), (.tool_input.skill // "")' 2>/dev/null)"
|
|
85
|
+
SESSION_ID="${STDIN_OUT%%
|
|
86
|
+
*}"
|
|
87
|
+
SKILL_NAME="${STDIN_OUT#*
|
|
88
|
+
}"
|
|
89
|
+
|
|
90
|
+
RUN_DIR="${HOME}/.skillsmith/run"
|
|
91
|
+
mkdir -p "$RUN_DIR" 2>/dev/null || true
|
|
92
|
+
|
|
93
|
+
# ---- Quarantine path: unparseable payload ----
|
|
94
|
+
# Per risk #13 (line 803): tool_input.skill shape changes ship a
|
|
95
|
+
# `skill_invoke_unparsed` event. Emit ONLY from `pre` so we don't
|
|
96
|
+
# double-count (post has no matching start file to read anyway).
|
|
97
|
+
if [ -z "$SESSION_ID" ] || [ -z "$SKILL_NAME" ]; then
|
|
98
|
+
if [ "$MODE" = "pre" ] && [ -n "$ANON_ID" ]; then
|
|
99
|
+
QUARANTINE_PAYLOAD="$(jq -n \
|
|
100
|
+
--arg event 'skill_invoke_unparsed' \
|
|
101
|
+
--arg anon "$ANON_ID" \
|
|
102
|
+
--arg source 'claude-code-hook' \
|
|
103
|
+
--arg framework 'claude-code' \
|
|
104
|
+
--arg platform "$(uname -s 2>/dev/null | tr '[:upper:]' '[:lower:]')" \
|
|
105
|
+
'{event:$event, anonymous_id:$anon, metadata:{source:$source, framework:$framework, platform:$platform, success:false}}' \
|
|
106
|
+
2>/dev/null)"
|
|
107
|
+
if [ -n "$QUARANTINE_PAYLOAD" ]; then
|
|
108
|
+
nohup curl -s -m 5 -X POST \
|
|
109
|
+
-H 'Content-Type: application/json' \
|
|
110
|
+
-d "$QUARANTINE_PAYLOAD" \
|
|
111
|
+
"$ENDPOINT" >/dev/null 2>&1 &
|
|
112
|
+
fi
|
|
113
|
+
fi
|
|
114
|
+
exit 0
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
START_FILE="$RUN_DIR/skill-${SESSION_ID}-${SKILL_NAME}.start"
|
|
118
|
+
|
|
119
|
+
case "$MODE" in
|
|
120
|
+
pre)
|
|
121
|
+
# GC orphans older than 1h (mtime), then record start time (ms epoch).
|
|
122
|
+
# `find -mmin` is portable across BSD (macOS) and GNU (Linux/Git Bash).
|
|
123
|
+
find "$RUN_DIR" -maxdepth 1 -name 'skill-*.start' -type f -mmin +60 -delete 2>/dev/null || true
|
|
124
|
+
NOW_MS="$(date +%s%3N 2>/dev/null)"
|
|
125
|
+
# BSD date doesn't support %3N — falls back to seconds with 000 suffix.
|
|
126
|
+
case "$NOW_MS" in
|
|
127
|
+
*N|'')
|
|
128
|
+
NOW_MS="$(date +%s 2>/dev/null)000"
|
|
129
|
+
;;
|
|
130
|
+
esac
|
|
131
|
+
printf '%s' "$NOW_MS" > "$START_FILE" 2>/dev/null || true
|
|
132
|
+
;;
|
|
133
|
+
|
|
134
|
+
post)
|
|
135
|
+
if [ ! -f "$START_FILE" ]; then
|
|
136
|
+
exit 0
|
|
137
|
+
fi
|
|
138
|
+
START_MS="$(cat "$START_FILE" 2>/dev/null)"
|
|
139
|
+
rm -f "$START_FILE" 2>/dev/null || true
|
|
140
|
+
if [ -z "$START_MS" ]; then
|
|
141
|
+
exit 0
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
NOW_MS="$(date +%s%3N 2>/dev/null)"
|
|
145
|
+
case "$NOW_MS" in
|
|
146
|
+
*N|'')
|
|
147
|
+
NOW_MS="$(date +%s 2>/dev/null)000"
|
|
148
|
+
;;
|
|
149
|
+
esac
|
|
150
|
+
|
|
151
|
+
# Pure-sh integer arithmetic; both operands are integers above.
|
|
152
|
+
DURATION_MS=$((NOW_MS - START_MS))
|
|
153
|
+
if [ "$DURATION_MS" -lt 0 ]; then
|
|
154
|
+
DURATION_MS=0
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
# If no anonymous id has been provisioned yet, we have nothing to send.
|
|
158
|
+
if [ -z "$ANON_ID" ]; then
|
|
159
|
+
exit 0
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
PLATFORM="$(uname -s 2>/dev/null | tr '[:upper:]' '[:lower:]')"
|
|
163
|
+
|
|
164
|
+
# Build payload (see wire format at skill-invoke-telemetry.md:614-643).
|
|
165
|
+
# NOTE: only $SKILL_NAME and $SESSION_ID flow from stdin → payload.
|
|
166
|
+
# No args, no paths, no env vars.
|
|
167
|
+
PAYLOAD_JSON="$(jq -n \
|
|
168
|
+
--arg event 'skill_invoke' \
|
|
169
|
+
--arg anon "$ANON_ID" \
|
|
170
|
+
--arg skill "$SKILL_NAME" \
|
|
171
|
+
--arg session "$SESSION_ID" \
|
|
172
|
+
--argjson dur "$DURATION_MS" \
|
|
173
|
+
--arg source 'claude-code-hook' \
|
|
174
|
+
--arg framework 'claude-code' \
|
|
175
|
+
--arg platform "$PLATFORM" \
|
|
176
|
+
'{event:$event, anonymous_id:$anon, metadata:{skill_name:$skill, session_id:$session, duration_ms:$dur, source:$source, framework:$framework, platform:$platform, success:true, is_subagent:false}}' \
|
|
177
|
+
2>/dev/null)"
|
|
178
|
+
|
|
179
|
+
if [ -z "$PAYLOAD_JSON" ]; then
|
|
180
|
+
exit 0
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
# Fire-and-forget. `nohup` + `&` + redirected fd's mean the parent
|
|
184
|
+
# shell does not wait on the curl process. `-m 5` caps the curl at
|
|
185
|
+
# 5s in case the endpoint is unreachable (no impact on hook latency
|
|
186
|
+
# because the curl is already detached).
|
|
187
|
+
nohup curl -s -m 5 -X POST \
|
|
188
|
+
-H 'Content-Type: application/json' \
|
|
189
|
+
-d "$PAYLOAD_JSON" \
|
|
190
|
+
"$ENDPOINT" >/dev/null 2>&1 &
|
|
191
|
+
;;
|
|
192
|
+
|
|
193
|
+
*)
|
|
194
|
+
# Unknown mode — silently exit. Belt-and-suspenders.
|
|
195
|
+
:
|
|
196
|
+
;;
|
|
197
|
+
esac
|
|
198
|
+
|
|
199
|
+
exit 0
|