diff --git a/apps/desktop/src/renderer/components/tasks/task-card.tsx b/apps/desktop/src/renderer/components/tasks/task-card.tsx
index 640fd298..4b7048b6 100644
--- a/apps/desktop/src/renderer/components/tasks/task-card.tsx
+++ b/apps/desktop/src/renderer/components/tasks/task-card.tsx
@@ -16,8 +16,10 @@ interface TaskCardProps {
export const TaskCard = ({ task }: TaskCardProps) => {
const layout = useLayout();
- const duration = formatDuration(task.createdAt, task.completedAt);
- const startedAgo = timeAgo(task.createdAt);
+ const startedAgo = task.startedAt ? timeAgo(task.startedAt) : 'Pending';
+ const duration = task.startedAt
+ ? formatDuration(task.startedAt, task.completedAt)
+ : '0s';
return (
diff --git a/apps/desktop/src/renderer/components/tasks/task-details.tsx b/apps/desktop/src/renderer/components/tasks/task-details.tsx
index f0b78a92..a3b7d67c 100644
--- a/apps/desktop/src/renderer/components/tasks/task-details.tsx
+++ b/apps/desktop/src/renderer/components/tasks/task-details.tsx
@@ -20,8 +20,10 @@ interface TaskDetailsProps {
}
export const TaskDetails = ({ task, logs, artifacts }: TaskDetailsProps) => {
- const duration = formatDuration(task.createdAt, task.completedAt);
- const createdAtAgo = timeAgo(task.createdAt);
+ const startedAgo = task.startedAt ? timeAgo(task.startedAt) : 'Pending';
+ const duration = task.startedAt
+ ? formatDuration(task.startedAt, task.completedAt)
+ : '0s';
return (
@@ -54,7 +56,7 @@ export const TaskDetails = ({ task, logs, artifacts }: TaskDetailsProps) => {
Started
- {createdAtAgo}
+ {startedAgo}
diff --git a/apps/server/src/lib/tasks/mappers.ts b/apps/server/src/lib/tasks/mappers.ts
index 27bbec6f..5eb6f81b 100644
--- a/apps/server/src/lib/tasks/mappers.ts
+++ b/apps/server/src/lib/tasks/mappers.ts
@@ -12,6 +12,8 @@ export const mapTaskOutput = (task: SelectTask): TaskOutput => {
createdAt: task.created_at.toISOString(),
createdBy: task.created_by,
completedAt: task.completed_at?.toISOString(),
+ startedAt: task.started_at?.toISOString(),
+ activeAt: task.active_at?.toISOString(),
attributes: task.attributes,
};
};
@@ -35,5 +37,6 @@ export const mapTaskArtifactOutput = (
size: artifact.size,
mimeType: artifact.mime_type,
createdAt: artifact.created_at.toISOString(),
+ expiresAt: artifact.expires_at?.toISOString(),
};
};
diff --git a/apps/server/src/lib/tasks/workspace-export.ts b/apps/server/src/lib/tasks/workspace-export.ts
index 6226a2c0..ff52cb6d 100644
--- a/apps/server/src/lib/tasks/workspace-export.ts
+++ b/apps/server/src/lib/tasks/workspace-export.ts
@@ -43,6 +43,7 @@ export class WorkspaceExport {
private readonly exportDataZipKey: string;
private readonly exportFilesZipPrefix: string;
private readonly exportTempDirectory: string;
+ private readonly artifactExpireDate: Date;
private readonly dataFileKeys: string[] = [];
private readonly uploadFileKeys: string[][] = [];
@@ -81,6 +82,7 @@ export class WorkspaceExport {
this.exportDataZipKey = `${this.taskDir}/data.zip`;
this.exportFilesZipPrefix = `${this.taskDir}/files`;
this.exportTempDirectory = `${this.taskDir}/temp`;
+ this.artifactExpireDate = new Date(Date.now() + 1000 * 60 * 60 * 24 * 30);
}
public async export() {
@@ -732,6 +734,7 @@ export class WorkspaceExport {
size,
path,
created_at: new Date(),
+ expires_at: this.artifactExpireDate,
})
.executeTakeFirst();
diff --git a/packages/core/src/types/tasks.ts b/packages/core/src/types/tasks.ts
index 4d5d8ff3..d1b60fb7 100644
--- a/packages/core/src/types/tasks.ts
+++ b/packages/core/src/types/tasks.ts
@@ -42,6 +42,8 @@ export const taskOutputSchema = z.object({
workspaceId: z.string(),
createdAt: z.string(),
createdBy: z.string(),
+ startedAt: z.string().optional(),
+ activeAt: z.string().optional(),
completedAt: z.string().optional(),
});
@@ -69,6 +71,7 @@ export const taskArtifactOutputSchema = z.object({
size: z.number(),
mimeType: z.string(),
createdAt: z.string(),
+ expiresAt: z.string().optional(),
});
export type TaskArtifactOutput = z.infer;