Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions docs/user/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,20 +149,54 @@ devbase はホストマシンの認証情報を自動収集し、コンテナ内
| `DEVBASE_OPEN_EDITOR` | 真(`1`/`true`/`yes`/`on`)で `up` 後にエディタを開く(既定: OFF) |
| `DEVBASE_EDITOR` | 起動コマンド(既定: `code`)。`cursor` / `code-insiders` 等も可 |
| `DEVBASE_OPEN_INDEX` | scale 時に開く dev インスタンス番号(既定: `1`) |
| `DEVBASE_EDITOR_SSH_HOST` | Remote-SSH 跨ホスト構成での ssh-remote ホスト名(例 `mac2`)。**通常は `~/.vscode-server` から自動検出**され不要。検出が外れる場合のみ明示。下記「跨ホスト」参照 |
| `DEVBASE_EDITOR_DOCKER_CONTEXT` | 跨ホスト時に ssh 先で使う docker context(既定: ホストの `docker context show`) |
| `DEVBASE_OPEN_TERMINAL` | 真で `up` 後に folderOpen ターミナル用 `.vscode/tasks.json` を配置(**既定: ON**) |

都度の上書きは CLI フラグで行います: `devbase up --open` / `devbase up --no-open` / `devbase up --open-index N`(env より優先)。
都度の上書きは CLI フラグで行います: `devbase up --open` / `--no-open` / `--open-index N` / `--open-terminal` / `--no-open-terminal`(env より優先)。

### 起動時に統合ターミナルを自動表示(`DEVBASE_OPEN_TERMINAL`)

`up` 時に、開く dev コンテナのワークスペース(`/work/$GIT_REPO`)へ folderOpen タスク(`.vscode/tasks.json`)を `docker exec` で配置します(既存があれば変更しません)。VS Code はフォルダを開いた時にこのタスクで統合ターミナルを前面表示します。

VS Code 公式には「起動時にターミナルを開く」専用設定が無く、folderOpen タスクが唯一の方法です。なお自動実行には次の 2 つの **VS Code クライアント側ユーザー設定**が関わり、devbase からは制御できません(いずれも application/user スコープ専用):

- **Workspace Trust**: 信頼していないフォルダではタスクは自動実行されません(初回は「フォルダを信頼」が必要)。
- **`task.allowAutomaticTasks`**: 既定 `off` ではフォルダごとに 1 回「自動タスクを許可」を尋ねます。`on` にするとプロンプト無しで実行されます。

→ 実際は「初回のみ信頼(+許可)クリック、以降は自動でターミナルが開く」挙動になります。無効化は `DEVBASE_OPEN_TERMINAL=0` または `devbase up --no-open-terminal`。

### 実行コンテキスト別の挙動

| コンテキスト | 挙動 |
|------|------|
| ローカル端末(Mac/Linux) | ローカル VS Code が開く |
| WSL 端末 | Windows 側 VS Code が開く(`code` ラッパ経由) |
| VS Code の Remote-SSH 統合ターミナル | **クライアント側(手元)の VS Code** が開く(`code` シムが委譲) |
| VS Code の Remote-SSH 統合ターミナル(同一ホストの Docker) | **クライアント側(手元)の VS Code** が開く(`code` シムが委譲) |
| VS Code の Remote-SSH 統合ターミナル(**跨ホスト**: ssh 先の Docker にコンテナ) | `DEVBASE_EDITOR_SSH_HOST` 設定時にネスト URI で開く(下記「跨ホスト」参照) |
| 手元から素の SSH(VS Code 外)で接続中 | クライアントへ自動で開く公式手段が無いため、手元で実行する `code --folder-uri ...` コマンドを提示 |
| CI / 非対話(非 TTY) / `code` 不在 | 理由を表示してスキップ(`up` 自体は成功) |

> SSH 越しに「手元の VS Code」を自動で開きたい場合は、手元の VS Code から **Remote-SSH で接続した統合ターミナル内**で `devbase up` を実行してください。そのターミナルの `code` はクライアント側 VS Code に委譲するため、リモートホスト上のコンテナへ接続した窓が手元に開きます。
#### 跨ホスト(Windows VS Code → Remote-SSH → Mac のコンテナ)

手元(例 Windows)の VS Code から Remote-SSH で別ホスト(例 Mac)へ入り、その統合ターミナルで `devbase up` を実行する構成では、コンテナは **ssh 先(Mac)の Docker** 上にあります。このとき `code` の開く要求はクライアント(Windows)へ委譲されるため、フラットな attach URI のままだと **クライアント側の Docker** を見に行きコンテナが見つかりません(「コンテナーにアタッチできません。すでに存在しません」)。

これを解決するには、ネスト URI `vscode-remote://attached-container+<hex>@ssh-remote+<host>/work/...` を使い、docker ルックアップを ssh 先(コンテナのある Mac)で行わせます。`<host>` は **手元 `~/.ssh/config` の `Host` 別名**(例 `mac2`)で、これは「今の VS Code 接続の authority ラベル」と完全一致する必要があります(ネスト attach は新規 ssh 接続を張らず既存接続を再利用するため。IP や `user@IP` は "Parent authority found without ExecServer" で不可)。

このラベルは VS Code が ssh 先の端末 env に渡さない(`SSH_CONNECTION` は IP のみ)ものの、**devbase は ssh 先(Mac)の VS Code 系サーバーディレクトリ(`~/.vscode-server` / `~/.cursor-server` / `~/.vscode-server-insiders` 等)の File History から自動検出**します(`DEVBASE_EDITOR` で cursor 等を使う場合も横断)。よって**通常は設定不要**です。docker context は `docker context show` から自動取得します。

自動検出が外れる場合(複数 ssh-remote ホストを使い分けている等)のみ明示します:

```sh
# $DEVBASE_ROOT/env など(全プロジェクト共通にしたい場合)
DEVBASE_EDITOR_SSH_HOST=mac2
# 必要なら docker context も明示
# DEVBASE_EDITOR_DOCKER_CONTEXT=desktop-linux
```

解決順は **`DEVBASE_EDITOR_SSH_HOST` 明示 → `~/.vscode-server` 自動検出 → フラット URI**。

> 同一ホスト構成(手元 Mac/Linux で直接、または ssh 先の Docker にコンテナが無い場合)では ssh-remote ホストは付かず、従来どおりフラット URI で開きます。

## ソースファイル変更検出

Expand Down
58 changes: 44 additions & 14 deletions issues/PLAN31_3_up-open-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,44 @@ vscode-remote://attached-container+<hex>/work/$GIT_REPO
`<hex>` は **`{"containerName":"/<実コンテナ名>"}` を UTF-8 hex 化**した文字列。
(単純な名前の hex ではない点に注意。Docker 内部のコンテナ名は先頭 `/` 付き。)

### 2.3 ネスト authority は公式未サポート
### 2.3 ネスト authority(**実機で動作することを確認・当初想定を訂正**)

`ssh-remote+<host>` と `attached-container+...` を 1 本の URI に合成する記法は
**存在しない**(microsoft/vscode#242489 は *Closed as not planned*)。
→ 「リモートホスト上のコンテナ」を単発 `code` で直接指定する手段は無い。
> ⚠️ 訂正(2026-06-13 実装時の実機検証)。当初は「合成記法は存在しない
> (microsoft/vscode#242489 *not planned*)」と記載していたが、**誤り**だった。

`attached-container+<hex>@ssh-remote+<host>` という**ネスト authority は実際に
サポートされており動作する**(VS Code 1.124.2 / Dev Containers 0.459.1 で確認)。
正常動作中の窓の resource URI を採取したところ:

```
vscode-remote://attached-container+<hex>@ssh-remote+mac2/work/...
hex = {"containerName":"/<name>","settings":{"context":"desktop-linux"}}
```

`@ssh-remote+<host>` を付けると docker ルックアップが **ssh 先(コンテナのある
ホスト)** で行われるため、跨ホスト(手元 Windows VS Code → ssh → Mac のコンテナ)
でも単発 `code --folder-uri` で直接アタッチできる。`settings.context` は ssh 先で
使う docker context を指定する。

### 2.4 結論(実行コンテキスト別マトリクス)

| コンテキスト | 自動オープン | 機構 / 根拠 |
|---|---|---|
| Mac/Linux ローカル端末 | ✓ | ローカル `code` が attach URI を解決 |
| WSL 端末 | ✓ (Windows VS Code) | `code` ラッパ→`code.exe`、Docker Desktop のコンテナへ attach |
| VS Code **Remote-SSH 統合端末**(リモート=Mac) | ✓ (クライアント側) | `code` シム + `VSCODE_IPC_HOOK_CLI`。シムは既にクライアントへ接続済みなのでネスト URI 不要で attached-container を解決し、**クライアント(Windows)に窓が開く** |
| plain SSH(WSL→ssh→Mac 等、VS Code 外) | ✗ → コマンド表示 | IPC hook 無し。公式にクライアントへ push 不可(§2.3)。手元で叩く `code` コマンドを提示するのが上限 |
| VS Code **Remote-SSH 統合端末**(リモート=Mac・**同一ホストの Docker**) | ✓ (クライアント側) | `code` シムが委譲。同一ホストの Docker にコンテナがある場合はフラット URI で解決 |
| VS Code **Remote-SSH 統合端末**(**跨ホスト**: ssh 先 Mac の Docker にコンテナ) | ✓ (host 自動検出) | フラット URI だとクライアント(Windows)の Docker を見て失敗。**ネスト URI `@ssh-remote+<host>`(§2.3)で ssh 先の Docker を解決**。`<host>` は **ssh 先 `~/.vscode-server` の File History から自動検出**(`DEVBASE_EDITOR_SSH_HOST` で上書き可)。IP/`user@IP` は既存 ExecServer 不一致で不可、別名一致が必須 |
| plain SSH(WSL→ssh→Mac 等、VS Code 外) | ✗ → コマンド表示 | IPC hook 無し。手元で叩く `code` コマンドを提示するのが上限 |
| CI / 非TTY / `code` 不在 | ✗ → info スキップ | エディタ起動の前提を満たさない |

→ ユーザ理想チェーンは **「手元 VS Code で Remote-SSH→Mac に入った統合ターミナルで
`devbase up`」の場合に自動成立**。plain ssh の場合は正直にコマンド提示で degrade する。
→ 跨ホスト(手元 Windows VS Code → Remote-SSH→Mac で `devbase up`、コンテナは Mac の
Docker)が最頻ユースケース。ssh ホスト名(クライアント `~/.ssh/config` の Host 別名)は
VS Code が ssh 先端末 env に渡さない(`SSH_CONNECTION` は IP のみ)が、**ssh 先 Mac の
`~/.vscode-server` の File History(resource URI の `ssh-remote%2B<host>`)から自動検出**
できるため**通常は設定不要で自動成立**する。検出が外れる場合のみ `DEVBASE_EDITOR_SSH_HOST`
で上書き。IP/`user@IP` は「ネスト attach は新規 ssh 接続を張らず既存 ExecServer の authority
と一致が必須」のため不可(実機: "Parent authority found without ExecServer")。
plain ssh はコマンド提示で degrade。

## 3. 既存コード調査結果

Expand Down Expand Up @@ -156,12 +176,22 @@ env 解釈は既存 `_parse_env_assignment`(`container.py:121`)に合わせ
`--no-open`/`DEVBASE_OPEN_EDITOR=0` で呼ばれないこと
- 既存 706 passed を維持

## 8. リスク・未確定

- **plain SSH では自動オープン不可**(§2.3 公式未サポート)。コマンド提示で degrade。
この制約は README に明記する
- VS Code Remote-SSH 統合端末でのクライアント側 attach は実機検証が必要
(`/ndf:investigation-rules`: 実機未検証の挙動は「推定」と明示)
## 8. リスク・未確定(実機検証で更新)

- ~~VS Code Remote-SSH 統合端末でのクライアント側 attach は実機検証が必要~~
→ **検証済み(2026-06-13)**。跨ホストではフラット URI だと失敗し、ネスト URI
`@ssh-remote+<host>` + `settings.context` で成立することを確認(§2.3/§2.4 を訂正)。
- ssh ホスト名は env には来ないが **`~/.vscode-server` の File History から自動検出**する
ようにした(実機: ホストは `ssh-remote%2Bmac2` の 1 種のみで一意に取れた)。検出は VS Code
内部データ依存のヒューリスティック(multi-host / バージョン差で外し得る)で、最新 mtime の
entries.json を優先し、外れる場合は `DEVBASE_EDITOR_SSH_HOST` 明示・最終的にフラット URI へ degrade。
- IP / `user@IP` でのネスト attach は不可(既存 Remote-SSH 接続=ExecServer の authority ラベルと
完全一致が必須。新規 ssh 接続は張らない)。実機で "Parent authority found without ExecServer" を確認。
- **plain SSH(VS Code 外)では自動オープン不可**。コマンド提示で degrade(変更なし)。
- 統合ターミナル自動表示は `.vscode/tasks.json`(folderOpen) 配置で実現。VS Code 公式に
起動時ターミナル設定は無く(`hideOnStartup` は復元セッションの表示制御のみ)folderOpen
が唯一。自動実行は Workspace Trust と `task.allowAutomaticTasks`(共に user スコープ専用・
devbase 制御外)に依存し、初回のみ承認クリックが要る。
- `code` ラッパの非ブロッキング起動が `up` プロセス終了をブロックしないこと確認

## 9. 参考(一次情報)
Expand Down
7 changes: 7 additions & 0 deletions lib/devbase/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ def _add_open_args(parser):
parser.add_argument('--open-index', dest='open_index', type=int, default=None,
metavar='N',
help='Container index to open (default: 1)')
parser.add_argument('--open-terminal', dest='open_terminal', action='store_true',
default=None,
help='Place .vscode/tasks.json so the integrated terminal '
'auto-opens on folder open (overrides DEVBASE_OPEN_TERMINAL)')
parser.add_argument('--no-open-terminal', dest='open_terminal', action='store_false',
help='Do not place the folderOpen terminal tasks.json '
'(overrides DEVBASE_OPEN_TERMINAL)')
return parser


Expand Down
Loading
Loading