index.ts 4.2 KB

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