(
this: AcpAgent,
params: NewSessionRequest,
opts: {
forceNewId?: boolean
sessionId?: string
initialMessages?: Message[]
} = {},
)
| 60 | // ── createSession ──────────────────────────────────────────────── |
| 61 | |
| 62 | async function createSession( |
| 63 | this: AcpAgent, |
| 64 | params: NewSessionRequest, |
| 65 | opts: { |
| 66 | forceNewId?: boolean |
| 67 | sessionId?: string |
| 68 | initialMessages?: Message[] |
| 69 | } = {}, |
| 70 | ): Promise<NewSessionResponse> { |
| 71 | enableConfigs() |
| 72 | |
| 73 | const sessionId = opts.sessionId ?? randomUUID() |
| 74 | const cwd = params.cwd |
| 75 | |
| 76 | // Align the global session state so that transcript persistence, |
| 77 | // analytics, and cost tracking use the ACP session ID. |
| 78 | // Preserve the projectDir set by getOrCreateSession so that |
| 79 | // getSessionProjectDir() continues to resolve correctly. |
| 80 | const currentProjectDir = getSessionProjectDir() |
| 81 | switchSession(sessionId as SessionId, currentProjectDir) |
| 82 | |
| 83 | // Set CWD for the session |
| 84 | setOriginalCwd(cwd) |
| 85 | const previousProcessCwd = process.cwd() |
| 86 | let processCwdChanged = false |
| 87 | try { |
| 88 | process.chdir(cwd) |
| 89 | processCwdChanged = true |
| 90 | } catch { |
| 91 | // CWD may not exist yet; best-effort |
| 92 | } |
| 93 | |
| 94 | // entry.ts calls applySafeConfigEnvironmentVariables() during handshake so the |
| 95 | // API client can authenticate before createSession arrives. At that point |
| 96 | // getOriginalCwd() is still the spawn cwd (not the project dir), so |
| 97 | // loadSettingsFromDisk() resolves localSettings/projectSettings against the |
| 98 | // wrong root and caches the empty result. Now that we've set the real project |
| 99 | // cwd, drop the cache and re-apply so settings.local.json and project env |
| 100 | // become visible to readSettingsPermissionMode() and downstream consumers. |
| 101 | resetSettingsCache() |
| 102 | applySafeConfigEnvironmentVariables() |
| 103 | |
| 104 | try { |
| 105 | // Build tools with a permissive permission context. |
| 106 | const permissionContext = getEmptyToolPermissionContext() |
| 107 | const tools: Tools = getTools(permissionContext) |
| 108 | |
| 109 | // Parse permission mode from _meta (passed by RCS/acp-link) or settings. |
| 110 | const meta = params._meta as Record<string, unknown> | null | undefined |
| 111 | const hasMetaPermissionMode = hasOwnField(meta, 'permissionMode') |
| 112 | const metaPermissionMode = hasMetaPermissionMode |
| 113 | ? meta?.permissionMode |
| 114 | : undefined |
| 115 | const settingsPermissionMode = readSettingsPermissionMode() |
| 116 | const permissionMode = resolveSessionPermissionMode( |
| 117 | metaPermissionMode, |
| 118 | hasMetaPermissionMode, |
| 119 | settingsPermissionMode, |
no test coverage detected