* List Coder workspaces (all statuses).
()
| 987 | * List Coder workspaces (all statuses). |
| 988 | */ |
| 989 | async listWorkspaces(): Promise<CoderListWorkspacesResult> { |
| 990 | // Derive known statuses from schema to avoid duplication and prevent ORPC validation errors |
| 991 | const KNOWN_STATUSES = new Set<string>(CoderWorkspaceStatusSchema.options); |
| 992 | |
| 993 | try { |
| 994 | const stdout = await this.runCoderJsonCommand(["list", "--output=json"]); |
| 995 | |
| 996 | // Handle empty output (no workspaces) |
| 997 | if (!stdout.trim()) { |
| 998 | return { ok: true, workspaces: [] }; |
| 999 | } |
| 1000 | |
| 1001 | const workspaces = JSON.parse(stdout) as Array<{ |
| 1002 | name: string; |
| 1003 | template_name: string; |
| 1004 | template_display_name: string; |
| 1005 | latest_build: { |
| 1006 | status: string; |
| 1007 | }; |
| 1008 | }>; |
| 1009 | |
| 1010 | // Filter to known statuses to avoid ORPC schema validation failures |
| 1011 | return { |
| 1012 | ok: true, |
| 1013 | workspaces: workspaces |
| 1014 | .filter((w) => KNOWN_STATUSES.has(w.latest_build.status)) |
| 1015 | .map((w) => ({ |
| 1016 | name: w.name, |
| 1017 | templateName: w.template_name, |
| 1018 | templateDisplayName: w.template_display_name || w.template_name, |
| 1019 | status: w.latest_build.status as CoderWorkspaceStatus, |
| 1020 | })), |
| 1021 | }; |
| 1022 | } catch (error) { |
| 1023 | const message = sanitizeCoderCliErrorForUi(error); |
| 1024 | // Users reported seeing "No workspaces found" even when the CLI failed, |
| 1025 | // so surface an error state instead of silently returning an empty list. |
| 1026 | log.warn("Failed to list Coder workspaces", { error }); |
| 1027 | return { ok: false, error: message || "Unknown error" }; |
| 1028 | } |
| 1029 | } |
| 1030 | |
| 1031 | /** |
| 1032 | * Run a `coder` CLI command with timeout + optional cancellation. |
no test coverage detected