@windyroad/risk-scorer 0.17.1 → 0.17.2

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.
@@ -310,5 +310,5 @@
310
310
  }
311
311
  },
312
312
  "name": "wr-risk-scorer",
313
- "version": "0.17.1"
313
+ "version": "0.17.2"
314
314
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wr-risk-scorer",
3
- "version": "0.17.1",
3
+ "version": "0.17.2",
4
4
  "description": "Pipeline risk scoring, commit/push gates, and secret leak detection",
5
5
  "author": {
6
6
  "name": "Windy Road Technology",
package/hooks/hooks.json CHANGED
@@ -4,23 +4,13 @@
4
4
  { "matcher": "startup", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-scorer-scaffold-nudge.sh" }] }
5
5
  ],
6
6
  "UserPromptSubmit": [
7
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-score.sh" }] },
8
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/staleness-check.sh" }] }
7
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-scorer-dispatch.sh user-prompt" }] }
9
8
  ],
10
9
  "PreToolUse": [
11
- { "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/secret-leak-gate.sh" }, { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/wip-risk-gate.sh" }] },
12
- { "matcher": "Bash", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/git-push-gate.sh" }] },
13
- { "matcher": "Bash", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-score-commit-gate.sh" }] },
14
- { "matcher": "Bash|Edit|Write", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/external-comms-gate.sh" }] },
15
- { "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-policy-enforce-edit.sh" }] },
16
- { "matcher": "ExitPlanMode", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-score-plan-enforce.sh" }] },
17
- { "matcher": "EnterPlanMode", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/plan-risk-guidance.sh" }] }
10
+ { "matcher": "Bash|Edit|Write|ExitPlanMode|EnterPlanMode", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-scorer-dispatch.sh pre-tool" }] }
18
11
  ],
19
12
  "PostToolUse": [
20
- { "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/wip-risk-mark.sh" }] },
21
- { "matcher": "Agent", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-score-mark.sh" }] },
22
- { "matcher": "Bash", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-hash-refresh.sh" }] },
23
- { "matcher": "Agent|Bash|Skill", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-slide-marker.sh" }] }
13
+ { "matcher": "Agent|Bash|Skill", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-scorer-dispatch.sh post-tool" }] }
24
14
  ]
25
15
  }
26
16
  }
@@ -0,0 +1,67 @@
1
+ #!/bin/bash
2
+ # Fan out risk-scorer hooks from one registered hook per event.
3
+
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ EVENT="${1:-}"
8
+ INPUT="$(cat)"
9
+
10
+ run_hook() {
11
+ local output
12
+ output="$(printf '%s' "$INPUT" | "$SCRIPT_DIR/$1")"
13
+ if [ -n "$output" ]; then
14
+ printf '%s\n' "$output"
15
+ exit 0
16
+ fi
17
+ }
18
+
19
+ tool_name() {
20
+ printf '%s' "$INPUT" | python3 -c 'import json,sys; print((json.load(sys.stdin).get("tool_name") or ""))' 2>/dev/null || true
21
+ }
22
+
23
+ case "$EVENT" in
24
+ user-prompt)
25
+ run_hook risk-score.sh
26
+ run_hook staleness-check.sh
27
+ ;;
28
+ pre-tool)
29
+ case "$(tool_name)" in
30
+ Edit|Write)
31
+ run_hook secret-leak-gate.sh
32
+ run_hook wip-risk-gate.sh
33
+ run_hook external-comms-gate.sh
34
+ run_hook risk-policy-enforce-edit.sh
35
+ ;;
36
+ Bash)
37
+ run_hook git-push-gate.sh
38
+ run_hook risk-score-commit-gate.sh
39
+ run_hook external-comms-gate.sh
40
+ ;;
41
+ ExitPlanMode)
42
+ run_hook risk-score-plan-enforce.sh
43
+ ;;
44
+ EnterPlanMode)
45
+ run_hook plan-risk-guidance.sh
46
+ ;;
47
+ esac
48
+ ;;
49
+ post-tool)
50
+ case "$(tool_name)" in
51
+ Agent)
52
+ run_hook risk-score-mark.sh
53
+ run_hook risk-slide-marker.sh
54
+ ;;
55
+ Bash)
56
+ run_hook risk-hash-refresh.sh
57
+ run_hook risk-slide-marker.sh
58
+ ;;
59
+ Skill)
60
+ run_hook risk-slide-marker.sh
61
+ ;;
62
+ esac
63
+ ;;
64
+ *)
65
+ exit 0
66
+ ;;
67
+ esac
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env bats
2
+
3
+ setup() {
4
+ REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
5
+ HOOKS="$REPO_ROOT/packages/risk-scorer/hooks"
6
+ }
7
+
8
+ @test "hooks.json registers four command hooks" {
9
+ run python3 - "$HOOKS/hooks.json" <<'PY'
10
+ import json, sys
11
+ data = json.load(open(sys.argv[1]))
12
+ print(sum(len(entry["hooks"]) for entries in data["hooks"].values() for entry in entries))
13
+ PY
14
+ [ "$status" -eq 0 ]
15
+ [ "$output" = "4" ]
16
+ }
17
+
18
+ @test "dispatcher is registered for prompt, pre-tool, and post-tool events" {
19
+ run grep -n "risk-scorer-dispatch.sh user-prompt" "$HOOKS/hooks.json"
20
+ [ "$status" -eq 0 ]
21
+ run grep -n "risk-scorer-dispatch.sh pre-tool" "$HOOKS/hooks.json"
22
+ [ "$status" -eq 0 ]
23
+ run grep -n "risk-scorer-dispatch.sh post-tool" "$HOOKS/hooks.json"
24
+ [ "$status" -eq 0 ]
25
+ }
26
+
27
+ @test "dispatcher routes Write through the secret leak gate" {
28
+ local fake_key input
29
+ fake_key="AKIA""ABCDEFGHIJKLMNOP"
30
+ input="$(python3 - "$fake_key" <<'PY'
31
+ import json, sys
32
+ print(json.dumps({
33
+ "tool_name": "Write",
34
+ "session_id": "dispatch-test",
35
+ "tool_input": {"file_path": "src/example.txt", "content": sys.argv[1]},
36
+ }))
37
+ PY
38
+ )"
39
+
40
+ run bash "$HOOKS/risk-scorer-dispatch.sh" pre-tool <<<"$input"
41
+ [ "$status" -eq 0 ]
42
+ [[ "$output" == *"permissionDecision"* ]]
43
+ [[ "$output" == *"deny"* ]]
44
+ [[ "$output" == *"AWS access key"* ]]
45
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/risk-scorer",
3
- "version": "0.17.1",
3
+ "version": "0.17.2",
4
4
  "description": "Pipeline risk scoring, commit/push gates, and secret leak detection",
5
5
  "bin": {
6
6
  "windyroad-risk-scorer": "./bin/install.mjs"