index.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /** Host Workspace Remote owner: explicit commands and reconnect-safe state. */
  2. import { Context } from '@deepseek-ai/cordis'
  3. import { Remote, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol'
  4. import { WorkspaceCommands } from './commands.ts'
  5. import { DirectoryPickerController } from './directory-picker.ts'
  6. import { WorkspaceFeed } from './feed.ts'
  7. import type {
  8. WorkspaceArchiveSessionRequest,
  9. WorkspaceArchiveValue,
  10. WorkspaceCreateRequest,
  11. WorkspaceCreateValue,
  12. WorkspaceDeleteRequest,
  13. WorkspaceDeleteValue,
  14. WorkspaceFollowFrame,
  15. WorkspaceInsertBeforeRequest,
  16. WorkspaceInsertSessionBeforeRequest,
  17. WorkspaceOrderValue,
  18. WorkspaceRenameRequest,
  19. WorkspaceUnarchiveSessionRequest,
  20. WorkspaceValue,
  21. } from './types.ts'
  22. export type * from './types.ts'
  23. export { DirectoryPickerController } from './directory-picker.ts'
  24. declare module '@deepseek-ai/cordis' {
  25. interface Context {
  26. /** Host Workspace business API and Remote namespace owner. */
  27. workspaceController: WorkspaceController
  28. }
  29. }
  30. /** Host service backing the generated `ctx.remote.workspace` namespace. */
  31. export class WorkspaceController extends TypertRemoteService {
  32. static inject = ['typert', 'workspaceRegistry']
  33. private readonly commands: WorkspaceCommands
  34. private readonly feed: WorkspaceFeed
  35. /** @param ctx - Host context containing the Workspace registry. */
  36. constructor(ctx: Context) {
  37. super(ctx, 'workspaceController', { namespace: 'workspace' })
  38. this.commands = new WorkspaceCommands(ctx)
  39. this.feed = new WorkspaceFeed(ctx)
  40. // This package is the Loader entry for both Remote owners it hosts: the
  41. // directory-picking seam is abstract and never an entry itself. The child
  42. // stays pending until a picking backend is composed, so a host without one
  43. // registers no picking namespace instead of answering an unservable verb.
  44. ctx.plugin(DirectoryPickerController)
  45. }
  46. /**
  47. * Create or idempotently resolve one Workspace over an existing directory.
  48. * @param request - directory path to register.
  49. * @returns the Workspace and whether this call created it.
  50. */
  51. @Remote('create')
  52. create(request: WorkspaceCreateRequest): Promise<WorkspaceCreateValue> {
  53. return this.commands.create(request)
  54. }
  55. /**
  56. * Rename one Workspace to a unique non-blank title.
  57. * @param request - Workspace identity and proposed title.
  58. * @returns the updated Workspace projection.
  59. */
  60. @Remote('rename')
  61. rename(request: WorkspaceRenameRequest): Promise<WorkspaceValue> {
  62. return this.commands.rename(request)
  63. }
  64. /**
  65. * Remove one Workspace registration while retaining files and Sessions.
  66. * @param request - Workspace identity to remove.
  67. * @returns deletion confirmation.
  68. */
  69. @Remote('delete')
  70. delete(request: WorkspaceDeleteRequest): Promise<WorkspaceDeleteValue> {
  71. return this.commands.delete(request)
  72. }
  73. /**
  74. * Move one Workspace within the registry display order.
  75. * @param request - moved Workspace and optional anchor.
  76. * @returns the complete resulting Workspace order.
  77. */
  78. @Remote('insertBefore')
  79. insertBefore(request: WorkspaceInsertBeforeRequest): Promise<WorkspaceOrderValue> {
  80. return this.commands.insertBefore(request)
  81. }
  82. /**
  83. * Move one accounted Session within a Workspace.
  84. * @param request - Workspace, Session, and optional anchor identities.
  85. * @returns the updated Workspace projection.
  86. */
  87. @Remote('insertSessionBefore')
  88. insertSessionBefore(request: WorkspaceInsertSessionBeforeRequest): Promise<WorkspaceValue> {
  89. return this.commands.insertSessionBefore(request)
  90. }
  91. /**
  92. * Hide one known Session from Workspace grouping surfaces.
  93. * @param request - Session identity to archive.
  94. * @returns the complete resulting archive set.
  95. */
  96. @Remote('archiveSession')
  97. archiveSession(request: WorkspaceArchiveSessionRequest): Promise<WorkspaceArchiveValue> {
  98. return this.commands.archiveSession(request)
  99. }
  100. /**
  101. * Restore one archived Session to Workspace grouping surfaces.
  102. * @param request - Session identity to unarchive.
  103. * @returns the complete resulting archive set.
  104. */
  105. @Remote('unarchiveSession')
  106. unarchiveSession(request: WorkspaceUnarchiveSessionRequest): Promise<WorkspaceArchiveValue> {
  107. return this.commands.unarchiveSession(request)
  108. }
  109. /**
  110. * Stream a complete Workspace baseline followed by ordered increments.
  111. * @param signal - generation cancellation.
  112. * @returns baseline followed by ordered Workspace increments.
  113. */
  114. @Remote({ mode: 'stream' })
  115. follow(signal: AbortSignal): AsyncIterable<WorkspaceFollowFrame> {
  116. return this.feed.follow(signal)
  117. }
  118. }
  119. export default WorkspaceController