takt/src/config/initialization.ts
2026-01-26 16:24:50 +09:00

108 lines
3.3 KiB
TypeScript

/**
* Initialization module for first-time setup
*
* Handles language selection and initial resource setup.
* Separated from paths.ts to avoid UI dependencies in utility modules.
*/
import { existsSync } from 'node:fs';
import type { Language } from '../models/types.js';
import { DEFAULT_LANGUAGE } from '../constants.js';
import { selectOptionWithDefault } from '../prompt/index.js';
import {
getGlobalConfigDir,
getGlobalAgentsDir,
getGlobalWorkflowsDir,
getGlobalLogsDir,
getProjectConfigDir,
ensureDir,
} from './paths.js';
import {
copyGlobalResourcesToDir,
copyLanguageResourcesToDir,
copyProjectResourcesToDir,
} from '../resources/index.js';
import { setLanguage, setProvider } from './globalConfig.js';
/**
* Check if language-specific resources need to be initialized.
* Returns true if agents or workflows directories don't exist.
*/
export function needsLanguageSetup(): boolean {
const agentsDir = getGlobalAgentsDir();
const workflowsDir = getGlobalWorkflowsDir();
return !existsSync(agentsDir) || !existsSync(workflowsDir);
}
/**
* Prompt user to select language for resources.
* Returns 'en' for English (default), 'ja' for Japanese.
*/
export async function promptLanguageSelection(): Promise<Language> {
const options: { label: string; value: Language }[] = [
{ label: 'English', value: 'en' },
{ label: '日本語 (Japanese)', value: 'ja' },
];
return await selectOptionWithDefault(
'Select language for default agents and workflows / デフォルトのエージェントとワークフローの言語を選択してください:',
options,
DEFAULT_LANGUAGE
);
}
/**
* Prompt user to select provider for resources.
*/
export async function promptProviderSelection(): Promise<'claude' | 'codex'> {
const options: { label: string; value: 'claude' | 'codex' }[] = [
{ label: 'Claude Code', value: 'claude' },
{ label: 'Codex', value: 'codex' },
];
return await selectOptionWithDefault(
'Select provider (Claude Code or Codex) / プロバイダーを選択してください:',
options,
'claude'
);
}
/**
* Initialize global takt directory structure with language selection.
* If agents/workflows don't exist, prompts user for language preference.
*/
export async function initGlobalDirs(): Promise<void> {
ensureDir(getGlobalConfigDir());
ensureDir(getGlobalLogsDir());
// Check if we need to set up language-specific resources
const needsSetup = needsLanguageSetup();
if (needsSetup) {
// Ask user for language preference
const lang = await promptLanguageSelection();
const provider = await promptProviderSelection();
// Copy language-specific resources (agents, workflows, config.yaml)
copyLanguageResourcesToDir(getGlobalConfigDir(), lang);
// Explicitly save the selected language (handles case where config.yaml existed)
setLanguage(lang);
setProvider(provider);
} else {
// Just copy base global resources (won't overwrite existing)
copyGlobalResourcesToDir(getGlobalConfigDir());
}
}
/**
* Initialize project-level .takt directory.
* Creates .takt/ and copies project resources (e.g., .gitignore).
* Only copies files that don't exist.
*/
export function initProjectDirs(projectDir: string): void {
const configDir = getProjectConfigDir(projectDir);
ensureDir(configDir);
copyProjectResourcesToDir(configDir);
}