022 · Client
Service client (attached front ends) (spec_client_022)
| Status | Implemented. Reverse-engineered from 53f8c53 (2026-09-24) and kept with the code since; its paths and names checked 2026-09-27 (//tools/specs). |
| Source | pkg/client/{client,convert,workers}.go; backend selection in apps/cli/setup.go, workers.go |
| Tests | pkg/client/client_test.go, apps/cli/internal/tui/remote_test.go |
| Depends on | spec_service_021, spec_workspace_018 |
| Used by | spec_cli_020, spec_tui_019 |
client.Remote is a workspace held by the service, reached over its socket, implementing api.Backend. Front ends drive it exactly like a local *engine.Workspace, including typed errors.
- CL-01
Attach(ctx, socket, dir, warn)makesdirabsolute, opens the workspace in the service (GetModel) and records whether its model works (ModelErr).AttachHTTPdoes the same over any HTTP client (tests). - CL-02 The CLI always attaches: to the shared service (started when it isn’t running), or to a private one it starts for a run of its own (spec_cli_020 CLI-14); it prints that it attached to the shared one. Failing to start or attach is an error. The interface language catalogs are always the client process’s own. Since 2026-10-04
Release(sock, dir)asks a service to close a workspace (CloseWorkspace; refused while a turn runs),Remote.ForgetProjectTrustforgets the project-settings decision, andSettingsreachesConfigServicewithout a workspace:ListModels(providers named or configured, with Blitz’s prices) andCheckPermission. - CL-03
Closeleaves the workspace open in the service for other clients. - CL-04
Processes()are the service’s background processes started in this client’s turns (the sessions it ran turns in, remembered byRun):Runninglists them (ListProcesses),WaitAllasks every 500 ms until none runs,Shutdownstops those still running (KillProcess), so the exit prompt (TUI-40) works attached as it does locally. Background tasks likewise:ListTasks,Task,StopTask,PendingTaskRequestsandAnswerTaskRequestsee only this client’s sessions’ tasks. Other clients’ processes aren’t listed and can’t be stopped from here (UNKNOWN_PROCESS); they survive this client.AuditShellrecords a!cmdin the service workspace’s audit log asuser_shell(AuditShell), though the command ran here. - CL-05
RunstreamsRunTurn, converts events toapi.Event, callsOnAcceptedonaccepted, and answersapproval_request/questionevents through the UI set withSetUI(no approver, or an approver error →DENY; failures to send an answer are warned).OnFinishedruns whenfinishedarrives, after the service collected unread steer messages; a message sent later is refused withSTEER_TOO_LATE(api.ErrSteerTooLate, already recorded), and the REPL and the desktop app send it as the next turn with the unread ones (ENG-42, BL-SVC-10). The result carries output, usage and leftover;finished.erroris converted to the typed error. - CL-06 Error conversion: an
ErrorInfo.reasonmaps back topkg/api’s sentinel or typed error (e.g.PROMPT_BLOCKED→*BlockedError,NO_ACTIVE_SESSION→ErrNoActiveSession), wrapped soerrors.Ismatches while the message stays the service’s. - CL-07 Operations whose
Backendsignature has no error (listings) return empty results and report the failure throughwarn. - CL-08 Images:
LoadImage/AddImageupload to the service and turns reference images by ID. - CL-09 Workers:
AttachWorkers(socket, dir)implements the CLI’s worker operations overWorkerService;RunWorkerstarts a run, watches its events (WatchWorkerRun), and returns the record once the run has finished (immediately if it finished before watching began).RunningWorkerRuns(the workspace’s runs going now) andStopWorkerRunserveblitz workers stop.