Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/providers/claude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ export function getDesktopSessionsDir(): string {
const override = process.env['CODEBURN_DESKTOP_SESSIONS_DIR']
if (override) return override
if (process.platform === 'darwin') return join(homedir(), 'Library', 'Application Support', 'Claude', 'local-agent-mode-sessions')
if (process.platform === 'win32') return join(homedir(), 'AppData', 'Roaming', 'Claude', 'local-agent-mode-sessions')
if (process.platform === 'win32') {
const appData = process.env['APPDATA']?.trim()
return join(appData || join(homedir(), 'AppData', 'Roaming'), 'Claude', 'local-agent-mode-sessions')
}
return join(homedir(), '.config', 'Claude', 'local-agent-mode-sessions')
}

Expand Down
47 changes: 45 additions & 2 deletions tests/providers/claude-config-dirs.test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import { mkdtemp, mkdir, rm, writeFile } from 'fs/promises'
import { delimiter as pathDelimiter, join } from 'path'
import { tmpdir, homedir } from 'os'
import { homedir, tmpdir } from 'os'

import { describe, it, expect, beforeEach, afterEach } from 'vitest'

import { claude } from '../../src/providers/claude.js'
import { claude, getDesktopSessionsDir } from '../../src/providers/claude.js'
import { parseAllSessions } from '../../src/parser.js'

let tmpRoot: string
const savedEnv = {
CLAUDE_CONFIG_DIR: process.env['CLAUDE_CONFIG_DIR'],
CLAUDE_CONFIG_DIRS: process.env['CLAUDE_CONFIG_DIRS'],
CODEBURN_DESKTOP_SESSIONS_DIR: process.env['CODEBURN_DESKTOP_SESSIONS_DIR'],
APPDATA: process.env['APPDATA'],
HOME: process.env['HOME'],
}

function withPlatform<T>(platform: typeof process.platform, run: () => T): T {
const descriptor = Object.getOwnPropertyDescriptor(process, 'platform')
Object.defineProperty(process, 'platform', { value: platform })
try {
return run()
} finally {
if (descriptor) Object.defineProperty(process, 'platform', descriptor)
}
}

beforeEach(async () => {
tmpRoot = await mkdtemp(join(tmpdir(), 'codeburn-claude-multi-'))
// Point HOME at a scratch dir so the default `~/.claude` fallback resolves
Expand All @@ -23,6 +35,8 @@ beforeEach(async () => {
await mkdir(process.env['HOME'], { recursive: true })
delete process.env['CLAUDE_CONFIG_DIR']
delete process.env['CLAUDE_CONFIG_DIRS']
delete process.env['CODEBURN_DESKTOP_SESSIONS_DIR']
delete process.env['APPDATA']
})

afterEach(async () => {
Expand Down Expand Up @@ -197,6 +211,35 @@ describe('claude provider — CLAUDE_CONFIG_DIRS discovery', () => {
})
})

describe('claude provider — Desktop sessions dir', () => {
it('uses APPDATA as the Windows Claude Desktop sessions root', () => {
const appData = join(tmpRoot, 'roaming-profile')
process.env['APPDATA'] = appData

withPlatform('win32', () => {
expect(getDesktopSessionsDir()).toBe(join(appData, 'Claude', 'local-agent-mode-sessions'))
})
})

it('falls back to the legacy Windows roaming profile path when APPDATA is unset', () => {
delete process.env['APPDATA']

withPlatform('win32', () => {
expect(getDesktopSessionsDir()).toBe(join(homedir(), 'AppData', 'Roaming', 'Claude', 'local-agent-mode-sessions'))
})
})

it('keeps CODEBURN_DESKTOP_SESSIONS_DIR ahead of Windows APPDATA discovery', () => {
const override = join(tmpRoot, 'desktop-override')
process.env['CODEBURN_DESKTOP_SESSIONS_DIR'] = override
process.env['APPDATA'] = join(tmpRoot, 'roaming-profile')

withPlatform('win32', () => {
expect(getDesktopSessionsDir()).toBe(override)
})
})
})

describe('claude provider — config.json claudeConfigDirs (menubar-driven)', () => {
async function writeConfigJson(value: unknown): Promise<void> {
const dir = join(process.env['HOME']!, '.config', 'codeburn')
Expand Down