()
| 46 | } |
| 47 | |
| 48 | export function createRuntimeNodeLocalPtyAdapter(): RuntimeNodePtyAdapter { |
| 49 | const local: LocalPtyState = { |
| 50 | active: new Map(), |
| 51 | listeners: new Set(), |
| 52 | } |
| 53 | |
| 54 | return { |
| 55 | addLifecycleListener(listener) { |
| 56 | local.listeners.add(listener) |
| 57 | return () => local.listeners.delete(listener) |
| 58 | }, |
| 59 | async spawn(params: RuntimeNodePtySpawnParams) { |
| 60 | await assertDirectory(params.cwd) |
| 61 | const ptyId = params.ptyId || `pty-${randomUUID()}` |
| 62 | if (local.active.has(ptyId)) return { ok: true } |
| 63 | |
| 64 | const shell = shellCommand() |
| 65 | const child = spawn(shell, [], { |
| 66 | cwd: params.cwd, |
| 67 | env: { ...process.env, ...params.env, TERM: process.env.TERM || "xterm-256color" }, |
| 68 | detached: process.platform !== "win32", |
| 69 | windowsHide: true, |
| 70 | }) |
| 71 | const state: ActivePty = { |
| 72 | process: child, |
| 73 | output: [], |
| 74 | completed: false, |
| 75 | exitCode: null, |
| 76 | cwd: params.cwd, |
| 77 | } |
| 78 | local.active.set(ptyId, state) |
| 79 | |
| 80 | child.stdout?.on("data", (data: Buffer) => { |
| 81 | const text = data.toString("utf8") |
| 82 | bufferOutput(state, text) |
| 83 | emit(local, { type: "output", ptyId, chunk: text }) |
| 84 | }) |
| 85 | child.stderr?.on("data", (data: Buffer) => { |
| 86 | const text = data.toString("utf8") |
| 87 | bufferOutput(state, text) |
| 88 | emit(local, { type: "output", ptyId, chunk: text }) |
| 89 | }) |
| 90 | child.once("exit", (exitCode) => { |
| 91 | if (state.completed) return |
| 92 | state.completed = true |
| 93 | state.exitCode = exitCode ?? 0 |
| 94 | emit(local, { type: "exit", ptyId, exitCode: state.exitCode }) |
| 95 | }) |
| 96 | child.once("error", (error) => { |
| 97 | if (state.completed) return |
| 98 | state.completed = true |
| 99 | state.exitCode = 1 |
| 100 | emit(local, { type: "output", ptyId, chunk: error.message }) |
| 101 | emit(local, { type: "exit", ptyId, exitCode: 1 }) |
| 102 | }) |
| 103 | |
| 104 | emit(local, { |
| 105 | type: "started", |
no outgoing calls
no test coverage detected