Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
915cb9d
feat(web-shell): restore remote workspace add flow
yiliang114 Sep 17, 2026
3ccc4e8
fix(web-shell): restore workspace location choice
yiliang114 Sep 17, 2026
e666df9
feat(web-shell): reuse remote connections for workspaces
yiliang114 Sep 17, 2026
67337b7
feat(web-shell): mark remote workspaces
yiliang114 Sep 17, 2026
11d6bac
fix(web-shell): keep the resumed add flow copy neutral
yiliang114 Sep 17, 2026
b910bfb
test(web-shell): disambiguate the extension manager's Add button
yiliang114 Sep 17, 2026
74fb08e
fix(web-shell): guard the resumed add step outside a document
yiliang114 Sep 17, 2026
b045a7d
test(web-shell): cover the remote workspace add flow end to end
yiliang114 Sep 17, 2026
2cde1e4
Merge remote-tracking branch 'origin/main' into codex/11475-remote-fo…
yiliang114 Sep 17, 2026
1773d98
refactor(web-shell): simplify resumed workspace add state
yiliang114 Sep 17, 2026
2364d15
fix(web-shell): keep the workspace add flow in place and cut its dupl…
yiliang114 Sep 17, 2026
c6b43d6
Merge branch 'main' into codex/11475-remote-folder-entry
yiliang114 Sep 18, 2026
a491d80
revert(web-shell): drop the folder-browser breadcrumbs
yiliang114 Sep 18, 2026
6769641
Merge branch 'main' into codex/11475-remote-folder-entry
yiliang114 Sep 18, 2026
8ccef6c
feat(web-shell): add connected folder sources
yiliang114 Sep 18, 2026
6ab462c
Merge remote-tracking branch 'origin/main' into codex/11475-remote-fo…
yiliang114 Sep 18, 2026
1b5c3d6
feat(web-shell): complete remote connection setup
yiliang114 Sep 18, 2026
0696655
fix(web-shell): drop a return location an abandoned hand-over left be…
yiliang114 Sep 19, 2026
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
14 changes: 11 additions & 3 deletions docs/design/remote-web-shell-daemon.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Web Shell already sends workspace, session, file, SSE, and WebSocket requests th

- Let a Web Shell URL select one remote daemon with `?daemon=<origin>`.
- Let users enter or replace the daemon address and optional bearer token in Web Shell.
- Remember successfully verified remote computers so workspace creation can reuse them.
- Keep the remote daemon as the sole owner of workspaces, sessions, files, terminals, and execution.
- Preserve reconnect and session navigation on the selected daemon.
- Keep bearer credentials isolated by daemon origin.
Expand All @@ -30,7 +31,9 @@ The standalone Web Shell reads the `daemon` query parameter and passes that orig

The pre-connection gate always exposes a daemon address and optional token form, including when the URL contains an invalid target. Once connected, the existing Daemon Status overview shows the current target and connection state and provides the same switch controls. Switching performs a full page navigation, clears the selected session, workspace, and context from the URL, and creates a fresh SDK client for the new daemon. Reconnecting to the target already in use reloads in place instead, so the selected session, workspace, and context survive it exactly as they survive a plain refresh. It does not probe or fall back to another runtime.

The existing sidebar remains the workspace and session management UI. Workspace registration uses typed absolute paths and daemon-provided directory suggestions; native folder selection remains hidden for remote daemons. Session discovery, transcript loading, file references, terminal traffic, and execution require no parallel remote-specific implementations because they already use the selected SDK client.
The existing sidebar remains the workspace and session management UI. Settings includes a **Connections** category where remote computers are added, reviewed, forgotten, or selected. Adding a cross-origin computer temporarily navigates to that daemon so the existing connection gate can verify its capabilities and credential without weakening CSP; success or cancellation returns to the source shell with **Settings > Connections** reopened. A successful remote connection records only its validated origin in a browser-local connection catalog; bearer tokens remain tab-scoped, and forgetting a connection removes its tab-scoped credential too. The normal **Add workspace** action opens the directory browser directly. Its **Folder source** selector lists this computer and the connected remote computers, matching the source-selection pattern used by Codex project creation without adding a separate Local/Remote step. Selecting a computer this tab is not already connected to navigates to that daemon and resumes the same directory browser; selecting the daemon already in use keeps it open in place without reloading the shell. The browser uses daemon-provided directory suggestions, supports parent-directory navigation and manual absolute paths, and registers the selected directory through the existing workspace mutation. Native folder selection remains hidden for remote daemons. A cross-origin daemon is named once as a host chip beside the sidebar's Project heading, and each remote workspace row uses a folder icon with a small blue globe so local and remote folders remain visually distinct. Session discovery, transcript loading, file references, terminal traffic, and execution require no parallel remote-specific implementations because they already use the selected SDK client.

The add operation remains a one-shot flow. The source URL is kept only in the current tab while navigation is in progress. Cancel returns to that URL, changing **Folder source** continues the same browser on the selected computer, and a successful registration stays on the selected daemon and clears the continuation state. The connection catalog stores origins only; it does not cache remote workspaces or aggregate projects from multiple daemons. Ordinary daemon switches do not resume the flow.

Bearer tokens remain in per-tab `sessionStorage`, but are keyed by daemon origin. The legacy unqualified key is used only for same-origin connections. Selecting a remote daemon never reuses a token stored for the page's own daemon or another remote daemon.

Expand All @@ -40,9 +43,9 @@ Disconnecting or closing the browser only disposes the client connection. It doe

## Failure and Security Boundaries

- An unfamiliar `?daemon=` target waits for explicit confirmation before any probe. Only the last confirmed origin in the current tab is remembered; there is no persistent host or project catalog.
- An unfamiliar `?daemon=` target waits for explicit confirmation before any probe. A target is added to the persistent connection catalog only after its capabilities probe succeeds.
- The browser-local file bridge is offered only when the connected daemon is the page's own origin, in the standalone and embedded shells alike: a cross-origin target never mounts it, so a client directory cannot be handed to a remote daemon whose panel copy promises files stay on the computer. Remote workspace files remain available through the selected daemon. The same-origin SSH-tunnel deployment keeps its behavior and origin-scoped grants.
- Switching hosts happens only through the connection gate or Daemon Status, before using the existing add-workspace form. There is no cross-host add continuation or duplicate directory browser.
- The remote-add continuation is explicit, tab-scoped, and one-shot. It reuses the origin-only connection catalog but does not persist a project catalog, aggregate workspaces from multiple daemons, or alter ordinary daemon switching.

- Invalid remote addresses are reported by the connection gate and are not contacted.
- Authentication, Origin, Host, and network failures stay explicit in the existing connection gate; there is no fallback from a valid selected remote daemon to a local runtime.
Expand All @@ -54,13 +57,18 @@ Disconnecting or closing the browser only disposes the client connection. It doe

- Unit-test address validation, token isolation, query preservation, and CSP sources.
- Start local Web Shell and a token-configured daemon on a remote host, then connect by entering the address and token in the browser.
- Add a remote computer in **Settings > Connections**, verify that the flow returns to the same settings category, choose the normal **Add workspace** action, select that computer from **Folder source**, browse its directories, register one, and verify that the new workspace becomes active on that daemon.
- Verify that changing **Folder source** keeps the directory browser open, Cancel returns to the exact source page without a token or continuation marker, and an ordinary daemon switch never opens the directory browser.
- Verify the local page lists the remote workspace, obtains remote directory suggestions, lists and references remote files, and loads a remote session transcript.
- Verify the target and selected session remain selected after refresh without re-entering the token.

## Acceptance Criteria

- A Web Shell page can connect directly to a configured remote daemon origin.
- An invalid or unavailable target can be replaced from the connection gate, and a connected target can be switched from Daemon Status.
- The standalone Settings panel exposes a Connections category for managing verified remote computer origins.
- The sidebar exposes one Add workspace action that opens the directory browser directly; its Folder source selector can switch between this computer and a verified remote connection, continue after navigation, browse daemon directories, and register the selected absolute path.
- Cancel returns to the source shell predictably, while changing Folder source keeps the browser flow active and a completed add stays on the selected daemon; the persistent catalog contains connection origins, never remote project data or bearer tokens.
- Workspace and session discovery and file/terminal operations use the selected daemon through the existing SDK.
- Credentials are never reused across daemon origins.
- Remote selection survives navigation and refresh.
Expand Down
14 changes: 11 additions & 3 deletions docs/design/remote-web-shell-daemon.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Web Shell 已经通过同一个 daemon `baseUrl` 发送 workspace、session、

- 允许 Web Shell URL 通过 `?daemon=<origin>` 选择一个远程 daemon。
- 允许用户在 Web Shell 中填写或更换 daemon 地址和可选的 bearer token。
- 记住验证成功的远程计算机,让后续添加 workspace 时可以复用。
- 远程 daemon 继续作为 workspace、session、文件、终端和执行的唯一所有者。
- 在所选 daemon 上保持重连和 session 导航。
- 按 daemon origin 隔离 bearer 凭据。
Expand All @@ -30,7 +31,9 @@ Web Shell 已经通过同一个 daemon `baseUrl` 发送 workspace、session、

连接前页面始终提供 daemon 地址和可选 token 表单,包括 URL 中目标无效的情况。连接成功后,现有 Daemon 状态概览会显示当前目标和连接状态,并提供相同的切换控件。切换目标时执行完整页面导航,清除 URL 中已选的 session、workspace 和 context,并为新 daemon 创建全新的 SDK client。重连到当前正在使用的目标时改为原地重新加载,因此已选的 session、workspace 和 context 会像普通刷新一样原样保留。此过程不会探测或回退到其他 runtime。

现有侧边栏继续作为 workspace 和 session 管理界面。workspace 注册使用手工输入的绝对路径和 daemon 返回的目录建议;连接远程 daemon 时继续隐藏原生目录选择器。session 发现、对话记录加载、文件引用、终端流量和执行不需要再实现一套远程专用逻辑,因为它们已经统一使用所选 SDK client。
现有侧边栏继续作为 workspace 和 session 管理界面。设置中新增“连接”分类,用于添加、查看、移除或选择远程计算机。添加跨 origin 计算机时会临时导航到对应 daemon,复用现有连接页验证 capabilities 和凭据而不放宽 CSP;验证成功或取消后都会返回来源 shell,并重新打开“设置 > 连接”。远程连接验证成功后,仅把其 origin 记录到浏览器本地的连接目录中,bearer token 仍限定在当前标签页;移除连接时也会同时清理该 origin 在当前标签页中的凭据。普通的“添加工作区”操作直接打开目录浏览器;浏览器顶部的“目录来源”可以选择这台计算机或一台已连接的远程计算机,参考 Codex 创建项目时的来源选择方式,不再增加独立的“本地/远程”步骤。选择当前标签页尚未连接的计算机时导航到对应 daemon,再续接同一个目录浏览流程;选择当前已连接的 daemon 则保持原地打开,不重新加载 shell。目录浏览使用 daemon 返回的目录建议,支持进入上级目录和手工填写绝对路径,并通过现有 workspace mutation 注册所选目录;连接远程 daemon 时继续隐藏原生目录选择器。跨 origin daemon 会在侧边栏“项目”标题旁显示主机名 chip;每个远程 workspace 行还会使用带蓝色小地球的文件夹图标,让本地和远程目录在视觉上保持可区分。session 发现、对话记录加载、文件引用、终端流量和执行不需要再实现一套远程专用逻辑,因为它们已经统一使用所选 SDK client。

添加操作仍是一次性流程。导航期间只在当前标签页保存来源 URL;取消会返回该 URL,切换“目录来源”会在所选计算机上续接同一个目录浏览器,注册成功后留在所选 daemon 并清除续接状态。连接目录只保存 origin,不缓存远程 workspace,也不聚合多个 daemon 的项目。普通 daemon 切换不会续接该流程。

Bearer token 仍保存在当前标签页的 `sessionStorage` 中,但存储键按 daemon origin 区分。旧的无限定存储键只用于同源连接。选择远程 daemon 时绝不会复用页面自身 daemon 或另一个远程 daemon 的 token。

Expand All @@ -40,9 +43,9 @@ Bearer token 仍保存在当前标签页的 `sessionStorage` 中,但存储键

## 失败与安全边界

- 不熟悉的 `?daemon=` 目标必须先明确确认,再发起探测。仅在当前标签页记住最后确认的 origin,不维护持久化主机或项目目录。
- 不熟悉的 `?daemon=` 目标必须先明确确认,再发起探测。只有 capabilities 探测成功后,目标才会加入持久化连接目录。
- 浏览器本地文件桥仅在所连接的 daemon 与页面同源时提供,独立与嵌入式外壳一致:跨来源目标不会挂载文件桥,本地目录不会被交给一个文案承诺「文件留在你的电脑上」的远程 daemon。远端工作区文件仍由选中的 daemon 提供。同源的 SSH 隧道部署保留原行为和按来源隔离的授权。
- 通过连接页或 Daemon 状态切换主机后,使用现有添加工作区表单。不保留跨主机添加续接或重复目录浏览器。
- 远程添加续接必须显式触发,只在当前标签页生效,并且仅使用一次。它会复用只含 origin 的连接目录,但不会持久化项目目录、不会聚合多个 daemon 的 workspace,也不会改变普通 daemon 切换行为。

- 无效的远程地址会由连接页明确报告,并且不会被访问。
- 认证、Origin、Host 和网络失败继续在现有连接页中明确展示;一个有效的远程目标失败时,不会回退到本地 runtime。
Expand All @@ -54,13 +57,18 @@ Bearer token 仍保存在当前标签页的 `sessionStorage` 中,但存储键

- 单元测试覆盖地址校验、token 隔离、查询参数保留和 CSP source。
- 启动本地 Web Shell 和远程主机上已配置 token 的 daemon,再在浏览器中填写地址和 token 完成连接。
- 在“设置 > 连接”中添加一台远程计算机,确认验证后回到同一个设置分类,再通过普通“添加工作区”的“目录来源”选择该计算机,浏览并注册一个目录,确认新 workspace 在该 daemon 上成为当前 workspace。
- 验证切换“目录来源”时目录浏览器保持打开,取消会回到准确的来源页面且 URL 不含 token 或续接标记,普通 daemon 切换不会打开目录浏览器。
- 验证本地页面能列出远程 workspace、获取远程目录建议、列出和引用远程文件,并加载远程 session 对话记录。
- 验证刷新后仍保留目标和已选 session,并且不需要重新填写 token。

## 验收标准

- Web Shell 页面可以直接连接显式配置的远程 daemon origin。
- 无效或不可达的目标可以在连接页替换;已连接的目标可以在 Daemon 状态中切换。
- 独立 Web Shell 的设置面板提供“连接”分类,用于管理验证过的远程计算机 origin。
- 侧边栏只提供一个“添加工作区”入口,并直接打开目录浏览器;“目录来源”可以在这台计算机和验证过的远程连接之间切换,跨导航续接、浏览 daemon 目录并注册所选绝对路径。
- 取消会按预期回到来源 shell,切换“目录来源”时目录浏览流程保持活动;添加成功后留在所选 daemon;持久化目录只含连接 origin,不包含远程项目数据或 bearer token。
- workspace/session 发现以及文件/终端操作通过现有 SDK 使用所选 daemon。
- 凭据绝不会跨 daemon origin 复用。
- 远程选择在导航和刷新后仍然保留。
Expand Down
Loading
Loading