rails-informant 0.4.7 → 0.5.0
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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ebe80aab76837ee09279a0831b344bca9072a873e48b70197868e54a7b5a6ceb
|
|
4
|
+
data.tar.gz: f637b4e6f460bbb982a2c3f51b49d87cb3fcaa8e6fd2c3547a694fc0f4fa70fc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '08bf946e26795a53d035667fad63f91ccf5dda9497710a09d9e187d82ee35323ed64397b4761a8af6e81896d915df47e4a6b3f94777e5150fb3250262db6c5ba'
|
|
7
|
+
data.tar.gz: 8fe9bb913213f18310a90ff232f11c1317246b231aeec3c9afba80c4e253d017dff9e41a829d90df5beee43f9dade333eb4317c24831340b1fdeabf50e068b02
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Informant:
|
|
2
|
+
# Informant: On the first Claude Code prompt of a session, check for unresolved
|
|
3
|
+
# production errors — unless that first prompt is the /informant command.
|
|
3
4
|
# Requires: curl, jq
|
|
4
5
|
# Env vars: INFORMANT_PRODUCTION_URL, INFORMANT_PRODUCTION_TOKEN
|
|
5
6
|
# INFORMANT_PRODUCTION_PATH_PREFIX (optional, default: /informant)
|
|
@@ -11,9 +12,28 @@ set -euo pipefail
|
|
|
11
12
|
[[ -z "${INFORMANT_PRODUCTION_TOKEN:-}" ]] && exit 0
|
|
12
13
|
[[ "$INFORMANT_PRODUCTION_URL" == https://* ]] || exit 0
|
|
13
14
|
|
|
14
|
-
# Silent exit if jq is not installed
|
|
15
|
+
# Silent exit if jq is not installed (needed to parse the hook payload)
|
|
15
16
|
command -v jq >/dev/null 2>&1 || exit 0
|
|
16
17
|
|
|
18
|
+
# UserPromptSubmit delivers a JSON payload on stdin carrying session_id and prompt.
|
|
19
|
+
payload=$(cat)
|
|
20
|
+
session_id=$(printf '%s' "$payload" | jq -r '.session_id // empty' 2>/dev/null || true)
|
|
21
|
+
|
|
22
|
+
# Run at most once per session, on the first prompt: a marker keyed by session_id
|
|
23
|
+
# records that this session was handled, so later prompts short-circuit here before
|
|
24
|
+
# parsing the prompt or doing network work. Require a token-shaped session_id (it is
|
|
25
|
+
# interpolated into the path below) and stay silent when we can't record the marker,
|
|
26
|
+
# rather than re-alerting on every later prompt of the session.
|
|
27
|
+
[[ "$session_id" =~ ^[A-Za-z0-9_-]+$ ]] || exit 0
|
|
28
|
+
marker="${TMPDIR:-/tmp}/rails-informant-alert-${session_id}"
|
|
29
|
+
[[ -e "$marker" ]] && exit 0
|
|
30
|
+
: > "$marker" 2>/dev/null || exit 0
|
|
31
|
+
|
|
32
|
+
# Stay quiet for the whole session when the first prompt is the /informant command —
|
|
33
|
+
# the user is already triaging errors, so the startup alert would be redundant.
|
|
34
|
+
prompt=$(printf '%s' "$payload" | jq -r '.prompt // empty' 2>/dev/null || true)
|
|
35
|
+
[[ "$prompt" =~ ^/informant($|[[:space:]]) ]] && exit 0
|
|
36
|
+
|
|
17
37
|
path_prefix="${INFORMANT_PRODUCTION_PATH_PREFIX:-/informant}"
|
|
18
38
|
url="${INFORMANT_PRODUCTION_URL}${path_prefix}/api/v1/status"
|
|
19
39
|
|
|
@@ -25,8 +45,9 @@ response=$(curl -s -f \
|
|
|
25
45
|
"$url" <<< "Authorization: Bearer ${INFORMANT_PRODUCTION_TOKEN}" \
|
|
26
46
|
2>/dev/null) || exit 0
|
|
27
47
|
|
|
28
|
-
# Parse unresolved count
|
|
29
|
-
unresolved=$(echo "$response" | jq -r '.unresolved_count // 0') || exit 0
|
|
48
|
+
# Parse unresolved count (silent exit on a missing or non-numeric value)
|
|
49
|
+
unresolved=$(echo "$response" | jq -r '.unresolved_count // 0' 2>/dev/null) || exit 0
|
|
50
|
+
[[ "$unresolved" =~ ^[0-9]+$ ]] || exit 0
|
|
30
51
|
[[ "$unresolved" -eq 0 ]] && exit 0
|
|
31
52
|
|
|
32
53
|
# Format error summary
|
|
@@ -39,20 +39,20 @@ module RailsInformant
|
|
|
39
39
|
if File.exist?(settings_path)
|
|
40
40
|
existing = JSON.parse(File.read(settings_path))
|
|
41
41
|
existing["hooks"] ||= {}
|
|
42
|
-
existing["hooks"]["
|
|
42
|
+
existing["hooks"]["UserPromptSubmit"] ||= []
|
|
43
43
|
|
|
44
|
-
already_registered = existing["hooks"]["
|
|
44
|
+
already_registered = existing["hooks"]["UserPromptSubmit"].any? do |entry|
|
|
45
45
|
entry["hooks"]&.any? { it["command"] == hook_command }
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
unless already_registered
|
|
49
|
-
existing["hooks"]["
|
|
49
|
+
existing["hooks"]["UserPromptSubmit"] << user_prompt_submit_hook(hook_command)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
create_file ".claude/settings.json", JSON.pretty_generate(existing) + "\n", force: true
|
|
53
53
|
else
|
|
54
54
|
create_file ".claude/settings.json", JSON.pretty_generate(
|
|
55
|
-
"hooks" => { "
|
|
55
|
+
"hooks" => { "UserPromptSubmit" => [ user_prompt_submit_hook(hook_command) ] }
|
|
56
56
|
) + "\n"
|
|
57
57
|
end
|
|
58
58
|
rescue JSON::ParserError
|
|
@@ -66,7 +66,7 @@ module RailsInformant
|
|
|
66
66
|
say " Created .mcp.json"
|
|
67
67
|
say " Created .claude/skills/informant/SKILL.md"
|
|
68
68
|
say " Created .claude/hooks/informant-alerts.sh"
|
|
69
|
-
say " Created .claude/settings.json (
|
|
69
|
+
say " Created .claude/settings.json (UserPromptSubmit hook)"
|
|
70
70
|
say ""
|
|
71
71
|
say "Next step — set env vars so the MCP server and startup alerts can reach your app.", :yellow
|
|
72
72
|
say "Add to your .envrc (or export manually):"
|
|
@@ -82,9 +82,8 @@ module RailsInformant
|
|
|
82
82
|
|
|
83
83
|
private
|
|
84
84
|
|
|
85
|
-
def
|
|
85
|
+
def user_prompt_submit_hook(command)
|
|
86
86
|
{
|
|
87
|
-
"matcher" => "startup",
|
|
88
87
|
"hooks" => [
|
|
89
88
|
{ "type" => "command", "command" => command, "timeout" => 10 }
|
|
90
89
|
]
|