@@ -31,6 +31,7 @@ check_beads_available() {
3131#
3232# Parameters:
3333# $1 (filterStatus) - Status filter (optional, default: "open")
34+ # $2 (limit) - Max issues to fetch (optional, default: "0" = all)
3435#
3536# Outputs:
3637# Tasks in markdown checkbox format, one per line
@@ -42,6 +43,7 @@ check_beads_available() {
4243#
4344fetch_beads_tasks () {
4445 local filterStatus=" ${1:- open} "
46+ local limit=" ${2:- 0} "
4547 local tasks=" "
4648
4749 # Check if beads is available
@@ -50,7 +52,7 @@ fetch_beads_tasks() {
5052 fi
5153
5254 # Build bd list command arguments
53- local bdArgs=(" list" " --json" )
55+ local bdArgs=(" list" " --json" " --limit " " $limit " )
5456 if [[ " $filterStatus " == " open" ]]; then
5557 bdArgs+=(" --status" " open" )
5658 elif [[ " $filterStatus " == " in_progress" ]]; then
@@ -78,7 +80,7 @@ fetch_beads_tasks() {
7880 # Fallback: try plain text output if JSON failed or produced no results
7981 if [[ -z " $tasks " ]]; then
8082 # Build fallback args (reuse status logic, but without --json)
81- local fallbackArgs=(" list" )
83+ local fallbackArgs=(" list" " --limit " " $limit " )
8284 if [[ " $filterStatus " == " open" ]]; then
8385 fallbackArgs+=(" --status" " open" )
8486 elif [[ " $filterStatus " == " in_progress" ]]; then
@@ -109,11 +111,16 @@ fetch_beads_tasks() {
109111
110112# get_beads_count - Get count of open beads issues
111113#
114+ # Parameters:
115+ # $1 (limit) - Max issues to fetch (optional, default: "0" = all)
116+ #
112117# Returns:
113118# 0 and echoes the count
114119# 1 if beads unavailable
115120#
116121get_beads_count () {
122+ local limit=" ${1:- 0} "
123+
117124 if ! check_beads_available; then
118125 echo " 0"
119126 return 1
@@ -122,9 +129,9 @@ get_beads_count() {
122129 local count
123130 if command -v jq & > /dev/null; then
124131 # Note: Use 'select(.status == "closed" | not)' to avoid bash escaping issues with '!='
125- count=$( bd list --json 2> /dev/null | jq ' [.[] | select(.status == "closed" | not)] | length' 2> /dev/null || echo " 0" )
132+ count=$( bd list --json --limit " $limit " 2> /dev/null | jq ' [.[] | select(.status == "closed" | not)] | length' 2> /dev/null || echo " 0" )
126133 else
127- count=$( bd list 2> /dev/null | wc -l | tr -d ' ' )
134+ count=$( bd list --limit " $limit " 2> /dev/null | wc -l | tr -d ' ' )
128135 fi
129136
130137 echo " ${count:- 0} "
@@ -163,8 +170,8 @@ check_github_available() {
163170# fetch_github_tasks - Fetch issues from GitHub
164171#
165172# Parameters:
166- # $1 (label) - Label to filter by (optional, default: "ralph-task" )
167- # $2 (limit) - Maximum number of issues (optional, default: 50 )
173+ # $1 (label) - Label to filter by (optional)
174+ # $2 (limit) - Maximum number of issues (optional, default: "0" = all )
168175#
169176# Outputs:
170177# Tasks in markdown checkbox format
@@ -174,34 +181,58 @@ check_github_available() {
174181# 0 - Success
175182# 1 - Error
176183#
184+ # Note:
185+ # `gh issue list --limit` enforces a hard cap of 1000 regardless of the
186+ # value supplied. When limit=0 ("all"), we fall back to `gh api --paginate`
187+ # against the issues endpoint so large repos are not silently truncated.
188+ # The issues endpoint returns pull requests as well, so those are filtered
189+ # out via `.pull_request | not`.
190+ #
177191fetch_github_tasks () {
178192 local label=" ${1:- } "
179- local limit=" ${2:- 50 } "
193+ local limit=" ${2:- 0 } "
180194 local tasks=" "
195+ local json_output
181196
182197 # Check if GitHub is available
183198 if ! check_github_available; then
184199 return 1
185200 fi
186201
187- # Build gh command
188- local gh_args=(" issue" " list" " --state" " open" " --limit" " $limit " " --json" " number,title,labels" )
189- if [[ -n " $label " ]]; then
190- gh_args+=(" --label" " $label " )
191- fi
192-
193- # Fetch issues
194- local json_output
195- if ! json_output=$( gh " ${gh_args[@]} " 2> /dev/null) ; then
196- return 1
197- fi
198-
199- # Parse JSON and format as markdown tasks
200- if command -v jq & > /dev/null; then
201- tasks=$( echo " $json_output " | jq -r '
202- .[] |
203- "- [ ] [#\(.number)] \(.title)"
204- ' 2> /dev/null)
202+ if [[ " $limit " == " 0" ]]; then
203+ # Fetch all open issues via the REST API with automatic pagination.
204+ # `-f` passes URL-encoded string fields so labels with spaces or
205+ # special characters are handled correctly.
206+ local api_args=(" api" " --method" " GET" " repos/{owner}/{repo}/issues"
207+ " -f" " state=open" " -f" " per_page=100" " --paginate" )
208+ if [[ -n " $label " ]]; then
209+ api_args+=(" -f" " labels=$label " )
210+ fi
211+ if ! json_output=$( gh " ${api_args[@]} " 2> /dev/null) ; then
212+ return 1
213+ fi
214+ # Parse and format, filtering out pull requests
215+ if command -v jq & > /dev/null; then
216+ tasks=$( echo " $json_output " | jq -r '
217+ .[] | select(.pull_request | not) |
218+ "- [ ] [#\(.number)] \(.title)"
219+ ' 2> /dev/null)
220+ fi
221+ else
222+ # Bounded fetch via `gh issue list` which already excludes PRs
223+ local gh_args=(" issue" " list" " --state" " open" " --limit" " $limit " " --json" " number,title,labels" )
224+ if [[ -n " $label " ]]; then
225+ gh_args+=(" --label" " $label " )
226+ fi
227+ if ! json_output=$( gh " ${gh_args[@]} " 2> /dev/null) ; then
228+ return 1
229+ fi
230+ if command -v jq & > /dev/null; then
231+ tasks=$( echo " $json_output " | jq -r '
232+ .[] |
233+ "- [ ] [#\(.number)] \(.title)"
234+ ' 2> /dev/null)
235+ fi
205236 fi
206237
207238 if [[ -n " $tasks " ]]; then
@@ -490,6 +521,7 @@ prioritize_tasks() {
490521# $1 (sources) - Space-separated list of sources: beads, github, prd
491522# $2 (prd_file) - Path to PRD file (required if prd in sources)
492523# $3 (github_label) - GitHub label filter (optional)
524+ # $4 (limit) - Max issues to fetch per source (optional, default: "0" = all)
493525#
494526# Outputs:
495527# Combined tasks in markdown format
@@ -502,14 +534,15 @@ import_tasks_from_sources() {
502534 local sources=$1
503535 local prd_file=" ${2:- } "
504536 local github_label=" ${3:- } "
537+ local limit=" ${4:- 0} "
505538
506539 local all_tasks=" "
507540 local source_count=0
508541
509542 # Import from beads
510543 if echo " $sources " | grep -qw " beads" ; then
511544 local beads_tasks
512- if beads_tasks=$( fetch_beads_tasks) ; then
545+ if beads_tasks=$( fetch_beads_tasks " open " " $limit " ) ; then
513546 if [[ -n " $beads_tasks " ]]; then
514547 all_tasks=" ${all_tasks}
515548# Tasks from beads
@@ -523,7 +556,7 @@ ${beads_tasks}
523556 # Import from GitHub
524557 if echo " $sources " | grep -qw " github" ; then
525558 local github_tasks
526- if github_tasks=$( fetch_github_tasks " $github_label " ) ; then
559+ if github_tasks=$( fetch_github_tasks " $github_label " " $limit " ) ; then
527560 if [[ -n " $github_tasks " ]]; then
528561 all_tasks=" ${all_tasks}
529562# Tasks from GitHub
0 commit comments