Skip to content

Commit 19e4b8c

Browse files
shmuel hizmiclaude
andcommitted
Add wmux/preset/tui: one-call TUI preset with web URL and awaitStop
New export `@playfast/wmux/preset/tui` that starts the wmux server, prints the web URL, opens the TUI client, and returns a handle with `url`, `stop()`, and `done` promise. Server auto-stops when TUI closes. Uses dynamic import for @playfast/wmux-client-terminal (devDependency for types only) — no circular deps. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 01728c7 commit 19e4b8c

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

bun.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demo/dev-server/server/tui.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { wmux } from "@playfast/wmux";
2-
import { renderWmuxTUI } from "@playfast/wmux-client-terminal";
1+
import { wmuxTUI } from "@playfast/wmux/preset/tui";
32

4-
const handle = await wmux({
3+
const { done } = await wmuxTUI({
54
title: "echoform",
65
description: "local",
76
sidebarItems: [
@@ -37,16 +36,7 @@ const handle = await wmux({
3736
],
3837
port: 4220,
3938
token: "test-token",
40-
open: false,
4139
});
4240

43-
const tui = await renderWmuxTUI({
44-
token: handle.token,
45-
wsUrl: handle.wsUrl,
46-
webUrl: handle.url,
47-
});
48-
49-
// Wait for user to quit the TUI (Ctrl+B q), then stop the server
50-
await tui.done;
51-
handle.stop();
41+
await done;
5242
process.exit(0);

packages/wmux/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
"types": "./src/views.ts",
1414
"import": "./src/views.ts",
1515
"default": "./src/views.ts"
16+
},
17+
"./preset/tui": {
18+
"types": "./src/preset/tui.ts",
19+
"import": "./src/preset/tui.ts",
20+
"default": "./src/preset/tui.ts"
1621
}
1722
},
1823
"files": [
@@ -31,6 +36,7 @@
3136
"react": ">=19.0.0"
3237
},
3338
"devDependencies": {
39+
"@playfast/wmux-client-terminal": "workspace:*",
3440
"@types/bun": "latest",
3541
"@types/react": "^19.0.0"
3642
},

packages/wmux/src/preset/tui.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { wmux } from "../wmux";
2+
import type { WmuxConfig } from "../types";
3+
import type { WmuxTUIHandle } from "@playfast/wmux-client-terminal";
4+
5+
export interface WmuxTUIPresetConfig extends Omit<WmuxConfig, "open"> {}
6+
7+
export interface WmuxTUIPresetHandle {
8+
/** Full web client URL (with token and ws params) */
9+
readonly url: string;
10+
/** Stop the wmux server and all processes */
11+
readonly stop: () => void;
12+
/** Resolves when the TUI is closed (user quit or programmatic stop) */
13+
readonly done: Promise<void>;
14+
}
15+
16+
export async function wmuxTUI(config: WmuxTUIPresetConfig): Promise<WmuxTUIPresetHandle> {
17+
const handle = await wmux({ ...config, open: false });
18+
19+
// Print web URL before TUI takes over the screen
20+
console.log(`\x1b[1m\x1b[34mweb\x1b[0m → \x1b[4m${handle.url}\x1b[0m`);
21+
22+
const { renderWmuxTUI } = await import("@playfast/wmux-client-terminal");
23+
24+
const tui: WmuxTUIHandle = await renderWmuxTUI({
25+
token: handle.token,
26+
wsUrl: handle.wsUrl,
27+
webUrl: handle.url,
28+
});
29+
30+
const done = tui.done.then(() => {
31+
handle.stop();
32+
});
33+
34+
const stop = (): void => {
35+
tui.destroy();
36+
};
37+
38+
return { url: handle.url, stop, done };
39+
}

0 commit comments

Comments
 (0)