Skip to content

Commit bc1cd27

Browse files
feat: wire multi-repo paths through session and agent
Pass additional repository paths from multi-repo workspaces through to the agent session: - ConnectParams: add additionalRepoPaths field - SessionService.createNewLocalSession: forward additionalDirectories to agent.start mutation - TaskCreationSaga: resolve additional workspace paths from workspace.getInfo and pass them as additionalRepoPaths - workspaceEnv: add buildMultiRepoWorkspaceEnv with indexed per-repo env vars (POSTHOG_CODE_REPO_0_NAME, POSTHOG_CODE_REPO_0_PATH, etc.) Generated-By: PostHog Code Task-Id: 230ec8e6-6781-43b4-ae30-ea24faa410dc
1 parent 1b9a330 commit bc1cd27

3 files changed

Lines changed: 68 additions & 3 deletions

File tree

apps/code/src/main/services/workspace/workspaceEnv.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ export interface WorkspaceEnvContext {
88
worktreePath: string | null;
99
worktreeName: string | null;
1010
mode: WorkspaceMode;
11+
label?: string | null;
12+
}
13+
14+
export interface MultiRepoEnvContext {
15+
taskId: string;
16+
workspaces: WorkspaceEnvContext[];
1117
}
1218

1319
const PORT_BASE = 50000;
@@ -71,3 +77,43 @@ export async function buildWorkspaceEnv(
7177
POSTHOG_CODE_WORKSPACE_PORTS_END: String(portAllocation.end),
7278
};
7379
}
80+
81+
/**
82+
* Build env vars for multi-repo tasks. Includes indexed per-repo vars
83+
* (POSTHOG_CODE_REPO_0_*, POSTHOG_CODE_REPO_1_*, etc.) alongside the
84+
* legacy single-repo vars from the first workspace.
85+
*/
86+
export async function buildMultiRepoWorkspaceEnv(
87+
context: MultiRepoEnvContext,
88+
): Promise<Record<string, string>> {
89+
const nonCloudWorkspaces = context.workspaces.filter(
90+
(ws) => ws.mode !== "cloud",
91+
);
92+
if (nonCloudWorkspaces.length === 0) return {};
93+
94+
// Legacy vars from first workspace
95+
const legacyEnv = await buildWorkspaceEnv(nonCloudWorkspaces[0]);
96+
97+
// Indexed per-repo vars
98+
const repoEnv: Record<string, string> = {
99+
POSTHOG_CODE_REPO_COUNT: String(nonCloudWorkspaces.length),
100+
};
101+
102+
for (let i = 0; i < nonCloudWorkspaces.length; i++) {
103+
const ws = nonCloudWorkspaces[i];
104+
const prefix = `POSTHOG_CODE_REPO_${i}`;
105+
const wsPath = ws.worktreePath ?? ws.folderPath;
106+
const wsName = ws.label ?? ws.worktreeName ?? path.basename(ws.folderPath);
107+
108+
repoEnv[`${prefix}_NAME`] = wsName;
109+
repoEnv[`${prefix}_PATH`] = wsPath;
110+
111+
try {
112+
repoEnv[`${prefix}_BRANCH`] = (await getCurrentBranch(wsPath)) ?? "";
113+
} catch {
114+
repoEnv[`${prefix}_BRANCH`] = "";
115+
}
116+
}
117+
118+
return { ...legacyEnv, ...repoEnv };
119+
}

apps/code/src/renderer/features/sessions/service/service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ interface AuthCredentials {
7070
export interface ConnectParams {
7171
task: Task;
7272
repoPath: string;
73+
/** Additional repo paths for multi-repo tasks (passed as additionalDirectories to agent). */
74+
additionalRepoPaths?: string[];
7375
initialPrompt?: ContentBlock[];
7476
executionMode?: ExecutionMode;
7577
adapter?: "claude" | "codex";
@@ -178,6 +180,7 @@ export class SessionService {
178180
const {
179181
task,
180182
repoPath,
183+
additionalRepoPaths,
181184
initialPrompt,
182185
executionMode,
183186
adapter,
@@ -282,6 +285,7 @@ export class SessionService {
282285
adapter,
283286
model,
284287
reasoningLevel,
288+
additionalRepoPaths,
285289
);
286290
}
287291
} catch (error) {
@@ -537,6 +541,7 @@ export class SessionService {
537541
adapter?: "claude" | "codex",
538542
model?: string,
539543
reasoningLevel?: string,
544+
additionalRepoPaths?: string[],
540545
): Promise<void> {
541546
const { client } = auth;
542547
if (!client) {
@@ -564,6 +569,7 @@ export class SessionService {
564569
? (reasoningLevel as EffortLevel)
565570
: undefined,
566571
model: preferredModel,
572+
additionalDirectories: additionalRepoPaths,
567573
});
568574

569575
const session = this.createBaseSession(taskRun.id, taskId, taskTitle);

apps/code/src/renderer/sagas/task/task-creation.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,15 +301,28 @@ export class TaskCreationSaga extends Saga<
301301
)
302302
: undefined;
303303

304+
// Resolve additional repo paths from multi-repo workspaces
305+
let additionalRepoPaths: string[] | undefined;
306+
if (!input.taskId) {
307+
// New task: resolve from workspace creation results
308+
const allWorkspaces = await trpcClient.workspace.getInfo.query({
309+
taskId: task.id,
310+
});
311+
if (allWorkspaces.length > 1) {
312+
additionalRepoPaths = allWorkspaces
313+
.slice(1)
314+
.map((ws) => ws.worktree?.worktreePath)
315+
.filter((p): p is string => !!p);
316+
}
317+
}
318+
304319
await this.step({
305320
name: "agent_session",
306321
execute: async () => {
307-
// Fire-and-forget for both open and create paths.
308-
// The UI handles "connecting" state with a spinner (TaskLogsPanel),
309-
// so we don't need to block the saga on the full reconnect chain.
310322
const connectParams: ConnectParams = {
311323
task,
312324
repoPath: agentCwd ?? "",
325+
additionalRepoPaths,
313326
};
314327
if (initialPrompt) connectParams.initialPrompt = initialPrompt;
315328
if (input.executionMode)

0 commit comments

Comments
 (0)