Просмотр исходного кода

fix(client): teach the IWorkspaces face and its test double the browse calls

master's new ctx.workspaces contract face (IWorkspaces + TestWorkspaces
double) predates this stack's listDirectory/createDirectory; widening the
face is the explicit act of letting the browse flow drive them, and the
double records/stubs them like its siblings.
creatixchu 2 месяцев назад
Родитель
Сommit
431d7340fa

+ 14 - 1
packages/client/runtime/src/client/contract/workspaces.ts

@@ -6,7 +6,7 @@
  * the concrete class. Widening this interface is the explicit act of
  * widening what features may do to the workspaces domain.
  */
-import type { SessionId, WorkspaceId, WorkspaceView } from '@deepseek-ai/dsh-client-connection/client'
+import type { DirectoryListing, SessionId, WorkspaceId, WorkspaceView } from '@deepseek-ai/dsh-client-connection/client'
 import type { WorkspaceListState } from '../workspaces/service.ts'
 import type { ObservableSnapshot } from './store.ts'
 
@@ -37,6 +37,19 @@ export interface IWorkspaces {
    * @returns the selected path, or null when the user cancelled.
    */
   pickDirectory(): Promise<string | null>
+  /**
+   * List one directory level through the Host's `browse` capability.
+   * @param path - absolute directory to list; absent lists the Host home directory.
+   * @returns the level's listing with breadcrumb ancestry.
+   */
+  listDirectory(path?: string): Promise<DirectoryListing>
+  /**
+   * Create one child directory through the Host's `browse` capability.
+   * @param path - absolute existing parent directory.
+   * @param name - single non-blank path segment.
+   * @returns the created directory's absolute path.
+   */
+  createDirectory(path: string, name: string): Promise<string>
   /**
    * Open a filesystem path with the Host operating system's default application.
    * @param path - absolute or host-resolvable path.

+ 27 - 1
packages/client/test-runtime/src/workspaces.ts

@@ -1,7 +1,7 @@
 /** Test-owned workspaces face: the renderer standard-kit observable plus recorded actions. */
 import { createSnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'
 import type {
-  IWorkspaces, SessionId, SnapshotStore, WorkspaceId, WorkspaceListState, WorkspaceView,
+  DirectoryListing, IWorkspaces, SessionId, SnapshotStore, WorkspaceId, WorkspaceListState, WorkspaceView,
 } from '@deepseek-ai/dsh-client-runtime/client'
 import { workspaceListState } from './fixtures.ts'
 import type { Stabilizer } from './fixtures.ts'
@@ -109,6 +109,32 @@ export class TestWorkspaces implements IWorkspaces {
     return null
   }
 
+  /**
+   * Browse listing (recorded). The default serves an empty home level; stub
+   * to shape a tree.
+   * @param path - absolute directory to list; absent lists the home level.
+   * @returns the level's listing.
+   */
+  async listDirectory(path?: string): Promise<DirectoryListing> {
+    this.calls.push({ method: 'listDirectory', args: [path] })
+    const stub = this.stubs.get('listDirectory')
+    if (stub !== undefined) return await (stub(path) as Promise<DirectoryListing>)
+    return { path: '/home/test', home: '/home/test', crumbs: [{ name: '/', path: '/', hidden: false }], entries: [] }
+  }
+
+  /**
+   * Browse child creation (recorded). The default joins parent and name.
+   * @param path - absolute existing parent directory.
+   * @param name - single path segment.
+   * @returns the created directory's absolute path.
+   */
+  async createDirectory(path: string, name: string): Promise<string> {
+    this.calls.push({ method: 'createDirectory', args: [path, name] })
+    const stub = this.stubs.get('createDirectory')
+    if (stub !== undefined) return await (stub(path, name) as Promise<string>)
+    return `${path}/${name}`
+  }
+
   /**
    * Rename a Workspace (recorded). The default echoes a minimal view.
    * @param workspaceId - target workspace.