refactor: drop the create-by-name workspace route

The Web picker collapsed onto the directory flow (see the one-route-to-add-a-workspace
Agent Note), leaving workspace.create({ name }) with no product consumer. Delete the
whole feed line: the wire schema's name member and WorkspaceApi spelling, the gateway's
workspaceRoot config/default and the mkdir branch, the client seam that carried the name
(WorkspaceCreateInput, WorkspacesService.create, intentName), the dsh web
--workspace-root flag, and the fixture's name handling. workspace-name-conflict stays as
workspace.rename's duplicate-title error.
This commit is contained in:
creatixchu
2026-08-07 14:26:50 +08:00
parent b767ad02e0
commit a7e43d4346
44 changed files with 145 additions and 252 deletions

View File

@@ -27,11 +27,11 @@ export interface IWorkspaces {
*/
startSession(workspaceId?: WorkspaceId): void
/**
* Create a Workspace by name or register an existing path.
* @param input - exactly one Host create spelling.
* Register an existing path as a Workspace.
* @param input - the Host create payload.
* @returns the created or idempotently resolved Workspace.
*/
create(input: { name: string } | { path: string }): Promise<WorkspaceView>
create(input: { path: string }): Promise<WorkspaceView>
/**
* Open the Host's native directory picker.
* @returns the selected path, or null when the user cancelled.

View File

@@ -120,7 +120,7 @@ export class WorkspaceManager {
/**
* Create or resolve a real Workspace, then publish its returned snapshot
* without waiting for the changed frame.
* @param input - name under workspaceRoot or an existing absolute path.
* @param input - the existing absolute path to adopt.
* @returns the wire result.
*/
async create(input: WorkspaceCreateInput): Promise<RpcResult<{ workspace: WorkspaceView; created: boolean }>> {

View File

@@ -186,11 +186,11 @@ export class WorkspacesService implements IWorkspaces {
}
/**
* Create a Workspace by name or register an existing path.
* @param input - exactly one Host create spelling.
* Register an existing path as a Workspace.
* @param input - the Host create payload.
* @returns the created or idempotently resolved Workspace.
*/
async create(input: { name: string } | { path: string }): Promise<WorkspaceView> {
async create(input: { path: string }): Promise<WorkspaceView> {
const result = await this.manager.create(input)
if (!result.ok) throw new WorkspaceCreateError(result.error)
return result.value.workspace

View File

@@ -8,7 +8,7 @@ import type { ObservableSnapshot } from '../contract/store.ts'
import { Notifier } from '../sessions/notifier.ts'
/** Host input retained by a local Workspace until materialization succeeds. */
export type WorkspaceCreateInput = { name: string } | { path: string }
export type WorkspaceCreateInput = { path: string }
/** Observable state of a client-local Workspace intent. */
export interface WorkspaceIntentSnapshot {
@@ -137,7 +137,6 @@ export class Workspace implements ObservableSnapshot<WorkspaceSnapshot> {
}
function intentName(input: WorkspaceCreateInput): string {
if ('name' in input) return input.name
const trimmed = input.path.replace(/[\\/]+$/, '')
return trimmed.split(/[\\/]/).pop() ?? input.path
}

View File

@@ -59,7 +59,7 @@ describe('WorkspaceManager', () => {
expect(manager.getSnapshot()).toMatchObject({ phase: 'ready', state: 'error', error: { message: 'wire down' } })
})
it('creates by name/path, prepends a new row, and folds failures', async () => {
it('creates by path, prepends a new row, and folds failures', async () => {
const api = new FakeApiClient()
const manager = new WorkspaceManager(api)
api.onWorkspaceCreate = payload => Promise.resolve(ok({
@@ -67,8 +67,8 @@ describe('WorkspaceManager', () => {
created: true,
payload,
} as never))
await expect(manager.create({ name: 'created' })).resolves.toMatchObject({ ok: true })
expect(api.callsOf('workspace.create')).toEqual([{ name: 'created' }])
await expect(manager.create({ path: '/w/created' })).resolves.toMatchObject({ ok: true })
expect(api.callsOf('workspace.create')).toEqual([{ path: '/w/created' }])
expect(manager.getSnapshot().items[0]?.workspaceId).toBe('created')
api.onWorkspaceCreate = () => Promise.reject(new Error('create transport'))