@windyroad/jtbd 0.1.3 → 0.2.0-preview.32
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/hooks/jtbd-enforce-edit.sh +28 -6
- package/hooks/jtbd-eval.sh +10 -13
- package/hooks/test/jtbd-enforce-scope.bats +57 -0
- package/hooks/test/jtbd-eval.bats +46 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# JTBD - PreToolUse enforcement hook
|
|
3
|
-
# BLOCKS Edit/Write to
|
|
3
|
+
# BLOCKS Edit/Write to project files until jtbd-lead is consulted.
|
|
4
4
|
# Uses shared review-gate.sh for TTL, drift detection, and fail-closed.
|
|
5
5
|
|
|
6
6
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
@@ -35,14 +35,36 @@ if [ -z "$FILE_PATH" ]; then
|
|
|
35
35
|
exit 0
|
|
36
36
|
fi
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
BASENAME=$(basename "$FILE_PATH")
|
|
39
|
+
|
|
40
|
+
# Exclude non-JTBD files (matches architect gate exclusions)
|
|
39
41
|
case "$FILE_PATH" in
|
|
40
|
-
*.
|
|
41
|
-
|
|
42
|
+
*.css|*.scss|*.sass|*.less)
|
|
43
|
+
exit 0 ;;
|
|
44
|
+
*.png|*.jpg|*.jpeg|*.gif|*.svg|*.ico|*.webp)
|
|
45
|
+
exit 0 ;;
|
|
46
|
+
*.woff|*.woff2|*.ttf|*.eot)
|
|
47
|
+
exit 0 ;;
|
|
48
|
+
*package-lock.json|*yarn.lock|*pnpm-lock.yaml)
|
|
49
|
+
exit 0 ;;
|
|
50
|
+
*.map)
|
|
51
|
+
exit 0 ;;
|
|
52
|
+
*.changeset/*.md|*/.changeset/*.md)
|
|
53
|
+
exit 0 ;;
|
|
54
|
+
*/MEMORY.md|*/.claude/projects/*/memory/*)
|
|
55
|
+
exit 0 ;;
|
|
56
|
+
*/.claude/plans/*.md|*.claude/plans/*.md)
|
|
57
|
+
exit 0 ;;
|
|
58
|
+
*/RISK-POLICY.md)
|
|
59
|
+
exit 0 ;;
|
|
60
|
+
*/.risk-reports/*)
|
|
61
|
+
exit 0 ;;
|
|
62
|
+
*/docs/BRIEFING.md|docs/BRIEFING.md)
|
|
63
|
+
exit 0 ;;
|
|
64
|
+
*/docs/problems/*.md|docs/problems/*.md)
|
|
65
|
+
exit 0 ;;
|
|
42
66
|
esac
|
|
43
67
|
|
|
44
|
-
BASENAME=$(basename "$FILE_PATH")
|
|
45
|
-
|
|
46
68
|
# If no JTBD doc exists, block and direct to create skill
|
|
47
69
|
if [ ! -f "docs/JOBS_TO_BE_DONE.md" ]; then
|
|
48
70
|
review_gate_deny "BLOCKED: Cannot edit '${BASENAME}' because docs/JOBS_TO_BE_DONE.md does not exist. Run /wr-jtbd:update-guide to generate a JTBD document for this project, then delegate to wr-jtbd:agent for review."
|
package/hooks/jtbd-eval.sh
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# JTBD - UserPromptSubmit hook
|
|
3
3
|
# Detects JOBS_TO_BE_DONE.md in the project and injects delegation instruction.
|
|
4
|
-
# If the file doesn't exist, instructs Claude to create it via the
|
|
4
|
+
# If the file doesn't exist, instructs Claude to create it via the update-guide skill.
|
|
5
5
|
|
|
6
6
|
if [ -f "docs/JOBS_TO_BE_DONE.md" ]; then
|
|
7
7
|
cat <<'HOOK_OUTPUT'
|
|
@@ -9,27 +9,24 @@ INSTRUCTION: MANDATORY JTBD CHECK. YOU MUST FOLLOW THIS.
|
|
|
9
9
|
DETECTED: docs/JOBS_TO_BE_DONE.md exists in this project.
|
|
10
10
|
|
|
11
11
|
This is a NON-OPTIONAL instruction. You MUST use the jtbd-lead agent
|
|
12
|
-
before editing any
|
|
13
|
-
|
|
12
|
+
before editing any project file. This is proactive. Do not wait for the
|
|
13
|
+
user to ask.
|
|
14
14
|
|
|
15
15
|
REQUIRED ACTIONS:
|
|
16
16
|
1. Use the Agent tool to delegate to wr-jtbd:agent
|
|
17
17
|
(subagent_type: "wr-jtbd:agent")
|
|
18
18
|
2. The jtbd-lead will review proposed changes against docs/JOBS_TO_BE_DONE.md
|
|
19
19
|
and PRODUCT_DISCOVERY.md persona definitions
|
|
20
|
-
3. Do NOT write or edit
|
|
20
|
+
3. Do NOT write or edit project files without jtbd-lead review FIRST
|
|
21
21
|
4. Do NOT skip this step even if you think you can handle it yourself
|
|
22
22
|
|
|
23
|
-
SCOPE:
|
|
24
|
-
Does NOT apply to:
|
|
23
|
+
SCOPE: All project files.
|
|
24
|
+
Does NOT apply to: CSS, images, fonts, lockfiles, changesets, memory files, plan files.
|
|
25
25
|
HOOK_OUTPUT
|
|
26
26
|
else
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
If the user's task involves editing UI files, the edit will be blocked
|
|
32
|
-
until a JTBD document exists. Run /wr-jtbd:update-guide to generate one.
|
|
27
|
+
cat <<'HOOK_OUTPUT'
|
|
28
|
+
NOTE: This project has no docs/JOBS_TO_BE_DONE.md.
|
|
29
|
+
Edits to project files will be blocked until a JTBD document exists.
|
|
30
|
+
Run /wr-jtbd:update-guide to generate one.
|
|
33
31
|
HOOK_OUTPUT
|
|
34
|
-
fi
|
|
35
32
|
fi
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
# Tests for jtbd-enforce-edit.sh — verifies broadened scope with exclusions
|
|
4
|
+
|
|
5
|
+
setup() {
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
7
|
+
HOOK="$SCRIPT_DIR/jtbd-enforce-edit.sh"
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
# Helper: check if a file extension is in the exclusion list by grepping the hook
|
|
11
|
+
file_is_excluded() {
|
|
12
|
+
local pattern="$1"
|
|
13
|
+
# The hook should have a case statement that exits 0 for excluded files
|
|
14
|
+
grep -q "$pattern" "$HOOK"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@test "enforce: excludes CSS files" {
|
|
18
|
+
file_is_excluded '\.css'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@test "enforce: excludes image files" {
|
|
22
|
+
file_is_excluded '\.png'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@test "enforce: excludes font files" {
|
|
26
|
+
file_is_excluded '\.woff'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@test "enforce: excludes lockfiles" {
|
|
30
|
+
file_is_excluded 'package-lock.json'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@test "enforce: excludes changeset files" {
|
|
34
|
+
file_is_excluded '\.changeset'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@test "enforce: excludes memory files" {
|
|
38
|
+
file_is_excluded 'MEMORY.md'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@test "enforce: excludes plan files" {
|
|
42
|
+
file_is_excluded '\.claude/plans'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@test "enforce: excludes risk reports" {
|
|
46
|
+
file_is_excluded '\.risk-reports'
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@test "enforce: excludes RISK-POLICY.md" {
|
|
50
|
+
file_is_excluded 'RISK-POLICY.md'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@test "enforce: does NOT have UI-only case guard" {
|
|
54
|
+
# The old guard matched only UI extensions then exited for everything else.
|
|
55
|
+
# The new hook should NOT exit 0 for all non-UI files.
|
|
56
|
+
! grep -q '\*) exit 0 ;;' "$HOOK"
|
|
57
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
# Tests for jtbd-eval.sh — verifies JTBD suggestion fires for any project
|
|
4
|
+
|
|
5
|
+
setup() {
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
7
|
+
HOOK="$SCRIPT_DIR/jtbd-eval.sh"
|
|
8
|
+
ORIG_DIR="$PWD"
|
|
9
|
+
TEST_DIR=$(mktemp -d)
|
|
10
|
+
cd "$TEST_DIR"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
teardown() {
|
|
14
|
+
cd "$ORIG_DIR"
|
|
15
|
+
rm -rf "$TEST_DIR"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@test "eval: suggests update-guide when JOBS_TO_BE_DONE.md missing (no UI files)" {
|
|
19
|
+
# No UI files, no docs — should still suggest
|
|
20
|
+
run bash "$HOOK"
|
|
21
|
+
[ "$status" -eq 0 ]
|
|
22
|
+
[[ "$output" == *"wr-jtbd:update-guide"* ]]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@test "eval: suggests update-guide when JOBS_TO_BE_DONE.md missing (with UI files)" {
|
|
26
|
+
mkdir -p src
|
|
27
|
+
touch src/App.tsx
|
|
28
|
+
run bash "$HOOK"
|
|
29
|
+
[ "$status" -eq 0 ]
|
|
30
|
+
[[ "$output" == *"wr-jtbd:update-guide"* ]]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@test "eval: injects enforcement instruction when JOBS_TO_BE_DONE.md exists" {
|
|
34
|
+
mkdir -p docs
|
|
35
|
+
echo "# Jobs" > docs/JOBS_TO_BE_DONE.md
|
|
36
|
+
run bash "$HOOK"
|
|
37
|
+
[ "$status" -eq 0 ]
|
|
38
|
+
[[ "$output" == *"MANDATORY JTBD CHECK"* ]]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@test "eval: does not reference UI-only scoping in output" {
|
|
42
|
+
run bash "$HOOK"
|
|
43
|
+
[ "$status" -eq 0 ]
|
|
44
|
+
# Should not contain the old UI-only messaging
|
|
45
|
+
[[ "$output" != *"UI files"* ]]
|
|
46
|
+
}
|