rhachet-roles-bhuild 0.1.2 → 0.4.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/dist/domain.operations/behavior/bind/flattenBranchName.cli.d.ts +2 -0
- package/dist/domain.operations/behavior/bind/flattenBranchName.cli.js +19 -0
- package/dist/domain.operations/behavior/bind/flattenBranchName.cli.js.map +1 -0
- package/dist/domain.operations/behavior/bind/flattenBranchName.d.ts +8 -0
- package/dist/domain.operations/behavior/bind/flattenBranchName.js +19 -0
- package/dist/domain.operations/behavior/bind/flattenBranchName.js.map +1 -0
- package/dist/domain.operations/behavior/bind/getBoundBehaviorByBranch.cli.d.ts +2 -0
- package/dist/domain.operations/behavior/bind/getBoundBehaviorByBranch.cli.js +18 -0
- package/dist/domain.operations/behavior/bind/getBoundBehaviorByBranch.cli.js.map +1 -0
- package/dist/domain.operations/behavior/bind/getBoundBehaviorByBranch.d.ts +11 -0
- package/dist/domain.operations/behavior/bind/getBoundBehaviorByBranch.js +51 -0
- package/dist/domain.operations/behavior/bind/getBoundBehaviorByBranch.js.map +1 -0
- package/dist/domain.operations/behavior/bind/getLatestBlueprintByBehavior.cli.d.ts +2 -0
- package/dist/domain.operations/behavior/bind/getLatestBlueprintByBehavior.cli.js +20 -0
- package/dist/domain.operations/behavior/bind/getLatestBlueprintByBehavior.cli.js.map +1 -0
- package/dist/domain.operations/behavior/bind/getLatestBlueprintByBehavior.d.ts +11 -0
- package/dist/domain.operations/behavior/bind/getLatestBlueprintByBehavior.js +51 -0
- package/dist/domain.operations/behavior/bind/getLatestBlueprintByBehavior.js.map +1 -0
- package/dist/domain.operations/behavior/bind/index.d.ts +3 -0
- package/dist/domain.operations/behavior/bind/index.js +10 -0
- package/dist/domain.operations/behavior/bind/index.js.map +1 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.blueprint/rule.require.criteria-satisfied.md +37 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.blueprint/rule.require.determinism-declared.md +44 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.blueprint/rule.require.test-coverage-specified.md +42 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.blueprint/rule.require.test-patterns-specified.md +43 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.criteria/rule.prefer.dependency-order.md +43 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.criteria/rule.prefer.depth-groups.md +44 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.criteria/rule.prefer.usecase-groups.md +41 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.criteria/rule.require.bdd-format.md +25 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.roadmap/rule.prefer.clear-deliverables.md +46 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.roadmap/rule.prefer.dependency-order.md +59 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.wish/rule.prefer.bounded-scope.md +29 -0
- package/dist/domain.roles/behaver/briefs/practices/behavior.wish/rule.prefer.clear-desires.md +31 -0
- package/dist/domain.roles/behaver/inits/claude.hooks/sessionstart.boot-behavior.sh +109 -0
- package/dist/domain.roles/behaver/inits/init.claude.hooks.findsert.sh +226 -0
- package/dist/domain.roles/behaver/inits/init.claude.hooks.sh +34 -0
- package/dist/domain.roles/behaver/skills/bind.behavior.sh +236 -0
- package/dist/domain.roles/behaver/skills/init.behavior.sh +55 -0
- package/dist/domain.roles/behaver/skills/review.behavior.sh +396 -0
- package/dist/domain.roles/behaver/skills/review.behavior.test.utils.d.ts +12 -0
- package/dist/domain.roles/behaver/skills/review.behavior.test.utils.js +63 -0
- package/dist/domain.roles/behaver/skills/review.behavior.test.utils.js.map +1 -0
- package/dist/domain.roles/behaver/skills/review.deliverable.sh +344 -0
- package/package.json +10 -8
- package/readme.md +34 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# .what = bind, unbind, or query branch-to-behavior binding
|
|
4
|
+
#
|
|
5
|
+
# .why = explicit user control over which behavior applies to current branch
|
|
6
|
+
#
|
|
7
|
+
# usage:
|
|
8
|
+
# bind.behavior.sh --set --behavior <name> # bind current branch
|
|
9
|
+
# bind.behavior.sh --del # unbind current branch
|
|
10
|
+
# bind.behavior.sh --get # query current binding
|
|
11
|
+
#
|
|
12
|
+
# guarantee:
|
|
13
|
+
# - fail-fast if behavior not found or ambiguous
|
|
14
|
+
# - fail-fast if --set to different behavior (suggest --del or worktree)
|
|
15
|
+
# - idempotent: --set to same behavior succeeds, --del when unbound succeeds
|
|
16
|
+
######################################################################
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
|
|
22
|
+
|
|
23
|
+
# ────────────────────────────────────────────────────────────────────
|
|
24
|
+
# argument parsing
|
|
25
|
+
# ────────────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
ACTION=""
|
|
28
|
+
BEHAVIOR_NAME=""
|
|
29
|
+
|
|
30
|
+
while [[ $# -gt 0 ]]; do
|
|
31
|
+
case $1 in
|
|
32
|
+
--set)
|
|
33
|
+
ACTION="set"
|
|
34
|
+
shift
|
|
35
|
+
;;
|
|
36
|
+
--del)
|
|
37
|
+
ACTION="del"
|
|
38
|
+
shift
|
|
39
|
+
;;
|
|
40
|
+
--get)
|
|
41
|
+
ACTION="get"
|
|
42
|
+
shift
|
|
43
|
+
;;
|
|
44
|
+
--behavior)
|
|
45
|
+
BEHAVIOR_NAME="$2"
|
|
46
|
+
shift 2
|
|
47
|
+
;;
|
|
48
|
+
--skill|--repo|--role|-s)
|
|
49
|
+
# ignore rhachet passthrough args
|
|
50
|
+
shift 2
|
|
51
|
+
;;
|
|
52
|
+
*)
|
|
53
|
+
echo "error: unknown argument '$1'"
|
|
54
|
+
echo "usage: bind.behavior.sh --set --behavior <name> | --del | --get"
|
|
55
|
+
exit 1
|
|
56
|
+
;;
|
|
57
|
+
esac
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
# validate action
|
|
61
|
+
if [[ -z "$ACTION" ]]; then
|
|
62
|
+
echo "error: no action specified"
|
|
63
|
+
echo "usage: bind.behavior.sh --set --behavior <name> | --del | --get"
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# ────────────────────────────────────────────────────────────────────
|
|
68
|
+
# helpers
|
|
69
|
+
# ────────────────────────────────────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
get_current_branch() {
|
|
72
|
+
git rev-parse --abbrev-ref HEAD
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
flatten_branch_name() {
|
|
76
|
+
local branch="$1"
|
|
77
|
+
npx tsx "$REPO_ROOT/src/domain.operations/behavior/bind/flattenBranchName.cli.ts" "$branch"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
get_bound_behavior() {
|
|
81
|
+
npx tsx "$REPO_ROOT/src/domain.operations/behavior/bind/getBoundBehaviorByBranch.cli.ts" "$1"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
resolve_behavior_dir() {
|
|
85
|
+
local name="$1"
|
|
86
|
+
local behavior_root="$PWD/.behavior"
|
|
87
|
+
|
|
88
|
+
if [[ ! -d "$behavior_root" ]]; then
|
|
89
|
+
echo ""
|
|
90
|
+
return
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# find matching behavior directories
|
|
94
|
+
local matches=()
|
|
95
|
+
while IFS= read -r -d '' dir; do
|
|
96
|
+
matches+=("$dir")
|
|
97
|
+
done < <(find "$behavior_root" -maxdepth 1 -type d -name "*${name}*" -print0 2>/dev/null)
|
|
98
|
+
|
|
99
|
+
if [[ ${#matches[@]} -eq 0 ]]; then
|
|
100
|
+
echo "error: no behavior found matching '$name'" >&2
|
|
101
|
+
echo "available behaviors:" >&2
|
|
102
|
+
ls -1 "$behavior_root" 2>/dev/null | sed 's/^/ /' >&2
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
if [[ ${#matches[@]} -gt 1 ]]; then
|
|
107
|
+
echo "error: multiple behaviors match '$name'" >&2
|
|
108
|
+
echo "matches:" >&2
|
|
109
|
+
printf ' %s\n' "${matches[@]}" >&2
|
|
110
|
+
exit 1
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
echo "${matches[0]}"
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
# ────────────────────────────────────────────────────────────────────
|
|
117
|
+
# actions
|
|
118
|
+
# ────────────────────────────────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
action_get() {
|
|
121
|
+
local branch
|
|
122
|
+
branch=$(get_current_branch)
|
|
123
|
+
local result
|
|
124
|
+
result=$(get_bound_behavior "$branch")
|
|
125
|
+
|
|
126
|
+
local behavior_dir
|
|
127
|
+
behavior_dir=$(echo "$result" | jq -r '.behaviorDir // empty')
|
|
128
|
+
|
|
129
|
+
if [[ -z "$behavior_dir" || "$behavior_dir" == "null" ]]; then
|
|
130
|
+
echo "not bound"
|
|
131
|
+
else
|
|
132
|
+
# extract just the behavior name from the path
|
|
133
|
+
local behavior_name
|
|
134
|
+
behavior_name=$(basename "$behavior_dir")
|
|
135
|
+
echo "bound to: $behavior_name"
|
|
136
|
+
fi
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
action_set() {
|
|
140
|
+
if [[ -z "$BEHAVIOR_NAME" ]]; then
|
|
141
|
+
echo "error: --behavior is required with --set"
|
|
142
|
+
exit 1
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
local branch
|
|
146
|
+
branch=$(get_current_branch)
|
|
147
|
+
local flat_branch
|
|
148
|
+
flat_branch=$(flatten_branch_name "$branch")
|
|
149
|
+
|
|
150
|
+
# resolve the behavior directory
|
|
151
|
+
local behavior_dir
|
|
152
|
+
behavior_dir=$(resolve_behavior_dir "$BEHAVIOR_NAME")
|
|
153
|
+
|
|
154
|
+
if [[ -z "$behavior_dir" ]]; then
|
|
155
|
+
echo "error: .behavior/ directory not found"
|
|
156
|
+
exit 1
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
# check if already bound
|
|
160
|
+
local result
|
|
161
|
+
result=$(get_bound_behavior "$branch")
|
|
162
|
+
local current_binding
|
|
163
|
+
current_binding=$(echo "$result" | jq -r '.behaviorDir // empty')
|
|
164
|
+
|
|
165
|
+
if [[ -n "$current_binding" && "$current_binding" != "null" ]]; then
|
|
166
|
+
if [[ "$current_binding" == "$behavior_dir" ]]; then
|
|
167
|
+
echo "✓ already bound to: $(basename "$behavior_dir")"
|
|
168
|
+
return 0
|
|
169
|
+
else
|
|
170
|
+
echo "error: branch already bound to different behavior: $(basename "$current_binding")"
|
|
171
|
+
echo ""
|
|
172
|
+
echo "to rebind, first unbind with:"
|
|
173
|
+
echo " bind.behavior.sh --del"
|
|
174
|
+
echo ""
|
|
175
|
+
echo "or use a new worktree for the new behavior:"
|
|
176
|
+
echo " git worktree add ../<new-branch> -b <new-branch>"
|
|
177
|
+
exit 1
|
|
178
|
+
fi
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
# create bind directory if needed
|
|
182
|
+
local bind_dir="$behavior_dir/.bind"
|
|
183
|
+
mkdir -p "$bind_dir"
|
|
184
|
+
|
|
185
|
+
# create bind flag with metadata
|
|
186
|
+
local flag_path="$bind_dir/${flat_branch}.flag"
|
|
187
|
+
cat > "$flag_path" <<EOF
|
|
188
|
+
branch: $branch
|
|
189
|
+
bound_at: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
190
|
+
bound_by: bind.behavior skill
|
|
191
|
+
EOF
|
|
192
|
+
|
|
193
|
+
echo "✓ bound branch '$branch' to: $(basename "$behavior_dir")"
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
action_del() {
|
|
197
|
+
local branch
|
|
198
|
+
branch=$(get_current_branch)
|
|
199
|
+
local flat_branch
|
|
200
|
+
flat_branch=$(flatten_branch_name "$branch")
|
|
201
|
+
|
|
202
|
+
# check if bound
|
|
203
|
+
local result
|
|
204
|
+
result=$(get_bound_behavior "$branch")
|
|
205
|
+
local current_binding
|
|
206
|
+
current_binding=$(echo "$result" | jq -r '.behaviorDir // empty')
|
|
207
|
+
|
|
208
|
+
if [[ -z "$current_binding" || "$current_binding" == "null" ]]; then
|
|
209
|
+
echo "✓ no binding existed"
|
|
210
|
+
return 0
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
# remove the bind flag
|
|
214
|
+
local flag_path="$current_binding/.bind/${flat_branch}.flag"
|
|
215
|
+
if [[ -f "$flag_path" ]]; then
|
|
216
|
+
rm "$flag_path"
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
echo "✓ unbound branch '$branch' from: $(basename "$current_binding")"
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
# ────────────────────────────────────────────────────────────────────
|
|
223
|
+
# main
|
|
224
|
+
# ────────────────────────────────────────────────────────────────────
|
|
225
|
+
|
|
226
|
+
case "$ACTION" in
|
|
227
|
+
get)
|
|
228
|
+
action_get
|
|
229
|
+
;;
|
|
230
|
+
set)
|
|
231
|
+
action_set
|
|
232
|
+
;;
|
|
233
|
+
del)
|
|
234
|
+
action_del
|
|
235
|
+
;;
|
|
236
|
+
esac
|
|
@@ -33,6 +33,9 @@ set -euo pipefail
|
|
|
33
33
|
# fail loud: print what failed
|
|
34
34
|
trap 'echo "❌ init.bhuild.sh failed at line $LINENO" >&2' ERR
|
|
35
35
|
|
|
36
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
37
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
|
|
38
|
+
|
|
36
39
|
# parse arguments
|
|
37
40
|
BEHAVIOR_NAME=""
|
|
38
41
|
TARGET_DIR="$PWD"
|
|
@@ -46,6 +49,10 @@ while [[ $# -gt 0 ]]; do
|
|
|
46
49
|
TARGET_DIR="$2"
|
|
47
50
|
shift 2
|
|
48
51
|
;;
|
|
52
|
+
--skill|--repo|--role|-s)
|
|
53
|
+
# ignore rhachet passthrough args
|
|
54
|
+
shift 2
|
|
55
|
+
;;
|
|
49
56
|
*)
|
|
50
57
|
echo "error: unknown argument '$1'"
|
|
51
58
|
echo "usage: init.bhuild.sh --name <behaviorname> [--dir <directory>]"
|
|
@@ -61,6 +68,37 @@ if [[ -z "$BEHAVIOR_NAME" ]]; then
|
|
|
61
68
|
exit 1
|
|
62
69
|
fi
|
|
63
70
|
|
|
71
|
+
# ────────────────────────────────────────────────────────────────────
|
|
72
|
+
# binding check: fail fast if branch already bound to a behavior
|
|
73
|
+
# ────────────────────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
get_bound_behavior() {
|
|
76
|
+
npx tsx "$REPO_ROOT/src/domain.operations/behavior/bind/getBoundBehaviorByBranch.cli.ts" "$1" 2>/dev/null || echo '{"behaviorDir":null,"bindings":[]}'
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
flatten_branch_name() {
|
|
80
|
+
local branch="$1"
|
|
81
|
+
npx tsx "$REPO_ROOT/src/domain.operations/behavior/bind/flattenBranchName.cli.ts" "$branch"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
85
|
+
BINDING_RESULT=$(get_bound_behavior "$CURRENT_BRANCH")
|
|
86
|
+
EXISTING_BEHAVIOR=$(echo "$BINDING_RESULT" | jq -r '.behaviorDir // empty')
|
|
87
|
+
|
|
88
|
+
if [[ -n "$EXISTING_BEHAVIOR" && "$EXISTING_BEHAVIOR" != "null" ]]; then
|
|
89
|
+
echo "error: branch '$CURRENT_BRANCH' is already bound to: $(basename "$EXISTING_BEHAVIOR")"
|
|
90
|
+
echo ""
|
|
91
|
+
echo "to create a new behavior, use a new worktree:"
|
|
92
|
+
echo " git worktree add ../<new-dir> -b <new-branch>"
|
|
93
|
+
echo " cd ../<new-dir>"
|
|
94
|
+
echo " init.behavior.sh --name <new-behavior>"
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# ────────────────────────────────────────────────────────────────────
|
|
99
|
+
# behavior directory setup
|
|
100
|
+
# ────────────────────────────────────────────────────────────────────
|
|
101
|
+
|
|
64
102
|
# generate isodate in format YYYY_MM_DD
|
|
65
103
|
ISO_DATE=$(date +%Y_%m_%d)
|
|
66
104
|
|
|
@@ -306,6 +344,23 @@ npx rhachet roles boot --repo ehmpathy --role mechanic
|
|
|
306
344
|
# blocker.3
|
|
307
345
|
EOF
|
|
308
346
|
|
|
347
|
+
# ────────────────────────────────────────────────────────────────────
|
|
348
|
+
# auto-bind: bind current branch to newly created behavior
|
|
349
|
+
# ────────────────────────────────────────────────────────────────────
|
|
350
|
+
|
|
351
|
+
FLAT_BRANCH=$(flatten_branch_name "$CURRENT_BRANCH")
|
|
352
|
+
BIND_DIR="$BEHAVIOR_DIR/.bind"
|
|
353
|
+
mkdir -p "$BIND_DIR"
|
|
354
|
+
|
|
355
|
+
FLAG_PATH="$BIND_DIR/${FLAT_BRANCH}.flag"
|
|
356
|
+
cat > "$FLAG_PATH" <<BIND_EOF
|
|
357
|
+
branch: $CURRENT_BRANCH
|
|
358
|
+
bound_at: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
359
|
+
bound_by: init.behavior skill
|
|
360
|
+
BIND_EOF
|
|
361
|
+
|
|
309
362
|
echo ""
|
|
310
363
|
echo "behavior thoughtroute initialized!"
|
|
311
364
|
echo " $BEHAVIOR_DIR"
|
|
365
|
+
echo ""
|
|
366
|
+
echo "branch '$CURRENT_BRANCH' bound to: v${ISO_DATE}.${BEHAVIOR_NAME}"
|