@akiojin/claude-worktree
Version:
Interactive Git worktree manager for Claude Code with graphical branch selection
138 lines • 5.29 kB
JavaScript
import { homedir } from 'node:os';
import path from 'node:path';
import { readFile, writeFile, mkdir } from 'node:fs/promises';
const DEFAULT_CONFIG = {
defaultBaseBranch: 'main',
skipPermissions: false,
enableGitHubIntegration: true,
enableDebugMode: false,
worktreeNamingPattern: '{repo}-{branch}'
};
/**
* 設定ファイルを読み込む
*/
export async function loadConfig() {
const configPaths = [
path.join(process.cwd(), '.claude-worktree.json'),
path.join(homedir(), '.config', 'claude-worktree', 'config.json'),
path.join(homedir(), '.claude-worktree.json')
];
for (const configPath of configPaths) {
try {
const content = await readFile(configPath, 'utf-8');
const userConfig = JSON.parse(content);
return { ...DEFAULT_CONFIG, ...userConfig };
}
catch (error) {
// 設定ファイルが見つからない場合は次を試す
if (process.env.DEBUG_CONFIG) {
console.error(`Failed to load config from ${configPath}:`, error instanceof Error ? error.message : String(error));
}
}
}
// 環境変数からも読み込み
return {
...DEFAULT_CONFIG,
defaultBaseBranch: process.env.CLAUDE_WORKTREE_BASE_BRANCH || DEFAULT_CONFIG.defaultBaseBranch,
skipPermissions: process.env.CLAUDE_WORKTREE_SKIP_PERMISSIONS === 'true',
enableGitHubIntegration: process.env.CLAUDE_WORKTREE_GITHUB !== 'false',
enableDebugMode: process.env.DEBUG_CLEANUP === 'true' || process.env.DEBUG === 'true'
};
}
/**
* 設定値を取得する
*/
let cachedConfig = null;
export async function getConfig() {
if (!cachedConfig) {
cachedConfig = await loadConfig();
}
return cachedConfig;
}
export function resetConfigCache() {
cachedConfig = null;
}
/**
* セッションデータの保存・読み込み
*/
function getSessionFilePath(repositoryRoot) {
const sessionDir = path.join(homedir(), '.config', 'claude-worktree', 'sessions');
const repoName = path.basename(repositoryRoot);
const repoHash = Buffer.from(repositoryRoot).toString('base64').replace(/[/+=]/g, '_');
return path.join(sessionDir, `${repoName}_${repoHash}.json`);
}
export async function saveSession(sessionData) {
try {
const sessionPath = getSessionFilePath(sessionData.repositoryRoot);
const sessionDir = path.dirname(sessionPath);
// ディレクトリを作成
await mkdir(sessionDir, { recursive: true });
await writeFile(sessionPath, JSON.stringify(sessionData, null, 2), 'utf-8');
}
catch (error) {
// セッション保存の失敗は致命的ではないため、エラーをログに出力するのみ
if (process.env.DEBUG_SESSION) {
console.error('Failed to save session:', error instanceof Error ? error.message : String(error));
}
}
}
export async function loadSession(repositoryRoot) {
try {
const sessionPath = getSessionFilePath(repositoryRoot);
const content = await readFile(sessionPath, 'utf-8');
const sessionData = JSON.parse(content);
// セッションが24時間以内のもののみ有効とする
const now = Date.now();
const sessionAge = now - sessionData.timestamp;
const maxAge = 24 * 60 * 60 * 1000; // 24時間
if (sessionAge > maxAge) {
return null;
}
return sessionData;
}
catch (error) {
if (process.env.DEBUG_SESSION) {
console.error('Failed to load session:', error instanceof Error ? error.message : String(error));
}
return null;
}
}
export async function getAllSessions() {
try {
const sessionDir = path.join(homedir(), '.config', 'claude-worktree', 'sessions');
const { readdir } = await import('node:fs/promises');
const files = await readdir(sessionDir);
const sessions = [];
const now = Date.now();
const maxAge = 24 * 60 * 60 * 1000; // 24時間
for (const file of files) {
if (!file.endsWith('.json'))
continue;
try {
const filePath = path.join(sessionDir, file);
const content = await readFile(filePath, 'utf-8');
const sessionData = JSON.parse(content);
// 有効期限内のセッションのみ
const sessionAge = now - sessionData.timestamp;
if (sessionAge <= maxAge) {
sessions.push(sessionData);
}
}
catch (error) {
if (process.env.DEBUG_SESSION) {
console.error(`Failed to load session file ${file}:`, error instanceof Error ? error.message : String(error));
}
}
}
// 最新のものから順にソート
sessions.sort((a, b) => b.timestamp - a.timestamp);
return sessions;
}
catch (error) {
if (process.env.DEBUG_SESSION) {
console.error('Failed to get all sessions:', error instanceof Error ? error.message : String(error));
}
return [];
}
}
//# sourceMappingURL=index.js.map