sync: update from private repo (edc775f2)
CI / build-and-test (push) Has been cancelled

This commit is contained in:
oss-sync
2026-07-06 01:04:12 +00:00
parent 747377bef9
commit b1292e34b2
322 changed files with 28001 additions and 4686 deletions
+31 -18
View File
@@ -1,10 +1,10 @@
# SSH Console Tools (SshConsoleEnsure / SshConsoleSend / SshConsoleSnapshot)
AI と人間が共有する SSH PTY セッションを操作する 3 ツール。1 タスクに 1 PTY セッションが対応し、`cd` / 環境変数 / foreground プロセス job をまたいで維持される。長時間の対話作業 / TUI (vim, top, less, tmux) / 複数ラウンドの調査向け。
AI と人間が共有する SSH PTY セッションを操作する 3 ツール。**1 タスクは接続ごとに 1 つ、複数の PTY セッションを同時に持てる**(例: 2 台のサーバーへ同時接続して並行作業)。各セッション内では `cd` / 環境変数 / foreground プロセス job をまたいで維持される。長時間の対話作業 / TUI (vim, top, less, tmux) / 複数ラウンドの調査向け。
単発コマンドだけなら **`SshExec`** (ssh-ops piece) のほうが軽い。本ツール群は対話的シェル + AI が画面を見続ける用途に最適化されている。
> **ユーザーが先にセッションを開いている場合がある**: タスク詳細の **Console タブ**から、ユーザーが接続を選んで自分でセッションを起動できる。その場合 `SshConsoleEnsure` は既存セッションをそのまま再利用する (`connection_id` を省略すれば active session が採用される)。「まず console を開く」操作を AI 側でやり直す必要はない
> **ユーザーが先にセッションを開いている場合がある**: タスク詳細の **Console タブ**から、ユーザーがタブを追加して自分でセッションを起動できる(複数タブを同時に開ける。→[SSH 接続](../../ui/src/content/help/14-ssh.md))。その場合 `SshConsoleEnsure` は既存セッションをそのまま再利用する。「まず console を開く」操作を AI 側でやり直す必要はない。ただし**タスクに複数セッションが同時に開いている場合、`connection_id` を省略して自動採用されるのは「直前にこのツール群で操作した接続 (current-connection pointer)」か「セッションが 1 つしかない」ときだけ**。2 つ以上開いていて pointer も無い状態で省略すると `ambiguous` エラーになる(詳細は後述)
## 典型的な flow (まずこれを真似る)
@@ -40,10 +40,10 @@ SshConsoleSnapshot({
| Param | Required | Description |
|---|---|---|
| `connection_id` | yes | UUID。piece の `allowed_ssh_connections` に含まれている必要がある。**label / hostname / 思い出した文字列で代用してはいけない** — 必ず `SshListConnections``id` を渡すこと |
| `connection_id` | yes | UUID。このワークスペースに登録された接続である必要がある。**label / hostname / 思い出した文字列で代用してはいけない** — 必ず `SshListConnections``id` を渡すこと |
| `cols` | no | 初回 open 時のターミナル幅。default `ssh.console.default_cols` (120) |
| `rows` | no | 初回 open 時のターミナル高さ。default `ssh.console.default_rows` (32) |
| `force_replace` | no | bool。default `false`既存 session が**別の** `connection_id`ある場合の挙動を制御 (下記参照) |
| `force_replace` | no | bool。default `false`**同じ** `connection_id`既存セッションがあるとき、それを閉じて開き直すかどうかを制御 (下記参照)。**別の** `connection_id` を渡した場合は `force_replace` に関係なく新規セッションが追加される |
Return:
```json
@@ -52,16 +52,28 @@ Return:
`reused: true` なら過去ターンから引き継いだ既存セッション (cd 等の state あり)。`false` なら今回新規 open。
### connection_id mismatch の挙動 (重要)
### 複数セッション: 別の接続を開くと「追加」される (重要)
同じ task で**別の** `connection_id` を渡した場合:
1 つのタスクは接続ごとに 1 つ、複数のセッションを同時に持てる。`SshConsoleEnsure` に**別の** `connection_id` を渡しても既存セッションは閉じられない — 単に新しい接続へのセッションが追加で開くだけ (add-not-replace)。**同じ** `connection_id` を渡した場合だけ「再利用か force_replace での再起動か」の分岐になる:
- `force_replace: false` (default) → エラー返却。レスポンスに **既存セッションの connection_id が含まれる** ので、それをそのまま使うか、本当に切り替えたければ次の呼び出しで `force_replace: true` を渡す
- `force_replace: true`旧セッションは `connection_change` 理由で閉じられ、新セッションが開く (旧 shell の state は失われる)
- 同じ `connection_id` + `force_replace: false` (default) → 既存セッションを再利用 (`alreadyActive: true`, `reused: true`)
- 同じ `connection_id` + `force_replace: true`**その接続のセッションだけ** `connection_change` 理由で閉じて開き直す (他の接続のセッションには影響しない。旧 shell の state は失われる)
**典型的なバグパターン**: ジョブをまたいで動作するエージェントが `connection_id` を覚えていなくて、
LLM の hallucination で適当な UUID を生成 → mismatch reject される、というケース。エラーメッセージの中に
正しい `connection_id` が出ているのでそれを使うか、Send/Snapshot で `connection_id` を省略する。
タスクあたりの上限 (既定 5、上限到達時は `task_session_cap`) やユーザー単位の上限 (`user_session_cap`、設定次第) に達すると新規オープンは拒否される。人間側も Console タブの「+ 接続」ボタンで同じように接続を追加でき、タブの ✕ で不要なセッションを閉じられる (→[SSH 接続](../../ui/src/content/help/14-ssh.md))。
### `connection_id` を省略できるのは 1 セッションのときだけ
`SshConsoleSend` / `SshConsoleRun` / `SshConsoleSnapshot``connection_id` を省略できるが、解決順は次のとおり:
1. `connection_id` を明示 → その接続のセッションを厳密に使う (無ければ `not found` エラー。勝手に新規 open はしない)
2. 省略時は、このツール群で直前に操作した接続 (current-connection pointer) が生きていればそれ
3. pointer も無く、タスクのセッションが**ちょうど 1 つ**ならそれを自動採用
4. タスクに**複数**セッションが同時に開いていて pointer も無い場合 → `ambiguous` エラー (`connection_id required (multiple sessions open: ...)`)。**この場合は `connection_id` を明示しないと動かない**
5. セッションが 1 つも無い場合 → `SshConsoleEnsure` で開くよう促すエラー
**複数接続で並行作業するときの鉄則**: 2 つ目以降のセッションを触るときは常に `connection_id` を明示する。省略に頼ってよいのは、セッションが 1 つしかないタスクか、直前にそのセッションを操作した直後だけ。
**典型的なバグパターン**: ジョブをまたいで動作するエージェントが `connection_id` を覚えておらず、複数セッションが開いている状態で省略 → `ambiguous` で reject される、というケース。エラーメッセージに出ている `connection_id` の一覧 (または `SshListConnections`) から正しいものを選んで明示する。
## SshConsoleSend
@@ -77,7 +89,7 @@ raw のまま送りたい (改行を付けない) ケース:
| Param | Required | Description |
|---|---|---|
| `connection_id` | no | UUID。**省略時はこの task の active session を自動採用 (推奨)**。明示する場合は active session の id と一致する必要があり、不一致なら reject (active id が surface される) |
| `connection_id` | no | UUID。**タスクにセッションが 1 つだけ、または直前にこのツール群で操作した接続 (pointer) がある場合は省略可**。複数セッションが開いていて pointer も無いと `ambiguous` エラー (下記「`connection_id` を省略できるのは 1 セッションのときだけ」参照) |
| `input` | yes | raw 文字列。LF / CRLF / control 文字 (`\x03` Ctrl-C, `\x04` Ctrl-D, `\x1b` Esc, `\t` Tab) を透過 |
| `wait_ms` | no | 送信後の screen_after 取得までの待ち時間 (default 500ms, max 5000ms) |
@@ -113,7 +125,7 @@ Return:
| Param | Required | Description |
|---|---|---|
| `connection_id` | no | UUID。**省略時はこの task の active session を自動採用 (推奨)**。明示する場合は active session の id と一致する必要があり、不一致なら reject |
| `connection_id` | no | UUID。**タスクにセッションが 1 つだけ、または直前にこのツール群で操作した接続 (pointer) がある場合は省略可**。複数セッションが開いていて pointer も無いと `ambiguous` エラー (上記「`connection_id` を省略できるのは 1 セッションのときだけ」参照) |
| `kind` | no | `screen` (デフォルト) — 現在の表示画面 / `scrollback` — それ以前を含む過去の出力 |
| `max_bytes` | no | scrollback の上限 (default 8192, max 65536)。tail から `max_bytes` バイト返す |
@@ -138,7 +150,7 @@ text は ANSI escape strip 済み (色 / cursor 移動シーケンスを除去)
| Param | Required | Description |
|---|---|---|
| `command` | yes | 実行するシェルコマンド |
| `connection_id` | no | UUID。**省略時はこの task の active session を自動採用 (推奨)** |
| `connection_id` | no | UUID。**タスクにセッションが 1 つだけ、または直前にこのツール群で操作した接続 (pointer) がある場合は省略可**。複数セッションが開いていて pointer も無いと `ambiguous` エラー |
| `timeout_ms` | no | タイムアウト (ms)。デフォルト 120000 (2分)、最大 600000 (10分)。タイムアウト時もコマンドは kill されない |
| `idle_ms` | no | 出力が `idle_ms` ms 途切れたら早期終了と判定する。0=無効 (デフォルト) |
@@ -176,12 +188,13 @@ Return:
| `host_key_*` | UI (Settings → User Folder → SSH Connections) で TOFU 検証してから再試行 |
| `command_rejected (builtin_deny / custom_deny)` | deny-list で reject。admin に許可パターン追加を相談 (ローカルで回避してはいけない) |
| `idle_timeout` / `duration_cap` | 古いセッションが閉じた。`SshConsoleEnsure` を再度呼んで開け直す |
| `connection_change` | 同 task で `force_replace: true` 付き Ensure が呼ばれた → 古いセッションが閉じた |
| `this task already has an active session on connection X (...)` | エラー文の中の **X が正しい id**。X を `connection_id` に使うか、Send/Snapshot で省略する。本当に切り替えたければ `force_replace: true` |
| `this task has an active session on connection X, not Y` | Send/Snapshot 側で id mismatch。X を使う or 省略する |
| `connection_change` | **同じ** `connection_id` `force_replace: true` 付き Ensure が呼ばれた → その接続のセッションだけ閉じて開き直した (別の接続を開いても発生しない) |
| `connection_id required (multiple sessions open: ...)` (ambiguous) | Send/Run/Snapshot で `connection_id` を省略したが、このタスクに複数セッションが同時に開いていて pointer も無い。エラー文中の一覧から狙った `connection_id` を明示する |
| `this task already has the maximum of N open console sessions` (`task_session_cap`) | タスクあたりのセッション上限 (既定 5) に到達。使っていない接続を `SshConsoleSend/Run` の完了を確認してからユーザーに Console タブでタブを閉じてもらうか、既存接続を使い回す |
| `you already have the maximum of N open console sessions` (`user_session_cap`) | ユーザー単位の上限 (設定されている場合) に到達。他タスクのセッションを閉じるまで新規オープンは拒否される |
| `maintenance` | admin の対応を待つ。`complete({status: 'needs_user_input', missing_info: 'SSH maintenance window'})` で停止 |
| `not initialised` | `ssh.enabled` または `ssh.console.enabled` が false / `MCP_ENCRYPTION_KEY` 未設定。admin に依頼 |
| `does not declare allowed_ssh_connections` | piece YAML の movement に `allowed_ssh_connections: ['*']` 等を追加する必要あり |
| `not registered to this workspace` | 対象接続がこのワークスペースに未登録。Settings → SSH で登録し、Settings → Tools で `ssh` カテゴリを有効化する |
## deny-list の限界