feat: sortable workspace tabs, tab context menus, and terminal auto-create removal

- Add drag-and-drop tab reordering with persistent tab order
- Add right-click context menu with copy agent ID, copy resume command, close to right
- Switch workspace route encoding from percent-encoding to base64url
- Remove terminal auto-creation on directory listing (explicit create only)
- Add swipe gestures on terminal emulator for mobile sidebar navigation
- Highlight active workspace row in sidebar
This commit is contained in:
Mohamed Boudra
2026-03-02 15:59:13 +07:00
parent c8cef9bec8
commit 223c8d7d0b
19 changed files with 1971 additions and 285 deletions
+29 -3
View File
@@ -1,5 +1,8 @@
import { describe, expect, it } from "vitest";
import {
buildHostWorkspaceRoute,
decodeWorkspaceIdFromPathSegment,
encodeWorkspaceIdForPathSegment,
parseHostAgentDraftRouteFromPathname,
parseHostAgentRouteFromPathname,
parseHostDraftRouteFromPathname,
@@ -46,9 +49,14 @@ describe("parseHostAgentRouteFromPathname", () => {
});
describe("workspace route parsing", () => {
it("encodes workspace IDs as base64url (no padding)", () => {
expect(encodeWorkspaceIdForPathSegment("/tmp/repo")).toBe("L3RtcC9yZXBv");
expect(decodeWorkspaceIdFromPathSegment("L3RtcC9yZXBv")).toBe("/tmp/repo");
});
it("parses workspace route", () => {
expect(
parseHostWorkspaceRouteFromPathname("/h/local/workspace/%2Ftmp%2Frepo")
parseHostWorkspaceRouteFromPathname("/h/local/workspace/L3RtcC9yZXBv")
).toEqual({
serverId: "local",
workspaceId: "/tmp/repo",
@@ -58,7 +66,7 @@ describe("workspace route parsing", () => {
it("parses workspace agent route", () => {
expect(
parseHostWorkspaceAgentRouteFromPathname(
"/h/local/workspace/%2Ftmp%2Frepo/agent/agent-1"
"/h/local/workspace/L3RtcC9yZXBv/agent/agent-1"
)
).toEqual({
serverId: "local",
@@ -70,7 +78,7 @@ describe("workspace route parsing", () => {
it("parses workspace terminal route", () => {
expect(
parseHostWorkspaceTerminalRouteFromPathname(
"/h/local/workspace/%2Ftmp%2Frepo/terminal/term-1"
"/h/local/workspace/L3RtcC9yZXBv/terminal/term-1"
)
).toEqual({
serverId: "local",
@@ -78,4 +86,22 @@ describe("workspace route parsing", () => {
terminalId: "term-1",
});
});
it("still parses legacy percent-encoded workspace routes", () => {
expect(
parseHostWorkspaceAgentRouteFromPathname(
"/h/local/workspace/%2Ftmp%2Frepo/agent/agent-1"
)
).toEqual({
serverId: "local",
workspaceId: "/tmp/repo",
agentId: "agent-1",
});
});
it("builds base64url workspace routes", () => {
expect(buildHostWorkspaceRoute("local", "/tmp/repo")).toBe(
"/h/local/workspace/L3RtcC9yZXBv"
);
});
});