44 account ,
55 apiKey ,
66 chat as chatTable ,
7+ copilotChats ,
78 customTools ,
89 document ,
910 environment ,
@@ -36,6 +37,8 @@ import {
3637 serializeKBMeta ,
3738 serializeRecentExecutions ,
3839 serializeTableMeta ,
40+ serializeTaskChat ,
41+ serializeTaskSession ,
3942 serializeWorkflowMeta ,
4043} from '@/lib/copilot/vfs/serializers'
4144import { listWorkspaceFiles } from '@/lib/uploads/contexts/workspace'
@@ -194,6 +197,8 @@ function getStaticComponentFiles(): Map<string, string> {
194197 * knowledgebases/{name}/documents.json
195198 * tables/{name}/meta.json
196199 * files/{name}/meta.json
200+ * tasks/{title}/session.md
201+ * tasks/{title}/chat.json
197202 * custom-tools/{name}.json
198203 * environment/credentials.json
199204 * environment/api-keys.json
@@ -219,6 +224,7 @@ export class WorkspaceVFS {
219224 this . materializeFiles ( workspaceId ) ,
220225 this . materializeEnvironment ( workspaceId , userId ) ,
221226 this . materializeCustomTools ( workspaceId ) ,
227+ this . materializeTasks ( workspaceId , userId ) ,
222228 generateWorkspaceContext ( workspaceId , userId ) . then ( ( content ) => {
223229 this . files . set ( 'WORKSPACE.md' , content )
224230 } ) ,
@@ -643,6 +649,57 @@ export class WorkspaceVFS {
643649 }
644650 }
645651
652+ /**
653+ * Materialize mothership task chats as browsable conversation files.
654+ */
655+ private async materializeTasks ( workspaceId : string , userId : string ) : Promise < void > {
656+ try {
657+ const taskRows = await db
658+ . select ( {
659+ id : copilotChats . id ,
660+ title : copilotChats . title ,
661+ messages : copilotChats . messages ,
662+ createdAt : copilotChats . createdAt ,
663+ updatedAt : copilotChats . updatedAt ,
664+ } )
665+ . from ( copilotChats )
666+ . where (
667+ and (
668+ eq ( copilotChats . workspaceId , workspaceId ) ,
669+ eq ( copilotChats . userId , userId ) ,
670+ eq ( copilotChats . type , 'mothership' )
671+ )
672+ )
673+
674+ for ( const task of taskRows ) {
675+ const title = task . title || 'Untitled task'
676+ const safeName = sanitizeName ( title )
677+ const prefix = `tasks/${ safeName } /`
678+ const messages = Array . isArray ( task . messages ) ? task . messages : [ ]
679+
680+ this . files . set (
681+ `${ prefix } session.md` ,
682+ serializeTaskSession ( {
683+ id : task . id ,
684+ title,
685+ messageCount : messages . length ,
686+ createdAt : task . createdAt ,
687+ updatedAt : task . updatedAt ,
688+ } )
689+ )
690+
691+ if ( messages . length > 0 ) {
692+ this . files . set ( `${ prefix } chat.json` , serializeTaskChat ( messages ) )
693+ }
694+ }
695+ } catch ( err ) {
696+ logger . warn ( 'Failed to materialize tasks' , {
697+ workspaceId,
698+ error : err instanceof Error ? err . message : String ( err ) ,
699+ } )
700+ }
701+ }
702+
646703 /**
647704 * Materialize environment data: credentials, API keys, env variable names.
648705 */
0 commit comments