MCPcopy
hub / github.com/coder/mux / CoderService

Class CoderService

src/node/services/coderService.ts:318–1546  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

316}
317
318export class CoderService {
319 // Ephemeral API sessions scoped to workspace provisioning.
320 // This keeps token reuse explicit without persisting anything to disk.
321 private provisioningSessionPromises = new Map<string, Promise<CoderApiSession>>();
322 private provisioningSessions = new Map<string, CoderApiSession>();
323 private cachedInfo: CoderInfo | null = null;
324 // Cache whoami results so later URL lookups can reuse the last CLI response.
325 private cachedWhoami: CoderWhoamiData | null = null;
326
327 private async resolveCoderBinaryPath(): Promise<string | null> {
328 if (process.platform === "win32") {
329 // Prefer native Windows lookup — returns paths cmd.exe can execute directly.
330 try {
331 using proc = execAsync("where.exe coder");
332 const { stdout } = await proc.result;
333 const firstLine = stdout.split(/\r?\n/)[0]?.trim();
334 if (firstLine) return firstLine;
335 } catch {
336 // where.exe may not find coder; fall through to Git Bash lookup.
337 }
338
339 // Fallback: Git Bash lookup. Normalize MSYS paths (/c/...) to Windows (C:\...).
340 let shell: string | undefined;
341 try {
342 shell = getBashPath();
343 } catch {
344 return null;
345 }
346
347 try {
348 using proc = execAsync("command -v coder", { shell });
349 const { stdout } = await proc.result;
350 const firstLine = stdout.split(/\r?\n/)[0]?.trim();
351 // Convert MSYS path format to native Windows path for cmd.exe compatibility.
352 // SSH ProxyCommand runs through cmd.exe, not Git Bash.
353 return firstLine ? toWindowsPath(firstLine) : null;
354 } catch {
355 return null;
356 }
357 }
358
359 // POSIX: command -v is universally available
360 try {
361 using proc = execAsync("command -v coder");
362 const { stdout } = await proc.result;
363 const firstLine = stdout.split(/\r?\n/)[0]?.trim();
364 return firstLine || null;
365 } catch {
366 return null;
367 }
368 }
369
370 /**
371 * Get Coder CLI info. Caches result for the session.
372 * Returns discriminated union: available | outdated | unavailable.
373 */
374 async getCoderInfo(): Promise<CoderInfo> {
375 if (this.cachedInfo) {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected