* Unarchive a workspace. Restores it to the main sidebar view.
(workspaceId: string)
| 5627 | * Unarchive a workspace. Restores it to the main sidebar view. |
| 5628 | */ |
| 5629 | async unarchive(workspaceId: string): Promise<Result<void>> { |
| 5630 | try { |
| 5631 | const workspace = this.config.findWorkspace(workspaceId); |
| 5632 | if (!workspace) { |
| 5633 | return Err("Workspace not found"); |
| 5634 | } |
| 5635 | const { projectPath, workspacePath } = workspace; |
| 5636 | |
| 5637 | let didUnarchive = false; |
| 5638 | let previousUnarchivedAt: string | undefined; |
| 5639 | let persistedUnarchivedAt: string | undefined; |
| 5640 | |
| 5641 | await this.config.editConfig((config) => { |
| 5642 | const projectConfig = config.projects.get(projectPath); |
| 5643 | if (projectConfig) { |
| 5644 | const workspaceEntry = |
| 5645 | projectConfig.workspaces.find((w) => w.id === workspaceId) ?? |
| 5646 | projectConfig.workspaces.find((w) => w.path === workspacePath); |
| 5647 | if (workspaceEntry) { |
| 5648 | const wasArchived = isWorkspaceArchived( |
| 5649 | workspaceEntry.archivedAt, |
| 5650 | workspaceEntry.unarchivedAt |
| 5651 | ); |
| 5652 | if (wasArchived) { |
| 5653 | // Just set unarchivedAt - archived state is derived from archivedAt > unarchivedAt. |
| 5654 | // This also bumps workspace to top of recency. |
| 5655 | previousUnarchivedAt = workspaceEntry.unarchivedAt; |
| 5656 | persistedUnarchivedAt = new Date().toISOString(); |
| 5657 | workspaceEntry.unarchivedAt = persistedUnarchivedAt; |
| 5658 | didUnarchive = true; |
| 5659 | } |
| 5660 | } |
| 5661 | } |
| 5662 | return config; |
| 5663 | }); |
| 5664 | |
| 5665 | // Only run hooks when the workspace is transitioning from archived → unarchived. |
| 5666 | if (!didUnarchive) { |
| 5667 | return Ok(undefined); |
| 5668 | } |
| 5669 | |
| 5670 | // Emit updated metadata |
| 5671 | const allMetadata = await this.config.getAllWorkspaceMetadata(); |
| 5672 | const updatedMetadata = allMetadata.find((m) => m.id === workspaceId); |
| 5673 | if (updatedMetadata) { |
| 5674 | const enrichedMetadata = this.enrichFrontendMetadata(updatedMetadata); |
| 5675 | const session = this.sessions.get(workspaceId); |
| 5676 | if (session) { |
| 5677 | session.emitMetadata(enrichedMetadata); |
| 5678 | } else { |
| 5679 | this.emit("metadata", { workspaceId, metadata: enrichedMetadata }); |
| 5680 | } |
| 5681 | } |
| 5682 | |
| 5683 | let hookMetadata: WorkspaceMetadata | undefined = updatedMetadata; |
| 5684 | if (!hookMetadata && (this.workspaceLifecycleHooks || this.worktreeArchiveSnapshotService)) { |
| 5685 | const metadataResult = await this.aiService.getWorkspaceMetadata(workspaceId); |
| 5686 | if (metadataResult.success) { |
no test coverage detected