@thebassclef/lite 1.0.0 → 1.0.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.
- package/dist/cli.cjs +240 -23
- package/dist/cli.js +242 -25
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.claude/hooks/artifact-ingestion-gate.sh +357 -0
- package/dist/lite/.claude/hooks/assert-verify-steering.sh +77 -0
- package/dist/lite/.claude/hooks/bassclef-source-config-validate.sh +215 -0
- package/dist/lite/.claude/hooks/bassclef-sync.sh +716 -0
- package/dist/lite/.claude/hooks/compound-noun-scrub.sh +292 -0
- package/dist/lite/.claude/hooks/kiss-expansion-inject.sh +69 -0
- package/dist/lite/.claude/hooks/longrun-prep-compounding-sequence-check.sh +492 -0
- package/dist/lite/.claude/hooks/plain-english-steering.sh +156 -0
- package/dist/lite/.claude/hooks/post-skill-friction-check.sh +177 -0
- package/dist/lite/.claude/hooks/post-skill-telemetry.sh +62 -0
- package/dist/lite/.claude/hooks/pre-build-gate.sh +511 -0
- package/dist/lite/.claude/hooks/pre-commit-gate.sh +451 -0
- package/dist/lite/.claude/hooks/session-end.sh +433 -0
- package/dist/lite/.claude/hooks/session-reflection.sh +303 -0
- package/dist/lite/.claude/hooks/skill-body-grade-gate.sh +219 -0
- package/dist/lite/.claude/hooks/skill-body-intent-drift.sh +107 -0
- package/dist/lite/.claude/hooks/state-validate.sh +271 -0
- package/dist/lite/.claude/hooks/substrate-clarity-gate.sh +1110 -0
- package/dist/lite/.claude/hooks/temperance-gate.sh +147 -0
- package/dist/lite/.claude/hooks/testing-tier-enforce.sh +233 -0
- package/dist/lite/.claude/hooks/turn-prose-grade-measure.sh +219 -0
- package/dist/lite/.claude/hooks/turn-prose-kiss-check.sh +463 -0
- package/dist/lite/.claude/hooks/vocabulary-migration-check.sh +171 -0
- package/dist/lite/.claude/hooks/whereami-utc-gate.sh +142 -0
- package/dist/lite/CLAUDE.md +2 -2
- package/dist/lite/whereami.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tier: lite
|
|
3
|
+
# install-class: dual
|
|
4
|
+
#
|
|
5
|
+
# whereami-utc-gate.sh — PreToolUse hook that BLOCKs Edit|Write|MultiEdit
|
|
6
|
+
# on docs/whereami.md when last_updated.at value does not end in Z (UTC).
|
|
7
|
+
#
|
|
8
|
+
# Wires per .claude/settings.json under hooks.PreToolUse with matcher
|
|
9
|
+
# "Edit|Write|MultiEdit". Reads the tool's event JSON from stdin,
|
|
10
|
+
# extracts the incoming content (content for Write; new_string for Edit
|
|
11
|
+
# and MultiEdit), scans for last_updated.at timestamp values in both
|
|
12
|
+
# YAML-frontmatter form (`at: <timestamp>` under `last_updated:` block)
|
|
13
|
+
# and markdown-section form (`## Last updated` followed by a timestamp).
|
|
14
|
+
# BLOCKs (exit 2) when any value carries a non-Z offset.
|
|
15
|
+
#
|
|
16
|
+
# Cure B side of #897; Cure A (sync-hook parser accepts both shapes for
|
|
17
|
+
# grace window) shipped in bet 26e PR #917. Cure B is the write-time
|
|
18
|
+
# gate; adopter grace window per ADR-031 through 2026-10-31 — Cure A
|
|
19
|
+
# parser keeps working during migration.
|
|
20
|
+
#
|
|
21
|
+
# Ships as WU-4 of bet 2026-07-26g.
|
|
22
|
+
#
|
|
23
|
+
# Override: SKIP_WHEREAMI_UTC_GATE=1 (logged to stderr).
|
|
24
|
+
#
|
|
25
|
+
# Pairs with: .claude/rules/state-schema-validation.md (sister discipline
|
|
26
|
+
# at state-spine surface; this hook covers the whereami-
|
|
27
|
+
# specific UTC-Z constraint)
|
|
28
|
+
|
|
29
|
+
set -u
|
|
30
|
+
|
|
31
|
+
# === Override path ===
|
|
32
|
+
|
|
33
|
+
if [ "${SKIP_WHEREAMI_UTC_GATE:-}" = "1" ]; then
|
|
34
|
+
echo "[whereami-utc-gate.sh] SKIP_WHEREAMI_UTC_GATE=1 — bypassing" >&2
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# === Read PreToolUse event ===
|
|
39
|
+
|
|
40
|
+
EVENT_JSON="$(cat 2>/dev/null || true)"
|
|
41
|
+
if [ -z "$EVENT_JSON" ]; then
|
|
42
|
+
exit 0 # empty stdin → pass through (fail-soft per stdin contract)
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Fail-soft on malformed JSON per sufficiency criterion 6
|
|
46
|
+
TOOL_NAME="$(echo "$EVENT_JSON" | jq -r '.tool_name // empty' 2>/dev/null || echo "")"
|
|
47
|
+
TARGET_PATH="$(echo "$EVENT_JSON" | jq -r '.tool_input.file_path // empty' 2>/dev/null || echo "")"
|
|
48
|
+
|
|
49
|
+
# --- Tool filter: only Edit / Write / MultiEdit trigger ---
|
|
50
|
+
case "$TOOL_NAME" in
|
|
51
|
+
Edit|Write|MultiEdit) ;;
|
|
52
|
+
*) exit 0 ;;
|
|
53
|
+
esac
|
|
54
|
+
|
|
55
|
+
# --- Path filter: only docs/whereami.md triggers ---
|
|
56
|
+
if [ -z "$TARGET_PATH" ]; then
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Match either bare "docs/whereami.md" or an absolute path ending in it
|
|
61
|
+
case "$TARGET_PATH" in
|
|
62
|
+
*/docs/whereami.md|docs/whereami.md) ;;
|
|
63
|
+
*) exit 0 ;;
|
|
64
|
+
esac
|
|
65
|
+
|
|
66
|
+
# === Extract incoming content ===
|
|
67
|
+
|
|
68
|
+
# Write uses .tool_input.content; Edit + MultiEdit use .tool_input.new_string
|
|
69
|
+
CONTENT=""
|
|
70
|
+
case "$TOOL_NAME" in
|
|
71
|
+
Write)
|
|
72
|
+
CONTENT="$(echo "$EVENT_JSON" | jq -r '.tool_input.content // empty' 2>/dev/null || echo "")"
|
|
73
|
+
;;
|
|
74
|
+
Edit|MultiEdit)
|
|
75
|
+
CONTENT="$(echo "$EVENT_JSON" | jq -r '.tool_input.new_string // empty' 2>/dev/null || echo "")"
|
|
76
|
+
;;
|
|
77
|
+
esac
|
|
78
|
+
|
|
79
|
+
if [ -z "$CONTENT" ]; then
|
|
80
|
+
exit 0 # nothing to validate
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# === Scan for non-Z last_updated.at values ===
|
|
84
|
+
#
|
|
85
|
+
# Two shapes to cover per Cure A parser scope:
|
|
86
|
+
#
|
|
87
|
+
# 1. YAML frontmatter (Shape B state-spine):
|
|
88
|
+
# last_updated:
|
|
89
|
+
# at: 2026-07-26T18:30:00Z
|
|
90
|
+
#
|
|
91
|
+
# 2. Markdown section (## Last updated form):
|
|
92
|
+
# ## Last updated
|
|
93
|
+
#
|
|
94
|
+
# 2026-07-26T18:30:00Z — session-end
|
|
95
|
+
#
|
|
96
|
+
# The scan pattern: any ISO-8601 timestamp of shape YYYY-MM-DDTHH:MM:SS
|
|
97
|
+
# followed by a non-Z suffix (+HHMM, -HHMM, +HH:MM, -HH:MM). We do NOT
|
|
98
|
+
# require the surrounding structure — a bare non-Z timestamp anywhere
|
|
99
|
+
# in the whereami content is a BLOCK signal.
|
|
100
|
+
|
|
101
|
+
NON_Z_MATCH=""
|
|
102
|
+
|
|
103
|
+
# Regex catches: 2026-07-26T18:30:00+0100 / -0500 / +01:00 / -05:00
|
|
104
|
+
NON_Z_PATTERN='[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:?[0-9]{2}'
|
|
105
|
+
|
|
106
|
+
NON_Z_MATCH="$(printf '%s' "$CONTENT" | grep -oE "$NON_Z_PATTERN" | head -3 || true)"
|
|
107
|
+
|
|
108
|
+
if [ -z "$NON_Z_MATCH" ]; then
|
|
109
|
+
exit 0 # all timestamps end in Z (or none present); pass
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# === BLOCK message ===
|
|
113
|
+
|
|
114
|
+
echo "" >&2
|
|
115
|
+
echo "============================================" >&2
|
|
116
|
+
echo "🛑 WHEREAMI UTC GATE — BLOCKED 🛑" >&2
|
|
117
|
+
echo "============================================" >&2
|
|
118
|
+
echo "" >&2
|
|
119
|
+
echo "File: $TARGET_PATH" >&2
|
|
120
|
+
echo "Tool: $TOOL_NAME" >&2
|
|
121
|
+
echo "" >&2
|
|
122
|
+
echo "Found timestamp value(s) with non-Z (non-UTC) offset:" >&2
|
|
123
|
+
echo "$NON_Z_MATCH" | sed 's/^/ /' >&2
|
|
124
|
+
echo "" >&2
|
|
125
|
+
echo "Spec: .claude/skills/session-end/SKILL.md L60 — \"Set last_updated" >&2
|
|
126
|
+
echo " to current UTC ISO-8601 timestamp.\"" >&2
|
|
127
|
+
echo "" >&2
|
|
128
|
+
echo "Cure: rewrite the value to end in Z. Get current UTC:" >&2
|
|
129
|
+
echo "" >&2
|
|
130
|
+
echo " date -u +%FT%TZ" >&2
|
|
131
|
+
echo "" >&2
|
|
132
|
+
echo "Adopter grace window per ADR-031: Cure A parser (bet 26e PR #917)" >&2
|
|
133
|
+
echo "accepts both Z and +HHMM through 2026-10-31. Cure B (this hook)" >&2
|
|
134
|
+
echo "closes the write-time class so new writes stay UTC-Z." >&2
|
|
135
|
+
echo "" >&2
|
|
136
|
+
echo "Override (logged): SKIP_WHEREAMI_UTC_GATE=1 <command>" >&2
|
|
137
|
+
echo "" >&2
|
|
138
|
+
echo "Rule: .claude/rules/state-schema-validation.md" >&2
|
|
139
|
+
echo "Issue: bassclef-upstream#897 Cure B" >&2
|
|
140
|
+
echo "============================================" >&2
|
|
141
|
+
|
|
142
|
+
exit 2
|
package/dist/lite/CLAUDE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# [
|
|
1
|
+
# [REPO_NAME]
|
|
2
2
|
|
|
3
3
|
@.claude/bassclef-orientation.md
|
|
4
4
|
|
|
@@ -25,7 +25,7 @@ Discovery commands:
|
|
|
25
25
|
|
|
26
26
|
## Bassclef version
|
|
27
27
|
|
|
28
|
-
Sync source declared in `.bassclef-source.json`. This adopter runs the
|
|
28
|
+
Sync source declared in `.bassclef-source.json`. This adopter runs the `[TIER]` tier. Substrate updates land at every session-start via `~/.claude/hooks/bassclef-sync.sh`.
|
|
29
29
|
|
|
30
30
|
## What NOT to do
|
|
31
31
|
|
package/dist/lite/whereami.md
CHANGED
|
@@ -13,7 +13,7 @@ Current project-state snapshot. Read at session-start. Updated at session-end.
|
|
|
13
13
|
|
|
14
14
|
## Bassclef bring-up
|
|
15
15
|
|
|
16
|
-
New adopter. Ran `bassclef init` at [ISO_TIMESTAMP]. Substrate landed at
|
|
16
|
+
New adopter. Ran `bassclef init` at [ISO_TIMESTAMP]. Substrate landed at `[TIER]` tier per `.bassclef-source.json`. Every session-start now fires the sync + reflection chain.
|
|
17
17
|
|
|
18
18
|
## First iteration goal
|
|
19
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thebassclef/lite",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Bassclef CLI — install and upgrade bassclef in your project with two commands.",
|
|
5
5
|
"keywords": ["bassclef", "claude-code", "cli", "scaffolding"],
|
|
6
6
|
"homepage": "https://github.com/sunj-labs/bassclef-cli",
|