Key workspace status and ownership by ID, not directory

Multiple workspaces can share one checkout directory. Agent and terminal
status, sidebar tabs, and ownership now attribute strictly by workspace ID,
so a running or blocked agent in one workspace no longer shows up on its
same-directory siblings.

A one-time startup migration backfills workspace IDs onto legacy agents, and
every agent and terminal is created with one thereafter. Directory lookups
remain only for genuinely folder-derived git facts (branch, diff) and the
archive-by-path adapter.
This commit is contained in:
Mohamed Boudra
2026-06-16 13:37:58 +07:00
parent ba9f7740a8
commit 9966e49329
102 changed files with 3222 additions and 1932 deletions
+15
View File
@@ -254,6 +254,21 @@ describe("translation resources", () => {
expect(en.openProject.tiles.addProject.title).toBe("Add a project");
});
it("resolves the worktree delete prompt keys used by the sidebar prompt", () => {
const strings = flattenStrings(en);
expect(strings["sidebar.workspace.confirmations.deleteWorktreePrompt.title"]).toBe(
"Archive workspace",
);
expect(strings["sidebar.workspace.confirmations.deleteWorktreePrompt.message"]).toBe(
"Also remove the worktree from disk?",
);
expect(strings["sidebar.workspace.confirmations.deleteWorktreePrompt.keep"]).toBe(
"Keep on disk",
);
expect(strings["sidebar.workspace.confirmations.deleteWorktreePrompt.delete"]).toBe("Delete");
});
it("includes provider selector and pairing keys for the Batch 4D migration", () => {
expect(en.modelSelector.title).toBe("Select provider");
expect(en.modelSelector.favorites).toBe("Favorites");
+6 -6
View File
@@ -811,12 +811,12 @@ export const ar: TranslationResources = {
'إخفاء "{{workspaceName}}" من الشريط الجانبي؟\n\n لن يتم تغيير الملفات الموجودة على القرص.',
hideConfirm: "يخفي",
cancel: "يلغي",
},
deleteWorktreePrompt: {
title: "أرشفة مساحة العمل",
message: "هل تريد أيضًا إزالة شجرة العمل من القرص؟",
keep: "الاحتفاظ على القرص",
delete: "حذف",
deleteWorktreePrompt: {
title: "أرشفة مساحة العمل",
message: "هل تريد أيضًا إزالة شجرة العمل من القرص؟",
keep: "الاحتفاظ على القرص",
delete: "حذف",
},
},
rename: {
title: "إعادة تسمية مساحة العمل",
+6 -6
View File
@@ -817,12 +817,12 @@ export const en = {
'Hide "{{workspaceName}}" from the sidebar?\n\nFiles on disk will not be changed.',
hideConfirm: "Hide",
cancel: "Cancel",
},
deleteWorktreePrompt: {
title: "Archive workspace",
message: "Also remove the worktree from disk?",
keep: "Keep on disk",
delete: "Delete",
deleteWorktreePrompt: {
title: "Archive workspace",
message: "Also remove the worktree from disk?",
keep: "Keep on disk",
delete: "Delete",
},
},
rename: {
title: "Rename workspace",
+6 -6
View File
@@ -837,12 +837,12 @@ export const es: TranslationResources = {
'¿Ocultar "{{workspaceName}}" de la barra lateral?\n\nLos archivos en el disco no se cambiarán.',
hideConfirm: "Esconder",
cancel: "Cancelar",
},
deleteWorktreePrompt: {
title: "Archivar espacio de trabajo",
message: "¿También eliminar el worktree del disco?",
keep: "Conservar en disco",
delete: "Eliminar",
deleteWorktreePrompt: {
title: "Archivar espacio de trabajo",
message: "¿También eliminar el worktree del disco?",
keep: "Conservar en disco",
delete: "Eliminar",
},
},
rename: {
title: "Cambiar nombre del espacio de trabajo",
+6 -6
View File
@@ -836,12 +836,12 @@ export const fr: TranslationResources = {
"Masquer «{{workspaceName}}» dans la barre latérale?\n\nLes fichiers sur le disque ne seront pas modifiés.",
hideConfirm: "Cacher",
cancel: "Annuler",
},
deleteWorktreePrompt: {
title: "Archiver l'espace de travail",
message: "Supprimer aussi le worktree du disque?",
keep: "Conserver sur le disque",
delete: "Supprimer",
deleteWorktreePrompt: {
title: "Archiver l'espace de travail",
message: "Supprimer aussi le worktree du disque?",
keep: "Conserver sur le disque",
delete: "Supprimer",
},
},
rename: {
title: "Renommer l'espace de travail",
+6 -6
View File
@@ -829,12 +829,12 @@ export const ru: TranslationResources = {
"Скрыть «{{workspaceName}}» на боковой панели?\n\n Файлы на диске не будут изменены.",
hideConfirm: "Скрывать",
cancel: "Отмена",
},
deleteWorktreePrompt: {
title: "Архивировать рабочее пространство",
message: "Также удалить рабочее дерево с диска?",
keep: "Оставить на диске",
delete: "Удалить",
deleteWorktreePrompt: {
title: "Архивировать рабочее пространство",
message: "Также удалить рабочее дерево с диска?",
keep: "Оставить на диске",
delete: "Удалить",
},
},
rename: {
title: "Переименовать рабочую область",
+6 -6
View File
@@ -802,12 +802,12 @@ export const zhCN: TranslationResources = {
hideMessage: "从侧边栏隐藏「{{workspaceName}}」?\n\n磁盘上的文件不会被更改。",
hideConfirm: "隐藏",
cancel: "取消",
},
deleteWorktreePrompt: {
title: "归档 workspace",
message: "同时从磁盘删除 worktree?",
keep: "保留在磁盘上",
delete: "删除",
deleteWorktreePrompt: {
title: "归档 workspace",
message: "同时从磁盘删除 worktree?",
keep: "保留在磁盘上",
delete: "删除",
},
},
rename: {
title: "重命名 workspace",