f169d25b72
Three independent fixes that all surface together while iterating on the Docker executor flow: - Remote Credentials card: the per-agent "Configured" / "Not Configured" badge was driven by useState that only seeded once on mount. Picking a secret in the dropdown updated the parent's `agentEnvVars` map but the local `choice` never moved to `"env"`, so the badge stayed grey until the page was reloaded. Derive `choice` straight from props every render so the badge tracks live state. - ACP session/load: when the agent process restarted between turns (common with claude-agent-acp because its session map is in-memory), the host's session/load call failed with JSON-RPC -32002 "Resource not found" and the entire launch errored out. Treat that as the same kind of "session is gone" signal as -32601 / capability=false and fall back to session/new. Worst case the agent loses prior context; best case the user just keeps typing. - Executor Settings popover: dropped Execution ID and Environment ID rows (debug-only noise users don't need), kept Container ID + the copyable `docker exec -it … bash` line, added a live status badge with tones for running / exited / paused / dead / error / missing, and a 3-second polling interval so the badge follows the real container state. New `GET /api/v1/tasks/:id/environment/live` endpoint plumbs Docker `inspect` data through the lifecycle manager → task service → handler. ContainerLiveStatus mirror type at the service layer keeps lifecycle types out of the public surface.
70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
import { fetchJson, type ApiRequestOptions } from "../client";
|
|
|
|
export type TaskEnvironment = {
|
|
id: string;
|
|
task_id: string;
|
|
repository_id: string;
|
|
executor_type: string;
|
|
executor_id: string;
|
|
executor_profile_id: string;
|
|
agent_execution_id: string;
|
|
control_port: number;
|
|
status: string;
|
|
worktree_id?: string;
|
|
worktree_path?: string;
|
|
worktree_branch?: string;
|
|
workspace_path?: string;
|
|
container_id?: string;
|
|
sandbox_id?: string;
|
|
created_at: string;
|
|
updated_at?: string;
|
|
};
|
|
|
|
export type ResetTaskEnvironmentPayload = {
|
|
push_branch?: boolean;
|
|
};
|
|
|
|
export type ContainerLiveStatus = {
|
|
container_id: string;
|
|
/** running, exited, paused, restarting, removing, dead, created, missing */
|
|
state: string;
|
|
/** Human-readable status, e.g. "Up 5 minutes". */
|
|
status: string;
|
|
started_at?: string;
|
|
finished_at?: string;
|
|
exit_code?: number;
|
|
health?: string;
|
|
missing?: boolean;
|
|
};
|
|
|
|
export type TaskEnvironmentLiveResponse = {
|
|
environment: TaskEnvironment;
|
|
container?: ContainerLiveStatus;
|
|
};
|
|
|
|
export async function fetchTaskEnvironment(taskId: string, options?: ApiRequestOptions) {
|
|
return fetchJson<TaskEnvironment>(`/api/v1/tasks/${taskId}/environment`, options);
|
|
}
|
|
|
|
export async function fetchTaskEnvironmentLive(taskId: string, options?: ApiRequestOptions) {
|
|
return fetchJson<TaskEnvironmentLiveResponse>(
|
|
`/api/v1/tasks/${taskId}/environment/live`,
|
|
options,
|
|
);
|
|
}
|
|
|
|
export async function resetTaskEnvironment(
|
|
taskId: string,
|
|
payload: ResetTaskEnvironmentPayload,
|
|
options?: ApiRequestOptions,
|
|
) {
|
|
return fetchJson<{ success: boolean }>(`/api/v1/tasks/${taskId}/environment/reset`, {
|
|
...options,
|
|
init: {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
...(options?.init ?? {}),
|
|
},
|
|
});
|
|
}
|