fix(hooks): after-write dedups its channel files; prior-art tests follow the extractor and skip list into scribe_defs.sh (#2901)
Run 4240: two pre-write hook tests pinned the skip case and scribe_defs() inside scribe_prior_art.sh, which moved to the shared library; the after-write test saw the same derive key appended once per changed file. Keep each token once (sort -u after the appends) and point the pins at the library. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -187,6 +187,11 @@ while IFS= read -r rel_path; do
|
|||||||
printf '%s' "$body" | jq -r '((.note_ids // []) - (.sync_note_ids // []))[]?' 2>/dev/null >> "$idfile" || true
|
printf '%s' "$body" | jq -r '((.note_ids // []) - (.sync_note_ids // []))[]?' 2>/dev/null >> "$idfile" || true
|
||||||
printf '%s' "$body" | jq -r '(.sync_note_ids // [])[]?' 2>/dev/null >> "$syncfile" || true
|
printf '%s' "$body" | jq -r '(.sync_note_ids // [])[]?' 2>/dev/null >> "$syncfile" || true
|
||||||
printf '%s' "$body" | jq -r '(.derive_keys // [])[]?' 2>/dev/null >> "$derivefile" || true
|
printf '%s' "$body" | jq -r '(.derive_keys // [])[]?' 2>/dev/null >> "$derivefile" || true
|
||||||
|
# Several files in one call may name the same family: keep each
|
||||||
|
# token once, so the next request's exclude list stays exact.
|
||||||
|
for f in "$idfile" "$syncfile" "$derivefile"; do
|
||||||
|
[ -s "$f" ] && { sort -u -o "$f" "$f" 2>/dev/null || true; }
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -853,14 +853,18 @@ def test_hook_exits_silently_when_unconfigured():
|
|||||||
|
|
||||||
|
|
||||||
def test_hook_skips_prose_and_data_files():
|
def test_hook_skips_prose_and_data_files():
|
||||||
"""No round-trip for a markdown edit — the server would return nothing anyway."""
|
"""No round-trip for a markdown edit — the server would return nothing
|
||||||
src = HOOK.read_text()
|
anyway. The list lives in the shared library (#2901) and the hook asks it."""
|
||||||
skip = re.search(r"case \"\$file_path\" in\n(.*?)esac", src, re.S)
|
lib = (PLUGIN / "hooks" / "scribe_defs.sh").read_text()
|
||||||
assert skip, "expected an extension skip list"
|
skip = re.search(r"scribe_skip_path\(\) \{\n case \"\$1\" in\n(.*?)esac", lib, re.S)
|
||||||
|
assert skip, "expected an extension skip list in scribe_defs.sh"
|
||||||
for ext in ("*.md", "*.json", "*.lock", "*.png"):
|
for ext in ("*.md", "*.json", "*.lock", "*.png"):
|
||||||
assert ext in skip.group(1)
|
assert ext in skip.group(1)
|
||||||
# Config formats are deliberately NOT skipped — a workflow file is reusable.
|
# Config formats are deliberately NOT skipped — a workflow file is reusable.
|
||||||
assert "*.yml" not in skip.group(1)
|
assert "*.yml" not in skip.group(1)
|
||||||
|
src = HOOK.read_text()
|
||||||
|
assert 'scribe_skip_path "$file_path" && exit 0' in src
|
||||||
|
assert '/scribe_defs.sh"' in src # sourced, not copied
|
||||||
|
|
||||||
|
|
||||||
def test_plugin_version_bumped_with_the_hook():
|
def test_plugin_version_bumped_with_the_hook():
|
||||||
@@ -1150,7 +1154,9 @@ def test_hook_names_the_shapes_being_written():
|
|||||||
that changes a body, not a signature — the definition enclosing the edit,
|
that changes a body, not a signature — the definition enclosing the edit,
|
||||||
found by walking the target file upward from the edited lines."""
|
found by walking the target file upward from the edited lines."""
|
||||||
src = HOOK.read_text()
|
src = HOOK.read_text()
|
||||||
assert "scribe_defs()" in src # one extractor, two consumers
|
lib = (PLUGIN / "hooks" / "scribe_defs.sh").read_text()
|
||||||
|
assert "scribe_defs()" in lib # one extractor, shared (#2901)
|
||||||
|
assert "scribe_defs()" not in src # ...not a second copy here
|
||||||
assert ".tool_input.old_string" in src # the Edit's anchor
|
assert ".tool_input.old_string" in src # the Edit's anchor
|
||||||
assert "| tac | scribe_defs | head -1" in src # nearest definition above
|
assert "| tac | scribe_defs | head -1" in src # nearest definition above
|
||||||
# The ledger feed sends NAMES, never bodies, and stays on the one GET.
|
# The ledger feed sends NAMES, never bodies, and stays on the one GET.
|
||||||
|
|||||||
Reference in New Issue
Block a user