juno-code 1.0.35 → 1.0.37
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 +534 -64
- package/dist/bin/cli.js +583 -181
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +582 -180
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +20 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -3
- package/dist/index.mjs.map +1 -1
- package/dist/templates/scripts/clean_logs_folder.sh +0 -0
- package/dist/templates/scripts/install_requirements.sh +3 -0
- package/dist/templates/scripts/run_until_completion.sh +418 -0
- package/dist/templates/scripts/slack_fetch.py +717 -0
- package/dist/templates/scripts/slack_fetch.sh +269 -0
- package/dist/templates/scripts/slack_respond.py +691 -0
- package/dist/templates/scripts/slack_respond.sh +263 -0
- package/dist/templates/scripts/slack_state.py +383 -0
- package/dist/templates/services/README.md +43 -0
- package/dist/templates/services/claude.py +1 -1
- package/dist/templates/services/codex.py +4 -4
- package/dist/templates/services/gemini.py +473 -0
- package/package.json +10 -4
|
File without changes
|
|
@@ -38,6 +38,9 @@ NC='\033[0m' # No Color
|
|
|
38
38
|
# Required packages
|
|
39
39
|
REQUIRED_PACKAGES=("juno-kanban" "roundtable-ai")
|
|
40
40
|
|
|
41
|
+
# Slack integration dependencies (optional, only installed when Slack scripts are used)
|
|
42
|
+
SLACK_PACKAGES=("slack_sdk" "python-dotenv")
|
|
43
|
+
|
|
41
44
|
# Logging functions
|
|
42
45
|
log_info() {
|
|
43
46
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# run_until_completion.sh
|
|
4
|
+
#
|
|
5
|
+
# Purpose: Continuously run juno-code until all kanban tasks are completed
|
|
6
|
+
#
|
|
7
|
+
# This script uses a do-while loop pattern: it runs juno-code at least once,
|
|
8
|
+
# then checks the kanban board for tasks in backlog, todo, or in_progress status.
|
|
9
|
+
# If tasks remain, it continues running juno-code. This ensures juno-code's
|
|
10
|
+
# internal task management systems get a chance to operate even if kanban.sh
|
|
11
|
+
# doesn't initially detect any tasks.
|
|
12
|
+
#
|
|
13
|
+
# Usage: ./.juno_task/scripts/run_until_completion.sh [options] [juno-code arguments]
|
|
14
|
+
# Example: ./.juno_task/scripts/run_until_completion.sh -s claude -i 5 -v
|
|
15
|
+
# Example: ./.juno_task/scripts/run_until_completion.sh -b shell -s claude -m :opus
|
|
16
|
+
# Example: ./.juno_task/scripts/run_until_completion.sh --pre-run "./slack/sync.sh" -s claude -i 5
|
|
17
|
+
# Example: ./.juno_task/scripts/run_until_completion.sh --pre-run-hook START_ITERATION -s claude -i 5
|
|
18
|
+
#
|
|
19
|
+
# Options (for run_until_completion.sh):
|
|
20
|
+
# --pre-run <cmd> - Execute command before entering the main loop
|
|
21
|
+
# Can be specified multiple times for multiple commands
|
|
22
|
+
# Commands are executed in order before juno-code starts
|
|
23
|
+
# --pre-run-hook <name> - Execute a named hook from .juno_task/config.json
|
|
24
|
+
# --pre-run-hooks <name> (alias for --pre-run-hook)
|
|
25
|
+
# --run-pre-hook <name> (alias for --pre-run-hook)
|
|
26
|
+
# --run-pre-hooks <name> (alias for --pre-run-hook)
|
|
27
|
+
# The hook should be defined in config.json under "hooks"
|
|
28
|
+
# with a "commands" array. All commands in the hook are
|
|
29
|
+
# executed before the main loop.
|
|
30
|
+
# Can be specified multiple times for multiple hooks.
|
|
31
|
+
#
|
|
32
|
+
# All other arguments are forwarded to juno-code.
|
|
33
|
+
# The script shows all stdout/stderr from juno-code in real-time.
|
|
34
|
+
#
|
|
35
|
+
# Environment Variables:
|
|
36
|
+
# JUNO_DEBUG=true - Show [DEBUG] diagnostic messages
|
|
37
|
+
# JUNO_VERBOSE=true - Show [RUN_UNTIL] informational messages
|
|
38
|
+
# JUNO_PRE_RUN - Alternative way to specify pre-run command (env var)
|
|
39
|
+
# JUNO_PRE_RUN_HOOK - Alternative way to specify pre-run hook name (env var)
|
|
40
|
+
# (JUNO_DEBUG and JUNO_VERBOSE default to false for silent operation)
|
|
41
|
+
#
|
|
42
|
+
# Created by: juno-code init command
|
|
43
|
+
# Date: Auto-generated during project initialization
|
|
44
|
+
|
|
45
|
+
set -euo pipefail # Exit on error, undefined variable, or pipe failure
|
|
46
|
+
|
|
47
|
+
# DEBUG OUTPUT: Show that run_until_completion.sh is being executed
|
|
48
|
+
if [ "${JUNO_DEBUG:-false}" = "true" ]; then
|
|
49
|
+
echo "[DEBUG] run_until_completion.sh is being executed from: $(pwd)" >&2
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Color output for better readability
|
|
53
|
+
RED='\033[0;31m'
|
|
54
|
+
GREEN='\033[0;32m'
|
|
55
|
+
YELLOW='\033[1;33m'
|
|
56
|
+
BLUE='\033[0;34m'
|
|
57
|
+
CYAN='\033[0;36m'
|
|
58
|
+
NC='\033[0m' # No Color
|
|
59
|
+
|
|
60
|
+
# Configuration
|
|
61
|
+
SCRIPTS_DIR=".juno_task/scripts"
|
|
62
|
+
KANBAN_SCRIPT="${SCRIPTS_DIR}/kanban.sh"
|
|
63
|
+
|
|
64
|
+
# Arrays to store pre-run commands, hooks, and juno-code arguments
|
|
65
|
+
declare -a PRE_RUN_CMDS=()
|
|
66
|
+
declare -a PRE_RUN_HOOKS=()
|
|
67
|
+
declare -a JUNO_ARGS=()
|
|
68
|
+
|
|
69
|
+
# Configuration file path
|
|
70
|
+
CONFIG_FILE=".juno_task/config.json"
|
|
71
|
+
|
|
72
|
+
# Parse arguments to extract --pre-run and --pre-run-hook commands
|
|
73
|
+
parse_arguments() {
|
|
74
|
+
while [[ $# -gt 0 ]]; do
|
|
75
|
+
case $1 in
|
|
76
|
+
--pre-run)
|
|
77
|
+
if [[ -z "${2:-}" ]]; then
|
|
78
|
+
echo "[ERROR] --pre-run requires a command argument" >&2
|
|
79
|
+
exit 1
|
|
80
|
+
fi
|
|
81
|
+
PRE_RUN_CMDS+=("$2")
|
|
82
|
+
shift 2
|
|
83
|
+
;;
|
|
84
|
+
--pre-run-hook|--pre-run-hooks|--run-pre-hook|--run-pre-hooks)
|
|
85
|
+
if [[ -z "${2:-}" ]]; then
|
|
86
|
+
echo "[ERROR] $1 requires a hook name argument" >&2
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
PRE_RUN_HOOKS+=("$2")
|
|
90
|
+
shift 2
|
|
91
|
+
;;
|
|
92
|
+
*)
|
|
93
|
+
JUNO_ARGS+=("$1")
|
|
94
|
+
shift
|
|
95
|
+
;;
|
|
96
|
+
esac
|
|
97
|
+
done
|
|
98
|
+
|
|
99
|
+
# Also check JUNO_PRE_RUN environment variable
|
|
100
|
+
if [[ -n "${JUNO_PRE_RUN:-}" ]]; then
|
|
101
|
+
# Prepend env var command (runs first)
|
|
102
|
+
PRE_RUN_CMDS=("$JUNO_PRE_RUN" "${PRE_RUN_CMDS[@]}")
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Also check JUNO_PRE_RUN_HOOK environment variable
|
|
106
|
+
if [[ -n "${JUNO_PRE_RUN_HOOK:-}" ]]; then
|
|
107
|
+
# Prepend env var hook (runs first)
|
|
108
|
+
PRE_RUN_HOOKS=("$JUNO_PRE_RUN_HOOK" "${PRE_RUN_HOOKS[@]}")
|
|
109
|
+
fi
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# Execute commands from a hook defined in config.json
|
|
113
|
+
execute_hook_commands() {
|
|
114
|
+
local hook_name="$1"
|
|
115
|
+
|
|
116
|
+
# Check if config file exists
|
|
117
|
+
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
118
|
+
log_error "Config file not found: $CONFIG_FILE"
|
|
119
|
+
log_error "Cannot execute hook: $hook_name"
|
|
120
|
+
return 1
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# Check if jq is available
|
|
124
|
+
if ! command -v jq &> /dev/null; then
|
|
125
|
+
log_error "jq is required for --pre-run-hook but not installed"
|
|
126
|
+
log_error "Please install jq: brew install jq (macOS) or apt-get install jq (Linux)"
|
|
127
|
+
return 1
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
# Check if hook exists in config
|
|
131
|
+
local hook_exists
|
|
132
|
+
hook_exists=$(jq -e ".hooks.\"$hook_name\"" "$CONFIG_FILE" 2>/dev/null)
|
|
133
|
+
if [[ $? -ne 0 ]] || [[ "$hook_exists" == "null" ]]; then
|
|
134
|
+
log_error "Hook '$hook_name' not found in $CONFIG_FILE"
|
|
135
|
+
log_error "Available hooks: $(jq -r '.hooks | keys | join(", ")' "$CONFIG_FILE" 2>/dev/null || echo "none")"
|
|
136
|
+
return 1
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
# Get commands array from hook
|
|
140
|
+
local commands_json
|
|
141
|
+
commands_json=$(jq -r ".hooks.\"$hook_name\".commands // []" "$CONFIG_FILE" 2>/dev/null)
|
|
142
|
+
|
|
143
|
+
# Get number of commands
|
|
144
|
+
local num_commands
|
|
145
|
+
num_commands=$(echo "$commands_json" | jq 'length')
|
|
146
|
+
|
|
147
|
+
if [[ "$num_commands" -eq 0 ]]; then
|
|
148
|
+
log_warning "Hook '$hook_name' has no commands defined"
|
|
149
|
+
return 0
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
log_status ""
|
|
153
|
+
log_status "Executing hook '$hook_name' ($num_commands command(s))"
|
|
154
|
+
log_status "------------------------------------------"
|
|
155
|
+
|
|
156
|
+
# Execute each command in the hook
|
|
157
|
+
local idx=0
|
|
158
|
+
while [[ $idx -lt $num_commands ]]; do
|
|
159
|
+
local cmd
|
|
160
|
+
cmd=$(echo "$commands_json" | jq -r ".[$idx]")
|
|
161
|
+
idx=$((idx + 1))
|
|
162
|
+
|
|
163
|
+
log_status "Hook command [$idx/$num_commands]: $cmd"
|
|
164
|
+
|
|
165
|
+
if eval "$cmd"; then
|
|
166
|
+
log_success "Hook command [$idx/$num_commands] completed successfully"
|
|
167
|
+
else
|
|
168
|
+
local exit_code=$?
|
|
169
|
+
log_error "Hook command [$idx/$num_commands] failed with exit code $exit_code"
|
|
170
|
+
log_error "Command was: $cmd"
|
|
171
|
+
# Continue with next command even if one fails
|
|
172
|
+
fi
|
|
173
|
+
done
|
|
174
|
+
|
|
175
|
+
return 0
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
# Execute all pre-run hooks
|
|
179
|
+
execute_pre_run_hooks() {
|
|
180
|
+
local hook_count=${#PRE_RUN_HOOKS[@]}
|
|
181
|
+
|
|
182
|
+
if [[ $hook_count -eq 0 ]]; then
|
|
183
|
+
return 0
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
log_status ""
|
|
187
|
+
log_status "=========================================="
|
|
188
|
+
log_status "Executing $hook_count pre-run hook(s)"
|
|
189
|
+
log_status "=========================================="
|
|
190
|
+
|
|
191
|
+
local idx=0
|
|
192
|
+
for hook_name in "${PRE_RUN_HOOKS[@]}"; do
|
|
193
|
+
idx=$((idx + 1))
|
|
194
|
+
log_status ""
|
|
195
|
+
log_status "Pre-run hook [$idx/$hook_count]: $hook_name"
|
|
196
|
+
|
|
197
|
+
if execute_hook_commands "$hook_name"; then
|
|
198
|
+
log_success "Pre-run hook [$idx/$hook_count] '$hook_name' completed"
|
|
199
|
+
else
|
|
200
|
+
log_error "Pre-run hook [$idx/$hook_count] '$hook_name' had errors"
|
|
201
|
+
# Continue with next hook even if one fails
|
|
202
|
+
fi
|
|
203
|
+
done
|
|
204
|
+
|
|
205
|
+
log_status ""
|
|
206
|
+
log_status "=========================================="
|
|
207
|
+
log_status "Pre-run hooks phase complete"
|
|
208
|
+
log_status "=========================================="
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
# Execute all pre-run commands
|
|
212
|
+
execute_pre_run_commands() {
|
|
213
|
+
local cmd_count=${#PRE_RUN_CMDS[@]}
|
|
214
|
+
|
|
215
|
+
if [[ $cmd_count -eq 0 ]]; then
|
|
216
|
+
return 0
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
log_status ""
|
|
220
|
+
log_status "=========================================="
|
|
221
|
+
log_status "Executing $cmd_count pre-run command(s)"
|
|
222
|
+
log_status "=========================================="
|
|
223
|
+
|
|
224
|
+
local idx=0
|
|
225
|
+
for cmd in "${PRE_RUN_CMDS[@]}"; do
|
|
226
|
+
idx=$((idx + 1))
|
|
227
|
+
log_status ""
|
|
228
|
+
log_status "Pre-run [$idx/$cmd_count]: $cmd"
|
|
229
|
+
log_status "------------------------------------------"
|
|
230
|
+
|
|
231
|
+
# Execute the command
|
|
232
|
+
if eval "$cmd"; then
|
|
233
|
+
log_success "Pre-run [$idx/$cmd_count] completed successfully"
|
|
234
|
+
else
|
|
235
|
+
local exit_code=$?
|
|
236
|
+
log_error "Pre-run [$idx/$cmd_count] failed with exit code $exit_code"
|
|
237
|
+
log_error "Command was: $cmd"
|
|
238
|
+
# Continue with next pre-run command even if one fails
|
|
239
|
+
# This allows partial execution like Slack sync failing but still running juno-code
|
|
240
|
+
fi
|
|
241
|
+
done
|
|
242
|
+
|
|
243
|
+
log_status ""
|
|
244
|
+
log_status "=========================================="
|
|
245
|
+
log_status "Pre-run phase complete"
|
|
246
|
+
log_status "=========================================="
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
# Logging functions
|
|
250
|
+
log_info() {
|
|
251
|
+
# Only print if JUNO_VERBOSE is set to true
|
|
252
|
+
if [ "${JUNO_VERBOSE:-false}" = "true" ]; then
|
|
253
|
+
echo -e "${BLUE}[RUN_UNTIL]${NC} $1" >&2
|
|
254
|
+
fi
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
log_success() {
|
|
258
|
+
# Only print if JUNO_VERBOSE is set to true
|
|
259
|
+
if [ "${JUNO_VERBOSE:-false}" = "true" ]; then
|
|
260
|
+
echo -e "${GREEN}[RUN_UNTIL]${NC} $1" >&2
|
|
261
|
+
fi
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
log_warning() {
|
|
265
|
+
# Only print if JUNO_VERBOSE is set to true
|
|
266
|
+
if [ "${JUNO_VERBOSE:-false}" = "true" ]; then
|
|
267
|
+
echo -e "${YELLOW}[RUN_UNTIL]${NC} $1" >&2
|
|
268
|
+
fi
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
log_error() {
|
|
272
|
+
# Always print errors regardless of JUNO_VERBOSE
|
|
273
|
+
echo -e "${RED}[RUN_UNTIL]${NC} $1" >&2
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
log_status() {
|
|
277
|
+
# Always print status updates so user knows what's happening
|
|
278
|
+
echo -e "${CYAN}[RUN_UNTIL]${NC} $1" >&2
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
# Get the directory where this script is located
|
|
282
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
283
|
+
|
|
284
|
+
# Navigate to project root (parent of scripts directory)
|
|
285
|
+
PROJECT_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )"
|
|
286
|
+
|
|
287
|
+
# Change to project root
|
|
288
|
+
cd "$PROJECT_ROOT"
|
|
289
|
+
|
|
290
|
+
# Function to check if there are tasks remaining
|
|
291
|
+
has_remaining_tasks() {
|
|
292
|
+
log_info "Checking kanban for remaining tasks..."
|
|
293
|
+
|
|
294
|
+
# Check if kanban script exists
|
|
295
|
+
if [ ! -f "$KANBAN_SCRIPT" ]; then
|
|
296
|
+
log_error "Kanban script not found: $KANBAN_SCRIPT"
|
|
297
|
+
log_error "Please run 'juno-code init' to initialize the project"
|
|
298
|
+
return 1
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
# Make sure the script is executable
|
|
302
|
+
chmod +x "$KANBAN_SCRIPT"
|
|
303
|
+
|
|
304
|
+
# Run kanban list and check for "No results found"
|
|
305
|
+
# We capture both stdout and stderr to handle various output formats
|
|
306
|
+
local kanban_output
|
|
307
|
+
if kanban_output=$("$KANBAN_SCRIPT" list --status backlog todo in_progress 2>&1); then
|
|
308
|
+
if echo "$kanban_output" | grep -q "No results found"; then
|
|
309
|
+
log_info "No remaining tasks found"
|
|
310
|
+
return 1 # No remaining tasks
|
|
311
|
+
else
|
|
312
|
+
log_info "Found remaining tasks"
|
|
313
|
+
if [ "${JUNO_DEBUG:-false}" = "true" ]; then
|
|
314
|
+
echo "[DEBUG] Kanban output:" >&2
|
|
315
|
+
echo "$kanban_output" >&2
|
|
316
|
+
fi
|
|
317
|
+
return 0 # Has remaining tasks
|
|
318
|
+
fi
|
|
319
|
+
else
|
|
320
|
+
# kanban.sh returned non-zero, check if it's because no results
|
|
321
|
+
if echo "$kanban_output" | grep -q "No results found"; then
|
|
322
|
+
log_info "No remaining tasks found (from error output)"
|
|
323
|
+
return 1
|
|
324
|
+
fi
|
|
325
|
+
log_error "Failed to check kanban status"
|
|
326
|
+
log_error "Output: $kanban_output"
|
|
327
|
+
return 1 # Treat errors as "no tasks" to prevent infinite loops
|
|
328
|
+
fi
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
# Main run loop
|
|
332
|
+
main() {
|
|
333
|
+
local iteration=0
|
|
334
|
+
local max_iterations="${JUNO_RUN_UNTIL_MAX_ITERATIONS:-0}" # 0 = unlimited
|
|
335
|
+
|
|
336
|
+
# Parse arguments first to extract --pre-run commands
|
|
337
|
+
parse_arguments "$@"
|
|
338
|
+
|
|
339
|
+
log_status "=== Run Until Completion ==="
|
|
340
|
+
if [[ ${#PRE_RUN_HOOKS[@]} -gt 0 ]]; then
|
|
341
|
+
log_status "Pre-run hooks: ${PRE_RUN_HOOKS[*]}"
|
|
342
|
+
fi
|
|
343
|
+
if [[ ${#PRE_RUN_CMDS[@]} -gt 0 ]]; then
|
|
344
|
+
log_status "Pre-run commands: ${#PRE_RUN_CMDS[@]}"
|
|
345
|
+
fi
|
|
346
|
+
log_status "Arguments to juno-code: ${JUNO_ARGS[*]:-<none>}"
|
|
347
|
+
|
|
348
|
+
if [ "$max_iterations" -gt 0 ]; then
|
|
349
|
+
log_status "Maximum iterations: $max_iterations"
|
|
350
|
+
else
|
|
351
|
+
log_status "Maximum iterations: unlimited"
|
|
352
|
+
fi
|
|
353
|
+
|
|
354
|
+
# Check if we have any arguments for juno-code
|
|
355
|
+
if [[ ${#JUNO_ARGS[@]} -eq 0 ]]; then
|
|
356
|
+
log_warning "No arguments provided. Running juno-code with no arguments."
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
# Execute pre-run hooks and commands before entering the main loop
|
|
360
|
+
# Hooks run first, then explicit commands
|
|
361
|
+
execute_pre_run_hooks
|
|
362
|
+
execute_pre_run_commands
|
|
363
|
+
|
|
364
|
+
# Do-while loop pattern: Run juno-code at least once, then continue while tasks remain
|
|
365
|
+
# This ensures juno-code's internal task management systems get a chance to operate
|
|
366
|
+
# even if kanban.sh doesn't initially detect any tasks
|
|
367
|
+
while true; do
|
|
368
|
+
iteration=$((iteration + 1))
|
|
369
|
+
|
|
370
|
+
log_status ""
|
|
371
|
+
log_status "=========================================="
|
|
372
|
+
log_status "Iteration $iteration"
|
|
373
|
+
log_status "=========================================="
|
|
374
|
+
|
|
375
|
+
# Check max iterations limit BEFORE running (prevents exceeding limit)
|
|
376
|
+
if [ "$max_iterations" -gt 0 ] && [ "$iteration" -gt "$max_iterations" ]; then
|
|
377
|
+
log_warning ""
|
|
378
|
+
log_warning "=========================================="
|
|
379
|
+
log_warning "Maximum iterations ($max_iterations) reached. Exiting."
|
|
380
|
+
log_warning "=========================================="
|
|
381
|
+
exit 0
|
|
382
|
+
fi
|
|
383
|
+
|
|
384
|
+
log_status "Running juno-code with args: ${JUNO_ARGS[*]:-<none>}"
|
|
385
|
+
log_status "------------------------------------------"
|
|
386
|
+
|
|
387
|
+
# Run juno-code with parsed arguments (excluding --pre-run which was already processed)
|
|
388
|
+
# We run juno-code FIRST (do-while pattern), then check for remaining tasks
|
|
389
|
+
if juno-code "${JUNO_ARGS[@]}"; then
|
|
390
|
+
log_success "juno-code completed successfully"
|
|
391
|
+
else
|
|
392
|
+
local exit_code=$?
|
|
393
|
+
log_warning "juno-code exited with code $exit_code"
|
|
394
|
+
# Continue the loop even if juno-code fails - it might succeed next iteration
|
|
395
|
+
# Some failures are expected (e.g., partial task completion)
|
|
396
|
+
fi
|
|
397
|
+
|
|
398
|
+
log_status "------------------------------------------"
|
|
399
|
+
log_status "Iteration $iteration complete. Checking for more tasks..."
|
|
400
|
+
|
|
401
|
+
# Small delay to prevent rapid-fire execution and allow user to Ctrl+C if needed
|
|
402
|
+
sleep 1
|
|
403
|
+
|
|
404
|
+
# Check for remaining tasks AFTER running juno-code (do-while pattern)
|
|
405
|
+
# This ensures juno-code runs at least once, allowing its internal task
|
|
406
|
+
# management systems to check kanban for updates
|
|
407
|
+
if ! has_remaining_tasks; then
|
|
408
|
+
log_success ""
|
|
409
|
+
log_success "=========================================="
|
|
410
|
+
log_success "All tasks completed! Exiting after $iteration iteration(s)."
|
|
411
|
+
log_success "=========================================="
|
|
412
|
+
exit 0
|
|
413
|
+
fi
|
|
414
|
+
done
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
# Run main function with all arguments
|
|
418
|
+
main "$@"
|