MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / makeCliSurface

Function makeCliSurface

e2e/src/surfaces/cli.ts:69–116  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

67// acquireUseRelease so a vitest timeout (fiber interruption) still tears the
68// PTY down instead of leaking the child process.
69export const makeCliSurface = (): CliSurface => ({
70 session: (command, drive, options) =>
71 Effect.acquireUseRelease(
72 Effect.promise(async () => {
73 const tc = await TerminalControl.make();
74 const session: Session = await tc.launch({
75 command,
76 cwd: options?.cwd,
77 env: options?.env,
78 record: options?.record ? true : undefined,
79 viewport: options?.viewport,
80 });
81 // Anchor the terminal recording on the run's focus timeline (symmetric
82 // with the browser surface), so a combined cli+browser scenario gets the
83 // synced SessionPlayer view (terminal/browser cuts + URL bar) for free.
84 const runDir = options?.record ? dirname(options.record) : null;
85 if (runDir) markRecordingStart(runDir, "terminal");
86 return { tc, session, runDir };
87 }),
88 ({ session, runDir }) =>
89 Effect.promise(async () => {
90 if (runDir) await enterFocus(runDir, "terminal");
91 const result = await drive(session);
92 // Hold the terminal's final frame (e.g. "connected") before the
93 // recording stops, so it isn't a single flash in the film. Filming
94 // only — fast runs return immediately.
95 await beat();
96 return result;
97 }),
98 ({ tc, session }) =>
99 Effect.promise(async () => {
100 if (options?.record) {
101 const recording = await session.recording().catch(() => undefined);
102 // Writing the cast is a best-effort film artifact (symmetric with the
103 // fetch above): a serialization or IO hiccup in teardown must never
104 // fail an otherwise-passing test.
105 // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: best-effort artifact write
106 try {
107 if (recording) writeFileSync(options.record, toAsciicast(recording));
108 } catch {
109 // drop the cast; the test result stands
110 }
111 }
112 await session.stop().catch(() => {});
113 await tc[Symbol.asyncDispose]();
114 }),
115 ),
116});

Callers 1

contextForFunction · 0.90

Calls 4

markRecordingStartFunction · 0.90
enterFocusFunction · 0.90
beatFunction · 0.90
toAsciicastFunction · 0.85

Tested by

no test coverage detected