thought-cabinet 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -7
- package/dist/index.js +88 -79
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/agent-assets/skills/creating-plan/SKILL.md +6 -0
- package/src/agent-assets/skills/creating-plan/plan-template.md +37 -12
- package/src/agent-assets/skills/implementing-plan/SKILL.md +30 -3
- package/src/agent-assets/skills/onboard/SKILL.md +74 -0
- package/src/agent-assets/skills/onboard/onboard.sh +118 -0
- package/src/agent-assets/skills/test-skill-e2e/SKILL.md +205 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/thoughts/init.ts","../src/config.ts","../src/commands/thoughts/utils/config.ts","../src/commands/thoughts/utils/paths.ts","../src/git.ts","../src/commands/thoughts/utils/repository.ts","../src/templates/gitignore.ts","../src/templates/readme.ts","../src/templates/agentMd.ts","../src/templates/gitHooks.ts","../src/commands/thoughts/utils/symlinks.ts","../src/commands/thoughts/utils/cleanup.ts","../src/commands/thoughts/profile/utils.ts","../src/commands/thoughts/utils/git-url.ts","../src/commands/thoughts/init-core.ts","../src/hooks/loader.ts","../src/hooks/executor.ts","../src/commands/thoughts/destroy.ts","../src/commands/thoughts/sync.ts","../src/commands/thoughts/status.ts","../src/commands/thoughts/config.ts","../src/commands/thoughts/prune.ts","../src/commands/thoughts/migrate.ts","../src/commands/agent/registry.ts","../src/commands/agent/constants.ts","../src/commands/thoughts/profile/create.ts","../src/commands/thoughts/profile/list.ts","../src/commands/thoughts/profile/show.ts","../src/commands/thoughts/profile/delete.ts","../src/commands/thoughts.ts","../src/commands/agent/init.ts","../src/commands/agent/discovery.ts","../src/commands/agent/installer.ts","../src/commands/agent/update.ts","../src/commands/agent.ts","../src/commands/metadata/metadata.ts","../src/commands/metadata.ts","../src/commands/worktree/add.ts","../src/tmux.ts","../src/agent-config.ts","../src/commands/worktree/list.ts","../src/commands/worktree/merge.ts","../src/commands/worktree/utils.ts","../src/commands/worktree/remove.ts","../src/commands/worktree.ts","../src/commands/hooks/init.ts","../src/commands/hooks.ts","../src/commands/completion.ts","../src/completion/handler.ts","../src/completion/providers.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander'\nimport { thoughtsCommand } from './commands/thoughts.js'\nimport { skillCommand } from './commands/agent.js'\nimport { metadataCommand } from './commands/metadata.js'\nimport { worktreeCommand } from './commands/worktree.js'\nimport { hooksCommand } from './commands/hooks.js'\nimport { completionCommand } from './commands/completion.js'\nimport { handleCompletion } from './completion/handler.js'\nimport dotenv from 'dotenv'\nimport { createRequire } from 'node:module'\n\nasync function main(): Promise<void> {\n // Handle shell completion before anything else\n const completionHandled = await handleCompletion()\n if (completionHandled) {\n process.exit(0)\n }\n\n // Load environment variables\n dotenv.config()\n\n const require = createRequire(import.meta.url)\n const { version } = require('../package.json') as { version: string }\n\n const program = new Command()\n\n program\n .name('thoughtcabinet')\n .description(\n 'Thought Cabinet (thc) — CLI for structured AI coding workflows with filesystem-based memory and context management.',\n )\n .version(version)\n\n // Add commands\n thoughtsCommand(program)\n skillCommand(program)\n metadataCommand(program)\n worktreeCommand(program)\n hooksCommand(program)\n completionCommand(program)\n\n program.parse(process.argv)\n}\n\nmain().catch(err => {\n console.error(err)\n process.exit(1)\n})\n","import fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport {\n ThoughtsConfig,\n loadThoughtsConfig,\n saveThoughtsConfig,\n getDefaultThoughtsRepo,\n ensureThoughtsRepoExists,\n createThoughtsDirectoryStructure,\n getCurrentRepoPath,\n getRepoNameFromPath,\n expandPath,\n getRepoThoughtsPath,\n getGlobalThoughtsPath,\n updateSymlinksForNewUsers,\n getMainRepoPath,\n} from './utils/index.js'\nimport { validateProfile, resolveProfileForRepo, getRepoNameFromMapping, getProfileNameFromMapping } from './profile/utils.js'\nimport { RepoMappingObject } from '../../config.js'\nimport { generateClaudeMd } from '../../templates/index.js'\nimport { setupGitHooks, pullThoughtsFromRemote } from './init-core.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\n\ninterface InitOptions {\n force?: boolean\n configFile?: string\n directory?: string\n profile?: string\n}\n\nfunction sanitizeDirectoryName(name: string): string {\n return name.replace(/[^a-zA-Z0-9_-]/g, '_')\n}\n\nfunction checkExistingSetup(config?: ThoughtsConfig | null): {\n exists: boolean\n isValid: boolean\n message?: string\n} {\n const thoughtsDir = path.join(process.cwd(), 'thoughts')\n\n if (!fs.existsSync(thoughtsDir)) {\n return { exists: false, isValid: false }\n }\n\n // Check if it's a directory\n if (!fs.lstatSync(thoughtsDir).isDirectory()) {\n return { exists: true, isValid: false, message: 'thoughts exists but is not a directory' }\n }\n\n // Need config to check for user-specific symlinks\n if (!config) {\n return {\n exists: true,\n isValid: false,\n message: 'thoughts directory exists but configuration is missing',\n }\n }\n\n // Check for expected symlinks in new structure\n const userPath = path.join(thoughtsDir, config.user)\n const sharedPath = path.join(thoughtsDir, 'shared')\n const globalPath = path.join(thoughtsDir, 'global')\n\n const hasUser = fs.existsSync(userPath) && fs.lstatSync(userPath).isSymbolicLink()\n const hasShared = fs.existsSync(sharedPath) && fs.lstatSync(sharedPath).isSymbolicLink()\n const hasGlobal = fs.existsSync(globalPath) && fs.lstatSync(globalPath).isSymbolicLink()\n\n if (!hasUser || !hasShared || !hasGlobal) {\n return {\n exists: true,\n isValid: false,\n message: 'thoughts directory exists but symlinks are missing or broken',\n }\n }\n\n return { exists: true, isValid: true }\n}\n\nexport async function thoughtsInitCommand(options: InitOptions): Promise<void> {\n try {\n // Check for interactive mode when needed\n if (!options.directory && !process.stdin.isTTY) {\n p.log.error('Not running in interactive terminal.')\n p.log.info('Use --directory flag to specify the repository directory name.')\n process.exit(1)\n }\n\n const currentRepo = getCurrentRepoPath()\n\n // Check if we're in a git repository\n try {\n execSync('git rev-parse --git-dir', { stdio: 'pipe' })\n } catch {\n p.log.error('Not in a git repository')\n process.exit(1)\n }\n\n // Load or create global config first\n let config = loadThoughtsConfig(options)\n\n // If no config exists, we need to set it up first\n if (!config) {\n p.intro(chalk.blue('Initial Thoughts Setup'))\n\n p.log.info(\"First, let's configure your global thoughts system.\")\n\n // Get thoughts repository location\n const defaultRepo = getDefaultThoughtsRepo()\n p.log.message(\n chalk.gray('This is where all your thoughts across all projects will be stored.'),\n )\n\n const thoughtsRepoInput = await p.text({\n message: 'Thoughts repository location:',\n initialValue: defaultRepo,\n placeholder: defaultRepo,\n })\n\n if (p.isCancel(thoughtsRepoInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n const thoughtsRepo = (thoughtsRepoInput as string) || defaultRepo\n\n // Get directory names\n p.log.message(chalk.gray('Your thoughts will be organized into two main directories:'))\n p.log.message(chalk.gray('- Repository-specific thoughts (one subdirectory per project)'))\n p.log.message(chalk.gray('- Global thoughts (shared across all projects)'))\n\n const reposDirInput = await p.text({\n message: 'Directory name for repository-specific thoughts:',\n initialValue: 'repos',\n placeholder: 'repos',\n })\n\n if (p.isCancel(reposDirInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n const reposDir = (reposDirInput as string) || 'repos'\n\n const globalDirInput = await p.text({\n message: 'Directory name for global thoughts:',\n initialValue: 'global',\n placeholder: 'global',\n })\n\n if (p.isCancel(globalDirInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n const globalDir = (globalDirInput as string) || 'global'\n\n // Get user name\n const defaultUser = process.env.USER || 'user'\n let user = ''\n while (!user || user.toLowerCase() === 'global') {\n const userInput = await p.text({\n message: 'Your username:',\n initialValue: defaultUser,\n placeholder: defaultUser,\n validate: value => {\n if (value.toLowerCase() === 'global') {\n return 'Username cannot be \"global\" as it\\'s reserved for cross-project thoughts.'\n }\n return undefined\n },\n })\n\n if (p.isCancel(userInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n user = (userInput as string) || defaultUser\n }\n\n config = {\n thoughtsRepo,\n reposDir,\n globalDir,\n user,\n repoMappings: {},\n }\n\n // Show what will be created\n p.note(\n `${chalk.cyan(thoughtsRepo)}/\\n` +\n ` ├── ${chalk.cyan(reposDir)}/ ${chalk.gray('(project-specific thoughts)')}\\n` +\n ` └── ${chalk.cyan(globalDir)}/ ${chalk.gray('(cross-project thoughts)')}`,\n 'Creating thoughts structure',\n )\n\n // Ensure thoughts repo exists\n ensureThoughtsRepoExists(thoughtsRepo, reposDir, globalDir)\n\n // Save initial config\n saveThoughtsConfig(config, options)\n p.log.success('Global thoughts configuration created')\n }\n\n // Validate profile if specified\n if (options.profile) {\n if (!validateProfile(config, options.profile)) {\n p.log.error(`Profile \"${options.profile}\" does not exist.`)\n p.log.message(chalk.gray('Available profiles:'))\n if (config.profiles) {\n Object.keys(config.profiles).forEach(name => {\n p.log.message(chalk.gray(` - ${name}`))\n })\n } else {\n p.log.message(chalk.gray(' (none)'))\n }\n p.log.warn('Create a profile first:')\n p.log.message(chalk.gray(` thoughtcabinet profile create ${options.profile}`))\n process.exit(1)\n }\n }\n\n // Resolve profile config early so we use the right thoughtsRepo throughout\n // Create a temporary mapping to resolve the profile (will be updated later with actual mapping)\n const tempProfileConfig =\n options.profile && config.profiles && config.profiles[options.profile]\n ? {\n thoughtsRepo: config.profiles[options.profile].thoughtsRepo,\n reposDir: config.profiles[options.profile].reposDir,\n globalDir: config.profiles[options.profile].globalDir,\n profileName: options.profile,\n }\n : {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n profileName: undefined,\n }\n\n // Now check for existing setup in current repo\n const setupStatus = checkExistingSetup(config)\n\n if (setupStatus.exists && !options.force) {\n if (setupStatus.isValid) {\n p.log.warn('Thoughts directory already configured for this repository.')\n\n const reconfigure = await p.confirm({\n message: 'Do you want to reconfigure?',\n initialValue: false,\n })\n\n if (p.isCancel(reconfigure) || !reconfigure) {\n p.cancel('Setup cancelled.')\n return\n }\n } else {\n p.log.warn(setupStatus.message || 'Thoughts setup is incomplete')\n\n const fix = await p.confirm({\n message: 'Do you want to fix the setup?',\n initialValue: true,\n })\n\n if (p.isCancel(fix) || !fix) {\n p.cancel('Setup cancelled.')\n return\n }\n }\n }\n\n // Ensure thoughts repo still exists (might have been deleted)\n let expandedRepo = expandPath(tempProfileConfig.thoughtsRepo)\n if (!fs.existsSync(expandedRepo)) {\n p.log.error(`Thoughts repository not found at ${tempProfileConfig.thoughtsRepo}`)\n p.log.warn('The thoughts repository may have been moved or deleted.')\n\n const recreate = await p.confirm({\n message: 'Do you want to recreate it?',\n initialValue: true,\n })\n\n if (p.isCancel(recreate) || !recreate) {\n p.log.info('Please update your configuration or restore the thoughts repository.')\n process.exit(1)\n }\n ensureThoughtsRepoExists(\n tempProfileConfig.thoughtsRepo,\n tempProfileConfig.reposDir,\n tempProfileConfig.globalDir,\n )\n }\n\n // Map current repository\n const reposDir = path.join(expandedRepo, tempProfileConfig.reposDir)\n\n // Ensure repos directory exists\n if (!fs.existsSync(reposDir)) {\n fs.mkdirSync(reposDir, { recursive: true })\n }\n\n // Get existing repo directories\n const existingRepos = fs.readdirSync(reposDir).filter(name => {\n const fullPath = path.join(reposDir, name)\n return fs.statSync(fullPath).isDirectory() && !name.startsWith('.')\n })\n\n // Check if current repo is already mapped\n const existingMapping = config.repoMappings[currentRepo]\n let mappedName = getRepoNameFromMapping(existingMapping)\n\n // 检测是否为 worktree,并查找主仓库的映射\n let mainRepoMapping: string | RepoMappingObject | undefined\n let mainRepoPath: string | null = null\n if (!mappedName) {\n mainRepoPath = getMainRepoPath()\n if (mainRepoPath && config.repoMappings[mainRepoPath]) {\n mainRepoMapping = config.repoMappings[mainRepoPath]\n }\n }\n\n if (!mappedName) {\n if (options.directory) {\n // Non-interactive mode with --directory option\n const sanitizedDir = sanitizeDirectoryName(options.directory)\n\n if (!existingRepos.includes(sanitizedDir)) {\n p.log.error(`Directory \"${sanitizedDir}\" not found in thoughts repository.`)\n p.log.error('In non-interactive mode (--directory), you must specify a directory')\n p.log.error('name that already exists in the thoughts repository.')\n p.log.warn('Available directories:')\n existingRepos.forEach(repo => p.log.message(chalk.gray(` - ${repo}`)))\n process.exit(1)\n }\n\n mappedName = sanitizedDir\n p.log.success(\n `Using existing: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${mappedName}`,\n )\n } else {\n // Interactive mode\n p.intro(chalk.blue('Repository Setup'))\n\n p.log.info(`Setting up thoughts for: ${chalk.cyan(currentRepo)}`)\n p.log.message(\n chalk.gray(\n `This will create a subdirectory in ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/`,\n ),\n )\n p.log.message(chalk.gray('to store thoughts specific to this repository.'))\n\n if (existingRepos.length > 0 || mainRepoMapping) {\n // 构建选项列表\n const selectOptions: Array<{ value: string; label: string }> = []\n let initialValue: string | undefined\n\n // 场景1: worktree 有主仓库映射 - 优先显示并默认选中\n const mainRepoMappedName = getRepoNameFromMapping(mainRepoMapping)\n if (mainRepoMappedName && existingRepos.includes(mainRepoMappedName)) {\n selectOptions.push({\n value: mainRepoMappedName,\n label: `Use existing: ${mainRepoMappedName} (from main repository)`,\n })\n initialValue = mainRepoMappedName\n }\n\n // 添加其他现有目录(排除已添加的主仓库映射)\n existingRepos\n .filter(repo => repo !== mainRepoMappedName)\n .forEach(repo => {\n selectOptions.push({ value: repo, label: `Use existing: ${repo}` })\n })\n\n // 创建新目录选项\n selectOptions.push({ value: '__create_new__', label: 'Create new directory' })\n\n // 场景2: 全新 repo(无 worktree 关联)- 默认选择创建新目录\n if (!initialValue) {\n initialValue = '__create_new__'\n }\n\n const selection = await p.select({\n message: 'Select or create a thoughts directory for this repository:',\n options: selectOptions,\n initialValue,\n })\n\n if (p.isCancel(selection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n if (selection === '__create_new__') {\n // Create new\n const defaultName = getRepoNameFromPath(currentRepo)\n p.log.message(\n chalk.gray(\n `This name will be used for the directory: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/[name]`,\n ),\n )\n\n const nameInput = await p.text({\n message: \"Directory name for this project's thoughts:\",\n initialValue: defaultName,\n placeholder: defaultName,\n })\n\n if (p.isCancel(nameInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n mappedName = (nameInput as string) || defaultName\n\n // Sanitize the name\n mappedName = sanitizeDirectoryName(mappedName)\n p.log.success(\n `Will create: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${mappedName}`,\n )\n } else {\n mappedName = selection as string\n\n // 如果选择了主仓库的目录,继承其 profile\n if (mainRepoMapping && mappedName === mainRepoMappedName) {\n const inheritedProfile = getProfileNameFromMapping(mainRepoMapping)\n if (inheritedProfile && !options.profile) {\n options.profile = inheritedProfile\n p.log.info(`Inheriting profile \"${inheritedProfile}\" from main repository`)\n }\n }\n\n p.log.success(\n `Will use existing: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${mappedName}`,\n )\n }\n } else {\n // No existing repos and no worktree mapping, just create new\n const defaultName = getRepoNameFromPath(currentRepo)\n p.log.message(\n chalk.gray(\n `This name will be used for the directory: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/[name]`,\n ),\n )\n\n const nameInput = await p.text({\n message: \"Directory name for this project's thoughts:\",\n initialValue: defaultName,\n placeholder: defaultName,\n })\n\n if (p.isCancel(nameInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n mappedName = (nameInput as string) || defaultName\n\n // Sanitize the name\n mappedName = sanitizeDirectoryName(mappedName)\n p.log.success(\n `Will create: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${mappedName}`,\n )\n }\n }\n\n // Update config with profile-aware mapping\n if (options.profile) {\n config.repoMappings[currentRepo] = {\n repo: mappedName,\n profile: options.profile,\n }\n } else {\n // Keep string format for backward compatibility\n config.repoMappings[currentRepo] = mappedName\n }\n saveThoughtsConfig(config, options)\n\n // 如果继承了 profile,需要刷新 expandedRepo 以用于后续的 git pull 操作\n const inheritedProfile = getProfileNameFromMapping(mainRepoMapping)\n if (inheritedProfile && options.profile === inheritedProfile && tempProfileConfig.profileName !== inheritedProfile) {\n const profileSettings = config.profiles?.[inheritedProfile]\n if (profileSettings) {\n expandedRepo = expandPath(profileSettings.thoughtsRepo)\n }\n }\n }\n\n // Ensure mappedName is resolved when mapping already existed\n if (!mappedName) {\n mappedName = getRepoNameFromMapping(config.repoMappings[currentRepo])!\n }\n\n // Resolve profile config for directory creation\n const profileConfig = resolveProfileForRepo(config, currentRepo)\n\n // Create directory structure using profile config\n createThoughtsDirectoryStructure(profileConfig, mappedName, config.user)\n\n // Create thoughts directory in current repo\n const thoughtsDir = path.join(currentRepo, 'thoughts')\n if (fs.existsSync(thoughtsDir)) {\n fs.rmSync(thoughtsDir, { recursive: true, force: true })\n }\n fs.mkdirSync(thoughtsDir)\n\n // Create symlinks - flipped structure for easier access\n const repoTarget = getRepoThoughtsPath(profileConfig, mappedName)\n const globalTarget = getGlobalThoughtsPath(profileConfig)\n\n // Direct symlinks to user and shared directories for repo-specific thoughts\n fs.symlinkSync(path.join(repoTarget, config.user), path.join(thoughtsDir, config.user), 'dir')\n fs.symlinkSync(path.join(repoTarget, 'shared'), path.join(thoughtsDir, 'shared'), 'dir')\n\n // Global directory as before\n fs.symlinkSync(globalTarget, path.join(thoughtsDir, 'global'), 'dir')\n\n // Check for other users and create symlinks\n const otherUsers = updateSymlinksForNewUsers(\n currentRepo,\n profileConfig,\n mappedName,\n config.user,\n )\n\n if (otherUsers.length > 0) {\n p.log.success(`Added symlinks for other users: ${otherUsers.join(', ')}`)\n }\n\n // Pull latest thoughts if remote exists\n if (pullThoughtsFromRemote(expandedRepo)) {\n p.log.success('Pulled latest thoughts from remote')\n }\n\n // Generate CLAUDE.md\n const claudeMd = generateClaudeMd({\n thoughtsRepo: profileConfig.thoughtsRepo,\n reposDir: profileConfig.reposDir,\n repoName: mappedName,\n user: config.user,\n })\n fs.writeFileSync(path.join(thoughtsDir, 'CLAUDE.md'), claudeMd)\n\n // Setup git hooks\n const hookResult = setupGitHooks(currentRepo)\n if (hookResult.updated.length > 0) {\n p.log.step(`Updated git hooks: ${hookResult.updated.join(', ')}`)\n }\n\n p.log.success('Thoughts setup complete!')\n\n // Summary note\n const structureText =\n `${chalk.cyan(currentRepo)}/\\n` +\n ` └── thoughts/\\n` +\n ` ├── ${config.user}/ ${chalk.gray(`→ ${profileConfig.thoughtsRepo}/${profileConfig.reposDir}/${mappedName}/${config.user}/`)}\\n` +\n ` ├── shared/ ${chalk.gray(`→ ${profileConfig.thoughtsRepo}/${profileConfig.reposDir}/${mappedName}/shared/`)}\\n` +\n ` └── global/ ${chalk.gray(`→ ${profileConfig.thoughtsRepo}/${profileConfig.globalDir}/`)}\\n` +\n ` ├── ${config.user}/ ${chalk.gray('(your cross-repo notes)')}\\n` +\n ` └── shared/ ${chalk.gray('(team cross-repo notes)')}`\n\n p.note(structureText, 'Repository structure created')\n\n p.note(\n `${chalk.green('✓')} Pre-commit hook: Prevents committing thoughts/\\n` +\n `${chalk.green('✓')} Post-commit hook: Auto-syncs thoughts after commits`,\n 'Protection enabled',\n )\n\n // Execute PostThoughtsInit hooks\n const hooksConfig = loadHooksConfig(currentRepo)\n const postInitHooks = getHooksForEvent(hooksConfig, 'PostThoughtsInit')\n\n if (postInitHooks.length > 0) {\n const hookInput = {\n hook_event_name: 'PostThoughtsInit' as const,\n cwd: currentRepo,\n thoughts_repo: profileConfig.thoughtsRepo,\n repos_dir: profileConfig.reposDir,\n global_dir: profileConfig.globalDir,\n mapped_name: mappedName,\n user: config.user,\n }\n\n const hookEnv = {\n THC_THOUGHTS_REPO: profileConfig.thoughtsRepo,\n THC_REPOS_DIR: profileConfig.reposDir,\n THC_GLOBAL_DIR: profileConfig.globalDir,\n THC_MAPPED_NAME: mappedName,\n THC_USER: config.user,\n }\n\n await executeHooks(postInitHooks, hookInput, hookEnv, true)\n }\n\n p.outro(\n chalk.gray('Next steps:\\n') +\n chalk.gray(\n ` 1. Run ${chalk.cyan('thoughtcabinet sync')} to create the searchable index\\n`,\n ) +\n chalk.gray(\n ` 2. Create markdown files in ${chalk.cyan(`thoughts/${config.user}/`)} for your notes\\n`,\n ) +\n chalk.gray(` 3. Your thoughts will sync automatically when you commit code\\n`) +\n chalk.gray(` 4. Run ${chalk.cyan('thoughtcabinet status')} to check sync status`),\n )\n } catch (error) {\n p.log.error(`Error during thoughts init: ${error}`)\n process.exit(1)\n }\n}\n","import dotenv from 'dotenv'\nimport fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\n\n// Load environment variables\ndotenv.config()\n\nexport type RepoMappingObject = {\n repo: string\n profile?: string\n}\n\nexport type ProfileConfig = {\n thoughtsRepo: string\n reposDir: string\n globalDir: string\n}\n\nexport type ConfigFile = {\n thoughts?: {\n thoughtsRepo: string\n reposDir: string\n globalDir: string\n user: string\n repoMappings: Record<string, string | RepoMappingObject>\n profiles?: Record<string, ProfileConfig>\n commitRepoPrefix?: boolean\n }\n}\n\nexport class ConfigResolver {\n public static DEFAULT_CONFIG_FILE = 'config.json'\n public configFile: ConfigFile\n private configFilePath: string\n\n constructor(options: { configFile?: string } = {}) {\n this.configFile = this.loadConfigFile(options.configFile)\n this.configFilePath = this.getConfigFilePath(options.configFile)\n }\n\n loadConfigFile(configFile?: string): ConfigFile {\n if (configFile) {\n const configContent = fs.readFileSync(configFile, 'utf8')\n return JSON.parse(configContent)\n }\n\n // these do not merge today\n const configPaths = [ConfigResolver.DEFAULT_CONFIG_FILE, getDefaultConfigPath()]\n\n for (const configPath of configPaths) {\n try {\n if (fs.existsSync(configPath)) {\n const configContent = fs.readFileSync(configPath, 'utf8')\n return JSON.parse(configContent)\n }\n } catch (error) {\n console.error(chalk.yellow(`Warning: Could not parse config file ${configPath}: ${error}`))\n }\n }\n\n return {}\n }\n\n private getConfigFilePath(configFile?: string): string {\n if (configFile) return configFile\n\n const configPaths = [ConfigResolver.DEFAULT_CONFIG_FILE, getDefaultConfigPath()]\n for (const configPath of configPaths) {\n try {\n if (fs.existsSync(configPath)) {\n return configPath\n }\n } catch {\n // Continue to next path\n }\n }\n return getDefaultConfigPath() // fallback\n }\n}\n\nexport function loadConfigFile(configFile?: string): ConfigFile {\n const resolver = new ConfigResolver({ configFile })\n return resolver.loadConfigFile(configFile)\n}\n\nexport function saveConfigFile(config: ConfigFile, configFile?: string): void {\n const configPath = configFile || getDefaultConfigPath()\n\n console.log(chalk.yellow(`Writing config to ${configPath}`))\n\n // Create directory if it doesn't exist\n const configDir = path.dirname(configPath)\n fs.mkdirSync(configDir, { recursive: true })\n\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2))\n\n console.log(chalk.green('Config saved successfully'))\n}\n\nexport function getDefaultConfigDir(): string {\n if (process.env.XDG_CONFIG_HOME) {\n return path.join(process.env.XDG_CONFIG_HOME, 'thought-cabinet')\n }\n return path.join(process.env.HOME || '', '.thought-cabinet')\n}\n\nexport function getLegacyConfigDir(): string {\n return path.join(process.env.HOME || '', '.config', 'thought-cabinet')\n}\n\nexport function resolveConfigDir(): string {\n const newDir = getDefaultConfigDir()\n const newConfigPath = path.join(newDir, ConfigResolver.DEFAULT_CONFIG_FILE)\n\n if (fs.existsSync(newConfigPath)) {\n return newDir\n }\n\n const legacyDir = getLegacyConfigDir()\n const legacyConfigPath = path.join(legacyDir, ConfigResolver.DEFAULT_CONFIG_FILE)\n\n if (fs.existsSync(legacyConfigPath)) {\n return legacyDir\n }\n\n // Neither exists — use new location for fresh installs\n return newDir\n}\n\nexport function getDefaultConfigPath(): string {\n return path.join(resolveConfigDir(), ConfigResolver.DEFAULT_CONFIG_FILE)\n}\n","import { ConfigResolver, saveConfigFile } from '../../../config.js'\nimport type { RepoMappingObject, ProfileConfig } from '../../../config.js'\n\n/**\n * Thoughts configuration interface\n */\nexport interface ThoughtsConfig {\n thoughtsRepo: string\n reposDir: string // Directory name within thoughtsRepo (e.g., \"repos\")\n globalDir: string // Directory name within thoughtsRepo (e.g., \"global\")\n user: string\n repoMappings: Record<string, string | RepoMappingObject>\n profiles?: Record<string, ProfileConfig>\n commitRepoPrefix?: boolean\n}\n\n/**\n * Resolved profile configuration interface\n */\nexport interface ResolvedProfileConfig {\n thoughtsRepo: string\n reposDir: string\n globalDir: string\n profileName?: string // undefined for default config\n}\n\n/**\n * Load thoughts configuration from config file\n */\nexport function loadThoughtsConfig(options: Record<string, unknown> = {}): ThoughtsConfig | null {\n const resolver = new ConfigResolver(options)\n return resolver.configFile.thoughts || null\n}\n\n/**\n * Save thoughts configuration to config file\n */\nexport function saveThoughtsConfig(\n thoughtsConfig: ThoughtsConfig,\n options: Record<string, unknown> = {},\n): void {\n const resolver = new ConfigResolver(options)\n resolver.configFile.thoughts = thoughtsConfig\n saveConfigFile(resolver.configFile, options.configFile as string | undefined)\n}\n","import path from 'path'\nimport os from 'os'\nimport type { ResolvedProfileConfig } from './config.js'\nimport { getDefaultConfigDir } from '../../../config.js'\n\n// Re-export getMainRepoPath from git module for backward compatibility\nexport { getMainRepoPath } from '../../../git.js'\n\nexport function getDefaultThoughtsRepo(): string {\n return path.join(getDefaultConfigDir(), 'thoughts')\n}\n\nexport function expandPath(filePath: string): string {\n if (filePath.startsWith('~/')) {\n return path.join(os.homedir(), filePath.slice(2))\n }\n return path.resolve(filePath)\n}\n\nexport function getCurrentRepoPath(): string {\n return process.cwd()\n}\n\nexport function getRepoNameFromPath(repoPath: string): string {\n // Extract a reasonable name from the repo path\n const parts = repoPath.split(path.sep)\n return parts[parts.length - 1] || 'unnamed_repo'\n}\n\n// Overloaded signatures for getRepoThoughtsPath\nexport function getRepoThoughtsPath(config: ResolvedProfileConfig, repoName: string): string\nexport function getRepoThoughtsPath(\n thoughtsRepo: string,\n reposDir: string,\n repoName: string,\n): string\nexport function getRepoThoughtsPath(\n thoughtsRepoOrConfig: string | ResolvedProfileConfig,\n reposDirOrRepoName: string,\n repoName?: string,\n): string {\n if (typeof thoughtsRepoOrConfig === 'string') {\n // Legacy signature: (thoughtsRepo, reposDir, repoName)\n return path.join(expandPath(thoughtsRepoOrConfig), reposDirOrRepoName, repoName!)\n }\n\n // New signature: (config, repoName)\n const config = thoughtsRepoOrConfig\n return path.join(expandPath(config.thoughtsRepo), config.reposDir, reposDirOrRepoName)\n}\n\n// Overloaded signatures for getGlobalThoughtsPath\nexport function getGlobalThoughtsPath(config: ResolvedProfileConfig): string\nexport function getGlobalThoughtsPath(thoughtsRepo: string, globalDir: string): string\nexport function getGlobalThoughtsPath(\n thoughtsRepoOrConfig: string | ResolvedProfileConfig,\n globalDir?: string,\n): string {\n if (typeof thoughtsRepoOrConfig === 'string') {\n // Legacy signature: (thoughtsRepo, globalDir)\n return path.join(expandPath(thoughtsRepoOrConfig), globalDir!)\n }\n\n // New signature: (config)\n const config = thoughtsRepoOrConfig\n return path.join(expandPath(config.thoughtsRepo), config.globalDir)\n}\n\n","import { execFileSync } from 'child_process'\nimport path from 'path'\n\n// Types\nexport interface WorktreeEntry {\n worktreePath: string\n branch: string\n detached: boolean\n}\n\nexport interface GitRunOptions {\n cwd?: string\n}\n\n// Command execution\nexport function runGitCommand(args: string[], opts: GitRunOptions = {}): string {\n return execFileSync('git', args, {\n cwd: opts.cwd,\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'pipe'],\n }).trim()\n}\n\nexport function runGitCommandOrThrow(args: string[], opts: GitRunOptions = {}): void {\n execFileSync('git', args, {\n cwd: opts.cwd,\n stdio: 'inherit',\n })\n}\n\n// Repository detection\nexport function isGitRepo(cwd?: string): boolean {\n try {\n runGitCommand(['rev-parse', '--git-dir'], { cwd })\n return true\n } catch {\n return false\n }\n}\n\n/**\n * 获取当前 git 仓库的主仓库路径(处理 worktree 场景)\n * 如果当前目录是 worktree,返回主仓库路径;否则返回 null\n */\nexport function getMainRepoPath(cwd?: string): string | null {\n try {\n const gitCommonDir = runGitCommand(['rev-parse', '--git-common-dir'], { cwd })\n const gitDir = runGitCommand(['rev-parse', '--git-dir'], { cwd })\n\n if (gitCommonDir !== gitDir && gitCommonDir !== '.git') {\n const mainRepoPath = path.dirname(path.resolve(gitCommonDir))\n return mainRepoPath\n }\n\n return null\n } catch {\n return null\n }\n}\n\n// Worktree handle validation\nexport function validateWorktreeHandle(name: string): void {\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name)) {\n throw new Error(\n `Invalid worktree name '${name}'. Use only [A-Za-z0-9._-] and start with a letter/number.`,\n )\n }\n}\n\n// Worktree list parsing\nexport function parseWorktreeListPorcelain(output: string): WorktreeEntry[] {\n const blocks = output.trim().length === 0 ? [] : output.trim().split(/\\n\\n+/)\n const out: WorktreeEntry[] = []\n\n for (const block of blocks) {\n let worktreePath = ''\n let branch = ''\n let detached = false\n\n for (const line of block.split('\\n')) {\n if (line.startsWith('worktree ')) {\n worktreePath = line.slice('worktree '.length).trim()\n } else if (line.startsWith('branch refs/heads/')) {\n branch = line.slice('branch refs/heads/'.length).trim()\n } else if (line.trim() === 'detached') {\n detached = true\n branch = '(detached)'\n }\n }\n\n if (worktreePath && branch) {\n out.push({ worktreePath, branch, detached })\n }\n }\n\n return out\n}\n\n// Worktree operations\nexport function getMainWorktreeRoot(cwd?: string): string {\n const list = runGitCommand(['worktree', 'list', '--porcelain'], { cwd })\n const entries = parseWorktreeListPorcelain(list)\n if (entries.length === 0) {\n throw new Error('No git worktrees found')\n }\n return entries[0].worktreePath\n}\n\nexport function getWorktreesBaseDir(mainWorktreeRoot: string): string {\n const repoName = path.basename(mainWorktreeRoot)\n const parent = path.dirname(mainWorktreeRoot)\n return path.join(parent, `${repoName}__worktrees`)\n}\n\nexport function findWorktree(nameOrBranch: string, cwd?: string): WorktreeEntry {\n const list = runGitCommand(['worktree', 'list', '--porcelain'], { cwd })\n const entries = parseWorktreeListPorcelain(list)\n\n // 1) Match by handle (directory name)\n for (const e of entries) {\n if (path.basename(e.worktreePath) === nameOrBranch) {\n return e\n }\n }\n\n // 2) Match by branch name\n for (const e of entries) {\n if (e.branch === nameOrBranch) {\n return e\n }\n }\n\n throw new Error(`Worktree not found: ${nameOrBranch}`)\n}\n\n// Status checking\nexport function hasUncommittedChanges(repoPath: string): boolean {\n const status = runGitCommand(['status', '--porcelain'], { cwd: repoPath })\n return status.trim().length > 0\n}\n\nexport function hasUnmergedCommits(branch: string, targetBranch: string, cwd: string): boolean {\n try {\n const count = runGitCommand(['rev-list', '--count', `${targetBranch}..${branch}`], { cwd })\n return parseInt(count, 10) > 0\n } catch {\n // If comparison fails, assume there might be unmerged commits\n return true\n }\n}\n\nfunction branchExists(branch: string, cwd: string): boolean {\n try {\n runGitCommand(['rev-parse', '--verify', branch], { cwd })\n return true\n } catch {\n return false\n }\n}\n\nexport function getDefaultBranch(cwd: string): string {\n try {\n const remoteBranch = runGitCommand(['symbolic-ref', 'refs/remotes/origin/HEAD'], { cwd })\n return remoteBranch.replace('refs/remotes/origin/', '')\n } catch {\n // Remote HEAD not set, fall back to checking local branches\n }\n\n if (branchExists('main', cwd)) return 'main'\n if (branchExists('master', cwd)) return 'master'\n return 'main'\n}\n\n// Configuration\nexport function setBranchBase(branch: string, base: string, cwd?: string): void {\n runGitCommandOrThrow(['config', '--local', `branch.${branch}.thc-base`, base], { cwd })\n}\n\n// Branch and commit info\nexport function getCurrentBranch(cwd?: string): string {\n try {\n return runGitCommand(['branch', '--show-current'], { cwd })\n } catch {\n try {\n return runGitCommand(['rev-parse', '--abbrev-ref', 'HEAD'], { cwd })\n } catch {\n return ''\n }\n }\n}\n\nexport function getCurrentCommit(cwd?: string): string {\n try {\n return runGitCommand(['rev-parse', 'HEAD'], { cwd })\n } catch {\n return ''\n }\n}\n\nexport function getWorktreeRoot(cwd?: string): string {\n return runGitCommand(['rev-parse', '--show-toplevel'], { cwd })\n}\n\nexport function getRepoRoot(cwd?: string): string {\n // If in a worktree, return the main repo path\n const mainRepoPath = getMainRepoPath(cwd)\n if (mainRepoPath) {\n return mainRepoPath\n }\n // Otherwise return the current worktree root (which is the main repo)\n return getWorktreeRoot(cwd)\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport {\n generateGitignore,\n generateRepoReadme,\n generateGlobalReadme,\n} from '../../../templates/index.js'\nimport type { ResolvedProfileConfig } from './config.js'\nimport { expandPath, getRepoThoughtsPath, getGlobalThoughtsPath } from './paths.js'\n\n// Overloaded signatures for ensureThoughtsRepoExists\nexport function ensureThoughtsRepoExists(config: ResolvedProfileConfig): void\nexport function ensureThoughtsRepoExists(\n thoughtsRepo: string,\n reposDir: string,\n globalDir: string,\n): void\nexport function ensureThoughtsRepoExists(\n configOrThoughtsRepo: ResolvedProfileConfig | string,\n reposDir?: string,\n globalDir?: string,\n): void {\n let thoughtsRepo: string\n let effectiveReposDir: string\n let effectiveGlobalDir: string\n\n if (typeof configOrThoughtsRepo === 'string') {\n // Legacy signature: (thoughtsRepo, reposDir, globalDir)\n thoughtsRepo = configOrThoughtsRepo\n effectiveReposDir = reposDir!\n effectiveGlobalDir = globalDir!\n } else {\n // New signature: (config)\n thoughtsRepo = configOrThoughtsRepo.thoughtsRepo\n effectiveReposDir = configOrThoughtsRepo.reposDir\n effectiveGlobalDir = configOrThoughtsRepo.globalDir\n }\n\n const expandedRepo = expandPath(thoughtsRepo)\n\n // Create thoughts repo if it doesn't exist\n if (!fs.existsSync(expandedRepo)) {\n fs.mkdirSync(expandedRepo, { recursive: true })\n }\n\n // Create subdirectories\n const expandedRepos = path.join(expandedRepo, effectiveReposDir)\n const expandedGlobal = path.join(expandedRepo, effectiveGlobalDir)\n\n if (!fs.existsSync(expandedRepos)) {\n fs.mkdirSync(expandedRepos, { recursive: true })\n }\n\n if (!fs.existsSync(expandedGlobal)) {\n fs.mkdirSync(expandedGlobal, { recursive: true })\n }\n\n // Check if we're in a git repo (handle both .git directory and .git file for worktrees)\n const gitPath = path.join(expandedRepo, '.git')\n const isGitRepo =\n fs.existsSync(gitPath) && (fs.statSync(gitPath).isDirectory() || fs.statSync(gitPath).isFile())\n\n if (!isGitRepo) {\n // Initialize as git repo\n execSync('git init', { cwd: expandedRepo })\n\n // Create initial .gitignore\n const gitignore = generateGitignore()\n fs.writeFileSync(path.join(expandedRepo, '.gitignore'), gitignore)\n\n // Initial commit\n execSync('git add .gitignore', { cwd: expandedRepo })\n execSync('git commit -m \"Initial thoughts repository setup\"', { cwd: expandedRepo })\n }\n}\n\n// Overloaded signatures for createThoughtsDirectoryStructure\nexport function createThoughtsDirectoryStructure(\n config: ResolvedProfileConfig,\n repoName: string,\n user: string,\n): void\nexport function createThoughtsDirectoryStructure(\n thoughtsRepo: string,\n reposDir: string,\n globalDir: string,\n repoName: string,\n user: string,\n): void\nexport function createThoughtsDirectoryStructure(\n configOrThoughtsRepo: ResolvedProfileConfig | string,\n reposDirOrRepoName: string,\n globalDirOrUser: string,\n repoName?: string,\n user?: string,\n): void {\n let resolvedConfig: { thoughtsRepo: string; reposDir: string; globalDir: string }\n let effectiveRepoName: string\n let effectiveUser: string\n\n if (typeof configOrThoughtsRepo === 'string') {\n // Legacy signature: (thoughtsRepo, reposDir, globalDir, repoName, user)\n resolvedConfig = {\n thoughtsRepo: configOrThoughtsRepo,\n reposDir: reposDirOrRepoName,\n globalDir: globalDirOrUser,\n }\n effectiveRepoName = repoName!\n effectiveUser = user!\n } else {\n // New signature: (config, repoName, user)\n resolvedConfig = configOrThoughtsRepo\n effectiveRepoName = reposDirOrRepoName\n effectiveUser = globalDirOrUser\n }\n\n // Create repo-specific directories\n const repoThoughtsPath = getRepoThoughtsPath(\n resolvedConfig.thoughtsRepo,\n resolvedConfig.reposDir,\n effectiveRepoName,\n )\n const repoUserPath = path.join(repoThoughtsPath, effectiveUser)\n const repoSharedPath = path.join(repoThoughtsPath, 'shared')\n\n // Create global directories\n const globalPath = getGlobalThoughtsPath(resolvedConfig.thoughtsRepo, resolvedConfig.globalDir)\n const globalUserPath = path.join(globalPath, effectiveUser)\n const globalSharedPath = path.join(globalPath, 'shared')\n\n // Create all directories\n for (const dir of [repoUserPath, repoSharedPath, globalUserPath, globalSharedPath]) {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n }\n\n // Create initial README files\n const repoReadme = generateRepoReadme({\n repoName: effectiveRepoName,\n user: effectiveUser,\n })\n\n const globalReadme = generateGlobalReadme({\n user: effectiveUser,\n })\n\n if (!fs.existsSync(path.join(repoThoughtsPath, 'README.md'))) {\n fs.writeFileSync(path.join(repoThoughtsPath, 'README.md'), repoReadme)\n }\n\n if (!fs.existsSync(path.join(globalPath, 'README.md'))) {\n fs.writeFileSync(path.join(globalPath, 'README.md'), globalReadme)\n }\n}\n","/**\n * Generates .gitignore content for thoughts repository\n */\nexport function generateGitignore(): string {\n return `# OS files\n.DS_Store\nThumbs.db\n\n# Editor files\n.vscode/\n.idea/\n*.swp\n*.swo\n*~\n\n# Temporary files\n*.tmp\n*.bak\n`\n}\n","/**\n * Parameters for generating repository-specific README\n */\nexport interface RepoReadmeParams {\n repoName: string\n user: string\n}\n\n/**\n * Parameters for generating global README\n */\nexport interface GlobalReadmeParams {\n user: string\n}\n\n/**\n * Generates README.md content for repository-specific thoughts directory\n */\nexport function generateRepoReadme({ repoName, user }: RepoReadmeParams): string {\n return `# ${repoName} Thoughts\n\nThis directory contains thoughts and notes specific to the ${repoName} repository.\n\n- \\`${user}/\\` - Your personal notes for this repository\n- \\`shared/\\` - Team-shared notes for this repository\n`\n}\n\n/**\n * Generates README.md content for global thoughts directory\n */\nexport function generateGlobalReadme({ user }: GlobalReadmeParams): string {\n return `# Global Thoughts\n\nThis directory contains thoughts and notes that apply across all repositories.\n\n- \\`${user}/\\` - Your personal cross-repository notes\n- \\`shared/\\` - Team-shared cross-repository notes\n`\n}\n","import path from 'path'\nimport os from 'os'\n\n/**\n * Parameters for generating agent markdown documentation\n */\nexport interface AgentMdParams {\n thoughtsRepo: string\n reposDir: string\n repoName: string\n user: string\n productName: string // 'Claude Code' | 'CodeBuddy Code' | etc.\n}\n\n/**\n * Generates agent markdown content explaining the thoughts directory structure\n */\nexport function generateAgentMd({\n thoughtsRepo,\n reposDir,\n repoName,\n user,\n productName,\n}: AgentMdParams): string {\n const reposPath = path.join(thoughtsRepo, reposDir, repoName).replace(os.homedir(), '~')\n const globalPath = path.join(thoughtsRepo, 'global').replace(os.homedir(), '~')\n\n return `# Thoughts Directory Structure\n\nThis directory contains developer thoughts and notes for the ${repoName} repository.\nIt is managed by the ThoughtCabinet thoughts system and should not be committed to the code repository.\n\n## Structure\n\n- \\`${user}/\\` → Your personal notes for this repository (symlink to ${reposPath}/${user})\n- \\`shared/\\` → Team-shared notes for this repository (symlink to ${reposPath}/shared)\n- \\`global/\\` → Cross-repository thoughts (symlink to ${globalPath})\n - \\`${user}/\\` - Your personal notes that apply across all repositories\n - \\`shared/\\` - Team-shared notes that apply across all repositories\n- \\`searchable/\\` → Hard links for search tools (auto-generated)\n\n## Searching in Thoughts\n\nThe \\`searchable/\\` directory contains hard links to all thoughts files accessible in this repository. This allows search tools to find content without following symlinks.\n\n**IMPORTANT**:\n- Files in \\`thoughts/searchable/\\` are hard links to the original files (editing either updates both)\n- For clarity and consistency, always reference files by their canonical path (e.g., \\`thoughts/${user}/todo.md\\`, not \\`thoughts/searchable/${user}/todo.md\\`)\n- The \\`searchable/\\` directory is automatically updated when you run \\`thoughtcabinet sync\\`\n\nThis design ensures that:\n1. Search tools can find all your thoughts content easily\n2. The symlink structure remains intact for git operations\n3. Files remain editable while maintaining consistent path references\n\n## Usage\n\nCreate markdown files in these directories to document:\n\n- Architecture decisions\n- Design notes\n- TODO items\n- Investigation results\n- Any other development thoughts\n\nQuick access:\n\n- \\`thoughts/${user}/\\` for your repo-specific notes (most common)\n- \\`thoughts/global/${user}/\\` for your cross-repo notes\n\nThese files will be automatically synchronized with your thoughts repository when you commit code changes (when using ${productName}).\n\n## Important\n\n- Never commit the thoughts/ directory to your code repository\n- The git pre-commit hook will prevent accidental commits\n- Use \\`thoughtcabinet sync\\` to manually sync changes\n- Use \\`thoughtcabinet status\\` to see sync status\n`\n}\n\n/**\n * Legacy parameters for backward compatibility\n */\nexport interface ClaudeMdParams {\n thoughtsRepo: string\n reposDir: string\n repoName: string\n user: string\n}\n\n/**\n * Generates CLAUDE.md content (backward compatibility wrapper)\n */\nexport function generateClaudeMd(params: ClaudeMdParams): string {\n return generateAgentMd({ ...params, productName: 'Claude Code' })\n}\n\n/**\n * Generates CODEBUDDY.md content\n */\nexport function generateCodebuddyMd(params: ClaudeMdParams): string {\n return generateAgentMd({ ...params, productName: 'CodeBuddy Code' })\n}\n","/**\n * Current hook version - increment when hooks need updating\n */\nexport const HOOK_VERSION = '1'\n\n/**\n * Parameters for generating pre-commit hook\n */\nexport interface PreCommitHookParams {\n hookPath: string\n}\n\n/**\n * Parameters for generating post-commit hook\n */\nexport interface PostCommitHookParams {\n hookPath: string\n}\n\n/**\n * Generates pre-commit Git hook content to prevent committing thoughts directory\n */\nexport function generatePreCommitHook({ hookPath }: PreCommitHookParams): string {\n return `#!/bin/bash\n# ThoughtCabinet thoughts protection - prevent committing thoughts directory\n# Version: ${HOOK_VERSION}\n\nif git diff --cached --name-only | grep -q \"^thoughts/\"; then\n echo \"❌ Cannot commit thoughts/ to code repository\"\n echo \"The thoughts directory should only exist in your separate thoughts repository.\"\n git reset HEAD -- thoughts/\n exit 1\nfi\n\n# Call any existing pre-commit hook\nif [ -f \"${hookPath}.old\" ]; then\n \"${hookPath}.old\" \"$@\"\nfi\n`\n}\n\n/**\n * Generates post-commit Git hook content for auto-syncing thoughts\n */\nexport function generatePostCommitHook({ hookPath }: PostCommitHookParams): string {\n return `#!/bin/bash\n# ThoughtCabinet thoughts auto-sync\n# Version: ${HOOK_VERSION}\n\n# Check if we're in a worktree\nif [ -f .git ]; then\n # Skip auto-sync in worktrees to avoid repository boundary confusion\n exit 0\nfi\n\n# Get the commit message\nCOMMIT_MSG=$(git log -1 --pretty=%B)\n\n# Auto-sync thoughts after each commit (only in non-worktree repos)\nthoughtcabinet sync --message \"Auto-sync with commit: $COMMIT_MSG\" >/dev/null 2>&1 &\n\n# Call any existing post-commit hook\nif [ -f \"${hookPath}.old\" ]; then\n \"${hookPath}.old\" \"$@\"\nfi\n`\n}\n","import fs from 'fs'\nimport path from 'path'\nimport type { ResolvedProfileConfig } from './config.js'\nimport { getRepoThoughtsPath } from './paths.js'\n\n// Overloaded signatures for updateSymlinksForNewUsers\nexport function updateSymlinksForNewUsers(\n currentRepoPath: string,\n config: ResolvedProfileConfig,\n repoName: string,\n currentUser: string,\n): string[]\nexport function updateSymlinksForNewUsers(\n currentRepoPath: string,\n thoughtsRepo: string,\n reposDir: string,\n repoName: string,\n currentUser: string,\n): string[]\nexport function updateSymlinksForNewUsers(\n currentRepoPath: string,\n configOrThoughtsRepo: ResolvedProfileConfig | string,\n reposDirOrRepoName: string,\n repoNameOrCurrentUser: string,\n currentUser?: string,\n): string[] {\n let resolvedConfig: { thoughtsRepo: string; reposDir: string }\n let effectiveRepoName: string\n let effectiveUser: string\n\n if (typeof configOrThoughtsRepo === 'string') {\n // Legacy signature: (currentRepoPath, thoughtsRepo, reposDir, repoName, currentUser)\n resolvedConfig = {\n thoughtsRepo: configOrThoughtsRepo,\n reposDir: reposDirOrRepoName,\n }\n effectiveRepoName = repoNameOrCurrentUser\n effectiveUser = currentUser!\n } else {\n // New signature: (currentRepoPath, config, repoName, currentUser)\n resolvedConfig = configOrThoughtsRepo\n effectiveRepoName = reposDirOrRepoName\n effectiveUser = repoNameOrCurrentUser\n }\n\n const thoughtsDir = path.join(currentRepoPath, 'thoughts')\n const repoThoughtsPath = getRepoThoughtsPath(\n resolvedConfig.thoughtsRepo,\n resolvedConfig.reposDir,\n effectiveRepoName,\n )\n const addedSymlinks: string[] = []\n\n if (!fs.existsSync(thoughtsDir) || !fs.existsSync(repoThoughtsPath)) {\n return addedSymlinks\n }\n\n // Get all user directories in the repo thoughts\n const entries = fs.readdirSync(repoThoughtsPath, { withFileTypes: true })\n const userDirs = entries\n .filter(entry => entry.isDirectory() && entry.name !== 'shared' && !entry.name.startsWith('.'))\n .map(entry => entry.name)\n\n // Check each user directory and create symlinks if missing\n for (const userName of userDirs) {\n const symlinkPath = path.join(thoughtsDir, userName)\n const targetPath = path.join(repoThoughtsPath, userName)\n\n // Skip if symlink already exists or if it's the current user (already handled)\n if (!fs.existsSync(symlinkPath) && userName !== effectiveUser) {\n try {\n fs.symlinkSync(targetPath, symlinkPath, 'dir')\n addedSymlinks.push(userName)\n } catch {\n // Ignore errors - might be permission issues\n }\n }\n }\n\n return addedSymlinks\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport type { ThoughtsConfig } from './config.js'\nimport { getRepoNameFromMapping, getProfileNameFromMapping } from '../profile/utils.js'\n\nexport interface CleanupThoughtsOptions {\n repoPath: string\n config: ThoughtsConfig\n force?: boolean\n verbose?: boolean\n}\n\nexport interface CleanupThoughtsResult {\n thoughtsRemoved: boolean\n configRemoved: boolean\n mappedName?: string\n profileName?: string\n}\n\n/**\n * Clean up thoughts directory and configuration for a repository\n * Returns information about what was cleaned up\n */\nexport function cleanupThoughtsDirectory({\n repoPath,\n config,\n force = false,\n verbose = true,\n}: CleanupThoughtsOptions): CleanupThoughtsResult {\n const thoughtsDir = path.join(repoPath, 'thoughts')\n const result: CleanupThoughtsResult = {\n thoughtsRemoved: false,\n configRemoved: false,\n }\n\n // Check if thoughts directory exists\n if (!fs.existsSync(thoughtsDir)) {\n return result\n }\n\n const mapping = config.repoMappings[repoPath]\n const mappedName = getRepoNameFromMapping(mapping)\n const profileName = getProfileNameFromMapping(mapping)\n\n result.mappedName = mappedName\n result.profileName = profileName\n\n // Validate mapping unless force is specified\n if (!mappedName && !force) {\n return result\n }\n\n // Step 1: Remove searchable directory if it exists\n const searchableDir = path.join(thoughtsDir, 'searchable')\n if (fs.existsSync(searchableDir)) {\n if (verbose) {\n console.log(chalk.gray('Removing searchable directory...'))\n }\n fs.rmSync(searchableDir, { recursive: true, force: true })\n }\n\n // Step 2: Remove the entire thoughts directory\n if (verbose) {\n console.log(chalk.gray('Removing thoughts directory...'))\n }\n try {\n fs.rmSync(thoughtsDir, { recursive: true, force: true })\n result.thoughtsRemoved = true\n } catch (error) {\n if (verbose) {\n console.error(chalk.red(`Error removing thoughts directory: ${error}`))\n }\n throw error\n }\n\n // Step 3: Remove from config if mapped\n if (mappedName) {\n if (verbose) {\n console.log(chalk.gray('Removing repository from thoughts configuration...'))\n }\n delete config.repoMappings[repoPath]\n result.configRemoved = true\n }\n\n return result\n}\n","import type { RepoMappingObject } from '../../../config.js'\nimport type { ThoughtsConfig, ResolvedProfileConfig } from '../utils/config.js'\n\n/**\n * Resolves the profile config for a given repository path\n * Returns default config if no profile specified or profile not found\n */\nexport function resolveProfileForRepo(\n config: ThoughtsConfig,\n repoPath: string,\n): ResolvedProfileConfig {\n const mapping = config.repoMappings[repoPath]\n\n // Handle string format (legacy - no profile)\n if (typeof mapping === 'string') {\n return {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n profileName: undefined,\n }\n }\n\n // Handle object format\n if (mapping && typeof mapping === 'object') {\n const profileName = mapping.profile\n\n // If profile specified, look it up\n if (profileName && config.profiles && config.profiles[profileName]) {\n const profile = config.profiles[profileName]\n return {\n thoughtsRepo: profile.thoughtsRepo,\n reposDir: profile.reposDir,\n globalDir: profile.globalDir,\n profileName,\n }\n }\n\n // Object format but no profile or profile not found - use default\n return {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n profileName: undefined,\n }\n }\n\n // No mapping - use default\n return {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n profileName: undefined,\n }\n}\n\n/**\n * Gets the repo name from a mapping (handles both string and object formats)\n */\nexport function getRepoNameFromMapping(\n mapping: string | RepoMappingObject | undefined,\n): string | undefined {\n if (!mapping) return undefined\n if (typeof mapping === 'string') return mapping\n return mapping.repo\n}\n\n/**\n * Gets the profile name from a mapping (returns undefined for string format)\n */\nexport function getProfileNameFromMapping(\n mapping: string | RepoMappingObject | undefined,\n): string | undefined {\n if (!mapping) return undefined\n if (typeof mapping === 'string') return undefined\n return mapping.profile\n}\n\n/**\n * Validates that a profile exists in the configuration\n */\nexport function validateProfile(config: ThoughtsConfig, profileName: string): boolean {\n return !!(config.profiles && config.profiles[profileName])\n}\n\n/**\n * Sanitizes profile name (same rules as directory names)\n */\nexport function sanitizeProfileName(name: string): string {\n return name.replace(/[^a-zA-Z0-9_-]/g, '_')\n}\n","export interface ParsedGitUrl {\n host: string\n owner: string\n repo: string\n}\n\n/**\n * Parse a git remote URL into its components.\n *\n * Supports:\n * - SSH: git@github.com:owner/repo.git\n * - HTTPS: https://github.com/owner/repo.git\n * - SSH with protocol: ssh://git@github.com/owner/repo.git\n * - Git protocol: git://github.com/owner/repo.git\n *\n * Returns null if the URL cannot be parsed (e.g., local paths).\n */\nexport function parseGitRemoteUrl(url: string): ParsedGitUrl | null {\n // Strip trailing .git\n const cleaned = url.trim().replace(/\\.git\\/?$/, '')\n\n // SSH format: git@host:owner/repo\n const sshMatch = cleaned.match(/^[\\w-]+@([^:]+):(.+?)\\/([^/]+)$/)\n if (sshMatch) {\n return { host: sshMatch[1], owner: sshMatch[2], repo: sshMatch[3] }\n }\n\n // URL format: https://host/owner/repo or ssh://git@host/owner/repo\n try {\n // Normalize ssh://git@host to just extract host\n const normalized = cleaned\n .replace(/^ssh:\\/\\/[^@]+@/, 'https://')\n .replace(/^git:\\/\\//, 'https://')\n const parsed = new URL(normalized)\n const parts = parsed.pathname.replace(/^\\//, '').split('/')\n if (parts.length >= 2) {\n return { host: parsed.hostname, owner: parts[0], repo: parts[1] }\n }\n } catch {\n // Not a parseable URL\n }\n\n return null\n}\n\n/**\n * Build a browsable HTTPS URL for a file in a git repository.\n *\n * Most platforms (GitHub, GitLab, Gitea, Gogs) use:\n * https://host/owner/repo/blob/branch/path\n *\n * Bitbucket uses:\n * https://host/owner/repo/src/branch/path\n */\nexport function buildFileShareLink(\n parsed: ParsedGitUrl,\n branch: string,\n filePath: string,\n): string {\n const pathSegment = parsed.host.includes('bitbucket') ? 'src' : 'blob'\n const cleanPath = filePath.replace(/^\\//, '')\n return `https://${parsed.host}/${parsed.owner}/${parsed.repo}/${pathSegment}/${branch}/${cleanPath}`\n}\n","/**\n * Core initialization logic for thoughts directory setup.\n * This module contains reusable functions that can be called from both\n * the `thoughtcabinet init` command and `thc worktree add` command.\n */\n\nimport fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport {\n ResolvedProfileConfig,\n getRepoThoughtsPath,\n getGlobalThoughtsPath,\n updateSymlinksForNewUsers,\n expandPath,\n} from './utils/index.js'\nimport {\n generateClaudeMd,\n generatePreCommitHook,\n generatePostCommitHook,\n HOOK_VERSION,\n} from '../../templates/index.js'\n\nexport interface SetupThoughtsOptions {\n /** Code repository path */\n repoPath: string\n /** Resolved profile configuration */\n profileConfig: ResolvedProfileConfig\n /** Thoughts directory name in thoughts repo */\n mappedName: string\n /** Username */\n user: string\n /** Whether to create searchable directory */\n createSearchable?: boolean\n /** Whether to install git hooks */\n setupHooks?: boolean\n}\n\nexport interface SetupThoughtsResult {\n thoughtsDir: string\n otherUsers: string[]\n hooksUpdated: string[]\n}\n\n/**\n * Set up thoughts directory structure and symlinks.\n * Can be reused by init command and worktree add.\n */\nexport function setupThoughtsDirectory(options: SetupThoughtsOptions): SetupThoughtsResult {\n const { repoPath, profileConfig, mappedName, user, createSearchable = false, setupHooks = false } = options\n \n const thoughtsDir = path.join(repoPath, 'thoughts')\n \n // Remove existing thoughts directory if present\n if (fs.existsSync(thoughtsDir)) {\n fs.rmSync(thoughtsDir, { recursive: true, force: true })\n }\n fs.mkdirSync(thoughtsDir)\n \n // Create symlinks\n const repoTarget = getRepoThoughtsPath(profileConfig, mappedName)\n const globalTarget = getGlobalThoughtsPath(profileConfig)\n \n // Direct symlinks to user and shared directories for repo-specific thoughts\n fs.symlinkSync(path.join(repoTarget, user), path.join(thoughtsDir, user), 'dir')\n fs.symlinkSync(path.join(repoTarget, 'shared'), path.join(thoughtsDir, 'shared'), 'dir')\n \n // Global directory\n fs.symlinkSync(globalTarget, path.join(thoughtsDir, 'global'), 'dir')\n \n // Check for other users and create symlinks\n const otherUsers = updateSymlinksForNewUsers(\n repoPath,\n profileConfig,\n mappedName,\n user,\n )\n \n // Generate CLAUDE.md\n const claudeMd = generateClaudeMd({\n thoughtsRepo: profileConfig.thoughtsRepo,\n reposDir: profileConfig.reposDir,\n repoName: mappedName,\n user: user,\n })\n fs.writeFileSync(path.join(thoughtsDir, 'CLAUDE.md'), claudeMd)\n \n // Setup git hooks if requested\n let hooksUpdated: string[] = []\n if (setupHooks) {\n const hookResult = setupGitHooks(repoPath)\n hooksUpdated = hookResult.updated\n }\n \n // Create searchable index if requested\n if (createSearchable) {\n createSearchableIndex(thoughtsDir)\n }\n \n return {\n thoughtsDir,\n otherUsers,\n hooksUpdated,\n }\n}\n\n/**\n * Set up git hooks (pre-commit, post-commit).\n * Extracted from init.ts setupGitHooks().\n */\nexport function setupGitHooks(repoPath: string): { updated: string[] } {\n const updated: string[] = []\n \n // Use git rev-parse to find the common git directory for hooks (handles worktrees)\n // In worktrees, hooks are stored in the common git directory, not the worktree-specific one\n let gitCommonDir: string\n try {\n gitCommonDir = execSync('git rev-parse --git-common-dir', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n\n // If the path is relative, make it absolute\n if (!path.isAbsolute(gitCommonDir)) {\n gitCommonDir = path.join(repoPath, gitCommonDir)\n }\n } catch (error) {\n throw new Error(`Failed to find git common directory: ${error}`)\n }\n\n const hooksDir = path.join(gitCommonDir, 'hooks')\n\n // Ensure hooks directory exists (might not exist in some setups)\n if (!fs.existsSync(hooksDir)) {\n fs.mkdirSync(hooksDir, { recursive: true })\n }\n\n // Pre-commit hook\n const preCommitPath = path.join(hooksDir, 'pre-commit')\n const preCommitContent = generatePreCommitHook({ hookPath: preCommitPath })\n\n // Post-commit hook\n const postCommitPath = path.join(hooksDir, 'post-commit')\n const postCommitContent = generatePostCommitHook({ hookPath: postCommitPath })\n\n // Helper to check if hook needs updating\n const hookNeedsUpdate = (hookPath: string): boolean => {\n if (!fs.existsSync(hookPath)) return true\n const content = fs.readFileSync(hookPath, 'utf8')\n if (!content.includes('ThoughtCabinet thoughts')) return false // Not our hook\n\n // Check version\n const versionMatch = content.match(/# Version: (\\d+)/)\n if (!versionMatch) return true // Old hook without version\n\n const currentVersion = parseInt(versionMatch[1])\n return currentVersion < parseInt(HOOK_VERSION)\n }\n\n // Backup existing hooks if they exist and aren't ours (or need updating)\n if (fs.existsSync(preCommitPath)) {\n const content = fs.readFileSync(preCommitPath, 'utf8')\n if (!content.includes('ThoughtCabinet thoughts') || hookNeedsUpdate(preCommitPath)) {\n // Only backup non-ThoughtCabinet hooks to prevent recursion\n if (!content.includes('ThoughtCabinet thoughts')) {\n fs.renameSync(preCommitPath, `${preCommitPath}.old`)\n } else {\n // For outdated ThoughtCabinet hooks, just remove them\n fs.unlinkSync(preCommitPath)\n }\n }\n }\n\n if (fs.existsSync(postCommitPath)) {\n const content = fs.readFileSync(postCommitPath, 'utf8')\n if (!content.includes('ThoughtCabinet thoughts') || hookNeedsUpdate(postCommitPath)) {\n // Only backup non-ThoughtCabinet hooks to prevent recursion\n if (!content.includes('ThoughtCabinet thoughts')) {\n fs.renameSync(postCommitPath, `${postCommitPath}.old`)\n } else {\n // For outdated ThoughtCabinet hooks, just remove them\n fs.unlinkSync(postCommitPath)\n }\n }\n }\n\n // Write new hooks only if needed\n if (!fs.existsSync(preCommitPath) || hookNeedsUpdate(preCommitPath)) {\n fs.writeFileSync(preCommitPath, preCommitContent)\n fs.chmodSync(preCommitPath, '755')\n updated.push('pre-commit')\n }\n\n if (!fs.existsSync(postCommitPath) || hookNeedsUpdate(postCommitPath)) {\n fs.writeFileSync(postCommitPath, postCommitContent)\n fs.chmodSync(postCommitPath, '755')\n updated.push('post-commit')\n }\n\n return { updated }\n}\n\n/**\n * Create searchable directory with hard links.\n * Extracted from sync.ts createSearchDirectory().\n */\nexport function createSearchableIndex(thoughtsDir: string): number {\n const searchDir = path.join(thoughtsDir, 'searchable')\n \n // Remove existing searchable directory if it exists\n if (fs.existsSync(searchDir)) {\n fs.rmSync(searchDir, { recursive: true, force: true })\n }\n\n // Create new searchable directory\n fs.mkdirSync(searchDir, { recursive: true })\n\n // Function to recursively find all files through symlinks\n function findFilesFollowingSymlinks(\n dir: string,\n baseDir: string = dir,\n visited: Set<string> = new Set(),\n ): string[] {\n const files: string[] = []\n\n // Resolve symlinks to avoid cycles\n const realPath = fs.realpathSync(dir)\n if (visited.has(realPath)) {\n return files\n }\n visited.add(realPath)\n\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name)\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n files.push(...findFilesFollowingSymlinks(fullPath, baseDir, visited))\n } else if (entry.isSymbolicLink() && !entry.name.startsWith('.')) {\n try {\n const stat = fs.statSync(fullPath)\n if (stat.isDirectory()) {\n files.push(...findFilesFollowingSymlinks(fullPath, baseDir, visited))\n } else if (stat.isFile() && path.basename(fullPath) !== 'CLAUDE.md') {\n files.push(path.relative(baseDir, fullPath))\n }\n } catch {\n // Ignore broken symlinks\n }\n } else if (entry.isFile() && !entry.name.startsWith('.') && entry.name !== 'CLAUDE.md') {\n files.push(path.relative(baseDir, fullPath))\n }\n }\n\n return files\n }\n\n // Get all files accessible through the thoughts directory (following symlinks)\n const allFiles = findFilesFollowingSymlinks(thoughtsDir)\n\n // Create hard links in searchable directory\n let linkedCount = 0\n for (const relPath of allFiles) {\n const sourcePath = path.join(thoughtsDir, relPath)\n const targetPath = path.join(searchDir, relPath)\n\n // Create directory structure\n const targetDir = path.dirname(targetPath)\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true })\n }\n\n try {\n // Resolve symlink to get the real file path\n const realSourcePath = fs.realpathSync(sourcePath)\n // Create hard link to the real file\n fs.linkSync(realSourcePath, targetPath)\n linkedCount++\n } catch {\n // Silently skip files we can't link (e.g., different filesystems)\n }\n }\n\n return linkedCount\n}\n\n/**\n * Pull latest thoughts from remote.\n * Extracted from init.ts.\n */\nexport function pullThoughtsFromRemote(thoughtsRepo: string): boolean {\n const expandedRepo = expandPath(thoughtsRepo)\n \n try {\n // Check if remote exists\n execSync('git remote get-url origin', { cwd: expandedRepo, stdio: 'pipe' })\n \n // Remote exists, try to pull\n try {\n execSync('git pull --rebase', {\n stdio: 'pipe',\n cwd: expandedRepo,\n })\n return true\n } catch {\n return false\n }\n } catch {\n // No remote configured, skip pull\n return false\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport type { HooksConfig, HookEvent, Hook } from './types.js'\n\n/**\n * Default hooks configuration directory name\n */\nexport const HOOKS_CONFIG_DIR = '.thought-cabinet'\n\n/**\n * Default hooks configuration file name\n */\nexport const HOOKS_CONFIG_FILE = `${HOOKS_CONFIG_DIR}/hooks.json`\n\n/**\n * Load hooks configuration from repository root\n * @param repoPath - Path to repository\n * @returns Hooks configuration or null if not found\n */\nexport function loadHooksConfig(repoPath: string): HooksConfig | null {\n const configPath = path.join(repoPath, HOOKS_CONFIG_FILE)\n\n if (!fs.existsSync(configPath)) {\n return null\n }\n\n try {\n const content = fs.readFileSync(configPath, 'utf8')\n const config = JSON.parse(content) as HooksConfig\n\n // Basic validation\n if (!config.hooks || typeof config.hooks !== 'object') {\n console.error(\n chalk.yellow(`Warning: Invalid hooks config at ${configPath}: missing 'hooks' object`),\n )\n return null\n }\n\n return config\n } catch (error) {\n console.error(\n chalk.yellow(\n `Warning: Could not parse hooks config at ${configPath}: ${(error as Error).message}`,\n ),\n )\n return null\n }\n}\n\n/**\n * Get all hooks for a specific event\n * @param config - Hooks configuration\n * @param event - Hook event name\n * @returns Array of hooks to execute\n */\nexport function getHooksForEvent(config: HooksConfig | null, event: HookEvent): Hook[] {\n const hookGroups = config?.hooks[event]\n if (!hookGroups) {\n return []\n }\n\n return hookGroups.flatMap(group => group.hooks ?? [])\n}\n","import { spawn } from 'child_process'\nimport chalk from 'chalk'\nimport type { Hook, HookInput, HookExecutionResult } from './types.js'\n\n/**\n * Default timeout for hook execution (60 seconds)\n */\nconst DEFAULT_TIMEOUT_SECONDS = 60\n\n/**\n * Determine the exit code for a hook execution result\n */\nfunction resolveExitCode(exitCode: number | null, timedOut: boolean): number {\n if (exitCode !== null) {\n return exitCode\n }\n if (timedOut) {\n return 124 // Standard timeout exit code\n }\n return 1\n}\n\n/**\n * Execute a single hook\n * @param hook - Hook configuration\n * @param input - Hook input data (passed via stdin as JSON)\n * @param env - Additional environment variables\n * @returns Execution result\n */\nexport async function executeHook(\n hook: Hook,\n input: HookInput,\n env: Record<string, string> = {},\n): Promise<HookExecutionResult> {\n const startTime = Date.now()\n const timeoutMs = (hook.timeout ?? DEFAULT_TIMEOUT_SECONDS) * 1000\n\n return new Promise(resolve => {\n let stdout = ''\n let stderr = ''\n let timedOut = false\n\n const child = spawn('bash', ['-c', hook.command], {\n cwd: input.cwd,\n env: { ...process.env, ...env },\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n\n const timer = setTimeout(() => {\n timedOut = true\n child.kill('SIGTERM')\n\n // Force kill after 5 seconds if still running\n setTimeout(() => {\n if (!child.killed) {\n child.kill('SIGKILL')\n }\n }, 5000)\n }, timeoutMs)\n\n // Send input via stdin (hook may or may not consume it)\n child.stdin.write(JSON.stringify(input, null, 2))\n child.stdin.end()\n\n child.stdout.on('data', data => {\n stdout += data.toString()\n })\n\n child.stderr.on('data', data => {\n stderr += data.toString()\n })\n\n child.on('close', exitCode => {\n clearTimeout(timer)\n const duration = Date.now() - startTime\n\n resolve({\n success: exitCode === 0 && !timedOut,\n exitCode: resolveExitCode(exitCode, timedOut),\n stdout: stdout.trim(),\n stderr: stderr.trim(),\n timedOut,\n duration,\n })\n })\n\n child.on('error', error => {\n clearTimeout(timer)\n const duration = Date.now() - startTime\n\n resolve({\n success: false,\n exitCode: 1,\n stdout: stdout.trim(),\n stderr: `Failed to execute hook: ${error.message}`,\n timedOut: false,\n duration,\n })\n })\n })\n}\n\n/**\n * Display the result of a single hook execution\n */\nfunction displayHookResult(hook: Hook, result: HookExecutionResult, verbose: boolean): void {\n const timeoutSeconds = hook.timeout ?? DEFAULT_TIMEOUT_SECONDS\n\n if (result.timedOut) {\n console.log(chalk.yellow(`Warning: Hook timed out after ${timeoutSeconds}s: ${hook.command}`))\n if (result.stderr) {\n console.log(chalk.yellow(result.stderr))\n }\n return\n }\n\n switch (result.exitCode) {\n case 0:\n console.log(chalk.gray(`Hook completed (${result.duration}ms): ${hook.command}`))\n if (verbose && result.stdout) {\n console.log(chalk.gray(result.stdout))\n }\n break\n\n case 2:\n // Exit code 2: blocking error (always show stderr)\n console.log(chalk.red(`Hook failed with exit code 2: ${hook.command}`))\n if (result.stderr) {\n console.log(chalk.red(result.stderr))\n }\n break\n\n default:\n // Other exit codes: non-blocking error\n console.log(\n chalk.yellow(`Warning: Hook failed with exit code ${result.exitCode}: ${hook.command}`),\n )\n if (verbose && result.stderr) {\n console.log(chalk.yellow(result.stderr))\n }\n }\n}\n\n/**\n * Execute all hooks for an event in parallel\n * @param hooks - Array of hooks to execute\n * @param input - Hook input data\n * @param env - Additional environment variables\n * @param verbose - Show detailed output\n * @returns Array of execution results\n */\nexport async function executeHooks(\n hooks: Hook[],\n input: HookInput,\n env: Record<string, string> = {},\n verbose = false,\n): Promise<HookExecutionResult[]> {\n if (hooks.length === 0) {\n return []\n }\n\n if (verbose) {\n console.log(chalk.gray(`\\nExecuting ${hooks.length} hook(s) for ${input.hook_event_name}...`))\n }\n\n const results = await Promise.all(hooks.map(hook => executeHook(hook, input, env)))\n\n for (let i = 0; i < results.length; i++) {\n displayHookResult(hooks[i], results[i], verbose)\n }\n\n return results\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n getCurrentRepoPath,\n cleanupThoughtsDirectory,\n} from './utils/index.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\n\ninterface DestoryOptions {\n force?: boolean\n configFile?: string\n}\n\nexport async function thoughtsDestoryCommand(options: DestoryOptions): Promise<void> {\n try {\n const currentRepo = getCurrentRepoPath()\n const thoughtsDir = path.join(currentRepo, 'thoughts')\n\n // Check if thoughts directory exists\n if (!fs.existsSync(thoughtsDir)) {\n console.error(chalk.red('Error: Thoughts not initialized for this repository.'))\n process.exit(1)\n }\n\n // Load config\n const config = loadThoughtsConfig(options)\n if (!config) {\n console.error(chalk.red('Error: Thoughts configuration not found.'))\n process.exit(1)\n }\n\n // Check if repository is in config (unless force is specified)\n const mapping = config.repoMappings[currentRepo]\n if (!mapping && !options.force) {\n console.error(chalk.red('Error: This repository is not in the thoughts configuration.'))\n console.error(chalk.yellow('Use --force to remove the thoughts directory anyway.'))\n process.exit(1)\n }\n\n console.log(chalk.blue('Removing thoughts setup from current repository...'))\n\n // Use shared cleanup utility\n const result = cleanupThoughtsDirectory({\n repoPath: currentRepo,\n config,\n force: options.force,\n verbose: true,\n })\n\n // Save updated config\n if (result.configRemoved) {\n saveThoughtsConfig(config, options)\n }\n\n console.log(chalk.green('✅ Thoughts removed from repository'))\n\n // Provide info about what was done\n if (result.mappedName) {\n console.log('')\n console.log(chalk.gray('Note: Your thoughts content remains safe in:'))\n\n if (result.profileName && config.profiles && config.profiles[result.profileName]) {\n const profile = config.profiles[result.profileName]\n console.log(chalk.gray(` ${profile.thoughtsRepo}/${profile.reposDir}/${result.mappedName}`))\n console.log(chalk.gray(` (profile: ${result.profileName})`))\n } else {\n console.log(chalk.gray(` ${config.thoughtsRepo}/${config.reposDir}/${result.mappedName}`))\n }\n\n console.log(chalk.gray('Only the local symlinks and configuration were removed.'))\n }\n\n // Execute PostThoughtsDestroy hooks\n const hooksConfig = loadHooksConfig(currentRepo)\n const postDestroyHooks = getHooksForEvent(hooksConfig, 'PostThoughtsDestroy')\n\n if (postDestroyHooks.length > 0) {\n const hookInput = {\n hook_event_name: 'PostThoughtsDestroy' as const,\n cwd: currentRepo,\n thoughts_removed: result.thoughtsRemoved,\n config_removed: result.configRemoved,\n mapped_name: result.mappedName,\n profile_name: result.profileName,\n }\n\n const hookEnv = {\n THC_THOUGHTS_REMOVED: result.thoughtsRemoved ? 'true' : 'false',\n THC_CONFIG_REMOVED: result.configRemoved ? 'true' : 'false',\n THC_MAPPED_NAME: result.mappedName || '',\n THC_PROFILE_NAME: result.profileName || '',\n }\n\n await executeHooks(postDestroyHooks, hookInput, hookEnv, true)\n }\n } catch (error) {\n console.error(chalk.red(`Error during thoughts destroy: ${error}`))\n process.exit(1)\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { execSync, execFileSync } from 'child_process'\nimport chalk from 'chalk'\nimport {\n loadThoughtsConfig,\n getCurrentRepoPath,\n expandPath,\n getRepoNameFromPath,\n updateSymlinksForNewUsers,\n parseGitRemoteUrl,\n buildFileShareLink,\n} from './utils/index.js'\nimport { resolveProfileForRepo, getRepoNameFromMapping } from './profile/utils.js'\nimport { createSearchableIndex } from './init-core.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\n\ninterface SyncOptions {\n message?: string\n configFile?: string\n}\n\nfunction checkGitStatus(repoPath: string): boolean {\n try {\n const status = execSync('git status --porcelain', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n })\n return status.trim().length > 0\n } catch {\n return false\n }\n}\n\nfunction syncThoughts(thoughtsRepo: string, message: string, repoName?: string): void {\n const expandedRepo = expandPath(thoughtsRepo)\n\n try {\n // Stage all changes\n execSync('git add -A', { cwd: expandedRepo, stdio: 'pipe' })\n\n // Check if there are changes to commit\n const hasChanges = checkGitStatus(expandedRepo)\n\n if (hasChanges) {\n // Commit changes\n const defaultMessage = `Sync thoughts - ${new Date().toISOString()}`\n const body = message || defaultMessage\n const commitMessage = repoName ? `[${repoName}] ${body}` : body\n execFileSync('git', ['commit', '-m', commitMessage], { cwd: expandedRepo, stdio: 'pipe' })\n\n console.log(chalk.green('✅ Thoughts synchronized'))\n } else {\n console.log(chalk.gray('No changes to commit'))\n }\n\n // Pull latest changes after committing (to avoid conflicts with staged changes)\n try {\n execSync('git pull --rebase', {\n stdio: 'pipe',\n cwd: expandedRepo,\n })\n } catch (error) {\n const errorStr = error.toString()\n if (\n errorStr.includes('CONFLICT (') ||\n errorStr.includes('Automatic merge failed') ||\n errorStr.includes('Patch failed at') ||\n errorStr.includes('When you have resolved this problem, run \"git rebase --continue\"')\n ) {\n console.error(chalk.red('Error: Merge conflict detected in thoughts repository'))\n console.error(chalk.red('Please resolve conflicts manually in:'), expandedRepo)\n console.error(chalk.red('Then run \"git rebase --continue\" and \"thoughtcabinet sync\" again'))\n process.exit(1)\n } else {\n // If pull fails for other reasons, show warning but continue\n // This handles cases like no upstream, network issues, etc.\n console.warn(chalk.yellow('Warning: Could not pull latest changes:'), error.message)\n }\n }\n\n // Check if remote exists and push any unpushed commits\n try {\n execSync('git remote get-url origin', { cwd: expandedRepo, stdio: 'pipe' })\n\n // Try to push\n console.log(chalk.gray('Pushing to remote...'))\n try {\n execSync('git push', { cwd: expandedRepo, stdio: 'pipe' })\n console.log(chalk.green('✅ Pushed to remote'))\n\n // Generate share links for changed files\n try {\n const branch = execSync('git rev-parse --abbrev-ref HEAD', {\n cwd: expandedRepo,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n\n const changedFiles = execSync('git diff --name-only HEAD~1 HEAD', {\n cwd: expandedRepo,\n encoding: 'utf8',\n stdio: 'pipe',\n })\n .trim()\n .split('\\n')\n .filter(Boolean)\n\n const remoteUrl = execSync('git remote get-url origin', {\n cwd: expandedRepo,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n\n const parsed = parseGitRemoteUrl(remoteUrl)\n if (parsed && changedFiles.length > 0) {\n console.log(chalk.cyan('📎 Share links:'))\n for (const file of changedFiles) {\n const link = buildFileShareLink(parsed, branch, file)\n console.log(chalk.gray(` ${link}`))\n }\n }\n } catch {\n // Non-critical: don't fail sync if share link generation fails\n }\n } catch {\n console.log(chalk.yellow('⚠️ Could not push to remote. You may need to push manually.'))\n }\n } catch {\n // No remote configured\n console.log(chalk.yellow('ℹ️ No remote configured for thoughts repository'))\n }\n } catch (error) {\n console.error(chalk.red(`Error syncing thoughts: ${error}`))\n process.exit(1)\n }\n}\n\nexport async function thoughtsSyncCommand(options: SyncOptions): Promise<void> {\n try {\n // Check if thoughts are configured\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('Error: Thoughts not configured. Run \"thoughtcabinet init\" first.'))\n process.exit(1)\n }\n\n // Check if current repo has thoughts setup\n const currentRepo = getCurrentRepoPath()\n const thoughtsDir = path.join(currentRepo, 'thoughts')\n\n if (!fs.existsSync(thoughtsDir)) {\n console.error(chalk.red('Error: Thoughts not initialized for this repository.'))\n console.error('Run \"thoughtcabinet init\" to set up thoughts.')\n process.exit(1)\n }\n\n // Get current repo mapping and resolve profile\n const mapping = config.repoMappings[currentRepo]\n const mappedName = getRepoNameFromMapping(mapping)\n const profileConfig = resolveProfileForRepo(config, currentRepo)\n\n if (mappedName) {\n // Update symlinks for any new users using profile config\n const newUsers = updateSymlinksForNewUsers(\n currentRepo,\n profileConfig,\n mappedName,\n config.user,\n )\n\n if (newUsers.length > 0) {\n console.log(chalk.green(`✓ Added symlinks for new users: ${newUsers.join(', ')}`))\n }\n }\n\n // Create searchable directory with hard links\n console.log(chalk.blue('Creating searchable index...'))\n const linkedCount = createSearchableIndex(thoughtsDir)\n console.log(chalk.gray(`Created ${linkedCount} hard links in searchable directory`))\n\n // Sync the thoughts repository using profile's thoughtsRepo\n console.log(chalk.blue('Syncing thoughts...'))\n const repoName =\n config.commitRepoPrefix !== false\n ? mappedName || getRepoNameFromPath(currentRepo)\n : undefined\n syncThoughts(profileConfig.thoughtsRepo, options.message || '', repoName)\n\n // Execute PostThoughtsSync hooks\n const hooksConfig = loadHooksConfig(currentRepo)\n const postSyncHooks = getHooksForEvent(hooksConfig, 'PostThoughtsSync')\n\n if (postSyncHooks.length > 0) {\n const hookInput = {\n hook_event_name: 'PostThoughtsSync' as const,\n cwd: currentRepo,\n thoughts_repo: profileConfig.thoughtsRepo,\n has_changes: true,\n searchable_created: true,\n }\n\n const hookEnv = {\n THC_THOUGHTS_REPO: profileConfig.thoughtsRepo,\n THC_HAS_CHANGES: 'true',\n THC_SEARCHABLE_CREATED: 'true',\n }\n\n await executeHooks(postSyncHooks, hookInput, hookEnv, true)\n }\n } catch (error) {\n console.error(chalk.red(`Error during thoughts sync: ${error}`))\n process.exit(1)\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport chalk from 'chalk'\nimport { loadThoughtsConfig, getCurrentRepoPath, expandPath } from './utils/index.js'\nimport {\n getRepoNameFromMapping,\n getProfileNameFromMapping,\n resolveProfileForRepo,\n} from './profile/utils.js'\n\nfunction getGitStatus(repoPath: string): string {\n try {\n return execSync('git status -sb', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n return 'Not a git repository'\n }\n}\n\nfunction getUncommittedChanges(repoPath: string): string[] {\n try {\n const output = execSync('git status --porcelain', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n })\n\n return output\n .split('\\n')\n .filter(line => line.trim())\n .map(line => {\n const status = line.substring(0, 2)\n const file = line.substring(3)\n let statusText = ''\n\n if (status[0] === 'M' || status[1] === 'M') statusText = 'modified'\n else if (status[0] === 'A') statusText = 'added'\n else if (status[0] === 'D') statusText = 'deleted'\n else if (status[0] === '?') statusText = 'untracked'\n else if (status[0] === 'R') statusText = 'renamed'\n\n return ` ${chalk.yellow(statusText.padEnd(10))} ${file}`\n })\n } catch {\n return []\n }\n}\n\nfunction getLastCommit(repoPath: string): string {\n try {\n return execSync('git log -1 --pretty=format:\"%h %s (%cr)\"', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n return 'No commits yet'\n }\n}\n\nconst STALE_FETCH_THRESHOLD_HOURS = 6\n\nfunction getFetchAgeMs(repoPath: string): number | null {\n const fetchHead = path.join(repoPath, '.git', 'FETCH_HEAD')\n try {\n const stat = fs.statSync(fetchHead)\n return Date.now() - stat.mtimeMs\n } catch {\n return null\n }\n}\n\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000)\n if (seconds < 60) return `${seconds}s`\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${minutes}m`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${hours}h`\n const days = Math.floor(hours / 24)\n return `${days}d`\n}\n\nfunction getRemoteStatus(repoPath: string, doFetch: boolean): string {\n try {\n execSync('git remote get-url origin', { cwd: repoPath, stdio: 'pipe' })\n\n if (doFetch) {\n try {\n execSync('git fetch', { cwd: repoPath, stdio: 'pipe' })\n } catch {\n // Fetch might fail, continue anyway\n }\n }\n\n const status = execSync('git status -sb', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n })\n\n if (status.includes('ahead')) {\n const ahead = status.match(/ahead (\\d+)/)?.[1] || '?'\n return chalk.yellow(`${ahead} commits ahead of remote`)\n } else if (status.includes('behind')) {\n const behind = status.match(/behind (\\d+)/)?.[1] || '?'\n return chalk.yellow(`${behind} commits behind remote`)\n } else {\n return chalk.green('Up to date with remote')\n }\n } catch {\n return chalk.gray('No remote configured')\n }\n}\n\ninterface StatusOptions {\n configFile?: string\n fetch?: boolean\n maxAgeSecs?: string\n}\n\nexport async function thoughtsStatusCommand(options: StatusOptions): Promise<void> {\n try {\n // Check if thoughts are configured\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('Error: Thoughts not configured. Run \"thoughtcabinet init\" first.'))\n process.exit(1)\n }\n\n console.log(chalk.blue('Thoughts Repository Status'))\n console.log(chalk.gray('='.repeat(50)))\n console.log('')\n\n // Show configuration\n console.log(chalk.yellow('Configuration:'))\n console.log(` Repository: ${chalk.cyan(config.thoughtsRepo)}`)\n console.log(` Repos directory: ${chalk.cyan(config.reposDir)}`)\n console.log(` Global directory: ${chalk.cyan(config.globalDir)}`)\n console.log(` User: ${chalk.cyan(config.user)}`)\n console.log(` Mapped repos: ${chalk.cyan(Object.keys(config.repoMappings).length)}`)\n console.log('')\n\n // Check current repo mapping\n const currentRepo = getCurrentRepoPath()\n const currentMapping = config.repoMappings[currentRepo]\n const mappedName = getRepoNameFromMapping(currentMapping)\n const profileName = getProfileNameFromMapping(currentMapping)\n const profileConfig = resolveProfileForRepo(config, currentRepo)\n\n if (mappedName) {\n console.log(chalk.yellow('Current Repository:'))\n console.log(` Path: ${chalk.cyan(currentRepo)}`)\n console.log(` Thoughts directory: ${chalk.cyan(`${profileConfig.reposDir}/${mappedName}`)}`)\n\n // Add profile info\n if (profileName) {\n console.log(` Profile: ${chalk.cyan(profileName)}`)\n } else {\n console.log(` Profile: ${chalk.gray('(default)')}`)\n }\n\n const thoughtsDir = path.join(currentRepo, 'thoughts')\n if (fs.existsSync(thoughtsDir)) {\n console.log(` Status: ${chalk.green('✓ Initialized')}`)\n } else {\n console.log(` Status: ${chalk.red('✗ Not initialized')}`)\n }\n } else {\n console.log(chalk.yellow('Current repository not mapped to thoughts'))\n }\n console.log('')\n\n // Show thoughts repository git status using profile's thoughtsRepo\n const expandedRepo = expandPath(profileConfig.thoughtsRepo)\n\n console.log(chalk.yellow('Thoughts Repository Git Status:'))\n if (profileName) {\n console.log(chalk.gray(` (using profile: ${profileName})`))\n }\n console.log(` ${getGitStatus(expandedRepo)}`)\n\n const doFetch = options.fetch ?? false\n const staleThresholdMs =\n (parseInt(options.maxAgeSecs ?? '', 10) || STALE_FETCH_THRESHOLD_HOURS * 60 * 60) * 1000\n\n console.log(` Remote: ${getRemoteStatus(expandedRepo, doFetch)}`)\n\n if (!doFetch) {\n const fetchAgeMs = getFetchAgeMs(expandedRepo)\n if (fetchAgeMs === null) {\n console.log(chalk.gray(' (never fetched, use --fetch to refresh)'))\n } else if (fetchAgeMs > staleThresholdMs) {\n console.log(\n chalk.gray(` (last fetched ${formatDuration(fetchAgeMs)} ago, use --fetch to refresh)`),\n )\n }\n }\n\n console.log(` Last commit: ${getLastCommit(expandedRepo)}`)\n console.log('')\n\n // Show uncommitted changes\n const changes = getUncommittedChanges(expandedRepo)\n if (changes.length > 0) {\n console.log(chalk.yellow('Uncommitted changes:'))\n changes.forEach(change => console.log(change))\n console.log('')\n console.log(chalk.gray('Run \"thoughtcabinet sync\" to commit these changes'))\n } else {\n console.log(chalk.green('✓ No uncommitted changes'))\n }\n } catch (error) {\n console.error(chalk.red(`Error checking thoughts status: ${error}`))\n process.exit(1)\n }\n}\n","import { spawn } from 'child_process'\nimport chalk from 'chalk'\nimport { loadThoughtsConfig } from './utils/index.js'\nimport { getRepoNameFromMapping, getProfileNameFromMapping } from './profile/utils.js'\nimport { getDefaultConfigPath } from '../../config.js'\n\ninterface ConfigOptions {\n edit?: boolean\n json?: boolean\n configFile?: string\n}\n\nexport async function thoughtsConfigCommand(options: ConfigOptions): Promise<void> {\n try {\n const configPath = options.configFile || getDefaultConfigPath()\n\n // Handle edit mode\n if (options.edit) {\n const editor = process.env.EDITOR || 'vi'\n spawn(editor, [configPath], { stdio: 'inherit' })\n return\n }\n\n // Load configuration\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('No thoughts configuration found.'))\n console.error('Run \"thoughtcabinet init\" to create one.')\n process.exit(1)\n }\n\n // Handle JSON output\n if (options.json) {\n console.log(JSON.stringify(config, null, 2))\n return\n }\n\n // Display configuration\n console.log(chalk.blue('Thoughts Configuration'))\n console.log(chalk.gray('='.repeat(50)))\n console.log('')\n\n console.log(chalk.yellow('Settings:'))\n console.log(` Config file: ${chalk.cyan(configPath)}`)\n console.log(` Thoughts repository: ${chalk.cyan(config.thoughtsRepo)}`)\n console.log(` Repos directory: ${chalk.cyan(config.reposDir)}`)\n console.log(` Global directory: ${chalk.cyan(config.globalDir)}`)\n console.log(` User: ${chalk.cyan(config.user)}`)\n console.log('')\n\n console.log(chalk.yellow('Repository Mappings:'))\n const mappings = Object.entries(config.repoMappings)\n\n if (mappings.length === 0) {\n console.log(chalk.gray(' No repositories mapped yet'))\n } else {\n mappings.forEach(([repo, mapping]) => {\n const repoName = getRepoNameFromMapping(mapping)\n const profileName = getProfileNameFromMapping(mapping)\n\n console.log(` ${chalk.cyan(repo)}`)\n console.log(` → ${chalk.green(`${config.reposDir}/${repoName}`)}`)\n\n if (profileName) {\n console.log(` Profile: ${chalk.yellow(profileName)}`)\n } else {\n console.log(` Profile: ${chalk.gray('(default)')}`)\n }\n })\n }\n\n console.log('')\n\n // Add profiles section\n console.log(chalk.yellow('Profiles:'))\n if (!config.profiles || Object.keys(config.profiles).length === 0) {\n console.log(chalk.gray(' No profiles configured'))\n } else {\n Object.keys(config.profiles).forEach(name => {\n console.log(` ${chalk.cyan(name)}`)\n })\n }\n\n console.log('')\n console.log(chalk.gray('To edit configuration, run: thoughtcabinet config --edit'))\n } catch (error) {\n console.error(chalk.red(`Error showing thoughts config: ${error}`))\n process.exit(1)\n }\n}\n","import fs from 'fs'\nimport chalk from 'chalk'\nimport { loadThoughtsConfig, saveThoughtsConfig } from './utils/index.js'\nimport { getRepoNameFromMapping, getProfileNameFromMapping } from './profile/utils.js'\n\ninterface PruneOptions {\n apply?: boolean\n configFile?: string\n}\n\ninterface StaleEntry {\n repoPath: string\n mappedName: string | undefined\n profileName: string | undefined\n}\n\nexport async function thoughtsPruneCommand(options: PruneOptions): Promise<void> {\n try {\n // Load config\n const config = loadThoughtsConfig(options)\n if (!config) {\n console.error(chalk.red('Error: Thoughts configuration not found.'))\n console.error('Run \"thoughtcabinet init\" to create one.')\n process.exit(1)\n }\n\n const mappings = Object.entries(config.repoMappings)\n\n if (mappings.length === 0) {\n console.log(chalk.gray('No repository mappings configured.'))\n return\n }\n\n // Find stale entries (repo paths that no longer exist)\n const staleEntries: StaleEntry[] = []\n\n for (const [repoPath, mapping] of mappings) {\n if (!fs.existsSync(repoPath)) {\n staleEntries.push({\n repoPath,\n mappedName: getRepoNameFromMapping(mapping),\n profileName: getProfileNameFromMapping(mapping),\n })\n }\n }\n\n if (staleEntries.length === 0) {\n console.log(chalk.green('No stale repository mappings found.'))\n console.log(chalk.gray(`All ${mappings.length} mapped repositories exist.`))\n return\n }\n\n // Display stale entries\n console.log(chalk.yellow(`Found ${staleEntries.length} stale repository mapping(s):`))\n console.log('')\n\n for (const entry of staleEntries) {\n console.log(` ${chalk.red('✗')} ${chalk.cyan(entry.repoPath)}`)\n console.log(` → ${chalk.gray(entry.mappedName || '(unknown)')}`)\n if (entry.profileName) {\n console.log(` Profile: ${chalk.yellow(entry.profileName)}`)\n }\n }\n\n console.log('')\n\n // Apply changes if --apply flag is set\n if (options.apply) {\n console.log(chalk.blue('Removing stale entries from configuration...'))\n\n for (const entry of staleEntries) {\n delete config.repoMappings[entry.repoPath]\n }\n\n saveThoughtsConfig(config, options)\n\n console.log(chalk.green(`✅ Removed ${staleEntries.length} stale mapping(s).`))\n console.log('')\n console.log(chalk.gray('Note: The thoughts content in your thoughts repository was not modified.'))\n console.log(chalk.gray('Only the configuration entries pointing to non-existent directories were removed.'))\n } else {\n console.log(chalk.gray('This is a dry run. No changes were made.'))\n console.log(chalk.gray('Run with --apply to remove these stale entries.'))\n }\n } catch (error) {\n console.error(chalk.red(`Error during thoughts prune: ${error}`))\n process.exit(1)\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { getDefaultConfigDir, getLegacyConfigDir, ConfigResolver } from '../../config.js'\nimport type { RepoMappingObject } from '../../config.js'\nimport { expandPath } from './utils/paths.js'\nimport { loadThoughtsConfig } from './utils/config.js'\nimport { setupThoughtsDirectory } from './init-core.js'\nimport { resolveProfileForRepo, getRepoNameFromMapping } from './profile/utils.js'\nimport { createThoughtsDirectoryStructure } from './utils/repository.js'\nimport { getAllAgents } from '../agent/registry.js'\nimport { CATEGORY_SUBDIRS } from '../agent/constants.js'\nimport type { AgentConfig } from '../agent/types.js'\n\ninterface MigrateOptions {\n dryRun?: boolean\n configFile?: string\n}\n\nexport interface MoveEntry {\n from: string\n to: string\n label: string\n}\n\nexport interface MigrationPlan {\n moves: MoveEntry[]\n newConfigDir: string\n legacyConfigDir: string\n config: Record<string, unknown>\n affectedRepos: string[]\n}\n\n/**\n * Plan the migration from legacy config dir to new config dir.\n * Returns null if there's nothing to migrate or already at new location.\n * Pure function suitable for testing — no side effects beyond reading the filesystem.\n */\nexport function planMigration(homeDir?: string): MigrationPlan | null {\n const home = homeDir || process.env.HOME || ''\n const newConfigDir = path.join(home, '.thought-cabinet')\n const legacyConfigDir = path.join(home, '.config', 'thought-cabinet')\n const legacyConfigPath = path.join(legacyConfigDir, 'config.json')\n const newConfigPath = path.join(newConfigDir, 'config.json')\n\n // Already at new location\n if (fs.existsSync(newConfigPath)) {\n return null\n }\n\n // No legacy config to migrate\n if (!fs.existsSync(legacyConfigPath)) {\n return null\n }\n\n // Load old config\n let config: Record<string, unknown>\n try {\n config = JSON.parse(fs.readFileSync(legacyConfigPath, 'utf8'))\n } catch {\n return null\n }\n\n const thoughts = config.thoughts as\n | {\n thoughtsRepo?: string\n profiles?: Record<string, { thoughtsRepo: string }>\n repoMappings?: Record<string, unknown>\n }\n | undefined\n\n if (!thoughts) {\n return null\n }\n\n const moves: MoveEntry[] = []\n\n // 1. Config file\n moves.push({\n from: legacyConfigPath,\n to: path.join(newConfigDir, 'config.json'),\n label: 'Config file',\n })\n\n // 2. Agent assets\n for (const dir of ['agents', 'skills']) {\n const src = path.join(legacyConfigDir, dir)\n if (fs.existsSync(src)) {\n moves.push({\n from: src,\n to: path.join(newConfigDir, dir),\n label: `${dir}/ directory`,\n })\n }\n }\n\n // 3. Default thoughts repo\n if (thoughts.thoughtsRepo) {\n const expandedThoughtsRepo = expandPath(thoughts.thoughtsRepo)\n const newDefaultThoughtsRepo = path.join(newConfigDir, 'thoughts')\n if (\n fs.existsSync(expandedThoughtsRepo) &&\n expandedThoughtsRepo !== newDefaultThoughtsRepo &&\n !expandedThoughtsRepo.startsWith(newConfigDir + path.sep)\n ) {\n moves.push({\n from: expandedThoughtsRepo,\n to: newDefaultThoughtsRepo,\n label: `Default thoughts repo (${thoughts.thoughtsRepo})`,\n })\n }\n }\n\n // 4. Profile thoughts repos\n if (thoughts.profiles) {\n for (const [name, profile] of Object.entries(thoughts.profiles)) {\n const expandedProfileRepo = expandPath(profile.thoughtsRepo)\n const newProfileRepo = path.join(newConfigDir, `thoughts-${name}`)\n if (\n fs.existsSync(expandedProfileRepo) &&\n expandedProfileRepo !== newProfileRepo &&\n !expandedProfileRepo.startsWith(newConfigDir + path.sep)\n ) {\n moves.push({\n from: expandedProfileRepo,\n to: newProfileRepo,\n label: `Profile \"${name}\" thoughts repo (${profile.thoughtsRepo})`,\n })\n }\n }\n }\n\n // Collect affected repos\n const affectedRepos = thoughts.repoMappings ? Object.keys(thoughts.repoMappings) : []\n\n return {\n moves,\n newConfigDir,\n legacyConfigDir,\n config,\n affectedRepos,\n }\n}\n\n/**\n * Execute a migration plan: move files/dirs and update config paths.\n * Separated from planMigration for testability.\n */\nexport function executeMigration(plan: MigrationPlan): void {\n fs.mkdirSync(plan.newConfigDir, { recursive: true })\n\n for (const move of plan.moves) {\n const destDir = path.dirname(move.to)\n fs.mkdirSync(destDir, { recursive: true })\n fs.renameSync(move.from, move.to)\n }\n\n // Update config paths\n const thoughts = plan.config.thoughts as {\n thoughtsRepo?: string\n profiles?: Record<string, { thoughtsRepo: string }>\n }\n\n if (thoughts) {\n thoughts.thoughtsRepo = path.join(plan.newConfigDir, 'thoughts')\n\n if (thoughts.profiles) {\n for (const [name, profile] of Object.entries(thoughts.profiles)) {\n profile.thoughtsRepo = path.join(plan.newConfigDir, `thoughts-${name}`)\n }\n }\n }\n\n // Write updated config\n const newConfigPath = path.join(plan.newConfigDir, 'config.json')\n fs.writeFileSync(newConfigPath, JSON.stringify(plan.config, null, 2))\n}\n\nexport interface RefreshResult {\n refreshed: string[]\n skipped: string[]\n}\n\ninterface RefreshableConfig {\n thoughtsRepo: string\n reposDir: string\n globalDir: string\n user: string\n repoMappings: Record<string, string | RepoMappingObject>\n profiles?: Record<string, { thoughtsRepo: string; reposDir: string; globalDir: string }>\n}\n\n/**\n * Refresh thoughts/ symlinks in registered repos after migration.\n * Calls setupThoughtsDirectory() for each repo that exists on disk.\n */\nexport function refreshRepoSymlinks(\n config: RefreshableConfig,\n affectedRepos: string[],\n): RefreshResult {\n const refreshed: string[] = []\n const skipped: string[] = []\n\n for (const repoPath of affectedRepos) {\n if (!fs.existsSync(repoPath)) {\n skipped.push(repoPath)\n continue\n }\n\n const mapping = config.repoMappings[repoPath]\n const mappedName = getRepoNameFromMapping(mapping)\n if (!mappedName) {\n skipped.push(repoPath)\n continue\n }\n\n const profileConfig = resolveProfileForRepo(\n {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n user: config.user,\n repoMappings: config.repoMappings,\n profiles: config.profiles,\n },\n repoPath,\n )\n\n // Ensure target directories exist in thoughts repo\n createThoughtsDirectoryStructure(profileConfig, mappedName, config.user)\n\n // Rebuild thoughts/ symlinks\n setupThoughtsDirectory({\n repoPath,\n profileConfig,\n mappedName,\n user: config.user,\n })\n\n refreshed.push(repoPath)\n }\n\n return { refreshed, skipped }\n}\n\nexport interface AgentSymlinkRefreshResult {\n refreshed: number\n agents: string[]\n}\n\ntype AgentInfo = Pick<AgentConfig, 'displayName' | 'globalConfigDir'>\n\n/**\n * Refresh global agent asset symlinks that point into the legacy config dir.\n * Recreates them to point into the new config dir.\n */\nexport function refreshGlobalAgentSymlinks(\n legacyConfigDir: string,\n newConfigDir: string,\n agentList?: AgentInfo[],\n): AgentSymlinkRefreshResult {\n let refreshed = 0\n const agents: string[] = []\n const agentsToScan = agentList || getAllAgents()\n\n for (const agent of agentsToScan) {\n if (!agent.globalConfigDir) continue\n let agentTouched = false\n\n for (const category of Object.values(CATEGORY_SUBDIRS)) {\n const categoryDir = path.join(agent.globalConfigDir, category)\n if (!fs.existsSync(categoryDir)) continue\n\n const entries = fs.readdirSync(categoryDir, { withFileTypes: true })\n for (const entry of entries) {\n const entryPath = path.join(categoryDir, entry.name)\n\n // Only process symlinks\n let stats: fs.Stats\n try {\n stats = fs.lstatSync(entryPath)\n } catch {\n continue\n }\n if (!stats.isSymbolicLink()) continue\n\n // Read the symlink target and resolve to absolute\n const linkTarget = fs.readlinkSync(entryPath)\n const resolvedTarget = path.resolve(path.dirname(entryPath), linkTarget)\n\n // Check if it points into the legacy config dir\n if (\n !resolvedTarget.startsWith(legacyConfigDir + path.sep) &&\n resolvedTarget !== legacyConfigDir\n ) {\n continue\n }\n\n // Compute the equivalent path in the new config dir\n const relativeToCfg = path.relative(legacyConfigDir, resolvedTarget)\n const newTarget = path.join(newConfigDir, relativeToCfg)\n\n // Verify the new target exists\n if (!fs.existsSync(newTarget)) continue\n\n // Recreate the symlink with a relative path to the new target\n fs.unlinkSync(entryPath)\n const newRelative = path.relative(path.dirname(entryPath), newTarget)\n fs.symlinkSync(newRelative, entryPath)\n\n refreshed++\n agentTouched = true\n }\n }\n\n if (agentTouched) {\n agents.push(agent.displayName)\n }\n }\n\n return { refreshed, agents }\n}\n\n/**\n * Preview which global agent symlinks would be refreshed (read-only scan).\n * Used for dry-run display.\n */\nexport function previewGlobalAgentSymlinks(\n legacyConfigDir: string,\n agentList?: AgentInfo[],\n): string[] {\n const entries: string[] = []\n const agentsToScan = agentList || getAllAgents()\n\n for (const agent of agentsToScan) {\n if (!agent.globalConfigDir) continue\n\n for (const category of Object.values(CATEGORY_SUBDIRS)) {\n const categoryDir = path.join(agent.globalConfigDir, category)\n if (!fs.existsSync(categoryDir)) continue\n\n const dirEntries = fs.readdirSync(categoryDir, { withFileTypes: true })\n for (const entry of dirEntries) {\n const entryPath = path.join(categoryDir, entry.name)\n try {\n const stats = fs.lstatSync(entryPath)\n if (!stats.isSymbolicLink()) continue\n const linkTarget = fs.readlinkSync(entryPath)\n const resolvedTarget = path.resolve(path.dirname(entryPath), linkTarget)\n if (resolvedTarget.startsWith(legacyConfigDir + path.sep)) {\n entries.push(entryPath)\n }\n } catch {\n continue\n }\n }\n }\n }\n\n return entries\n}\n\n/**\n * Interactive migrate command entry point.\n */\nexport async function thoughtsMigrateCommand(options: MigrateOptions): Promise<void> {\n const newConfigDir = getDefaultConfigDir()\n const legacyConfigDir = getLegacyConfigDir()\n const newConfigPath = path.join(newConfigDir, ConfigResolver.DEFAULT_CONFIG_FILE)\n const legacyConfigPath = path.join(legacyConfigDir, ConfigResolver.DEFAULT_CONFIG_FILE)\n\n // Check if there's anything to migrate\n if (!fs.existsSync(legacyConfigPath)) {\n if (fs.existsSync(newConfigPath)) {\n p.log.info('Configuration is already at the new location.')\n return\n }\n p.log.info('No configuration found to migrate.')\n return\n }\n\n if (legacyConfigDir === newConfigDir) {\n p.log.info('Configuration is already at the expected location.')\n return\n }\n\n const plan = planMigration()\n\n if (!plan) {\n p.log.info('Nothing to migrate.')\n return\n }\n\n p.intro(chalk.blue('Migrate Thought Cabinet Configuration'))\n\n // Show plan\n p.log.step('Migration plan:')\n for (const move of plan.moves) {\n p.log.message(` ${move.label}`)\n p.log.message(chalk.gray(` ${move.from} → ${move.to}`))\n }\n\n if (options.dryRun) {\n // Show repo symlinks that would be refreshed\n if (plan.affectedRepos.length > 0) {\n p.log.step('Repo symlinks that would be refreshed:')\n for (const repo of plan.affectedRepos) {\n if (fs.existsSync(repo)) {\n p.log.message(chalk.gray(` ${repo}/thoughts/`))\n } else {\n p.log.message(chalk.gray(` ${repo}/thoughts/ (skipped — repo not found)`))\n }\n }\n }\n\n // Show agent symlinks that would be refreshed (scan without modifying)\n const agentPreview = previewGlobalAgentSymlinks(plan.legacyConfigDir)\n if (agentPreview.length > 0) {\n p.log.step('Global agent symlinks that would be refreshed:')\n for (const entry of agentPreview) {\n p.log.message(chalk.gray(` ${entry}`))\n }\n }\n\n p.log.info('Dry run — no changes made.')\n return\n }\n\n // Confirm\n const confirm = await p.confirm({\n message: 'Proceed with migration?',\n initialValue: true,\n })\n\n if (p.isCancel(confirm) || !confirm) {\n p.cancel('Migration cancelled.')\n return\n }\n\n // Execute\n executeMigration(plan)\n\n for (const move of plan.moves) {\n p.log.success(`Moved: ${move.label}`)\n }\n\n // Try to clean up old dir if empty\n try {\n const remaining = fs.readdirSync(plan.legacyConfigDir)\n if (remaining.length === 0) {\n fs.rmdirSync(plan.legacyConfigDir)\n p.log.info(`Removed empty directory: ${plan.legacyConfigDir}`)\n }\n } catch {\n // Ignore cleanup errors\n }\n\n // Refresh repo symlinks\n if (plan.affectedRepos.length > 0) {\n const config = loadThoughtsConfig({ configFile: path.join(plan.newConfigDir, 'config.json') })\n if (config) {\n p.log.step('Refreshing thoughts symlinks in registered repos...')\n const repoResult = refreshRepoSymlinks(config, plan.affectedRepos)\n for (const repo of repoResult.refreshed) {\n p.log.success(`Refreshed: ${repo}`)\n }\n for (const repo of repoResult.skipped) {\n p.log.warn(`Skipped (not found): ${repo}`)\n }\n }\n }\n\n // Refresh global agent symlinks\n p.log.step('Refreshing global agent symlinks...')\n const agentResult = refreshGlobalAgentSymlinks(plan.legacyConfigDir, plan.newConfigDir)\n if (agentResult.refreshed > 0) {\n p.log.success(\n `Refreshed ${agentResult.refreshed} symlink(s) for: ${agentResult.agents.join(', ')}`,\n )\n } else {\n p.log.info('No global agent symlinks needed updating.')\n }\n\n p.outro(chalk.green('Migration complete!'))\n}\n","import { homedir } from 'os'\nimport { join } from 'path'\nimport { existsSync } from 'fs'\nimport type { AgentType, AgentConfig } from './types.js'\n\nconst home = homedir()\nconst claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || join(home, '.claude')\n\n/**\n * Curated agent registry.\n * Each agent defines where its assets live at project and global scope.\n */\nexport const agents: Record<AgentType, AgentConfig> = {\n 'claude-code': {\n name: 'claude-code',\n displayName: 'Claude Code',\n configDir: '.claude',\n globalConfigDir: claudeHome,\n detectInstalled: async () => existsSync(claudeHome),\n },\n codebuddy: {\n name: 'codebuddy',\n displayName: 'CodeBuddy Code',\n configDir: '.codebuddy',\n globalConfigDir: join(home, '.codebuddy'),\n detectInstalled: async () =>\n existsSync(join(process.cwd(), '.codebuddy')) || existsSync(join(home, '.codebuddy')),\n },\n}\n\n/** Get agent config by type, throws if unknown */\nexport function getAgentConfig(type: AgentType): AgentConfig {\n const config = agents[type]\n if (!config) {\n const valid = Object.keys(agents).join(', ')\n throw new Error(`Unknown agent: ${type}. Valid agents: ${valid}`)\n }\n return config\n}\n\n/** Get all registered agents */\nexport function getAllAgents(): AgentConfig[] {\n return Object.values(agents)\n}\n\n/** Detect which agents are installed on this system */\nexport async function detectInstalledAgents(): Promise<AgentType[]> {\n const results = await Promise.all(\n Object.entries(agents).map(async ([type, config]) => ({\n type: type as AgentType,\n installed: await config.detectInstalled(),\n })),\n )\n return results.filter(r => r.installed).map(r => r.type)\n}\n\n/** Check if a given string is a valid AgentType */\nexport function isValidAgentType(value: string): value is AgentType {\n return value in agents\n}\n","/** Base directory for canonical agent asset storage */\nexport const AGENTS_DIR = '.agents'\n\n/** In-repo directory for canonical asset storage (project scope) */\nexport const CANONICAL_DIR = '.thought-cabinet'\n\n/** Subdirectory names for each asset category */\nexport const CATEGORY_SUBDIRS = {\n skills: 'skills',\n commands: 'commands',\n agents: 'agents',\n} as const\n\nexport type AssetCategory = keyof typeof CATEGORY_SUBDIRS\n","import chalk from 'chalk'\nimport path from 'path'\nimport * as p from '@clack/prompts'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n ensureThoughtsRepoExists,\n} from '../utils/index.js'\nimport { sanitizeProfileName, validateProfile } from './utils.js'\nimport { getDefaultConfigDir } from '../../../config.js'\nimport type { ProfileConfig } from '../../../config'\n\ninterface CreateOptions {\n repo?: string\n reposDir?: string\n globalDir?: string\n configFile?: string\n}\n\nexport async function profileCreateCommand(\n profileName: string,\n options: CreateOptions,\n): Promise<void> {\n try {\n // Check for non-interactive mode\n if (!options.repo || !options.reposDir || !options.globalDir) {\n if (!process.stdin.isTTY) {\n p.log.error('Not running in interactive terminal.')\n p.log.info('Provide all options: --repo, --repos-dir, --global-dir')\n process.exit(1)\n }\n }\n\n // Load existing config\n const config = loadThoughtsConfig(options as Record<string, unknown>)\n\n if (!config) {\n p.log.error('Thoughts not configured.')\n p.log.info('Run \"thoughtcabinet init\" first to set up the base configuration.')\n process.exit(1)\n }\n\n // Sanitize profile name\n const sanitizedName = sanitizeProfileName(profileName)\n if (sanitizedName !== profileName) {\n p.log.warn(`Profile name sanitized: \"${profileName}\" → \"${sanitizedName}\"`)\n }\n\n p.intro(chalk.blue(`Creating Profile: ${sanitizedName}`))\n\n // Check if profile already exists\n if (validateProfile(config, sanitizedName)) {\n p.log.error(`Profile \"${sanitizedName}\" already exists.`)\n p.log.info('Use a different name or delete the existing profile first.')\n process.exit(1)\n }\n\n // Get profile configuration\n let thoughtsRepo: string\n let reposDir: string\n let globalDir: string\n\n if (options.repo && options.reposDir && options.globalDir) {\n // Non-interactive mode\n thoughtsRepo = options.repo\n reposDir = options.reposDir\n globalDir = options.globalDir\n } else {\n // Interactive mode\n const defaultRepo = path.join(getDefaultConfigDir(), `thoughts-${sanitizedName}`)\n p.log.info('Specify the thoughts repository location for this profile.')\n\n const repoInput = await p.text({\n message: 'Thoughts repository:',\n initialValue: defaultRepo,\n placeholder: defaultRepo,\n })\n\n if (p.isCancel(repoInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n thoughtsRepo = (repoInput as string) || defaultRepo\n\n const reposDirInput = await p.text({\n message: 'Repository-specific thoughts directory:',\n initialValue: 'repos',\n placeholder: 'repos',\n })\n\n if (p.isCancel(reposDirInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n reposDir = (reposDirInput as string) || 'repos'\n\n const globalDirInput = await p.text({\n message: 'Global thoughts directory:',\n initialValue: 'global',\n placeholder: 'global',\n })\n\n if (p.isCancel(globalDirInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n globalDir = (globalDirInput as string) || 'global'\n }\n\n // Create profile config\n const profileConfig: ProfileConfig = {\n thoughtsRepo,\n reposDir,\n globalDir,\n }\n\n // Initialize profiles object if it doesn't exist\n if (!config.profiles) {\n config.profiles = {}\n }\n\n // Add profile\n config.profiles[sanitizedName] = profileConfig\n\n // Save config\n saveThoughtsConfig(config, options as Record<string, unknown>)\n\n // Create the profile's thoughts repository structure\n p.log.step('Initializing profile thoughts repository...')\n ensureThoughtsRepoExists(profileConfig)\n\n p.log.success(`Profile \"${sanitizedName}\" created successfully!`)\n\n p.note(\n `Name: ${chalk.cyan(sanitizedName)}\\n` +\n `Thoughts repository: ${chalk.cyan(thoughtsRepo)}\\n` +\n `Repos directory: ${chalk.cyan(reposDir)}\\n` +\n `Global directory: ${chalk.cyan(globalDir)}`,\n 'Profile Configuration',\n )\n\n p.outro(\n chalk.gray('Next steps:\\n') +\n chalk.gray(` 1. Run \"thoughtcabinet init --profile ${sanitizedName}\" in a repository\\n`) +\n chalk.gray(` 2. Your thoughts will sync to the profile's repository`),\n )\n } catch (error) {\n p.log.error(`Error creating profile: ${error}`)\n process.exit(1)\n }\n}\n","import chalk from 'chalk'\nimport { loadThoughtsConfig } from '../utils/index.js'\n\ninterface ListOptions {\n json?: boolean\n configFile?: string\n}\n\nexport async function profileListCommand(options: ListOptions): Promise<void> {\n try {\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('Error: Thoughts not configured.'))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify(config.profiles || {}, null, 2))\n return\n }\n\n console.log(chalk.blue('Thoughts Profiles'))\n console.log(chalk.gray('='.repeat(50)))\n console.log('')\n\n // Show default config\n console.log(chalk.yellow('Default Configuration:'))\n console.log(` Thoughts repository: ${chalk.cyan(config.thoughtsRepo)}`)\n console.log(` Repos directory: ${chalk.cyan(config.reposDir)}`)\n console.log(` Global directory: ${chalk.cyan(config.globalDir)}`)\n console.log('')\n\n // Show profiles\n if (!config.profiles || Object.keys(config.profiles).length === 0) {\n console.log(chalk.gray('No profiles configured.'))\n console.log('')\n console.log(chalk.gray('Create a profile with: thoughtcabinet profile create <name>'))\n } else {\n console.log(chalk.yellow(`Profiles (${Object.keys(config.profiles).length}):`))\n console.log('')\n\n Object.entries(config.profiles).forEach(([name, profile]) => {\n console.log(chalk.cyan(` ${name}:`))\n console.log(` Thoughts repository: ${profile.thoughtsRepo}`)\n console.log(` Repos directory: ${profile.reposDir}`)\n console.log(` Global directory: ${profile.globalDir}`)\n console.log('')\n })\n }\n } catch (error) {\n console.error(chalk.red(`Error listing profiles: ${error}`))\n process.exit(1)\n }\n}\n","import chalk from 'chalk'\nimport { loadThoughtsConfig } from '../utils/index.js'\nimport { validateProfile } from './utils.js'\n\ninterface ShowOptions {\n json?: boolean\n configFile?: string\n}\n\nexport async function profileShowCommand(profileName: string, options: ShowOptions): Promise<void> {\n try {\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('Error: Thoughts not configured.'))\n process.exit(1)\n }\n\n if (!validateProfile(config, profileName)) {\n console.error(chalk.red(`Error: Profile \"${profileName}\" not found.`))\n console.error('')\n console.error(chalk.gray('Available profiles:'))\n if (config.profiles) {\n Object.keys(config.profiles).forEach(name => {\n console.error(chalk.gray(` - ${name}`))\n })\n } else {\n console.error(chalk.gray(' (none)'))\n }\n process.exit(1)\n }\n\n const profile = config.profiles![profileName]\n\n if (options.json) {\n console.log(JSON.stringify(profile, null, 2))\n return\n }\n\n console.log(chalk.blue(`Profile: ${profileName}`))\n console.log(chalk.gray('='.repeat(50)))\n console.log('')\n console.log(chalk.yellow('Configuration:'))\n console.log(` Thoughts repository: ${chalk.cyan(profile.thoughtsRepo)}`)\n console.log(` Repos directory: ${chalk.cyan(profile.reposDir)}`)\n console.log(` Global directory: ${chalk.cyan(profile.globalDir)}`)\n console.log('')\n\n // Count repositories using this profile\n let repoCount = 0\n Object.values(config.repoMappings).forEach(mapping => {\n if (typeof mapping === 'object' && mapping.profile === profileName) {\n repoCount++\n }\n })\n\n console.log(chalk.yellow('Usage:'))\n console.log(` Repositories using this profile: ${chalk.cyan(repoCount)}`)\n } catch (error) {\n console.error(chalk.red(`Error showing profile: ${error}`))\n process.exit(1)\n }\n}\n","import chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { loadThoughtsConfig, saveThoughtsConfig } from '../utils/index.js'\nimport { validateProfile } from './utils.js'\n\ninterface DeleteOptions {\n force?: boolean\n configFile?: string\n}\n\nexport async function profileDeleteCommand(\n profileName: string,\n options: DeleteOptions,\n): Promise<void> {\n try {\n // Check for non-interactive mode\n if (!options.force && !process.stdin.isTTY) {\n p.log.error('Not running in interactive terminal.')\n p.log.info('Use --force flag to delete without confirmation.')\n process.exit(1)\n }\n\n p.intro(chalk.blue(`Delete Profile: ${profileName}`))\n\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n p.log.error('Thoughts not configured.')\n process.exit(1)\n }\n\n if (!validateProfile(config, profileName)) {\n p.log.error(`Profile \"${profileName}\" not found.`)\n process.exit(1)\n }\n\n // Check if any repositories are using this profile\n const usingRepos: string[] = []\n Object.entries(config.repoMappings).forEach(([repoPath, mapping]) => {\n if (typeof mapping === 'object' && mapping.profile === profileName) {\n usingRepos.push(repoPath)\n }\n })\n\n if (usingRepos.length > 0 && !options.force) {\n p.log.error(`Profile \"${profileName}\" is in use by ${usingRepos.length} repository(ies):`)\n usingRepos.forEach(repo => {\n p.log.message(chalk.gray(` - ${repo}`))\n })\n p.log.warn('Options:')\n p.log.message(chalk.gray(' 1. Run \"thoughtcabinet destroy\" in each repository'))\n p.log.message(\n chalk.gray(' 2. Use --force to delete anyway (repos will fall back to default config)'),\n )\n process.exit(1)\n }\n\n // Confirm deletion\n if (!options.force) {\n p.log.warn(`You are about to delete profile: ${chalk.cyan(profileName)}`)\n p.log.message(chalk.gray('This will remove the profile configuration.'))\n p.log.message(chalk.gray('The thoughts repository files will NOT be deleted.'))\n\n const confirmDelete = await p.confirm({\n message: `Delete profile \"${profileName}\"?`,\n initialValue: false,\n })\n\n if (p.isCancel(confirmDelete) || !confirmDelete) {\n p.cancel('Deletion cancelled.')\n return\n }\n }\n\n // Delete profile\n delete config.profiles![profileName]\n\n // If profiles is now empty, remove it entirely\n if (Object.keys(config.profiles!).length === 0) {\n delete config.profiles\n }\n\n // Save config\n saveThoughtsConfig(config, options)\n\n p.log.success(`Profile \"${profileName}\" deleted`)\n\n if (usingRepos.length > 0) {\n p.log.warn('Repositories using this profile will fall back to default config')\n }\n\n p.outro(chalk.green('Done'))\n } catch (error) {\n p.log.error(`Error deleting profile: ${error}`)\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport { thoughtsInitCommand } from './thoughts/init.js'\nimport { thoughtsDestoryCommand } from './thoughts/destroy.js'\nimport { thoughtsSyncCommand } from './thoughts/sync.js'\nimport { thoughtsStatusCommand } from './thoughts/status.js'\nimport { thoughtsConfigCommand } from './thoughts/config.js'\nimport { thoughtsPruneCommand } from './thoughts/prune.js'\nimport { thoughtsMigrateCommand } from './thoughts/migrate.js'\nimport { profileCreateCommand } from './thoughts/profile/create.js'\nimport { profileListCommand } from './thoughts/profile/list.js'\nimport { profileShowCommand } from './thoughts/profile/show.js'\nimport { profileDeleteCommand } from './thoughts/profile/delete.js'\n\nexport function thoughtsCommand(program: Command): void {\n const cmd = program\n\n cmd\n .command('init')\n .description('Initialize thoughts for current repository')\n .option('--force', 'Force reconfiguration even if already set up')\n .option('--config-file <path>', 'Path to config file')\n .option(\n '--directory <name>',\n 'Specify the repository directory name (skips interactive prompt)',\n )\n .option('--profile <name>', 'Use a specific thoughts profile')\n .action(thoughtsInitCommand)\n\n cmd\n .command('destroy')\n .description('Remove thoughts setup from current repository')\n .option('--force', 'Force removal even if not in configuration')\n .option('--config-file <path>', 'Path to config file')\n .action(thoughtsDestoryCommand)\n\n cmd\n .command('sync')\n .description('Manually sync thoughts to thoughts repository')\n .option('-m, --message <message>', 'Commit message for sync')\n .option('--config-file <path>', 'Path to config file')\n .action(thoughtsSyncCommand)\n\n cmd\n .command('status')\n .description('Show status of thoughts repository')\n .option('--config-file <path>', 'Path to config file')\n .option('--fetch', 'Fetch from remote before showing status')\n .action(thoughtsStatusCommand)\n\n cmd\n .command('config')\n .description('View or edit thoughts configuration')\n .option('--edit', 'Open configuration in editor')\n .option('--json', 'Output configuration as JSON')\n .option('--config-file <path>', 'Path to config file')\n .action(thoughtsConfigCommand)\n\n cmd\n .command('prune')\n .description('Remove stale repository mappings (directories that no longer exist)')\n .option('--apply', 'Apply changes (default is dry-run)')\n .option('--config-file <path>', 'Path to config file')\n .action(thoughtsPruneCommand)\n\n cmd\n .command('migrate')\n .description('Migrate configuration from ~/.config/thought-cabinet/ to ~/.thought-cabinet/')\n .option('--dry-run', 'Show what would be migrated without making changes')\n .option('--config-file <path>', 'Path to legacy config file')\n .action(thoughtsMigrateCommand)\n\n // Profile management commands\n const profile = cmd.command('profile').description('Manage thoughts profiles')\n\n profile\n .command('create <name>')\n .description('Create a new thoughts profile')\n .option('--repo <path>', 'Thoughts repository path')\n .option('--repos-dir <name>', 'Repos directory name')\n .option('--global-dir <name>', 'Global directory name')\n .option('--config-file <path>', 'Path to config file')\n .action(profileCreateCommand)\n\n profile\n .command('list')\n .description('List all thoughts profiles')\n .option('--json', 'Output as JSON')\n .option('--config-file <path>', 'Path to config file')\n .action(profileListCommand)\n\n profile\n .command('show <name>')\n .description('Show details of a specific profile')\n .option('--json', 'Output as JSON')\n .option('--config-file <path>', 'Path to config file')\n .action(profileShowCommand)\n\n profile\n .command('delete <name>')\n .description('Delete a thoughts profile')\n .option('--force', 'Force deletion even if in use')\n .option('--config-file <path>', 'Path to config file')\n .action(profileDeleteCommand)\n}\n","import { existsSync } from 'fs'\nimport { dirname, join, resolve } from 'path'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { fileURLToPath } from 'url'\nimport { cp, mkdir, readdir } from 'fs/promises'\nimport type { AgentType, AgentInitOptions, Asset, InstallMode, InstallScope } from './types.js'\nimport { agents } from './registry.js'\nimport { discoverAllAssets } from './discovery.js'\nimport { installAssetForAgent } from './installer.js'\nimport { getDefaultConfigDir } from '../../config.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst ASSET_CATEGORIES = ['agents', 'skills'] as const\n\n/** Find the bundled agent-assets directory relative to __dirname */\nexport function getBundledAssetsDir(): string | null {\n const candidates = [\n resolve(__dirname, '..', 'src', 'agent-assets'),\n resolve(__dirname, '..', '..', 'src', 'agent-assets'),\n resolve(__dirname, '..', '..', '..', 'src', 'agent-assets'),\n ]\n return candidates.find(dir => existsSync(dir)) ?? null\n}\n\n/**\n * Copy bundled assets to the config directory when it lacks agents/ and skills/ subdirectories.\n * Returns the config dir path on success, null if bundledDir is null.\n */\nexport async function bootstrapAssetsIfNeeded(\n configDir: string,\n bundledDir: string | null,\n): Promise<string | null> {\n if (!bundledDir) return null\n\n const hasAssets = ASSET_CATEGORIES.some(cat => existsSync(join(configDir, cat)))\n if (hasAssets) return configDir\n\n for (const category of ASSET_CATEGORIES) {\n const src = join(bundledDir, category)\n const dest = join(configDir, category)\n\n if (!existsSync(src)) continue\n await mkdir(dest, { recursive: true })\n\n const entries = await readdir(src, { withFileTypes: true })\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n await cp(join(src, entry.name), join(dest, entry.name), {\n recursive: true,\n force: false,\n errorOnExist: false,\n })\n }\n }\n\n return configDir\n}\n\n/**\n * Resolve the source directory for agent assets.\n * Priority: config dir (with asset subdirs) > bootstrap from bundled > bundled fallback.\n *\n * Optional configDir and bundledDir parameters override defaults for testability.\n */\nexport async function resolveSourceDir(\n configDir?: string,\n bundledDir?: string | null,\n): Promise<string | null> {\n const config = configDir ?? getDefaultConfigDir()\n const bundled = bundledDir === undefined ? getBundledAssetsDir() : bundledDir\n\n // Priority 1: config directory already has asset subdirectories\n const hasAssets = ASSET_CATEGORIES.some(cat => existsSync(join(config, cat)))\n if (hasAssets) return config\n\n // Priority 2: bootstrap bundled assets into config dir\n const bootstrapped = await bootstrapAssetsIfNeeded(config, bundled)\n if (bootstrapped) return bootstrapped\n\n // Priority 3: fall back to bundled assets directly\n return bundled\n}\n\n/** Resolve the agent's config directory based on scope */\nfunction resolveAgentBaseDir(agentType: AgentType, scope: InstallScope, cwd: string): string {\n const agent = agents[agentType]\n return scope === 'global' && agent.globalConfigDir\n ? agent.globalConfigDir\n : join(cwd, agent.configDir)\n}\n\nexport async function agentInitCommand(options: AgentInitOptions): Promise<void> {\n try {\n p.intro(chalk.blue('Install Skills & Agents'))\n\n const sourceDir = await resolveSourceDir()\n if (!sourceDir) {\n p.log.error('Agent assets not found.')\n p.log.info('Bundled agent assets not found. Are you running from the package?')\n process.exit(1)\n }\n\n const discovered = await discoverAllAssets(sourceDir)\n const totalAssets = discovered.agents.length + discovered.skills.length\n\n if (totalAssets === 0) {\n p.log.warn(`No assets found in ${sourceDir}`)\n process.exit(0)\n }\n\n // Deterministic defaults\n const selectedAgents: AgentType[] = options.agents ?? ['claude-code']\n const scope: InstallScope = options.scope ?? 'project'\n const mode: InstallMode = options.mode ?? 'symlink'\n const cwd = process.cwd()\n\n // Check for existing installations (prompt only if TTY and not --force)\n if (!options.force) {\n for (const agentType of selectedAgents) {\n const agentDir = resolveAgentBaseDir(agentType, scope, cwd)\n\n if (existsSync(agentDir) && process.stdin.isTTY) {\n const overwrite = await p.confirm({\n message: `${agents[agentType].displayName} directory already exists at ${agentDir}. Overwrite?`,\n initialValue: false,\n })\n\n if (p.isCancel(overwrite) || !overwrite) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n }\n }\n }\n\n // Install all assets\n const allAssets = [...discovered.skills, ...discovered.agents]\n\n interface InstallEntry {\n asset: Asset\n agentType: AgentType\n success: boolean\n symlinkFailed?: boolean\n error?: string\n }\n const results: InstallEntry[] = []\n\n for (const asset of allAssets) {\n for (const agentType of selectedAgents) {\n const result = await installAssetForAgent(asset, agentType, { scope, cwd, mode })\n results.push({\n asset,\n agentType,\n success: result.success,\n symlinkFailed: result.symlinkFailed,\n error: result.error,\n })\n }\n }\n\n // Print itemized list by category\n for (const category of ASSET_CATEGORIES) {\n const categoryResults = results.filter(r => r.asset.category === category)\n if (categoryResults.length === 0) continue\n\n const label = category.charAt(0).toUpperCase() + category.slice(1)\n p.log.step(chalk.bold(label))\n\n for (const entry of categoryResults) {\n if (entry.success && entry.symlinkFailed) {\n p.log.warn(` ⚠ ${entry.asset.name} (symlink failed, copied instead)`)\n } else if (entry.success) {\n p.log.success(` ✓ ${entry.asset.name}`)\n } else {\n p.log.error(` ✗ ${entry.asset.name}: ${entry.error}`)\n }\n }\n }\n\n // Summary\n const totalInstalled = results.filter(r => r.success).length\n const totalFailed = results.filter(r => !r.success).length\n const agentNames = selectedAgents.map(a => agents[a].displayName).join(', ')\n let message = `Installed ${totalInstalled} asset(s) to ${agentNames}`\n if (totalFailed > 0) {\n message += chalk.red(` (${totalFailed} failed)`)\n }\n message += chalk.gray(`\\n Scope: ${scope} | Mode: ${mode}`)\n\n p.outro(message)\n } catch (error) {\n p.log.error(`Error during agent init: ${error}`)\n process.exit(1)\n }\n}\n","import { readdir, readFile } from 'fs/promises'\nimport { join } from 'path'\nimport type { Asset } from './types.js'\n\n/** Parse SKILL.md frontmatter to extract name and description */\nexport function parseSkillFrontmatter(content: string): {\n name: string\n description: string\n} | null {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/)\n if (!match) return null\n\n const data: Record<string, string> = {}\n\n for (const line of match[1].split('\\n')) {\n const colonIndex = line.indexOf(':')\n if (colonIndex > 0) {\n const key = line.slice(0, colonIndex).trim()\n const value = line.slice(colonIndex + 1).trim()\n data[key] = value.replace(/^[\"']|[\"']$/g, '')\n }\n }\n\n if (!data.name || !data.description) return null\n\n return { name: data.name, description: data.description }\n}\n\n/** Discover skills from a directory (looks for subdirectories with SKILL.md) */\nexport async function discoverSkills(basePath: string): Promise<Asset[]> {\n const assets: Asset[] = []\n\n try {\n const entries = await readdir(basePath, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n\n const skillDir = join(basePath, entry.name)\n\n try {\n const content = await readFile(join(skillDir, 'SKILL.md'), 'utf-8')\n const parsed = parseSkillFrontmatter(content)\n\n assets.push({\n name: parsed?.name ?? entry.name,\n description: parsed?.description ?? '',\n sourcePath: skillDir,\n category: 'skills',\n isDirectory: true,\n })\n } catch {\n // No readable SKILL.md in this directory, skip\n }\n }\n } catch {\n // basePath doesn't exist or isn't readable\n }\n\n return assets\n}\n\n/** Discover agent/command directories containing markdown files */\nexport async function discoverMarkdownAssets(\n basePath: string,\n category: 'commands' | 'agents',\n): Promise<Asset[]> {\n const assets: Asset[] = []\n\n try {\n const entries = await readdir(basePath, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n\n const dirPath = join(basePath, entry.name)\n\n // Look for a .md file matching the directory name\n const mdFile = join(dirPath, `${entry.name}.md`)\n let description = ''\n try {\n const content = await readFile(mdFile, 'utf-8')\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/)\n if (match) {\n const descMatch = match[1].match(/description:\\s*(.+)/)\n if (descMatch) {\n description = descMatch[1].trim().replace(/^[\"']|[\"']$/g, '')\n }\n }\n } catch {\n // No matching .md file, skip this directory\n continue\n }\n\n assets.push({\n name: entry.name,\n description,\n sourcePath: dirPath,\n category,\n isDirectory: true,\n })\n }\n } catch {\n // basePath doesn't exist\n }\n\n return assets\n}\n\n/** Discover all assets from a source directory (expected layout: agents/, skills/) */\nexport async function discoverAllAssets(sourcePath: string): Promise<{\n agents: Asset[]\n skills: Asset[]\n}> {\n const [agents, skills] = await Promise.all([\n discoverMarkdownAssets(join(sourcePath, 'agents'), 'agents'),\n discoverSkills(join(sourcePath, 'skills')),\n ])\n\n return { agents, skills }\n}\n","import { mkdir, cp, readdir, symlink as fsSymlink, lstat, rm, readlink } from 'fs/promises'\nimport { join, basename, normalize, resolve, sep, relative, dirname } from 'path'\nimport { homedir, platform } from 'os'\nimport type { AgentType, Asset, InstallMode, InstallResult, InstallScope } from './types.js'\nimport type { AssetCategory } from './constants.js'\nimport { agents } from './registry.js'\nimport { CANONICAL_DIR, CATEGORY_SUBDIRS } from './constants.js'\n\nexport function sanitizeName(name: string): string {\n const sanitized = name\n .toLowerCase()\n .replace(/[^a-z0-9._]+/g, '-')\n .replace(/^[.-]+|[.-]+$/g, '')\n return sanitized.substring(0, 255) || 'unnamed-asset'\n}\n\nfunction isPathSafe(basePath: string, targetPath: string): boolean {\n const normalizedBase = normalize(resolve(basePath))\n const normalizedTarget = normalize(resolve(targetPath))\n return normalizedTarget.startsWith(normalizedBase + sep) || normalizedTarget === normalizedBase\n}\n\nexport function getAgentDir(\n agentType: AgentType,\n category: AssetCategory,\n scope: InstallScope,\n cwd?: string,\n): string {\n const agent = agents[agentType]\n const agentBase =\n scope === 'global' && agent.globalConfigDir\n ? agent.globalConfigDir\n : join(cwd || process.cwd(), agent.configDir)\n return join(agentBase, CATEGORY_SUBDIRS[category])\n}\n\nexport function getCanonicalDir(\n category: AssetCategory,\n scope: InstallScope,\n cwd?: string,\n): string {\n const baseDir = scope === 'global' ? homedir() : cwd || process.cwd()\n return join(baseDir, CANONICAL_DIR, CATEGORY_SUBDIRS[category])\n}\n\nasync function cleanAndCreateDirectory(dirPath: string): Promise<void> {\n try {\n await rm(dirPath, { recursive: true, force: true })\n } catch {\n // Ignore: directory may not exist\n }\n await mkdir(dirPath, { recursive: true })\n}\n\nasync function createSymlink(target: string, linkPath: string): Promise<boolean> {\n try {\n const resolvedTarget = resolve(target)\n const resolvedLinkPath = resolve(linkPath)\n\n if (resolvedTarget === resolvedLinkPath) {\n return true\n }\n\n // Remove existing entry at link path if present\n try {\n const stats = await lstat(linkPath)\n if (stats.isSymbolicLink()) {\n const existingTarget = await readlink(linkPath)\n const resolvedExisting = resolve(dirname(linkPath), existingTarget)\n if (resolvedExisting === resolvedTarget) {\n return true\n }\n await rm(linkPath)\n } else {\n await rm(linkPath, { recursive: true })\n }\n } catch (err: unknown) {\n const code = err && typeof err === 'object' && 'code' in err ? err.code : undefined\n if (code === 'ELOOP') {\n try {\n await rm(linkPath, { force: true })\n } catch {\n // Will fail at symlink creation below and trigger copy fallback\n }\n }\n }\n\n const linkDir = dirname(linkPath)\n await mkdir(linkDir, { recursive: true })\n\n const relativePath = relative(linkDir, target)\n const symlinkType = platform() === 'win32' ? 'junction' : undefined\n await fsSymlink(relativePath, linkPath, symlinkType)\n return true\n } catch {\n return false\n }\n}\n\nconst EXCLUDE_FILES = new Set(['README.md', 'metadata.json'])\nconst EXCLUDE_DIRS = new Set(['.git'])\n\nfunction isExcluded(name: string, isDirectory: boolean): boolean {\n if (name.startsWith('_')) return true\n return isDirectory ? EXCLUDE_DIRS.has(name) : EXCLUDE_FILES.has(name)\n}\n\nasync function copyDirectoryContents(src: string, dest: string): Promise<void> {\n await mkdir(dest, { recursive: true })\n const entries = await readdir(src, { withFileTypes: true })\n\n await Promise.all(\n entries\n .filter(entry => !isExcluded(entry.name, entry.isDirectory()))\n .map(async entry => {\n const srcPath = join(src, entry.name)\n const destPath = join(dest, entry.name)\n if (entry.isDirectory()) {\n await copyDirectoryContents(srcPath, destPath)\n } else {\n await cp(srcPath, destPath, { dereference: true, recursive: true })\n }\n }),\n )\n}\n\nexport async function installAssetForAgent(\n asset: Asset,\n agentType: AgentType,\n options: { scope?: InstallScope; cwd?: string; mode?: InstallMode } = {},\n): Promise<InstallResult> {\n const agent = agents[agentType]\n const scope = options.scope ?? 'project'\n const cwd = options.cwd || process.cwd()\n const installMode = options.mode ?? 'symlink'\n\n if (scope === 'global' && agent.globalConfigDir === undefined) {\n return {\n success: false,\n path: '',\n mode: installMode,\n error: `${agent.displayName} does not support global installation`,\n }\n }\n\n const assetName = sanitizeName(asset.name)\n\n const agentBase = getAgentDir(agentType, asset.category, scope, cwd)\n const agentDir = join(agentBase, assetName)\n\n // Guard against path traversal\n if (!isPathSafe(agentBase, agentDir)) {\n return {\n success: false,\n path: agentDir,\n mode: installMode,\n error: 'Invalid asset name: potential path traversal detected',\n }\n }\n\n try {\n const copyAsset = async (targetDir: string) => {\n if (asset.isDirectory) {\n await copyDirectoryContents(asset.sourcePath, targetDir)\n } else {\n await mkdir(targetDir, { recursive: true })\n const fileName = basename(asset.sourcePath)\n await cp(asset.sourcePath, join(targetDir, fileName), { dereference: true })\n }\n }\n\n if (installMode === 'copy') {\n await cleanAndCreateDirectory(agentDir)\n await copyAsset(agentDir)\n return { success: true, path: agentDir, mode: 'copy' }\n }\n\n // Symlink mode\n if (scope === 'project') {\n // Project scope: use in-repo intermediate to keep symlinks within repo\n const canonicalBase = getCanonicalDir(asset.category, scope, cwd)\n const canonicalDir = join(canonicalBase, assetName)\n\n await cleanAndCreateDirectory(canonicalDir)\n await copyAsset(canonicalDir)\n\n await rm(agentDir, { recursive: true, force: true })\n await mkdir(dirname(agentDir), { recursive: true })\n\n const symlinkCreated = await createSymlink(canonicalDir, agentDir)\n if (!symlinkCreated) {\n // Fallback to copy\n await cleanAndCreateDirectory(agentDir)\n await copyAsset(agentDir)\n return {\n success: true,\n path: agentDir,\n canonicalPath: canonicalDir,\n mode: 'symlink',\n symlinkFailed: true,\n }\n }\n\n return { success: true, path: agentDir, canonicalPath: canonicalDir, mode: 'symlink' }\n } else {\n // Global scope: direct symlink to source (both paths outside repo)\n await rm(agentDir, { recursive: true, force: true })\n await mkdir(dirname(agentDir), { recursive: true })\n\n const symlinkCreated = await createSymlink(asset.sourcePath, agentDir)\n if (!symlinkCreated) {\n // Fallback to copy\n await cleanAndCreateDirectory(agentDir)\n await copyAsset(agentDir)\n return { success: true, path: agentDir, mode: 'symlink', symlinkFailed: true }\n }\n\n return { success: true, path: agentDir, mode: 'symlink' }\n }\n } catch (error) {\n return {\n success: false,\n path: agentDir,\n mode: installMode,\n error: error instanceof Error ? error.message : 'Unknown error',\n }\n }\n}\n","import { existsSync } from 'fs'\nimport { join } from 'path'\nimport { cp, readdir, mkdir, rm, lstat } from 'fs/promises'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { getBundledAssetsDir } from './init.js'\nimport { getDefaultConfigDir, loadConfigFile } from '../../config.js'\nimport { discoverAllAssets } from './discovery.js'\nimport { installAssetForAgent } from './installer.js'\nimport { agents, getAllAgents } from './registry.js'\nimport { CATEGORY_SUBDIRS } from './constants.js'\nimport type { AgentType, InstallMode, InstallScope } from './types.js'\n\nconst ASSET_CATEGORIES = ['agents', 'skills'] as const\n\ninterface UpdateResult {\n seeded: string[]\n skipped: string[]\n}\n\n/**\n * Re-seed bundled assets into config dir, overwriting only those\n * that match bundled asset directory names.\n */\nexport async function updateBundledAssets(\n configDir: string,\n bundledDir: string,\n): Promise<UpdateResult> {\n const seeded: string[] = []\n const skipped: string[] = []\n\n for (const category of ASSET_CATEGORIES) {\n const bundledCategoryDir = join(bundledDir, category)\n const configCategoryDir = join(configDir, category)\n\n if (!existsSync(bundledCategoryDir)) continue\n await mkdir(configCategoryDir, { recursive: true })\n\n const bundledEntries = await readdir(bundledCategoryDir, { withFileTypes: true })\n\n for (const entry of bundledEntries) {\n if (!entry.isDirectory()) continue\n\n const src = join(bundledCategoryDir, entry.name)\n const dest = join(configCategoryDir, entry.name)\n\n // Force overwrite: remove existing then copy\n await rm(dest, { recursive: true, force: true })\n await cp(src, dest, { recursive: true })\n seeded.push(`${category}/${entry.name}`)\n }\n\n // Identify user-added assets (in config dir but not in bundle)\n if (existsSync(configCategoryDir)) {\n const configEntries = await readdir(configCategoryDir, { withFileTypes: true })\n const bundledNames = new Set(bundledEntries.filter(e => e.isDirectory()).map(e => e.name))\n for (const entry of configEntries) {\n if (entry.isDirectory() && !bundledNames.has(entry.name)) {\n skipped.push(`${category}/${entry.name}`)\n }\n }\n }\n }\n\n return { seeded, skipped }\n}\n\nexport interface InstallTarget {\n agentType: AgentType\n scope: InstallScope\n mode: InstallMode\n cwd: string\n}\n\n/**\n * Detect existing installations by scanning agent config dirs.\n * Returns a list of (agentType, scope, mode, cwd) to re-install into.\n */\nexport async function detectInstallTargets(repoPaths: string[]): Promise<InstallTarget[]> {\n const targets: InstallTarget[] = []\n\n for (const agent of getAllAgents()) {\n // Check project-scope installations for each repo\n for (const repoPath of repoPaths) {\n const mode = await detectModeInDir(repoPath, agent.configDir)\n if (mode) {\n targets.push({ agentType: agent.name, scope: 'project', mode, cwd: repoPath })\n }\n }\n\n // Check global-scope installation\n if (agent.globalConfigDir) {\n const mode = await detectModeInBaseDir(agent.globalConfigDir)\n if (mode) {\n targets.push({ agentType: agent.name, scope: 'global', mode, cwd: process.cwd() })\n }\n }\n }\n\n return targets\n}\n\n/**\n * Detect install mode by checking asset entries in an agent's config dir.\n * Checks skills/ and agents/ subdirs for symlink vs regular directory entries.\n * Returns the majority mode, or null if no assets found.\n */\nasync function detectModeInDir(\n repoPath: string,\n agentConfigDir: string,\n): Promise<InstallMode | null> {\n const baseDir = join(repoPath, agentConfigDir)\n return detectModeInBaseDir(baseDir)\n}\n\nasync function detectModeInBaseDir(baseDir: string): Promise<InstallMode | null> {\n let symlinkCount = 0\n let copyCount = 0\n\n for (const category of Object.values(CATEGORY_SUBDIRS)) {\n const categoryDir = join(baseDir, category)\n if (!existsSync(categoryDir)) continue\n\n try {\n const entries = await readdir(categoryDir)\n for (const name of entries) {\n const entryPath = join(categoryDir, name)\n try {\n const stats = await lstat(entryPath)\n if (stats.isSymbolicLink()) {\n symlinkCount++\n } else if (stats.isDirectory()) {\n copyCount++\n }\n } catch {\n // skip unreadable entries\n }\n }\n } catch {\n // skip unreadable category dirs\n }\n }\n\n if (symlinkCount === 0 && copyCount === 0) return null\n return symlinkCount >= copyCount ? 'symlink' : 'copy'\n}\n\nexport interface SkillUpdateOptions {\n all?: boolean\n}\n\nexport async function skillUpdateCommand(options: SkillUpdateOptions): Promise<void> {\n try {\n p.intro(chalk.blue('Update Skills'))\n\n // Step 1: Find bundled assets\n const bundledDir = getBundledAssetsDir()\n if (!bundledDir) {\n p.log.error('Bundled assets not found. Are you running from the package?')\n process.exit(1)\n }\n\n const configDir = getDefaultConfigDir()\n\n // Step 2: Re-seed config dir from bundle\n p.log.step('Updating config directory from bundle...')\n const seedResult = await updateBundledAssets(configDir, bundledDir)\n\n for (const name of seedResult.seeded) {\n p.log.info(` Updated: ${name}`)\n }\n if (seedResult.skipped.length > 0) {\n p.log.info(chalk.gray(` Preserved ${seedResult.skipped.length} custom asset(s)`))\n }\n\n // Step 3: Discover updated assets from config dir\n const discovered = await discoverAllAssets(configDir)\n // Filter to only bundled assets (those that were just seeded)\n const bundledAssetNames = new Set(seedResult.seeded.map(s => s.split('/')[1]))\n const bundledAssets = [\n ...discovered.agents.filter(a => bundledAssetNames.has(a.name)),\n ...discovered.skills.filter(a => bundledAssetNames.has(a.name)),\n ]\n\n if (bundledAssets.length === 0) {\n p.log.warn('No assets to update.')\n p.outro('Done.')\n return\n }\n\n // Step 4: Collect repo paths to scan\n const repoPaths: string[] = []\n\n if (options.all) {\n const config = loadConfigFile()\n if (config.thoughts?.repoMappings) {\n for (const repoPath of Object.keys(config.thoughts.repoMappings)) {\n if (existsSync(repoPath)) {\n repoPaths.push(repoPath)\n } else {\n p.log.warn(`Skipping (not found): ${repoPath}`)\n }\n }\n }\n // Include cwd if not already listed\n const cwd = process.cwd()\n if (!repoPaths.includes(cwd) && existsSync(join(cwd, '.git'))) {\n repoPaths.push(cwd)\n }\n } else {\n repoPaths.push(process.cwd())\n }\n\n // Step 5: Detect existing installations\n p.log.step('Detecting existing installations...')\n const targets = await detectInstallTargets(repoPaths)\n\n if (targets.length === 0) {\n p.log.warn('No existing installations detected. Run `thc skill install` first.')\n p.outro('Done.')\n return\n }\n\n for (const t of targets) {\n const scopeLabel = t.scope === 'global' ? 'global' : t.cwd\n p.log.info(chalk.gray(` ${agents[t.agentType].displayName}: ${scopeLabel} (${t.mode})`))\n }\n\n // Step 6: Re-install updated assets into each detected target\n const s = p.spinner()\n s.start('Installing updated assets...')\n\n let totalInstalled = 0\n let totalFailed = 0\n\n for (const target of targets) {\n for (const asset of bundledAssets) {\n const result = await installAssetForAgent(asset, target.agentType, {\n scope: target.scope,\n cwd: target.cwd,\n mode: target.mode,\n })\n\n if (result.success) {\n totalInstalled++\n } else {\n totalFailed++\n if (result.error) {\n p.log.warn(\n `Failed: ${asset.name} → ${agents[target.agentType].displayName}: ${result.error}`,\n )\n }\n }\n }\n }\n\n s.stop('Update complete.')\n\n // Summary\n const uniqueRepos = new Set(targets.filter(t => t.scope === 'project').map(t => t.cwd))\n const hasGlobal = targets.some(t => t.scope === 'global')\n let message = `Updated ${totalInstalled} asset(s)`\n if (uniqueRepos.size > 0) {\n message += ` in ${uniqueRepos.size} repo(s)`\n }\n if (hasGlobal) {\n message += ` + global`\n }\n if (totalFailed > 0) {\n message += chalk.red(` (${totalFailed} failed)`)\n }\n\n p.outro(message)\n } catch (error) {\n p.log.error(`Error during skill update: ${error}`)\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport { agentInitCommand } from './agent/init.js'\nimport { skillUpdateCommand } from './agent/update.js'\nimport type { AgentType, InstallMode } from './agent/types.js'\nimport { isValidAgentType } from './agent/registry.js'\n\nexport function skillCommand(program: Command): void {\n const skill = program.command('skill').description('Manage skill and agent asset installation')\n\n skill\n .command('install')\n .description('Install skills and agent configs to target agent directories')\n .option('--target <agents...>', 'Target agents (e.g., claude-code codebuddy)')\n .option('-g, --global', 'Install to global scope')\n .option('--mode <mode>', 'Installation mode: symlink or copy (default: symlink)')\n .option('--force', 'Force overwrite of existing installations')\n .action(async options => {\n const agentTypes: AgentType[] | undefined = options.target?.map((a: string) => {\n if (!isValidAgentType(a)) {\n console.error(`Unknown agent: ${a}`)\n process.exit(1)\n }\n return a as AgentType\n })\n\n let mode: InstallMode | undefined\n if (options.mode) {\n if (options.mode !== 'symlink' && options.mode !== 'copy') {\n console.error(`Invalid mode: ${options.mode}. Must be 'symlink' or 'copy'`)\n process.exit(1)\n }\n mode = options.mode as InstallMode\n }\n\n await agentInitCommand({\n agents: agentTypes,\n scope: options.global ? 'global' : undefined,\n mode,\n force: options.force,\n })\n })\n\n skill\n .command('update')\n .description('Update skills from package bundle and refresh installations')\n .option('--all', 'Update all registered repos (from config repoMappings)')\n .action(async options => {\n await skillUpdateCommand({ all: options.all })\n })\n}\n","import path from 'path'\nimport { isGitRepo, getCurrentBranch, getCurrentCommit, getRepoRoot } from '../../git.js'\n\ninterface GitInfo {\n repoRoot: string\n repoName: string\n branch: string\n commit: string\n}\n\nfunction getGitInfo(): GitInfo | null {\n if (!isGitRepo()) {\n return null\n }\n\n try {\n const repoRoot = getRepoRoot()\n const repoName = path.basename(repoRoot)\n const branch = getCurrentBranch()\n const commit = getCurrentCommit()\n\n return { repoRoot, repoName, branch, commit }\n } catch {\n return null\n }\n}\n\nfunction formatDate(date: Date): string {\n const pad = (n: number) => n.toString().padStart(2, '0')\n\n const year = date.getFullYear()\n const month = pad(date.getMonth() + 1)\n const day = pad(date.getDate())\n const hours = pad(date.getHours())\n const minutes = pad(date.getMinutes())\n const seconds = pad(date.getSeconds())\n\n // Get timezone name\n const tz = Intl.DateTimeFormat().resolvedOptions().timeZone\n\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds} ${tz}`\n}\n\nfunction formatFilenameTimestamp(date: Date): string {\n const pad = (n: number) => n.toString().padStart(2, '0')\n\n const year = date.getFullYear()\n const month = pad(date.getMonth() + 1)\n const day = pad(date.getDate())\n const hours = pad(date.getHours())\n const minutes = pad(date.getMinutes())\n const seconds = pad(date.getSeconds())\n\n return `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`\n}\n\nexport async function specMetadataCommand(): Promise<void> {\n const now = new Date()\n\n // Output datetime with timezone\n console.log(`Current Date/Time (TZ): ${formatDate(now)}`)\n\n // Output git info if available\n const gitInfo = getGitInfo()\n if (gitInfo) {\n if (gitInfo.commit) {\n console.log(`Current Git Commit Hash: ${gitInfo.commit}`)\n }\n if (gitInfo.branch) {\n console.log(`Current Branch Name: ${gitInfo.branch}`)\n }\n if (gitInfo.repoName) {\n console.log(`Repository Name: ${gitInfo.repoName}`)\n }\n }\n\n // Output timestamp suitable for filenames\n console.log(`Timestamp For Filename: ${formatFilenameTimestamp(now)}`)\n}\n","import { Command } from 'commander'\nimport { specMetadataCommand } from './metadata/metadata.js'\n\nexport function metadataCommand(program: Command): void {\n program\n .command('metadata')\n .description('Output metadata for current repository (branch, commit, timestamp, etc.)')\n .action(specMetadataCommand)\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport {\n isGitRepo,\n validateWorktreeHandle,\n getMainWorktreeRoot,\n getWorktreesBaseDir,\n setBranchBase,\n runGitCommandOrThrow,\n} from '../../git.js'\nimport {\n sessionNameForHandle,\n allSessionNamesForHandle,\n tmuxHasSession,\n tmuxNewSession,\n isTmuxAvailable,\n} from '../../tmux.js'\nimport { copyAgentConfigDirs } from '../../agent-config.js'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n createThoughtsDirectoryStructure,\n} from '../thoughts/utils/index.js'\nimport { setupThoughtsDirectory, pullThoughtsFromRemote } from '../thoughts/init-core.js'\nimport { resolveProfileForRepo, getRepoNameFromMapping } from '../thoughts/profile/utils.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\nimport type { WorktreeAddOptions } from './utils.js'\n\nexport async function worktreeAddCommand(name: string, options: WorktreeAddOptions): Promise<void> {\n try {\n validateWorktreeHandle(name)\n\n if (!isGitRepo()) {\n console.error(chalk.red('Error: not in a git repository'))\n process.exit(1)\n }\n\n const mainRoot = getMainWorktreeRoot()\n const baseDir = getWorktreesBaseDir(mainRoot)\n const worktreePath = options.path ? path.resolve(options.path) : path.join(baseDir, name)\n const branch = options.detached ? '' : (options.branch ?? name)\n const sessionName = sessionNameForHandle(name)\n\n fs.mkdirSync(path.dirname(worktreePath), { recursive: true })\n\n const tmuxAvailable = isTmuxAvailable()\n\n if (tmuxAvailable) {\n const sessionCandidates = allSessionNamesForHandle(name)\n const existingSession = sessionCandidates.find(s => tmuxHasSession(s))\n if (existingSession) {\n console.error(chalk.red(`Error: tmux session already exists: ${existingSession}`))\n process.exit(1)\n }\n }\n\n // Execute PreWorktreeAdd hooks\n const hooksConfig = loadHooksConfig(mainRoot)\n const preAddHooks = getHooksForEvent(hooksConfig, 'PreWorktreeAdd')\n\n if (preAddHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: worktreePath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: branch,\n THC_MAIN_ROOT: mainRoot,\n THC_SESSION_NAME: sessionName,\n THC_BASE_REF: options.base,\n }\n\n await executeHooks(\n preAddHooks,\n {\n hook_event_name: 'PreWorktreeAdd',\n cwd: mainRoot,\n worktree_path: worktreePath,\n worktree_name: name,\n worktree_branch: branch,\n main_root: mainRoot,\n session_name: sessionName,\n base_ref: options.base,\n },\n hookEnv,\n true,\n )\n }\n\n if (options.detached) {\n runGitCommandOrThrow(['worktree', 'add', '--detach', worktreePath, options.base], {\n cwd: mainRoot,\n })\n } else {\n runGitCommandOrThrow(['worktree', 'add', '-b', branch, worktreePath, options.base], {\n cwd: mainRoot,\n })\n setBranchBase(branch, options.base, worktreePath)\n }\n\n if (tmuxAvailable) {\n tmuxNewSession(sessionName, worktreePath)\n } else {\n console.log(chalk.yellow('Warning: tmux not found, skipping session creation'))\n }\n\n // Copy agent configuration directories\n const configResult = copyAgentConfigDirs({\n sourceDir: mainRoot,\n targetDir: worktreePath,\n })\n if (configResult.copied.length > 0) {\n console.log(chalk.gray(`Copied config: ${configResult.copied.join(', ')}`))\n }\n\n // Initialize thoughts (unless --no-thoughts is specified)\n if (options.thoughts !== false) {\n initializeWorktreeThoughts(mainRoot, worktreePath)\n }\n\n // Execute PostWorktreeAdd hooks\n const postAddHooks = getHooksForEvent(hooksConfig, 'PostWorktreeAdd')\n\n if (postAddHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: worktreePath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: branch,\n THC_MAIN_ROOT: mainRoot,\n THC_SESSION_NAME: sessionName,\n }\n\n await executeHooks(\n postAddHooks,\n {\n hook_event_name: 'PostWorktreeAdd',\n cwd: worktreePath,\n worktree_path: worktreePath,\n worktree_name: name,\n worktree_branch: branch,\n main_root: mainRoot,\n session_name: sessionName,\n },\n hookEnv,\n true,\n )\n }\n\n console.log(chalk.green('\\n✓ Worktree created'))\n console.log(chalk.gray(`Path: ${worktreePath}`))\n if (tmuxAvailable) {\n console.log(chalk.gray(`Tmux session: ${sessionName}`))\n console.log(chalk.gray(`Attach: tmux attach -t ${sessionName}`))\n }\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n}\n\nfunction initializeWorktreeThoughts(mainRoot: string, worktreePath: string): void {\n const config = loadThoughtsConfig({})\n if (!config) {\n console.log(chalk.yellow('Thoughts not configured globally, skipping'))\n return\n }\n\n const mainRepoMapping = config.repoMappings[mainRoot]\n const mappedName = getRepoNameFromMapping(mainRepoMapping)\n\n if (!mappedName) {\n console.log(chalk.yellow('Main repo not configured for thoughts, skipping'))\n return\n }\n\n // Add repo mapping for new worktree\n config.repoMappings[worktreePath] = mainRepoMapping\n saveThoughtsConfig(config, {})\n\n const profileConfig = resolveProfileForRepo(config, worktreePath)\n\n // Ensure the thoughts directory structure exists in thoughts repo\n createThoughtsDirectoryStructure(profileConfig, mappedName, config.user)\n\n // Set up thoughts directory\n const result = setupThoughtsDirectory({\n repoPath: worktreePath,\n profileConfig,\n mappedName,\n user: config.user,\n createSearchable: true,\n setupHooks: true,\n })\n\n console.log(chalk.gray('Thoughts initialized'))\n if (result.hooksUpdated.length > 0) {\n console.log(chalk.gray(`Updated git hooks: ${result.hooksUpdated.join(', ')}`))\n }\n\n // Sync thoughts from remote\n if (pullThoughtsFromRemote(profileConfig.thoughtsRepo)) {\n console.log(chalk.gray('Pulled latest thoughts from remote'))\n }\n}\n","import { execFileSync } from 'child_process'\n\n// Session naming\nexport function sessionNameForHandle(handle: string): string {\n // NOTE: tmux uses ':' as a target separator (session:window.pane),\n // so ':' is not allowed in session names on many tmux versions.\n return `thc-${handle}`\n}\n\nexport function legacySessionNameForHandle(handle: string): string {\n return `thc:${handle}`\n}\n\nexport function allSessionNamesForHandle(handle: string): string[] {\n return [sessionNameForHandle(handle), legacySessionNameForHandle(handle)]\n}\n\n// Availability check\nlet _tmuxAvailable: boolean | undefined\n\nexport function isTmuxAvailable(): boolean {\n if (_tmuxAvailable === undefined) {\n try {\n execFileSync('tmux', ['-V'], { stdio: 'ignore' })\n _tmuxAvailable = true\n } catch {\n _tmuxAvailable = false\n }\n }\n return _tmuxAvailable\n}\n\n// Session management\nexport function listTmuxSessions(): string[] {\n try {\n const out = execFileSync('tmux', ['list-sessions', '-F', '#{session_name}'], {\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'pipe'],\n }).trim()\n return out\n .split('\\n')\n .map(s => s.trim())\n .filter(Boolean)\n } catch {\n return []\n }\n}\n\nexport function tmuxHasSession(sessionName: string): boolean {\n try {\n execFileSync('tmux', ['has-session', '-t', sessionName], {\n stdio: 'ignore',\n })\n return true\n } catch {\n return false\n }\n}\n\nexport function tmuxNewSession(sessionName: string, cwd: string): void {\n execFileSync('tmux', ['new-session', '-d', '-s', sessionName, '-c', cwd], {\n stdio: 'inherit',\n })\n}\n\nexport function tmuxKillSession(sessionName: string): void {\n try {\n execFileSync('tmux', ['kill-session', '-t', sessionName], { stdio: 'ignore' })\n } catch {\n // ignore\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { agents } from './commands/agent/registry.js'\nimport { CANONICAL_DIR } from './commands/agent/constants.js'\n\nexport interface CopyAgentConfigOptions {\n /** Source directory (main worktree) */\n sourceDir: string\n /** Target directory (new worktree) */\n targetDir: string\n}\n\nexport interface CopyAgentConfigResult {\n /** Agent config directories that were copied */\n copied: string[]\n /** Agent config directories that were skipped (not present in source) */\n skipped: string[]\n}\n\n/**\n * Detect which agent config directories exist in the source directory.\n * Scans for unique configDir values from the agent registry.\n */\nfunction detectAgentConfigDirs(sourceDir: string): string[] {\n const uniqueDirs = [...new Set(Object.values(agents).map(a => a.configDir))]\n // Also include the canonical intermediate directory\n uniqueDirs.push(CANONICAL_DIR)\n return uniqueDirs.filter(dir => fs.existsSync(path.join(sourceDir, dir)))\n}\n\n/**\n * Create a symlink at destPath, falling back to a dereferenced copy on failure.\n * Silently skips if both the symlink and copy fail (e.g. broken source symlink).\n */\nfunction symlinkOrCopy(srcPath: string, destPath: string, linkTarget: string): void {\n try {\n fs.symlinkSync(linkTarget, destPath)\n } catch {\n try {\n fs.cpSync(srcPath, destPath, { recursive: true, dereference: true })\n } catch {\n // Skip — source symlink may be broken\n }\n }\n}\n\n/**\n * Recursively copy a directory, preserving symlinks as-is.\n */\nfunction copyDirWithSymlinkHandling(srcDir: string, destDir: string): void {\n fs.mkdirSync(destDir, { recursive: true })\n\n for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {\n const srcPath = path.join(srcDir, entry.name)\n const destPath = path.join(destDir, entry.name)\n\n if (entry.isSymbolicLink()) {\n symlinkOrCopy(srcPath, destPath, fs.readlinkSync(srcPath))\n } else if (entry.isDirectory()) {\n copyDirWithSymlinkHandling(srcPath, destPath)\n } else {\n fs.cpSync(srcPath, destPath)\n }\n }\n}\n\n/**\n * Copy agent configuration directories to a new worktree.\n *\n * Copies agent config dirs (e.g. .claude/) and the canonical intermediate\n * directory (.thought-cabinet/) so that project-scope symlinks resolve correctly.\n * Preserves symlinks as-is. Non-symlink files are copied normally.\n */\nexport function copyAgentConfigDirs(options: CopyAgentConfigOptions): CopyAgentConfigResult {\n const { sourceDir, targetDir } = options\n const copied: string[] = []\n const skipped: string[] = []\n\n // Detect and copy agent config directories\n for (const dirName of detectAgentConfigDirs(sourceDir)) {\n try {\n copyDirWithSymlinkHandling(path.join(sourceDir, dirName), path.join(targetDir, dirName))\n copied.push(dirName)\n } catch {\n skipped.push(dirName)\n }\n }\n\n return { copied, skipped }\n}\n","import path from 'path'\nimport chalk from 'chalk'\nimport {\n isGitRepo,\n getMainWorktreeRoot,\n getWorktreesBaseDir,\n runGitCommand,\n parseWorktreeListPorcelain,\n} from '../../git.js'\nimport { allSessionNamesForHandle, listTmuxSessions } from '../../tmux.js'\nimport type { WorktreeListOptions } from './utils.js'\n\ninterface WorktreeRow {\n name: string\n branch: string\n tmux: string\n path: string\n isCurrent: boolean\n}\n\nexport async function worktreeListCommand(options: WorktreeListOptions): Promise<void> {\n try {\n if (!isGitRepo()) {\n console.error(chalk.red('Error: not in a git repository'))\n process.exit(1)\n }\n\n const mainRoot = getMainWorktreeRoot()\n const baseDir = path.resolve(getWorktreesBaseDir(mainRoot))\n const cwd = path.resolve(process.cwd())\n\n const entries = parseWorktreeListPorcelain(\n runGitCommand(['worktree', 'list', '--porcelain'], { cwd: mainRoot }),\n )\n\n const sessions = new Set(listTmuxSessions())\n\n const filtered = options.all\n ? entries\n : entries.filter(e => {\n const p = path.resolve(e.worktreePath)\n return p === path.resolve(mainRoot) || p.startsWith(baseDir + path.sep)\n })\n\n if (filtered.length === 0) {\n console.log(chalk.gray('No worktrees found.'))\n return\n }\n\n const rows: WorktreeRow[] = filtered.map(e => {\n const name = path.basename(e.worktreePath)\n const isCurrent = path.resolve(e.worktreePath) === cwd\n return {\n name: isCurrent ? `* ${name}` : ` ${name}`,\n branch: e.branch,\n tmux: allSessionNamesForHandle(name).find(s => sessions.has(s)) ?? '-',\n path: e.worktreePath,\n isCurrent,\n }\n })\n\n const colWidths = {\n name: Math.max(' NAME'.length, ...rows.map(r => r.name.length)),\n branch: Math.max('BRANCH'.length, ...rows.map(r => r.branch.length)),\n tmux: Math.max('TMUX'.length, ...rows.map(r => r.tmux.length)),\n }\n\n // Print header\n const header =\n `${' NAME'.padEnd(colWidths.name)} ` +\n `${'BRANCH'.padEnd(colWidths.branch)} ` +\n `${'TMUX'.padEnd(colWidths.tmux)} ` +\n `PATH`\n console.log(chalk.blue(header))\n\n // Print rows\n for (const row of rows) {\n const line =\n `${row.name.padEnd(colWidths.name)} ` +\n `${row.branch.padEnd(colWidths.branch)} ` +\n `${row.tmux.padEnd(colWidths.tmux)} ` +\n `${row.path}`\n\n console.log(row.isCurrent ? chalk.green(line) : line)\n }\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n}\n","import path from 'path'\nimport chalk from 'chalk'\nimport {\n isGitRepo,\n getMainWorktreeRoot,\n findWorktree,\n hasUncommittedChanges,\n runGitCommandOrThrow,\n runGitCommand,\n} from '../../git.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\nimport {\n cleanupWorktreeThoughts,\n cleanupWorktreeTmuxSession,\n removeGitWorktree,\n deleteWorktreeBranch,\n type WorktreeMergeOptions,\n} from './utils.js'\n\nexport async function worktreeMergeCommand(\n name: string,\n options: WorktreeMergeOptions,\n): Promise<void> {\n try {\n if (!isGitRepo()) {\n console.error(chalk.red('Error: not in a git repository'))\n process.exit(1)\n }\n\n const mainRoot = getMainWorktreeRoot()\n const wtEntry = findWorktree(name, mainRoot)\n const wtPath = path.resolve(wtEntry.worktreePath)\n\n if (wtPath === path.resolve(mainRoot)) {\n console.error(chalk.red('Error: refusing to merge/remove the main worktree'))\n process.exit(1)\n }\n\n if (wtEntry.detached || wtEntry.branch === '(detached)') {\n console.error(chalk.red('Error: cannot merge a detached worktree'))\n process.exit(1)\n }\n\n const targetBranch =\n options.into ?? runGitCommand(['branch', '--show-current'], { cwd: mainRoot })\n if (!targetBranch) {\n console.error(chalk.red('Error: could not determine target branch. Use --into <branch>.'))\n process.exit(1)\n }\n\n if (targetBranch === wtEntry.branch) {\n console.error(chalk.red('Error: source and target branch are the same'))\n process.exit(1)\n }\n\n // Execute PreWorktreeMerge hooks\n const hooksConfig = loadHooksConfig(mainRoot)\n const preHooks = getHooksForEvent(hooksConfig, 'PreWorktreeMerge')\n\n if (preHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: wtPath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: wtEntry.branch,\n THC_TARGET_BRANCH: targetBranch,\n THC_MAIN_ROOT: mainRoot,\n }\n\n await executeHooks(\n preHooks,\n {\n hook_event_name: 'PreWorktreeMerge',\n cwd: mainRoot,\n worktree_path: wtPath,\n worktree_name: name,\n worktree_branch: wtEntry.branch,\n target_branch: targetBranch,\n main_root: mainRoot,\n },\n hookEnv,\n true,\n )\n }\n\n // Clean up thoughts before checking uncommitted changes\n // (thoughts/ directory would show as untracked and cause false positive)\n cleanupWorktreeThoughts(wtPath, { force: options.force, verbose: true })\n\n if (!options.force && hasUncommittedChanges(wtEntry.worktreePath)) {\n console.error(\n chalk.red('Error: worktree has uncommitted changes. Commit/stash first or use --force.'),\n )\n process.exit(1)\n }\n\n console.log(chalk.blue(`Rebasing ${wtEntry.branch} onto ${targetBranch}...`))\n runGitCommandOrThrow(['rebase', targetBranch], { cwd: wtEntry.worktreePath })\n\n console.log(chalk.blue(`Fast-forward merging into ${targetBranch}...`))\n runGitCommandOrThrow(['switch', targetBranch], { cwd: mainRoot })\n runGitCommandOrThrow(['merge', '--ff-only', wtEntry.branch], { cwd: mainRoot })\n\n if (!options.keepSession) {\n cleanupWorktreeTmuxSession(wtPath)\n }\n\n if (!options.keepWorktree) {\n removeGitWorktree(wtPath, mainRoot, { force: options.force })\n }\n\n if (!options.keepBranch) {\n deleteWorktreeBranch(wtEntry.branch, mainRoot, { force: options.force })\n }\n\n // Execute PostWorktreeMerge hooks\n const postHooks = getHooksForEvent(hooksConfig, 'PostWorktreeMerge')\n\n if (postHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: wtPath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: wtEntry.branch,\n THC_TARGET_BRANCH: targetBranch,\n THC_MAIN_ROOT: mainRoot,\n THC_KEPT_SESSION: options.keepSession ? 'true' : 'false',\n THC_KEPT_WORKTREE: options.keepWorktree ? 'true' : 'false',\n THC_KEPT_BRANCH: options.keepBranch ? 'true' : 'false',\n }\n\n await executeHooks(\n postHooks,\n {\n hook_event_name: 'PostWorktreeMerge',\n cwd: mainRoot,\n worktree_path: wtPath,\n worktree_name: name,\n worktree_branch: wtEntry.branch,\n target_branch: targetBranch,\n main_root: mainRoot,\n kept_session: options.keepSession ?? false,\n kept_worktree: options.keepWorktree ?? false,\n kept_branch: options.keepBranch ?? false,\n },\n hookEnv,\n true,\n )\n }\n\n console.log(chalk.green('✓ Merged and cleaned up'))\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n}\n","import path from 'path'\nimport chalk from 'chalk'\nimport { allSessionNamesForHandle, tmuxKillSession } from '../../tmux.js'\nimport { runGitCommandOrThrow } from '../../git.js'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n cleanupThoughtsDirectory,\n} from '../thoughts/utils/index.js'\n\nexport interface WorktreeAddOptions {\n branch?: string\n base: string\n path?: string\n detached?: boolean\n thoughts?: boolean\n}\n\nexport interface WorktreeListOptions {\n all?: boolean\n}\n\nexport interface WorktreeMergeOptions {\n into?: string\n force?: boolean\n keepSession?: boolean\n keepWorktree?: boolean\n keepBranch?: boolean\n}\n\nexport interface WorktreeRemoveOptions {\n force?: boolean\n}\n\n/**\n * Clean up thoughts directory for a worktree\n */\nexport function cleanupWorktreeThoughts(\n wtPath: string,\n options: { force?: boolean; verbose?: boolean } = {},\n): void {\n const config = loadThoughtsConfig({})\n if (!config || !config.repoMappings[wtPath]) {\n return\n }\n\n try {\n if (options.verbose) {\n console.log(chalk.gray('Cleaning up thoughts directory...'))\n }\n const result = cleanupThoughtsDirectory({\n repoPath: wtPath,\n config,\n force: options.force,\n verbose: false,\n })\n\n if (result.configRemoved) {\n saveThoughtsConfig(config, {})\n }\n\n if (result.thoughtsRemoved && options.verbose) {\n console.log(chalk.gray('✓ Thoughts directory cleaned up'))\n }\n } catch (error) {\n if (options.verbose) {\n console.log(chalk.yellow(`Warning: Could not clean up thoughts: ${(error as Error).message}`))\n }\n }\n}\n\n/**\n * Kill tmux sessions for a worktree\n */\nexport function cleanupWorktreeTmuxSession(wtPath: string): void {\n const handle = path.basename(wtPath)\n const sessionNames = allSessionNamesForHandle(handle)\n for (const s of sessionNames) {\n tmuxKillSession(s)\n }\n}\n\n/**\n * Remove git worktree\n */\nexport function removeGitWorktree(\n wtPath: string,\n mainRoot: string,\n options: { force?: boolean } = {},\n): void {\n const removeArgs = ['worktree', 'remove']\n if (options.force) {\n removeArgs.push('--force')\n }\n removeArgs.push(wtPath)\n runGitCommandOrThrow(removeArgs, { cwd: mainRoot })\n\n // Best-effort prune\n try {\n runGitCommandOrThrow(['worktree', 'prune'], { cwd: mainRoot })\n } catch {\n // ignore\n }\n}\n\n/**\n * Delete a branch\n */\nexport function deleteWorktreeBranch(\n branch: string,\n mainRoot: string,\n options: { force?: boolean } = {},\n): void {\n try {\n runGitCommandOrThrow(['branch', '-d', branch], { cwd: mainRoot })\n } catch {\n if (options.force) {\n runGitCommandOrThrow(['branch', '-D', branch], { cwd: mainRoot })\n } else {\n throw new Error(`Failed to delete branch '${branch}'. Re-run with --force to force delete.`)\n }\n }\n}\n","import path from 'path'\nimport chalk from 'chalk'\nimport {\n isGitRepo,\n getMainWorktreeRoot,\n findWorktree,\n hasUncommittedChanges,\n hasUnmergedCommits,\n getDefaultBranch,\n} from '../../git.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\nimport {\n cleanupWorktreeThoughts,\n cleanupWorktreeTmuxSession,\n removeGitWorktree,\n deleteWorktreeBranch,\n type WorktreeRemoveOptions,\n} from './utils.js'\n\nexport async function worktreeRemoveCommand(\n name: string,\n options: WorktreeRemoveOptions,\n): Promise<void> {\n try {\n if (!isGitRepo()) {\n console.error(chalk.red('Error: not in a git repository'))\n process.exit(1)\n }\n\n const mainRoot = getMainWorktreeRoot()\n const wtEntry = findWorktree(name, mainRoot)\n const wtPath = path.resolve(wtEntry.worktreePath)\n const hasBranch = !wtEntry.detached && wtEntry.branch !== '(detached)'\n\n if (wtPath === path.resolve(mainRoot)) {\n console.error(chalk.red('Error: refusing to remove the main worktree'))\n process.exit(1)\n }\n\n // Check for unmerged commits (only if branch exists)\n if (!options.force && hasBranch) {\n const defaultBranch = getDefaultBranch(mainRoot)\n if (hasUnmergedCommits(wtEntry.branch, defaultBranch, mainRoot)) {\n console.error(\n chalk.red(\n `Error: branch '${wtEntry.branch}' has commits not merged into '${defaultBranch}'. ` +\n `Merge first or use --force to discard.`,\n ),\n )\n process.exit(1)\n }\n }\n\n // Execute PreWorktreeRemove hooks\n const hooksConfig = loadHooksConfig(mainRoot)\n const preHooks = getHooksForEvent(hooksConfig, 'PreWorktreeRemove')\n\n if (preHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: wtPath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: wtEntry.branch,\n THC_MAIN_ROOT: mainRoot,\n }\n\n await executeHooks(\n preHooks,\n {\n hook_event_name: 'PreWorktreeRemove',\n cwd: mainRoot,\n worktree_path: wtPath,\n worktree_name: name,\n worktree_branch: wtEntry.branch,\n main_root: mainRoot,\n },\n hookEnv,\n true,\n )\n }\n\n // Clean up thoughts directory before checking uncommitted changes\n // (thoughts/ directory would show as untracked and cause false positive)\n cleanupWorktreeThoughts(wtPath, { force: options.force, verbose: true })\n\n if (!options.force && hasUncommittedChanges(wtEntry.worktreePath)) {\n console.error(\n chalk.red('Error: worktree has uncommitted changes. Commit/stash first or use --force.'),\n )\n process.exit(1)\n }\n\n cleanupWorktreeTmuxSession(wtPath)\n\n console.log(chalk.gray('Removing git worktree...'))\n removeGitWorktree(wtPath, mainRoot, { force: options.force })\n\n if (hasBranch) {\n console.log(chalk.gray(`Deleting branch '${wtEntry.branch}'...`))\n try {\n deleteWorktreeBranch(wtEntry.branch, mainRoot, { force: options.force })\n } catch (error) {\n console.log(chalk.yellow(`Warning: ${(error as Error).message}`))\n }\n }\n\n // Execute PostWorktreeRemove hooks\n const postHooks = getHooksForEvent(hooksConfig, 'PostWorktreeRemove')\n\n if (postHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: wtPath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: wtEntry.branch,\n THC_MAIN_ROOT: mainRoot,\n }\n\n await executeHooks(\n postHooks,\n {\n hook_event_name: 'PostWorktreeRemove',\n cwd: mainRoot,\n worktree_path: wtPath,\n worktree_name: name,\n worktree_branch: wtEntry.branch,\n main_root: mainRoot,\n },\n hookEnv,\n true,\n )\n }\n\n console.log(chalk.green('✓ Worktree removed'))\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport { worktreeAddCommand } from './worktree/add.js'\nimport { worktreeListCommand } from './worktree/list.js'\nimport { worktreeMergeCommand } from './worktree/merge.js'\nimport { worktreeRemoveCommand } from './worktree/remove.js'\n\nexport function worktreeCommand(program: Command): void {\n const wt = program.command('worktree').description('Manage git worktrees bound to tmux sessions')\n\n wt.command('add <name>')\n .description('Create a git worktree and a tmux session for it')\n .option('--branch <branch>', 'Branch name (defaults to <name>)')\n .option('--base <ref>', 'Base ref/commit (default: HEAD)', 'HEAD')\n .option('--path <path>', 'Worktree directory path (default: ../<repo>__worktrees/<name>)')\n .option('--detached', 'Create a detached worktree at <base> (no branch)')\n .option('--no-thoughts', 'Skip thoughts initialization')\n .action(worktreeAddCommand)\n\n wt.command('list')\n .description('List thc-managed worktrees and their tmux sessions')\n .option('--all', 'Show all git worktrees (not just ../<repo>__worktrees)')\n .action(worktreeListCommand)\n\n wt.command('merge <name>')\n .description(\n 'Rebase worktree branch onto target, ff-merge, then clean up worktree + tmux session',\n )\n .option(\n '--into <branch>',\n 'Target branch to merge into (default: current branch in main worktree)',\n )\n .option('--force', 'Force cleanup even if uncommitted changes exist')\n .option('--keep-session', 'Do not kill the tmux session')\n .option('--keep-worktree', 'Do not remove the git worktree')\n .option('--keep-branch', 'Do not delete the source branch')\n .action(worktreeMergeCommand)\n\n wt.command('remove <name>')\n .description(\n 'Remove a worktree and clean up associated resources (tmux session, thoughts, branch)',\n )\n .option('--force', 'Force removal even with uncommitted changes or unmerged commits')\n .action(worktreeRemoveCommand)\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport { fileURLToPath } from 'url'\nimport { dirname } from 'path'\nimport { HOOKS_CONFIG_DIR, HOOKS_CONFIG_FILE } from '../../hooks/index.js'\n\n// Get the directory of this module\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport async function hooksInitCommand(): Promise<void> {\n try {\n const repoPath = process.cwd()\n const configDir = path.join(repoPath, HOOKS_CONFIG_DIR)\n const configPath = path.join(repoPath, HOOKS_CONFIG_FILE)\n\n // Check if config already exists\n if (fs.existsSync(configPath)) {\n console.log(chalk.yellow(`${HOOKS_CONFIG_FILE} already exists.`))\n console.log(chalk.gray(`Edit the file directly: ${configPath}`))\n return\n }\n\n // Find the example file\n // Try multiple possible locations for the example file\n const possiblePaths = [\n // When running from built dist: one level up from dist/\n path.resolve(__dirname, '..', '.thought-cabinet/hooks.example.json'),\n // When installed via npm: one level up from dist/\n path.resolve(__dirname, '../..', '.thought-cabinet/hooks.example.json'),\n ]\n\n let examplePath: string | null = null\n for (const candidatePath of possiblePaths) {\n if (fs.existsSync(candidatePath)) {\n examplePath = candidatePath\n break\n }\n }\n\n if (!examplePath) {\n console.error(chalk.red('Error: hooks.example.json not found in expected locations'))\n console.log(chalk.gray('Searched paths:'))\n possiblePaths.forEach(p => console.log(chalk.gray(` - ${p}`)))\n process.exit(1)\n }\n\n // Create directory and copy example file\n fs.mkdirSync(configDir, { recursive: true })\n fs.copyFileSync(examplePath, configPath)\n\n console.log(chalk.green(`Created ${HOOKS_CONFIG_FILE}`))\n } catch (error) {\n console.error(chalk.red(`Error during hooks init: ${error}`))\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport { hooksInitCommand } from './hooks/init.js'\n\nexport function hooksCommand(program: Command): void {\n const hooks = program.command('hooks').description('Manage hook configuration')\n\n hooks\n .command('init')\n .description('Initialize hooks configuration in current repository')\n .action(hooksInitCommand)\n}\n","import { Command } from 'commander'\n\nexport function completionCommand(program: Command): void {\n const completion = program\n .command('completion')\n .description('Manage shell completion for thoughtcabinet CLI')\n\n completion\n .command('install')\n .description('Install shell completion scripts')\n .action(async () => {\n const { install } = await import('../completion/installer.js')\n await install()\n })\n\n completion\n .command('uninstall')\n .description('Remove shell completion scripts')\n .action(async () => {\n const { uninstall } = await import('../completion/installer.js')\n await uninstall()\n })\n}\n","import tabtab from 'tabtab'\nimport { getProfileNames, getWorktreeNames, getBranchNames, getAgentNames } from './providers.js'\n\n// Top-level commands available on the program\nconst TOP_LEVEL_COMMANDS = [\n 'init',\n 'destroy',\n 'sync',\n 'status',\n 'config',\n 'prune',\n 'migrate',\n 'profile',\n 'worktree',\n 'skill',\n 'metadata',\n 'hooks',\n 'completion',\n]\n\n// Subcommands for command groups\nconst SUBCOMMANDS: Record<string, string[]> = {\n profile: ['create', 'list', 'show', 'delete'],\n worktree: ['add', 'list', 'merge', 'remove'],\n skill: ['install', 'update'],\n hooks: ['init'],\n completion: ['install', 'uninstall'],\n}\n\n// Options for each command\nconst OPTIONS: Record<string, string[]> = {\n init: ['--force', '--config-file', '--directory', '--profile'],\n destroy: ['--force', '--config-file'],\n sync: ['-m', '--message', '--config-file'],\n status: ['--config-file', '--fetch'],\n config: ['--edit', '--json', '--config-file'],\n prune: ['--apply', '--config-file'],\n migrate: ['--dry-run', '--config-file'],\n 'profile create': ['--repo', '--repos-dir', '--global-dir', '--config-file'],\n 'profile list': ['--json', '--config-file'],\n 'profile show': ['--json', '--config-file'],\n 'profile delete': ['--force', '--config-file'],\n 'worktree add': ['--branch', '--base', '--path', '--detached', '--no-thoughts'],\n 'worktree list': ['--all'],\n 'worktree merge': ['--into', '--force', '--keep-session', '--keep-worktree', '--keep-branch'],\n 'worktree remove': ['--force'],\n 'skill install': ['--force', '--target', '--global', '--mode'],\n 'skill update': ['--all'],\n}\n\n// Commands that expect dynamic arguments\nconst DYNAMIC_ARGS: Record<string, () => string[]> = {\n 'profile show': getProfileNames,\n 'profile delete': getProfileNames,\n 'worktree merge': getWorktreeNames,\n 'worktree remove': getWorktreeNames,\n}\n\n// Options that expect dynamic values\nconst DYNAMIC_OPTIONS: Record<string, () => string[]> = {\n '--profile': getProfileNames,\n '--branch': getBranchNames,\n '--base': getBranchNames,\n '--into': getBranchNames,\n '--target': getAgentNames,\n '--mode': () => ['symlink', 'copy'],\n}\n\nexport async function handleCompletion(): Promise<boolean> {\n const env = tabtab.parseEnv(process.env)\n\n if (!env.complete) {\n return false\n }\n\n const { line, prev } = env\n const args = line.split(' ').filter(Boolean).slice(1) // Remove CLI name\n\n // Check if previous word is an option expecting dynamic value\n if (prev in DYNAMIC_OPTIONS) {\n const provider = DYNAMIC_OPTIONS[prev]\n await tabtab.log(provider())\n return true\n }\n\n // Complete top-level commands\n if (args.length === 0 || (args.length === 1 && !line.endsWith(' '))) {\n const partial = args[0] || ''\n const matches = TOP_LEVEL_COMMANDS.filter(cmd => cmd.startsWith(partial))\n await tabtab.log(matches)\n return true\n }\n\n const firstArg = args[0]\n\n // Complete subcommands for command groups\n if (firstArg in SUBCOMMANDS) {\n const subcommands = SUBCOMMANDS[firstArg]\n if (args.length === 1 && line.endsWith(' ')) {\n await tabtab.log(subcommands)\n return true\n }\n if (args.length === 2 && !line.endsWith(' ')) {\n const partial = args[1]\n const matches = subcommands.filter(sub => sub.startsWith(partial))\n await tabtab.log(matches)\n return true\n }\n }\n\n // Check for dynamic argument completion\n const commandKey = args.slice(0, 2).join(' ')\n if (commandKey in DYNAMIC_ARGS && args.length === 2 && line.endsWith(' ')) {\n const provider = DYNAMIC_ARGS[commandKey]\n await tabtab.log(provider())\n return true\n }\n\n // Complete options\n if (prev.startsWith('-')) {\n // Option expects a value, don't complete\n await tabtab.log([])\n return true\n }\n\n // Determine command context for options\n const options = OPTIONS[commandKey] || OPTIONS[firstArg] || []\n\n if (line.endsWith(' ') || prev.startsWith('-')) {\n const usedOptions = args.filter(arg => arg.startsWith('-'))\n const availableOptions = options.filter(opt => !usedOptions.includes(opt))\n await tabtab.log(availableOptions)\n return true\n }\n\n await tabtab.log([])\n return true\n}\n","import { loadConfigFile } from '../config.js'\nimport {\n isGitRepo,\n runGitCommand,\n parseWorktreeListPorcelain,\n getMainWorktreeRoot,\n getWorktreesBaseDir,\n} from '../git.js'\nimport path from 'path'\n\n/**\n * Get list of profile names from config\n */\nexport function getProfileNames(): string[] {\n try {\n const config = loadConfigFile()\n if (!config.thoughts?.profiles) {\n return []\n }\n return Object.keys(config.thoughts.profiles)\n } catch {\n return []\n }\n}\n\n/**\n * Get list of worktree names (directory basenames)\n */\nexport function getWorktreeNames(): string[] {\n try {\n if (!isGitRepo()) {\n return []\n }\n\n const mainRoot = getMainWorktreeRoot()\n const baseDir = getWorktreesBaseDir(mainRoot)\n const output = runGitCommand(['worktree', 'list', '--porcelain'])\n const entries = parseWorktreeListPorcelain(output)\n\n // Filter to only thc-managed worktrees and extract names\n return entries\n .filter(e => {\n const p = path.resolve(e.worktreePath)\n return p.startsWith(baseDir + path.sep)\n })\n .map(e => path.basename(e.worktreePath))\n } catch {\n return []\n }\n}\n\n/**\n * Get list of local branch names\n */\nexport function getBranchNames(): string[] {\n try {\n if (!isGitRepo()) {\n return []\n }\n\n const output = runGitCommand(['branch', '--format=%(refname:short)'])\n return output.split('\\n').filter(Boolean)\n } catch {\n return []\n }\n}\n\n/**\n * Get list of agent type names for completion\n */\nexport function getAgentNames(): string[] {\n return ['claude-code', 'codebuddy']\n}\n"],"mappings":"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","names":["fs","path","execSync","chalk","path","path","path","fs","path","path","os","fs","path","isGitRepo","fs","path","path","fs","fs","path","chalk","path","fs","chalk","fs","path","execSync","path","fs","execSync","fs","path","chalk","chalk","resolve","path","fs","execSync","chalk","reposDir","inheritedProfile","fs","path","chalk","path","fs","chalk","fs","path","execSync","execFileSync","chalk","execSync","execFileSync","chalk","path","fs","fs","path","execSync","chalk","execSync","chalk","path","fs","spawn","chalk","spawn","chalk","fs","chalk","chalk","fs","fs","path","chalk","p","home","path","fs","agents","chalk","confirm","chalk","path","p","chalk","path","chalk","chalk","chalk","chalk","chalk","p","chalk","existsSync","dirname","join","resolve","chalk","p","cp","mkdir","readdir","join","agents","readdir","join","homedir","join","homedir","readdir","__dirname","dirname","resolve","existsSync","join","mkdir","readdir","cp","chalk","existsSync","join","cp","readdir","mkdir","rm","lstat","chalk","p","ASSET_CATEGORIES","join","existsSync","mkdir","readdir","rm","cp","lstat","chalk","s","path","path","fs","path","chalk","execFileSync","fs","path","fs","path","chalk","path","fs","path","chalk","chalk","path","p","path","chalk","path","chalk","chalk","path","chalk","path","path","chalk","chalk","path","fs","path","chalk","fileURLToPath","dirname","__filename","fileURLToPath","__dirname","dirname","path","fs","chalk","p","path","p","dotenv","require"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/thoughts/init.ts","../src/config.ts","../src/commands/thoughts/utils/config.ts","../src/commands/thoughts/utils/paths.ts","../src/git.ts","../src/commands/thoughts/utils/repository.ts","../src/templates/gitignore.ts","../src/templates/readme.ts","../src/templates/agentMd.ts","../src/templates/gitHooks.ts","../src/commands/thoughts/utils/symlinks.ts","../src/commands/thoughts/utils/cleanup.ts","../src/commands/thoughts/profile/utils.ts","../src/commands/thoughts/utils/git-url.ts","../src/commands/thoughts/init-core.ts","../src/hooks/loader.ts","../src/hooks/executor.ts","../src/commands/thoughts/destroy.ts","../src/commands/thoughts/sync.ts","../src/commands/thoughts/status.ts","../src/commands/thoughts/config.ts","../src/commands/thoughts/prune.ts","../src/commands/thoughts/migrate.ts","../src/commands/agent/registry.ts","../src/commands/agent/constants.ts","../src/commands/thoughts/profile/create.ts","../src/commands/thoughts/profile/list.ts","../src/commands/thoughts/profile/show.ts","../src/commands/thoughts/profile/delete.ts","../src/commands/thoughts.ts","../src/commands/agent/init.ts","../src/commands/agent/discovery.ts","../src/commands/agent/installer.ts","../src/commands/agent/update.ts","../src/commands/agent.ts","../src/commands/metadata/metadata.ts","../src/commands/metadata.ts","../src/commands/worktree/add.ts","../src/tmux.ts","../src/agent-config.ts","../src/commands/worktree/list.ts","../src/commands/worktree/merge.ts","../src/commands/worktree/utils.ts","../src/commands/worktree/remove.ts","../src/commands/worktree.ts","../src/commands/hooks/init.ts","../src/commands/hooks.ts","../src/commands/completion.ts","../src/completion/handler.ts","../src/completion/providers.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander'\nimport { thoughtsCommand } from './commands/thoughts.js'\nimport { skillCommand } from './commands/agent.js'\nimport { metadataCommand } from './commands/metadata.js'\nimport { worktreeCommand } from './commands/worktree.js'\nimport { hooksCommand } from './commands/hooks.js'\nimport { completionCommand } from './commands/completion.js'\nimport { handleCompletion } from './completion/handler.js'\nimport dotenv from 'dotenv'\nimport { createRequire } from 'node:module'\n\nasync function main(): Promise<void> {\n // Handle shell completion before anything else\n const completionHandled = await handleCompletion()\n if (completionHandled) {\n process.exit(0)\n }\n\n // Load environment variables\n dotenv.config()\n\n const require = createRequire(import.meta.url)\n const { version } = require('../package.json') as { version: string }\n\n const program = new Command()\n\n program\n .name('thoughtcabinet')\n .description(\n 'Thought Cabinet (thc) — CLI for structured AI coding workflows with filesystem-based memory and context management.',\n )\n .version(version)\n\n // Add commands\n thoughtsCommand(program)\n skillCommand(program)\n metadataCommand(program)\n worktreeCommand(program)\n hooksCommand(program)\n completionCommand(program)\n\n program.parse(process.argv)\n}\n\nmain().catch(err => {\n console.error(err)\n process.exit(1)\n})\n","import fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport {\n ThoughtsConfig,\n loadThoughtsConfig,\n saveThoughtsConfig,\n getDefaultThoughtsRepo,\n ensureThoughtsRepoExists,\n createThoughtsDirectoryStructure,\n getCurrentRepoPath,\n getRepoNameFromPath,\n expandPath,\n getRepoThoughtsPath,\n getGlobalThoughtsPath,\n updateSymlinksForNewUsers,\n getMainRepoPath,\n} from './utils/index.js'\nimport { validateProfile, resolveProfileForRepo, getRepoNameFromMapping, getProfileNameFromMapping } from './profile/utils.js'\nimport { RepoMappingObject } from '../../config.js'\nimport { generateClaudeMd } from '../../templates/index.js'\nimport { setupGitHooks, pullThoughtsFromRemote } from './init-core.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\n\ninterface InitOptions {\n force?: boolean\n configFile?: string\n directory?: string\n profile?: string\n}\n\nfunction sanitizeDirectoryName(name: string): string {\n return name.replace(/[^a-zA-Z0-9_-]/g, '_')\n}\n\nfunction checkExistingSetup(config?: ThoughtsConfig | null): {\n exists: boolean\n isValid: boolean\n message?: string\n} {\n const thoughtsDir = path.join(process.cwd(), 'thoughts')\n\n if (!fs.existsSync(thoughtsDir)) {\n return { exists: false, isValid: false }\n }\n\n // Check if it's a directory\n if (!fs.lstatSync(thoughtsDir).isDirectory()) {\n return { exists: true, isValid: false, message: 'thoughts exists but is not a directory' }\n }\n\n // Need config to check for user-specific symlinks\n if (!config) {\n return {\n exists: true,\n isValid: false,\n message: 'thoughts directory exists but configuration is missing',\n }\n }\n\n // Check for expected symlinks in new structure\n const userPath = path.join(thoughtsDir, config.user)\n const sharedPath = path.join(thoughtsDir, 'shared')\n const globalPath = path.join(thoughtsDir, 'global')\n\n const hasUser = fs.existsSync(userPath) && fs.lstatSync(userPath).isSymbolicLink()\n const hasShared = fs.existsSync(sharedPath) && fs.lstatSync(sharedPath).isSymbolicLink()\n const hasGlobal = fs.existsSync(globalPath) && fs.lstatSync(globalPath).isSymbolicLink()\n\n if (!hasUser || !hasShared || !hasGlobal) {\n return {\n exists: true,\n isValid: false,\n message: 'thoughts directory exists but symlinks are missing or broken',\n }\n }\n\n return { exists: true, isValid: true }\n}\n\nexport async function thoughtsInitCommand(options: InitOptions): Promise<void> {\n try {\n // Check for interactive mode when needed\n if (!options.directory && !process.stdin.isTTY) {\n p.log.error('Not running in interactive terminal.')\n p.log.info('Use --directory flag to specify the repository directory name.')\n process.exit(1)\n }\n\n const currentRepo = getCurrentRepoPath()\n\n // Check if we're in a git repository\n try {\n execSync('git rev-parse --git-dir', { stdio: 'pipe' })\n } catch {\n p.log.error('Not in a git repository')\n process.exit(1)\n }\n\n // Load or create global config first\n let config = loadThoughtsConfig(options)\n\n // If no config exists, we need to set it up first\n if (!config) {\n if (options.directory) {\n // Non-interactive: use sensible defaults\n const thoughtsRepo = getDefaultThoughtsRepo()\n const reposDir = 'repos'\n const globalDir = 'global'\n const user = process.env.USER || 'user'\n\n config = { thoughtsRepo, reposDir, globalDir, user, repoMappings: {} }\n ensureThoughtsRepoExists(thoughtsRepo, reposDir, globalDir)\n saveThoughtsConfig(config, options)\n p.log.success('Global thoughts configuration created with defaults')\n } else {\n p.intro(chalk.blue('Initial Thoughts Setup'))\n\n p.log.info(\"First, let's configure your global thoughts system.\")\n\n // Get thoughts repository location\n const defaultRepo = getDefaultThoughtsRepo()\n p.log.message(\n chalk.gray('This is where all your thoughts across all projects will be stored.'),\n )\n\n const thoughtsRepoInput = await p.text({\n message: 'Thoughts repository location:',\n initialValue: defaultRepo,\n placeholder: defaultRepo,\n })\n\n if (p.isCancel(thoughtsRepoInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n const thoughtsRepo = (thoughtsRepoInput as string) || defaultRepo\n\n // Get directory names\n p.log.message(chalk.gray('Your thoughts will be organized into two main directories:'))\n p.log.message(chalk.gray('- Repository-specific thoughts (one subdirectory per project)'))\n p.log.message(chalk.gray('- Global thoughts (shared across all projects)'))\n\n const reposDirInput = await p.text({\n message: 'Directory name for repository-specific thoughts:',\n initialValue: 'repos',\n placeholder: 'repos',\n })\n\n if (p.isCancel(reposDirInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n const reposDir = (reposDirInput as string) || 'repos'\n\n const globalDirInput = await p.text({\n message: 'Directory name for global thoughts:',\n initialValue: 'global',\n placeholder: 'global',\n })\n\n if (p.isCancel(globalDirInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n const globalDir = (globalDirInput as string) || 'global'\n\n // Get user name\n const defaultUser = process.env.USER || 'user'\n let user = ''\n while (!user || user.toLowerCase() === 'global') {\n const userInput = await p.text({\n message: 'Your username:',\n initialValue: defaultUser,\n placeholder: defaultUser,\n validate: value => {\n if (value.toLowerCase() === 'global') {\n return 'Username cannot be \"global\" as it\\'s reserved for cross-project thoughts.'\n }\n return undefined\n },\n })\n\n if (p.isCancel(userInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n user = (userInput as string) || defaultUser\n }\n\n config = {\n thoughtsRepo,\n reposDir,\n globalDir,\n user,\n repoMappings: {},\n }\n\n // Show what will be created\n p.note(\n `${chalk.cyan(thoughtsRepo)}/\\n` +\n ` ├── ${chalk.cyan(reposDir)}/ ${chalk.gray('(project-specific thoughts)')}\\n` +\n ` └── ${chalk.cyan(globalDir)}/ ${chalk.gray('(cross-project thoughts)')}`,\n 'Creating thoughts structure',\n )\n\n // Ensure thoughts repo exists\n ensureThoughtsRepoExists(thoughtsRepo, reposDir, globalDir)\n\n // Save initial config\n saveThoughtsConfig(config, options)\n p.log.success('Global thoughts configuration created')\n }\n }\n\n // Validate profile if specified\n if (options.profile) {\n if (!validateProfile(config, options.profile)) {\n p.log.error(`Profile \"${options.profile}\" does not exist.`)\n p.log.message(chalk.gray('Available profiles:'))\n if (config.profiles) {\n Object.keys(config.profiles).forEach(name => {\n p.log.message(chalk.gray(` - ${name}`))\n })\n } else {\n p.log.message(chalk.gray(' (none)'))\n }\n p.log.warn('Create a profile first:')\n p.log.message(chalk.gray(` thoughtcabinet profile create ${options.profile}`))\n process.exit(1)\n }\n }\n\n // Resolve profile config early so we use the right thoughtsRepo throughout\n // Create a temporary mapping to resolve the profile (will be updated later with actual mapping)\n const tempProfileConfig =\n options.profile && config.profiles && config.profiles[options.profile]\n ? {\n thoughtsRepo: config.profiles[options.profile].thoughtsRepo,\n reposDir: config.profiles[options.profile].reposDir,\n globalDir: config.profiles[options.profile].globalDir,\n profileName: options.profile,\n }\n : {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n profileName: undefined,\n }\n\n // Now check for existing setup in current repo\n const setupStatus = checkExistingSetup(config)\n\n if (setupStatus.exists && !options.force) {\n if (setupStatus.isValid) {\n p.log.warn('Thoughts directory already configured for this repository.')\n\n const reconfigure = await p.confirm({\n message: 'Do you want to reconfigure?',\n initialValue: false,\n })\n\n if (p.isCancel(reconfigure) || !reconfigure) {\n p.cancel('Setup cancelled.')\n return\n }\n } else {\n p.log.warn(setupStatus.message || 'Thoughts setup is incomplete')\n\n const fix = await p.confirm({\n message: 'Do you want to fix the setup?',\n initialValue: true,\n })\n\n if (p.isCancel(fix) || !fix) {\n p.cancel('Setup cancelled.')\n return\n }\n }\n }\n\n // Ensure thoughts repo still exists (might have been deleted)\n let expandedRepo = expandPath(tempProfileConfig.thoughtsRepo)\n if (!fs.existsSync(expandedRepo)) {\n p.log.error(`Thoughts repository not found at ${tempProfileConfig.thoughtsRepo}`)\n p.log.warn('The thoughts repository may have been moved or deleted.')\n\n const recreate = await p.confirm({\n message: 'Do you want to recreate it?',\n initialValue: true,\n })\n\n if (p.isCancel(recreate) || !recreate) {\n p.log.info('Please update your configuration or restore the thoughts repository.')\n process.exit(1)\n }\n ensureThoughtsRepoExists(\n tempProfileConfig.thoughtsRepo,\n tempProfileConfig.reposDir,\n tempProfileConfig.globalDir,\n )\n }\n\n // Map current repository\n const reposDir = path.join(expandedRepo, tempProfileConfig.reposDir)\n\n // Ensure repos directory exists\n if (!fs.existsSync(reposDir)) {\n fs.mkdirSync(reposDir, { recursive: true })\n }\n\n // Get existing repo directories\n const existingRepos = fs.readdirSync(reposDir).filter(name => {\n const fullPath = path.join(reposDir, name)\n return fs.statSync(fullPath).isDirectory() && !name.startsWith('.')\n })\n\n // Check if current repo is already mapped\n const existingMapping = config.repoMappings[currentRepo]\n let mappedName = getRepoNameFromMapping(existingMapping)\n\n // 检测是否为 worktree,并查找主仓库的映射\n let mainRepoMapping: string | RepoMappingObject | undefined\n let mainRepoPath: string | null = null\n if (!mappedName) {\n mainRepoPath = getMainRepoPath()\n if (mainRepoPath && config.repoMappings[mainRepoPath]) {\n mainRepoMapping = config.repoMappings[mainRepoPath]\n }\n }\n\n if (!mappedName) {\n if (options.directory) {\n // Non-interactive mode with --directory option\n const sanitizedDir = sanitizeDirectoryName(options.directory)\n\n if (existingRepos.includes(sanitizedDir)) {\n p.log.success(\n `Using existing: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${sanitizedDir}`,\n )\n } else {\n p.log.success(\n `Will create: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${sanitizedDir}`,\n )\n }\n\n mappedName = sanitizedDir\n } else {\n // Interactive mode\n p.intro(chalk.blue('Repository Setup'))\n\n p.log.info(`Setting up thoughts for: ${chalk.cyan(currentRepo)}`)\n p.log.message(\n chalk.gray(\n `This will create a subdirectory in ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/`,\n ),\n )\n p.log.message(chalk.gray('to store thoughts specific to this repository.'))\n\n if (existingRepos.length > 0 || mainRepoMapping) {\n // 构建选项列表\n const selectOptions: Array<{ value: string; label: string }> = []\n let initialValue: string | undefined\n\n // 场景1: worktree 有主仓库映射 - 优先显示并默认选中\n const mainRepoMappedName = getRepoNameFromMapping(mainRepoMapping)\n if (mainRepoMappedName && existingRepos.includes(mainRepoMappedName)) {\n selectOptions.push({\n value: mainRepoMappedName,\n label: `Use existing: ${mainRepoMappedName} (from main repository)`,\n })\n initialValue = mainRepoMappedName\n }\n\n // 添加其他现有目录(排除已添加的主仓库映射)\n existingRepos\n .filter(repo => repo !== mainRepoMappedName)\n .forEach(repo => {\n selectOptions.push({ value: repo, label: `Use existing: ${repo}` })\n })\n\n // 创建新目录选项\n selectOptions.push({ value: '__create_new__', label: 'Create new directory' })\n\n // 场景2: 全新 repo(无 worktree 关联)- 默认选择创建新目录\n if (!initialValue) {\n initialValue = '__create_new__'\n }\n\n const selection = await p.select({\n message: 'Select or create a thoughts directory for this repository:',\n options: selectOptions,\n initialValue,\n })\n\n if (p.isCancel(selection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n if (selection === '__create_new__') {\n // Create new\n const defaultName = getRepoNameFromPath(currentRepo)\n p.log.message(\n chalk.gray(\n `This name will be used for the directory: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/[name]`,\n ),\n )\n\n const nameInput = await p.text({\n message: \"Directory name for this project's thoughts:\",\n initialValue: defaultName,\n placeholder: defaultName,\n })\n\n if (p.isCancel(nameInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n mappedName = (nameInput as string) || defaultName\n\n // Sanitize the name\n mappedName = sanitizeDirectoryName(mappedName)\n p.log.success(\n `Will create: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${mappedName}`,\n )\n } else {\n mappedName = selection as string\n\n // 如果选择了主仓库的目录,继承其 profile\n if (mainRepoMapping && mappedName === mainRepoMappedName) {\n const inheritedProfile = getProfileNameFromMapping(mainRepoMapping)\n if (inheritedProfile && !options.profile) {\n options.profile = inheritedProfile\n p.log.info(`Inheriting profile \"${inheritedProfile}\" from main repository`)\n }\n }\n\n p.log.success(\n `Will use existing: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${mappedName}`,\n )\n }\n } else {\n // No existing repos and no worktree mapping, just create new\n const defaultName = getRepoNameFromPath(currentRepo)\n p.log.message(\n chalk.gray(\n `This name will be used for the directory: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/[name]`,\n ),\n )\n\n const nameInput = await p.text({\n message: \"Directory name for this project's thoughts:\",\n initialValue: defaultName,\n placeholder: defaultName,\n })\n\n if (p.isCancel(nameInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n mappedName = (nameInput as string) || defaultName\n\n // Sanitize the name\n mappedName = sanitizeDirectoryName(mappedName)\n p.log.success(\n `Will create: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${mappedName}`,\n )\n }\n }\n\n // Update config with profile-aware mapping\n if (options.profile) {\n config.repoMappings[currentRepo] = {\n repo: mappedName,\n profile: options.profile,\n }\n } else {\n // Keep string format for backward compatibility\n config.repoMappings[currentRepo] = mappedName\n }\n saveThoughtsConfig(config, options)\n\n // 如果继承了 profile,需要刷新 expandedRepo 以用于后续的 git pull 操作\n const inheritedProfile = getProfileNameFromMapping(mainRepoMapping)\n if (inheritedProfile && options.profile === inheritedProfile && tempProfileConfig.profileName !== inheritedProfile) {\n const profileSettings = config.profiles?.[inheritedProfile]\n if (profileSettings) {\n expandedRepo = expandPath(profileSettings.thoughtsRepo)\n }\n }\n }\n\n // Ensure mappedName is resolved when mapping already existed\n if (!mappedName) {\n mappedName = getRepoNameFromMapping(config.repoMappings[currentRepo])!\n }\n\n // Resolve profile config for directory creation\n const profileConfig = resolveProfileForRepo(config, currentRepo)\n\n // Create directory structure using profile config\n createThoughtsDirectoryStructure(profileConfig, mappedName, config.user)\n\n // Create thoughts directory in current repo\n const thoughtsDir = path.join(currentRepo, 'thoughts')\n if (fs.existsSync(thoughtsDir)) {\n fs.rmSync(thoughtsDir, { recursive: true, force: true })\n }\n fs.mkdirSync(thoughtsDir)\n\n // Create symlinks - flipped structure for easier access\n const repoTarget = getRepoThoughtsPath(profileConfig, mappedName)\n const globalTarget = getGlobalThoughtsPath(profileConfig)\n\n // Direct symlinks to user and shared directories for repo-specific thoughts\n fs.symlinkSync(path.join(repoTarget, config.user), path.join(thoughtsDir, config.user), 'dir')\n fs.symlinkSync(path.join(repoTarget, 'shared'), path.join(thoughtsDir, 'shared'), 'dir')\n\n // Global directory as before\n fs.symlinkSync(globalTarget, path.join(thoughtsDir, 'global'), 'dir')\n\n // Check for other users and create symlinks\n const otherUsers = updateSymlinksForNewUsers(\n currentRepo,\n profileConfig,\n mappedName,\n config.user,\n )\n\n if (otherUsers.length > 0) {\n p.log.success(`Added symlinks for other users: ${otherUsers.join(', ')}`)\n }\n\n // Pull latest thoughts if remote exists\n if (pullThoughtsFromRemote(expandedRepo)) {\n p.log.success('Pulled latest thoughts from remote')\n }\n\n // Generate CLAUDE.md\n const claudeMd = generateClaudeMd({\n thoughtsRepo: profileConfig.thoughtsRepo,\n reposDir: profileConfig.reposDir,\n repoName: mappedName,\n user: config.user,\n })\n fs.writeFileSync(path.join(thoughtsDir, 'CLAUDE.md'), claudeMd)\n\n // Setup git hooks\n const hookResult = setupGitHooks(currentRepo)\n if (hookResult.updated.length > 0) {\n p.log.step(`Updated git hooks: ${hookResult.updated.join(', ')}`)\n }\n\n p.log.success('Thoughts setup complete!')\n\n // Summary note\n const structureText =\n `${chalk.cyan(currentRepo)}/\\n` +\n ` └── thoughts/\\n` +\n ` ├── ${config.user}/ ${chalk.gray(`→ ${profileConfig.thoughtsRepo}/${profileConfig.reposDir}/${mappedName}/${config.user}/`)}\\n` +\n ` ├── shared/ ${chalk.gray(`→ ${profileConfig.thoughtsRepo}/${profileConfig.reposDir}/${mappedName}/shared/`)}\\n` +\n ` └── global/ ${chalk.gray(`→ ${profileConfig.thoughtsRepo}/${profileConfig.globalDir}/`)}\\n` +\n ` ├── ${config.user}/ ${chalk.gray('(your cross-repo notes)')}\\n` +\n ` └── shared/ ${chalk.gray('(team cross-repo notes)')}`\n\n p.note(structureText, 'Repository structure created')\n\n p.note(\n `${chalk.green('✓')} Pre-commit hook: Prevents committing thoughts/\\n` +\n `${chalk.green('✓')} Post-commit hook: Auto-syncs thoughts after commits`,\n 'Protection enabled',\n )\n\n // Execute PostThoughtsInit hooks\n const hooksConfig = loadHooksConfig(currentRepo)\n const postInitHooks = getHooksForEvent(hooksConfig, 'PostThoughtsInit')\n\n if (postInitHooks.length > 0) {\n const hookInput = {\n hook_event_name: 'PostThoughtsInit' as const,\n cwd: currentRepo,\n thoughts_repo: profileConfig.thoughtsRepo,\n repos_dir: profileConfig.reposDir,\n global_dir: profileConfig.globalDir,\n mapped_name: mappedName,\n user: config.user,\n }\n\n const hookEnv = {\n THC_THOUGHTS_REPO: profileConfig.thoughtsRepo,\n THC_REPOS_DIR: profileConfig.reposDir,\n THC_GLOBAL_DIR: profileConfig.globalDir,\n THC_MAPPED_NAME: mappedName,\n THC_USER: config.user,\n }\n\n await executeHooks(postInitHooks, hookInput, hookEnv, true)\n }\n\n p.outro(\n chalk.gray('Next steps:\\n') +\n chalk.gray(\n ` 1. Run ${chalk.cyan('thoughtcabinet sync')} to create the searchable index\\n`,\n ) +\n chalk.gray(\n ` 2. Create markdown files in ${chalk.cyan(`thoughts/${config.user}/`)} for your notes\\n`,\n ) +\n chalk.gray(` 3. Your thoughts will sync automatically when you commit code\\n`) +\n chalk.gray(` 4. Run ${chalk.cyan('thoughtcabinet status')} to check sync status`),\n )\n } catch (error) {\n p.log.error(`Error during thoughts init: ${error}`)\n process.exit(1)\n }\n}\n","import dotenv from 'dotenv'\nimport fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\n\n// Load environment variables\ndotenv.config()\n\nexport type RepoMappingObject = {\n repo: string\n profile?: string\n}\n\nexport type ProfileConfig = {\n thoughtsRepo: string\n reposDir: string\n globalDir: string\n}\n\nexport type ConfigFile = {\n thoughts?: {\n thoughtsRepo: string\n reposDir: string\n globalDir: string\n user: string\n repoMappings: Record<string, string | RepoMappingObject>\n profiles?: Record<string, ProfileConfig>\n commitRepoPrefix?: boolean\n }\n}\n\nexport class ConfigResolver {\n public static DEFAULT_CONFIG_FILE = 'config.json'\n public configFile: ConfigFile\n private configFilePath: string\n\n constructor(options: { configFile?: string } = {}) {\n this.configFile = this.loadConfigFile(options.configFile)\n this.configFilePath = this.getConfigFilePath(options.configFile)\n }\n\n loadConfigFile(configFile?: string): ConfigFile {\n if (configFile) {\n const configContent = fs.readFileSync(configFile, 'utf8')\n return JSON.parse(configContent)\n }\n\n // these do not merge today\n const configPaths = [ConfigResolver.DEFAULT_CONFIG_FILE, getDefaultConfigPath()]\n\n for (const configPath of configPaths) {\n try {\n if (fs.existsSync(configPath)) {\n const configContent = fs.readFileSync(configPath, 'utf8')\n return JSON.parse(configContent)\n }\n } catch (error) {\n console.error(chalk.yellow(`Warning: Could not parse config file ${configPath}: ${error}`))\n }\n }\n\n return {}\n }\n\n private getConfigFilePath(configFile?: string): string {\n if (configFile) return configFile\n\n const configPaths = [ConfigResolver.DEFAULT_CONFIG_FILE, getDefaultConfigPath()]\n for (const configPath of configPaths) {\n try {\n if (fs.existsSync(configPath)) {\n return configPath\n }\n } catch {\n // Continue to next path\n }\n }\n return getDefaultConfigPath() // fallback\n }\n}\n\nexport function loadConfigFile(configFile?: string): ConfigFile {\n const resolver = new ConfigResolver({ configFile })\n return resolver.loadConfigFile(configFile)\n}\n\nexport function saveConfigFile(config: ConfigFile, configFile?: string): void {\n const configPath = configFile || getDefaultConfigPath()\n\n console.log(chalk.yellow(`Writing config to ${configPath}`))\n\n // Create directory if it doesn't exist\n const configDir = path.dirname(configPath)\n fs.mkdirSync(configDir, { recursive: true })\n\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2))\n\n console.log(chalk.green('Config saved successfully'))\n}\n\nexport function getDefaultConfigDir(): string {\n if (process.env.XDG_CONFIG_HOME) {\n return path.join(process.env.XDG_CONFIG_HOME, 'thought-cabinet')\n }\n return path.join(process.env.HOME || '', '.thought-cabinet')\n}\n\nexport function getLegacyConfigDir(): string {\n return path.join(process.env.HOME || '', '.config', 'thought-cabinet')\n}\n\nexport function resolveConfigDir(): string {\n const newDir = getDefaultConfigDir()\n const newConfigPath = path.join(newDir, ConfigResolver.DEFAULT_CONFIG_FILE)\n\n if (fs.existsSync(newConfigPath)) {\n return newDir\n }\n\n const legacyDir = getLegacyConfigDir()\n const legacyConfigPath = path.join(legacyDir, ConfigResolver.DEFAULT_CONFIG_FILE)\n\n if (fs.existsSync(legacyConfigPath)) {\n return legacyDir\n }\n\n // Neither exists — use new location for fresh installs\n return newDir\n}\n\nexport function getDefaultConfigPath(): string {\n return path.join(resolveConfigDir(), ConfigResolver.DEFAULT_CONFIG_FILE)\n}\n","import { ConfigResolver, saveConfigFile } from '../../../config.js'\nimport type { RepoMappingObject, ProfileConfig } from '../../../config.js'\n\n/**\n * Thoughts configuration interface\n */\nexport interface ThoughtsConfig {\n thoughtsRepo: string\n reposDir: string // Directory name within thoughtsRepo (e.g., \"repos\")\n globalDir: string // Directory name within thoughtsRepo (e.g., \"global\")\n user: string\n repoMappings: Record<string, string | RepoMappingObject>\n profiles?: Record<string, ProfileConfig>\n commitRepoPrefix?: boolean\n}\n\n/**\n * Resolved profile configuration interface\n */\nexport interface ResolvedProfileConfig {\n thoughtsRepo: string\n reposDir: string\n globalDir: string\n profileName?: string // undefined for default config\n}\n\n/**\n * Load thoughts configuration from config file\n */\nexport function loadThoughtsConfig(options: Record<string, unknown> = {}): ThoughtsConfig | null {\n const resolver = new ConfigResolver(options)\n return resolver.configFile.thoughts || null\n}\n\n/**\n * Save thoughts configuration to config file\n */\nexport function saveThoughtsConfig(\n thoughtsConfig: ThoughtsConfig,\n options: Record<string, unknown> = {},\n): void {\n const resolver = new ConfigResolver(options)\n resolver.configFile.thoughts = thoughtsConfig\n saveConfigFile(resolver.configFile, options.configFile as string | undefined)\n}\n","import path from 'path'\nimport os from 'os'\nimport type { ResolvedProfileConfig } from './config.js'\nimport { getDefaultConfigDir } from '../../../config.js'\n\n// Re-export getMainRepoPath from git module for backward compatibility\nexport { getMainRepoPath } from '../../../git.js'\n\nexport function getDefaultThoughtsRepo(): string {\n return path.join(getDefaultConfigDir(), 'thoughts')\n}\n\nexport function expandPath(filePath: string): string {\n if (filePath.startsWith('~/')) {\n return path.join(os.homedir(), filePath.slice(2))\n }\n return path.resolve(filePath)\n}\n\nexport function getCurrentRepoPath(): string {\n return process.cwd()\n}\n\nexport function getRepoNameFromPath(repoPath: string): string {\n // Extract a reasonable name from the repo path\n const parts = repoPath.split(path.sep)\n return parts[parts.length - 1] || 'unnamed_repo'\n}\n\n// Overloaded signatures for getRepoThoughtsPath\nexport function getRepoThoughtsPath(config: ResolvedProfileConfig, repoName: string): string\nexport function getRepoThoughtsPath(\n thoughtsRepo: string,\n reposDir: string,\n repoName: string,\n): string\nexport function getRepoThoughtsPath(\n thoughtsRepoOrConfig: string | ResolvedProfileConfig,\n reposDirOrRepoName: string,\n repoName?: string,\n): string {\n if (typeof thoughtsRepoOrConfig === 'string') {\n // Legacy signature: (thoughtsRepo, reposDir, repoName)\n return path.join(expandPath(thoughtsRepoOrConfig), reposDirOrRepoName, repoName!)\n }\n\n // New signature: (config, repoName)\n const config = thoughtsRepoOrConfig\n return path.join(expandPath(config.thoughtsRepo), config.reposDir, reposDirOrRepoName)\n}\n\n// Overloaded signatures for getGlobalThoughtsPath\nexport function getGlobalThoughtsPath(config: ResolvedProfileConfig): string\nexport function getGlobalThoughtsPath(thoughtsRepo: string, globalDir: string): string\nexport function getGlobalThoughtsPath(\n thoughtsRepoOrConfig: string | ResolvedProfileConfig,\n globalDir?: string,\n): string {\n if (typeof thoughtsRepoOrConfig === 'string') {\n // Legacy signature: (thoughtsRepo, globalDir)\n return path.join(expandPath(thoughtsRepoOrConfig), globalDir!)\n }\n\n // New signature: (config)\n const config = thoughtsRepoOrConfig\n return path.join(expandPath(config.thoughtsRepo), config.globalDir)\n}\n\n","import { execFileSync } from 'child_process'\nimport path from 'path'\n\n// Types\nexport interface WorktreeEntry {\n worktreePath: string\n branch: string\n detached: boolean\n}\n\nexport interface GitRunOptions {\n cwd?: string\n}\n\n// Command execution\nexport function runGitCommand(args: string[], opts: GitRunOptions = {}): string {\n return execFileSync('git', args, {\n cwd: opts.cwd,\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'pipe'],\n }).trim()\n}\n\nexport function runGitCommandOrThrow(args: string[], opts: GitRunOptions = {}): void {\n execFileSync('git', args, {\n cwd: opts.cwd,\n stdio: 'inherit',\n })\n}\n\n// Repository detection\nexport function isGitRepo(cwd?: string): boolean {\n try {\n runGitCommand(['rev-parse', '--git-dir'], { cwd })\n return true\n } catch {\n return false\n }\n}\n\n/**\n * 获取当前 git 仓库的主仓库路径(处理 worktree 场景)\n * 如果当前目录是 worktree,返回主仓库路径;否则返回 null\n */\nexport function getMainRepoPath(cwd?: string): string | null {\n try {\n const gitCommonDir = runGitCommand(['rev-parse', '--git-common-dir'], { cwd })\n const gitDir = runGitCommand(['rev-parse', '--git-dir'], { cwd })\n\n if (gitCommonDir !== gitDir && gitCommonDir !== '.git') {\n const mainRepoPath = path.dirname(path.resolve(gitCommonDir))\n return mainRepoPath\n }\n\n return null\n } catch {\n return null\n }\n}\n\n// Worktree handle validation\nexport function validateWorktreeHandle(name: string): void {\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name)) {\n throw new Error(\n `Invalid worktree name '${name}'. Use only [A-Za-z0-9._-] and start with a letter/number.`,\n )\n }\n}\n\n// Worktree list parsing\nexport function parseWorktreeListPorcelain(output: string): WorktreeEntry[] {\n const blocks = output.trim().length === 0 ? [] : output.trim().split(/\\n\\n+/)\n const out: WorktreeEntry[] = []\n\n for (const block of blocks) {\n let worktreePath = ''\n let branch = ''\n let detached = false\n\n for (const line of block.split('\\n')) {\n if (line.startsWith('worktree ')) {\n worktreePath = line.slice('worktree '.length).trim()\n } else if (line.startsWith('branch refs/heads/')) {\n branch = line.slice('branch refs/heads/'.length).trim()\n } else if (line.trim() === 'detached') {\n detached = true\n branch = '(detached)'\n }\n }\n\n if (worktreePath && branch) {\n out.push({ worktreePath, branch, detached })\n }\n }\n\n return out\n}\n\n// Worktree operations\nexport function getMainWorktreeRoot(cwd?: string): string {\n const list = runGitCommand(['worktree', 'list', '--porcelain'], { cwd })\n const entries = parseWorktreeListPorcelain(list)\n if (entries.length === 0) {\n throw new Error('No git worktrees found')\n }\n return entries[0].worktreePath\n}\n\nexport function getWorktreesBaseDir(mainWorktreeRoot: string): string {\n const repoName = path.basename(mainWorktreeRoot)\n const parent = path.dirname(mainWorktreeRoot)\n return path.join(parent, `${repoName}__worktrees`)\n}\n\nexport function findWorktree(nameOrBranch: string, cwd?: string): WorktreeEntry {\n const list = runGitCommand(['worktree', 'list', '--porcelain'], { cwd })\n const entries = parseWorktreeListPorcelain(list)\n\n // 1) Match by handle (directory name)\n for (const e of entries) {\n if (path.basename(e.worktreePath) === nameOrBranch) {\n return e\n }\n }\n\n // 2) Match by branch name\n for (const e of entries) {\n if (e.branch === nameOrBranch) {\n return e\n }\n }\n\n throw new Error(`Worktree not found: ${nameOrBranch}`)\n}\n\n// Status checking\nexport function hasUncommittedChanges(repoPath: string): boolean {\n const status = runGitCommand(['status', '--porcelain'], { cwd: repoPath })\n return status.trim().length > 0\n}\n\nexport function hasUnmergedCommits(branch: string, targetBranch: string, cwd: string): boolean {\n try {\n const count = runGitCommand(['rev-list', '--count', `${targetBranch}..${branch}`], { cwd })\n return parseInt(count, 10) > 0\n } catch {\n // If comparison fails, assume there might be unmerged commits\n return true\n }\n}\n\nfunction branchExists(branch: string, cwd: string): boolean {\n try {\n runGitCommand(['rev-parse', '--verify', branch], { cwd })\n return true\n } catch {\n return false\n }\n}\n\nexport function getDefaultBranch(cwd: string): string {\n try {\n const remoteBranch = runGitCommand(['symbolic-ref', 'refs/remotes/origin/HEAD'], { cwd })\n return remoteBranch.replace('refs/remotes/origin/', '')\n } catch {\n // Remote HEAD not set, fall back to checking local branches\n }\n\n if (branchExists('main', cwd)) return 'main'\n if (branchExists('master', cwd)) return 'master'\n return 'main'\n}\n\n// Configuration\nexport function setBranchBase(branch: string, base: string, cwd?: string): void {\n runGitCommandOrThrow(['config', '--local', `branch.${branch}.thc-base`, base], { cwd })\n}\n\n// Branch and commit info\nexport function getCurrentBranch(cwd?: string): string {\n try {\n return runGitCommand(['branch', '--show-current'], { cwd })\n } catch {\n try {\n return runGitCommand(['rev-parse', '--abbrev-ref', 'HEAD'], { cwd })\n } catch {\n return ''\n }\n }\n}\n\nexport function getCurrentCommit(cwd?: string): string {\n try {\n return runGitCommand(['rev-parse', 'HEAD'], { cwd })\n } catch {\n return ''\n }\n}\n\nexport function getWorktreeRoot(cwd?: string): string {\n return runGitCommand(['rev-parse', '--show-toplevel'], { cwd })\n}\n\nexport function getRepoRoot(cwd?: string): string {\n // If in a worktree, return the main repo path\n const mainRepoPath = getMainRepoPath(cwd)\n if (mainRepoPath) {\n return mainRepoPath\n }\n // Otherwise return the current worktree root (which is the main repo)\n return getWorktreeRoot(cwd)\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport {\n generateGitignore,\n generateRepoReadme,\n generateGlobalReadme,\n} from '../../../templates/index.js'\nimport type { ResolvedProfileConfig } from './config.js'\nimport { expandPath, getRepoThoughtsPath, getGlobalThoughtsPath } from './paths.js'\n\n// Overloaded signatures for ensureThoughtsRepoExists\nexport function ensureThoughtsRepoExists(config: ResolvedProfileConfig): void\nexport function ensureThoughtsRepoExists(\n thoughtsRepo: string,\n reposDir: string,\n globalDir: string,\n): void\nexport function ensureThoughtsRepoExists(\n configOrThoughtsRepo: ResolvedProfileConfig | string,\n reposDir?: string,\n globalDir?: string,\n): void {\n let thoughtsRepo: string\n let effectiveReposDir: string\n let effectiveGlobalDir: string\n\n if (typeof configOrThoughtsRepo === 'string') {\n // Legacy signature: (thoughtsRepo, reposDir, globalDir)\n thoughtsRepo = configOrThoughtsRepo\n effectiveReposDir = reposDir!\n effectiveGlobalDir = globalDir!\n } else {\n // New signature: (config)\n thoughtsRepo = configOrThoughtsRepo.thoughtsRepo\n effectiveReposDir = configOrThoughtsRepo.reposDir\n effectiveGlobalDir = configOrThoughtsRepo.globalDir\n }\n\n const expandedRepo = expandPath(thoughtsRepo)\n\n // Create thoughts repo if it doesn't exist\n if (!fs.existsSync(expandedRepo)) {\n fs.mkdirSync(expandedRepo, { recursive: true })\n }\n\n // Create subdirectories\n const expandedRepos = path.join(expandedRepo, effectiveReposDir)\n const expandedGlobal = path.join(expandedRepo, effectiveGlobalDir)\n\n if (!fs.existsSync(expandedRepos)) {\n fs.mkdirSync(expandedRepos, { recursive: true })\n }\n\n if (!fs.existsSync(expandedGlobal)) {\n fs.mkdirSync(expandedGlobal, { recursive: true })\n }\n\n // Check if we're in a git repo (handle both .git directory and .git file for worktrees)\n const gitPath = path.join(expandedRepo, '.git')\n const isGitRepo =\n fs.existsSync(gitPath) && (fs.statSync(gitPath).isDirectory() || fs.statSync(gitPath).isFile())\n\n if (!isGitRepo) {\n // Initialize as git repo\n execSync('git init', { cwd: expandedRepo })\n\n // Create initial .gitignore\n const gitignore = generateGitignore()\n fs.writeFileSync(path.join(expandedRepo, '.gitignore'), gitignore)\n\n // Initial commit\n execSync('git add .gitignore', { cwd: expandedRepo })\n execSync('git commit -m \"Initial thoughts repository setup\"', { cwd: expandedRepo })\n }\n}\n\n// Overloaded signatures for createThoughtsDirectoryStructure\nexport function createThoughtsDirectoryStructure(\n config: ResolvedProfileConfig,\n repoName: string,\n user: string,\n): void\nexport function createThoughtsDirectoryStructure(\n thoughtsRepo: string,\n reposDir: string,\n globalDir: string,\n repoName: string,\n user: string,\n): void\nexport function createThoughtsDirectoryStructure(\n configOrThoughtsRepo: ResolvedProfileConfig | string,\n reposDirOrRepoName: string,\n globalDirOrUser: string,\n repoName?: string,\n user?: string,\n): void {\n let resolvedConfig: { thoughtsRepo: string; reposDir: string; globalDir: string }\n let effectiveRepoName: string\n let effectiveUser: string\n\n if (typeof configOrThoughtsRepo === 'string') {\n // Legacy signature: (thoughtsRepo, reposDir, globalDir, repoName, user)\n resolvedConfig = {\n thoughtsRepo: configOrThoughtsRepo,\n reposDir: reposDirOrRepoName,\n globalDir: globalDirOrUser,\n }\n effectiveRepoName = repoName!\n effectiveUser = user!\n } else {\n // New signature: (config, repoName, user)\n resolvedConfig = configOrThoughtsRepo\n effectiveRepoName = reposDirOrRepoName\n effectiveUser = globalDirOrUser\n }\n\n // Create repo-specific directories\n const repoThoughtsPath = getRepoThoughtsPath(\n resolvedConfig.thoughtsRepo,\n resolvedConfig.reposDir,\n effectiveRepoName,\n )\n const repoUserPath = path.join(repoThoughtsPath, effectiveUser)\n const repoSharedPath = path.join(repoThoughtsPath, 'shared')\n\n // Create global directories\n const globalPath = getGlobalThoughtsPath(resolvedConfig.thoughtsRepo, resolvedConfig.globalDir)\n const globalUserPath = path.join(globalPath, effectiveUser)\n const globalSharedPath = path.join(globalPath, 'shared')\n\n // Create all directories\n for (const dir of [repoUserPath, repoSharedPath, globalUserPath, globalSharedPath]) {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n }\n\n // Create initial README files\n const repoReadme = generateRepoReadme({\n repoName: effectiveRepoName,\n user: effectiveUser,\n })\n\n const globalReadme = generateGlobalReadme({\n user: effectiveUser,\n })\n\n if (!fs.existsSync(path.join(repoThoughtsPath, 'README.md'))) {\n fs.writeFileSync(path.join(repoThoughtsPath, 'README.md'), repoReadme)\n }\n\n if (!fs.existsSync(path.join(globalPath, 'README.md'))) {\n fs.writeFileSync(path.join(globalPath, 'README.md'), globalReadme)\n }\n}\n","/**\n * Generates .gitignore content for thoughts repository\n */\nexport function generateGitignore(): string {\n return `# OS files\n.DS_Store\nThumbs.db\n\n# Editor files\n.vscode/\n.idea/\n*.swp\n*.swo\n*~\n\n# Temporary files\n*.tmp\n*.bak\n`\n}\n","/**\n * Parameters for generating repository-specific README\n */\nexport interface RepoReadmeParams {\n repoName: string\n user: string\n}\n\n/**\n * Parameters for generating global README\n */\nexport interface GlobalReadmeParams {\n user: string\n}\n\n/**\n * Generates README.md content for repository-specific thoughts directory\n */\nexport function generateRepoReadme({ repoName, user }: RepoReadmeParams): string {\n return `# ${repoName} Thoughts\n\nThis directory contains thoughts and notes specific to the ${repoName} repository.\n\n- \\`${user}/\\` - Your personal notes for this repository\n- \\`shared/\\` - Team-shared notes for this repository\n`\n}\n\n/**\n * Generates README.md content for global thoughts directory\n */\nexport function generateGlobalReadme({ user }: GlobalReadmeParams): string {\n return `# Global Thoughts\n\nThis directory contains thoughts and notes that apply across all repositories.\n\n- \\`${user}/\\` - Your personal cross-repository notes\n- \\`shared/\\` - Team-shared cross-repository notes\n`\n}\n","import path from 'path'\nimport os from 'os'\n\n/**\n * Parameters for generating agent markdown documentation\n */\nexport interface AgentMdParams {\n thoughtsRepo: string\n reposDir: string\n repoName: string\n user: string\n productName: string // 'Claude Code' | 'CodeBuddy Code' | etc.\n}\n\n/**\n * Generates agent markdown content explaining the thoughts directory structure\n */\nexport function generateAgentMd({\n thoughtsRepo,\n reposDir,\n repoName,\n user,\n productName,\n}: AgentMdParams): string {\n const reposPath = path.join(thoughtsRepo, reposDir, repoName).replace(os.homedir(), '~')\n const globalPath = path.join(thoughtsRepo, 'global').replace(os.homedir(), '~')\n\n return `# Thoughts Directory Structure\n\nThis directory contains developer thoughts and notes for the ${repoName} repository.\nIt is managed by the ThoughtCabinet thoughts system and should not be committed to the code repository.\n\n## Structure\n\n- \\`${user}/\\` → Your personal notes for this repository (symlink to ${reposPath}/${user})\n- \\`shared/\\` → Team-shared notes for this repository (symlink to ${reposPath}/shared)\n- \\`global/\\` → Cross-repository thoughts (symlink to ${globalPath})\n - \\`${user}/\\` - Your personal notes that apply across all repositories\n - \\`shared/\\` - Team-shared notes that apply across all repositories\n- \\`searchable/\\` → Hard links for search tools (auto-generated)\n\n## Searching in Thoughts\n\nThe \\`searchable/\\` directory contains hard links to all thoughts files accessible in this repository. This allows search tools to find content without following symlinks.\n\n**IMPORTANT**:\n- Files in \\`thoughts/searchable/\\` are hard links to the original files (editing either updates both)\n- For clarity and consistency, always reference files by their canonical path (e.g., \\`thoughts/${user}/todo.md\\`, not \\`thoughts/searchable/${user}/todo.md\\`)\n- The \\`searchable/\\` directory is automatically updated when you run \\`thoughtcabinet sync\\`\n\nThis design ensures that:\n1. Search tools can find all your thoughts content easily\n2. The symlink structure remains intact for git operations\n3. Files remain editable while maintaining consistent path references\n\n## Usage\n\nCreate markdown files in these directories to document:\n\n- Architecture decisions\n- Design notes\n- TODO items\n- Investigation results\n- Any other development thoughts\n\nQuick access:\n\n- \\`thoughts/${user}/\\` for your repo-specific notes (most common)\n- \\`thoughts/global/${user}/\\` for your cross-repo notes\n\nThese files will be automatically synchronized with your thoughts repository when you commit code changes (when using ${productName}).\n\n## Important\n\n- Never commit the thoughts/ directory to your code repository\n- The git pre-commit hook will prevent accidental commits\n- Use \\`thoughtcabinet sync\\` to manually sync changes\n- Use \\`thoughtcabinet status\\` to see sync status\n`\n}\n\n/**\n * Legacy parameters for backward compatibility\n */\nexport interface ClaudeMdParams {\n thoughtsRepo: string\n reposDir: string\n repoName: string\n user: string\n}\n\n/**\n * Generates CLAUDE.md content (backward compatibility wrapper)\n */\nexport function generateClaudeMd(params: ClaudeMdParams): string {\n return generateAgentMd({ ...params, productName: 'Claude Code' })\n}\n\n/**\n * Generates CODEBUDDY.md content\n */\nexport function generateCodebuddyMd(params: ClaudeMdParams): string {\n return generateAgentMd({ ...params, productName: 'CodeBuddy Code' })\n}\n","/**\n * Current hook version - increment when hooks need updating\n */\nexport const HOOK_VERSION = '1'\n\n/**\n * Parameters for generating pre-commit hook\n */\nexport interface PreCommitHookParams {\n hookPath: string\n}\n\n/**\n * Parameters for generating post-commit hook\n */\nexport interface PostCommitHookParams {\n hookPath: string\n}\n\n/**\n * Generates pre-commit Git hook content to prevent committing thoughts directory\n */\nexport function generatePreCommitHook({ hookPath }: PreCommitHookParams): string {\n return `#!/bin/bash\n# ThoughtCabinet thoughts protection - prevent committing thoughts directory\n# Version: ${HOOK_VERSION}\n\nif git diff --cached --name-only | grep -q \"^thoughts/\"; then\n echo \"❌ Cannot commit thoughts/ to code repository\"\n echo \"The thoughts directory should only exist in your separate thoughts repository.\"\n git reset HEAD -- thoughts/\n exit 1\nfi\n\n# Call any existing pre-commit hook\nif [ -f \"${hookPath}.old\" ]; then\n \"${hookPath}.old\" \"$@\"\nfi\n`\n}\n\n/**\n * Generates post-commit Git hook content for auto-syncing thoughts\n */\nexport function generatePostCommitHook({ hookPath }: PostCommitHookParams): string {\n return `#!/bin/bash\n# ThoughtCabinet thoughts auto-sync\n# Version: ${HOOK_VERSION}\n\n# Check if we're in a worktree\nif [ -f .git ]; then\n # Skip auto-sync in worktrees to avoid repository boundary confusion\n exit 0\nfi\n\n# Get the commit message\nCOMMIT_MSG=$(git log -1 --pretty=%B)\n\n# Auto-sync thoughts after each commit (only in non-worktree repos)\nthoughtcabinet sync --message \"Auto-sync with commit: $COMMIT_MSG\" >/dev/null 2>&1 &\n\n# Call any existing post-commit hook\nif [ -f \"${hookPath}.old\" ]; then\n \"${hookPath}.old\" \"$@\"\nfi\n`\n}\n","import fs from 'fs'\nimport path from 'path'\nimport type { ResolvedProfileConfig } from './config.js'\nimport { getRepoThoughtsPath } from './paths.js'\n\n// Overloaded signatures for updateSymlinksForNewUsers\nexport function updateSymlinksForNewUsers(\n currentRepoPath: string,\n config: ResolvedProfileConfig,\n repoName: string,\n currentUser: string,\n): string[]\nexport function updateSymlinksForNewUsers(\n currentRepoPath: string,\n thoughtsRepo: string,\n reposDir: string,\n repoName: string,\n currentUser: string,\n): string[]\nexport function updateSymlinksForNewUsers(\n currentRepoPath: string,\n configOrThoughtsRepo: ResolvedProfileConfig | string,\n reposDirOrRepoName: string,\n repoNameOrCurrentUser: string,\n currentUser?: string,\n): string[] {\n let resolvedConfig: { thoughtsRepo: string; reposDir: string }\n let effectiveRepoName: string\n let effectiveUser: string\n\n if (typeof configOrThoughtsRepo === 'string') {\n // Legacy signature: (currentRepoPath, thoughtsRepo, reposDir, repoName, currentUser)\n resolvedConfig = {\n thoughtsRepo: configOrThoughtsRepo,\n reposDir: reposDirOrRepoName,\n }\n effectiveRepoName = repoNameOrCurrentUser\n effectiveUser = currentUser!\n } else {\n // New signature: (currentRepoPath, config, repoName, currentUser)\n resolvedConfig = configOrThoughtsRepo\n effectiveRepoName = reposDirOrRepoName\n effectiveUser = repoNameOrCurrentUser\n }\n\n const thoughtsDir = path.join(currentRepoPath, 'thoughts')\n const repoThoughtsPath = getRepoThoughtsPath(\n resolvedConfig.thoughtsRepo,\n resolvedConfig.reposDir,\n effectiveRepoName,\n )\n const addedSymlinks: string[] = []\n\n if (!fs.existsSync(thoughtsDir) || !fs.existsSync(repoThoughtsPath)) {\n return addedSymlinks\n }\n\n // Get all user directories in the repo thoughts\n const entries = fs.readdirSync(repoThoughtsPath, { withFileTypes: true })\n const userDirs = entries\n .filter(entry => entry.isDirectory() && entry.name !== 'shared' && !entry.name.startsWith('.'))\n .map(entry => entry.name)\n\n // Check each user directory and create symlinks if missing\n for (const userName of userDirs) {\n const symlinkPath = path.join(thoughtsDir, userName)\n const targetPath = path.join(repoThoughtsPath, userName)\n\n // Skip if symlink already exists or if it's the current user (already handled)\n if (!fs.existsSync(symlinkPath) && userName !== effectiveUser) {\n try {\n fs.symlinkSync(targetPath, symlinkPath, 'dir')\n addedSymlinks.push(userName)\n } catch {\n // Ignore errors - might be permission issues\n }\n }\n }\n\n return addedSymlinks\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport type { ThoughtsConfig } from './config.js'\nimport { getRepoNameFromMapping, getProfileNameFromMapping } from '../profile/utils.js'\n\nexport interface CleanupThoughtsOptions {\n repoPath: string\n config: ThoughtsConfig\n force?: boolean\n verbose?: boolean\n}\n\nexport interface CleanupThoughtsResult {\n thoughtsRemoved: boolean\n configRemoved: boolean\n mappedName?: string\n profileName?: string\n}\n\n/**\n * Clean up thoughts directory and configuration for a repository\n * Returns information about what was cleaned up\n */\nexport function cleanupThoughtsDirectory({\n repoPath,\n config,\n force = false,\n verbose = true,\n}: CleanupThoughtsOptions): CleanupThoughtsResult {\n const thoughtsDir = path.join(repoPath, 'thoughts')\n const result: CleanupThoughtsResult = {\n thoughtsRemoved: false,\n configRemoved: false,\n }\n\n // Check if thoughts directory exists\n if (!fs.existsSync(thoughtsDir)) {\n return result\n }\n\n const mapping = config.repoMappings[repoPath]\n const mappedName = getRepoNameFromMapping(mapping)\n const profileName = getProfileNameFromMapping(mapping)\n\n result.mappedName = mappedName\n result.profileName = profileName\n\n // Validate mapping unless force is specified\n if (!mappedName && !force) {\n return result\n }\n\n // Step 1: Remove searchable directory if it exists\n const searchableDir = path.join(thoughtsDir, 'searchable')\n if (fs.existsSync(searchableDir)) {\n if (verbose) {\n console.log(chalk.gray('Removing searchable directory...'))\n }\n fs.rmSync(searchableDir, { recursive: true, force: true })\n }\n\n // Step 2: Remove the entire thoughts directory\n if (verbose) {\n console.log(chalk.gray('Removing thoughts directory...'))\n }\n try {\n fs.rmSync(thoughtsDir, { recursive: true, force: true })\n result.thoughtsRemoved = true\n } catch (error) {\n if (verbose) {\n console.error(chalk.red(`Error removing thoughts directory: ${error}`))\n }\n throw error\n }\n\n // Step 3: Remove from config if mapped\n if (mappedName) {\n if (verbose) {\n console.log(chalk.gray('Removing repository from thoughts configuration...'))\n }\n delete config.repoMappings[repoPath]\n result.configRemoved = true\n }\n\n return result\n}\n","import type { RepoMappingObject } from '../../../config.js'\nimport type { ThoughtsConfig, ResolvedProfileConfig } from '../utils/config.js'\n\n/**\n * Resolves the profile config for a given repository path\n * Returns default config if no profile specified or profile not found\n */\nexport function resolveProfileForRepo(\n config: ThoughtsConfig,\n repoPath: string,\n): ResolvedProfileConfig {\n const mapping = config.repoMappings[repoPath]\n\n // Handle string format (legacy - no profile)\n if (typeof mapping === 'string') {\n return {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n profileName: undefined,\n }\n }\n\n // Handle object format\n if (mapping && typeof mapping === 'object') {\n const profileName = mapping.profile\n\n // If profile specified, look it up\n if (profileName && config.profiles && config.profiles[profileName]) {\n const profile = config.profiles[profileName]\n return {\n thoughtsRepo: profile.thoughtsRepo,\n reposDir: profile.reposDir,\n globalDir: profile.globalDir,\n profileName,\n }\n }\n\n // Object format but no profile or profile not found - use default\n return {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n profileName: undefined,\n }\n }\n\n // No mapping - use default\n return {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n profileName: undefined,\n }\n}\n\n/**\n * Gets the repo name from a mapping (handles both string and object formats)\n */\nexport function getRepoNameFromMapping(\n mapping: string | RepoMappingObject | undefined,\n): string | undefined {\n if (!mapping) return undefined\n if (typeof mapping === 'string') return mapping\n return mapping.repo\n}\n\n/**\n * Gets the profile name from a mapping (returns undefined for string format)\n */\nexport function getProfileNameFromMapping(\n mapping: string | RepoMappingObject | undefined,\n): string | undefined {\n if (!mapping) return undefined\n if (typeof mapping === 'string') return undefined\n return mapping.profile\n}\n\n/**\n * Validates that a profile exists in the configuration\n */\nexport function validateProfile(config: ThoughtsConfig, profileName: string): boolean {\n return !!(config.profiles && config.profiles[profileName])\n}\n\n/**\n * Sanitizes profile name (same rules as directory names)\n */\nexport function sanitizeProfileName(name: string): string {\n return name.replace(/[^a-zA-Z0-9_-]/g, '_')\n}\n","export interface ParsedGitUrl {\n host: string\n owner: string\n repo: string\n}\n\n/**\n * Parse a git remote URL into its components.\n *\n * Supports:\n * - SSH: git@github.com:owner/repo.git\n * - HTTPS: https://github.com/owner/repo.git\n * - SSH with protocol: ssh://git@github.com/owner/repo.git\n * - Git protocol: git://github.com/owner/repo.git\n *\n * Returns null if the URL cannot be parsed (e.g., local paths).\n */\nexport function parseGitRemoteUrl(url: string): ParsedGitUrl | null {\n // Strip trailing .git\n const cleaned = url.trim().replace(/\\.git\\/?$/, '')\n\n // SSH format: git@host:owner/repo\n const sshMatch = cleaned.match(/^[\\w-]+@([^:]+):(.+?)\\/([^/]+)$/)\n if (sshMatch) {\n return { host: sshMatch[1], owner: sshMatch[2], repo: sshMatch[3] }\n }\n\n // URL format: https://host/owner/repo or ssh://git@host/owner/repo\n try {\n // Normalize ssh://git@host to just extract host\n const normalized = cleaned\n .replace(/^ssh:\\/\\/[^@]+@/, 'https://')\n .replace(/^git:\\/\\//, 'https://')\n const parsed = new URL(normalized)\n const parts = parsed.pathname.replace(/^\\//, '').split('/')\n if (parts.length >= 2) {\n return { host: parsed.hostname, owner: parts[0], repo: parts[1] }\n }\n } catch {\n // Not a parseable URL\n }\n\n return null\n}\n\n/**\n * Build a browsable HTTPS URL for a file in a git repository.\n *\n * Most platforms (GitHub, GitLab, Gitea, Gogs) use:\n * https://host/owner/repo/blob/branch/path\n *\n * Bitbucket uses:\n * https://host/owner/repo/src/branch/path\n */\nexport function buildFileShareLink(\n parsed: ParsedGitUrl,\n branch: string,\n filePath: string,\n): string {\n const pathSegment = parsed.host.includes('bitbucket') ? 'src' : 'blob'\n const cleanPath = filePath.replace(/^\\//, '')\n return `https://${parsed.host}/${parsed.owner}/${parsed.repo}/${pathSegment}/${branch}/${cleanPath}`\n}\n","/**\n * Core initialization logic for thoughts directory setup.\n * This module contains reusable functions that can be called from both\n * the `thoughtcabinet init` command and `thc worktree add` command.\n */\n\nimport fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport {\n ResolvedProfileConfig,\n getRepoThoughtsPath,\n getGlobalThoughtsPath,\n updateSymlinksForNewUsers,\n expandPath,\n} from './utils/index.js'\nimport {\n generateClaudeMd,\n generatePreCommitHook,\n generatePostCommitHook,\n HOOK_VERSION,\n} from '../../templates/index.js'\n\nexport interface SetupThoughtsOptions {\n /** Code repository path */\n repoPath: string\n /** Resolved profile configuration */\n profileConfig: ResolvedProfileConfig\n /** Thoughts directory name in thoughts repo */\n mappedName: string\n /** Username */\n user: string\n /** Whether to create searchable directory */\n createSearchable?: boolean\n /** Whether to install git hooks */\n setupHooks?: boolean\n}\n\nexport interface SetupThoughtsResult {\n thoughtsDir: string\n otherUsers: string[]\n hooksUpdated: string[]\n}\n\n/**\n * Set up thoughts directory structure and symlinks.\n * Can be reused by init command and worktree add.\n */\nexport function setupThoughtsDirectory(options: SetupThoughtsOptions): SetupThoughtsResult {\n const { repoPath, profileConfig, mappedName, user, createSearchable = false, setupHooks = false } = options\n \n const thoughtsDir = path.join(repoPath, 'thoughts')\n \n // Remove existing thoughts directory if present\n if (fs.existsSync(thoughtsDir)) {\n fs.rmSync(thoughtsDir, { recursive: true, force: true })\n }\n fs.mkdirSync(thoughtsDir)\n \n // Create symlinks\n const repoTarget = getRepoThoughtsPath(profileConfig, mappedName)\n const globalTarget = getGlobalThoughtsPath(profileConfig)\n \n // Direct symlinks to user and shared directories for repo-specific thoughts\n fs.symlinkSync(path.join(repoTarget, user), path.join(thoughtsDir, user), 'dir')\n fs.symlinkSync(path.join(repoTarget, 'shared'), path.join(thoughtsDir, 'shared'), 'dir')\n \n // Global directory\n fs.symlinkSync(globalTarget, path.join(thoughtsDir, 'global'), 'dir')\n \n // Check for other users and create symlinks\n const otherUsers = updateSymlinksForNewUsers(\n repoPath,\n profileConfig,\n mappedName,\n user,\n )\n \n // Generate CLAUDE.md\n const claudeMd = generateClaudeMd({\n thoughtsRepo: profileConfig.thoughtsRepo,\n reposDir: profileConfig.reposDir,\n repoName: mappedName,\n user: user,\n })\n fs.writeFileSync(path.join(thoughtsDir, 'CLAUDE.md'), claudeMd)\n \n // Setup git hooks if requested\n let hooksUpdated: string[] = []\n if (setupHooks) {\n const hookResult = setupGitHooks(repoPath)\n hooksUpdated = hookResult.updated\n }\n \n // Create searchable index if requested\n if (createSearchable) {\n createSearchableIndex(thoughtsDir)\n }\n \n return {\n thoughtsDir,\n otherUsers,\n hooksUpdated,\n }\n}\n\n/**\n * Set up git hooks (pre-commit, post-commit).\n * Extracted from init.ts setupGitHooks().\n */\nexport function setupGitHooks(repoPath: string): { updated: string[] } {\n const updated: string[] = []\n \n // Use git rev-parse to find the common git directory for hooks (handles worktrees)\n // In worktrees, hooks are stored in the common git directory, not the worktree-specific one\n let gitCommonDir: string\n try {\n gitCommonDir = execSync('git rev-parse --git-common-dir', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n\n // If the path is relative, make it absolute\n if (!path.isAbsolute(gitCommonDir)) {\n gitCommonDir = path.join(repoPath, gitCommonDir)\n }\n } catch (error) {\n throw new Error(`Failed to find git common directory: ${error}`)\n }\n\n const hooksDir = path.join(gitCommonDir, 'hooks')\n\n // Ensure hooks directory exists (might not exist in some setups)\n if (!fs.existsSync(hooksDir)) {\n fs.mkdirSync(hooksDir, { recursive: true })\n }\n\n // Pre-commit hook\n const preCommitPath = path.join(hooksDir, 'pre-commit')\n const preCommitContent = generatePreCommitHook({ hookPath: preCommitPath })\n\n // Post-commit hook\n const postCommitPath = path.join(hooksDir, 'post-commit')\n const postCommitContent = generatePostCommitHook({ hookPath: postCommitPath })\n\n // Helper to check if hook needs updating\n const hookNeedsUpdate = (hookPath: string): boolean => {\n if (!fs.existsSync(hookPath)) return true\n const content = fs.readFileSync(hookPath, 'utf8')\n if (!content.includes('ThoughtCabinet thoughts')) return false // Not our hook\n\n // Check version\n const versionMatch = content.match(/# Version: (\\d+)/)\n if (!versionMatch) return true // Old hook without version\n\n const currentVersion = parseInt(versionMatch[1])\n return currentVersion < parseInt(HOOK_VERSION)\n }\n\n // Backup existing hooks if they exist and aren't ours (or need updating)\n if (fs.existsSync(preCommitPath)) {\n const content = fs.readFileSync(preCommitPath, 'utf8')\n if (!content.includes('ThoughtCabinet thoughts') || hookNeedsUpdate(preCommitPath)) {\n // Only backup non-ThoughtCabinet hooks to prevent recursion\n if (!content.includes('ThoughtCabinet thoughts')) {\n fs.renameSync(preCommitPath, `${preCommitPath}.old`)\n } else {\n // For outdated ThoughtCabinet hooks, just remove them\n fs.unlinkSync(preCommitPath)\n }\n }\n }\n\n if (fs.existsSync(postCommitPath)) {\n const content = fs.readFileSync(postCommitPath, 'utf8')\n if (!content.includes('ThoughtCabinet thoughts') || hookNeedsUpdate(postCommitPath)) {\n // Only backup non-ThoughtCabinet hooks to prevent recursion\n if (!content.includes('ThoughtCabinet thoughts')) {\n fs.renameSync(postCommitPath, `${postCommitPath}.old`)\n } else {\n // For outdated ThoughtCabinet hooks, just remove them\n fs.unlinkSync(postCommitPath)\n }\n }\n }\n\n // Write new hooks only if needed\n if (!fs.existsSync(preCommitPath) || hookNeedsUpdate(preCommitPath)) {\n fs.writeFileSync(preCommitPath, preCommitContent)\n fs.chmodSync(preCommitPath, '755')\n updated.push('pre-commit')\n }\n\n if (!fs.existsSync(postCommitPath) || hookNeedsUpdate(postCommitPath)) {\n fs.writeFileSync(postCommitPath, postCommitContent)\n fs.chmodSync(postCommitPath, '755')\n updated.push('post-commit')\n }\n\n return { updated }\n}\n\n/**\n * Create searchable directory with hard links.\n * Extracted from sync.ts createSearchDirectory().\n */\nexport function createSearchableIndex(thoughtsDir: string): number {\n const searchDir = path.join(thoughtsDir, 'searchable')\n \n // Remove existing searchable directory if it exists\n if (fs.existsSync(searchDir)) {\n fs.rmSync(searchDir, { recursive: true, force: true })\n }\n\n // Create new searchable directory\n fs.mkdirSync(searchDir, { recursive: true })\n\n // Function to recursively find all files through symlinks\n function findFilesFollowingSymlinks(\n dir: string,\n baseDir: string = dir,\n visited: Set<string> = new Set(),\n ): string[] {\n const files: string[] = []\n\n // Resolve symlinks to avoid cycles\n const realPath = fs.realpathSync(dir)\n if (visited.has(realPath)) {\n return files\n }\n visited.add(realPath)\n\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name)\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n files.push(...findFilesFollowingSymlinks(fullPath, baseDir, visited))\n } else if (entry.isSymbolicLink() && !entry.name.startsWith('.')) {\n try {\n const stat = fs.statSync(fullPath)\n if (stat.isDirectory()) {\n files.push(...findFilesFollowingSymlinks(fullPath, baseDir, visited))\n } else if (stat.isFile() && path.basename(fullPath) !== 'CLAUDE.md') {\n files.push(path.relative(baseDir, fullPath))\n }\n } catch {\n // Ignore broken symlinks\n }\n } else if (entry.isFile() && !entry.name.startsWith('.') && entry.name !== 'CLAUDE.md') {\n files.push(path.relative(baseDir, fullPath))\n }\n }\n\n return files\n }\n\n // Get all files accessible through the thoughts directory (following symlinks)\n const allFiles = findFilesFollowingSymlinks(thoughtsDir)\n\n // Create hard links in searchable directory\n let linkedCount = 0\n for (const relPath of allFiles) {\n const sourcePath = path.join(thoughtsDir, relPath)\n const targetPath = path.join(searchDir, relPath)\n\n // Create directory structure\n const targetDir = path.dirname(targetPath)\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true })\n }\n\n try {\n // Resolve symlink to get the real file path\n const realSourcePath = fs.realpathSync(sourcePath)\n // Create hard link to the real file\n fs.linkSync(realSourcePath, targetPath)\n linkedCount++\n } catch {\n // Silently skip files we can't link (e.g., different filesystems)\n }\n }\n\n return linkedCount\n}\n\n/**\n * Pull latest thoughts from remote.\n * Extracted from init.ts.\n */\nexport function pullThoughtsFromRemote(thoughtsRepo: string): boolean {\n const expandedRepo = expandPath(thoughtsRepo)\n \n try {\n // Check if remote exists\n execSync('git remote get-url origin', { cwd: expandedRepo, stdio: 'pipe' })\n \n // Remote exists, try to pull\n try {\n execSync('git pull --rebase', {\n stdio: 'pipe',\n cwd: expandedRepo,\n })\n return true\n } catch {\n return false\n }\n } catch {\n // No remote configured, skip pull\n return false\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport type { HooksConfig, HookEvent, Hook } from './types.js'\n\n/**\n * Default hooks configuration directory name\n */\nexport const HOOKS_CONFIG_DIR = '.thought-cabinet'\n\n/**\n * Default hooks configuration file name\n */\nexport const HOOKS_CONFIG_FILE = `${HOOKS_CONFIG_DIR}/hooks.json`\n\n/**\n * Load hooks configuration from repository root\n * @param repoPath - Path to repository\n * @returns Hooks configuration or null if not found\n */\nexport function loadHooksConfig(repoPath: string): HooksConfig | null {\n const configPath = path.join(repoPath, HOOKS_CONFIG_FILE)\n\n if (!fs.existsSync(configPath)) {\n return null\n }\n\n try {\n const content = fs.readFileSync(configPath, 'utf8')\n const config = JSON.parse(content) as HooksConfig\n\n // Basic validation\n if (!config.hooks || typeof config.hooks !== 'object') {\n console.error(\n chalk.yellow(`Warning: Invalid hooks config at ${configPath}: missing 'hooks' object`),\n )\n return null\n }\n\n return config\n } catch (error) {\n console.error(\n chalk.yellow(\n `Warning: Could not parse hooks config at ${configPath}: ${(error as Error).message}`,\n ),\n )\n return null\n }\n}\n\n/**\n * Get all hooks for a specific event\n * @param config - Hooks configuration\n * @param event - Hook event name\n * @returns Array of hooks to execute\n */\nexport function getHooksForEvent(config: HooksConfig | null, event: HookEvent): Hook[] {\n const hookGroups = config?.hooks[event]\n if (!hookGroups) {\n return []\n }\n\n return hookGroups.flatMap(group => group.hooks ?? [])\n}\n","import { spawn } from 'child_process'\nimport chalk from 'chalk'\nimport type { Hook, HookInput, HookExecutionResult } from './types.js'\n\n/**\n * Default timeout for hook execution (60 seconds)\n */\nconst DEFAULT_TIMEOUT_SECONDS = 60\n\n/**\n * Determine the exit code for a hook execution result\n */\nfunction resolveExitCode(exitCode: number | null, timedOut: boolean): number {\n if (exitCode !== null) {\n return exitCode\n }\n if (timedOut) {\n return 124 // Standard timeout exit code\n }\n return 1\n}\n\n/**\n * Execute a single hook\n * @param hook - Hook configuration\n * @param input - Hook input data (passed via stdin as JSON)\n * @param env - Additional environment variables\n * @returns Execution result\n */\nexport async function executeHook(\n hook: Hook,\n input: HookInput,\n env: Record<string, string> = {},\n): Promise<HookExecutionResult> {\n const startTime = Date.now()\n const timeoutMs = (hook.timeout ?? DEFAULT_TIMEOUT_SECONDS) * 1000\n\n return new Promise(resolve => {\n let stdout = ''\n let stderr = ''\n let timedOut = false\n\n const child = spawn('bash', ['-c', hook.command], {\n cwd: input.cwd,\n env: { ...process.env, ...env },\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n\n const timer = setTimeout(() => {\n timedOut = true\n child.kill('SIGTERM')\n\n // Force kill after 5 seconds if still running\n setTimeout(() => {\n if (!child.killed) {\n child.kill('SIGKILL')\n }\n }, 5000)\n }, timeoutMs)\n\n // Send input via stdin (hook may or may not consume it)\n child.stdin.write(JSON.stringify(input, null, 2))\n child.stdin.end()\n\n child.stdout.on('data', data => {\n stdout += data.toString()\n })\n\n child.stderr.on('data', data => {\n stderr += data.toString()\n })\n\n child.on('close', exitCode => {\n clearTimeout(timer)\n const duration = Date.now() - startTime\n\n resolve({\n success: exitCode === 0 && !timedOut,\n exitCode: resolveExitCode(exitCode, timedOut),\n stdout: stdout.trim(),\n stderr: stderr.trim(),\n timedOut,\n duration,\n })\n })\n\n child.on('error', error => {\n clearTimeout(timer)\n const duration = Date.now() - startTime\n\n resolve({\n success: false,\n exitCode: 1,\n stdout: stdout.trim(),\n stderr: `Failed to execute hook: ${error.message}`,\n timedOut: false,\n duration,\n })\n })\n })\n}\n\n/**\n * Display the result of a single hook execution\n */\nfunction displayHookResult(hook: Hook, result: HookExecutionResult, verbose: boolean): void {\n const timeoutSeconds = hook.timeout ?? DEFAULT_TIMEOUT_SECONDS\n\n if (result.timedOut) {\n console.log(chalk.yellow(`Warning: Hook timed out after ${timeoutSeconds}s: ${hook.command}`))\n if (result.stderr) {\n console.log(chalk.yellow(result.stderr))\n }\n return\n }\n\n switch (result.exitCode) {\n case 0:\n console.log(chalk.gray(`Hook completed (${result.duration}ms): ${hook.command}`))\n if (verbose && result.stdout) {\n console.log(chalk.gray(result.stdout))\n }\n break\n\n case 2:\n // Exit code 2: blocking error (always show stderr)\n console.log(chalk.red(`Hook failed with exit code 2: ${hook.command}`))\n if (result.stderr) {\n console.log(chalk.red(result.stderr))\n }\n break\n\n default:\n // Other exit codes: non-blocking error\n console.log(\n chalk.yellow(`Warning: Hook failed with exit code ${result.exitCode}: ${hook.command}`),\n )\n if (verbose && result.stderr) {\n console.log(chalk.yellow(result.stderr))\n }\n }\n}\n\n/**\n * Execute all hooks for an event in parallel\n * @param hooks - Array of hooks to execute\n * @param input - Hook input data\n * @param env - Additional environment variables\n * @param verbose - Show detailed output\n * @returns Array of execution results\n */\nexport async function executeHooks(\n hooks: Hook[],\n input: HookInput,\n env: Record<string, string> = {},\n verbose = false,\n): Promise<HookExecutionResult[]> {\n if (hooks.length === 0) {\n return []\n }\n\n if (verbose) {\n console.log(chalk.gray(`\\nExecuting ${hooks.length} hook(s) for ${input.hook_event_name}...`))\n }\n\n const results = await Promise.all(hooks.map(hook => executeHook(hook, input, env)))\n\n for (let i = 0; i < results.length; i++) {\n displayHookResult(hooks[i], results[i], verbose)\n }\n\n return results\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n getCurrentRepoPath,\n cleanupThoughtsDirectory,\n} from './utils/index.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\n\ninterface DestoryOptions {\n force?: boolean\n configFile?: string\n}\n\nexport async function thoughtsDestoryCommand(options: DestoryOptions): Promise<void> {\n try {\n const currentRepo = getCurrentRepoPath()\n const thoughtsDir = path.join(currentRepo, 'thoughts')\n\n // Check if thoughts directory exists\n if (!fs.existsSync(thoughtsDir)) {\n console.error(chalk.red('Error: Thoughts not initialized for this repository.'))\n process.exit(1)\n }\n\n // Load config\n const config = loadThoughtsConfig(options)\n if (!config) {\n console.error(chalk.red('Error: Thoughts configuration not found.'))\n process.exit(1)\n }\n\n // Check if repository is in config (unless force is specified)\n const mapping = config.repoMappings[currentRepo]\n if (!mapping && !options.force) {\n console.error(chalk.red('Error: This repository is not in the thoughts configuration.'))\n console.error(chalk.yellow('Use --force to remove the thoughts directory anyway.'))\n process.exit(1)\n }\n\n console.log(chalk.blue('Removing thoughts setup from current repository...'))\n\n // Use shared cleanup utility\n const result = cleanupThoughtsDirectory({\n repoPath: currentRepo,\n config,\n force: options.force,\n verbose: true,\n })\n\n // Save updated config\n if (result.configRemoved) {\n saveThoughtsConfig(config, options)\n }\n\n console.log(chalk.green('✅ Thoughts removed from repository'))\n\n // Provide info about what was done\n if (result.mappedName) {\n console.log('')\n console.log(chalk.gray('Note: Your thoughts content remains safe in:'))\n\n if (result.profileName && config.profiles && config.profiles[result.profileName]) {\n const profile = config.profiles[result.profileName]\n console.log(chalk.gray(` ${profile.thoughtsRepo}/${profile.reposDir}/${result.mappedName}`))\n console.log(chalk.gray(` (profile: ${result.profileName})`))\n } else {\n console.log(chalk.gray(` ${config.thoughtsRepo}/${config.reposDir}/${result.mappedName}`))\n }\n\n console.log(chalk.gray('Only the local symlinks and configuration were removed.'))\n }\n\n // Execute PostThoughtsDestroy hooks\n const hooksConfig = loadHooksConfig(currentRepo)\n const postDestroyHooks = getHooksForEvent(hooksConfig, 'PostThoughtsDestroy')\n\n if (postDestroyHooks.length > 0) {\n const hookInput = {\n hook_event_name: 'PostThoughtsDestroy' as const,\n cwd: currentRepo,\n thoughts_removed: result.thoughtsRemoved,\n config_removed: result.configRemoved,\n mapped_name: result.mappedName,\n profile_name: result.profileName,\n }\n\n const hookEnv = {\n THC_THOUGHTS_REMOVED: result.thoughtsRemoved ? 'true' : 'false',\n THC_CONFIG_REMOVED: result.configRemoved ? 'true' : 'false',\n THC_MAPPED_NAME: result.mappedName || '',\n THC_PROFILE_NAME: result.profileName || '',\n }\n\n await executeHooks(postDestroyHooks, hookInput, hookEnv, true)\n }\n } catch (error) {\n console.error(chalk.red(`Error during thoughts destroy: ${error}`))\n process.exit(1)\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { execSync, execFileSync } from 'child_process'\nimport chalk from 'chalk'\nimport {\n loadThoughtsConfig,\n getCurrentRepoPath,\n expandPath,\n getRepoNameFromPath,\n updateSymlinksForNewUsers,\n parseGitRemoteUrl,\n buildFileShareLink,\n} from './utils/index.js'\nimport { resolveProfileForRepo, getRepoNameFromMapping } from './profile/utils.js'\nimport { createSearchableIndex } from './init-core.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\n\ninterface SyncOptions {\n message?: string\n configFile?: string\n}\n\nfunction checkGitStatus(repoPath: string): boolean {\n try {\n const status = execSync('git status --porcelain', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n })\n return status.trim().length > 0\n } catch {\n return false\n }\n}\n\nfunction syncThoughts(thoughtsRepo: string, message: string, repoName?: string): void {\n const expandedRepo = expandPath(thoughtsRepo)\n\n try {\n // Stage all changes\n execSync('git add -A', { cwd: expandedRepo, stdio: 'pipe' })\n\n // Check if there are changes to commit\n const hasChanges = checkGitStatus(expandedRepo)\n\n if (hasChanges) {\n // Commit changes\n const defaultMessage = `Sync thoughts - ${new Date().toISOString()}`\n const body = message || defaultMessage\n const commitMessage = repoName ? `[${repoName}] ${body}` : body\n execFileSync('git', ['commit', '-m', commitMessage], { cwd: expandedRepo, stdio: 'pipe' })\n\n console.log(chalk.green('✅ Thoughts synchronized'))\n } else {\n console.log(chalk.gray('No changes to commit'))\n }\n\n // Pull latest changes after committing (to avoid conflicts with staged changes)\n try {\n execSync('git pull --rebase', {\n stdio: 'pipe',\n cwd: expandedRepo,\n })\n } catch (error) {\n const errorStr = error.toString()\n if (\n errorStr.includes('CONFLICT (') ||\n errorStr.includes('Automatic merge failed') ||\n errorStr.includes('Patch failed at') ||\n errorStr.includes('When you have resolved this problem, run \"git rebase --continue\"')\n ) {\n console.error(chalk.red('Error: Merge conflict detected in thoughts repository'))\n console.error(chalk.red('Please resolve conflicts manually in:'), expandedRepo)\n console.error(chalk.red('Then run \"git rebase --continue\" and \"thoughtcabinet sync\" again'))\n process.exit(1)\n } else {\n // If pull fails for other reasons, show warning but continue\n // This handles cases like no upstream, network issues, etc.\n console.warn(chalk.yellow('Warning: Could not pull latest changes:'), error.message)\n }\n }\n\n // Check if remote exists and push any unpushed commits\n try {\n execSync('git remote get-url origin', { cwd: expandedRepo, stdio: 'pipe' })\n\n // Try to push\n console.log(chalk.gray('Pushing to remote...'))\n try {\n execSync('git push', { cwd: expandedRepo, stdio: 'pipe' })\n console.log(chalk.green('✅ Pushed to remote'))\n\n // Generate share links for changed files\n try {\n const branch = execSync('git rev-parse --abbrev-ref HEAD', {\n cwd: expandedRepo,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n\n const changedFiles = execSync('git diff --name-only HEAD~1 HEAD', {\n cwd: expandedRepo,\n encoding: 'utf8',\n stdio: 'pipe',\n })\n .trim()\n .split('\\n')\n .filter(Boolean)\n\n const remoteUrl = execSync('git remote get-url origin', {\n cwd: expandedRepo,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n\n const parsed = parseGitRemoteUrl(remoteUrl)\n if (parsed && changedFiles.length > 0) {\n console.log(chalk.cyan('📎 Share links:'))\n for (const file of changedFiles) {\n const link = buildFileShareLink(parsed, branch, file)\n console.log(chalk.gray(` ${link}`))\n }\n }\n } catch {\n // Non-critical: don't fail sync if share link generation fails\n }\n } catch {\n console.log(chalk.yellow('⚠️ Could not push to remote. You may need to push manually.'))\n }\n } catch {\n // No remote configured\n console.log(chalk.yellow('ℹ️ No remote configured for thoughts repository'))\n }\n } catch (error) {\n console.error(chalk.red(`Error syncing thoughts: ${error}`))\n process.exit(1)\n }\n}\n\nexport async function thoughtsSyncCommand(options: SyncOptions): Promise<void> {\n try {\n // Check if thoughts are configured\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('Error: Thoughts not configured. Run \"thoughtcabinet init\" first.'))\n process.exit(1)\n }\n\n // Check if current repo has thoughts setup\n const currentRepo = getCurrentRepoPath()\n const thoughtsDir = path.join(currentRepo, 'thoughts')\n\n if (!fs.existsSync(thoughtsDir)) {\n console.error(chalk.red('Error: Thoughts not initialized for this repository.'))\n console.error('Run \"thoughtcabinet init\" to set up thoughts.')\n process.exit(1)\n }\n\n // Get current repo mapping and resolve profile\n const mapping = config.repoMappings[currentRepo]\n const mappedName = getRepoNameFromMapping(mapping)\n const profileConfig = resolveProfileForRepo(config, currentRepo)\n\n if (mappedName) {\n // Update symlinks for any new users using profile config\n const newUsers = updateSymlinksForNewUsers(\n currentRepo,\n profileConfig,\n mappedName,\n config.user,\n )\n\n if (newUsers.length > 0) {\n console.log(chalk.green(`✓ Added symlinks for new users: ${newUsers.join(', ')}`))\n }\n }\n\n // Create searchable directory with hard links\n console.log(chalk.blue('Creating searchable index...'))\n const linkedCount = createSearchableIndex(thoughtsDir)\n console.log(chalk.gray(`Created ${linkedCount} hard links in searchable directory`))\n\n // Sync the thoughts repository using profile's thoughtsRepo\n console.log(chalk.blue('Syncing thoughts...'))\n const repoName =\n config.commitRepoPrefix !== false\n ? mappedName || getRepoNameFromPath(currentRepo)\n : undefined\n syncThoughts(profileConfig.thoughtsRepo, options.message || '', repoName)\n\n // Execute PostThoughtsSync hooks\n const hooksConfig = loadHooksConfig(currentRepo)\n const postSyncHooks = getHooksForEvent(hooksConfig, 'PostThoughtsSync')\n\n if (postSyncHooks.length > 0) {\n const hookInput = {\n hook_event_name: 'PostThoughtsSync' as const,\n cwd: currentRepo,\n thoughts_repo: profileConfig.thoughtsRepo,\n has_changes: true,\n searchable_created: true,\n }\n\n const hookEnv = {\n THC_THOUGHTS_REPO: profileConfig.thoughtsRepo,\n THC_HAS_CHANGES: 'true',\n THC_SEARCHABLE_CREATED: 'true',\n }\n\n await executeHooks(postSyncHooks, hookInput, hookEnv, true)\n }\n } catch (error) {\n console.error(chalk.red(`Error during thoughts sync: ${error}`))\n process.exit(1)\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport chalk from 'chalk'\nimport { loadThoughtsConfig, getCurrentRepoPath, expandPath } from './utils/index.js'\nimport {\n getRepoNameFromMapping,\n getProfileNameFromMapping,\n resolveProfileForRepo,\n} from './profile/utils.js'\n\nfunction getGitStatus(repoPath: string): string {\n try {\n return execSync('git status -sb', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n return 'Not a git repository'\n }\n}\n\nfunction getUncommittedChanges(repoPath: string): string[] {\n try {\n const output = execSync('git status --porcelain', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n })\n\n return output\n .split('\\n')\n .filter(line => line.trim())\n .map(line => {\n const status = line.substring(0, 2)\n const file = line.substring(3)\n let statusText = ''\n\n if (status[0] === 'M' || status[1] === 'M') statusText = 'modified'\n else if (status[0] === 'A') statusText = 'added'\n else if (status[0] === 'D') statusText = 'deleted'\n else if (status[0] === '?') statusText = 'untracked'\n else if (status[0] === 'R') statusText = 'renamed'\n\n return ` ${chalk.yellow(statusText.padEnd(10))} ${file}`\n })\n } catch {\n return []\n }\n}\n\nfunction getLastCommit(repoPath: string): string {\n try {\n return execSync('git log -1 --pretty=format:\"%h %s (%cr)\"', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n return 'No commits yet'\n }\n}\n\nconst STALE_FETCH_THRESHOLD_HOURS = 6\n\nfunction getFetchAgeMs(repoPath: string): number | null {\n const fetchHead = path.join(repoPath, '.git', 'FETCH_HEAD')\n try {\n const stat = fs.statSync(fetchHead)\n return Date.now() - stat.mtimeMs\n } catch {\n return null\n }\n}\n\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000)\n if (seconds < 60) return `${seconds}s`\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${minutes}m`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${hours}h`\n const days = Math.floor(hours / 24)\n return `${days}d`\n}\n\nfunction getRemoteStatus(repoPath: string, doFetch: boolean): string {\n try {\n execSync('git remote get-url origin', { cwd: repoPath, stdio: 'pipe' })\n\n if (doFetch) {\n try {\n execSync('git fetch', { cwd: repoPath, stdio: 'pipe' })\n } catch {\n // Fetch might fail, continue anyway\n }\n }\n\n const status = execSync('git status -sb', {\n cwd: repoPath,\n encoding: 'utf8',\n stdio: 'pipe',\n })\n\n if (status.includes('ahead')) {\n const ahead = status.match(/ahead (\\d+)/)?.[1] || '?'\n return chalk.yellow(`${ahead} commits ahead of remote`)\n } else if (status.includes('behind')) {\n const behind = status.match(/behind (\\d+)/)?.[1] || '?'\n return chalk.yellow(`${behind} commits behind remote`)\n } else {\n return chalk.green('Up to date with remote')\n }\n } catch {\n return chalk.gray('No remote configured')\n }\n}\n\ninterface StatusOptions {\n configFile?: string\n fetch?: boolean\n maxAgeSecs?: string\n}\n\nexport async function thoughtsStatusCommand(options: StatusOptions): Promise<void> {\n try {\n // Check if thoughts are configured\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('Error: Thoughts not configured. Run \"thoughtcabinet init\" first.'))\n process.exit(1)\n }\n\n console.log(chalk.blue('Thoughts Repository Status'))\n console.log(chalk.gray('='.repeat(50)))\n console.log('')\n\n // Show configuration\n console.log(chalk.yellow('Configuration:'))\n console.log(` Repository: ${chalk.cyan(config.thoughtsRepo)}`)\n console.log(` Repos directory: ${chalk.cyan(config.reposDir)}`)\n console.log(` Global directory: ${chalk.cyan(config.globalDir)}`)\n console.log(` User: ${chalk.cyan(config.user)}`)\n console.log(` Mapped repos: ${chalk.cyan(Object.keys(config.repoMappings).length)}`)\n console.log('')\n\n // Check current repo mapping\n const currentRepo = getCurrentRepoPath()\n const currentMapping = config.repoMappings[currentRepo]\n const mappedName = getRepoNameFromMapping(currentMapping)\n const profileName = getProfileNameFromMapping(currentMapping)\n const profileConfig = resolveProfileForRepo(config, currentRepo)\n\n if (mappedName) {\n console.log(chalk.yellow('Current Repository:'))\n console.log(` Path: ${chalk.cyan(currentRepo)}`)\n console.log(` Thoughts directory: ${chalk.cyan(`${profileConfig.reposDir}/${mappedName}`)}`)\n\n // Add profile info\n if (profileName) {\n console.log(` Profile: ${chalk.cyan(profileName)}`)\n } else {\n console.log(` Profile: ${chalk.gray('(default)')}`)\n }\n\n const thoughtsDir = path.join(currentRepo, 'thoughts')\n if (fs.existsSync(thoughtsDir)) {\n console.log(` Status: ${chalk.green('✓ Initialized')}`)\n } else {\n console.log(` Status: ${chalk.red('✗ Not initialized')}`)\n }\n } else {\n console.log(chalk.yellow('Current repository not mapped to thoughts'))\n }\n console.log('')\n\n // Show thoughts repository git status using profile's thoughtsRepo\n const expandedRepo = expandPath(profileConfig.thoughtsRepo)\n\n console.log(chalk.yellow('Thoughts Repository Git Status:'))\n if (profileName) {\n console.log(chalk.gray(` (using profile: ${profileName})`))\n }\n console.log(` ${getGitStatus(expandedRepo)}`)\n\n const doFetch = options.fetch ?? false\n const staleThresholdMs =\n (parseInt(options.maxAgeSecs ?? '', 10) || STALE_FETCH_THRESHOLD_HOURS * 60 * 60) * 1000\n\n console.log(` Remote: ${getRemoteStatus(expandedRepo, doFetch)}`)\n\n if (!doFetch) {\n const fetchAgeMs = getFetchAgeMs(expandedRepo)\n if (fetchAgeMs === null) {\n console.log(chalk.gray(' (never fetched, use --fetch to refresh)'))\n } else if (fetchAgeMs > staleThresholdMs) {\n console.log(\n chalk.gray(` (last fetched ${formatDuration(fetchAgeMs)} ago, use --fetch to refresh)`),\n )\n }\n }\n\n console.log(` Last commit: ${getLastCommit(expandedRepo)}`)\n console.log('')\n\n // Show uncommitted changes\n const changes = getUncommittedChanges(expandedRepo)\n if (changes.length > 0) {\n console.log(chalk.yellow('Uncommitted changes:'))\n changes.forEach(change => console.log(change))\n console.log('')\n console.log(chalk.gray('Run \"thoughtcabinet sync\" to commit these changes'))\n } else {\n console.log(chalk.green('✓ No uncommitted changes'))\n }\n } catch (error) {\n console.error(chalk.red(`Error checking thoughts status: ${error}`))\n process.exit(1)\n }\n}\n","import { spawn } from 'child_process'\nimport chalk from 'chalk'\nimport { loadThoughtsConfig } from './utils/index.js'\nimport { getRepoNameFromMapping, getProfileNameFromMapping } from './profile/utils.js'\nimport { getDefaultConfigPath } from '../../config.js'\n\ninterface ConfigOptions {\n edit?: boolean\n json?: boolean\n configFile?: string\n}\n\nexport async function thoughtsConfigCommand(options: ConfigOptions): Promise<void> {\n try {\n const configPath = options.configFile || getDefaultConfigPath()\n\n // Handle edit mode\n if (options.edit) {\n const editor = process.env.EDITOR || 'vi'\n spawn(editor, [configPath], { stdio: 'inherit' })\n return\n }\n\n // Load configuration\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('No thoughts configuration found.'))\n console.error('Run \"thoughtcabinet init\" to create one.')\n process.exit(1)\n }\n\n // Handle JSON output\n if (options.json) {\n console.log(JSON.stringify(config, null, 2))\n return\n }\n\n // Display configuration\n console.log(chalk.blue('Thoughts Configuration'))\n console.log(chalk.gray('='.repeat(50)))\n console.log('')\n\n console.log(chalk.yellow('Settings:'))\n console.log(` Config file: ${chalk.cyan(configPath)}`)\n console.log(` Thoughts repository: ${chalk.cyan(config.thoughtsRepo)}`)\n console.log(` Repos directory: ${chalk.cyan(config.reposDir)}`)\n console.log(` Global directory: ${chalk.cyan(config.globalDir)}`)\n console.log(` User: ${chalk.cyan(config.user)}`)\n console.log('')\n\n console.log(chalk.yellow('Repository Mappings:'))\n const mappings = Object.entries(config.repoMappings)\n\n if (mappings.length === 0) {\n console.log(chalk.gray(' No repositories mapped yet'))\n } else {\n mappings.forEach(([repo, mapping]) => {\n const repoName = getRepoNameFromMapping(mapping)\n const profileName = getProfileNameFromMapping(mapping)\n\n console.log(` ${chalk.cyan(repo)}`)\n console.log(` → ${chalk.green(`${config.reposDir}/${repoName}`)}`)\n\n if (profileName) {\n console.log(` Profile: ${chalk.yellow(profileName)}`)\n } else {\n console.log(` Profile: ${chalk.gray('(default)')}`)\n }\n })\n }\n\n console.log('')\n\n // Add profiles section\n console.log(chalk.yellow('Profiles:'))\n if (!config.profiles || Object.keys(config.profiles).length === 0) {\n console.log(chalk.gray(' No profiles configured'))\n } else {\n Object.keys(config.profiles).forEach(name => {\n console.log(` ${chalk.cyan(name)}`)\n })\n }\n\n console.log('')\n console.log(chalk.gray('To edit configuration, run: thoughtcabinet config --edit'))\n } catch (error) {\n console.error(chalk.red(`Error showing thoughts config: ${error}`))\n process.exit(1)\n }\n}\n","import fs from 'fs'\nimport chalk from 'chalk'\nimport { loadThoughtsConfig, saveThoughtsConfig } from './utils/index.js'\nimport { getRepoNameFromMapping, getProfileNameFromMapping } from './profile/utils.js'\n\ninterface PruneOptions {\n apply?: boolean\n configFile?: string\n}\n\ninterface StaleEntry {\n repoPath: string\n mappedName: string | undefined\n profileName: string | undefined\n}\n\nexport async function thoughtsPruneCommand(options: PruneOptions): Promise<void> {\n try {\n // Load config\n const config = loadThoughtsConfig(options)\n if (!config) {\n console.error(chalk.red('Error: Thoughts configuration not found.'))\n console.error('Run \"thoughtcabinet init\" to create one.')\n process.exit(1)\n }\n\n const mappings = Object.entries(config.repoMappings)\n\n if (mappings.length === 0) {\n console.log(chalk.gray('No repository mappings configured.'))\n return\n }\n\n // Find stale entries (repo paths that no longer exist)\n const staleEntries: StaleEntry[] = []\n\n for (const [repoPath, mapping] of mappings) {\n if (!fs.existsSync(repoPath)) {\n staleEntries.push({\n repoPath,\n mappedName: getRepoNameFromMapping(mapping),\n profileName: getProfileNameFromMapping(mapping),\n })\n }\n }\n\n if (staleEntries.length === 0) {\n console.log(chalk.green('No stale repository mappings found.'))\n console.log(chalk.gray(`All ${mappings.length} mapped repositories exist.`))\n return\n }\n\n // Display stale entries\n console.log(chalk.yellow(`Found ${staleEntries.length} stale repository mapping(s):`))\n console.log('')\n\n for (const entry of staleEntries) {\n console.log(` ${chalk.red('✗')} ${chalk.cyan(entry.repoPath)}`)\n console.log(` → ${chalk.gray(entry.mappedName || '(unknown)')}`)\n if (entry.profileName) {\n console.log(` Profile: ${chalk.yellow(entry.profileName)}`)\n }\n }\n\n console.log('')\n\n // Apply changes if --apply flag is set\n if (options.apply) {\n console.log(chalk.blue('Removing stale entries from configuration...'))\n\n for (const entry of staleEntries) {\n delete config.repoMappings[entry.repoPath]\n }\n\n saveThoughtsConfig(config, options)\n\n console.log(chalk.green(`✅ Removed ${staleEntries.length} stale mapping(s).`))\n console.log('')\n console.log(chalk.gray('Note: The thoughts content in your thoughts repository was not modified.'))\n console.log(chalk.gray('Only the configuration entries pointing to non-existent directories were removed.'))\n } else {\n console.log(chalk.gray('This is a dry run. No changes were made.'))\n console.log(chalk.gray('Run with --apply to remove these stale entries.'))\n }\n } catch (error) {\n console.error(chalk.red(`Error during thoughts prune: ${error}`))\n process.exit(1)\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { getDefaultConfigDir, getLegacyConfigDir, ConfigResolver } from '../../config.js'\nimport type { RepoMappingObject } from '../../config.js'\nimport { expandPath } from './utils/paths.js'\nimport { loadThoughtsConfig } from './utils/config.js'\nimport { setupThoughtsDirectory } from './init-core.js'\nimport { resolveProfileForRepo, getRepoNameFromMapping } from './profile/utils.js'\nimport { createThoughtsDirectoryStructure } from './utils/repository.js'\nimport { getAllAgents } from '../agent/registry.js'\nimport { CATEGORY_SUBDIRS } from '../agent/constants.js'\nimport type { AgentConfig } from '../agent/types.js'\n\ninterface MigrateOptions {\n dryRun?: boolean\n configFile?: string\n}\n\nexport interface MoveEntry {\n from: string\n to: string\n label: string\n}\n\nexport interface MigrationPlan {\n moves: MoveEntry[]\n newConfigDir: string\n legacyConfigDir: string\n config: Record<string, unknown>\n affectedRepos: string[]\n}\n\n/**\n * Plan the migration from legacy config dir to new config dir.\n * Returns null if there's nothing to migrate or already at new location.\n * Pure function suitable for testing — no side effects beyond reading the filesystem.\n */\nexport function planMigration(homeDir?: string): MigrationPlan | null {\n const home = homeDir || process.env.HOME || ''\n const newConfigDir = path.join(home, '.thought-cabinet')\n const legacyConfigDir = path.join(home, '.config', 'thought-cabinet')\n const legacyConfigPath = path.join(legacyConfigDir, 'config.json')\n const newConfigPath = path.join(newConfigDir, 'config.json')\n\n // Already at new location\n if (fs.existsSync(newConfigPath)) {\n return null\n }\n\n // No legacy config to migrate\n if (!fs.existsSync(legacyConfigPath)) {\n return null\n }\n\n // Load old config\n let config: Record<string, unknown>\n try {\n config = JSON.parse(fs.readFileSync(legacyConfigPath, 'utf8'))\n } catch {\n return null\n }\n\n const thoughts = config.thoughts as\n | {\n thoughtsRepo?: string\n profiles?: Record<string, { thoughtsRepo: string }>\n repoMappings?: Record<string, unknown>\n }\n | undefined\n\n if (!thoughts) {\n return null\n }\n\n const moves: MoveEntry[] = []\n\n // 1. Config file\n moves.push({\n from: legacyConfigPath,\n to: path.join(newConfigDir, 'config.json'),\n label: 'Config file',\n })\n\n // 2. Agent assets\n for (const dir of ['agents', 'skills']) {\n const src = path.join(legacyConfigDir, dir)\n if (fs.existsSync(src)) {\n moves.push({\n from: src,\n to: path.join(newConfigDir, dir),\n label: `${dir}/ directory`,\n })\n }\n }\n\n // 3. Default thoughts repo\n if (thoughts.thoughtsRepo) {\n const expandedThoughtsRepo = expandPath(thoughts.thoughtsRepo)\n const newDefaultThoughtsRepo = path.join(newConfigDir, 'thoughts')\n if (\n fs.existsSync(expandedThoughtsRepo) &&\n expandedThoughtsRepo !== newDefaultThoughtsRepo &&\n !expandedThoughtsRepo.startsWith(newConfigDir + path.sep)\n ) {\n moves.push({\n from: expandedThoughtsRepo,\n to: newDefaultThoughtsRepo,\n label: `Default thoughts repo (${thoughts.thoughtsRepo})`,\n })\n }\n }\n\n // 4. Profile thoughts repos\n if (thoughts.profiles) {\n for (const [name, profile] of Object.entries(thoughts.profiles)) {\n const expandedProfileRepo = expandPath(profile.thoughtsRepo)\n const newProfileRepo = path.join(newConfigDir, `thoughts-${name}`)\n if (\n fs.existsSync(expandedProfileRepo) &&\n expandedProfileRepo !== newProfileRepo &&\n !expandedProfileRepo.startsWith(newConfigDir + path.sep)\n ) {\n moves.push({\n from: expandedProfileRepo,\n to: newProfileRepo,\n label: `Profile \"${name}\" thoughts repo (${profile.thoughtsRepo})`,\n })\n }\n }\n }\n\n // Collect affected repos\n const affectedRepos = thoughts.repoMappings ? Object.keys(thoughts.repoMappings) : []\n\n return {\n moves,\n newConfigDir,\n legacyConfigDir,\n config,\n affectedRepos,\n }\n}\n\n/**\n * Execute a migration plan: move files/dirs and update config paths.\n * Separated from planMigration for testability.\n */\nexport function executeMigration(plan: MigrationPlan): void {\n fs.mkdirSync(plan.newConfigDir, { recursive: true })\n\n for (const move of plan.moves) {\n const destDir = path.dirname(move.to)\n fs.mkdirSync(destDir, { recursive: true })\n fs.renameSync(move.from, move.to)\n }\n\n // Update config paths\n const thoughts = plan.config.thoughts as {\n thoughtsRepo?: string\n profiles?: Record<string, { thoughtsRepo: string }>\n }\n\n if (thoughts) {\n thoughts.thoughtsRepo = path.join(plan.newConfigDir, 'thoughts')\n\n if (thoughts.profiles) {\n for (const [name, profile] of Object.entries(thoughts.profiles)) {\n profile.thoughtsRepo = path.join(plan.newConfigDir, `thoughts-${name}`)\n }\n }\n }\n\n // Write updated config\n const newConfigPath = path.join(plan.newConfigDir, 'config.json')\n fs.writeFileSync(newConfigPath, JSON.stringify(plan.config, null, 2))\n}\n\nexport interface RefreshResult {\n refreshed: string[]\n skipped: string[]\n}\n\ninterface RefreshableConfig {\n thoughtsRepo: string\n reposDir: string\n globalDir: string\n user: string\n repoMappings: Record<string, string | RepoMappingObject>\n profiles?: Record<string, { thoughtsRepo: string; reposDir: string; globalDir: string }>\n}\n\n/**\n * Refresh thoughts/ symlinks in registered repos after migration.\n * Calls setupThoughtsDirectory() for each repo that exists on disk.\n */\nexport function refreshRepoSymlinks(\n config: RefreshableConfig,\n affectedRepos: string[],\n): RefreshResult {\n const refreshed: string[] = []\n const skipped: string[] = []\n\n for (const repoPath of affectedRepos) {\n if (!fs.existsSync(repoPath)) {\n skipped.push(repoPath)\n continue\n }\n\n const mapping = config.repoMappings[repoPath]\n const mappedName = getRepoNameFromMapping(mapping)\n if (!mappedName) {\n skipped.push(repoPath)\n continue\n }\n\n const profileConfig = resolveProfileForRepo(\n {\n thoughtsRepo: config.thoughtsRepo,\n reposDir: config.reposDir,\n globalDir: config.globalDir,\n user: config.user,\n repoMappings: config.repoMappings,\n profiles: config.profiles,\n },\n repoPath,\n )\n\n // Ensure target directories exist in thoughts repo\n createThoughtsDirectoryStructure(profileConfig, mappedName, config.user)\n\n // Rebuild thoughts/ symlinks\n setupThoughtsDirectory({\n repoPath,\n profileConfig,\n mappedName,\n user: config.user,\n })\n\n refreshed.push(repoPath)\n }\n\n return { refreshed, skipped }\n}\n\nexport interface AgentSymlinkRefreshResult {\n refreshed: number\n agents: string[]\n}\n\ntype AgentInfo = Pick<AgentConfig, 'displayName' | 'globalConfigDir'>\n\n/**\n * Refresh global agent asset symlinks that point into the legacy config dir.\n * Recreates them to point into the new config dir.\n */\nexport function refreshGlobalAgentSymlinks(\n legacyConfigDir: string,\n newConfigDir: string,\n agentList?: AgentInfo[],\n): AgentSymlinkRefreshResult {\n let refreshed = 0\n const agents: string[] = []\n const agentsToScan = agentList || getAllAgents()\n\n for (const agent of agentsToScan) {\n if (!agent.globalConfigDir) continue\n let agentTouched = false\n\n for (const category of Object.values(CATEGORY_SUBDIRS)) {\n const categoryDir = path.join(agent.globalConfigDir, category)\n if (!fs.existsSync(categoryDir)) continue\n\n const entries = fs.readdirSync(categoryDir, { withFileTypes: true })\n for (const entry of entries) {\n const entryPath = path.join(categoryDir, entry.name)\n\n // Only process symlinks\n let stats: fs.Stats\n try {\n stats = fs.lstatSync(entryPath)\n } catch {\n continue\n }\n if (!stats.isSymbolicLink()) continue\n\n // Read the symlink target and resolve to absolute\n const linkTarget = fs.readlinkSync(entryPath)\n const resolvedTarget = path.resolve(path.dirname(entryPath), linkTarget)\n\n // Check if it points into the legacy config dir\n if (\n !resolvedTarget.startsWith(legacyConfigDir + path.sep) &&\n resolvedTarget !== legacyConfigDir\n ) {\n continue\n }\n\n // Compute the equivalent path in the new config dir\n const relativeToCfg = path.relative(legacyConfigDir, resolvedTarget)\n const newTarget = path.join(newConfigDir, relativeToCfg)\n\n // Verify the new target exists\n if (!fs.existsSync(newTarget)) continue\n\n // Recreate the symlink with a relative path to the new target\n fs.unlinkSync(entryPath)\n const newRelative = path.relative(path.dirname(entryPath), newTarget)\n fs.symlinkSync(newRelative, entryPath)\n\n refreshed++\n agentTouched = true\n }\n }\n\n if (agentTouched) {\n agents.push(agent.displayName)\n }\n }\n\n return { refreshed, agents }\n}\n\n/**\n * Preview which global agent symlinks would be refreshed (read-only scan).\n * Used for dry-run display.\n */\nexport function previewGlobalAgentSymlinks(\n legacyConfigDir: string,\n agentList?: AgentInfo[],\n): string[] {\n const entries: string[] = []\n const agentsToScan = agentList || getAllAgents()\n\n for (const agent of agentsToScan) {\n if (!agent.globalConfigDir) continue\n\n for (const category of Object.values(CATEGORY_SUBDIRS)) {\n const categoryDir = path.join(agent.globalConfigDir, category)\n if (!fs.existsSync(categoryDir)) continue\n\n const dirEntries = fs.readdirSync(categoryDir, { withFileTypes: true })\n for (const entry of dirEntries) {\n const entryPath = path.join(categoryDir, entry.name)\n try {\n const stats = fs.lstatSync(entryPath)\n if (!stats.isSymbolicLink()) continue\n const linkTarget = fs.readlinkSync(entryPath)\n const resolvedTarget = path.resolve(path.dirname(entryPath), linkTarget)\n if (resolvedTarget.startsWith(legacyConfigDir + path.sep)) {\n entries.push(entryPath)\n }\n } catch {\n continue\n }\n }\n }\n }\n\n return entries\n}\n\n/**\n * Interactive migrate command entry point.\n */\nexport async function thoughtsMigrateCommand(options: MigrateOptions): Promise<void> {\n const newConfigDir = getDefaultConfigDir()\n const legacyConfigDir = getLegacyConfigDir()\n const newConfigPath = path.join(newConfigDir, ConfigResolver.DEFAULT_CONFIG_FILE)\n const legacyConfigPath = path.join(legacyConfigDir, ConfigResolver.DEFAULT_CONFIG_FILE)\n\n // Check if there's anything to migrate\n if (!fs.existsSync(legacyConfigPath)) {\n if (fs.existsSync(newConfigPath)) {\n p.log.info('Configuration is already at the new location.')\n return\n }\n p.log.info('No configuration found to migrate.')\n return\n }\n\n if (legacyConfigDir === newConfigDir) {\n p.log.info('Configuration is already at the expected location.')\n return\n }\n\n const plan = planMigration()\n\n if (!plan) {\n p.log.info('Nothing to migrate.')\n return\n }\n\n p.intro(chalk.blue('Migrate Thought Cabinet Configuration'))\n\n // Show plan\n p.log.step('Migration plan:')\n for (const move of plan.moves) {\n p.log.message(` ${move.label}`)\n p.log.message(chalk.gray(` ${move.from} → ${move.to}`))\n }\n\n if (options.dryRun) {\n // Show repo symlinks that would be refreshed\n if (plan.affectedRepos.length > 0) {\n p.log.step('Repo symlinks that would be refreshed:')\n for (const repo of plan.affectedRepos) {\n if (fs.existsSync(repo)) {\n p.log.message(chalk.gray(` ${repo}/thoughts/`))\n } else {\n p.log.message(chalk.gray(` ${repo}/thoughts/ (skipped — repo not found)`))\n }\n }\n }\n\n // Show agent symlinks that would be refreshed (scan without modifying)\n const agentPreview = previewGlobalAgentSymlinks(plan.legacyConfigDir)\n if (agentPreview.length > 0) {\n p.log.step('Global agent symlinks that would be refreshed:')\n for (const entry of agentPreview) {\n p.log.message(chalk.gray(` ${entry}`))\n }\n }\n\n p.log.info('Dry run — no changes made.')\n return\n }\n\n // Confirm\n const confirm = await p.confirm({\n message: 'Proceed with migration?',\n initialValue: true,\n })\n\n if (p.isCancel(confirm) || !confirm) {\n p.cancel('Migration cancelled.')\n return\n }\n\n // Execute\n executeMigration(plan)\n\n for (const move of plan.moves) {\n p.log.success(`Moved: ${move.label}`)\n }\n\n // Try to clean up old dir if empty\n try {\n const remaining = fs.readdirSync(plan.legacyConfigDir)\n if (remaining.length === 0) {\n fs.rmdirSync(plan.legacyConfigDir)\n p.log.info(`Removed empty directory: ${plan.legacyConfigDir}`)\n }\n } catch {\n // Ignore cleanup errors\n }\n\n // Refresh repo symlinks\n if (plan.affectedRepos.length > 0) {\n const config = loadThoughtsConfig({ configFile: path.join(plan.newConfigDir, 'config.json') })\n if (config) {\n p.log.step('Refreshing thoughts symlinks in registered repos...')\n const repoResult = refreshRepoSymlinks(config, plan.affectedRepos)\n for (const repo of repoResult.refreshed) {\n p.log.success(`Refreshed: ${repo}`)\n }\n for (const repo of repoResult.skipped) {\n p.log.warn(`Skipped (not found): ${repo}`)\n }\n }\n }\n\n // Refresh global agent symlinks\n p.log.step('Refreshing global agent symlinks...')\n const agentResult = refreshGlobalAgentSymlinks(plan.legacyConfigDir, plan.newConfigDir)\n if (agentResult.refreshed > 0) {\n p.log.success(\n `Refreshed ${agentResult.refreshed} symlink(s) for: ${agentResult.agents.join(', ')}`,\n )\n } else {\n p.log.info('No global agent symlinks needed updating.')\n }\n\n p.outro(chalk.green('Migration complete!'))\n}\n","import { homedir } from 'os'\nimport { join } from 'path'\nimport { existsSync } from 'fs'\nimport type { AgentType, AgentConfig } from './types.js'\n\nconst home = homedir()\nconst claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || join(home, '.claude')\n\n/**\n * Curated agent registry.\n * Each agent defines where its assets live at project and global scope.\n */\nexport const agents: Record<AgentType, AgentConfig> = {\n 'claude-code': {\n name: 'claude-code',\n displayName: 'Claude Code',\n configDir: '.claude',\n globalConfigDir: claudeHome,\n detectInstalled: async () => existsSync(claudeHome),\n },\n codebuddy: {\n name: 'codebuddy',\n displayName: 'CodeBuddy Code',\n configDir: '.codebuddy',\n globalConfigDir: join(home, '.codebuddy'),\n detectInstalled: async () =>\n existsSync(join(process.cwd(), '.codebuddy')) || existsSync(join(home, '.codebuddy')),\n },\n}\n\n/** Get agent config by type, throws if unknown */\nexport function getAgentConfig(type: AgentType): AgentConfig {\n const config = agents[type]\n if (!config) {\n const valid = Object.keys(agents).join(', ')\n throw new Error(`Unknown agent: ${type}. Valid agents: ${valid}`)\n }\n return config\n}\n\n/** Get all registered agents */\nexport function getAllAgents(): AgentConfig[] {\n return Object.values(agents)\n}\n\n/** Detect which agents are installed on this system */\nexport async function detectInstalledAgents(): Promise<AgentType[]> {\n const results = await Promise.all(\n Object.entries(agents).map(async ([type, config]) => ({\n type: type as AgentType,\n installed: await config.detectInstalled(),\n })),\n )\n return results.filter(r => r.installed).map(r => r.type)\n}\n\n/** Check if a given string is a valid AgentType */\nexport function isValidAgentType(value: string): value is AgentType {\n return value in agents\n}\n","/** Base directory for canonical agent asset storage */\nexport const AGENTS_DIR = '.agents'\n\n/** In-repo directory for canonical asset storage (project scope) */\nexport const CANONICAL_DIR = '.thought-cabinet'\n\n/** Subdirectory names for each asset category */\nexport const CATEGORY_SUBDIRS = {\n skills: 'skills',\n commands: 'commands',\n agents: 'agents',\n} as const\n\nexport type AssetCategory = keyof typeof CATEGORY_SUBDIRS\n","import chalk from 'chalk'\nimport path from 'path'\nimport * as p from '@clack/prompts'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n ensureThoughtsRepoExists,\n} from '../utils/index.js'\nimport { sanitizeProfileName, validateProfile } from './utils.js'\nimport { getDefaultConfigDir } from '../../../config.js'\nimport type { ProfileConfig } from '../../../config'\n\ninterface CreateOptions {\n repo?: string\n reposDir?: string\n globalDir?: string\n configFile?: string\n}\n\nexport async function profileCreateCommand(\n profileName: string,\n options: CreateOptions,\n): Promise<void> {\n try {\n // Check for non-interactive mode\n if (!options.repo || !options.reposDir || !options.globalDir) {\n if (!process.stdin.isTTY) {\n p.log.error('Not running in interactive terminal.')\n p.log.info('Provide all options: --repo, --repos-dir, --global-dir')\n process.exit(1)\n }\n }\n\n // Load existing config\n const config = loadThoughtsConfig(options as Record<string, unknown>)\n\n if (!config) {\n p.log.error('Thoughts not configured.')\n p.log.info('Run \"thoughtcabinet init\" first to set up the base configuration.')\n process.exit(1)\n }\n\n // Sanitize profile name\n const sanitizedName = sanitizeProfileName(profileName)\n if (sanitizedName !== profileName) {\n p.log.warn(`Profile name sanitized: \"${profileName}\" → \"${sanitizedName}\"`)\n }\n\n p.intro(chalk.blue(`Creating Profile: ${sanitizedName}`))\n\n // Check if profile already exists\n if (validateProfile(config, sanitizedName)) {\n p.log.error(`Profile \"${sanitizedName}\" already exists.`)\n p.log.info('Use a different name or delete the existing profile first.')\n process.exit(1)\n }\n\n // Get profile configuration\n let thoughtsRepo: string\n let reposDir: string\n let globalDir: string\n\n if (options.repo && options.reposDir && options.globalDir) {\n // Non-interactive mode\n thoughtsRepo = options.repo\n reposDir = options.reposDir\n globalDir = options.globalDir\n } else {\n // Interactive mode\n const defaultRepo = path.join(getDefaultConfigDir(), `thoughts-${sanitizedName}`)\n p.log.info('Specify the thoughts repository location for this profile.')\n\n const repoInput = await p.text({\n message: 'Thoughts repository:',\n initialValue: defaultRepo,\n placeholder: defaultRepo,\n })\n\n if (p.isCancel(repoInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n thoughtsRepo = (repoInput as string) || defaultRepo\n\n const reposDirInput = await p.text({\n message: 'Repository-specific thoughts directory:',\n initialValue: 'repos',\n placeholder: 'repos',\n })\n\n if (p.isCancel(reposDirInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n reposDir = (reposDirInput as string) || 'repos'\n\n const globalDirInput = await p.text({\n message: 'Global thoughts directory:',\n initialValue: 'global',\n placeholder: 'global',\n })\n\n if (p.isCancel(globalDirInput)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n globalDir = (globalDirInput as string) || 'global'\n }\n\n // Create profile config\n const profileConfig: ProfileConfig = {\n thoughtsRepo,\n reposDir,\n globalDir,\n }\n\n // Initialize profiles object if it doesn't exist\n if (!config.profiles) {\n config.profiles = {}\n }\n\n // Add profile\n config.profiles[sanitizedName] = profileConfig\n\n // Save config\n saveThoughtsConfig(config, options as Record<string, unknown>)\n\n // Create the profile's thoughts repository structure\n p.log.step('Initializing profile thoughts repository...')\n ensureThoughtsRepoExists(profileConfig)\n\n p.log.success(`Profile \"${sanitizedName}\" created successfully!`)\n\n p.note(\n `Name: ${chalk.cyan(sanitizedName)}\\n` +\n `Thoughts repository: ${chalk.cyan(thoughtsRepo)}\\n` +\n `Repos directory: ${chalk.cyan(reposDir)}\\n` +\n `Global directory: ${chalk.cyan(globalDir)}`,\n 'Profile Configuration',\n )\n\n p.outro(\n chalk.gray('Next steps:\\n') +\n chalk.gray(` 1. Run \"thoughtcabinet init --profile ${sanitizedName}\" in a repository\\n`) +\n chalk.gray(` 2. Your thoughts will sync to the profile's repository`),\n )\n } catch (error) {\n p.log.error(`Error creating profile: ${error}`)\n process.exit(1)\n }\n}\n","import chalk from 'chalk'\nimport { loadThoughtsConfig } from '../utils/index.js'\n\ninterface ListOptions {\n json?: boolean\n configFile?: string\n}\n\nexport async function profileListCommand(options: ListOptions): Promise<void> {\n try {\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('Error: Thoughts not configured.'))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify(config.profiles || {}, null, 2))\n return\n }\n\n console.log(chalk.blue('Thoughts Profiles'))\n console.log(chalk.gray('='.repeat(50)))\n console.log('')\n\n // Show default config\n console.log(chalk.yellow('Default Configuration:'))\n console.log(` Thoughts repository: ${chalk.cyan(config.thoughtsRepo)}`)\n console.log(` Repos directory: ${chalk.cyan(config.reposDir)}`)\n console.log(` Global directory: ${chalk.cyan(config.globalDir)}`)\n console.log('')\n\n // Show profiles\n if (!config.profiles || Object.keys(config.profiles).length === 0) {\n console.log(chalk.gray('No profiles configured.'))\n console.log('')\n console.log(chalk.gray('Create a profile with: thoughtcabinet profile create <name>'))\n } else {\n console.log(chalk.yellow(`Profiles (${Object.keys(config.profiles).length}):`))\n console.log('')\n\n Object.entries(config.profiles).forEach(([name, profile]) => {\n console.log(chalk.cyan(` ${name}:`))\n console.log(` Thoughts repository: ${profile.thoughtsRepo}`)\n console.log(` Repos directory: ${profile.reposDir}`)\n console.log(` Global directory: ${profile.globalDir}`)\n console.log('')\n })\n }\n } catch (error) {\n console.error(chalk.red(`Error listing profiles: ${error}`))\n process.exit(1)\n }\n}\n","import chalk from 'chalk'\nimport { loadThoughtsConfig } from '../utils/index.js'\nimport { validateProfile } from './utils.js'\n\ninterface ShowOptions {\n json?: boolean\n configFile?: string\n}\n\nexport async function profileShowCommand(profileName: string, options: ShowOptions): Promise<void> {\n try {\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n console.error(chalk.red('Error: Thoughts not configured.'))\n process.exit(1)\n }\n\n if (!validateProfile(config, profileName)) {\n console.error(chalk.red(`Error: Profile \"${profileName}\" not found.`))\n console.error('')\n console.error(chalk.gray('Available profiles:'))\n if (config.profiles) {\n Object.keys(config.profiles).forEach(name => {\n console.error(chalk.gray(` - ${name}`))\n })\n } else {\n console.error(chalk.gray(' (none)'))\n }\n process.exit(1)\n }\n\n const profile = config.profiles![profileName]\n\n if (options.json) {\n console.log(JSON.stringify(profile, null, 2))\n return\n }\n\n console.log(chalk.blue(`Profile: ${profileName}`))\n console.log(chalk.gray('='.repeat(50)))\n console.log('')\n console.log(chalk.yellow('Configuration:'))\n console.log(` Thoughts repository: ${chalk.cyan(profile.thoughtsRepo)}`)\n console.log(` Repos directory: ${chalk.cyan(profile.reposDir)}`)\n console.log(` Global directory: ${chalk.cyan(profile.globalDir)}`)\n console.log('')\n\n // Count repositories using this profile\n let repoCount = 0\n Object.values(config.repoMappings).forEach(mapping => {\n if (typeof mapping === 'object' && mapping.profile === profileName) {\n repoCount++\n }\n })\n\n console.log(chalk.yellow('Usage:'))\n console.log(` Repositories using this profile: ${chalk.cyan(repoCount)}`)\n } catch (error) {\n console.error(chalk.red(`Error showing profile: ${error}`))\n process.exit(1)\n }\n}\n","import chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { loadThoughtsConfig, saveThoughtsConfig } from '../utils/index.js'\nimport { validateProfile } from './utils.js'\n\ninterface DeleteOptions {\n force?: boolean\n configFile?: string\n}\n\nexport async function profileDeleteCommand(\n profileName: string,\n options: DeleteOptions,\n): Promise<void> {\n try {\n // Check for non-interactive mode\n if (!options.force && !process.stdin.isTTY) {\n p.log.error('Not running in interactive terminal.')\n p.log.info('Use --force flag to delete without confirmation.')\n process.exit(1)\n }\n\n p.intro(chalk.blue(`Delete Profile: ${profileName}`))\n\n const config = loadThoughtsConfig(options)\n\n if (!config) {\n p.log.error('Thoughts not configured.')\n process.exit(1)\n }\n\n if (!validateProfile(config, profileName)) {\n p.log.error(`Profile \"${profileName}\" not found.`)\n process.exit(1)\n }\n\n // Check if any repositories are using this profile\n const usingRepos: string[] = []\n Object.entries(config.repoMappings).forEach(([repoPath, mapping]) => {\n if (typeof mapping === 'object' && mapping.profile === profileName) {\n usingRepos.push(repoPath)\n }\n })\n\n if (usingRepos.length > 0 && !options.force) {\n p.log.error(`Profile \"${profileName}\" is in use by ${usingRepos.length} repository(ies):`)\n usingRepos.forEach(repo => {\n p.log.message(chalk.gray(` - ${repo}`))\n })\n p.log.warn('Options:')\n p.log.message(chalk.gray(' 1. Run \"thoughtcabinet destroy\" in each repository'))\n p.log.message(\n chalk.gray(' 2. Use --force to delete anyway (repos will fall back to default config)'),\n )\n process.exit(1)\n }\n\n // Confirm deletion\n if (!options.force) {\n p.log.warn(`You are about to delete profile: ${chalk.cyan(profileName)}`)\n p.log.message(chalk.gray('This will remove the profile configuration.'))\n p.log.message(chalk.gray('The thoughts repository files will NOT be deleted.'))\n\n const confirmDelete = await p.confirm({\n message: `Delete profile \"${profileName}\"?`,\n initialValue: false,\n })\n\n if (p.isCancel(confirmDelete) || !confirmDelete) {\n p.cancel('Deletion cancelled.')\n return\n }\n }\n\n // Delete profile\n delete config.profiles![profileName]\n\n // If profiles is now empty, remove it entirely\n if (Object.keys(config.profiles!).length === 0) {\n delete config.profiles\n }\n\n // Save config\n saveThoughtsConfig(config, options)\n\n p.log.success(`Profile \"${profileName}\" deleted`)\n\n if (usingRepos.length > 0) {\n p.log.warn('Repositories using this profile will fall back to default config')\n }\n\n p.outro(chalk.green('Done'))\n } catch (error) {\n p.log.error(`Error deleting profile: ${error}`)\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport { thoughtsInitCommand } from './thoughts/init.js'\nimport { thoughtsDestoryCommand } from './thoughts/destroy.js'\nimport { thoughtsSyncCommand } from './thoughts/sync.js'\nimport { thoughtsStatusCommand } from './thoughts/status.js'\nimport { thoughtsConfigCommand } from './thoughts/config.js'\nimport { thoughtsPruneCommand } from './thoughts/prune.js'\nimport { thoughtsMigrateCommand } from './thoughts/migrate.js'\nimport { profileCreateCommand } from './thoughts/profile/create.js'\nimport { profileListCommand } from './thoughts/profile/list.js'\nimport { profileShowCommand } from './thoughts/profile/show.js'\nimport { profileDeleteCommand } from './thoughts/profile/delete.js'\n\nexport function thoughtsCommand(program: Command): void {\n const cmd = program\n\n cmd\n .command('init')\n .description('Initialize thoughts for current repository')\n .option('--force', 'Force reconfiguration even if already set up')\n .option('--config-file <path>', 'Path to config file')\n .option(\n '--directory <name>',\n 'Specify the repository directory name (skips interactive prompt)',\n )\n .option('--profile <name>', 'Use a specific thoughts profile')\n .action(thoughtsInitCommand)\n\n cmd\n .command('destroy')\n .description('Remove thoughts setup from current repository')\n .option('--force', 'Force removal even if not in configuration')\n .option('--config-file <path>', 'Path to config file')\n .action(thoughtsDestoryCommand)\n\n cmd\n .command('sync')\n .description('Manually sync thoughts to thoughts repository')\n .option('-m, --message <message>', 'Commit message for sync')\n .option('--config-file <path>', 'Path to config file')\n .action(thoughtsSyncCommand)\n\n cmd\n .command('status')\n .description('Show status of thoughts repository')\n .option('--config-file <path>', 'Path to config file')\n .option('--fetch', 'Fetch from remote before showing status')\n .action(thoughtsStatusCommand)\n\n cmd\n .command('config')\n .description('View or edit thoughts configuration')\n .option('--edit', 'Open configuration in editor')\n .option('--json', 'Output configuration as JSON')\n .option('--config-file <path>', 'Path to config file')\n .action(thoughtsConfigCommand)\n\n cmd\n .command('prune')\n .description('Remove stale repository mappings (directories that no longer exist)')\n .option('--apply', 'Apply changes (default is dry-run)')\n .option('--config-file <path>', 'Path to config file')\n .action(thoughtsPruneCommand)\n\n cmd\n .command('migrate')\n .description('Migrate configuration from ~/.config/thought-cabinet/ to ~/.thought-cabinet/')\n .option('--dry-run', 'Show what would be migrated without making changes')\n .option('--config-file <path>', 'Path to legacy config file')\n .action(thoughtsMigrateCommand)\n\n // Profile management commands\n const profile = cmd.command('profile').description('Manage thoughts profiles')\n\n profile\n .command('create <name>')\n .description('Create a new thoughts profile')\n .option('--repo <path>', 'Thoughts repository path')\n .option('--repos-dir <name>', 'Repos directory name')\n .option('--global-dir <name>', 'Global directory name')\n .option('--config-file <path>', 'Path to config file')\n .action(profileCreateCommand)\n\n profile\n .command('list')\n .description('List all thoughts profiles')\n .option('--json', 'Output as JSON')\n .option('--config-file <path>', 'Path to config file')\n .action(profileListCommand)\n\n profile\n .command('show <name>')\n .description('Show details of a specific profile')\n .option('--json', 'Output as JSON')\n .option('--config-file <path>', 'Path to config file')\n .action(profileShowCommand)\n\n profile\n .command('delete <name>')\n .description('Delete a thoughts profile')\n .option('--force', 'Force deletion even if in use')\n .option('--config-file <path>', 'Path to config file')\n .action(profileDeleteCommand)\n}\n","import { existsSync } from 'fs'\nimport { dirname, join, resolve } from 'path'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { fileURLToPath } from 'url'\nimport { cp, mkdir, readdir } from 'fs/promises'\nimport type { AgentType, AgentInitOptions, Asset, InstallMode, InstallScope } from './types.js'\nimport { agents } from './registry.js'\nimport { discoverAllAssets } from './discovery.js'\nimport { installAssetForAgent } from './installer.js'\nimport { getDefaultConfigDir } from '../../config.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst ASSET_CATEGORIES = ['agents', 'skills'] as const\n\n/** Find the bundled agent-assets directory relative to __dirname */\nexport function getBundledAssetsDir(): string | null {\n const candidates = [\n resolve(__dirname, '..', 'src', 'agent-assets'),\n resolve(__dirname, '..', '..', 'src', 'agent-assets'),\n resolve(__dirname, '..', '..', '..', 'src', 'agent-assets'),\n ]\n return candidates.find(dir => existsSync(dir)) ?? null\n}\n\n/**\n * Copy bundled assets to the config directory when it lacks agents/ and skills/ subdirectories.\n * Returns the config dir path on success, null if bundledDir is null.\n */\nexport async function bootstrapAssetsIfNeeded(\n configDir: string,\n bundledDir: string | null,\n): Promise<string | null> {\n if (!bundledDir) return null\n\n const hasAssets = ASSET_CATEGORIES.some(cat => existsSync(join(configDir, cat)))\n if (hasAssets) return configDir\n\n for (const category of ASSET_CATEGORIES) {\n const src = join(bundledDir, category)\n const dest = join(configDir, category)\n\n if (!existsSync(src)) continue\n await mkdir(dest, { recursive: true })\n\n const entries = await readdir(src, { withFileTypes: true })\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n await cp(join(src, entry.name), join(dest, entry.name), {\n recursive: true,\n force: false,\n errorOnExist: false,\n })\n }\n }\n\n return configDir\n}\n\n/**\n * Resolve the source directory for agent assets.\n * Priority: config dir (with asset subdirs) > bootstrap from bundled > bundled fallback.\n *\n * Optional configDir and bundledDir parameters override defaults for testability.\n */\nexport async function resolveSourceDir(\n configDir?: string,\n bundledDir?: string | null,\n): Promise<string | null> {\n const config = configDir ?? getDefaultConfigDir()\n const bundled = bundledDir === undefined ? getBundledAssetsDir() : bundledDir\n\n // Priority 1: config directory already has asset subdirectories\n const hasAssets = ASSET_CATEGORIES.some(cat => existsSync(join(config, cat)))\n if (hasAssets) return config\n\n // Priority 2: bootstrap bundled assets into config dir\n const bootstrapped = await bootstrapAssetsIfNeeded(config, bundled)\n if (bootstrapped) return bootstrapped\n\n // Priority 3: fall back to bundled assets directly\n return bundled\n}\n\n/** Resolve the agent's config directory based on scope */\nfunction resolveAgentBaseDir(agentType: AgentType, scope: InstallScope, cwd: string): string {\n const agent = agents[agentType]\n return scope === 'global' && agent.globalConfigDir\n ? agent.globalConfigDir\n : join(cwd, agent.configDir)\n}\n\nexport async function agentInitCommand(options: AgentInitOptions): Promise<void> {\n try {\n p.intro(chalk.blue('Install Skills & Agents'))\n\n const sourceDir = await resolveSourceDir()\n if (!sourceDir) {\n p.log.error('Agent assets not found.')\n p.log.info('Bundled agent assets not found. Are you running from the package?')\n process.exit(1)\n }\n\n const discovered = await discoverAllAssets(sourceDir)\n const totalAssets = discovered.agents.length + discovered.skills.length\n\n if (totalAssets === 0) {\n p.log.warn(`No assets found in ${sourceDir}`)\n process.exit(0)\n }\n\n // Deterministic defaults\n const selectedAgents: AgentType[] = options.agents ?? ['claude-code']\n const scope: InstallScope = options.scope ?? 'project'\n const mode: InstallMode = options.mode ?? 'symlink'\n const cwd = process.cwd()\n\n // Check for existing installations (prompt only if TTY and not --force)\n if (!options.force) {\n for (const agentType of selectedAgents) {\n const agentDir = resolveAgentBaseDir(agentType, scope, cwd)\n\n if (existsSync(agentDir) && process.stdin.isTTY) {\n const overwrite = await p.confirm({\n message: `${agents[agentType].displayName} directory already exists at ${agentDir}. Overwrite?`,\n initialValue: false,\n })\n\n if (p.isCancel(overwrite) || !overwrite) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n }\n }\n }\n\n // Install all assets\n const allAssets = [...discovered.skills, ...discovered.agents]\n\n interface InstallEntry {\n asset: Asset\n agentType: AgentType\n success: boolean\n symlinkFailed?: boolean\n error?: string\n }\n const results: InstallEntry[] = []\n\n for (const asset of allAssets) {\n for (const agentType of selectedAgents) {\n const result = await installAssetForAgent(asset, agentType, { scope, cwd, mode })\n results.push({\n asset,\n agentType,\n success: result.success,\n symlinkFailed: result.symlinkFailed,\n error: result.error,\n })\n }\n }\n\n // Print itemized list by category\n for (const category of ASSET_CATEGORIES) {\n const categoryResults = results.filter(r => r.asset.category === category)\n if (categoryResults.length === 0) continue\n\n const label = category.charAt(0).toUpperCase() + category.slice(1)\n p.log.step(chalk.bold(label))\n\n for (const entry of categoryResults) {\n if (entry.success && entry.symlinkFailed) {\n p.log.warn(` ⚠ ${entry.asset.name} (symlink failed, copied instead)`)\n } else if (entry.success) {\n p.log.success(` ✓ ${entry.asset.name}`)\n } else {\n p.log.error(` ✗ ${entry.asset.name}: ${entry.error}`)\n }\n }\n }\n\n // Summary\n const totalInstalled = results.filter(r => r.success).length\n const totalFailed = results.filter(r => !r.success).length\n const agentNames = selectedAgents.map(a => agents[a].displayName).join(', ')\n let message = `Installed ${totalInstalled} asset(s) to ${agentNames}`\n if (totalFailed > 0) {\n message += chalk.red(` (${totalFailed} failed)`)\n }\n message += chalk.gray(`\\n Scope: ${scope} | Mode: ${mode}`)\n\n p.outro(message)\n } catch (error) {\n p.log.error(`Error during agent init: ${error}`)\n process.exit(1)\n }\n}\n","import { readdir, readFile } from 'fs/promises'\nimport { join } from 'path'\nimport type { Asset } from './types.js'\n\n/** Parse SKILL.md frontmatter to extract name and description */\nexport function parseSkillFrontmatter(content: string): {\n name: string\n description: string\n} | null {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/)\n if (!match) return null\n\n const data: Record<string, string> = {}\n\n for (const line of match[1].split('\\n')) {\n const colonIndex = line.indexOf(':')\n if (colonIndex > 0) {\n const key = line.slice(0, colonIndex).trim()\n const value = line.slice(colonIndex + 1).trim()\n data[key] = value.replace(/^[\"']|[\"']$/g, '')\n }\n }\n\n if (!data.name || !data.description) return null\n\n return { name: data.name, description: data.description }\n}\n\n/** Discover skills from a directory (looks for subdirectories with SKILL.md) */\nexport async function discoverSkills(basePath: string): Promise<Asset[]> {\n const assets: Asset[] = []\n\n try {\n const entries = await readdir(basePath, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n\n const skillDir = join(basePath, entry.name)\n\n try {\n const content = await readFile(join(skillDir, 'SKILL.md'), 'utf-8')\n const parsed = parseSkillFrontmatter(content)\n\n assets.push({\n name: parsed?.name ?? entry.name,\n description: parsed?.description ?? '',\n sourcePath: skillDir,\n category: 'skills',\n isDirectory: true,\n })\n } catch {\n // No readable SKILL.md in this directory, skip\n }\n }\n } catch {\n // basePath doesn't exist or isn't readable\n }\n\n return assets\n}\n\n/** Discover agent/command directories containing markdown files */\nexport async function discoverMarkdownAssets(\n basePath: string,\n category: 'commands' | 'agents',\n): Promise<Asset[]> {\n const assets: Asset[] = []\n\n try {\n const entries = await readdir(basePath, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n\n const dirPath = join(basePath, entry.name)\n\n // Look for a .md file matching the directory name\n const mdFile = join(dirPath, `${entry.name}.md`)\n let description = ''\n try {\n const content = await readFile(mdFile, 'utf-8')\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/)\n if (match) {\n const descMatch = match[1].match(/description:\\s*(.+)/)\n if (descMatch) {\n description = descMatch[1].trim().replace(/^[\"']|[\"']$/g, '')\n }\n }\n } catch {\n // No matching .md file, skip this directory\n continue\n }\n\n assets.push({\n name: entry.name,\n description,\n sourcePath: dirPath,\n category,\n isDirectory: true,\n })\n }\n } catch {\n // basePath doesn't exist\n }\n\n return assets\n}\n\n/** Discover all assets from a source directory (expected layout: agents/, skills/) */\nexport async function discoverAllAssets(sourcePath: string): Promise<{\n agents: Asset[]\n skills: Asset[]\n}> {\n const [agents, skills] = await Promise.all([\n discoverMarkdownAssets(join(sourcePath, 'agents'), 'agents'),\n discoverSkills(join(sourcePath, 'skills')),\n ])\n\n return { agents, skills }\n}\n","import { mkdir, cp, readdir, symlink as fsSymlink, lstat, rm, readlink } from 'fs/promises'\nimport { join, basename, normalize, resolve, sep, relative, dirname } from 'path'\nimport { homedir, platform } from 'os'\nimport type { AgentType, Asset, InstallMode, InstallResult, InstallScope } from './types.js'\nimport type { AssetCategory } from './constants.js'\nimport { agents } from './registry.js'\nimport { CANONICAL_DIR, CATEGORY_SUBDIRS } from './constants.js'\n\nexport function sanitizeName(name: string): string {\n const sanitized = name\n .toLowerCase()\n .replace(/[^a-z0-9._]+/g, '-')\n .replace(/^[.-]+|[.-]+$/g, '')\n return sanitized.substring(0, 255) || 'unnamed-asset'\n}\n\nfunction isPathSafe(basePath: string, targetPath: string): boolean {\n const normalizedBase = normalize(resolve(basePath))\n const normalizedTarget = normalize(resolve(targetPath))\n return normalizedTarget.startsWith(normalizedBase + sep) || normalizedTarget === normalizedBase\n}\n\nexport function getAgentDir(\n agentType: AgentType,\n category: AssetCategory,\n scope: InstallScope,\n cwd?: string,\n): string {\n const agent = agents[agentType]\n const agentBase =\n scope === 'global' && agent.globalConfigDir\n ? agent.globalConfigDir\n : join(cwd || process.cwd(), agent.configDir)\n return join(agentBase, CATEGORY_SUBDIRS[category])\n}\n\nexport function getCanonicalDir(\n category: AssetCategory,\n scope: InstallScope,\n cwd?: string,\n): string {\n const baseDir = scope === 'global' ? homedir() : cwd || process.cwd()\n return join(baseDir, CANONICAL_DIR, CATEGORY_SUBDIRS[category])\n}\n\nasync function cleanAndCreateDirectory(dirPath: string): Promise<void> {\n try {\n await rm(dirPath, { recursive: true, force: true })\n } catch {\n // Ignore: directory may not exist\n }\n await mkdir(dirPath, { recursive: true })\n}\n\nasync function createSymlink(target: string, linkPath: string): Promise<boolean> {\n try {\n const resolvedTarget = resolve(target)\n const resolvedLinkPath = resolve(linkPath)\n\n if (resolvedTarget === resolvedLinkPath) {\n return true\n }\n\n // Remove existing entry at link path if present\n try {\n const stats = await lstat(linkPath)\n if (stats.isSymbolicLink()) {\n const existingTarget = await readlink(linkPath)\n const resolvedExisting = resolve(dirname(linkPath), existingTarget)\n if (resolvedExisting === resolvedTarget) {\n return true\n }\n await rm(linkPath)\n } else {\n await rm(linkPath, { recursive: true })\n }\n } catch (err: unknown) {\n const code = err && typeof err === 'object' && 'code' in err ? err.code : undefined\n if (code === 'ELOOP') {\n try {\n await rm(linkPath, { force: true })\n } catch {\n // Will fail at symlink creation below and trigger copy fallback\n }\n }\n }\n\n const linkDir = dirname(linkPath)\n await mkdir(linkDir, { recursive: true })\n\n const relativePath = relative(linkDir, target)\n const symlinkType = platform() === 'win32' ? 'junction' : undefined\n await fsSymlink(relativePath, linkPath, symlinkType)\n return true\n } catch {\n return false\n }\n}\n\nconst EXCLUDE_FILES = new Set(['README.md', 'metadata.json'])\nconst EXCLUDE_DIRS = new Set(['.git'])\n\nfunction isExcluded(name: string, isDirectory: boolean): boolean {\n if (name.startsWith('_')) return true\n return isDirectory ? EXCLUDE_DIRS.has(name) : EXCLUDE_FILES.has(name)\n}\n\nasync function copyDirectoryContents(src: string, dest: string): Promise<void> {\n await mkdir(dest, { recursive: true })\n const entries = await readdir(src, { withFileTypes: true })\n\n await Promise.all(\n entries\n .filter(entry => !isExcluded(entry.name, entry.isDirectory()))\n .map(async entry => {\n const srcPath = join(src, entry.name)\n const destPath = join(dest, entry.name)\n if (entry.isDirectory()) {\n await copyDirectoryContents(srcPath, destPath)\n } else {\n await cp(srcPath, destPath, { dereference: true, recursive: true })\n }\n }),\n )\n}\n\nexport async function installAssetForAgent(\n asset: Asset,\n agentType: AgentType,\n options: { scope?: InstallScope; cwd?: string; mode?: InstallMode } = {},\n): Promise<InstallResult> {\n const agent = agents[agentType]\n const scope = options.scope ?? 'project'\n const cwd = options.cwd || process.cwd()\n const installMode = options.mode ?? 'symlink'\n\n if (scope === 'global' && agent.globalConfigDir === undefined) {\n return {\n success: false,\n path: '',\n mode: installMode,\n error: `${agent.displayName} does not support global installation`,\n }\n }\n\n const assetName = sanitizeName(asset.name)\n\n const agentBase = getAgentDir(agentType, asset.category, scope, cwd)\n const agentDir = join(agentBase, assetName)\n\n // Guard against path traversal\n if (!isPathSafe(agentBase, agentDir)) {\n return {\n success: false,\n path: agentDir,\n mode: installMode,\n error: 'Invalid asset name: potential path traversal detected',\n }\n }\n\n try {\n const copyAsset = async (targetDir: string) => {\n if (asset.isDirectory) {\n await copyDirectoryContents(asset.sourcePath, targetDir)\n } else {\n await mkdir(targetDir, { recursive: true })\n const fileName = basename(asset.sourcePath)\n await cp(asset.sourcePath, join(targetDir, fileName), { dereference: true })\n }\n }\n\n if (installMode === 'copy') {\n await cleanAndCreateDirectory(agentDir)\n await copyAsset(agentDir)\n return { success: true, path: agentDir, mode: 'copy' }\n }\n\n // Symlink mode\n if (scope === 'project') {\n // Project scope: use in-repo intermediate to keep symlinks within repo\n const canonicalBase = getCanonicalDir(asset.category, scope, cwd)\n const canonicalDir = join(canonicalBase, assetName)\n\n await cleanAndCreateDirectory(canonicalDir)\n await copyAsset(canonicalDir)\n\n await rm(agentDir, { recursive: true, force: true })\n await mkdir(dirname(agentDir), { recursive: true })\n\n const symlinkCreated = await createSymlink(canonicalDir, agentDir)\n if (!symlinkCreated) {\n // Fallback to copy\n await cleanAndCreateDirectory(agentDir)\n await copyAsset(agentDir)\n return {\n success: true,\n path: agentDir,\n canonicalPath: canonicalDir,\n mode: 'symlink',\n symlinkFailed: true,\n }\n }\n\n return { success: true, path: agentDir, canonicalPath: canonicalDir, mode: 'symlink' }\n } else {\n // Global scope: direct symlink to source (both paths outside repo)\n await rm(agentDir, { recursive: true, force: true })\n await mkdir(dirname(agentDir), { recursive: true })\n\n const symlinkCreated = await createSymlink(asset.sourcePath, agentDir)\n if (!symlinkCreated) {\n // Fallback to copy\n await cleanAndCreateDirectory(agentDir)\n await copyAsset(agentDir)\n return { success: true, path: agentDir, mode: 'symlink', symlinkFailed: true }\n }\n\n return { success: true, path: agentDir, mode: 'symlink' }\n }\n } catch (error) {\n return {\n success: false,\n path: agentDir,\n mode: installMode,\n error: error instanceof Error ? error.message : 'Unknown error',\n }\n }\n}\n","import { existsSync } from 'fs'\nimport { join } from 'path'\nimport { cp, readdir, mkdir, rm, lstat } from 'fs/promises'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { getBundledAssetsDir } from './init.js'\nimport { getDefaultConfigDir, loadConfigFile } from '../../config.js'\nimport { discoverAllAssets } from './discovery.js'\nimport { installAssetForAgent } from './installer.js'\nimport { agents, getAllAgents } from './registry.js'\nimport { CATEGORY_SUBDIRS } from './constants.js'\nimport type { AgentType, InstallMode, InstallScope } from './types.js'\n\nconst ASSET_CATEGORIES = ['agents', 'skills'] as const\n\ninterface UpdateResult {\n seeded: string[]\n skipped: string[]\n}\n\n/**\n * Re-seed bundled assets into config dir, overwriting only those\n * that match bundled asset directory names.\n */\nexport async function updateBundledAssets(\n configDir: string,\n bundledDir: string,\n): Promise<UpdateResult> {\n const seeded: string[] = []\n const skipped: string[] = []\n\n for (const category of ASSET_CATEGORIES) {\n const bundledCategoryDir = join(bundledDir, category)\n const configCategoryDir = join(configDir, category)\n\n if (!existsSync(bundledCategoryDir)) continue\n await mkdir(configCategoryDir, { recursive: true })\n\n const bundledEntries = await readdir(bundledCategoryDir, { withFileTypes: true })\n\n for (const entry of bundledEntries) {\n if (!entry.isDirectory()) continue\n\n const src = join(bundledCategoryDir, entry.name)\n const dest = join(configCategoryDir, entry.name)\n\n // Force overwrite: remove existing then copy\n await rm(dest, { recursive: true, force: true })\n await cp(src, dest, { recursive: true })\n seeded.push(`${category}/${entry.name}`)\n }\n\n // Identify user-added assets (in config dir but not in bundle)\n if (existsSync(configCategoryDir)) {\n const configEntries = await readdir(configCategoryDir, { withFileTypes: true })\n const bundledNames = new Set(bundledEntries.filter(e => e.isDirectory()).map(e => e.name))\n for (const entry of configEntries) {\n if (entry.isDirectory() && !bundledNames.has(entry.name)) {\n skipped.push(`${category}/${entry.name}`)\n }\n }\n }\n }\n\n return { seeded, skipped }\n}\n\nexport interface InstallTarget {\n agentType: AgentType\n scope: InstallScope\n mode: InstallMode\n cwd: string\n}\n\n/**\n * Detect existing installations by scanning agent config dirs.\n * Returns a list of (agentType, scope, mode, cwd) to re-install into.\n */\nexport async function detectInstallTargets(repoPaths: string[]): Promise<InstallTarget[]> {\n const targets: InstallTarget[] = []\n\n for (const agent of getAllAgents()) {\n // Check project-scope installations for each repo\n for (const repoPath of repoPaths) {\n const mode = await detectModeInDir(repoPath, agent.configDir)\n if (mode) {\n targets.push({ agentType: agent.name, scope: 'project', mode, cwd: repoPath })\n }\n }\n\n // Check global-scope installation\n if (agent.globalConfigDir) {\n const mode = await detectModeInBaseDir(agent.globalConfigDir)\n if (mode) {\n targets.push({ agentType: agent.name, scope: 'global', mode, cwd: process.cwd() })\n }\n }\n }\n\n return targets\n}\n\n/**\n * Detect install mode by checking asset entries in an agent's config dir.\n * Checks skills/ and agents/ subdirs for symlink vs regular directory entries.\n * Returns the majority mode, or null if no assets found.\n */\nasync function detectModeInDir(\n repoPath: string,\n agentConfigDir: string,\n): Promise<InstallMode | null> {\n const baseDir = join(repoPath, agentConfigDir)\n return detectModeInBaseDir(baseDir)\n}\n\nasync function detectModeInBaseDir(baseDir: string): Promise<InstallMode | null> {\n let symlinkCount = 0\n let copyCount = 0\n\n for (const category of Object.values(CATEGORY_SUBDIRS)) {\n const categoryDir = join(baseDir, category)\n if (!existsSync(categoryDir)) continue\n\n try {\n const entries = await readdir(categoryDir)\n for (const name of entries) {\n const entryPath = join(categoryDir, name)\n try {\n const stats = await lstat(entryPath)\n if (stats.isSymbolicLink()) {\n symlinkCount++\n } else if (stats.isDirectory()) {\n copyCount++\n }\n } catch {\n // skip unreadable entries\n }\n }\n } catch {\n // skip unreadable category dirs\n }\n }\n\n if (symlinkCount === 0 && copyCount === 0) return null\n return symlinkCount >= copyCount ? 'symlink' : 'copy'\n}\n\nexport interface SkillUpdateOptions {\n all?: boolean\n}\n\nexport async function skillUpdateCommand(options: SkillUpdateOptions): Promise<void> {\n try {\n p.intro(chalk.blue('Update Skills'))\n\n // Step 1: Find bundled assets\n const bundledDir = getBundledAssetsDir()\n if (!bundledDir) {\n p.log.error('Bundled assets not found. Are you running from the package?')\n process.exit(1)\n }\n\n const configDir = getDefaultConfigDir()\n\n // Step 2: Re-seed config dir from bundle\n p.log.step('Updating config directory from bundle...')\n const seedResult = await updateBundledAssets(configDir, bundledDir)\n\n for (const name of seedResult.seeded) {\n p.log.info(` Updated: ${name}`)\n }\n if (seedResult.skipped.length > 0) {\n p.log.info(chalk.gray(` Preserved ${seedResult.skipped.length} custom asset(s)`))\n }\n\n // Step 3: Discover updated assets from config dir\n const discovered = await discoverAllAssets(configDir)\n // Filter to only bundled assets (those that were just seeded)\n const bundledAssetNames = new Set(seedResult.seeded.map(s => s.split('/')[1]))\n const bundledAssets = [\n ...discovered.agents.filter(a => bundledAssetNames.has(a.name)),\n ...discovered.skills.filter(a => bundledAssetNames.has(a.name)),\n ]\n\n if (bundledAssets.length === 0) {\n p.log.warn('No assets to update.')\n p.outro('Done.')\n return\n }\n\n // Step 4: Collect repo paths to scan\n const repoPaths: string[] = []\n\n if (options.all) {\n const config = loadConfigFile()\n if (config.thoughts?.repoMappings) {\n for (const repoPath of Object.keys(config.thoughts.repoMappings)) {\n if (existsSync(repoPath)) {\n repoPaths.push(repoPath)\n } else {\n p.log.warn(`Skipping (not found): ${repoPath}`)\n }\n }\n }\n // Include cwd if not already listed\n const cwd = process.cwd()\n if (!repoPaths.includes(cwd) && existsSync(join(cwd, '.git'))) {\n repoPaths.push(cwd)\n }\n } else {\n repoPaths.push(process.cwd())\n }\n\n // Step 5: Detect existing installations\n p.log.step('Detecting existing installations...')\n const targets = await detectInstallTargets(repoPaths)\n\n if (targets.length === 0) {\n p.log.warn('No existing installations detected. Run `thc skill install` first.')\n p.outro('Done.')\n return\n }\n\n for (const t of targets) {\n const scopeLabel = t.scope === 'global' ? 'global' : t.cwd\n p.log.info(chalk.gray(` ${agents[t.agentType].displayName}: ${scopeLabel} (${t.mode})`))\n }\n\n // Step 6: Re-install updated assets into each detected target\n const s = p.spinner()\n s.start('Installing updated assets...')\n\n let totalInstalled = 0\n let totalFailed = 0\n\n for (const target of targets) {\n for (const asset of bundledAssets) {\n const result = await installAssetForAgent(asset, target.agentType, {\n scope: target.scope,\n cwd: target.cwd,\n mode: target.mode,\n })\n\n if (result.success) {\n totalInstalled++\n } else {\n totalFailed++\n if (result.error) {\n p.log.warn(\n `Failed: ${asset.name} → ${agents[target.agentType].displayName}: ${result.error}`,\n )\n }\n }\n }\n }\n\n s.stop('Update complete.')\n\n // Summary\n const uniqueRepos = new Set(targets.filter(t => t.scope === 'project').map(t => t.cwd))\n const hasGlobal = targets.some(t => t.scope === 'global')\n let message = `Updated ${totalInstalled} asset(s)`\n if (uniqueRepos.size > 0) {\n message += ` in ${uniqueRepos.size} repo(s)`\n }\n if (hasGlobal) {\n message += ` + global`\n }\n if (totalFailed > 0) {\n message += chalk.red(` (${totalFailed} failed)`)\n }\n\n p.outro(message)\n } catch (error) {\n p.log.error(`Error during skill update: ${error}`)\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport { agentInitCommand } from './agent/init.js'\nimport { skillUpdateCommand } from './agent/update.js'\nimport type { AgentType, InstallMode } from './agent/types.js'\nimport { isValidAgentType } from './agent/registry.js'\n\nexport function skillCommand(program: Command): void {\n const skill = program.command('skill').description('Manage skill and agent asset installation')\n\n skill\n .command('install')\n .description('Install skills and agent configs to target agent directories')\n .option('--target <agents...>', 'Target agents (e.g., claude-code codebuddy)')\n .option('-g, --global', 'Install to global scope')\n .option('--mode <mode>', 'Installation mode: symlink or copy (default: symlink)')\n .option('--force', 'Force overwrite of existing installations')\n .action(async options => {\n const agentTypes: AgentType[] | undefined = options.target?.map((a: string) => {\n if (!isValidAgentType(a)) {\n console.error(`Unknown agent: ${a}`)\n process.exit(1)\n }\n return a as AgentType\n })\n\n let mode: InstallMode | undefined\n if (options.mode) {\n if (options.mode !== 'symlink' && options.mode !== 'copy') {\n console.error(`Invalid mode: ${options.mode}. Must be 'symlink' or 'copy'`)\n process.exit(1)\n }\n mode = options.mode as InstallMode\n }\n\n await agentInitCommand({\n agents: agentTypes,\n scope: options.global ? 'global' : undefined,\n mode,\n force: options.force,\n })\n })\n\n skill\n .command('update')\n .description('Update skills from package bundle and refresh installations')\n .option('--all', 'Update all registered repos (from config repoMappings)')\n .action(async options => {\n await skillUpdateCommand({ all: options.all })\n })\n}\n","import path from 'path'\nimport { isGitRepo, getCurrentBranch, getCurrentCommit, getRepoRoot } from '../../git.js'\n\ninterface GitInfo {\n repoRoot: string\n repoName: string\n branch: string\n commit: string\n}\n\nfunction getGitInfo(): GitInfo | null {\n if (!isGitRepo()) {\n return null\n }\n\n try {\n const repoRoot = getRepoRoot()\n const repoName = path.basename(repoRoot)\n const branch = getCurrentBranch()\n const commit = getCurrentCommit()\n\n return { repoRoot, repoName, branch, commit }\n } catch {\n return null\n }\n}\n\nfunction formatDate(date: Date): string {\n const pad = (n: number) => n.toString().padStart(2, '0')\n\n const year = date.getFullYear()\n const month = pad(date.getMonth() + 1)\n const day = pad(date.getDate())\n const hours = pad(date.getHours())\n const minutes = pad(date.getMinutes())\n const seconds = pad(date.getSeconds())\n\n // Get timezone name\n const tz = Intl.DateTimeFormat().resolvedOptions().timeZone\n\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds} ${tz}`\n}\n\nfunction formatFilenameTimestamp(date: Date): string {\n const pad = (n: number) => n.toString().padStart(2, '0')\n\n const year = date.getFullYear()\n const month = pad(date.getMonth() + 1)\n const day = pad(date.getDate())\n const hours = pad(date.getHours())\n const minutes = pad(date.getMinutes())\n const seconds = pad(date.getSeconds())\n\n return `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`\n}\n\nexport async function specMetadataCommand(): Promise<void> {\n const now = new Date()\n\n // Output datetime with timezone\n console.log(`Current Date/Time (TZ): ${formatDate(now)}`)\n\n // Output git info if available\n const gitInfo = getGitInfo()\n if (gitInfo) {\n if (gitInfo.commit) {\n console.log(`Current Git Commit Hash: ${gitInfo.commit}`)\n }\n if (gitInfo.branch) {\n console.log(`Current Branch Name: ${gitInfo.branch}`)\n }\n if (gitInfo.repoName) {\n console.log(`Repository Name: ${gitInfo.repoName}`)\n }\n }\n\n // Output timestamp suitable for filenames\n console.log(`Timestamp For Filename: ${formatFilenameTimestamp(now)}`)\n}\n","import { Command } from 'commander'\nimport { specMetadataCommand } from './metadata/metadata.js'\n\nexport function metadataCommand(program: Command): void {\n program\n .command('metadata')\n .description('Output metadata for current repository (branch, commit, timestamp, etc.)')\n .action(specMetadataCommand)\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport {\n isGitRepo,\n validateWorktreeHandle,\n getMainWorktreeRoot,\n getWorktreesBaseDir,\n setBranchBase,\n runGitCommandOrThrow,\n} from '../../git.js'\nimport {\n sessionNameForHandle,\n allSessionNamesForHandle,\n tmuxHasSession,\n tmuxNewSession,\n isTmuxAvailable,\n} from '../../tmux.js'\nimport { copyAgentConfigDirs } from '../../agent-config.js'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n createThoughtsDirectoryStructure,\n} from '../thoughts/utils/index.js'\nimport { setupThoughtsDirectory, pullThoughtsFromRemote } from '../thoughts/init-core.js'\nimport { resolveProfileForRepo, getRepoNameFromMapping } from '../thoughts/profile/utils.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\nimport type { WorktreeAddOptions } from './utils.js'\n\nexport async function worktreeAddCommand(name: string, options: WorktreeAddOptions): Promise<void> {\n try {\n validateWorktreeHandle(name)\n\n if (!isGitRepo()) {\n console.error(chalk.red('Error: not in a git repository'))\n process.exit(1)\n }\n\n const mainRoot = getMainWorktreeRoot()\n const baseDir = getWorktreesBaseDir(mainRoot)\n const worktreePath = options.path ? path.resolve(options.path) : path.join(baseDir, name)\n const branch = options.detached ? '' : (options.branch ?? name)\n const sessionName = sessionNameForHandle(name)\n\n fs.mkdirSync(path.dirname(worktreePath), { recursive: true })\n\n const tmuxAvailable = isTmuxAvailable()\n\n if (tmuxAvailable) {\n const sessionCandidates = allSessionNamesForHandle(name)\n const existingSession = sessionCandidates.find(s => tmuxHasSession(s))\n if (existingSession) {\n console.error(chalk.red(`Error: tmux session already exists: ${existingSession}`))\n process.exit(1)\n }\n }\n\n // Execute PreWorktreeAdd hooks\n const hooksConfig = loadHooksConfig(mainRoot)\n const preAddHooks = getHooksForEvent(hooksConfig, 'PreWorktreeAdd')\n\n if (preAddHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: worktreePath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: branch,\n THC_MAIN_ROOT: mainRoot,\n THC_SESSION_NAME: sessionName,\n THC_BASE_REF: options.base,\n }\n\n await executeHooks(\n preAddHooks,\n {\n hook_event_name: 'PreWorktreeAdd',\n cwd: mainRoot,\n worktree_path: worktreePath,\n worktree_name: name,\n worktree_branch: branch,\n main_root: mainRoot,\n session_name: sessionName,\n base_ref: options.base,\n },\n hookEnv,\n true,\n )\n }\n\n if (options.detached) {\n runGitCommandOrThrow(['worktree', 'add', '--detach', worktreePath, options.base], {\n cwd: mainRoot,\n })\n } else {\n runGitCommandOrThrow(['worktree', 'add', '-b', branch, worktreePath, options.base], {\n cwd: mainRoot,\n })\n setBranchBase(branch, options.base, worktreePath)\n }\n\n if (tmuxAvailable) {\n tmuxNewSession(sessionName, worktreePath)\n } else {\n console.log(chalk.yellow('Warning: tmux not found, skipping session creation'))\n }\n\n // Copy agent configuration directories\n const configResult = copyAgentConfigDirs({\n sourceDir: mainRoot,\n targetDir: worktreePath,\n })\n if (configResult.copied.length > 0) {\n console.log(chalk.gray(`Copied config: ${configResult.copied.join(', ')}`))\n }\n\n // Initialize thoughts (unless --no-thoughts is specified)\n if (options.thoughts !== false) {\n initializeWorktreeThoughts(mainRoot, worktreePath)\n }\n\n // Execute PostWorktreeAdd hooks\n const postAddHooks = getHooksForEvent(hooksConfig, 'PostWorktreeAdd')\n\n if (postAddHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: worktreePath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: branch,\n THC_MAIN_ROOT: mainRoot,\n THC_SESSION_NAME: sessionName,\n }\n\n await executeHooks(\n postAddHooks,\n {\n hook_event_name: 'PostWorktreeAdd',\n cwd: worktreePath,\n worktree_path: worktreePath,\n worktree_name: name,\n worktree_branch: branch,\n main_root: mainRoot,\n session_name: sessionName,\n },\n hookEnv,\n true,\n )\n }\n\n console.log(chalk.green('\\n✓ Worktree created'))\n console.log(chalk.gray(`Path: ${worktreePath}`))\n if (tmuxAvailable) {\n console.log(chalk.gray(`Tmux session: ${sessionName}`))\n console.log(chalk.gray(`Attach: tmux attach -t ${sessionName}`))\n }\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n}\n\nfunction initializeWorktreeThoughts(mainRoot: string, worktreePath: string): void {\n const config = loadThoughtsConfig({})\n if (!config) {\n console.log(chalk.yellow('Thoughts not configured globally, skipping'))\n return\n }\n\n const mainRepoMapping = config.repoMappings[mainRoot]\n const mappedName = getRepoNameFromMapping(mainRepoMapping)\n\n if (!mappedName) {\n console.log(chalk.yellow('Main repo not configured for thoughts, skipping'))\n return\n }\n\n // Add repo mapping for new worktree\n config.repoMappings[worktreePath] = mainRepoMapping\n saveThoughtsConfig(config, {})\n\n const profileConfig = resolveProfileForRepo(config, worktreePath)\n\n // Ensure the thoughts directory structure exists in thoughts repo\n createThoughtsDirectoryStructure(profileConfig, mappedName, config.user)\n\n // Set up thoughts directory\n const result = setupThoughtsDirectory({\n repoPath: worktreePath,\n profileConfig,\n mappedName,\n user: config.user,\n createSearchable: true,\n setupHooks: true,\n })\n\n console.log(chalk.gray('Thoughts initialized'))\n if (result.hooksUpdated.length > 0) {\n console.log(chalk.gray(`Updated git hooks: ${result.hooksUpdated.join(', ')}`))\n }\n\n // Sync thoughts from remote\n if (pullThoughtsFromRemote(profileConfig.thoughtsRepo)) {\n console.log(chalk.gray('Pulled latest thoughts from remote'))\n }\n}\n","import { execFileSync } from 'child_process'\n\n// Session naming\nexport function sessionNameForHandle(handle: string): string {\n // NOTE: tmux uses ':' as a target separator (session:window.pane),\n // so ':' is not allowed in session names on many tmux versions.\n return `thc-${handle}`\n}\n\nexport function legacySessionNameForHandle(handle: string): string {\n return `thc:${handle}`\n}\n\nexport function allSessionNamesForHandle(handle: string): string[] {\n return [sessionNameForHandle(handle), legacySessionNameForHandle(handle)]\n}\n\n// Availability check\nlet _tmuxAvailable: boolean | undefined\n\nexport function isTmuxAvailable(): boolean {\n if (_tmuxAvailable === undefined) {\n try {\n execFileSync('tmux', ['-V'], { stdio: 'ignore' })\n _tmuxAvailable = true\n } catch {\n _tmuxAvailable = false\n }\n }\n return _tmuxAvailable\n}\n\n// Session management\nexport function listTmuxSessions(): string[] {\n try {\n const out = execFileSync('tmux', ['list-sessions', '-F', '#{session_name}'], {\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'pipe'],\n }).trim()\n return out\n .split('\\n')\n .map(s => s.trim())\n .filter(Boolean)\n } catch {\n return []\n }\n}\n\nexport function tmuxHasSession(sessionName: string): boolean {\n try {\n execFileSync('tmux', ['has-session', '-t', sessionName], {\n stdio: 'ignore',\n })\n return true\n } catch {\n return false\n }\n}\n\nexport function tmuxNewSession(sessionName: string, cwd: string): void {\n execFileSync('tmux', ['new-session', '-d', '-s', sessionName, '-c', cwd], {\n stdio: 'inherit',\n })\n}\n\nexport function tmuxKillSession(sessionName: string): void {\n try {\n execFileSync('tmux', ['kill-session', '-t', sessionName], { stdio: 'ignore' })\n } catch {\n // ignore\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { agents } from './commands/agent/registry.js'\nimport { CANONICAL_DIR } from './commands/agent/constants.js'\n\nexport interface CopyAgentConfigOptions {\n /** Source directory (main worktree) */\n sourceDir: string\n /** Target directory (new worktree) */\n targetDir: string\n}\n\nexport interface CopyAgentConfigResult {\n /** Agent config directories that were copied */\n copied: string[]\n /** Agent config directories that were skipped (not present in source) */\n skipped: string[]\n}\n\n/**\n * Detect which agent config directories exist in the source directory.\n * Scans for unique configDir values from the agent registry.\n */\nfunction detectAgentConfigDirs(sourceDir: string): string[] {\n const uniqueDirs = [...new Set(Object.values(agents).map(a => a.configDir))]\n // Also include the canonical intermediate directory\n uniqueDirs.push(CANONICAL_DIR)\n return uniqueDirs.filter(dir => fs.existsSync(path.join(sourceDir, dir)))\n}\n\n/**\n * Create a symlink at destPath, falling back to a dereferenced copy on failure.\n * Silently skips if both the symlink and copy fail (e.g. broken source symlink).\n */\nfunction symlinkOrCopy(srcPath: string, destPath: string, linkTarget: string): void {\n try {\n fs.symlinkSync(linkTarget, destPath)\n } catch {\n try {\n fs.cpSync(srcPath, destPath, { recursive: true, dereference: true })\n } catch {\n // Skip — source symlink may be broken\n }\n }\n}\n\n/**\n * Recursively copy a directory, preserving symlinks as-is.\n */\nfunction copyDirWithSymlinkHandling(srcDir: string, destDir: string): void {\n fs.mkdirSync(destDir, { recursive: true })\n\n for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {\n const srcPath = path.join(srcDir, entry.name)\n const destPath = path.join(destDir, entry.name)\n\n if (entry.isSymbolicLink()) {\n symlinkOrCopy(srcPath, destPath, fs.readlinkSync(srcPath))\n } else if (entry.isDirectory()) {\n copyDirWithSymlinkHandling(srcPath, destPath)\n } else {\n fs.cpSync(srcPath, destPath)\n }\n }\n}\n\n/**\n * Copy agent configuration directories to a new worktree.\n *\n * Copies agent config dirs (e.g. .claude/) and the canonical intermediate\n * directory (.thought-cabinet/) so that project-scope symlinks resolve correctly.\n * Preserves symlinks as-is. Non-symlink files are copied normally.\n */\nexport function copyAgentConfigDirs(options: CopyAgentConfigOptions): CopyAgentConfigResult {\n const { sourceDir, targetDir } = options\n const copied: string[] = []\n const skipped: string[] = []\n\n // Detect and copy agent config directories\n for (const dirName of detectAgentConfigDirs(sourceDir)) {\n try {\n copyDirWithSymlinkHandling(path.join(sourceDir, dirName), path.join(targetDir, dirName))\n copied.push(dirName)\n } catch {\n skipped.push(dirName)\n }\n }\n\n return { copied, skipped }\n}\n","import path from 'path'\nimport chalk from 'chalk'\nimport {\n isGitRepo,\n getMainWorktreeRoot,\n getWorktreesBaseDir,\n runGitCommand,\n parseWorktreeListPorcelain,\n} from '../../git.js'\nimport { allSessionNamesForHandle, listTmuxSessions } from '../../tmux.js'\nimport type { WorktreeListOptions } from './utils.js'\n\ninterface WorktreeRow {\n name: string\n branch: string\n tmux: string\n path: string\n isCurrent: boolean\n}\n\nexport async function worktreeListCommand(options: WorktreeListOptions): Promise<void> {\n try {\n if (!isGitRepo()) {\n console.error(chalk.red('Error: not in a git repository'))\n process.exit(1)\n }\n\n const mainRoot = getMainWorktreeRoot()\n const baseDir = path.resolve(getWorktreesBaseDir(mainRoot))\n const cwd = path.resolve(process.cwd())\n\n const entries = parseWorktreeListPorcelain(\n runGitCommand(['worktree', 'list', '--porcelain'], { cwd: mainRoot }),\n )\n\n const sessions = new Set(listTmuxSessions())\n\n const filtered = options.all\n ? entries\n : entries.filter(e => {\n const p = path.resolve(e.worktreePath)\n return p === path.resolve(mainRoot) || p.startsWith(baseDir + path.sep)\n })\n\n if (filtered.length === 0) {\n console.log(chalk.gray('No worktrees found.'))\n return\n }\n\n const rows: WorktreeRow[] = filtered.map(e => {\n const name = path.basename(e.worktreePath)\n const isCurrent = path.resolve(e.worktreePath) === cwd\n return {\n name: isCurrent ? `* ${name}` : ` ${name}`,\n branch: e.branch,\n tmux: allSessionNamesForHandle(name).find(s => sessions.has(s)) ?? '-',\n path: e.worktreePath,\n isCurrent,\n }\n })\n\n const colWidths = {\n name: Math.max(' NAME'.length, ...rows.map(r => r.name.length)),\n branch: Math.max('BRANCH'.length, ...rows.map(r => r.branch.length)),\n tmux: Math.max('TMUX'.length, ...rows.map(r => r.tmux.length)),\n }\n\n // Print header\n const header =\n `${' NAME'.padEnd(colWidths.name)} ` +\n `${'BRANCH'.padEnd(colWidths.branch)} ` +\n `${'TMUX'.padEnd(colWidths.tmux)} ` +\n `PATH`\n console.log(chalk.blue(header))\n\n // Print rows\n for (const row of rows) {\n const line =\n `${row.name.padEnd(colWidths.name)} ` +\n `${row.branch.padEnd(colWidths.branch)} ` +\n `${row.tmux.padEnd(colWidths.tmux)} ` +\n `${row.path}`\n\n console.log(row.isCurrent ? chalk.green(line) : line)\n }\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n}\n","import path from 'path'\nimport chalk from 'chalk'\nimport {\n isGitRepo,\n getMainWorktreeRoot,\n findWorktree,\n hasUncommittedChanges,\n runGitCommandOrThrow,\n runGitCommand,\n} from '../../git.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\nimport {\n cleanupWorktreeThoughts,\n cleanupWorktreeTmuxSession,\n removeGitWorktree,\n deleteWorktreeBranch,\n type WorktreeMergeOptions,\n} from './utils.js'\n\nexport async function worktreeMergeCommand(\n name: string,\n options: WorktreeMergeOptions,\n): Promise<void> {\n try {\n if (!isGitRepo()) {\n console.error(chalk.red('Error: not in a git repository'))\n process.exit(1)\n }\n\n const mainRoot = getMainWorktreeRoot()\n const wtEntry = findWorktree(name, mainRoot)\n const wtPath = path.resolve(wtEntry.worktreePath)\n\n if (wtPath === path.resolve(mainRoot)) {\n console.error(chalk.red('Error: refusing to merge/remove the main worktree'))\n process.exit(1)\n }\n\n if (wtEntry.detached || wtEntry.branch === '(detached)') {\n console.error(chalk.red('Error: cannot merge a detached worktree'))\n process.exit(1)\n }\n\n const targetBranch =\n options.into ?? runGitCommand(['branch', '--show-current'], { cwd: mainRoot })\n if (!targetBranch) {\n console.error(chalk.red('Error: could not determine target branch. Use --into <branch>.'))\n process.exit(1)\n }\n\n if (targetBranch === wtEntry.branch) {\n console.error(chalk.red('Error: source and target branch are the same'))\n process.exit(1)\n }\n\n // Execute PreWorktreeMerge hooks\n const hooksConfig = loadHooksConfig(mainRoot)\n const preHooks = getHooksForEvent(hooksConfig, 'PreWorktreeMerge')\n\n if (preHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: wtPath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: wtEntry.branch,\n THC_TARGET_BRANCH: targetBranch,\n THC_MAIN_ROOT: mainRoot,\n }\n\n await executeHooks(\n preHooks,\n {\n hook_event_name: 'PreWorktreeMerge',\n cwd: mainRoot,\n worktree_path: wtPath,\n worktree_name: name,\n worktree_branch: wtEntry.branch,\n target_branch: targetBranch,\n main_root: mainRoot,\n },\n hookEnv,\n true,\n )\n }\n\n // Clean up thoughts before checking uncommitted changes\n // (thoughts/ directory would show as untracked and cause false positive)\n cleanupWorktreeThoughts(wtPath, { force: options.force, verbose: true })\n\n if (!options.force && hasUncommittedChanges(wtEntry.worktreePath)) {\n console.error(\n chalk.red('Error: worktree has uncommitted changes. Commit/stash first or use --force.'),\n )\n process.exit(1)\n }\n\n console.log(chalk.blue(`Rebasing ${wtEntry.branch} onto ${targetBranch}...`))\n runGitCommandOrThrow(['rebase', targetBranch], { cwd: wtEntry.worktreePath })\n\n console.log(chalk.blue(`Fast-forward merging into ${targetBranch}...`))\n runGitCommandOrThrow(['switch', targetBranch], { cwd: mainRoot })\n runGitCommandOrThrow(['merge', '--ff-only', wtEntry.branch], { cwd: mainRoot })\n\n if (!options.keepSession) {\n cleanupWorktreeTmuxSession(wtPath)\n }\n\n if (!options.keepWorktree) {\n removeGitWorktree(wtPath, mainRoot, { force: options.force })\n }\n\n if (!options.keepBranch) {\n deleteWorktreeBranch(wtEntry.branch, mainRoot, { force: options.force })\n }\n\n // Execute PostWorktreeMerge hooks\n const postHooks = getHooksForEvent(hooksConfig, 'PostWorktreeMerge')\n\n if (postHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: wtPath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: wtEntry.branch,\n THC_TARGET_BRANCH: targetBranch,\n THC_MAIN_ROOT: mainRoot,\n THC_KEPT_SESSION: options.keepSession ? 'true' : 'false',\n THC_KEPT_WORKTREE: options.keepWorktree ? 'true' : 'false',\n THC_KEPT_BRANCH: options.keepBranch ? 'true' : 'false',\n }\n\n await executeHooks(\n postHooks,\n {\n hook_event_name: 'PostWorktreeMerge',\n cwd: mainRoot,\n worktree_path: wtPath,\n worktree_name: name,\n worktree_branch: wtEntry.branch,\n target_branch: targetBranch,\n main_root: mainRoot,\n kept_session: options.keepSession ?? false,\n kept_worktree: options.keepWorktree ?? false,\n kept_branch: options.keepBranch ?? false,\n },\n hookEnv,\n true,\n )\n }\n\n console.log(chalk.green('✓ Merged and cleaned up'))\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n}\n","import path from 'path'\nimport chalk from 'chalk'\nimport { allSessionNamesForHandle, tmuxKillSession } from '../../tmux.js'\nimport { runGitCommandOrThrow } from '../../git.js'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n cleanupThoughtsDirectory,\n} from '../thoughts/utils/index.js'\n\nexport interface WorktreeAddOptions {\n branch?: string\n base: string\n path?: string\n detached?: boolean\n thoughts?: boolean\n}\n\nexport interface WorktreeListOptions {\n all?: boolean\n}\n\nexport interface WorktreeMergeOptions {\n into?: string\n force?: boolean\n keepSession?: boolean\n keepWorktree?: boolean\n keepBranch?: boolean\n}\n\nexport interface WorktreeRemoveOptions {\n force?: boolean\n}\n\n/**\n * Clean up thoughts directory for a worktree\n */\nexport function cleanupWorktreeThoughts(\n wtPath: string,\n options: { force?: boolean; verbose?: boolean } = {},\n): void {\n const config = loadThoughtsConfig({})\n if (!config || !config.repoMappings[wtPath]) {\n return\n }\n\n try {\n if (options.verbose) {\n console.log(chalk.gray('Cleaning up thoughts directory...'))\n }\n const result = cleanupThoughtsDirectory({\n repoPath: wtPath,\n config,\n force: options.force,\n verbose: false,\n })\n\n if (result.configRemoved) {\n saveThoughtsConfig(config, {})\n }\n\n if (result.thoughtsRemoved && options.verbose) {\n console.log(chalk.gray('✓ Thoughts directory cleaned up'))\n }\n } catch (error) {\n if (options.verbose) {\n console.log(chalk.yellow(`Warning: Could not clean up thoughts: ${(error as Error).message}`))\n }\n }\n}\n\n/**\n * Kill tmux sessions for a worktree\n */\nexport function cleanupWorktreeTmuxSession(wtPath: string): void {\n const handle = path.basename(wtPath)\n const sessionNames = allSessionNamesForHandle(handle)\n for (const s of sessionNames) {\n tmuxKillSession(s)\n }\n}\n\n/**\n * Remove git worktree\n */\nexport function removeGitWorktree(\n wtPath: string,\n mainRoot: string,\n options: { force?: boolean } = {},\n): void {\n const removeArgs = ['worktree', 'remove']\n if (options.force) {\n removeArgs.push('--force')\n }\n removeArgs.push(wtPath)\n runGitCommandOrThrow(removeArgs, { cwd: mainRoot })\n\n // Best-effort prune\n try {\n runGitCommandOrThrow(['worktree', 'prune'], { cwd: mainRoot })\n } catch {\n // ignore\n }\n}\n\n/**\n * Delete a branch\n */\nexport function deleteWorktreeBranch(\n branch: string,\n mainRoot: string,\n options: { force?: boolean } = {},\n): void {\n try {\n runGitCommandOrThrow(['branch', '-d', branch], { cwd: mainRoot })\n } catch {\n if (options.force) {\n runGitCommandOrThrow(['branch', '-D', branch], { cwd: mainRoot })\n } else {\n throw new Error(`Failed to delete branch '${branch}'. Re-run with --force to force delete.`)\n }\n }\n}\n","import path from 'path'\nimport chalk from 'chalk'\nimport {\n isGitRepo,\n getMainWorktreeRoot,\n findWorktree,\n hasUncommittedChanges,\n hasUnmergedCommits,\n getDefaultBranch,\n} from '../../git.js'\nimport { loadHooksConfig, getHooksForEvent, executeHooks } from '../../hooks/index.js'\nimport {\n cleanupWorktreeThoughts,\n cleanupWorktreeTmuxSession,\n removeGitWorktree,\n deleteWorktreeBranch,\n type WorktreeRemoveOptions,\n} from './utils.js'\n\nexport async function worktreeRemoveCommand(\n name: string,\n options: WorktreeRemoveOptions,\n): Promise<void> {\n try {\n if (!isGitRepo()) {\n console.error(chalk.red('Error: not in a git repository'))\n process.exit(1)\n }\n\n const mainRoot = getMainWorktreeRoot()\n const wtEntry = findWorktree(name, mainRoot)\n const wtPath = path.resolve(wtEntry.worktreePath)\n const hasBranch = !wtEntry.detached && wtEntry.branch !== '(detached)'\n\n if (wtPath === path.resolve(mainRoot)) {\n console.error(chalk.red('Error: refusing to remove the main worktree'))\n process.exit(1)\n }\n\n // Check for unmerged commits (only if branch exists)\n if (!options.force && hasBranch) {\n const defaultBranch = getDefaultBranch(mainRoot)\n if (hasUnmergedCommits(wtEntry.branch, defaultBranch, mainRoot)) {\n console.error(\n chalk.red(\n `Error: branch '${wtEntry.branch}' has commits not merged into '${defaultBranch}'. ` +\n `Merge first or use --force to discard.`,\n ),\n )\n process.exit(1)\n }\n }\n\n // Execute PreWorktreeRemove hooks\n const hooksConfig = loadHooksConfig(mainRoot)\n const preHooks = getHooksForEvent(hooksConfig, 'PreWorktreeRemove')\n\n if (preHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: wtPath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: wtEntry.branch,\n THC_MAIN_ROOT: mainRoot,\n }\n\n await executeHooks(\n preHooks,\n {\n hook_event_name: 'PreWorktreeRemove',\n cwd: mainRoot,\n worktree_path: wtPath,\n worktree_name: name,\n worktree_branch: wtEntry.branch,\n main_root: mainRoot,\n },\n hookEnv,\n true,\n )\n }\n\n // Clean up thoughts directory before checking uncommitted changes\n // (thoughts/ directory would show as untracked and cause false positive)\n cleanupWorktreeThoughts(wtPath, { force: options.force, verbose: true })\n\n if (!options.force && hasUncommittedChanges(wtEntry.worktreePath)) {\n console.error(\n chalk.red('Error: worktree has uncommitted changes. Commit/stash first or use --force.'),\n )\n process.exit(1)\n }\n\n cleanupWorktreeTmuxSession(wtPath)\n\n console.log(chalk.gray('Removing git worktree...'))\n removeGitWorktree(wtPath, mainRoot, { force: options.force })\n\n if (hasBranch) {\n console.log(chalk.gray(`Deleting branch '${wtEntry.branch}'...`))\n try {\n deleteWorktreeBranch(wtEntry.branch, mainRoot, { force: options.force })\n } catch (error) {\n console.log(chalk.yellow(`Warning: ${(error as Error).message}`))\n }\n }\n\n // Execute PostWorktreeRemove hooks\n const postHooks = getHooksForEvent(hooksConfig, 'PostWorktreeRemove')\n\n if (postHooks.length > 0) {\n const hookEnv = {\n THC_WORKTREE_PATH: wtPath,\n THC_WORKTREE_NAME: name,\n THC_WORKTREE_BRANCH: wtEntry.branch,\n THC_MAIN_ROOT: mainRoot,\n }\n\n await executeHooks(\n postHooks,\n {\n hook_event_name: 'PostWorktreeRemove',\n cwd: mainRoot,\n worktree_path: wtPath,\n worktree_name: name,\n worktree_branch: wtEntry.branch,\n main_root: mainRoot,\n },\n hookEnv,\n true,\n )\n }\n\n console.log(chalk.green('✓ Worktree removed'))\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport { worktreeAddCommand } from './worktree/add.js'\nimport { worktreeListCommand } from './worktree/list.js'\nimport { worktreeMergeCommand } from './worktree/merge.js'\nimport { worktreeRemoveCommand } from './worktree/remove.js'\n\nexport function worktreeCommand(program: Command): void {\n const wt = program.command('worktree').description('Manage git worktrees bound to tmux sessions')\n\n wt.command('add <name>')\n .description('Create a git worktree and a tmux session for it')\n .option('--branch <branch>', 'Branch name (defaults to <name>)')\n .option('--base <ref>', 'Base ref/commit (default: HEAD)', 'HEAD')\n .option('--path <path>', 'Worktree directory path (default: ../<repo>__worktrees/<name>)')\n .option('--detached', 'Create a detached worktree at <base> (no branch)')\n .option('--no-thoughts', 'Skip thoughts initialization')\n .action(worktreeAddCommand)\n\n wt.command('list')\n .description('List thc-managed worktrees and their tmux sessions')\n .option('--all', 'Show all git worktrees (not just ../<repo>__worktrees)')\n .action(worktreeListCommand)\n\n wt.command('merge <name>')\n .description(\n 'Rebase worktree branch onto target, ff-merge, then clean up worktree + tmux session',\n )\n .option(\n '--into <branch>',\n 'Target branch to merge into (default: current branch in main worktree)',\n )\n .option('--force', 'Force cleanup even if uncommitted changes exist')\n .option('--keep-session', 'Do not kill the tmux session')\n .option('--keep-worktree', 'Do not remove the git worktree')\n .option('--keep-branch', 'Do not delete the source branch')\n .action(worktreeMergeCommand)\n\n wt.command('remove <name>')\n .description(\n 'Remove a worktree and clean up associated resources (tmux session, thoughts, branch)',\n )\n .option('--force', 'Force removal even with uncommitted changes or unmerged commits')\n .action(worktreeRemoveCommand)\n}\n","import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport { fileURLToPath } from 'url'\nimport { dirname } from 'path'\nimport { HOOKS_CONFIG_DIR, HOOKS_CONFIG_FILE } from '../../hooks/index.js'\n\n// Get the directory of this module\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport async function hooksInitCommand(): Promise<void> {\n try {\n const repoPath = process.cwd()\n const configDir = path.join(repoPath, HOOKS_CONFIG_DIR)\n const configPath = path.join(repoPath, HOOKS_CONFIG_FILE)\n\n // Check if config already exists\n if (fs.existsSync(configPath)) {\n console.log(chalk.yellow(`${HOOKS_CONFIG_FILE} already exists.`))\n console.log(chalk.gray(`Edit the file directly: ${configPath}`))\n return\n }\n\n // Find the example file\n // Try multiple possible locations for the example file\n const possiblePaths = [\n // When running from built dist: one level up from dist/\n path.resolve(__dirname, '..', '.thought-cabinet/hooks.example.json'),\n // When installed via npm: one level up from dist/\n path.resolve(__dirname, '../..', '.thought-cabinet/hooks.example.json'),\n ]\n\n let examplePath: string | null = null\n for (const candidatePath of possiblePaths) {\n if (fs.existsSync(candidatePath)) {\n examplePath = candidatePath\n break\n }\n }\n\n if (!examplePath) {\n console.error(chalk.red('Error: hooks.example.json not found in expected locations'))\n console.log(chalk.gray('Searched paths:'))\n possiblePaths.forEach(p => console.log(chalk.gray(` - ${p}`)))\n process.exit(1)\n }\n\n // Create directory and copy example file\n fs.mkdirSync(configDir, { recursive: true })\n fs.copyFileSync(examplePath, configPath)\n\n console.log(chalk.green(`Created ${HOOKS_CONFIG_FILE}`))\n } catch (error) {\n console.error(chalk.red(`Error during hooks init: ${error}`))\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport { hooksInitCommand } from './hooks/init.js'\n\nexport function hooksCommand(program: Command): void {\n const hooks = program.command('hooks').description('Manage hook configuration')\n\n hooks\n .command('init')\n .description('Initialize hooks configuration in current repository')\n .action(hooksInitCommand)\n}\n","import { Command } from 'commander'\n\nexport function completionCommand(program: Command): void {\n const completion = program\n .command('completion')\n .description('Manage shell completion for thoughtcabinet CLI')\n\n completion\n .command('install')\n .description('Install shell completion scripts')\n .action(async () => {\n const { install } = await import('../completion/installer.js')\n await install()\n })\n\n completion\n .command('uninstall')\n .description('Remove shell completion scripts')\n .action(async () => {\n const { uninstall } = await import('../completion/installer.js')\n await uninstall()\n })\n}\n","import tabtab from 'tabtab'\nimport { getProfileNames, getWorktreeNames, getBranchNames, getAgentNames } from './providers.js'\n\n// Top-level commands available on the program\nconst TOP_LEVEL_COMMANDS = [\n 'init',\n 'destroy',\n 'sync',\n 'status',\n 'config',\n 'prune',\n 'migrate',\n 'profile',\n 'worktree',\n 'skill',\n 'metadata',\n 'hooks',\n 'completion',\n]\n\n// Subcommands for command groups\nconst SUBCOMMANDS: Record<string, string[]> = {\n profile: ['create', 'list', 'show', 'delete'],\n worktree: ['add', 'list', 'merge', 'remove'],\n skill: ['install', 'update'],\n hooks: ['init'],\n completion: ['install', 'uninstall'],\n}\n\n// Options for each command\nconst OPTIONS: Record<string, string[]> = {\n init: ['--force', '--config-file', '--directory', '--profile'],\n destroy: ['--force', '--config-file'],\n sync: ['-m', '--message', '--config-file'],\n status: ['--config-file', '--fetch'],\n config: ['--edit', '--json', '--config-file'],\n prune: ['--apply', '--config-file'],\n migrate: ['--dry-run', '--config-file'],\n 'profile create': ['--repo', '--repos-dir', '--global-dir', '--config-file'],\n 'profile list': ['--json', '--config-file'],\n 'profile show': ['--json', '--config-file'],\n 'profile delete': ['--force', '--config-file'],\n 'worktree add': ['--branch', '--base', '--path', '--detached', '--no-thoughts'],\n 'worktree list': ['--all'],\n 'worktree merge': ['--into', '--force', '--keep-session', '--keep-worktree', '--keep-branch'],\n 'worktree remove': ['--force'],\n 'skill install': ['--force', '--target', '--global', '--mode'],\n 'skill update': ['--all'],\n}\n\n// Commands that expect dynamic arguments\nconst DYNAMIC_ARGS: Record<string, () => string[]> = {\n 'profile show': getProfileNames,\n 'profile delete': getProfileNames,\n 'worktree merge': getWorktreeNames,\n 'worktree remove': getWorktreeNames,\n}\n\n// Options that expect dynamic values\nconst DYNAMIC_OPTIONS: Record<string, () => string[]> = {\n '--profile': getProfileNames,\n '--branch': getBranchNames,\n '--base': getBranchNames,\n '--into': getBranchNames,\n '--target': getAgentNames,\n '--mode': () => ['symlink', 'copy'],\n}\n\nexport async function handleCompletion(): Promise<boolean> {\n const env = tabtab.parseEnv(process.env)\n\n if (!env.complete) {\n return false\n }\n\n const { line, prev } = env\n const args = line.split(' ').filter(Boolean).slice(1) // Remove CLI name\n\n // Check if previous word is an option expecting dynamic value\n if (prev in DYNAMIC_OPTIONS) {\n const provider = DYNAMIC_OPTIONS[prev]\n await tabtab.log(provider())\n return true\n }\n\n // Complete top-level commands\n if (args.length === 0 || (args.length === 1 && !line.endsWith(' '))) {\n const partial = args[0] || ''\n const matches = TOP_LEVEL_COMMANDS.filter(cmd => cmd.startsWith(partial))\n await tabtab.log(matches)\n return true\n }\n\n const firstArg = args[0]\n\n // Complete subcommands for command groups\n if (firstArg in SUBCOMMANDS) {\n const subcommands = SUBCOMMANDS[firstArg]\n if (args.length === 1 && line.endsWith(' ')) {\n await tabtab.log(subcommands)\n return true\n }\n if (args.length === 2 && !line.endsWith(' ')) {\n const partial = args[1]\n const matches = subcommands.filter(sub => sub.startsWith(partial))\n await tabtab.log(matches)\n return true\n }\n }\n\n // Check for dynamic argument completion\n const commandKey = args.slice(0, 2).join(' ')\n if (commandKey in DYNAMIC_ARGS && args.length === 2 && line.endsWith(' ')) {\n const provider = DYNAMIC_ARGS[commandKey]\n await tabtab.log(provider())\n return true\n }\n\n // Complete options\n if (prev.startsWith('-')) {\n // Option expects a value, don't complete\n await tabtab.log([])\n return true\n }\n\n // Determine command context for options\n const options = OPTIONS[commandKey] || OPTIONS[firstArg] || []\n\n if (line.endsWith(' ') || prev.startsWith('-')) {\n const usedOptions = args.filter(arg => arg.startsWith('-'))\n const availableOptions = options.filter(opt => !usedOptions.includes(opt))\n await tabtab.log(availableOptions)\n return true\n }\n\n await tabtab.log([])\n return true\n}\n","import { loadConfigFile } from '../config.js'\nimport {\n isGitRepo,\n runGitCommand,\n parseWorktreeListPorcelain,\n getMainWorktreeRoot,\n getWorktreesBaseDir,\n} from '../git.js'\nimport path from 'path'\n\n/**\n * Get list of profile names from config\n */\nexport function getProfileNames(): string[] {\n try {\n const config = loadConfigFile()\n if (!config.thoughts?.profiles) {\n return []\n }\n return Object.keys(config.thoughts.profiles)\n } catch {\n return []\n }\n}\n\n/**\n * Get list of worktree names (directory basenames)\n */\nexport function getWorktreeNames(): string[] {\n try {\n if (!isGitRepo()) {\n return []\n }\n\n const mainRoot = getMainWorktreeRoot()\n const baseDir = getWorktreesBaseDir(mainRoot)\n const output = runGitCommand(['worktree', 'list', '--porcelain'])\n const entries = parseWorktreeListPorcelain(output)\n\n // Filter to only thc-managed worktrees and extract names\n return entries\n .filter(e => {\n const p = path.resolve(e.worktreePath)\n return p.startsWith(baseDir + path.sep)\n })\n .map(e => path.basename(e.worktreePath))\n } catch {\n return []\n }\n}\n\n/**\n * Get list of local branch names\n */\nexport function getBranchNames(): string[] {\n try {\n if (!isGitRepo()) {\n return []\n }\n\n const output = runGitCommand(['branch', '--format=%(refname:short)'])\n return output.split('\\n').filter(Boolean)\n } catch {\n return []\n }\n}\n\n/**\n * Get list of agent type names for completion\n */\nexport function getAgentNames(): string[] {\n return ['claude-code', 'codebuddy']\n}\n"],"mappings":"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","names":["fs","path","execSync","chalk","path","path","path","fs","path","path","os","fs","path","isGitRepo","fs","path","path","fs","fs","path","chalk","path","fs","chalk","fs","path","execSync","path","fs","execSync","fs","path","chalk","chalk","resolve","path","fs","execSync","reposDir","chalk","inheritedProfile","fs","path","chalk","path","fs","chalk","fs","path","execSync","execFileSync","chalk","execSync","execFileSync","chalk","path","fs","fs","path","execSync","chalk","execSync","chalk","path","fs","spawn","chalk","spawn","chalk","fs","chalk","chalk","fs","fs","path","chalk","p","home","path","fs","agents","chalk","confirm","chalk","path","p","chalk","path","chalk","chalk","chalk","chalk","chalk","p","chalk","existsSync","dirname","join","resolve","chalk","p","cp","mkdir","readdir","join","agents","readdir","join","homedir","join","homedir","readdir","__dirname","dirname","resolve","existsSync","join","mkdir","readdir","cp","chalk","existsSync","join","cp","readdir","mkdir","rm","lstat","chalk","p","ASSET_CATEGORIES","join","existsSync","mkdir","readdir","rm","cp","lstat","chalk","s","path","path","fs","path","chalk","execFileSync","fs","path","fs","path","chalk","path","fs","path","chalk","chalk","path","p","path","chalk","path","chalk","chalk","path","chalk","path","path","chalk","chalk","path","fs","path","chalk","fileURLToPath","dirname","__filename","fileURLToPath","__dirname","dirname","path","fs","chalk","p","path","p","dotenv","require"]}
|