[PR #636] feat(ssh): add @opentui/ssh package with stream-mode renderer migration #1459

Open
opened 2026-03-14 09:37:55 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/anomalyco/opentui/pull/636
Author: @msmps
Created: 2/6/2026
Status: 🔄 Open

Base: mainHead: feat/ssh


📝 Commits (4)

  • 978af38 feat(ssh/core): add SSH package and migrate renderer to NativeSpanFeed stream output
  • 88b4f61 fix(ssh/core): address code review findings across SSH and renderer
  • 9c5234c fix(ssh/core): address reviewer findings in SSH and stream mode
  • 9639f9f feat(ssh): add allowAll() middleware for production-ready open servers

📊 Changes

29 files changed (+4282 additions, -239 deletions)

View changed files

📝 bun.lock (+77 -0)
📝 packages/core/src/console.ts (+8 -0)
📝 packages/core/src/renderer.ts (+333 -68)
📝 packages/core/src/testing/test-renderer.ts (+15 -4)
packages/core/src/tests/renderer.stream-mode.test.ts (+269 -0)
packages/core/src/tests/renderer.stream-validation.test.ts (+48 -0)
📝 packages/core/src/zig.ts (+16 -4)
📝 packages/core/src/zig/lib.zig (+22 -2)
📝 packages/core/src/zig/renderer.zig (+311 -137)
📝 packages/core/src/zig/tests/buffer_test.zig (+2 -2)
📝 packages/core/src/zig/tests/renderer_test.zig (+287 -22)
packages/ssh/README.md (+291 -0)
packages/ssh/examples/counter.ts (+109 -0)
packages/ssh/package.json (+40 -0)
packages/ssh/src/index.ts (+24 -0)
packages/ssh/src/middleware/index.ts (+172 -0)
packages/ssh/src/server.ts (+354 -0)
packages/ssh/src/session.ts (+207 -0)
packages/ssh/src/types.ts (+65 -0)
packages/ssh/src/utils/authorized-keys.ts (+36 -0)

...and 9 more files

📄 Description

@opentui/ssh + stream-mode renderer migration

Summary

  • Adds a new @opentui/ssh package for running OpenTUI apps over SSH with per-session renderer isolation.
  • Migrates core non-stdout transport from callback output to outputMode: "stream" backed by NativeSpanFeed in Zig.
  • Applies follow-up hardening from review: auth decision guarding, session admission race fixes, authorized_keys option safety, PTY dimension normalization, and renderer stdin teardown correction.

What This PR Includes

1) New package: @opentui/ssh

  • createSSHServer() with lifecycle events (listening, session, error, close).
  • SSHSession wrapper with stream output wiring, input forwarding, resize handling, and idempotent close.
  • Built-in middleware:
    • logging()
    • publicKey() (OpenSSH authorized_keys parsing/matching)
    • allowAll() (production-ready open server, no warnings)
    • devMode() (development-only, prints security warning)
  • Host key utilities and docs/examples/tests.

2) Core renderer stream architecture

  • outputMode: "stream" in @opentui/core with required onOutput, width, and height validation.
  • NativeSpanFeed/Zig integration for feed-backed output dispatch and backpressure-safe async delivery.
  • Renderer and test utilities updated for stream-mode creation and validation.

3) Reviewer follow-up fixes

  • Prevents auth double-decision races via guarded accept/reject flow in SSH auth handling.
  • Enforces maxSessions against active + pending session creation to close async admission race.
  • Normalizes invalid PTY dimensions (e.g. 0x0) to safe defaults before renderer creation.
  • Treats authorized_keys option-prefixed entries as unsupported and ignores them (with warning) to avoid silently weakening restrictions.
  • Fixes global process.stdin.pause() behavior so stream-only renderer teardown does not pause stdin.

Documentation and Testing

  • Expanded packages/ssh/README.md with middleware phases/order, auth/session patterns, and compatibility notes.
  • Added/expanded tests across:
    • packages/ssh/tests/* (server, middleware, authorized-keys, session, integration, host-key)
    • packages/core/src/tests/renderer.stream-mode.test.ts
    • packages/core/src/tests/renderer.stream-validation.test.ts

Manual Verification (SSH Counter Example)

  1. Start the example server:
    • cd packages/ssh
    • bun run example
  2. In another terminal, connect with SSH:
    • ssh -p 2222 localhost
  3. Validate behavior in one or more sessions:
    • + / - updates the counter
    • terminal resize updates displayed dimensions
    • q cleanly closes the session
  4. (If host key changed) clear stale host key entry:
    • ssh-keygen -R "[localhost]:2222"

Pilotty-Based Verification

1) Install Pilotty

npm install -g pilotty

Verify with pilotty --version.

2) Install the Pilotty OpenCode skill

npx skills add msmps/pilotty

3) AI-assisted review prompt

Use this in OpenCode to run the flow autonomously:

use pilotty to test out the ssh impl with the ssh counter example;
spawn concurrent sessions and validate

Expected validation flow: start server, open concurrent SSH sessions, verify per-session counter isolation, test resize propagation, and quit sessions cleanly.

Notes

  • publicKey() currently supports key matching only; OpenSSH option prefixes (from=, command=, no-pty, etc.) are intentionally not enforced yet and are ignored.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/anomalyco/opentui/pull/636 **Author:** [@msmps](https://github.com/msmps) **Created:** 2/6/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/ssh` --- ### 📝 Commits (4) - [`978af38`](https://github.com/anomalyco/opentui/commit/978af384d22e596ee3ce72709990d0e37acb0f5d) feat(ssh/core): add SSH package and migrate renderer to NativeSpanFeed stream output - [`88b4f61`](https://github.com/anomalyco/opentui/commit/88b4f61ed3b3ac0fe3c7172cfa7e14027859962e) fix(ssh/core): address code review findings across SSH and renderer - [`9c5234c`](https://github.com/anomalyco/opentui/commit/9c5234c1526e4aac6d168de2acede2aa4904a08e) fix(ssh/core): address reviewer findings in SSH and stream mode - [`9639f9f`](https://github.com/anomalyco/opentui/commit/9639f9f5262447b471538d5a2b1fd462443dcf7d) feat(ssh): add allowAll() middleware for production-ready open servers ### 📊 Changes **29 files changed** (+4282 additions, -239 deletions) <details> <summary>View changed files</summary> 📝 `bun.lock` (+77 -0) 📝 `packages/core/src/console.ts` (+8 -0) 📝 `packages/core/src/renderer.ts` (+333 -68) 📝 `packages/core/src/testing/test-renderer.ts` (+15 -4) ➕ `packages/core/src/tests/renderer.stream-mode.test.ts` (+269 -0) ➕ `packages/core/src/tests/renderer.stream-validation.test.ts` (+48 -0) 📝 `packages/core/src/zig.ts` (+16 -4) 📝 `packages/core/src/zig/lib.zig` (+22 -2) 📝 `packages/core/src/zig/renderer.zig` (+311 -137) 📝 `packages/core/src/zig/tests/buffer_test.zig` (+2 -2) 📝 `packages/core/src/zig/tests/renderer_test.zig` (+287 -22) ➕ `packages/ssh/README.md` (+291 -0) ➕ `packages/ssh/examples/counter.ts` (+109 -0) ➕ `packages/ssh/package.json` (+40 -0) ➕ `packages/ssh/src/index.ts` (+24 -0) ➕ `packages/ssh/src/middleware/index.ts` (+172 -0) ➕ `packages/ssh/src/server.ts` (+354 -0) ➕ `packages/ssh/src/session.ts` (+207 -0) ➕ `packages/ssh/src/types.ts` (+65 -0) ➕ `packages/ssh/src/utils/authorized-keys.ts` (+36 -0) _...and 9 more files_ </details> ### 📄 Description # `@opentui/ssh` + stream-mode renderer migration ## Summary - Adds a new `@opentui/ssh` package for running OpenTUI apps over SSH with per-session renderer isolation. - Migrates core non-stdout transport from callback output to `outputMode: "stream"` backed by `NativeSpanFeed` in Zig. - Applies follow-up hardening from review: auth decision guarding, session admission race fixes, authorized_keys option safety, PTY dimension normalization, and renderer stdin teardown correction. ## What This PR Includes ### 1) New package: `@opentui/ssh` - `createSSHServer()` with lifecycle events (`listening`, `session`, `error`, `close`). - `SSHSession` wrapper with stream output wiring, input forwarding, resize handling, and idempotent close. - Built-in middleware: - `logging()` - `publicKey()` (OpenSSH `authorized_keys` parsing/matching) - `allowAll()` (production-ready open server, no warnings) - `devMode()` (development-only, prints security warning) - Host key utilities and docs/examples/tests. ### 2) Core renderer stream architecture - `outputMode: "stream"` in `@opentui/core` with required `onOutput`, `width`, and `height` validation. - NativeSpanFeed/Zig integration for feed-backed output dispatch and backpressure-safe async delivery. - Renderer and test utilities updated for stream-mode creation and validation. ### 3) Reviewer follow-up fixes - Prevents auth double-decision races via guarded accept/reject flow in SSH auth handling. - Enforces `maxSessions` against active + pending session creation to close async admission race. - Normalizes invalid PTY dimensions (e.g. `0x0`) to safe defaults before renderer creation. - Treats `authorized_keys` option-prefixed entries as unsupported and ignores them (with warning) to avoid silently weakening restrictions. - Fixes global `process.stdin.pause()` behavior so stream-only renderer teardown does not pause stdin. ## Documentation and Testing - Expanded `packages/ssh/README.md` with middleware phases/order, auth/session patterns, and compatibility notes. - Added/expanded tests across: - `packages/ssh/tests/*` (server, middleware, authorized-keys, session, integration, host-key) - `packages/core/src/tests/renderer.stream-mode.test.ts` - `packages/core/src/tests/renderer.stream-validation.test.ts` ## Manual Verification (SSH Counter Example) 1. Start the example server: - `cd packages/ssh` - `bun run example` 2. In another terminal, connect with SSH: - `ssh -p 2222 localhost` 3. Validate behavior in one or more sessions: - `+` / `-` updates the counter - terminal resize updates displayed dimensions - `q` cleanly closes the session 4. (If host key changed) clear stale host key entry: - `ssh-keygen -R "[localhost]:2222"` ## Pilotty-Based Verification ### 1) Install Pilotty ```bash npm install -g pilotty ``` Verify with `pilotty --version`. ### 2) Install the Pilotty OpenCode skill ```bash npx skills add msmps/pilotty ``` ### 3) AI-assisted review prompt Use this in OpenCode to run the flow autonomously: ```text use pilotty to test out the ssh impl with the ssh counter example; spawn concurrent sessions and validate ``` Expected validation flow: start server, open concurrent SSH sessions, verify per-session counter isolation, test resize propagation, and quit sessions cleanly. ## Notes - `publicKey()` currently supports key matching only; OpenSSH option prefixes (`from=`, `command=`, `no-pty`, etc.) are intentionally not enforced yet and are ignored. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#1459
No description provided.