@rsktash/beads-ui 0.1.30 → 0.1.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/README.md CHANGED
@@ -154,6 +154,29 @@ Sections and headings get unique element IDs for fragment linking:
154
154
 
155
155
  Solarized Light color palette with matching syntax highlighting.
156
156
 
157
+ ## CLI Tools
158
+
159
+ ### bd-grep
160
+
161
+ Grep across beads issue content with snippet output. Uses `bd list` for issue filtering, then greps field content for pattern matches.
162
+
163
+ ```bash
164
+ bd-grep <pattern> [bd-list-flags] [--field fields] [-A N] [-B N] [-C N] [-i] [-l]
165
+ ```
166
+
167
+ Examples:
168
+
169
+ ```bash
170
+ bd-grep "timeline" # open issues, description
171
+ bd-grep "timeline" --all # include closed
172
+ bd-grep "route" -t epic # epics only
173
+ bd-grep "fallback" --field description,design # multiple fields
174
+ bd-grep "composite" -C2 # 2 lines context
175
+ bd-grep "trip.id" -l # list matching IDs only
176
+ ```
177
+
178
+ Requires `bd` and `jq`.
179
+
157
180
  ## License
158
181
 
159
182
  MIT
package/bin/bd-grep ADDED
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env bash
2
+ # bd-grep — grep across beads issue content with snippet output
3
+ #
4
+ # Uses `bd list` for issue filtering (all bd list flags pass through),
5
+ # then greps field content for pattern matches with context.
6
+ #
7
+ # Usage:
8
+ # bd-grep <pattern> [bd-list-flags] [--field fields] [-A N] [-B N] [-C N] [-i] [-l]
9
+ #
10
+ # Examples:
11
+ # bd-grep "timeline" # open issues, description
12
+ # bd-grep "timeline" --all # include closed
13
+ # bd-grep "route" -t epic # epics only
14
+ # bd-grep "fallback" --field description,design # multiple fields
15
+ # bd-grep "composite" -C2 # 2 lines context
16
+ # bd-grep "trip.id" -l # list matching IDs only
17
+ # bd-grep "#1" --id yuklar-32p,yuklar-985 # specific issues
18
+ #
19
+ # Output:
20
+ # yuklar-32p:description:23: matched line text
21
+
22
+ set -euo pipefail
23
+
24
+ FIELDS="description"
25
+ AFTER=0
26
+ BEFORE=0
27
+ CASE_FLAG=""
28
+ LIST_ONLY=false
29
+ PATTERN=""
30
+ BD_ARGS=()
31
+
32
+ args=("$@")
33
+ i=0
34
+ while [ $i -lt ${#args[@]} ]; do
35
+ arg="${args[$i]}"
36
+ case "$arg" in
37
+ --field) FIELDS="${args[$((i+1))]}"; i=$((i+2)) ;;
38
+ --field=*) FIELDS="${arg#--field=}"; i=$((i+1)) ;;
39
+ -A) AFTER="${args[$((i+1))]}"; i=$((i+2)) ;;
40
+ -A[0-9]*) AFTER="${arg#-A}"; i=$((i+1)) ;;
41
+ -B) BEFORE="${args[$((i+1))]}"; i=$((i+2)) ;;
42
+ -B[0-9]*) BEFORE="${arg#-B}"; i=$((i+1)) ;;
43
+ -C) AFTER="${args[$((i+1))]}"; BEFORE="${args[$((i+1))]}"; i=$((i+2)) ;;
44
+ -C[0-9]*) AFTER="${arg#-C}"; BEFORE="${arg#-C}"; i=$((i+1)) ;;
45
+ -i) CASE_FLAG="-i"; i=$((i+1)) ;;
46
+ -l) LIST_ONLY=true; i=$((i+1)) ;;
47
+ -*) BD_ARGS+=("$arg"); i=$((i+1))
48
+ if [ $i -lt ${#args[@]} ] && [[ ! "${args[$i]}" == -* ]]; then
49
+ BD_ARGS+=("${args[$i]}"); i=$((i+1))
50
+ fi ;;
51
+ *) if [ -z "$PATTERN" ]; then
52
+ PATTERN="$arg"
53
+ else
54
+ BD_ARGS+=("$arg")
55
+ fi
56
+ i=$((i+1)) ;;
57
+ esac
58
+ done
59
+
60
+ if [ -z "$PATTERN" ]; then
61
+ echo "Usage: bd-grep <pattern> [bd-list-flags] [--field fields] [-A N] [-B N] [-C N] [-i] [-l]" >&2
62
+ exit 1
63
+ fi
64
+
65
+ # Use bd list for issue discovery (all bd flags pass through)
66
+ ISSUES=()
67
+ while IFS= read -r id; do
68
+ [ -n "$id" ] && ISSUES+=("$id")
69
+ done < <(bd list "${BD_ARGS[@]}" --flat --json 2>/dev/null | jq -r '.[].id')
70
+
71
+ if [ ${#ISSUES[@]} -eq 0 ]; then
72
+ echo "No issues found matching filters" >&2
73
+ exit 1
74
+ fi
75
+
76
+ IFS=',' read -ra FIELD_ARRAY <<< "$FIELDS"
77
+
78
+ grep_flags="-n"
79
+ [ -n "$CASE_FLAG" ] && grep_flags="$grep_flags -i"
80
+ [ "$AFTER" -gt 0 ] && grep_flags="$grep_flags -A $AFTER"
81
+ [ "$BEFORE" -gt 0 ] && grep_flags="$grep_flags -B $BEFORE"
82
+
83
+ found=false
84
+
85
+ for issue_id in "${ISSUES[@]}"; do
86
+ json=$(bd show "$issue_id" --json 2>/dev/null) || continue
87
+
88
+ for field in "${FIELD_ARRAY[@]}"; do
89
+ content=$(echo "$json" | jq -r ".[0].${field} // empty")
90
+ [ -z "$content" ] && continue
91
+
92
+ matches=$(echo "$content" | grep $grep_flags -- "$PATTERN" 2>/dev/null) || continue
93
+ found=true
94
+
95
+ if [ "$LIST_ONLY" = true ]; then
96
+ echo "$issue_id"
97
+ continue 2
98
+ fi
99
+
100
+ while IFS= read -r line; do
101
+ echo "$issue_id:$field:$line"
102
+ done <<< "$matches"
103
+ done
104
+ done
105
+
106
+ $found || exit 1