@thebassclef/lite 1.9.3 → 1.9.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/README.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/bassclef-version.json +5 -5
- package/dist/lite/lib/bassclef-dir-resolver.sh +20 -14
- package/dist/lite/presence/install/bassclef-hook-connect.sh +56 -2
- package/dist/lite/standards/lite-manifest.json +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ your browser.
|
|
|
63
63
|
|
|
64
64
|
## Current release
|
|
65
65
|
|
|
66
|
-
<!-- version-start -->1.9.
|
|
66
|
+
<!-- version-start -->1.9.4<!-- version-end -->
|
|
67
67
|
|
|
68
68
|
See [CHANGELOG.md](CHANGELOG.md) for the full changelog. Adopter-facing
|
|
69
69
|
release notes live at [docs.bassclef.dev/docs/whats-new/releases](https://docs.bassclef.dev/docs/whats-new/releases).
|
package/dist/index.cjs
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version: "1.9.
|
|
1
|
+
export declare const version: "1.9.4";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "v1.
|
|
3
|
-
"marker_tag": "release-2026-09-
|
|
4
|
-
"release_date": "2026-09-
|
|
5
|
-
"release_sha": "
|
|
6
|
-
"release_tag": "release-2026-09-
|
|
2
|
+
"version": "v1.6.0",
|
|
3
|
+
"marker_tag": "release-2026-09-26-db89d305",
|
|
4
|
+
"release_date": "2026-09-26T12:19:56Z",
|
|
5
|
+
"release_sha": "db89d305",
|
|
6
|
+
"release_tag": "release-2026-09-26-db89d305"
|
|
7
7
|
}
|
|
@@ -8,14 +8,17 @@
|
|
|
8
8
|
# file at $HOME/.claude/hooks/, not a symlink to a checkout).
|
|
9
9
|
#
|
|
10
10
|
# The resolver probes four paths in order per Chain-of-Responsibility:
|
|
11
|
-
# 1.
|
|
12
|
-
#
|
|
13
|
-
#
|
|
11
|
+
# 1. Bundled path — walk up from $HOOK_REAL_PATH with sentinel present
|
|
12
|
+
# (was Check 3 pre-#1954; moved to Check 1 for #1953 shadow class cure —
|
|
13
|
+
# adopters with adjacent bassclef checkouts now get the npm install path)
|
|
14
|
+
# 2. Peer-checkout — $CWD/../bassclef with sentinel file present
|
|
15
|
+
# 3. $HOME/bassclef — tarball adopter path with sentinel file present
|
|
14
16
|
# 4. Fallback — $CWD (adopter repo); safer than $HOME because the files
|
|
15
17
|
# fragments want ship into the repo via bassclef init
|
|
16
18
|
#
|
|
17
19
|
# The sentinel file is presence/install/bassclef-hook-connect.sh. Every
|
|
18
20
|
# probe requires it — an empty peer dir or empty $HOME/bassclef does NOT win.
|
|
21
|
+
# Nygard R1 fold — bundled probe fail-through preserves peer-checkout adopters.
|
|
19
22
|
#
|
|
20
23
|
# Silent contract: never crashes, never writes to stderr on the resolve path.
|
|
21
24
|
# Consumers (13 fragments plus session-reflection.sh coordinator) treat the
|
|
@@ -42,17 +45,9 @@ resolve_bassclef_dir() {
|
|
|
42
45
|
local home_dir="${HOME_OVERRIDE:-${HOME:-/nonexistent}}"
|
|
43
46
|
local sentinel="presence/install/bassclef-hook-connect.sh"
|
|
44
47
|
|
|
45
|
-
# 1.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
fi
|
|
49
|
-
|
|
50
|
-
# 2. $HOME/bassclef — tarball adopter path
|
|
51
|
-
if [ -d "$home_dir/bassclef" ] && [ -f "$home_dir/bassclef/$sentinel" ]; then
|
|
52
|
-
printf '%s\n' "$home_dir/bassclef" && return 0
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
# 3. Bundled path — walk up two levels from dispatcher
|
|
48
|
+
# 1. Bundled path — walk up two levels from dispatcher (SWAPPED to Check 1
|
|
49
|
+
# per #1954 Layer 1a — closes #1953 shadow class where an adjacent
|
|
50
|
+
# bassclef checkout at $CWD/../bassclef was winning over the npm install).
|
|
56
51
|
if [ -n "$hook_path" ]; then
|
|
57
52
|
local candidate
|
|
58
53
|
candidate="$( cd "$(dirname "$hook_path")/../.." 2>/dev/null && pwd )" || candidate=""
|
|
@@ -61,6 +56,17 @@ resolve_bassclef_dir() {
|
|
|
61
56
|
fi
|
|
62
57
|
fi
|
|
63
58
|
|
|
59
|
+
# 2. Peer-checkout — sibling bassclef dir next to $CWD (Nygard R1 fold —
|
|
60
|
+
# preserves peer-checkout adopters when bundled probe fails).
|
|
61
|
+
if [ -d "$cwd/../bassclef" ] && [ -f "$cwd/../bassclef/$sentinel" ]; then
|
|
62
|
+
( cd "$cwd/../bassclef" 2>/dev/null && pwd ) && return 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# 3. $HOME/bassclef — tarball adopter path
|
|
66
|
+
if [ -d "$home_dir/bassclef" ] && [ -f "$home_dir/bassclef/$sentinel" ]; then
|
|
67
|
+
printf '%s\n' "$home_dir/bassclef" && return 0
|
|
68
|
+
fi
|
|
69
|
+
|
|
64
70
|
# 4. Fallback — $CWD (adopter repo). Safer than $HOME because the files
|
|
65
71
|
# fragments want (init manifest, presence/install/*) ship into the repo.
|
|
66
72
|
( cd "$cwd" 2>/dev/null && pwd ) || printf '%s\n' "$cwd"
|
|
@@ -241,13 +241,58 @@ bassclef_hook_connect_apply() {
|
|
|
241
241
|
echo "[bassclef-hook-connect] no tier declared in .bassclef-source.json — merging all wires (grace window). Set tier: lite to filter." >&2
|
|
242
242
|
fi
|
|
243
243
|
|
|
244
|
+
# === Filter-on-read (bassclef-upstream#1954) ===
|
|
245
|
+
# For each bassclef hook command, verify the target file exists at
|
|
246
|
+
# $bassclef_root/.claude/hooks/<basename>. Skip any entry whose target is
|
|
247
|
+
# missing. Log every skip to stderr. Emit warn banner over threshold.
|
|
248
|
+
# Saltzer-Schroeder R4 fold — matches both $CLAUDE_PROJECT_DIR- and
|
|
249
|
+
# $HOME-prefixed commands via basename extraction from .claude/hooks/ path.
|
|
250
|
+
# Nygard R2 mitigation — [ -f ] with symlink follow.
|
|
251
|
+
local present_re=""
|
|
252
|
+
local skip_count=0
|
|
253
|
+
local skipped_targets_file="$adopter_cwd/.bassclef-hook-connect-skipped.$$.tmp"
|
|
254
|
+
: > "$skipped_targets_file"
|
|
255
|
+
local present_basenames_file="$adopter_cwd/.bassclef-hook-connect-present.$$.tmp"
|
|
256
|
+
: > "$present_basenames_file"
|
|
257
|
+
local bhc_cmd bhc_base bhc_target
|
|
258
|
+
while IFS= read -r bhc_cmd; do
|
|
259
|
+
[ -z "$bhc_cmd" ] && continue
|
|
260
|
+
bhc_base=$(echo "$bhc_cmd" | grep -oE '\.claude/hooks/[^"'"'"'[:space:]\\]+\.sh' | head -1 | sed 's#\.claude/hooks/##')
|
|
261
|
+
if [ -z "$bhc_base" ]; then
|
|
262
|
+
continue
|
|
263
|
+
fi
|
|
264
|
+
bhc_target="$bassclef_root/.claude/hooks/$bhc_base"
|
|
265
|
+
if [ -f "$bhc_target" ] || [ -L "$bhc_target" ]; then
|
|
266
|
+
echo "$bhc_base" >> "$present_basenames_file"
|
|
267
|
+
else
|
|
268
|
+
echo "$bhc_target" >> "$skipped_targets_file"
|
|
269
|
+
skip_count=$((skip_count + 1))
|
|
270
|
+
echo "[bassclef-hook-connect] skip — target missing at $bhc_target" >&2
|
|
271
|
+
fi
|
|
272
|
+
done < <(jq -r '.hooks // {} | to_entries[] | .value[]? | .hooks[]? | .command // empty' "$bassclef_settings" 2>/dev/null)
|
|
273
|
+
|
|
274
|
+
if [ -s "$present_basenames_file" ]; then
|
|
275
|
+
present_re=$(sort -u "$present_basenames_file" | sed 's/\.sh$//' | paste -sd'|' -)
|
|
276
|
+
fi
|
|
277
|
+
|
|
278
|
+
# Warn banner over threshold. Threshold=0 disables banner but per-skip
|
|
279
|
+
# stderr above still fires.
|
|
280
|
+
local warn_threshold="${BASSCLEF_HOOK_CONNECT_SKIP_WARN:-5}"
|
|
281
|
+
if [ "$skip_count" -gt 0 ] && [ "$warn_threshold" -gt 0 ] && [ "$skip_count" -gt "$warn_threshold" ]; then
|
|
282
|
+
echo "[bassclef-hook-connect] WARN — $skip_count entries skipped (target files missing). Top 3:" >&2
|
|
283
|
+
sort -u "$skipped_targets_file" | head -3 | sed 's/^/ - /' >&2
|
|
284
|
+
echo " Set BASSCLEF_HOOK_CONNECT_SKIP_WARN=N to change threshold, or 0 to disable banner." >&2
|
|
285
|
+
fi
|
|
286
|
+
rm -f "$present_basenames_file" "$skipped_targets_file"
|
|
287
|
+
|
|
244
288
|
# Merge every hook entry from every event type. Preserves operator-owned
|
|
245
289
|
# entries. Adds bassclef entries under matching (event, matcher) pairs
|
|
246
290
|
# without duplicating commands. Skips Lane 3 hooks at $CLAUDE_PROJECT_DIR
|
|
247
291
|
# per <consumer-repo>#1262. Filters off-tier entries when tier_re non-empty
|
|
248
|
-
# per bassclef-upstream#1946.
|
|
292
|
+
# per bassclef-upstream#1946. Filters missing-target entries when
|
|
293
|
+
# present_re non-empty per bassclef-upstream#1954.
|
|
249
294
|
local merged
|
|
250
|
-
merged=$(jq --slurpfile bassclef "$bassclef_settings" --arg lane3re "$lane3_re" --arg tierre "$tier_re" '
|
|
295
|
+
merged=$(jq --slurpfile bassclef "$bassclef_settings" --arg lane3re "$lane3_re" --arg tierre "$tier_re" --arg presentre "$present_re" '
|
|
251
296
|
. as $adopter
|
|
252
297
|
| ($bassclef[0].hooks // {}) as $bhooks
|
|
253
298
|
| .hooks //= {}
|
|
@@ -264,6 +309,15 @@ bassclef_hook_connect_apply() {
|
|
|
264
309
|
# tier manifest set. Empty tier_re means no filter (fallback).
|
|
265
310
|
($tierre == "") or
|
|
266
311
|
((.command // "") | test("\\.claude/hooks/(" + $tierre + ")\\.sh"))
|
|
312
|
+
)) | map(select(
|
|
313
|
+
# Filter-on-read (bassclef-upstream#1954): keep only entries whose
|
|
314
|
+
# target hook file exists at $bassclef_root/.claude/hooks/<basename>.
|
|
315
|
+
# Empty present_re means no filter (fallback merge-all — matches
|
|
316
|
+
# the tier filter fallback shape). Non-.claude/hooks commands pass
|
|
317
|
+
# through (not our target class).
|
|
318
|
+
($presentre == "") or
|
|
319
|
+
((.command // "") | test("\\.claude/hooks/[a-zA-Z0-9._-]+\\.sh") | not) or
|
|
320
|
+
((.command // "") | test("\\.claude/hooks/(" + $presentre + ")\\.sh"))
|
|
267
321
|
))) as $bhookslist |
|
|
268
322
|
if ($bhookslist | length) == 0 then .
|
|
269
323
|
elif any(.hooks[$event][]; (.matcher // "") == $bmatcher) then
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"tier": "lite",
|
|
3
|
-
"manifest_version": "1.11.
|
|
4
|
-
"generated_at": "2026-09-
|
|
3
|
+
"manifest_version": "1.11.2",
|
|
4
|
+
"generated_at": "2026-09-26T11:18:11Z",
|
|
5
5
|
"entries": [
|
|
6
6
|
{
|
|
7
7
|
"slug": "029-release-pipeline",
|
|
@@ -736,7 +736,7 @@
|
|
|
736
736
|
"type": "lib",
|
|
737
737
|
"path": "lib/bassclef-dir-resolver.sh",
|
|
738
738
|
"tier": "lite",
|
|
739
|
-
"content_hash": "sha256:
|
|
739
|
+
"content_hash": "sha256:7b0f95e282983cca1edcf27083526edabc964e72cd0ef3596c7c8df915e24f92",
|
|
740
740
|
"description": "bassclef-dir-resolver.sh — resolve BASSCLEF_DIR across install layouts."
|
|
741
741
|
},
|
|
742
742
|
{
|
|
@@ -1303,7 +1303,7 @@
|
|
|
1303
1303
|
"type": "presence-template",
|
|
1304
1304
|
"path": "presence/install/bassclef-hook-connect.sh",
|
|
1305
1305
|
"tier": "lite",
|
|
1306
|
-
"content_hash": "sha256:
|
|
1306
|
+
"content_hash": "sha256:a50c3ca715f4f786e2bcbbd804923711f34fe29924aa7a487808934612993ec6",
|
|
1307
1307
|
"description": "description: Dynamic-derive hook connect — closes bassclef-upstream#625."
|
|
1308
1308
|
},
|
|
1309
1309
|
{
|