agentk8 1.0.0
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/LICENSE +21 -0
- package/README.md +222 -0
- package/agentk +481 -0
- package/bin/agentk-wrapper.js +35 -0
- package/bin/postinstall.js +97 -0
- package/lib/core.sh +281 -0
- package/lib/ipc.sh +501 -0
- package/lib/spawn.sh +398 -0
- package/lib/ui.sh +415 -0
- package/lib/visual.sh +349 -0
- package/modes/dev/engineer.md +118 -0
- package/modes/dev/orchestrator.md +110 -0
- package/modes/dev/security.md +221 -0
- package/modes/dev/tester.md +161 -0
- package/modes/ml/data-engineer.md +244 -0
- package/modes/ml/evaluator.md +265 -0
- package/modes/ml/ml-engineer.md +239 -0
- package/modes/ml/orchestrator.md +145 -0
- package/modes/ml/researcher.md +198 -0
- package/modes/shared/scout.md +270 -0
- package/package.json +49 -0
package/lib/ui.sh
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# AGENT-K UI Library
|
|
3
|
+
# Pretty terminal output, spinners, boxes, and status displays
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
# Source core for colors
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
source "$SCRIPT_DIR/core.sh"
|
|
10
|
+
|
|
11
|
+
# =============================================================================
|
|
12
|
+
# UNICODE CHARACTERS
|
|
13
|
+
# =============================================================================
|
|
14
|
+
|
|
15
|
+
# Box drawing
|
|
16
|
+
BOX_TL="╭"
|
|
17
|
+
BOX_TR="╮"
|
|
18
|
+
BOX_BL="╰"
|
|
19
|
+
BOX_BR="╯"
|
|
20
|
+
BOX_H="─"
|
|
21
|
+
BOX_V="│"
|
|
22
|
+
BOX_CROSS="┼"
|
|
23
|
+
BOX_T_DOWN="┬"
|
|
24
|
+
BOX_T_UP="┴"
|
|
25
|
+
BOX_T_RIGHT="├"
|
|
26
|
+
BOX_T_LEFT="┤"
|
|
27
|
+
|
|
28
|
+
# Status indicators
|
|
29
|
+
STATUS_WAITING="[ ]"
|
|
30
|
+
STATUS_WORKING="[◐]"
|
|
31
|
+
STATUS_ACTIVE="[●]"
|
|
32
|
+
STATUS_DONE="[✓]"
|
|
33
|
+
STATUS_FAILED="[✗]"
|
|
34
|
+
|
|
35
|
+
# Spinner frames
|
|
36
|
+
SPINNER_FRAMES=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
|
|
37
|
+
|
|
38
|
+
# Progress bar
|
|
39
|
+
PROGRESS_FILLED="█"
|
|
40
|
+
PROGRESS_EMPTY="░"
|
|
41
|
+
|
|
42
|
+
# =============================================================================
|
|
43
|
+
# SCREEN UTILITIES
|
|
44
|
+
# =============================================================================
|
|
45
|
+
|
|
46
|
+
get_terminal_width() {
|
|
47
|
+
tput cols 2>/dev/null || echo 80
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get_terminal_height() {
|
|
51
|
+
tput lines 2>/dev/null || echo 24
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
clear_screen() {
|
|
55
|
+
printf "\033[2J\033[H"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
move_cursor() {
|
|
59
|
+
local row="$1"
|
|
60
|
+
local col="$2"
|
|
61
|
+
printf "\033[%d;%dH" "$row" "$col"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
hide_cursor() {
|
|
65
|
+
printf "\033[?25l"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
show_cursor() {
|
|
69
|
+
printf "\033[?25h"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
save_cursor() {
|
|
73
|
+
printf "\033[s"
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
restore_cursor() {
|
|
77
|
+
printf "\033[u"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# =============================================================================
|
|
81
|
+
# BOX DRAWING
|
|
82
|
+
# =============================================================================
|
|
83
|
+
|
|
84
|
+
draw_box() {
|
|
85
|
+
local title="$1"
|
|
86
|
+
local width="${2:-$(get_terminal_width)}"
|
|
87
|
+
|
|
88
|
+
# Ensure minimum width
|
|
89
|
+
[[ $width -lt 20 ]] && width=20
|
|
90
|
+
|
|
91
|
+
local inner_width=$((width - 2))
|
|
92
|
+
local title_len=${#title}
|
|
93
|
+
local padding=$(( (inner_width - title_len) / 2 ))
|
|
94
|
+
|
|
95
|
+
# Top border
|
|
96
|
+
printf "%s" "$BOX_TL"
|
|
97
|
+
printf "%${inner_width}s" | tr ' ' "$BOX_H"
|
|
98
|
+
printf "%s\n" "$BOX_TR"
|
|
99
|
+
|
|
100
|
+
# Title line
|
|
101
|
+
if [[ -n "$title" ]]; then
|
|
102
|
+
printf "%s" "$BOX_V"
|
|
103
|
+
printf "%${padding}s" ""
|
|
104
|
+
printf "${BOLD}%s${RESET}" "$title"
|
|
105
|
+
printf "%$((inner_width - padding - title_len))s" ""
|
|
106
|
+
printf "%s\n" "$BOX_V"
|
|
107
|
+
|
|
108
|
+
# Separator after title
|
|
109
|
+
printf "%s" "$BOX_V"
|
|
110
|
+
printf "%${inner_width}s" | tr ' ' "$BOX_H"
|
|
111
|
+
printf "%s\n" "$BOX_V"
|
|
112
|
+
fi
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
draw_box_line() {
|
|
116
|
+
local content="$1"
|
|
117
|
+
local width="${2:-$(get_terminal_width)}"
|
|
118
|
+
local inner_width=$((width - 4))
|
|
119
|
+
|
|
120
|
+
printf "%s " "$BOX_V"
|
|
121
|
+
printf "%-${inner_width}s" "$content"
|
|
122
|
+
printf " %s\n" "$BOX_V"
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
close_box() {
|
|
126
|
+
local width="${1:-$(get_terminal_width)}"
|
|
127
|
+
local inner_width=$((width - 2))
|
|
128
|
+
|
|
129
|
+
printf "%s" "$BOX_BL"
|
|
130
|
+
printf "%${inner_width}s" | tr ' ' "$BOX_H"
|
|
131
|
+
printf "%s\n" "$BOX_BR"
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# =============================================================================
|
|
135
|
+
# HEADER / BANNER
|
|
136
|
+
# =============================================================================
|
|
137
|
+
|
|
138
|
+
print_banner() {
|
|
139
|
+
local width
|
|
140
|
+
width=$(get_terminal_width)
|
|
141
|
+
[[ $width -gt 60 ]] && width=60
|
|
142
|
+
|
|
143
|
+
echo
|
|
144
|
+
draw_box "AGENT-K v${AGENTK_VERSION}" "$width"
|
|
145
|
+
close_box "$width"
|
|
146
|
+
echo
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
print_mode_banner() {
|
|
150
|
+
local mode="$1"
|
|
151
|
+
local mode_display
|
|
152
|
+
|
|
153
|
+
case "$mode" in
|
|
154
|
+
dev) mode_display="Software Development Mode" ;;
|
|
155
|
+
ml) mode_display="ML Research & Training Mode" ;;
|
|
156
|
+
*) mode_display="$mode Mode" ;;
|
|
157
|
+
esac
|
|
158
|
+
|
|
159
|
+
echo "${DIM}Mode: ${RESET}${CYAN}$mode_display${RESET}"
|
|
160
|
+
echo
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# =============================================================================
|
|
164
|
+
# STATUS INDICATORS
|
|
165
|
+
# =============================================================================
|
|
166
|
+
|
|
167
|
+
get_status_indicator() {
|
|
168
|
+
local status="$1"
|
|
169
|
+
|
|
170
|
+
case "$status" in
|
|
171
|
+
waiting|pending) echo "${DIM}${STATUS_WAITING}${RESET}" ;;
|
|
172
|
+
working|in_progress) echo "${YELLOW}${STATUS_WORKING}${RESET}" ;;
|
|
173
|
+
active) echo "${CYAN}${STATUS_ACTIVE}${RESET}" ;;
|
|
174
|
+
done|completed) echo "${GREEN}${STATUS_DONE}${RESET}" ;;
|
|
175
|
+
failed|error) echo "${RED}${STATUS_FAILED}${RESET}" ;;
|
|
176
|
+
*) echo "${STATUS_WAITING}" ;;
|
|
177
|
+
esac
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
print_agent_status() {
|
|
181
|
+
local agent="$1"
|
|
182
|
+
local status="$2"
|
|
183
|
+
local message="${3:-}"
|
|
184
|
+
|
|
185
|
+
local indicator
|
|
186
|
+
indicator=$(get_status_indicator "$status")
|
|
187
|
+
local agent_display
|
|
188
|
+
agent_display=$(printf "%-12s" "$agent")
|
|
189
|
+
|
|
190
|
+
echo "${indicator} ${BOLD}${agent_display}${RESET} ${DIM}${message}${RESET}"
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
print_all_agent_status() {
|
|
194
|
+
local -n agents_ref=$1 # nameref to associative array
|
|
195
|
+
|
|
196
|
+
for agent in "${!agents_ref[@]}"; do
|
|
197
|
+
local status="${agents_ref[$agent]%%:*}"
|
|
198
|
+
local message="${agents_ref[$agent]#*:}"
|
|
199
|
+
print_agent_status "$agent" "$status" "$message"
|
|
200
|
+
done
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
# =============================================================================
|
|
204
|
+
# SPINNER
|
|
205
|
+
# =============================================================================
|
|
206
|
+
|
|
207
|
+
# Global spinner state
|
|
208
|
+
_SPINNER_PID=""
|
|
209
|
+
_SPINNER_MSG=""
|
|
210
|
+
|
|
211
|
+
start_spinner() {
|
|
212
|
+
local message="${1:-Working...}"
|
|
213
|
+
_SPINNER_MSG="$message"
|
|
214
|
+
|
|
215
|
+
hide_cursor
|
|
216
|
+
|
|
217
|
+
(
|
|
218
|
+
local i=0
|
|
219
|
+
while true; do
|
|
220
|
+
printf "\r${YELLOW}%s${RESET} %s" "${SPINNER_FRAMES[$i]}" "$message"
|
|
221
|
+
i=$(( (i + 1) % ${#SPINNER_FRAMES[@]} ))
|
|
222
|
+
sleep 0.1
|
|
223
|
+
done
|
|
224
|
+
) &
|
|
225
|
+
|
|
226
|
+
_SPINNER_PID=$!
|
|
227
|
+
disown "$_SPINNER_PID" 2>/dev/null || true
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
stop_spinner() {
|
|
231
|
+
local success="${1:-true}"
|
|
232
|
+
local final_message="${2:-$_SPINNER_MSG}"
|
|
233
|
+
|
|
234
|
+
if [[ -n "$_SPINNER_PID" ]]; then
|
|
235
|
+
kill "$_SPINNER_PID" 2>/dev/null || true
|
|
236
|
+
wait "$_SPINNER_PID" 2>/dev/null || true
|
|
237
|
+
_SPINNER_PID=""
|
|
238
|
+
fi
|
|
239
|
+
|
|
240
|
+
# Clear the spinner line
|
|
241
|
+
printf "\r%${COLUMNS:-80}s\r" ""
|
|
242
|
+
|
|
243
|
+
if [[ "$success" == "true" ]]; then
|
|
244
|
+
echo "${GREEN}${STATUS_DONE}${RESET} $final_message"
|
|
245
|
+
else
|
|
246
|
+
echo "${RED}${STATUS_FAILED}${RESET} $final_message"
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
show_cursor
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
# =============================================================================
|
|
253
|
+
# PROGRESS BAR
|
|
254
|
+
# =============================================================================
|
|
255
|
+
|
|
256
|
+
print_progress_bar() {
|
|
257
|
+
local current="$1"
|
|
258
|
+
local total="$2"
|
|
259
|
+
local width="${3:-40}"
|
|
260
|
+
local label="${4:-Progress}"
|
|
261
|
+
|
|
262
|
+
local percent=$((current * 100 / total))
|
|
263
|
+
local filled=$((current * width / total))
|
|
264
|
+
local empty=$((width - filled))
|
|
265
|
+
|
|
266
|
+
printf "%s: " "$label"
|
|
267
|
+
|
|
268
|
+
# Filled portion
|
|
269
|
+
printf "${GREEN}"
|
|
270
|
+
for ((i = 0; i < filled; i++)); do
|
|
271
|
+
printf "%s" "$PROGRESS_FILLED"
|
|
272
|
+
done
|
|
273
|
+
|
|
274
|
+
# Empty portion
|
|
275
|
+
printf "${DIM}"
|
|
276
|
+
for ((i = 0; i < empty; i++)); do
|
|
277
|
+
printf "%s" "$PROGRESS_EMPTY"
|
|
278
|
+
done
|
|
279
|
+
|
|
280
|
+
printf "${RESET} %3d%%\n" "$percent"
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
# =============================================================================
|
|
284
|
+
# MESSAGES
|
|
285
|
+
# =============================================================================
|
|
286
|
+
|
|
287
|
+
print_task() {
|
|
288
|
+
local task="$1"
|
|
289
|
+
echo
|
|
290
|
+
echo "${BOLD}Task:${RESET} ${CYAN}\"$task\"${RESET}"
|
|
291
|
+
echo
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
print_orchestrator_message() {
|
|
295
|
+
local message="$1"
|
|
296
|
+
echo "${MAGENTA}[Orchestrator]${RESET} $message"
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
print_agent_message() {
|
|
300
|
+
local agent="$1"
|
|
301
|
+
local message="$2"
|
|
302
|
+
echo "${CYAN}[$agent]${RESET} $message"
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
print_user_prompt() {
|
|
306
|
+
printf "\n${GREEN}You:${RESET} "
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
print_focus_prompt() {
|
|
310
|
+
local agent="$1"
|
|
311
|
+
printf "\n${CYAN}[$agent]${RESET} ${GREEN}You:${RESET} "
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
print_task_assignment() {
|
|
315
|
+
local agent="$1"
|
|
316
|
+
local task="$2"
|
|
317
|
+
echo " ${DIM}→${RESET} ${BOLD}$agent:${RESET} $task"
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
# =============================================================================
|
|
321
|
+
# DIVIDERS
|
|
322
|
+
# =============================================================================
|
|
323
|
+
|
|
324
|
+
print_divider() {
|
|
325
|
+
local char="${1:-─}"
|
|
326
|
+
local width
|
|
327
|
+
width=$(get_terminal_width)
|
|
328
|
+
printf "${DIM}"
|
|
329
|
+
printf "%${width}s" | tr ' ' "$char"
|
|
330
|
+
printf "${RESET}\n"
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
print_section() {
|
|
334
|
+
local title="$1"
|
|
335
|
+
echo
|
|
336
|
+
print_divider
|
|
337
|
+
echo "${BOLD}$title${RESET}"
|
|
338
|
+
print_divider
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
# =============================================================================
|
|
342
|
+
# HELP TEXT
|
|
343
|
+
# =============================================================================
|
|
344
|
+
|
|
345
|
+
print_command_help() {
|
|
346
|
+
echo
|
|
347
|
+
echo "${BOLD}Session Commands:${RESET}"
|
|
348
|
+
echo " ${CYAN}/status${RESET} Show all agent states"
|
|
349
|
+
echo " ${CYAN}/logs <agent>${RESET} View agent output"
|
|
350
|
+
echo " ${CYAN}/kill <agent>${RESET} Stop agent(s)"
|
|
351
|
+
echo " ${CYAN}/focus <agent>${RESET} Talk directly to agent"
|
|
352
|
+
echo " ${CYAN}/unfocus${RESET} Return to orchestrator"
|
|
353
|
+
echo " ${CYAN}/visual${RESET} Toggle tmux view"
|
|
354
|
+
echo " ${CYAN}/clear${RESET} Clear screen"
|
|
355
|
+
echo " ${CYAN}/exit${RESET} End session"
|
|
356
|
+
echo
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
print_scout_commands() {
|
|
360
|
+
echo
|
|
361
|
+
echo "${BOLD}Scout Commands:${RESET}"
|
|
362
|
+
echo " ${CYAN}/search <query>${RESET} Web search"
|
|
363
|
+
echo " ${CYAN}/github <query>${RESET} Search GitHub"
|
|
364
|
+
echo " ${CYAN}/papers <topic>${RESET} Search papers"
|
|
365
|
+
echo " ${CYAN}/libs <task>${RESET} Find libraries"
|
|
366
|
+
echo " ${CYAN}/sota <topic>${RESET} State-of-the-art"
|
|
367
|
+
echo
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
print_ml_commands() {
|
|
371
|
+
echo
|
|
372
|
+
echo "${BOLD}ML Commands:${RESET}"
|
|
373
|
+
echo " ${CYAN}/experiment <name>${RESET} Start experiment"
|
|
374
|
+
echo " ${CYAN}/metrics${RESET} Show metrics"
|
|
375
|
+
echo " ${CYAN}/tensorboard${RESET} Open TensorBoard"
|
|
376
|
+
echo " ${CYAN}/checkpoint${RESET} Save model"
|
|
377
|
+
echo " ${CYAN}/compare <e1> <e2>${RESET} Compare experiments"
|
|
378
|
+
echo " ${CYAN}/huggingface <q>${RESET} Search HF Hub"
|
|
379
|
+
echo
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
# =============================================================================
|
|
383
|
+
# ERROR DISPLAY
|
|
384
|
+
# =============================================================================
|
|
385
|
+
|
|
386
|
+
print_error() {
|
|
387
|
+
local message="$1"
|
|
388
|
+
echo "${RED}${BOLD}Error:${RESET} ${RED}$message${RESET}" >&2
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
print_warning() {
|
|
392
|
+
local message="$1"
|
|
393
|
+
echo "${YELLOW}${BOLD}Warning:${RESET} ${YELLOW}$message${RESET}"
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
print_success() {
|
|
397
|
+
local message="$1"
|
|
398
|
+
echo "${GREEN}${BOLD}Success:${RESET} $message"
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
print_info() {
|
|
402
|
+
local message="$1"
|
|
403
|
+
echo "${CYAN}${BOLD}Info:${RESET} $message"
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
# =============================================================================
|
|
407
|
+
# CLEANUP ON EXIT
|
|
408
|
+
# =============================================================================
|
|
409
|
+
|
|
410
|
+
ui_cleanup() {
|
|
411
|
+
show_cursor
|
|
412
|
+
[[ -n "${_SPINNER_PID:-}" ]] && kill "$_SPINNER_PID" 2>/dev/null || true
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
trap ui_cleanup EXIT
|