Merge pull request #1864 from deepseek-harness/worktree/drop-create-by-name
refactor: drop the create-by-name workspace route
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-31-one-route-to-add-a-workspace.md
|
||||
2026-07-31-one-route-to-add-a-workspace.md: 46bd5d5ca5ecfbc340fcb46b6da5e9f237764ab1
|
||||
2026-07-31-one-route-to-add-a-workspace.zh.md: 6a6e8b3fc9f64a62d3264f4c7779d11c8515e447
|
||||
2026-07-31-one-route-to-add-a-workspace.md: 4de79b7db30853a13319aa016d4eb5fb5d9ec1f1
|
||||
2026-07-31-one-route-to-add-a-workspace.zh.md: 2b305494c5d61db11f9ecf247c323040e6a549bf
|
||||
|
||||
@@ -25,9 +25,9 @@ The direct-open path carries the busy rule the menu entry states: while a pick i
|
||||
|
||||
`WorkspaceCreateFlow` is now `WorkspacePickFlow` and its `createOnly` prop is `addOnly`; the injected `createWorkspace` narrows from `{ name } | { path }` to `{ path }`.
|
||||
|
||||
## Wire and CLI residue
|
||||
## Wire and CLI surface
|
||||
|
||||
The host's `workspace.create` still accepts `{ name }`, and `dsh web --workspace-root` still feeds its target directory, but no product surface reaches either any more. The same is true of the client contract that carried the name to the wire: `WorkspaceCreateInput`, `WorkspacesService.create`'s `{ name }` arm, `intentName`'s name branch, and the manager's "name under workspaceRoot" contract. `apps/cli/README.md` and its Chinese counterpart still document `--workspace-root` as creating named Workspaces. The whole set is marked for deletion at the call site in `packages/host/apiproxy/src/api-proxy.ts` and left to a follow-up change: it is backend, client-contract, and CLI surface with its own test fallout (the api-proxy workspace suite, the runtime workspace suite, the config catalog), and the release-blocking part of this decision is the UI.
|
||||
`workspace.create` accepts only `{ path }`; the wire schema and `WorkspaceApi` have no `name` member. The gateway has no `workspaceRoot` config, the client contract exposes only path adoption through `WorkspaceCreateInput`, `WorkspacesService.create`, and `intentName`, and `dsh web` has no `--workspace-root` flag. `workspace-name-conflict` remains on the wire as `workspace.rename`'s duplicate-title error.
|
||||
|
||||
## Testing
|
||||
|
||||
@@ -45,13 +45,13 @@ The host's `workspace.create` still accepts `{ name }`, and `dsh web --workspace
|
||||
|
||||
**Keep the menu shell for entries we might add later (clone a repo, remote directory).** Rejected under "require a current owner and need": no such entry exists, and restoring a menu when one arrives is a smaller change than shipping an empty frame now.
|
||||
|
||||
**Delete the wire's create-by-name branch in the same change.** Rejected here: it is backend/CLI surface with a wider test fallout, and the urgent decision is the UI. See the residue section — it is marked, not forgotten.
|
||||
**Delete the wire's create-by-name branch in the same change.** Rejected because the UI decision did not depend on the backend and CLI deletion, whose separate contracts and tests formed an independently reviewable change.
|
||||
|
||||
**Register the workspace through the host in the e2e scaffold instead of driving the dialog.** Rejected: it would have decoupled all 15 scenarios from the picker, so nothing in the lane would prove the surviving route reaches a live composer. Every scenario now walks the real dialog to adopt its directory; only the create-a-folder half is concentrated in one scenario, because repeating it everywhere makes the shared helper non-idempotent for no extra signal.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Creating a Workspace outside the operator's chosen directory is no longer possible from the UI; the server-controlled `--workspace-root` target was the one way to constrain where new workspace folders land, and nothing replaces it. A deployment that needs that constraint has to re-introduce it deliberately.
|
||||
- The one remaining route browses the host filesystem, so the picker's reach is now the whole host rather than one configured parent. That is already the browse occupant's contract; this change makes it the only contract.
|
||||
- A composition that mounts `ui-workspace` without any directory-picker package can no longer add a Workspace at all, and now says so by omitting the button instead of offering a create-by-name fallback.
|
||||
- The UI creates Workspace folders only under a directory the operator chooses. No server-controlled configuration constrains that location; a deployment that needs such a constraint must add it deliberately.
|
||||
- The picker's configured reach defines the host filesystem available to the remaining route; there is no separate configured parent.
|
||||
- A composition that mounts `ui-workspace` without a directory-picker package cannot add a Workspace and omits the button.
|
||||
- The hero chip still announces `aria-haspopup="menu"` while the direct-open path raises a dialog instead. Making that truthful means routing the flow's presentation choice up through the `conversation.hero.workspace` owner contract — the flow owns the decision, the chip owns the announcement, and they sit in different packages — so it is a named follow-up rather than a silent inconsistency. The sidebar button this change added makes no popup claim at all.
|
||||
|
||||
@@ -25,9 +25,9 @@ Status: implemented
|
||||
|
||||
`WorkspaceCreateFlow` 现更名为 `WorkspacePickFlow`,其 `createOnly` prop 更名为 `addOnly`;注入的 `createWorkspace` 从 `{ name } | { path }` 收窄为 `{ path }`。
|
||||
|
||||
## Wire and CLI residue
|
||||
## Wire 与 CLI 表层
|
||||
|
||||
Host 侧的 `workspace.create` 仍接受 `{ name }`,`dsh web --workspace-root` 也仍在为它提供目标目录,但已没有任何产品表层会走到它们。把名称送到 wire 的客户端约定同样如此:`WorkspaceCreateInput`、`WorkspacesService.create` 的 `{ name }` 分支、`intentName` 的名称分支,以及 manager 中"workspaceRoot 下的 name"这一约定。`apps/cli/README.md` 及其中文对照本也仍把 `--workspace-root` 记为"创建具名 Workspace"。这一整套都在 `packages/host/apiproxy/src/api-proxy.ts` 的调用点标记为待删除,并留给后续改动:它横跨 backend、客户端约定与 CLI 面,有各自的测试波及面(api-proxy workspace 套件、runtime workspace 套件、配置目录),而本决定中阻塞发布的部分是 UI。
|
||||
`workspace.create` 只接受 `{ path }`;wire schema 与 `WorkspaceApi` 没有 `name` 成员。网关没有 `workspaceRoot` 配置;客户端约定只通过 `WorkspaceCreateInput`、`WorkspacesService.create` 与 `intentName` 提供按路径接纳,`dsh web` 没有 `--workspace-root` flag。`workspace-name-conflict` 仍保留在 wire 上,作为 `workspace.rename` 的标题重名错误。
|
||||
|
||||
## Testing
|
||||
|
||||
@@ -45,13 +45,13 @@ Host 侧的 `workspace.create` 仍接受 `{ name }`,`dsh web --workspace-root`
|
||||
|
||||
**为将来可能新增的入口(克隆仓库、远程目录)保留菜单壳。** 否决,依据"require a current owner and need":这样的入口目前并不存在,而等它到来时再恢复菜单,比现在就发一个空壳的改动更小。
|
||||
|
||||
**在同一改动中删除 wire 的按名称创建分支。** 在此否决:那是 backend/CLI 面,测试波及面更广,而紧急的决定是 UI。见 residue 一节——它是被标记了,不是被遗忘了。
|
||||
**在同一改动中删除 wire 的按名称创建分支。** 否决,因为 UI 决定不依赖后端与 CLI 删除,后两者各自的约定和测试构成一项可独立评审的改动。
|
||||
|
||||
**在 e2e scaffold 中经 host 注册 workspace,而不驱动对话框。** 否决:那会让全部 15 个场景与选择器解耦,整条 lane 将无法证明幸存的这条路径能走到可用的 composer。现在每个场景都会走真实对话框来接纳自己的目录;只有"新建文件夹"那一半集中在一个场景里,因为处处重复只会让共享辅助函数失去幂等性,却换不来额外信号。
|
||||
|
||||
## Consequences
|
||||
|
||||
- 从 UI 已无法在操作者选定目录之外创建 Workspace;服务端控制的 `--workspace-root` 目标曾是约束新 workspace 文件夹落点的唯一手段,现在没有替代品。需要该约束的部署必须有意识地重新引入它。
|
||||
- 仅存的这条路径会浏览宿主机文件系统,因此选择器的可达范围现在是整台宿主机,而非一个配置好的父目录。这本就是浏览占用者的约定,本改动使它成为唯一的约定。
|
||||
- 挂载了 `ui-workspace` 但未挂任何 directory-picker 包的组合,已完全无法添加 Workspace;现在它通过不渲染按钮来说明这一点,而不是提供一个按名称创建的兜底。
|
||||
- UI 只在操作者选择的目录下创建 Workspace 文件夹。没有服务端控制的配置约束其位置;需要该约束的部署必须明确加入该约束。
|
||||
- picker 配置的可达范围决定剩余路径可用的 Host 文件系统;不存在另一个配置好的父目录。
|
||||
- 挂载 `ui-workspace` 但没有 directory-picker 包的组合无法添加 Workspace,也不渲染按钮。
|
||||
- 主视觉区的 chip 仍声明 `aria-haspopup="menu"`,而直接拉起的路径实际弹出的是对话框。要让它如实,需要把流程的展示方式经 `conversation.hero.workspace` 的 owner 约定上报——决定权在流程,播报权在 chip,两者分属不同的包——因此这被列为一项具名的后续工作,而不是一处无声的不一致。本次新增的侧边栏按钮完全不作任何 popup 声明。
|
||||
|
||||
Reference in New Issue
Block a user