diff --git a/apps/control-plane/src/app.ts b/apps/control-plane/src/app.ts index ce6dde6..76bfe21 100644 --- a/apps/control-plane/src/app.ts +++ b/apps/control-plane/src/app.ts @@ -1213,9 +1213,12 @@ export async function createControlPlaneApp(deps: ControlPlaneDeps) { ); } + // Inject workspace env vars if daemon is linked to a workspace + const wsEnv = injectWorkspaceEnv(workload.env, workspaceStore, daemon.workspace); + const sessionRequest = { snapshot: daemon.snapshot, - workload, + workload: { ...workload, env: wsEnv }, resources: daemon.resources, timeoutMs: 600_000, network: daemon.network, @@ -1466,12 +1469,13 @@ export async function createControlPlaneApp(deps: ControlPlaneDeps) { } const prNumber = event.type === 'pull_request' ? event.prNumber : event.prNumber; + const enrichedEnv = injectWorkspaceEnv(envVars, workspaceStore, daemon.workspace); const sessionRequest = { snapshot: src.snapshot, workload: { type: 'script' as const, script: src.workload.script, - env: envVars, + env: enrichedEnv, }, resources: src.resources, timeoutMs: 600_000, @@ -2190,6 +2194,40 @@ export async function createControlPlaneApp(deps: ControlPlaneDeps) { // Dispatch helpers // --------------------------------------------------------------------------- +/** Inject workspace env vars into a session's workload env. */ +function injectWorkspaceEnv( + env: Record, + wsStore: { get(id: string): import('@paws/domain-workspace').Workspace | undefined }, + workspaceId: string | undefined, +): Record { + if (!workspaceId) return env; + const ws = wsStore.get(workspaceId); + if (!ws) return env; + + const primary = ws.repos.find((r) => r.role === 'primary') ?? ws.repos[0]; + if (!primary) return env; + + const extra: Record = { + PAWS_WORKSPACE_NAME: ws.name, + PAWS_WORKSPACE_TYPE: ws.type, + PAWS_WORKSPACE_REPO: primary.repo, + PAWS_WORKSPACE_ROOT_DIR: primary.rootDir, + PAWS_WORKSPACE_BRANCH: primary.branch, + PAWS_CLONE_URL: `https://github.com/${primary.repo}.git`, + }; + + if (ws.type === 'multi-repo') { + extra['PAWS_WORKSPACE_REPOS'] = ws.repos.map((r) => r.repo).join(','); + } + if (ws.settings.language) extra['PAWS_WORKSPACE_LANGUAGE'] = ws.settings.language; + if (ws.settings.packageManager) + extra['PAWS_WORKSPACE_PACKAGE_MANAGER'] = ws.settings.packageManager; + if (ws.settings.testCommand) extra['PAWS_WORKSPACE_TEST_COMMAND'] = ws.settings.testCommand; + if (ws.settings.buildCommand) extra['PAWS_WORKSPACE_BUILD_COMMAND'] = ws.settings.buildCommand; + + return { ...env, ...extra }; +} + /** * Fire-and-forget session dispatch. * diff --git a/apps/control-plane/src/store/daemons.ts b/apps/control-plane/src/store/daemons.ts index 838378d..3049d78 100644 --- a/apps/control-plane/src/store/daemons.ts +++ b/apps/control-plane/src/store/daemons.ts @@ -15,6 +15,7 @@ export interface StoredDaemon { status: DaemonStatus; snapshot: string; trigger: Trigger; + workspace?: string | undefined; workload?: Workload | undefined; agent?: AgentConfig | undefined; resources?: Resources | undefined; diff --git a/packages/integrations/src/types.ts b/packages/integrations/src/types.ts index 3c406fc..8a610b0 100644 --- a/packages/integrations/src/types.ts +++ b/packages/integrations/src/types.ts @@ -45,6 +45,7 @@ export interface GitHubDaemon { events: string[]; command?: string; }; + workspace?: string | undefined; snapshot: string; workload: { type: string; script: string; env: Record }; resources?: { vcpus: number; memoryMB: number };