juno-code 1.0.36 → 1.0.38
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 +170 -0
- package/dist/bin/cli.js +143 -5
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +143 -5
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +18 -1
- package/dist/index.mjs.map +1 -1
- package/dist/templates/scripts/install_requirements.sh +3 -0
- package/dist/templates/scripts/run_until_completion.sh +227 -11
- 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 +693 -0
- package/dist/templates/scripts/slack_respond.sh +263 -0
- package/dist/templates/scripts/slack_state.py +383 -0
- package/package.json +8 -2
|
@@ -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"
|
|
@@ -10,17 +10,34 @@
|
|
|
10
10
|
# internal task management systems get a chance to operate even if kanban.sh
|
|
11
11
|
# doesn't initially detect any tasks.
|
|
12
12
|
#
|
|
13
|
-
# Usage: ./.juno_task/scripts/run_until_completion.sh [juno-code arguments]
|
|
13
|
+
# Usage: ./.juno_task/scripts/run_until_completion.sh [options] [juno-code arguments]
|
|
14
14
|
# Example: ./.juno_task/scripts/run_until_completion.sh -s claude -i 5 -v
|
|
15
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
|
|
16
18
|
#
|
|
17
|
-
#
|
|
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.
|
|
18
33
|
# The script shows all stdout/stderr from juno-code in real-time.
|
|
19
34
|
#
|
|
20
35
|
# Environment Variables:
|
|
21
|
-
# JUNO_DEBUG=true
|
|
22
|
-
# JUNO_VERBOSE=true
|
|
23
|
-
#
|
|
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)
|
|
24
41
|
#
|
|
25
42
|
# Created by: juno-code init command
|
|
26
43
|
# Date: Auto-generated during project initialization
|
|
@@ -44,6 +61,191 @@ NC='\033[0m' # No Color
|
|
|
44
61
|
SCRIPTS_DIR=".juno_task/scripts"
|
|
45
62
|
KANBAN_SCRIPT="${SCRIPTS_DIR}/kanban.sh"
|
|
46
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
|
+
|
|
47
249
|
# Logging functions
|
|
48
250
|
log_info() {
|
|
49
251
|
# Only print if JUNO_VERBOSE is set to true
|
|
@@ -131,8 +333,17 @@ main() {
|
|
|
131
333
|
local iteration=0
|
|
132
334
|
local max_iterations="${JUNO_RUN_UNTIL_MAX_ITERATIONS:-0}" # 0 = unlimited
|
|
133
335
|
|
|
336
|
+
# Parse arguments first to extract --pre-run commands
|
|
337
|
+
parse_arguments "$@"
|
|
338
|
+
|
|
134
339
|
log_status "=== Run Until Completion ==="
|
|
135
|
-
|
|
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>}"
|
|
136
347
|
|
|
137
348
|
if [ "$max_iterations" -gt 0 ]; then
|
|
138
349
|
log_status "Maximum iterations: $max_iterations"
|
|
@@ -140,11 +351,16 @@ main() {
|
|
|
140
351
|
log_status "Maximum iterations: unlimited"
|
|
141
352
|
fi
|
|
142
353
|
|
|
143
|
-
# Check if we have any arguments
|
|
144
|
-
if [
|
|
354
|
+
# Check if we have any arguments for juno-code
|
|
355
|
+
if [[ ${#JUNO_ARGS[@]} -eq 0 ]]; then
|
|
145
356
|
log_warning "No arguments provided. Running juno-code with no arguments."
|
|
146
357
|
fi
|
|
147
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
|
+
|
|
148
364
|
# Do-while loop pattern: Run juno-code at least once, then continue while tasks remain
|
|
149
365
|
# This ensures juno-code's internal task management systems get a chance to operate
|
|
150
366
|
# even if kanban.sh doesn't initially detect any tasks
|
|
@@ -165,12 +381,12 @@ main() {
|
|
|
165
381
|
exit 0
|
|
166
382
|
fi
|
|
167
383
|
|
|
168
|
-
log_status "Running juno-code with args:
|
|
384
|
+
log_status "Running juno-code with args: ${JUNO_ARGS[*]:-<none>}"
|
|
169
385
|
log_status "------------------------------------------"
|
|
170
386
|
|
|
171
|
-
# Run juno-code with
|
|
387
|
+
# Run juno-code with parsed arguments (excluding --pre-run which was already processed)
|
|
172
388
|
# We run juno-code FIRST (do-while pattern), then check for remaining tasks
|
|
173
|
-
if juno-code "
|
|
389
|
+
if juno-code "${JUNO_ARGS[@]}"; then
|
|
174
390
|
log_success "juno-code completed successfully"
|
|
175
391
|
else
|
|
176
392
|
local exit_code=$?
|