@rulemetric/hooks 0.12.7 → 0.13.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.
- package/package.json +3 -2
- package/scripts/jq +8 -0
- package/scripts/session-end.sh +20 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulemetric/hooks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"vitest": "^3.2.4"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"test": "vitest run"
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"lint": "eslint ."
|
|
20
21
|
}
|
|
21
22
|
}
|
package/scripts/jq
CHANGED
|
@@ -378,6 +378,14 @@ def run():
|
|
|
378
378
|
if files:
|
|
379
379
|
with open(files[0], "r", encoding="utf-8") as handle:
|
|
380
380
|
stdin = handle.read()
|
|
381
|
+
elif "n" in flags and not re.search(r"\binputs\b", filter_):
|
|
382
|
+
# Real jq does NOT read stdin under -n/--null-input — its input is
|
|
383
|
+
# null. Reading it anyway made a bare `jq -n --arg k v '{k:$k}'` block
|
|
384
|
+
# forever when the caller attached an open-but-silent stdin (a harness
|
|
385
|
+
# with no heredoc), a divergence invisible in tests that close stdin.
|
|
386
|
+
# `inputs` is the one construct that consumes the stream even under -n
|
|
387
|
+
# and is handled below from this same variable, so it still reads.
|
|
388
|
+
stdin = ""
|
|
381
389
|
else:
|
|
382
390
|
stdin = sys.stdin.read()
|
|
383
391
|
|
package/scripts/session-end.sh
CHANGED
|
@@ -95,12 +95,26 @@ _rulemetric_log "session-end" "success"
|
|
|
95
95
|
# ── Emit a synthetic instruction snapshot (hooks-first, zero-proxy linking) ──
|
|
96
96
|
# The proxy classifies the rendered system prompt into context_items that
|
|
97
97
|
# link-instructions matches on. Hooks-only sessions have no proxy, so build an
|
|
98
|
-
# equivalent snapshot from on-disk
|
|
99
|
-
# it must land before the backgrounded link-instructions call
|
|
100
|
-
# a failure never breaks session-end (see the ERR trap guard).
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
# equivalent snapshot from the on-disk instruction files and POST it
|
|
99
|
+
# SYNCHRONOUSLY — it must land before the backgrounded link-instructions call
|
|
100
|
+
# below. Best-effort: a failure never breaks session-end (see the ERR trap guard).
|
|
101
|
+
#
|
|
102
|
+
# The tool is PASSED, not assumed: each harness reads a different file
|
|
103
|
+
# (CLAUDE.md / AGENTS.md / .github/copilot-instructions.md). This block used to
|
|
104
|
+
# be gated on claude_code alone, so a Codex or Copilot project could have a rule
|
|
105
|
+
# adopted into the file its agent reads while linking never saw it. The command
|
|
106
|
+
# prints nothing for a tool it does not know, so an unrecognised HOOK_TOOL is a
|
|
107
|
+
# no-op rather than a CLAUDE.md attributed to the wrong harness.
|
|
108
|
+
#
|
|
109
|
+
# Kept in its OWN variable: HOOK_TOOL is still read further down (the transcript
|
|
110
|
+
# reimport is claude_code-only), so narrowing it here would silently disable
|
|
111
|
+
# that block too.
|
|
112
|
+
case "$HOOK_TOOL" in
|
|
113
|
+
claude_code|codex|copilot_agent|copilot_cli|vscode_copilot) SNAPSHOT_TOOL="$HOOK_TOOL" ;;
|
|
114
|
+
*) SNAPSHOT_TOOL="" ;;
|
|
115
|
+
esac
|
|
116
|
+
if [ -n "$SNAPSHOT_TOOL" ]; then
|
|
117
|
+
INSTR_SNAPSHOT=$(rulemetric hooks emit-instructions --project-dir "${HOOK_CWD:-$(pwd)}" --tool "$SNAPSHOT_TOOL" 2>/dev/null || true)
|
|
104
118
|
if [ -n "$INSTR_SNAPSHOT" ]; then
|
|
105
119
|
# Bounded 503/429 retry — this snapshot is the ONLY instruction-linking
|
|
106
120
|
# signal a hooks-only (no-proxy) session ever emits; a one-shot curl made
|