juno-code 1.0.41 → 1.0.43
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/bin/cli.js +4245 -3670
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +4247 -3671
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +219 -83
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +211 -75
- package/dist/index.mjs.map +1 -1
- package/dist/templates/scripts/install_requirements.sh +3 -4
- package/dist/templates/scripts/kanban.sh +85 -3
- package/dist/templates/scripts/run_until_completion.sh +190 -14
- package/package.json +1 -1
|
@@ -52,10 +52,9 @@ BLUE='\033[0;34m'
|
|
|
52
52
|
NC='\033[0m' # No Color
|
|
53
53
|
|
|
54
54
|
# Required packages
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
SLACK_PACKAGES=("slack_sdk" "python-dotenv")
|
|
55
|
+
# Note: requests and python-dotenv are required by github.py
|
|
56
|
+
# slack_sdk is required by Slack integration scripts (slack_fetch.py, slack_respond.py)
|
|
57
|
+
REQUIRED_PACKAGES=("juno-kanban" "roundtable-ai" "requests" "python-dotenv" "slack_sdk")
|
|
59
58
|
|
|
60
59
|
# Version check cache configuration
|
|
61
60
|
# This ensures we don't check PyPI on every run (performance optimization per Task RTafs5)
|
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
#
|
|
10
10
|
# Usage: ./.juno_task/scripts/kanban.sh [juno-kanban arguments]
|
|
11
11
|
# Example: ./.juno_task/scripts/kanban.sh list --limit 5
|
|
12
|
+
# Example: ./.juno_task/scripts/kanban.sh list -f json --raw # (flag order normalized)
|
|
13
|
+
# Example: ./.juno_task/scripts/kanban.sh -f json --raw list # (also works)
|
|
14
|
+
#
|
|
15
|
+
# Note: Global flags (-f/--format, -p/--pretty, --raw, -v/--verbose, -c/--config)
|
|
16
|
+
# can be placed anywhere in the command line. This wrapper normalizes them
|
|
17
|
+
# to appear before the command for juno-kanban compatibility.
|
|
12
18
|
#
|
|
13
19
|
# Environment Variables:
|
|
14
20
|
# JUNO_DEBUG=true - Show [DEBUG] diagnostic messages
|
|
@@ -170,6 +176,67 @@ PROJECT_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )"
|
|
|
170
176
|
# Change to project root
|
|
171
177
|
cd "$PROJECT_ROOT"
|
|
172
178
|
|
|
179
|
+
# Arrays to store normalized arguments (declared at script level for proper handling)
|
|
180
|
+
declare -a NORMALIZED_GLOBAL_FLAGS=()
|
|
181
|
+
declare -a NORMALIZED_COMMAND_ARGS=()
|
|
182
|
+
|
|
183
|
+
# Normalize argument order for juno-kanban
|
|
184
|
+
# juno-kanban requires global flags BEFORE the command, but users often
|
|
185
|
+
# write them after (e.g., "list -f json --raw" instead of "-f json --raw list")
|
|
186
|
+
# This function reorders arguments so global flags come first.
|
|
187
|
+
# Results are stored in NORMALIZED_GLOBAL_FLAGS and NORMALIZED_COMMAND_ARGS arrays.
|
|
188
|
+
normalize_arguments() {
|
|
189
|
+
# Reset arrays
|
|
190
|
+
NORMALIZED_GLOBAL_FLAGS=()
|
|
191
|
+
NORMALIZED_COMMAND_ARGS=()
|
|
192
|
+
local found_command=false
|
|
193
|
+
|
|
194
|
+
# Known subcommands
|
|
195
|
+
local commands="create search get show update archive mark list merge"
|
|
196
|
+
|
|
197
|
+
while [[ $# -gt 0 ]]; do
|
|
198
|
+
case $1 in
|
|
199
|
+
# Global flags that take a value
|
|
200
|
+
-f|--format|-c|--config)
|
|
201
|
+
if [[ -n "${2:-}" ]]; then
|
|
202
|
+
NORMALIZED_GLOBAL_FLAGS+=("$1" "$2")
|
|
203
|
+
shift 2
|
|
204
|
+
else
|
|
205
|
+
NORMALIZED_GLOBAL_FLAGS+=("$1")
|
|
206
|
+
shift
|
|
207
|
+
fi
|
|
208
|
+
;;
|
|
209
|
+
# Global flags that don't take a value
|
|
210
|
+
-p|--pretty|--raw|-v|--verbose|-h|--help|--version)
|
|
211
|
+
NORMALIZED_GLOBAL_FLAGS+=("$1")
|
|
212
|
+
shift
|
|
213
|
+
;;
|
|
214
|
+
# Check if this is a known command
|
|
215
|
+
*)
|
|
216
|
+
# Check if this argument is a known command
|
|
217
|
+
local is_command=false
|
|
218
|
+
for cmd in $commands; do
|
|
219
|
+
if [[ "$1" == "$cmd" ]]; then
|
|
220
|
+
is_command=true
|
|
221
|
+
found_command=true
|
|
222
|
+
break
|
|
223
|
+
fi
|
|
224
|
+
done
|
|
225
|
+
|
|
226
|
+
# If we found a command, everything from here goes to command_args
|
|
227
|
+
if $is_command || $found_command; then
|
|
228
|
+
NORMALIZED_COMMAND_ARGS+=("$1")
|
|
229
|
+
found_command=true
|
|
230
|
+
else
|
|
231
|
+
# Before finding a command, treat as command arg
|
|
232
|
+
NORMALIZED_COMMAND_ARGS+=("$1")
|
|
233
|
+
fi
|
|
234
|
+
shift
|
|
235
|
+
;;
|
|
236
|
+
esac
|
|
237
|
+
done
|
|
238
|
+
}
|
|
239
|
+
|
|
173
240
|
# Main kanban logic
|
|
174
241
|
main() {
|
|
175
242
|
log_info "=== juno-kanban Wrapper ==="
|
|
@@ -182,11 +249,26 @@ main() {
|
|
|
182
249
|
|
|
183
250
|
log_success "Python environment ready!"
|
|
184
251
|
|
|
185
|
-
#
|
|
252
|
+
# Normalize argument order (global flags before command)
|
|
253
|
+
# This allows users to write "list -f json --raw" which gets reordered to "-f json --raw list"
|
|
254
|
+
normalize_arguments "$@"
|
|
255
|
+
|
|
256
|
+
if [ "${JUNO_DEBUG:-false}" = "true" ]; then
|
|
257
|
+
echo "[DEBUG] Original args: $*" >&2
|
|
258
|
+
echo "[DEBUG] Normalized global flags: ${NORMALIZED_GLOBAL_FLAGS[*]:-<none>}" >&2
|
|
259
|
+
echo "[DEBUG] Normalized command args: ${NORMALIZED_COMMAND_ARGS[*]:-<none>}" >&2
|
|
260
|
+
fi
|
|
261
|
+
|
|
262
|
+
# Execute juno-kanban with normalized arguments from project root
|
|
186
263
|
# Close stdin (redirect from /dev/null) to prevent hanging when called from tools
|
|
187
264
|
# that don't provide stdin (similar to Issue #42 hook fix)
|
|
188
|
-
|
|
189
|
-
juno-kanban
|
|
265
|
+
# Build the command properly preserving argument quoting
|
|
266
|
+
log_info "Executing juno-kanban with normalized arguments"
|
|
267
|
+
|
|
268
|
+
# Execute with proper array expansion to preserve quoting
|
|
269
|
+
# Use ${arr[@]+"${arr[@]}"} pattern to handle empty arrays with set -u
|
|
270
|
+
juno-kanban ${NORMALIZED_GLOBAL_FLAGS[@]+"${NORMALIZED_GLOBAL_FLAGS[@]}"} \
|
|
271
|
+
${NORMALIZED_COMMAND_ARGS[@]+"${NORMALIZED_COMMAND_ARGS[@]}"} < /dev/null
|
|
190
272
|
}
|
|
191
273
|
|
|
192
274
|
# Run main function with all arguments
|
|
@@ -4,11 +4,10 @@
|
|
|
4
4
|
#
|
|
5
5
|
# Purpose: Continuously run juno-code until all kanban tasks are completed
|
|
6
6
|
#
|
|
7
|
-
# This script uses a
|
|
8
|
-
# then checks the kanban board for tasks
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
# doesn't initially detect any tasks.
|
|
7
|
+
# This script uses a while loop pattern: it ALWAYS runs pre-run hooks/commands,
|
|
8
|
+
# then checks the kanban board for tasks BEFORE running juno-code. If no tasks
|
|
9
|
+
# exist, juno-code is NOT executed. This allows pre-run hooks (e.g., Slack sync,
|
|
10
|
+
# GitHub sync) to create tasks that will then be processed by juno-code.
|
|
12
11
|
#
|
|
13
12
|
# Usage: ./.juno_task/scripts/run_until_completion.sh [options] [juno-code arguments]
|
|
14
13
|
# Example: ./.juno_task/scripts/run_until_completion.sh -s claude -i 5 -v
|
|
@@ -33,6 +32,9 @@
|
|
|
33
32
|
# - Using the flag multiple times: --pre-run-hook A --pre-run-hook B
|
|
34
33
|
# - Comma-separated: --pre-run-hook "A,B,C"
|
|
35
34
|
# - Pipe-separated: --pre-run-hook "A|B|C"
|
|
35
|
+
# --stale-threshold <n> - Number of stale iterations before exiting (default: 3)
|
|
36
|
+
# Set to 0 to disable stale detection
|
|
37
|
+
# --no-stale-check - Alias for --stale-threshold 0
|
|
36
38
|
#
|
|
37
39
|
# All other arguments are forwarded to juno-code.
|
|
38
40
|
# The script shows all stdout/stderr from juno-code in real-time.
|
|
@@ -42,8 +44,16 @@
|
|
|
42
44
|
# JUNO_VERBOSE=true - Show [RUN_UNTIL] informational messages
|
|
43
45
|
# JUNO_PRE_RUN - Alternative way to specify pre-run command (env var)
|
|
44
46
|
# JUNO_PRE_RUN_HOOK - Alternative way to specify pre-run hook name (env var)
|
|
47
|
+
# JUNO_STALE_THRESHOLD - Number of stale iterations before exiting (default: 3)
|
|
48
|
+
# Set to 0 to disable stale detection
|
|
45
49
|
# (JUNO_DEBUG and JUNO_VERBOSE default to false for silent operation)
|
|
46
50
|
#
|
|
51
|
+
# Stale Iteration Detection:
|
|
52
|
+
# The script tracks kanban state (task IDs and statuses) between iterations.
|
|
53
|
+
# If no changes are detected for JUNO_STALE_THRESHOLD consecutive iterations,
|
|
54
|
+
# the script will exit to prevent infinite loops where the agent doesn't
|
|
55
|
+
# process any tasks.
|
|
56
|
+
#
|
|
47
57
|
# Created by: juno-code init command
|
|
48
58
|
# Date: Auto-generated during project initialization
|
|
49
59
|
|
|
@@ -66,6 +76,12 @@ NC='\033[0m' # No Color
|
|
|
66
76
|
SCRIPTS_DIR=".juno_task/scripts"
|
|
67
77
|
KANBAN_SCRIPT="${SCRIPTS_DIR}/kanban.sh"
|
|
68
78
|
|
|
79
|
+
# Stale iteration detection configuration
|
|
80
|
+
# Number of consecutive iterations without kanban changes before exiting
|
|
81
|
+
STALE_THRESHOLD="${JUNO_STALE_THRESHOLD:-3}"
|
|
82
|
+
STALE_COUNTER=0
|
|
83
|
+
PREVIOUS_KANBAN_STATE=""
|
|
84
|
+
|
|
69
85
|
# Arrays to store pre-run commands, hooks, and juno-code arguments
|
|
70
86
|
declare -a PRE_RUN_CMDS=()
|
|
71
87
|
declare -a PRE_RUN_HOOKS=()
|
|
@@ -86,6 +102,22 @@ parse_arguments() {
|
|
|
86
102
|
PRE_RUN_CMDS+=("$2")
|
|
87
103
|
shift 2
|
|
88
104
|
;;
|
|
105
|
+
--stale-threshold)
|
|
106
|
+
if [[ -z "${2:-}" ]]; then
|
|
107
|
+
echo "[ERROR] --stale-threshold requires a number argument" >&2
|
|
108
|
+
exit 1
|
|
109
|
+
fi
|
|
110
|
+
if ! [[ "$2" =~ ^[0-9]+$ ]]; then
|
|
111
|
+
echo "[ERROR] --stale-threshold must be a non-negative integer, got: $2" >&2
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
STALE_THRESHOLD="$2"
|
|
115
|
+
shift 2
|
|
116
|
+
;;
|
|
117
|
+
--no-stale-check)
|
|
118
|
+
STALE_THRESHOLD=0
|
|
119
|
+
shift
|
|
120
|
+
;;
|
|
89
121
|
--pre-run-hook|--pre-run-hooks|--run-pre-hook|--run-pre-hooks)
|
|
90
122
|
if [[ -z "${2:-}" ]]; then
|
|
91
123
|
echo "[ERROR] $1 requires a hook name argument" >&2
|
|
@@ -327,6 +359,85 @@ PROJECT_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )"
|
|
|
327
359
|
# Change to project root
|
|
328
360
|
cd "$PROJECT_ROOT"
|
|
329
361
|
|
|
362
|
+
# Function to get a snapshot of kanban state for comparison
|
|
363
|
+
# Uses the summary statistics (total_tasks + status_counts) as a reliable indicator
|
|
364
|
+
# of kanban state changes. This approach is more robust than parsing multi-line JSON
|
|
365
|
+
# which can contain control characters that break jq parsing.
|
|
366
|
+
get_kanban_state_snapshot() {
|
|
367
|
+
local snapshot=""
|
|
368
|
+
|
|
369
|
+
# Check if kanban script exists
|
|
370
|
+
if [ ! -f "$KANBAN_SCRIPT" ]; then
|
|
371
|
+
echo ""
|
|
372
|
+
return
|
|
373
|
+
fi
|
|
374
|
+
|
|
375
|
+
# Use --raw format for cleaner JSON output
|
|
376
|
+
# The --raw flag outputs: line 1 = tasks array, line 2 = summary object
|
|
377
|
+
local kanban_output
|
|
378
|
+
if kanban_output=$("$KANBAN_SCRIPT" -f json --raw list --status backlog todo in_progress 2>/dev/null); then
|
|
379
|
+
if command -v jq &> /dev/null; then
|
|
380
|
+
# Extract the summary line (last line of --raw output)
|
|
381
|
+
local summary_line
|
|
382
|
+
summary_line=$(echo "$kanban_output" | tail -1)
|
|
383
|
+
|
|
384
|
+
# Extract status counts from summary - this is a reliable state indicator
|
|
385
|
+
# Format: "backlog:N|done:N|in_progress:N|todo:N|archive:N|total:N"
|
|
386
|
+
local summary_snapshot=""
|
|
387
|
+
if [[ -n "$summary_line" ]] && echo "$summary_line" | grep -q '"summary"'; then
|
|
388
|
+
summary_snapshot=$(echo "$summary_line" | jq -r '
|
|
389
|
+
.summary |
|
|
390
|
+
"backlog:\(.status_counts.backlog // 0)|" +
|
|
391
|
+
"todo:\(.status_counts.todo // 0)|" +
|
|
392
|
+
"in_progress:\(.status_counts.in_progress // 0)|" +
|
|
393
|
+
"done:\(.status_counts.done // 0)|" +
|
|
394
|
+
"archive:\(.status_counts.archive // 0)|" +
|
|
395
|
+
"total:\(.total_tasks // 0)"
|
|
396
|
+
' 2>/dev/null)
|
|
397
|
+
fi
|
|
398
|
+
|
|
399
|
+
# Also try to extract task IDs using grep (more robust than jq for multi-line JSON)
|
|
400
|
+
# This catches cases where tasks are added/removed but counts stay the same
|
|
401
|
+
local task_ids=""
|
|
402
|
+
task_ids=$(echo "$kanban_output" | grep -o '"id": *"[^"]*"' | sed 's/"id": *"\([^"]*\)"/\1/' | sort | tr '\n' ',')
|
|
403
|
+
|
|
404
|
+
# Combine summary stats and task IDs for comprehensive state tracking
|
|
405
|
+
if [[ -n "$summary_snapshot" ]]; then
|
|
406
|
+
snapshot="${summary_snapshot}|ids:${task_ids}"
|
|
407
|
+
elif [[ -n "$task_ids" ]]; then
|
|
408
|
+
# Fallback to just task IDs if summary parsing failed
|
|
409
|
+
snapshot="ids:${task_ids}"
|
|
410
|
+
fi
|
|
411
|
+
else
|
|
412
|
+
# Fallback without jq: use grep to extract id and status fields
|
|
413
|
+
snapshot=$(echo "$kanban_output" | grep -E '"id"|"status"' | tr -d ' \n')
|
|
414
|
+
fi
|
|
415
|
+
fi
|
|
416
|
+
|
|
417
|
+
echo "$snapshot"
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
# Function to check if kanban state has changed
|
|
421
|
+
# Returns 0 if state changed, 1 if stale (no change)
|
|
422
|
+
check_kanban_state_changed() {
|
|
423
|
+
local current_state
|
|
424
|
+
current_state=$(get_kanban_state_snapshot)
|
|
425
|
+
|
|
426
|
+
if [ "${JUNO_DEBUG:-false}" = "true" ]; then
|
|
427
|
+
echo "[DEBUG] Previous kanban state: $PREVIOUS_KANBAN_STATE" >&2
|
|
428
|
+
echo "[DEBUG] Current kanban state: $current_state" >&2
|
|
429
|
+
fi
|
|
430
|
+
|
|
431
|
+
if [[ "$current_state" == "$PREVIOUS_KANBAN_STATE" ]]; then
|
|
432
|
+
# State is the same - no changes detected
|
|
433
|
+
return 1
|
|
434
|
+
else
|
|
435
|
+
# State changed
|
|
436
|
+
PREVIOUS_KANBAN_STATE="$current_state"
|
|
437
|
+
return 0
|
|
438
|
+
fi
|
|
439
|
+
}
|
|
440
|
+
|
|
330
441
|
# Function to check if there are tasks remaining
|
|
331
442
|
has_remaining_tasks() {
|
|
332
443
|
log_info "Checking kanban for remaining tasks..."
|
|
@@ -391,19 +502,37 @@ main() {
|
|
|
391
502
|
log_status "Maximum iterations: unlimited"
|
|
392
503
|
fi
|
|
393
504
|
|
|
505
|
+
if [ "$STALE_THRESHOLD" -gt 0 ]; then
|
|
506
|
+
log_status "Stale iteration threshold: $STALE_THRESHOLD"
|
|
507
|
+
else
|
|
508
|
+
log_status "Stale iteration detection: disabled"
|
|
509
|
+
fi
|
|
510
|
+
|
|
511
|
+
# Capture initial kanban state before first iteration
|
|
512
|
+
PREVIOUS_KANBAN_STATE=$(get_kanban_state_snapshot)
|
|
513
|
+
|
|
394
514
|
# Check if we have any arguments for juno-code
|
|
395
515
|
if [[ ${#JUNO_ARGS[@]} -eq 0 ]]; then
|
|
396
516
|
log_warning "No arguments provided. Running juno-code with no arguments."
|
|
397
517
|
fi
|
|
398
518
|
|
|
399
|
-
#
|
|
400
|
-
#
|
|
519
|
+
# ALWAYS execute pre-run hooks and commands before checking for tasks
|
|
520
|
+
# This ensures hooks (e.g., Slack sync, GitHub sync) can create tasks
|
|
521
|
+
# that will then be processed by juno-code
|
|
401
522
|
execute_pre_run_hooks
|
|
402
523
|
execute_pre_run_commands
|
|
403
524
|
|
|
404
|
-
#
|
|
405
|
-
#
|
|
406
|
-
|
|
525
|
+
# Check for tasks BEFORE entering the main loop
|
|
526
|
+
# If no tasks exist after running pre-run hooks, exit gracefully
|
|
527
|
+
if ! has_remaining_tasks; then
|
|
528
|
+
log_success ""
|
|
529
|
+
log_success "=========================================="
|
|
530
|
+
log_success "No tasks found in kanban. Pre-run hooks executed, juno-code skipped."
|
|
531
|
+
log_success "=========================================="
|
|
532
|
+
exit 0
|
|
533
|
+
fi
|
|
534
|
+
|
|
535
|
+
# While loop pattern: Only run juno-code if there are tasks to process
|
|
407
536
|
while true; do
|
|
408
537
|
iteration=$((iteration + 1))
|
|
409
538
|
|
|
@@ -425,7 +554,6 @@ main() {
|
|
|
425
554
|
log_status "------------------------------------------"
|
|
426
555
|
|
|
427
556
|
# Run juno-code with parsed arguments (excluding --pre-run which was already processed)
|
|
428
|
-
# We run juno-code FIRST (do-while pattern), then check for remaining tasks
|
|
429
557
|
if juno-code "${JUNO_ARGS[@]}"; then
|
|
430
558
|
log_success "juno-code completed successfully"
|
|
431
559
|
else
|
|
@@ -441,9 +569,57 @@ main() {
|
|
|
441
569
|
# Small delay to prevent rapid-fire execution and allow user to Ctrl+C if needed
|
|
442
570
|
sleep 1
|
|
443
571
|
|
|
444
|
-
# Check for
|
|
445
|
-
# This
|
|
446
|
-
|
|
572
|
+
# Check for stale iterations (no kanban state changes)
|
|
573
|
+
# This prevents infinite loops where agent doesn't process any tasks
|
|
574
|
+
if [ "$STALE_THRESHOLD" -gt 0 ]; then
|
|
575
|
+
if check_kanban_state_changed; then
|
|
576
|
+
# State changed - reset the stale counter
|
|
577
|
+
STALE_COUNTER=0
|
|
578
|
+
log_info "Kanban state changed. Stale counter reset."
|
|
579
|
+
else
|
|
580
|
+
# State unchanged - increment stale counter
|
|
581
|
+
STALE_COUNTER=$((STALE_COUNTER + 1))
|
|
582
|
+
log_warning "No kanban changes detected. Stale iteration count: $STALE_COUNTER/$STALE_THRESHOLD"
|
|
583
|
+
|
|
584
|
+
if [ "$STALE_COUNTER" -ge "$STALE_THRESHOLD" ]; then
|
|
585
|
+
# Execute ON_STALE hook before exiting
|
|
586
|
+
log_status ""
|
|
587
|
+
log_status "Executing ON_STALE hook due to stale iteration detection"
|
|
588
|
+
execute_hook_commands "ON_STALE"
|
|
589
|
+
|
|
590
|
+
log_error ""
|
|
591
|
+
log_error "=========================================="
|
|
592
|
+
log_error "STALE ITERATION LIMIT REACHED"
|
|
593
|
+
log_error "=========================================="
|
|
594
|
+
log_error ""
|
|
595
|
+
log_error "The script has run $STALE_COUNTER consecutive iterations"
|
|
596
|
+
log_error "without any changes to the kanban board state."
|
|
597
|
+
log_error ""
|
|
598
|
+
log_error "This typically happens when:"
|
|
599
|
+
log_error " 1. The agent doesn't recognize or prioritize remaining tasks"
|
|
600
|
+
log_error " 2. Tasks are stuck in a state the agent cannot process"
|
|
601
|
+
log_error " 3. There's a configuration or prompt issue"
|
|
602
|
+
log_error ""
|
|
603
|
+
log_error "Remaining tasks are still in the kanban system but"
|
|
604
|
+
log_error "the agent is not making progress on them."
|
|
605
|
+
log_error ""
|
|
606
|
+
log_error "To adjust this threshold, set JUNO_STALE_THRESHOLD"
|
|
607
|
+
log_error "environment variable (current: $STALE_THRESHOLD, default: 3)"
|
|
608
|
+
log_error "Set to 0 to disable stale detection."
|
|
609
|
+
log_error ""
|
|
610
|
+
log_error "=========================================="
|
|
611
|
+
# Also print to stdout so it's visible in all contexts
|
|
612
|
+
echo ""
|
|
613
|
+
echo "STALE ITERATION LIMIT REACHED: No kanban changes detected for $STALE_COUNTER iterations."
|
|
614
|
+
echo "The agent is not processing remaining tasks. Exiting to prevent infinite loop."
|
|
615
|
+
echo "Set JUNO_STALE_THRESHOLD=0 to disable this check, or increase the threshold value."
|
|
616
|
+
echo ""
|
|
617
|
+
exit 2
|
|
618
|
+
fi
|
|
619
|
+
fi
|
|
620
|
+
fi
|
|
621
|
+
|
|
622
|
+
# Check for remaining tasks AFTER running juno-code
|
|
447
623
|
if ! has_remaining_tasks; then
|
|
448
624
|
log_success ""
|
|
449
625
|
log_success "=========================================="
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "juno-code",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.43",
|
|
4
4
|
"description": "Ralph Wiggum meet Kanban! Ralph style execution for [Claude Code, Codex, Gemini, Cursor]. One task per iteration, automatic progress tracking, and git commits. Set it and let it run.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ralph",
|