Skip to content

Commit aee1dac

Browse files
authored
feat(command-center): choose folder when opening a terminal (#3275)
1 parent 1c76940 commit aee1dac

6 files changed

Lines changed: 187 additions & 78 deletions

File tree

packages/core/src/command-center/cells.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import type { AgentSession, WorkspaceMode } from "@posthog/shared";
22
import type { Task } from "@posthog/shared/domain-types";
3-
import { getTerminalCellId, isBrainrotCell, isTerminalCell } from "./grid";
3+
import {
4+
getTerminalCellCwd,
5+
getTerminalCellId,
6+
isBrainrotCell,
7+
isTerminalCell,
8+
} from "./grid";
49
import { type CellStatus, deriveStatus, getRepoName } from "./status";
510

611
export interface CommandCenterCellData {
@@ -15,6 +20,7 @@ export interface CommandCenterCellData {
1520
isBrainrot: boolean;
1621
// Standalone terminal slot, independent of any agent run.
1722
terminalId: string | null;
23+
terminalCwd: string | null;
1824
}
1925

2026
export interface BuildCellsInput {
@@ -32,6 +38,7 @@ const EMPTY_CELL_DATA = {
3238
workspaceMode: null,
3339
isBrainrot: false,
3440
terminalId: null,
41+
terminalCwd: null,
3542
};
3643

3744
export function buildCommandCenterCells(
@@ -49,6 +56,7 @@ export function buildCommandCenterCells(
4956
...EMPTY_CELL_DATA,
5057
cellIndex,
5158
terminalId: getTerminalCellId(cellValue),
59+
terminalCwd: getTerminalCellCwd(cellValue),
5260
};
5361
}
5462

packages/core/src/command-center/grid.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
getCellCount,
66
getCellSessionId,
77
getGridDimensions,
8+
getTerminalCellCwd,
89
getTerminalCellId,
910
isBrainrotCell,
1011
isTerminalCell,
@@ -71,6 +72,14 @@ describe("terminal cells", () => {
7172
const value = makeTerminalCellValue("abc123");
7273
expect(isTerminalCell(value)).toBe(true);
7374
expect(getTerminalCellId(value)).toBe("abc123");
75+
expect(getTerminalCellCwd(value)).toBeNull();
76+
});
77+
78+
it("round-trips a terminal id and cwd through the cell value", () => {
79+
const value = makeTerminalCellValue("abc123", "/Users/me/my:repo");
80+
expect(isTerminalCell(value)).toBe(true);
81+
expect(getTerminalCellId(value)).toBe("abc123");
82+
expect(getTerminalCellCwd(value)).toBe("/Users/me/my:repo");
7483
});
7584

7685
it.each([

packages/core/src/command-center/grid.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,28 @@ export function isTerminalCell(value: string | null): value is string {
2525
return value?.startsWith(TERMINAL_CELL_PREFIX) ?? false;
2626
}
2727

28-
export function makeTerminalCellValue(terminalId: string): string {
29-
return `${TERMINAL_CELL_PREFIX}${terminalId}`;
28+
// terminalId is a base36 random string (no colon), so an optional cwd can be
29+
// appended after a colon. cwd is URI-encoded, so it never contains a colon.
30+
export function makeTerminalCellValue(
31+
terminalId: string,
32+
cwd?: string,
33+
): string {
34+
const base = `${TERMINAL_CELL_PREFIX}${terminalId}`;
35+
return cwd ? `${base}:${encodeURIComponent(cwd)}` : base;
3036
}
3137

3238
export function getTerminalCellId(value: string | null): string | null {
33-
return isTerminalCell(value)
34-
? value.slice(TERMINAL_CELL_PREFIX.length)
35-
: null;
39+
if (!isTerminalCell(value)) return null;
40+
const rest = value.slice(TERMINAL_CELL_PREFIX.length);
41+
const colon = rest.indexOf(":");
42+
return colon === -1 ? rest : rest.slice(0, colon);
43+
}
44+
45+
export function getTerminalCellCwd(value: string | null): string | null {
46+
if (!isTerminalCell(value)) return null;
47+
const rest = value.slice(TERMINAL_CELL_PREFIX.length);
48+
const colon = rest.indexOf(":");
49+
return colon === -1 ? null : decodeURIComponent(rest.slice(colon + 1));
3650
}
3751

3852
export function getGridDimensions(preset: LayoutPreset): GridDimensions {

packages/ui/src/features/command-center/commandCenterStore.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ interface CommandCenterStoreActions {
3434
setActiveCell: (cellIndex: number | null) => void;
3535
assignTask: (cellIndex: number, taskId: string) => void;
3636
setBrainrotCell: (cellIndex: number) => void;
37-
setTerminalCell: (cellIndex: number, terminalId: string) => void;
37+
setTerminalCell: (
38+
cellIndex: number,
39+
terminalId: string,
40+
cwd?: string,
41+
) => void;
3842
autofillCells: (taskIds: string[]) => void;
3943
clearCell: (cellIndex: number) => void;
4044
removeTaskById: (taskId: string) => void;
@@ -118,11 +122,11 @@ export const useCommandCenterStore = create<CommandCenterStore>()(
118122
};
119123
}),
120124

121-
setTerminalCell: (cellIndex, terminalId) =>
125+
setTerminalCell: (cellIndex, terminalId, cwd) =>
122126
set((state) => {
123127
if (cellIndex < 0 || cellIndex >= state.cells.length) return state;
124128
const cells = [...state.cells];
125-
cells[cellIndex] = makeTerminalCellValue(terminalId);
129+
cells[cellIndex] = makeTerminalCellValue(terminalId, cwd);
126130
return {
127131
cells,
128132
activeTaskId: null,

packages/ui/src/features/command-center/components/CommandCenterPanel.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,12 @@ function EmptyCell({ cellIndex }: { cellIndex: number }) {
133133
setBrainrotCell(cellIndex);
134134
}, [layout, cells, setBrainrotCell, cellIndex]);
135135

136-
const handleNewTerminal = useCallback(() => {
137-
setTerminalCell(cellIndex, secureRandomString(8));
138-
}, [setTerminalCell, cellIndex]);
136+
const handleNewTerminal = useCallback(
137+
(cwd?: string) => {
138+
setTerminalCell(cellIndex, secureRandomString(8), cwd);
139+
},
140+
[setTerminalCell, cellIndex],
141+
);
139142

140143
const handleTaskCreated = useCallback(
141144
(task: Task) => {
@@ -279,13 +282,15 @@ function BrainrotCell({ cellIndex }: { cellIndex: number }) {
279282
function TerminalCell({
280283
cellIndex,
281284
terminalId,
285+
terminalCwd,
282286
}: {
283287
cellIndex: number;
284288
terminalId: string;
289+
terminalCwd: string | null;
285290
}) {
286291
const clearCell = useCommandCenterStore((s) => s.clearCell);
287292
const { getRecentFolders, getFolderDisplayName } = useFolders();
288-
const cwd = getRecentFolders(1)[0]?.path;
293+
const cwd = terminalCwd ?? getRecentFolders(1)[0]?.path;
289294
const folderName = cwd ? getFolderDisplayName(cwd) : null;
290295
const stateKey = getTerminalCellStateKey(terminalId);
291296

@@ -413,7 +418,11 @@ export function CommandCenterPanel({
413418

414419
if (cell.terminalId) {
415420
return (
416-
<TerminalCell cellIndex={cell.cellIndex} terminalId={cell.terminalId} />
421+
<TerminalCell
422+
cellIndex={cell.cellIndex}
423+
terminalId={cell.terminalId}
424+
terminalCwd={cell.terminalCwd}
425+
/>
417426
);
418427
}
419428

0 commit comments

Comments
 (0)