Skip to content

feat(tui): add ssh remote runtime transport (with hardening fixes)#4

Draft
kousw wants to merge 8 commits into
mainfrom
codex/implement-tui-remote-runtime-ssh
Draft

feat(tui): add ssh remote runtime transport (with hardening fixes)#4
kousw wants to merge 8 commits into
mainfrom
codex/implement-tui-remote-runtime-ssh

Conversation

@kousw

@kousw kousw commented Feb 15, 2026

Copy link
Copy Markdown
Owner

概要

TUI から runtime を SSH 経由でリモート起動できるようにする変更です。
あわせて、運用時に問題になった SSH 起動まわりの不具合(bootstrap スクリプト、SSH オプション保持、diagnostics 伝搬、--ssh 不正指定時の挙動)を修正しています。

主な変更

1) TUI の SSH リモート実行オプション追加

  • --ssh <user@host>
  • --ssh-port <port>
  • --ssh-identity <path>
  • --ssh-option <key=value>(複数可)
  • --remote-command <cmd>
  • --remote-cwd <path>

上記を runtime 用環境変数へ変換して起動するようにしました。

2) runtime クライアントの SSH 起動実装

  • SSH transport で ssh -T ... sh -lc <script> を使って remote runtime を起動
  • remote bootstrap スクリプト生成を実装
  • bootstrap 進捗を stderr 経由で TUI に表示

3) フォローアップ修正(レビュー反映)

  • if/while を含む bootstrap script を "; " 結合していた問題を修正(改行区切りへ)
  • --ssh-port / --ssh-identity / --ssh-option 使用時も、
    デフォルト SSH 安全オプション(BatchMode / StrictHostKeyChecking / keepalive)を保持
  • --diagnostics を remote runtime にも伝搬(CODELIA_DIAGNOSTICS=1 を remote script で export)
  • --ssh 値欠落時に local へ黙ってフォールバックしないよう修正(SSH モードとして扱い、起動失敗で明示)
  • custom --remote-command の場合は codelia/npm bootstrap を強制しない(条件付き bootstrap)

4) UI clipboard read の capability ガード

  • runtime 側の ui.clipboard.readsupports_clipboard_read でガード
  • 対応テスト追加

ドキュメント

  • crates/tui/AGENTS.md に SSH transport / clipboard read 対応の要点を追記
  • backlog に remote config layering 検討メモを追加(B-030)

テスト

実施済み:

  • cargo test --manifest-path crates/tui/Cargo.toml (最新 139 passed)
  • bun run test
  • bun run typecheck

既知の前提/仕様

  • config / logs / sessions / cache は remote runtime 側に保存されます
  • config 優先は現状 remote project > remote global(local global 混在は未導入)

チェックリスト

  • SSH transport で initialize まで到達
  • custom --remote-command が bootstrap 非依存で実行可能
  • --ssh 不正指定で明示的に失敗
  • diagnostics が remote runtime に反映
  • clipboard read capability ガード動作

@kousw

kousw commented Feb 16, 2026

Copy link
Copy Markdown
Owner Author

@codex
設計方針や実装、不具合やセキュリティリスクの可能性などをレビューして

1 similar comment
@kousw

kousw commented Feb 16, 2026

Copy link
Copy Markdown
Owner Author

@codex
設計方針や実装、不具合やセキュリティリスクの可能性などをレビューして

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

let _ = (run_id, purpose);
let result = match read_clipboard_image_attachment(max_bytes) {

P1 Badge Gate clipboard reads on explicit user consent

The new ui.clipboard.read path reads local clipboard data immediately and returns it to runtime by calling read_clipboard_image_attachment(max_bytes) without any confirmation or permission check. In SSH transport, a remote runtime process that can send JSON-RPC requests can therefore pull local clipboard images silently, which is a privacy/security regression; this flow should require an explicit allow step (or default deny) before accessing clipboard contents.


.unwrap_or_else(|| "bun packages/runtime/src/index.ts".to_string());

P2 Badge Require a resolvable runtime path for SSH default command

In SSH mode, the fallback remote command is bun packages/runtime/src/index.ts, which is a relative path, while CODELIA_RUNTIME_REMOTE_CWD remains optional. If the remote SSH login directory is not the repository root, runtime startup fails because the script path cannot be resolved, so the new SSH transport breaks in common setups unless users discover and set extra flags; enforce CODELIA_RUNTIME_REMOTE_CWD or use an absolute default command.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@kousw kousw marked this pull request as draft February 22, 2026 18:29
@kousw kousw changed the title Codex-generated pull request feat(tui): add ssh remote runtime transport (with hardening fixes) Feb 22, 2026
…tui-remote-runtime-ssh-79a4444e

# Conflicts:
#	crates/tui/src/app/runtime/client.rs
#	crates/tui/src/main.rs
#	docs/specs/backlog.md
@kousw

kousw commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad2ee13a43

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/tui/src/main.rs
app.push_line(LogKind::Status, format!("Clipboard request: {prompt}"));
}
let _ = (run_id, purpose);
let result = match read_clipboard_image_attachment(max_bytes) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require consent before serving clipboard read RPC

handle_clipboard_read_request reads and returns local clipboard image data immediately on any ui.clipboard.read request, without a confirmation/approval step tied to user intent. In SSH mode this lets a compromised or misbehaving remote runtime exfiltrate local clipboard contents just by emitting the RPC, even when the user never initiated paste/attach, so this path needs an explicit consent gate (or equivalent policy check) before read_clipboard_image_attachment is called.

Useful? React with 👍 / 👎.

Comment thread crates/tui/src/main.rs
Comment on lines +392 to +394
let joined = defaults
.into_iter()
.chain(ssh_parts)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve user SSH option precedence over defaults

This builds CODELIA_RUNTIME_SSH_OPTS by placing default -o options before user-supplied --ssh-option values; with OpenSSH, duplicate options are resolved from the first occurrence (you can observe this via ssh -G), so a user-provided override like --ssh-option StrictHostKeyChecking=no is ignored once the default StrictHostKeyChecking=yes is prepended. That makes the new CLI flag unexpectedly ineffective for conflicting keys and can block valid connection setups.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant