@@ -69,6 +69,7 @@ import { DispatchModeLimit, exceededDispatchModeLimit } from "./DispatchModeLimi
6969import { projectTurnItemForDetail } from "./WireProjection.ts" ;
7070import * as LegacyV1ThreadImporter from "./legacy/LegacyV1ThreadImporter.ts" ;
7171import * as ServerSettings from "../serverSettings.ts" ;
72+ import { ThreadWorktreeRestore } from "../workspace/restoreMissingWorktree.ts" ;
7273
7374export type ThreadManagementSendMode = "auto" | "queue" | "steer" | "restart" ;
7475
@@ -316,6 +317,19 @@ export class ThreadManagementDurableRunProjectionError extends Schema.TaggedErro
316317 }
317318}
318319
320+ export class ThreadManagementWorktreeRestoreError extends Schema . TaggedError < ThreadManagementWorktreeRestoreError > ( ) (
321+ "ThreadManagementWorktreeRestoreError" ,
322+ {
323+ threadId : ThreadId ,
324+ cause : Schema . Defect ( ) ,
325+ } ,
326+ ) {
327+ override get message ( ) : string {
328+ const detail = this . cause instanceof Error ? ` ${ this . cause . message } ` : "" ;
329+ return `Couldn't recreate the missing workspace of thread ${ this . threadId } , so the message was not sent.${ detail } ` ;
330+ }
331+ }
332+
319333export class ThreadManagementProviderInstanceDisabledError extends Schema . TaggedError < ThreadManagementProviderInstanceDisabledError > ( ) (
320334 "ThreadManagementProviderInstanceDisabledError" ,
321335 {
@@ -360,6 +374,7 @@ export const ThreadManagementError = Schema.Union([
360374 ThreadManagementProjectThreadsListError ,
361375 ThreadManagementDurableRunProjectionError ,
362376 ThreadManagementProviderInstanceDisabledError ,
377+ ThreadManagementWorktreeRestoreError ,
363378] ) ;
364379export type ThreadManagementError = typeof ThreadManagementError . Type ;
365380
@@ -592,6 +607,7 @@ const make = Effect.gen(function* () {
592607 const legacyImporter = yield * LegacyV1ThreadImporter . LegacyV1ThreadImporter ;
593608 const serverSettings = yield * ServerSettings . ServerSettingsService ;
594609 const receipts = yield * CommandReceiptStore . CommandReceiptStoreV2 ;
610+ const worktreeRestore = yield * ThreadWorktreeRestore ;
595611
596612 const assertProviderInstanceEnabled : ThreadManagementServiceShape [ "assertProviderInstanceEnabled" ] =
597613 ( input ) =>
@@ -873,6 +889,26 @@ const make = Effect.gen(function* () {
873889 } ;
874890 }
875891
892+ // Turn start would fail on its own after the send reported success; a replay keeps its answer.
893+ // A live steer starts no turn, so it needs no workspace.
894+ if ( dispatchMode . type !== "steer_active" ) {
895+ yield * worktreeRestore
896+ . restore ( target . thread )
897+ . pipe (
898+ Effect . catch ( ( cause ) =>
899+ hasReceipt ( input . commandId ) . pipe (
900+ Effect . flatMap ( ( replay ) =>
901+ replay
902+ ? Effect . void
903+ : Effect . fail (
904+ new ThreadManagementWorktreeRestoreError ( { threadId : input . threadId , cause } ) ,
905+ ) ,
906+ ) ,
907+ ) ,
908+ ) ,
909+ ) ;
910+ }
911+
876912 const dispatched = yield * dispatch ( {
877913 type : "message.dispatch" ,
878914 commandId : input . commandId ,
@@ -1719,6 +1755,12 @@ const make = Effect.gen(function* () {
17191755 } ) ;
17201756} ) ;
17211757
1758+ const layerThreadWorktreeRestoreNoop = Layer . succeed ( ThreadWorktreeRestore , {
1759+ restore : Effect . fn ( "ThreadWorktreeRestore.restore" ) ( function ( ) {
1760+ return Effect . void ;
1761+ } ) ,
1762+ } ) ;
1763+
17221764const layerLegacyV1ThreadImporterNoop = Layer . succeed (
17231765 LegacyV1ThreadImporter . LegacyV1ThreadImporter ,
17241766 LegacyV1ThreadImporter . LegacyV1ThreadImporter . of ( {
@@ -1740,13 +1782,15 @@ export const layer: Layer.Layer<
17401782 | CommandReceiptStore . CommandReceiptStoreV2
17411783> = Layer . effect ( ThreadManagementService , make ) . pipe (
17421784 Layer . provide ( layerLegacyV1ThreadImporterNoop ) ,
1785+ Layer . provide ( layerThreadWorktreeRestoreNoop ) ,
17431786 Layer . provide ( ThreadCommandExecutor . layer ) ,
17441787) ;
17451788
17461789export const layerWithLegacyImporter : Layer . Layer <
17471790 ThreadManagementService ,
17481791 never ,
17491792 | LegacyV1ThreadImporter . LegacyV1ThreadImporter
1793+ | ThreadWorktreeRestore
17501794 | Orchestrator . OrchestratorV2
17511795 | ProviderSessionManager . ProviderSessionManagerV2
17521796 | ServerSettings . ServerSettingsService
0 commit comments