@thebassclef/lite 1.7.0 → 1.8.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/README.md CHANGED
@@ -35,7 +35,7 @@ See [`standards/os-support.md`](standards/os-support.md) for the full policy.
35
35
 
36
36
  ## Current release
37
37
 
38
- <!-- version-start -->1.7.0<!-- version-end -->
38
+ <!-- version-start -->1.8.0<!-- version-end -->
39
39
 
40
40
  See [CHANGELOG.md](CHANGELOG.md) for release notes.
41
41
 
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const version = "1.7.0";
3
+ const version = "1.8.0";
4
4
  exports.version = version;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version: "1.7.0";
1
+ export declare const version: "1.8.0";
2
2
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = "1.7.0";
1
+ const version = "1.8.0";
2
2
  export {
3
3
  version
4
4
  };
@@ -28,18 +28,57 @@ if [ "${SELF_MODE:-0}" = "1" ]; then
28
28
  return 0 2>/dev/null || exit 0
29
29
  fi
30
30
 
31
- # Fresh-install gate (#1818 Ship 3): if state/markers/hook-heartbeat/ does
32
- # not exist, no producer has ever called heartbeat_mark on this machine, so
33
- # no hook can be "stale" — a fresh install has no heartbeat history to check
34
- # against. Skip silently. Cold adopters see no false "never fired" banner
35
- # on their first skill run. The gate activates the moment a producer hook
36
- # fires and writes its first marker.
31
+ # Fresh-install gate — two layers close the #1895 self-defeat class:
32
+ #
33
+ # Layer 1: state/markers/hook-heartbeat/ does not exist — no producer has
34
+ # ever called heartbeat_mark on this machine. Skip silently. Cold
35
+ # adopters see no false "never fired" banner on their first skill run.
36
+ #
37
+ # Layer 2: dir exists BUT the oldest marker is younger than the grace
38
+ # window (default 24h). The install is still bootstrapping — the FIRST
39
+ # producer fire creates the dir + first marker, but critical hooks that
40
+ # have not had their trigger event yet would show "never fired." Sam
41
+ # sees false-positive banner at 4-minute-old install. Cure per #1895:
42
+ # use oldest marker mtime as the install activation anchor. Add a
43
+ # wallclock grace window before "never fired" reports get treated as
44
+ # real defects. New markers written after the first do NOT reset the
45
+ # anchor (find + sort + head-1 gives the oldest).
46
+ #
47
+ # Override: FRESH_INSTALL_GRACE_SECONDS=0 disables the grace layer for
48
+ # operator debugging.
49
+ #
37
50
  # Anchor: @luminary donald-norman — a banner fires only when a real problem
38
- # exists. @luminary michael-nygard — fresh state is not broken state.
39
- if [ ! -d "state/markers/hook-heartbeat" ]; then
51
+ # exists. Sam's user model: "I just installed this; give it time."
52
+ # @luminary michael-nygard — fresh state is not broken state.
53
+ # Resolve marker dir — mirror lib/hook-heartbeat.sh::_heartbeat_dir semantics
54
+ # so tests that set HEARTBEAT_MARKER_DIR get consistent behavior.
55
+ _HB_MARKER_DIR="${HEARTBEAT_MARKER_DIR:-state/markers/hook-heartbeat}"
56
+
57
+ if [ ! -d "$_HB_MARKER_DIR" ]; then
40
58
  return 0 2>/dev/null || exit 0
41
59
  fi
42
60
 
61
+ FRESH_INSTALL_GRACE_SECONDS="${FRESH_INSTALL_GRACE_SECONDS:-86400}" # 24h default per #1895
62
+ if [ "$FRESH_INSTALL_GRACE_SECONDS" -gt 0 ]; then
63
+ # Find oldest marker mtime — install activation anchor. Try GNU stat -c
64
+ # first (Linux; -f on GNU means filesystem info NOT mtime; silently returns
65
+ # a string that breaks arithmetic below). BSD stat -f second (macOS).
66
+ # Filter numeric-only output for portability safety.
67
+ _oldest_mtime=$(find "$_HB_MARKER_DIR" -maxdepth 1 -type f -name '*.marker' -exec stat -c %Y {} + 2>/dev/null | grep -E '^[0-9]+$' | sort -n | head -1)
68
+ if [ -z "$_oldest_mtime" ]; then
69
+ _oldest_mtime=$(find "$_HB_MARKER_DIR" -maxdepth 1 -type f -name '*.marker' -exec stat -f %m {} + 2>/dev/null | grep -E '^[0-9]+$' | sort -n | head -1)
70
+ fi
71
+ _now=$(date -u +%s)
72
+ # No markers yet: install has not activated any producer. Skip silently.
73
+ if [ -z "$_oldest_mtime" ]; then
74
+ return 0 2>/dev/null || exit 0
75
+ fi
76
+ # Grace window active: skip silently.
77
+ if [ $((_now - _oldest_mtime)) -lt "$FRESH_INSTALL_GRACE_SECONDS" ]; then
78
+ return 0 2>/dev/null || exit 0
79
+ fi
80
+ fi
81
+
43
82
  # Probe bundled path first (dist/lite/ ship path per ADR-056 D3), then
44
83
  # $BASSCLEF_DIR fallback for synced adopters. Pattern matches
45
84
  # session-reflection.sh:11-17. Cures #1732 Phase A silent-fail at operator
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "v1.2.0",
3
- "marker_tag": "release-2026-09-22-a26d8936",
4
- "release_date": "2026-09-22T11:04:29Z",
5
- "release_sha": "a26d8936",
6
- "release_tag": "release-2026-09-22-a26d8936"
2
+ "version": "v1.3.0",
3
+ "marker_tag": "release-2026-09-23-8f764ed8",
4
+ "release_date": "2026-09-23T00:10:17Z",
5
+ "release_sha": "8f764ed8",
6
+ "release_tag": "release-2026-09-23-8f764ed8"
7
7
  }
@@ -126,6 +126,45 @@ bassclef_sync_resolve_pointer_file() {
126
126
  fi
127
127
  }
128
128
 
129
+ # bassclef_sync_bundled_substrate_present <cwd>
130
+ #
131
+ # Returns 0 (yes) when .claude/hooks/, .claude/rules/, .claude/skills/ all
132
+ # exist AND contain at least one file (recursively). Returns 1 (no) when
133
+ # any of those conditions fails.
134
+ #
135
+ # Cures the npm-only cold adopter false-error class per
136
+ # bassclef-upstream#1849. The dispatcher was designed for peer-checkout
137
+ # OR source-config models. Neither works for anonymous adopters against
138
+ # private repos. But the npm bundle already unpacks substrate at install
139
+ # time. The fetch failure is not a real failure; this check catches the
140
+ # steady state and lets the dispatcher exit silently.
141
+ #
142
+ # Composes with:
143
+ # @luminary alan-cooper — Sam persona; silent-on-success matches user model
144
+ # @luminary donald-norman — signifier; false-positive banner erodes real signal
145
+ # @luminary linus-torvalds — adopter contract; npm bundle IS the substrate
146
+ # @luminary michael-feathers — characterization tests over 3 install shapes
147
+ #
148
+ # Tests: .claude/hooks/tests/bassclef-sync-bundled-substrate-check.test.sh
149
+ # Refs: bassclef-upstream#1849
150
+ bassclef_sync_bundled_substrate_present() {
151
+ local cwd="${1:-}"
152
+ if [ -z "$cwd" ] || [ ! -d "$cwd" ]; then
153
+ return 1
154
+ fi
155
+ local _dir
156
+ for _dir in .claude/hooks .claude/rules .claude/skills; do
157
+ if [ ! -d "$cwd/$_dir" ]; then
158
+ return 1
159
+ fi
160
+ # Nonempty check: at least one file anywhere under the dir.
161
+ if [ -z "$(find "$cwd/$_dir" -mindepth 1 -maxdepth 4 -type f -print -quit 2>/dev/null)" ]; then
162
+ return 1
163
+ fi
164
+ done
165
+ return 0
166
+ }
167
+
129
168
  bassclef_sync_self_heal_pointer() {
130
169
  local cwd="${1:-$CWD}"
131
170
  if [ "${SKIP_SELF_HEAL_POINTER:-0}" = "1" ]; then
@@ -713,6 +752,21 @@ if [ -f "$SIBLING_TEMPLATE" ]; then
713
752
  exit $?
714
753
  fi
715
754
 
755
+ # === Path 1.5. Bundled-substrate recognition (per #1849) ===
756
+ # npm-only cold adopters carry substrate in the package bundle. The
757
+ # dispatcher was designed for peer-checkout OR source-config models; both
758
+ # fail for anonymous adopters against private repos. Before firing the
759
+ # fetch-strategies path, check whether the substrate is already loaded at
760
+ # CWD. If yes, exit silently — no news is good news (Cooper).
761
+ #
762
+ # Override: BASSCLEF_DISPATCHER_STRICT=1 forces the Path 2 fetch even when
763
+ # bundled substrate is present (operator debugging).
764
+ if [ "${BASSCLEF_DISPATCHER_STRICT:-0}" != "1" ]; then
765
+ if bassclef_sync_bundled_substrate_present "$CWD"; then
766
+ exit 0
767
+ fi
768
+ fi
769
+
716
770
  # === Path 2. Curl fallback ===
717
771
  # Uses the same resolver as auto_sync pre-check so old-name adopters
718
772
  # still get here (self-heal already fired above, but resolve for safety
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "tier": "lite",
3
- "manifest_version": "1.9.11",
4
- "generated_at": "2026-09-22T06:14:43Z",
3
+ "manifest_version": "1.9.14",
4
+ "generated_at": "2026-09-22T23:10:32Z",
5
5
  "entries": [
6
6
  {
7
7
  "slug": "029-release-pipeline",
@@ -232,7 +232,7 @@
232
232
  "type": "hook",
233
233
  "path": ".claude/hooks/session-reflection.d/80-hook-heartbeat-check.sh",
234
234
  "tier": "lite",
235
- "content_hash": "sha256:fa72927b90d4f6f57733249f41f2353f930b84c18003c53f7a15c98eb8045e45",
235
+ "content_hash": "sha256:0955f4045ae979d6d11102b6aa711f74c3bf2683754beb1d2587e9debcdef30c",
236
236
  "description": "Hook heartbeat check — reads standards/hook-cadence.json, calls"
237
237
  },
238
238
  {
@@ -1287,7 +1287,7 @@
1287
1287
  "type": "presence-template",
1288
1288
  "path": "presence/install/bassclef-sync.dispatcher.template.sh",
1289
1289
  "tier": "lite",
1290
- "content_hash": "sha256:b94d6f09c8539c09918f79904c4bcbd50d1e5e44481c6bf641a60810dd117298",
1290
+ "content_hash": "sha256:0c5eb10d58174652549d403cec382fc801a3fa7f7b3e4496dbf2eb5dcfffc2ac",
1291
1291
  "description": "description: Retagged standard → lite per #1301 concentric rule (ADR-052 D1) —"
1292
1292
  },
1293
1293
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thebassclef/lite",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Bassclef CLI — install and upgrade bassclef in your project with two commands.",
5
5
  "keywords": [
6
6
  "bassclef",