mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 23:19:43 +02:00
feat(docker): make the container field a picker you can also type into
Typing a container name from memory is error-prone. The field becomes a native datalist: pick from the engine's containers, type to filter, or type a name that is not listed (the engine may be remote, or the container may not exist yet). A datalist gives all three natively, so no dropdown state machine is introduced. Adds listDockerContainers and GET /api/docker-hosts/:hostId/containers, following the listRemoteCodemanSessions discovery precedent: read-only and never throwing, so an unreachable daemon returns an empty list and the field degrades to plain text instead of erroring. Stopped containers stay in the list, sorted after running ones and labelled. Attaching does require a running container, but hiding stopped ones turns "my container is not in the list" into a dead end, while showing `Exited (137) 8 days ago` says exactly what to fix.
This commit is contained in:
@@ -69,6 +69,7 @@ import {
|
||||
dockerContainerName,
|
||||
dockerDisplayPath,
|
||||
probeAdoptableContainer,
|
||||
listDockerContainers,
|
||||
DOCKER_ADOPT_PROBE_MODES,
|
||||
readDockerCases,
|
||||
readDockerHosts,
|
||||
@@ -77,7 +78,7 @@ import {
|
||||
writeDockerCases,
|
||||
writeDockerHosts,
|
||||
} from '../../docker-hosts.js';
|
||||
import type { AdoptedContainerProbe } from '../../docker-hosts.js';
|
||||
import type { AdoptedContainerProbe, DockerContainerInfo } from '../../docker-hosts.js';
|
||||
import { buildDockerRemoveCommand } from '../../tmux-manager.js';
|
||||
import {
|
||||
checkRemoteTmuxAvailable,
|
||||
@@ -868,6 +869,27 @@ export function registerCaseRoutes(app: FastifyInstance, ctx: EventPort & Config
|
||||
* the user "not running" / "no tmux" / "codex present, claude missing" before
|
||||
* they commit to a case name. Read-only; never touches container lifecycle.
|
||||
*/
|
||||
/**
|
||||
* Containers on the host's engine, for the adoption picker. Read-only and
|
||||
* best-effort (mirror of the remote `:hostId/sessions` discovery route): an
|
||||
* unreachable daemon yields an empty list rather than an error, because the
|
||||
* container name is a free-text field the user can always type by hand.
|
||||
*/
|
||||
app.get(
|
||||
'/api/docker-hosts/:hostId/containers',
|
||||
async (req): Promise<ApiResponse<{ containers: DockerContainerInfo[] }>> => {
|
||||
const { hostId } = req.params as { hostId: string };
|
||||
const host = (await readDockerHosts(CODEMAN_CONFIG_DIR)).find((item) => item.id === hostId);
|
||||
if (!host) return createErrorResponse(ApiErrorCode.NOT_FOUND, 'Docker host not found');
|
||||
const containers = await listDockerContainers({
|
||||
engine: host.engine ?? 'docker',
|
||||
context: host.context,
|
||||
daemonHost: host.daemonHost,
|
||||
});
|
||||
return { success: true, data: { containers } };
|
||||
}
|
||||
);
|
||||
|
||||
app.post('/api/docker-cases/adopt-preflight', async (req): Promise<ApiResponse<AdoptedContainerProbe>> => {
|
||||
const body = parseBody(DockerAdoptPreflightSchema, req.body);
|
||||
const host = (await readDockerHosts(CODEMAN_CONFIG_DIR)).find((item) => item.id === body.hostId);
|
||||
|
||||
Reference in New Issue
Block a user