Skip to content

Uses process IO Instead of SSH2 socket IO #187

@AlexanderYW

Description

@AlexanderYW

Hey,

As of Bun v1.2.5, I noticed that the ssh2 server package should be working correctly. So I decided to try integrating @opentui/react with it. Unfortunately, things didn’t go quite as expected.

When I start the SSH server, the TUI output is written to the server’s process IO instead of the client’s stream when connecting (provided by ssh2). I attempted to debug this myself, but due to my limited understanding of the codebase, I wasn’t able to figure out the issue.

Interestingly, when using nearly identical code with Ink instead of @opentui/react, only replacing the render and elements, everything works, the UI renders to the SSH client stream, with minor issues e.g. the known LF/CRLF issue which can be patched.

To reproduce it:

Create ssh key

Generate key in same folder as the code
ssh-keygen -t rsa -b 4096 -f host.key

Code snippet

// server.ts
import { Server as SSHServer } from "ssh2";
import { render } from "@opentui/react";
import { readFileSync } from "fs";
import { PassThrough } from "stream";

const ssh = new SSHServer({
  hostKeys: [readFileSync('host.key')]
});

ssh.on("connection", (client, info) => {
  client.on("authentication", (ctx) => {
    ctx.accept();
  });

  client.on("ready", () => {
    client.on("session", (accept, reject) => {
      const session = accept();
      session.on("pty", (acceptPty) => {
        acceptPty();
      });

      session.on("shell", async (acceptShell) => {
        const stream = acceptShell();

        const sshInput = new PassThrough();
        const sshOutput = new PassThrough();

        // Pipe streams between SSH and OpenTUI
        stream.pipe(sshInput);
        sshOutput.pipe(stream);

        const App = () => (
          <box style={{ flexDirection: "column", padding: 1 }}>
            <text>Welcome to my TUI over SSH!</text>
          </box>
        );

        // render with custom stdin/stdout
        await render(<App />, {
          stdin: sshInput as unknown as NodeJS.ReadStream,
          stdout: sshOutput as unknown as NodeJS.WriteStream,
          exitOnCtrlC: true,
        });
      });
    });
  });
});

ssh.listen(2222, "0.0.0.0", () => {
  console.log("SSH server listening on port 2222");
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    coreThis relates to the core packageenhancementNew feature or requesthelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions