@runuai/host 0.8.20 → 0.8.21
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/lib/agent.ts +2 -0
- package/package.json +1 -1
- package/scripts/agent/task-down.sh +16 -10
- package/scripts/agent/task-up.sh +17 -1
- package/src/index.ts +8 -0
- package/src/protocol.ts +2 -0
package/lib/agent.ts
CHANGED
|
@@ -75,6 +75,8 @@ const TaskUpData = z.object({
|
|
|
75
75
|
worktreePath: z.string(),
|
|
76
76
|
codeServerPort: z.number().int().positive().optional(),
|
|
77
77
|
previewPorts: PreviewPortRuntimesSchema.optional(),
|
|
78
|
+
/** Degraded start: uai-init failed twice; surfaced as a feed system note. */
|
|
79
|
+
initWarning: z.string().optional(),
|
|
78
80
|
});
|
|
79
81
|
export type TaskUpResult = z.infer<typeof TaskUpData>;
|
|
80
82
|
|
package/package.json
CHANGED
|
@@ -20,17 +20,23 @@ UAI_TASK_ID="$task_id"
|
|
|
20
20
|
setup_err_trap
|
|
21
21
|
|
|
22
22
|
step "TASK_NOT_FOUND" "read task row"
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
# Teardown must never depend on bookkeeping: a broken/missing command
|
|
24
|
+
# snapshot (seen live 2026-07-21 cleaning up after a failed task-up —
|
|
25
|
+
# db_get_task errored, the trap reported TASK_NOT_FOUND, and the container
|
|
26
|
+
# survived) still tears the stack down by convention-derived names.
|
|
27
|
+
task_json=$(db_get_task "$task_id" 2>/dev/null) || task_json="[]"
|
|
28
|
+
row_count=$(jq 'length' <<<"$task_json" 2>/dev/null) || row_count=0
|
|
29
|
+
if [ "$row_count" -lt 1 ]; then
|
|
30
|
+
log "task row unavailable — tearing down by derived names"
|
|
31
|
+
worktree_path=""
|
|
32
|
+
compose_project="$(compose_project_for_task "$task_id")"
|
|
33
|
+
projects_json="[]"
|
|
34
|
+
else
|
|
35
|
+
worktree_path=$(jq -r '.[0].worktree_path // ""' <<<"$task_json")
|
|
36
|
+
compose_project=$(jq -r '.[0].compose_project // ""' <<<"$task_json")
|
|
37
|
+
projects_json=$(db_get_projects_for_task "$task_id" 2>/dev/null) \
|
|
38
|
+
|| projects_json="[]"
|
|
28
39
|
fi
|
|
29
|
-
|
|
30
|
-
worktree_path=$(jq -r '.[0].worktree_path // ""' <<<"$task_json")
|
|
31
|
-
compose_project=$(jq -r '.[0].compose_project // ""' <<<"$task_json")
|
|
32
|
-
|
|
33
|
-
projects_json=$(db_get_projects_for_task "$task_id")
|
|
34
40
|
projects_root="$UAI_WORKSPACE_ROOT/projects"
|
|
35
41
|
|
|
36
42
|
# task_dir falls back to the derived path when the row's worktree_path is
|
package/scripts/agent/task-up.sh
CHANGED
|
@@ -545,7 +545,21 @@ if [ -f "$uai_identity_key" ]; then
|
|
|
545
545
|
>/dev/null 2>&1 || true
|
|
546
546
|
fi
|
|
547
547
|
|
|
548
|
-
|
|
548
|
+
# uai-init (workspace deps + code-server) is re-runnable, and its death must
|
|
549
|
+
# not error a task whose container is already up (graceful degradation): a
|
|
550
|
+
# SIGKILLed exec session (observed live 2026-07-21, exit 137 with no timeout
|
|
551
|
+
# anywhere on this path) used to fail the whole task over a step anyone can
|
|
552
|
+
# re-run. Retry once, then come up DEGRADED with a warning the host surfaces
|
|
553
|
+
# as a system note in the task feed.
|
|
554
|
+
init_warning=""
|
|
555
|
+
if ! docker exec "$app_container" /usr/local/bin/uai-init >/dev/null; then
|
|
556
|
+
log "warning: uai-init failed — retrying once"
|
|
557
|
+
sleep 2
|
|
558
|
+
if ! docker exec "$app_container" /usr/local/bin/uai-init >/dev/null; then
|
|
559
|
+
init_warning="Workspace init (deps + editor) failed twice — the task is up, but the editor and installed dependencies may be missing. Retry from a task terminal with: /usr/local/bin/uai-init"
|
|
560
|
+
log "warning: $init_warning"
|
|
561
|
+
fi
|
|
562
|
+
fi
|
|
549
563
|
|
|
550
564
|
# -----------------------------------------------------------------------------
|
|
551
565
|
# 7. Discover code-server + preview ports, mark running, unlock.
|
|
@@ -588,7 +602,9 @@ emit_ok "$(jq -nc \
|
|
|
588
602
|
--arg cp "$compose_project" \
|
|
589
603
|
--arg wp "$task_dir" \
|
|
590
604
|
--arg csport "${code_server_port:-}" \
|
|
605
|
+
--arg iw "${init_warning}" \
|
|
591
606
|
--argjson previewPorts "$preview_ports_runtime_json" \
|
|
592
607
|
'{composeProject:$cp,worktreePath:$wp}
|
|
593
608
|
+ (if $csport == "" then {} else {codeServerPort:($csport|tonumber)} end)
|
|
609
|
+
+ (if $iw == "" then {} else {initWarning:$iw} end)
|
|
594
610
|
+ {previewPorts:$previewPorts}')"
|
package/src/index.ts
CHANGED
|
@@ -123,6 +123,14 @@ export const hostCommands: HostCommands = {
|
|
|
123
123
|
if (result.ok) {
|
|
124
124
|
recordTaskUpResult(input.task.id, result.value);
|
|
125
125
|
recordHostEvent(input.task.id, "task.started");
|
|
126
|
+
// Degraded start (uai-init failed twice): the task is up, but say so
|
|
127
|
+
// in the feed — a silent half-start reads as a broken product.
|
|
128
|
+
if (result.value.initWarning) {
|
|
129
|
+
getOrchestrator().emitSystemNote(
|
|
130
|
+
input.task.id,
|
|
131
|
+
result.value.initWarning,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
126
134
|
// GitHub auth for the container is best-effort (ADR-027) and runs in the
|
|
127
135
|
// background — it must never block or fail task-up. Awaiting it here would
|
|
128
136
|
// couple the command result to a network token-exchange: a slow/hung
|
package/src/protocol.ts
CHANGED
|
@@ -93,6 +93,8 @@ export interface TaskUpResult {
|
|
|
93
93
|
worktreePath: string;
|
|
94
94
|
codeServerPort?: number;
|
|
95
95
|
previewPorts?: Array<{ name: string; hostPort: number }>;
|
|
96
|
+
/** Degraded start: uai-init failed twice; the task is up without deps/editor. */
|
|
97
|
+
initWarning?: string;
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
export interface TaskDownResult {
|