thought-cabinet 0.0.3 → 0.0.4
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/dist/index.js +288 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -297,8 +297,8 @@ function ensureThoughtsRepoExists(configOrThoughtsRepo, reposDir, globalDir) {
|
|
|
297
297
|
fs2.mkdirSync(expandedGlobal, { recursive: true });
|
|
298
298
|
}
|
|
299
299
|
const gitPath = path4.join(expandedRepo, ".git");
|
|
300
|
-
const
|
|
301
|
-
if (!
|
|
300
|
+
const isGitRepo2 = fs2.existsSync(gitPath) && (fs2.statSync(gitPath).isDirectory() || fs2.statSync(gitPath).isFile());
|
|
301
|
+
if (!isGitRepo2) {
|
|
302
302
|
execSync("git init", { cwd: expandedRepo });
|
|
303
303
|
const gitignore = generateGitignore();
|
|
304
304
|
fs2.writeFileSync(path4.join(expandedRepo, ".gitignore"), gitignore);
|
|
@@ -2095,6 +2095,291 @@ function metadataCommand(program2) {
|
|
|
2095
2095
|
program2.command("metadata").description("Output metadata for current repository (branch, commit, timestamp, etc.)").action(specMetadataCommand);
|
|
2096
2096
|
}
|
|
2097
2097
|
|
|
2098
|
+
// src/commands/worktree.ts
|
|
2099
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
2100
|
+
import fs9 from "fs";
|
|
2101
|
+
import path11 from "path";
|
|
2102
|
+
import chalk12 from "chalk";
|
|
2103
|
+
function run(cmd, args, opts = {}) {
|
|
2104
|
+
return execFileSync2(cmd, args, {
|
|
2105
|
+
cwd: opts.cwd,
|
|
2106
|
+
encoding: "utf8",
|
|
2107
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
2108
|
+
}).trim();
|
|
2109
|
+
}
|
|
2110
|
+
function runOrThrow(cmd, args, opts = {}) {
|
|
2111
|
+
execFileSync2(cmd, args, {
|
|
2112
|
+
cwd: opts.cwd,
|
|
2113
|
+
stdio: "inherit"
|
|
2114
|
+
});
|
|
2115
|
+
}
|
|
2116
|
+
function validateWorktreeHandle(name) {
|
|
2117
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name)) {
|
|
2118
|
+
throw new Error(
|
|
2119
|
+
`Invalid worktree name '${name}'. Use only [A-Za-z0-9._-] and start with a letter/number.`
|
|
2120
|
+
);
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
function isGitRepo(cwd) {
|
|
2124
|
+
try {
|
|
2125
|
+
run("git", ["rev-parse", "--git-dir"], { cwd });
|
|
2126
|
+
return true;
|
|
2127
|
+
} catch {
|
|
2128
|
+
return false;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
function parseWorktreeListPorcelain(output) {
|
|
2132
|
+
const blocks = output.trim().length === 0 ? [] : output.trim().split(/\n\n+/);
|
|
2133
|
+
const out = [];
|
|
2134
|
+
for (const block of blocks) {
|
|
2135
|
+
let worktreePath = "";
|
|
2136
|
+
let branch = "";
|
|
2137
|
+
let detached = false;
|
|
2138
|
+
for (const line of block.split("\n")) {
|
|
2139
|
+
if (line.startsWith("worktree ")) {
|
|
2140
|
+
worktreePath = line.slice("worktree ".length).trim();
|
|
2141
|
+
} else if (line.startsWith("branch refs/heads/")) {
|
|
2142
|
+
branch = line.slice("branch refs/heads/".length).trim();
|
|
2143
|
+
} else if (line.trim() === "detached") {
|
|
2144
|
+
detached = true;
|
|
2145
|
+
branch = "(detached)";
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
if (worktreePath && branch) {
|
|
2149
|
+
out.push({ worktreePath, branch, detached });
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
return out;
|
|
2153
|
+
}
|
|
2154
|
+
function getMainWorktreeRoot(cwd) {
|
|
2155
|
+
const list = run("git", ["worktree", "list", "--porcelain"], { cwd });
|
|
2156
|
+
const entries = parseWorktreeListPorcelain(list);
|
|
2157
|
+
if (entries.length === 0) {
|
|
2158
|
+
throw new Error("No git worktrees found");
|
|
2159
|
+
}
|
|
2160
|
+
return entries[0].worktreePath;
|
|
2161
|
+
}
|
|
2162
|
+
function getWorktreesBaseDir(mainWorktreeRoot) {
|
|
2163
|
+
const repoName = path11.basename(mainWorktreeRoot);
|
|
2164
|
+
const parent = path11.dirname(mainWorktreeRoot);
|
|
2165
|
+
return path11.join(parent, `${repoName}__worktrees`);
|
|
2166
|
+
}
|
|
2167
|
+
function findWorktree(nameOrBranch, cwd) {
|
|
2168
|
+
const list = run("git", ["worktree", "list", "--porcelain"], { cwd });
|
|
2169
|
+
const entries = parseWorktreeListPorcelain(list);
|
|
2170
|
+
for (const e of entries) {
|
|
2171
|
+
if (path11.basename(e.worktreePath) === nameOrBranch) {
|
|
2172
|
+
return e;
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
for (const e of entries) {
|
|
2176
|
+
if (e.branch === nameOrBranch) {
|
|
2177
|
+
return e;
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
throw new Error(`Worktree not found: ${nameOrBranch}`);
|
|
2181
|
+
}
|
|
2182
|
+
function hasUncommittedChanges(repoPath) {
|
|
2183
|
+
const status = run("git", ["status", "--porcelain"], { cwd: repoPath });
|
|
2184
|
+
return status.trim().length > 0;
|
|
2185
|
+
}
|
|
2186
|
+
function setBranchBase(branch, base, cwd) {
|
|
2187
|
+
runOrThrow("git", ["config", "--local", `branch.${branch}.thc-base`, base], { cwd });
|
|
2188
|
+
}
|
|
2189
|
+
function listTmuxSessions() {
|
|
2190
|
+
try {
|
|
2191
|
+
const out = run("tmux", ["list-sessions", "-F", "#{session_name}"]);
|
|
2192
|
+
return out.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
2193
|
+
} catch {
|
|
2194
|
+
return [];
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
function tmuxHasSession(sessionName) {
|
|
2198
|
+
try {
|
|
2199
|
+
execFileSync2("tmux", ["has-session", "-t", sessionName], {
|
|
2200
|
+
stdio: "ignore"
|
|
2201
|
+
});
|
|
2202
|
+
return true;
|
|
2203
|
+
} catch {
|
|
2204
|
+
return false;
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
function tmuxNewSession(sessionName, cwd) {
|
|
2208
|
+
runOrThrow("tmux", ["new-session", "-d", "-s", sessionName, "-c", cwd]);
|
|
2209
|
+
}
|
|
2210
|
+
function tmuxKillSession(sessionName) {
|
|
2211
|
+
try {
|
|
2212
|
+
execFileSync2("tmux", ["kill-session", "-t", sessionName], { stdio: "ignore" });
|
|
2213
|
+
} catch {
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
function sessionNameForHandle(handle) {
|
|
2217
|
+
return `thc-${handle}`;
|
|
2218
|
+
}
|
|
2219
|
+
function legacySessionNameForHandle(handle) {
|
|
2220
|
+
return `thc:${handle}`;
|
|
2221
|
+
}
|
|
2222
|
+
function allSessionNamesForHandle(handle) {
|
|
2223
|
+
return [sessionNameForHandle(handle), legacySessionNameForHandle(handle)];
|
|
2224
|
+
}
|
|
2225
|
+
function worktreeCommand(program2) {
|
|
2226
|
+
const wt = program2.command("worktree").description("Manage git worktrees bound to tmux sessions");
|
|
2227
|
+
wt.command("add <name>").description("Create a git worktree and a tmux session for it").option("--branch <branch>", "Branch name (defaults to <name>)").option("--base <ref>", "Base ref/commit (default: HEAD)", "HEAD").option("--path <path>", "Worktree directory path (default: ../<repo>__worktrees/<name>)").option("--detached", "Create a detached worktree at <base> (no branch)").action(async (name, options) => {
|
|
2228
|
+
try {
|
|
2229
|
+
validateWorktreeHandle(name);
|
|
2230
|
+
if (!isGitRepo()) {
|
|
2231
|
+
console.error(chalk12.red("Error: not in a git repository"));
|
|
2232
|
+
process.exit(1);
|
|
2233
|
+
}
|
|
2234
|
+
const mainRoot = getMainWorktreeRoot();
|
|
2235
|
+
const baseDir = getWorktreesBaseDir(mainRoot);
|
|
2236
|
+
const worktreePath = options.path ? path11.resolve(options.path) : path11.join(baseDir, name);
|
|
2237
|
+
fs9.mkdirSync(path11.dirname(worktreePath), { recursive: true });
|
|
2238
|
+
const sessionName = sessionNameForHandle(name);
|
|
2239
|
+
const sessionCandidates = allSessionNamesForHandle(name);
|
|
2240
|
+
const existing = sessionCandidates.find((s) => tmuxHasSession(s));
|
|
2241
|
+
if (existing) {
|
|
2242
|
+
console.error(chalk12.red(`Error: tmux session already exists: ${existing}`));
|
|
2243
|
+
process.exit(1);
|
|
2244
|
+
}
|
|
2245
|
+
if (options.detached) {
|
|
2246
|
+
runOrThrow("git", ["worktree", "add", "--detach", worktreePath, options.base], {
|
|
2247
|
+
cwd: mainRoot
|
|
2248
|
+
});
|
|
2249
|
+
} else {
|
|
2250
|
+
const branch = options.branch ?? name;
|
|
2251
|
+
runOrThrow("git", ["worktree", "add", "-b", branch, worktreePath, options.base], {
|
|
2252
|
+
cwd: mainRoot
|
|
2253
|
+
});
|
|
2254
|
+
setBranchBase(branch, options.base, worktreePath);
|
|
2255
|
+
}
|
|
2256
|
+
tmuxNewSession(sessionName, worktreePath);
|
|
2257
|
+
console.log(chalk12.green("\u2713 Worktree created"));
|
|
2258
|
+
console.log(chalk12.gray(`Path: ${worktreePath}`));
|
|
2259
|
+
console.log(chalk12.gray(`Tmux session: ${sessionName}`));
|
|
2260
|
+
console.log(chalk12.gray(`Attach: tmux attach -t ${sessionName}`));
|
|
2261
|
+
} catch (error) {
|
|
2262
|
+
console.error(chalk12.red(`Error: ${error.message}`));
|
|
2263
|
+
process.exit(1);
|
|
2264
|
+
}
|
|
2265
|
+
});
|
|
2266
|
+
wt.command("list").description("List thc-managed worktrees and their tmux sessions").option("--all", "Show all git worktrees (not just ../<repo>__worktrees)").action(async (options) => {
|
|
2267
|
+
try {
|
|
2268
|
+
if (!isGitRepo()) {
|
|
2269
|
+
console.error(chalk12.red("Error: not in a git repository"));
|
|
2270
|
+
process.exit(1);
|
|
2271
|
+
}
|
|
2272
|
+
const mainRoot = getMainWorktreeRoot();
|
|
2273
|
+
const baseDir = getWorktreesBaseDir(mainRoot);
|
|
2274
|
+
const baseDirResolved = path11.resolve(baseDir);
|
|
2275
|
+
const entries = parseWorktreeListPorcelain(
|
|
2276
|
+
run("git", ["worktree", "list", "--porcelain"], { cwd: mainRoot })
|
|
2277
|
+
);
|
|
2278
|
+
const sessions = new Set(listTmuxSessions());
|
|
2279
|
+
const filtered = options.all ? entries : entries.filter((e) => {
|
|
2280
|
+
const p5 = path11.resolve(e.worktreePath);
|
|
2281
|
+
return p5 === path11.resolve(mainRoot) || p5.startsWith(baseDirResolved + path11.sep);
|
|
2282
|
+
});
|
|
2283
|
+
if (filtered.length === 0) {
|
|
2284
|
+
console.log(chalk12.gray("No worktrees found."));
|
|
2285
|
+
return;
|
|
2286
|
+
}
|
|
2287
|
+
console.log("NAME BRANCH TMUX PATH");
|
|
2288
|
+
for (const e of filtered) {
|
|
2289
|
+
const name = path11.basename(e.worktreePath);
|
|
2290
|
+
const sessionName = allSessionNamesForHandle(name).find((s) => sessions.has(s));
|
|
2291
|
+
console.log(`${name} ${e.branch} ${sessionName ?? "-"} ${e.worktreePath}`);
|
|
2292
|
+
}
|
|
2293
|
+
} catch (error) {
|
|
2294
|
+
console.error(chalk12.red(`Error: ${error.message}`));
|
|
2295
|
+
process.exit(1);
|
|
2296
|
+
}
|
|
2297
|
+
});
|
|
2298
|
+
wt.command("merge <name>").description(
|
|
2299
|
+
"Rebase worktree branch onto target, ff-merge, then clean up worktree + tmux session"
|
|
2300
|
+
).option(
|
|
2301
|
+
"--into <branch>",
|
|
2302
|
+
"Target branch to merge into (default: current branch in main worktree)"
|
|
2303
|
+
).option("--force", "Force cleanup even if uncommitted changes exist").option("--keep-session", "Do not kill the tmux session").option("--keep-worktree", "Do not remove the git worktree").option("--keep-branch", "Do not delete the source branch").action(async (name, options) => {
|
|
2304
|
+
try {
|
|
2305
|
+
if (!isGitRepo()) {
|
|
2306
|
+
console.error(chalk12.red("Error: not in a git repository"));
|
|
2307
|
+
process.exit(1);
|
|
2308
|
+
}
|
|
2309
|
+
const mainRoot = getMainWorktreeRoot();
|
|
2310
|
+
const mainRootResolved = path11.resolve(mainRoot);
|
|
2311
|
+
const wtEntry = findWorktree(name, mainRoot);
|
|
2312
|
+
const wtResolved = path11.resolve(wtEntry.worktreePath);
|
|
2313
|
+
if (wtResolved === mainRootResolved) {
|
|
2314
|
+
console.error(chalk12.red("Error: refusing to merge/remove the main worktree"));
|
|
2315
|
+
process.exit(1);
|
|
2316
|
+
}
|
|
2317
|
+
if (wtEntry.detached || wtEntry.branch === "(detached)") {
|
|
2318
|
+
console.error(chalk12.red("Error: cannot merge a detached worktree"));
|
|
2319
|
+
process.exit(1);
|
|
2320
|
+
}
|
|
2321
|
+
const targetBranch = options.into ?? run("git", ["branch", "--show-current"], { cwd: mainRoot });
|
|
2322
|
+
if (!targetBranch) {
|
|
2323
|
+
console.error(chalk12.red("Error: could not determine target branch. Use --into <branch>."));
|
|
2324
|
+
process.exit(1);
|
|
2325
|
+
}
|
|
2326
|
+
if (targetBranch === wtEntry.branch) {
|
|
2327
|
+
console.error(chalk12.red("Error: source and target branch are the same"));
|
|
2328
|
+
process.exit(1);
|
|
2329
|
+
}
|
|
2330
|
+
if (!options.force && hasUncommittedChanges(wtEntry.worktreePath)) {
|
|
2331
|
+
console.error(
|
|
2332
|
+
chalk12.red(
|
|
2333
|
+
"Error: worktree has uncommitted changes. Commit/stash first or use --force."
|
|
2334
|
+
)
|
|
2335
|
+
);
|
|
2336
|
+
process.exit(1);
|
|
2337
|
+
}
|
|
2338
|
+
console.log(chalk12.blue(`Rebasing ${wtEntry.branch} onto ${targetBranch}...`));
|
|
2339
|
+
runOrThrow("git", ["rebase", targetBranch], { cwd: wtEntry.worktreePath });
|
|
2340
|
+
console.log(chalk12.blue(`Fast-forward merging into ${targetBranch}...`));
|
|
2341
|
+
runOrThrow("git", ["switch", targetBranch], { cwd: mainRoot });
|
|
2342
|
+
runOrThrow("git", ["merge", "--ff-only", wtEntry.branch], { cwd: mainRoot });
|
|
2343
|
+
const handle = path11.basename(wtEntry.worktreePath);
|
|
2344
|
+
const sessionNames = allSessionNamesForHandle(handle);
|
|
2345
|
+
if (!options.keepSession) {
|
|
2346
|
+
for (const s of sessionNames) {
|
|
2347
|
+
tmuxKillSession(s);
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
if (!options.keepWorktree) {
|
|
2351
|
+
const removeArgs = ["worktree", "remove"];
|
|
2352
|
+
if (options.force) {
|
|
2353
|
+
removeArgs.push("--force");
|
|
2354
|
+
}
|
|
2355
|
+
removeArgs.push(wtEntry.worktreePath);
|
|
2356
|
+
runOrThrow("git", removeArgs, { cwd: mainRoot });
|
|
2357
|
+
try {
|
|
2358
|
+
runOrThrow("git", ["worktree", "prune"], { cwd: mainRoot });
|
|
2359
|
+
} catch {
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
if (!options.keepBranch) {
|
|
2363
|
+
try {
|
|
2364
|
+
runOrThrow("git", ["branch", "-d", wtEntry.branch], { cwd: mainRoot });
|
|
2365
|
+
} catch {
|
|
2366
|
+
if (options.force) {
|
|
2367
|
+
runOrThrow("git", ["branch", "-D", wtEntry.branch], { cwd: mainRoot });
|
|
2368
|
+
} else {
|
|
2369
|
+
throw new Error(
|
|
2370
|
+
`Failed to delete branch '${wtEntry.branch}'. Re-run with --force to delete it.`
|
|
2371
|
+
);
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
console.log(chalk12.green("\u2713 Merged and cleaned up"));
|
|
2376
|
+
} catch (error) {
|
|
2377
|
+
console.error(chalk12.red(`Error: ${error.message}`));
|
|
2378
|
+
process.exit(1);
|
|
2379
|
+
}
|
|
2380
|
+
});
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2098
2383
|
// src/index.ts
|
|
2099
2384
|
import dotenv2 from "dotenv";
|
|
2100
2385
|
import { createRequire } from "module";
|
|
@@ -2108,5 +2393,6 @@ program.name("thoughtcabinet").description(
|
|
|
2108
2393
|
thoughtsCommand(program);
|
|
2109
2394
|
agentCommand(program);
|
|
2110
2395
|
metadataCommand(program);
|
|
2396
|
+
worktreeCommand(program);
|
|
2111
2397
|
program.parse(process.argv);
|
|
2112
2398
|
//# sourceMappingURL=index.js.map
|
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/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/profile/utils.ts","../src/commands/thoughts/destroy.ts","../src/commands/thoughts/sync.ts","../src/commands/thoughts/status.ts","../src/commands/thoughts/config.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/registry.ts","../src/commands/agent.ts","../src/commands/metadata/metadata.ts","../src/commands/metadata.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander'\nimport { thoughtsCommand } from './commands/thoughts.js'\nimport { agentCommand } from './commands/agent.js'\nimport { metadataCommand } from './commands/metadata.js'\nimport dotenv from 'dotenv'\nimport { createRequire } from 'node:module'\n\n// Load environment variables\ndotenv.config()\n\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json') as { version: string }\n\nconst program = new Command()\n\nprogram\n .name('thoughtcabinet')\n .description(\n 'Thought Cabinet (thc) - thoughts management CLI for developer notes and documentation',\n )\n .version(version)\n\n// Add commands\nthoughtsCommand(program)\nagentCommand(program)\nmetadataCommand(program)\n\nprogram.parse(process.argv)\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} from './utils/index.js'\nimport { validateProfile, resolveProfileForRepo, getRepoNameFromMapping } from './profile/utils.js'\nimport {\n generateClaudeMd,\n generatePreCommitHook,\n generatePostCommitHook,\n HOOK_VERSION,\n} from '../../templates/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\nfunction setupGitHooks(repoPath: string): { updated: string[] } {\n const updated: string[] = []\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\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 const 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 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) {\n const selectOptions = [\n ...existingRepos.map(repo => ({ value: repo, label: `Use existing: ${repo}` })),\n { value: '__create_new__', label: 'Create new directory' },\n ]\n\n const selection = await p.select({\n message: 'Select or create a thoughts directory for this repository:',\n options: selectOptions,\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 p.log.success(\n `Will use existing: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${mappedName}`,\n )\n }\n } else {\n // No existing repos, 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\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 // Handle searchable directories specially if they exist (might have read-only permissions)\n const searchableDir = path.join(thoughtsDir, 'searchable')\n if (fs.existsSync(searchableDir)) {\n try {\n // Reset permissions so we can delete it\n execSync(`chmod -R 755 \"${searchableDir}\"`, { stdio: 'pipe' })\n } catch {\n // Ignore chmod errors\n }\n }\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 try {\n execSync('git remote get-url origin', { cwd: expandedRepo, stdio: 'pipe' })\n // Remote exists, try to pull\n try {\n execSync('git pull --rebase', {\n stdio: 'pipe',\n cwd: expandedRepo,\n })\n p.log.success('Pulled latest thoughts from remote')\n } catch (error) {\n p.log.warn(`Could not pull latest thoughts: ${(error as Error).message}`)\n }\n } catch {\n // No remote configured, skip pull\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 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 }\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 getDefaultConfigPath(): string {\n const xdgConfigHome = process.env.XDG_CONFIG_HOME || path.join(process.env.HOME || '', '.config')\n return path.join(xdgConfigHome, 'thought-cabinet', 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}\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'\n\nexport function getDefaultThoughtsRepo(): string {\n return path.join(os.homedir(), '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","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 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","import fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport chalk from 'chalk'\nimport { loadThoughtsConfig, saveThoughtsConfig, getCurrentRepoPath } from './utils/index.js'\nimport { getRepoNameFromMapping, getProfileNameFromMapping } from './profile/utils.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 const mapping = config.repoMappings[currentRepo]\n const mappedName = getRepoNameFromMapping(mapping)\n const profileName = getProfileNameFromMapping(mapping)\n\n if (!mappedName && !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 // Step 1: Handle searchable directory if it exists\n const searchableDir = path.join(thoughtsDir, 'searchable')\n if (fs.existsSync(searchableDir)) {\n console.log(chalk.gray('Removing searchable directory...'))\n try {\n // Reset permissions in case they're restricted\n execSync(`chmod -R 755 \"${searchableDir}\"`, { stdio: 'pipe' })\n } catch {\n // Ignore chmod errors\n }\n fs.rmSync(searchableDir, { recursive: true, force: true })\n }\n\n // Step 2: Remove the entire thoughts directory\n // IMPORTANT: This only removes the local thoughts/ directory containing symlinks\n // The actual thoughts content in the thoughts repository remains untouched\n console.log(chalk.gray('Removing thoughts directory (symlinks only)...'))\n try {\n fs.rmSync(thoughtsDir, { recursive: true, force: true })\n } catch (error) {\n console.error(chalk.red(`Error removing thoughts directory: ${error}`))\n console.error(chalk.yellow('You may need to manually remove: ' + thoughtsDir))\n process.exit(1)\n }\n\n // Step 3: Remove from config if mapped\n if (mappedName) {\n console.log(chalk.gray('Removing repository from thoughts configuration...'))\n delete config.repoMappings[currentRepo]\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 (mappedName) {\n console.log('')\n console.log(chalk.gray('Note: Your thoughts content remains safe in:'))\n\n if (profileName && config.profiles && config.profiles[profileName]) {\n const profile = config.profiles[profileName]\n console.log(chalk.gray(` ${profile.thoughtsRepo}/${profile.reposDir}/${mappedName}`))\n console.log(chalk.gray(` (profile: ${profileName})`))\n } else {\n console.log(chalk.gray(` ${config.thoughtsRepo}/${config.reposDir}/${mappedName}`))\n }\n\n console.log(chalk.gray('Only the local symlinks and configuration were removed.'))\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 updateSymlinksForNewUsers,\n} from './utils/index.js'\nimport { resolveProfileForRepo, getRepoNameFromMapping } from './profile/utils.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): 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 commitMessage = message || `Sync thoughts - ${new Date().toISOString()}`\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 } 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\nfunction createSearchDirectory(thoughtsDir: string): void {\n const searchDir = path.join(thoughtsDir, 'searchable')\n // Remove existing searchable directory if it exists\n if (fs.existsSync(searchDir)) {\n try {\n // Reset permissions so we can delete it\n execSync(`chmod -R 755 \"${searchDir}\"`, { stdio: 'pipe' })\n } catch {\n // Ignore chmod errors\n }\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 console.log(chalk.gray(`Created ${linkedCount} hard links in searchable directory`))\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 createSearchDirectory(thoughtsDir)\n\n // Sync the thoughts repository using profile's thoughtsRepo\n console.log(chalk.blue('Syncing thoughts...'))\n syncThoughts(profileConfig.thoughtsRepo, options.message || '')\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\nfunction getRemoteStatus(repoPath: string): string {\n try {\n execSync('git remote get-url origin', { cwd: repoPath, stdio: 'pipe' })\n\n // Fetch to update remote refs\n try {\n execSync('git fetch', { cwd: repoPath, stdio: 'pipe' })\n } catch {\n // Fetch might fail, continue anyway\n }\n\n // Check if we're ahead/behind\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\n // Try to automatically pull if we're behind\n try {\n execSync('git pull --rebase', {\n stdio: 'pipe',\n cwd: repoPath,\n })\n console.log(chalk.green('✓ Automatically pulled latest changes'))\n\n // Re-check status after pull\n const newStatus = execSync('git status -sb', {\n encoding: 'utf8',\n cwd: repoPath,\n stdio: 'pipe',\n })\n\n if (newStatus.includes('behind')) {\n const newBehind = newStatus.match(/behind (\\d+)/)?.[1] || '?'\n return chalk.yellow(`${newBehind} commits behind remote (after pull)`)\n } else {\n return chalk.green('Up to date with remote (after pull)')\n }\n } catch {\n // Silent fail - status is read-only operation\n return chalk.yellow(`${behind} commits behind remote`)\n }\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}\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 console.log(` Remote: ${getRemoteStatus(expandedRepo)}`)\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 chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n getDefaultThoughtsRepo,\n ensureThoughtsRepoExists,\n} from '../utils/index.js'\nimport { sanitizeProfileName, validateProfile } from './utils.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 = getDefaultThoughtsRepo() + `-${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 { 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 .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 // 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 fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { fileURLToPath } from 'url'\nimport { dirname } from 'path'\nimport { AgentProduct } from './registry.js'\n\n// Get the directory of this module\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport interface AgentInitOptions {\n product: AgentProduct\n force?: boolean\n all?: boolean\n maxThinkingTokens?: number\n}\n\nfunction ensureGitignoreEntry(targetDir: string, entry: string, productName: string): void {\n const gitignorePath = path.join(targetDir, '.gitignore')\n\n // Read existing .gitignore or create empty\n let gitignoreContent = ''\n if (fs.existsSync(gitignorePath)) {\n gitignoreContent = fs.readFileSync(gitignorePath, 'utf8')\n }\n\n // Check if entry already exists\n const lines = gitignoreContent.split('\\n')\n if (lines.some(line => line.trim() === entry)) {\n return // Already exists\n }\n\n // Add entry with section comment\n const newContent =\n gitignoreContent +\n (gitignoreContent && !gitignoreContent.endsWith('\\n') ? '\\n' : '') +\n '\\n# ' +\n productName +\n ' local settings\\n' +\n entry +\n '\\n'\n\n fs.writeFileSync(gitignorePath, newContent)\n}\n\n/**\n * Recursively copy a directory\n * @returns Number of files copied\n */\nfunction copyDirectoryRecursive(sourceDir: string, targetDir: string): number {\n let filesCopied = 0\n\n // Create target directory\n fs.mkdirSync(targetDir, { recursive: true })\n\n const entries = fs.readdirSync(sourceDir, { withFileTypes: true })\n\n for (const entry of entries) {\n const sourcePath = path.join(sourceDir, entry.name)\n const targetPath = path.join(targetDir, entry.name)\n\n if (entry.isDirectory()) {\n // Recursively copy subdirectory\n filesCopied += copyDirectoryRecursive(sourcePath, targetPath)\n } else {\n // Copy file\n fs.copyFileSync(sourcePath, targetPath)\n filesCopied++\n }\n }\n\n return filesCopied\n}\n\nexport async function agentInitCommand(options: AgentInitOptions): Promise<void> {\n const { product } = options\n\n try {\n p.intro(chalk.blue(`Initialize ${product.name} Configuration`))\n\n // Check if running in interactive terminal\n if (!process.stdin.isTTY && !options.all) {\n p.log.error('Not running in interactive terminal.')\n p.log.info('Use --all flag to copy all files without prompting.')\n process.exit(1)\n }\n\n const targetDir = process.cwd()\n const agentTargetDir = path.join(targetDir, product.dirName)\n\n // Determine source location\n // Try multiple possible locations for the agent directory\n const possiblePaths = [\n // When installed via npm: package root is one level up from dist\n path.resolve(__dirname, '..', product.sourceDirName),\n // When running from repo: repo root is two levels up from dist\n path.resolve(__dirname, '../..', product.sourceDirName),\n ]\n\n let sourceAgentDir: string | null = null\n for (const candidatePath of possiblePaths) {\n if (fs.existsSync(candidatePath)) {\n sourceAgentDir = candidatePath\n break\n }\n }\n\n // Verify source directory exists\n if (!sourceAgentDir) {\n p.log.error(`Source ${product.dirName} directory not found in expected locations`)\n p.log.info('Searched paths:')\n possiblePaths.forEach(candidatePath => {\n p.log.info(` - ${candidatePath}`)\n })\n p.log.info('Are you running from the thoughtcabinet repository or npm package?')\n process.exit(1)\n }\n\n // Check if agent directory already exists\n if (fs.existsSync(agentTargetDir) && !options.force) {\n const overwrite = await p.confirm({\n message: `${product.dirName} directory already exists. 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 let selectedCategories: string[]\n\n if (options.all) {\n selectedCategories = ['commands', 'agents', 'skills', 'settings']\n } else {\n // Interactive selection\n // Calculate actual file counts\n let commandsCount = 0\n let agentsCount = 0\n\n const commandsDir = path.join(sourceAgentDir, 'commands')\n const agentsDir = path.join(sourceAgentDir, 'agents')\n\n if (fs.existsSync(commandsDir)) {\n commandsCount = fs.readdirSync(commandsDir).length\n }\n\n if (fs.existsSync(agentsDir)) {\n agentsCount = fs.readdirSync(agentsDir).length\n }\n\n let skillsCount = 0\n const skillsDir = path.join(sourceAgentDir, 'skills')\n\n if (fs.existsSync(skillsDir)) {\n // Count skill folders (not files)\n skillsCount = fs\n .readdirSync(skillsDir, { withFileTypes: true })\n .filter(dirent => dirent.isDirectory()).length\n }\n\n p.note(\n 'Use ↑/↓ to move, press Space to select/deselect, press A to select/deselect all, press Enter to confirm. (Subsequent multi-selects apply; Ctrl+C to exit)',\n 'Multi-select instructions',\n )\n const selection = await p.multiselect({\n message: 'What would you like to copy?',\n options: [\n {\n value: 'commands',\n label: 'Commands',\n hint: `${commandsCount} workflow commands (planning, CI, research, etc.)`,\n },\n {\n value: 'agents',\n label: 'Agents',\n hint: `${agentsCount} specialized sub-agents for code analysis`,\n },\n {\n value: 'skills',\n label: 'Skills',\n hint: `${skillsCount} specialized skill packages for extended capabilities`,\n },\n {\n value: 'settings',\n label: 'Settings',\n hint: 'Project permissions configuration',\n },\n ],\n initialValues: ['commands', 'agents', 'skills', 'settings'],\n required: false,\n })\n\n if (p.isCancel(selection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n selectedCategories = selection as string[]\n\n if (selectedCategories.length === 0) {\n p.cancel('No items selected.')\n process.exit(0)\n }\n }\n\n // Create agent directory\n fs.mkdirSync(agentTargetDir, { recursive: true })\n\n let filesCopied = 0\n let filesSkipped = 0\n\n // Wizard-style file selection for each category\n const filesToCopyByCategory: Record<string, string[]> = {}\n\n // If in interactive mode, prompt for file selection per category\n if (!options.all) {\n // Commands file selection (if selected)\n if (selectedCategories.includes('commands')) {\n const sourceDir = path.join(sourceAgentDir, 'commands')\n if (fs.existsSync(sourceDir)) {\n const allFiles = fs.readdirSync(sourceDir)\n const fileSelection = await p.multiselect({\n message: 'Select command files to copy:',\n options: allFiles.map(file => ({\n value: file,\n label: file,\n })),\n initialValues: allFiles,\n required: false,\n })\n\n if (p.isCancel(fileSelection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n filesToCopyByCategory['commands'] = fileSelection as string[]\n\n if (filesToCopyByCategory['commands'].length === 0) {\n filesSkipped += allFiles.length\n }\n }\n }\n\n // Agents file selection (if selected)\n if (selectedCategories.includes('agents')) {\n const sourceDir = path.join(sourceAgentDir, 'agents')\n if (fs.existsSync(sourceDir)) {\n const allFiles = fs.readdirSync(sourceDir)\n const fileSelection = await p.multiselect({\n message: 'Select agent files to copy:',\n options: allFiles.map(file => ({\n value: file,\n label: file,\n })),\n initialValues: allFiles,\n required: false,\n })\n\n if (p.isCancel(fileSelection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n filesToCopyByCategory['agents'] = fileSelection as string[]\n\n if (filesToCopyByCategory['agents'].length === 0) {\n filesSkipped += allFiles.length\n }\n }\n }\n\n // Skills folder selection (if selected)\n if (selectedCategories.includes('skills')) {\n const sourceDir = path.join(sourceAgentDir, 'skills')\n if (fs.existsSync(sourceDir)) {\n // Get skill folders (directories only)\n const allSkills = fs\n .readdirSync(sourceDir, { withFileTypes: true })\n .filter(dirent => dirent.isDirectory())\n .map(dirent => dirent.name)\n\n if (allSkills.length > 0) {\n const skillSelection = await p.multiselect({\n message: 'Select skills to copy:',\n options: allSkills.map(skill => ({\n value: skill,\n label: skill,\n })),\n initialValues: allSkills,\n required: false,\n })\n\n if (p.isCancel(skillSelection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n filesToCopyByCategory['skills'] = skillSelection as string[]\n }\n }\n }\n }\n\n // Configure settings\n let maxThinkingTokens = options.maxThinkingTokens\n\n // Prompt for settings if in interactive mode and not provided via flags\n if (!options.all && selectedCategories.includes('settings')) {\n if (maxThinkingTokens === undefined) {\n const tokensPrompt = await p.text({\n message: 'Maximum thinking tokens:',\n initialValue: '32000',\n validate: value => {\n const num = parseInt(value, 10)\n if (isNaN(num) || num < 1000) {\n return 'Please enter a valid number (minimum 1000)'\n }\n return undefined\n },\n })\n\n if (p.isCancel(tokensPrompt)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n maxThinkingTokens = parseInt(tokensPrompt as string, 10)\n }\n } else if (selectedCategories.includes('settings')) {\n // Non-interactive mode: use defaults if not provided\n if (maxThinkingTokens === undefined) {\n maxThinkingTokens = 32000\n }\n }\n\n // Copy selected categories\n for (const category of selectedCategories) {\n if (category === 'commands' || category === 'agents') {\n const sourceDir = path.join(sourceAgentDir, category)\n const targetCategoryDir = path.join(agentTargetDir, category)\n\n if (!fs.existsSync(sourceDir)) {\n p.log.warn(`${category} directory not found in source, skipping`)\n continue\n }\n\n // Get all files in category\n const allFiles = fs.readdirSync(sourceDir)\n\n // Determine which files to copy\n let filesToCopy = allFiles\n if (!options.all && filesToCopyByCategory[category]) {\n filesToCopy = filesToCopyByCategory[category]\n }\n\n if (filesToCopy.length === 0) {\n continue\n }\n\n // Copy files\n fs.mkdirSync(targetCategoryDir, { recursive: true })\n\n for (const file of filesToCopy) {\n const sourcePath = path.join(sourceDir, file)\n const targetPath = path.join(targetCategoryDir, file)\n\n fs.copyFileSync(sourcePath, targetPath)\n filesCopied++\n }\n\n filesSkipped += allFiles.length - filesToCopy.length\n p.log.success(`Copied ${filesToCopy.length} ${category} file(s)`)\n } else if (category === 'settings') {\n const settingsPath = path.join(sourceAgentDir, 'settings.template.json')\n const targetSettingsPath = path.join(agentTargetDir, 'settings.json')\n\n if (fs.existsSync(settingsPath)) {\n // Read source settings\n const settingsContent = fs.readFileSync(settingsPath, 'utf8')\n const settings = JSON.parse(settingsContent)\n\n // Merge user's configuration into settings\n if (maxThinkingTokens !== undefined) {\n if (!settings.env) {\n settings.env = {}\n }\n settings.env.MAX_THINKING_TOKENS = maxThinkingTokens.toString()\n }\n\n // Set product-specific environment variables\n if (!settings.env) {\n settings.env = {}\n }\n for (const [key, value] of Object.entries(product.defaultEnvVars)) {\n settings.env[key] = value\n }\n\n // Write modified settings\n fs.writeFileSync(targetSettingsPath, JSON.stringify(settings, null, 2) + '\\n')\n filesCopied++\n p.log.success(`Copied settings.json (maxTokens: ${maxThinkingTokens})`)\n } else {\n p.log.warn('settings.json not found in source, skipping')\n }\n } else if (category === 'skills') {\n const sourceDir = path.join(sourceAgentDir, 'skills')\n const targetCategoryDir = path.join(agentTargetDir, 'skills')\n\n if (!fs.existsSync(sourceDir)) {\n p.log.warn('skills directory not found in source, skipping')\n continue\n }\n\n // Get all skill folders\n const allSkills = fs\n .readdirSync(sourceDir, { withFileTypes: true })\n .filter(dirent => dirent.isDirectory())\n .map(dirent => dirent.name)\n\n // Determine which skills to copy\n let skillsToCopy = allSkills\n if (!options.all && filesToCopyByCategory['skills']) {\n skillsToCopy = filesToCopyByCategory['skills']\n }\n\n if (skillsToCopy.length === 0) {\n continue\n }\n\n // Create skills directory\n fs.mkdirSync(targetCategoryDir, { recursive: true })\n\n // Copy each selected skill folder recursively\n let skillFilesCopied = 0\n for (const skill of skillsToCopy) {\n const sourceSkillPath = path.join(sourceDir, skill)\n const targetSkillPath = path.join(targetCategoryDir, skill)\n\n skillFilesCopied += copyDirectoryRecursive(sourceSkillPath, targetSkillPath)\n }\n\n filesCopied += skillFilesCopied\n filesSkipped += allSkills.length - skillsToCopy.length // Count skipped skills (not files)\n p.log.success(`Copied ${skillsToCopy.length} skill(s) (${skillFilesCopied} files)`)\n }\n }\n\n // Update .gitignore to exclude settings.local.json\n if (selectedCategories.includes('settings')) {\n ensureGitignoreEntry(targetDir, product.gitignoreEntry, product.name)\n p.log.info('Updated .gitignore to exclude settings.local.json')\n }\n\n let message = `Successfully copied ${filesCopied} file(s) to ${agentTargetDir}`\n if (filesSkipped > 0) {\n message += chalk.gray(`\\n Skipped ${filesSkipped} file(s)`)\n }\n message += chalk.gray(`\\n You can now use these commands in ${product.name}.`)\n\n p.outro(message)\n } catch (error) {\n p.log.error(`Error during ${product.name} init: ${error}`)\n process.exit(1)\n }\n}\n","/**\n * Agent Product Registry\n *\n * Manages configuration for different coding agent products (claude-code, codebuddy-code, etc.)\n */\n\nexport interface AgentProduct {\n id: string // 'claude' | 'codebuddy'\n name: string // 'Claude Code' | 'CodeBuddy Code'\n dirName: string // '.claude' | '.codebuddy'\n sourceDirName: string // '.claude' | '.codebuddy'\n envVarPrefix: string // 'CLAUDE' | 'CODEBUDDY'\n defaultEnvVars: Record<string, string>\n gitignoreEntry: string // Relative path to settings.local.json\n}\n\nexport const AGENT_PRODUCTS: Record<string, AgentProduct> = {\n claude: {\n id: 'claude',\n name: 'Claude Code',\n dirName: '.claude',\n sourceDirName: 'src/agent-assets',\n envVarPrefix: 'CLAUDE',\n defaultEnvVars: {\n MAX_THINKING_TOKENS: '32000',\n CLAUDE_BASH_MAINTAIN_WORKING_DIR: '1',\n },\n gitignoreEntry: '.claude/settings.local.json',\n },\n codebuddy: {\n id: 'codebuddy',\n name: 'CodeBuddy Code',\n dirName: '.codebuddy',\n sourceDirName: 'src/agent-assets',\n envVarPrefix: 'CODEBUDDY',\n defaultEnvVars: {\n MAX_THINKING_TOKENS: '32000',\n // Note: Current not implemented in CodeBuddy\n CODEBUDDY_BASH_MAINTAIN_PROJECT_WORKING_DIR: '1',\n },\n gitignoreEntry: '.codebuddy/settings.local.json',\n },\n}\n\n/**\n * Get agent product configuration by ID\n * @throws Error if product ID is unknown\n */\nexport function getAgentProduct(id: string): AgentProduct {\n const product = AGENT_PRODUCTS[id]\n if (!product) {\n const validIds = Object.keys(AGENT_PRODUCTS).join(', ')\n throw new Error(`Unknown agent product: ${id}. Valid options: ${validIds}`)\n }\n return product\n}\n\n/**\n * Get all available agent products\n */\nexport function getAllAgentProducts(): AgentProduct[] {\n return Object.values(AGENT_PRODUCTS)\n}\n","import { Command } from 'commander'\nimport { agentInitCommand } from './agent/init.js'\nimport { getAgentProduct } from './agent/registry.js'\n\nexport function agentCommand(program: Command): void {\n const agent = program.command('agent').description('Manage coding agent configuration')\n\n agent\n .command('init')\n .description('Initialize coding agent configuration in current directory')\n .option('--force', 'Force overwrite of existing agent directory')\n .option('--all', 'Copy all files without prompting')\n .option('--max-thinking-tokens <number>', 'Maximum thinking tokens (default: 32000)', value =>\n parseInt(value, 10),\n )\n .option('--name <name>', 'Agent name to configure (claude|codebuddy)', 'claude')\n .action(async options => {\n const product = getAgentProduct(options.name)\n await agentInitCommand({ ...options, product })\n })\n}\n","import { execSync } from 'child_process'\n\ninterface GitInfo {\n repoRoot: string\n repoName: string\n branch: string\n commit: string\n}\n\nfunction getGitInfo(): GitInfo | null {\n try {\n // Check if git is available and we're in a git repo\n execSync('git rev-parse --is-inside-work-tree', {\n encoding: 'utf8',\n stdio: 'pipe',\n })\n\n const repoRoot = execSync('git rev-parse --show-toplevel', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n\n const repoName = repoRoot.split('/').pop() || ''\n\n // Get current branch - try --show-current first, fall back to --abbrev-ref HEAD\n let branch = ''\n try {\n branch = execSync('git branch --show-current', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n try {\n branch = execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n // No branch yet (fresh repo with no commits)\n branch = ''\n }\n }\n\n // Get commit hash - may fail if no commits yet\n let commit = ''\n try {\n commit = execSync('git rev-parse HEAD', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n // No commits yet\n commit = ''\n }\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"],"mappings":"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","names":["fs","path","execSync","chalk","path","fs","path","path","os","fs","path","fs","path","path","fs","path","fs","execSync","chalk","reposDir","fs","path","execSync","chalk","path","fs","chalk","execSync","fs","path","execSync","chalk","execSync","chalk","path","fs","fs","path","execSync","chalk","execSync","chalk","path","fs","chalk","chalk","chalk","p","chalk","chalk","chalk","chalk","chalk","chalk","p","chalk","program","fs","path","chalk","p","__filename","__dirname","program","execSync","program","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/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/profile/utils.ts","../src/commands/thoughts/destroy.ts","../src/commands/thoughts/sync.ts","../src/commands/thoughts/status.ts","../src/commands/thoughts/config.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/registry.ts","../src/commands/agent.ts","../src/commands/metadata/metadata.ts","../src/commands/metadata.ts","../src/commands/worktree.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander'\nimport { thoughtsCommand } from './commands/thoughts.js'\nimport { agentCommand } from './commands/agent.js'\nimport { metadataCommand } from './commands/metadata.js'\nimport { worktreeCommand } from './commands/worktree.js'\nimport dotenv from 'dotenv'\nimport { createRequire } from 'node:module'\n\n// Load environment variables\ndotenv.config()\n\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json') as { version: string }\n\nconst program = new Command()\n\nprogram\n .name('thoughtcabinet')\n .description(\n 'Thought Cabinet (thc) - thoughts management CLI for developer notes and documentation',\n )\n .version(version)\n\n// Add commands\nthoughtsCommand(program)\nagentCommand(program)\nmetadataCommand(program)\nworktreeCommand(program)\n\nprogram.parse(process.argv)\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} from './utils/index.js'\nimport { validateProfile, resolveProfileForRepo, getRepoNameFromMapping } from './profile/utils.js'\nimport {\n generateClaudeMd,\n generatePreCommitHook,\n generatePostCommitHook,\n HOOK_VERSION,\n} from '../../templates/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\nfunction setupGitHooks(repoPath: string): { updated: string[] } {\n const updated: string[] = []\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\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 const 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 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) {\n const selectOptions = [\n ...existingRepos.map(repo => ({ value: repo, label: `Use existing: ${repo}` })),\n { value: '__create_new__', label: 'Create new directory' },\n ]\n\n const selection = await p.select({\n message: 'Select or create a thoughts directory for this repository:',\n options: selectOptions,\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 p.log.success(\n `Will use existing: ${tempProfileConfig.thoughtsRepo}/${tempProfileConfig.reposDir}/${mappedName}`,\n )\n }\n } else {\n // No existing repos, 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\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 // Handle searchable directories specially if they exist (might have read-only permissions)\n const searchableDir = path.join(thoughtsDir, 'searchable')\n if (fs.existsSync(searchableDir)) {\n try {\n // Reset permissions so we can delete it\n execSync(`chmod -R 755 \"${searchableDir}\"`, { stdio: 'pipe' })\n } catch {\n // Ignore chmod errors\n }\n }\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 try {\n execSync('git remote get-url origin', { cwd: expandedRepo, stdio: 'pipe' })\n // Remote exists, try to pull\n try {\n execSync('git pull --rebase', {\n stdio: 'pipe',\n cwd: expandedRepo,\n })\n p.log.success('Pulled latest thoughts from remote')\n } catch (error) {\n p.log.warn(`Could not pull latest thoughts: ${(error as Error).message}`)\n }\n } catch {\n // No remote configured, skip pull\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 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 }\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 getDefaultConfigPath(): string {\n const xdgConfigHome = process.env.XDG_CONFIG_HOME || path.join(process.env.HOME || '', '.config')\n return path.join(xdgConfigHome, 'thought-cabinet', 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}\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'\n\nexport function getDefaultThoughtsRepo(): string {\n return path.join(os.homedir(), '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","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 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","import fs from 'fs'\nimport path from 'path'\nimport { execSync } from 'child_process'\nimport chalk from 'chalk'\nimport { loadThoughtsConfig, saveThoughtsConfig, getCurrentRepoPath } from './utils/index.js'\nimport { getRepoNameFromMapping, getProfileNameFromMapping } from './profile/utils.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 const mapping = config.repoMappings[currentRepo]\n const mappedName = getRepoNameFromMapping(mapping)\n const profileName = getProfileNameFromMapping(mapping)\n\n if (!mappedName && !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 // Step 1: Handle searchable directory if it exists\n const searchableDir = path.join(thoughtsDir, 'searchable')\n if (fs.existsSync(searchableDir)) {\n console.log(chalk.gray('Removing searchable directory...'))\n try {\n // Reset permissions in case they're restricted\n execSync(`chmod -R 755 \"${searchableDir}\"`, { stdio: 'pipe' })\n } catch {\n // Ignore chmod errors\n }\n fs.rmSync(searchableDir, { recursive: true, force: true })\n }\n\n // Step 2: Remove the entire thoughts directory\n // IMPORTANT: This only removes the local thoughts/ directory containing symlinks\n // The actual thoughts content in the thoughts repository remains untouched\n console.log(chalk.gray('Removing thoughts directory (symlinks only)...'))\n try {\n fs.rmSync(thoughtsDir, { recursive: true, force: true })\n } catch (error) {\n console.error(chalk.red(`Error removing thoughts directory: ${error}`))\n console.error(chalk.yellow('You may need to manually remove: ' + thoughtsDir))\n process.exit(1)\n }\n\n // Step 3: Remove from config if mapped\n if (mappedName) {\n console.log(chalk.gray('Removing repository from thoughts configuration...'))\n delete config.repoMappings[currentRepo]\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 (mappedName) {\n console.log('')\n console.log(chalk.gray('Note: Your thoughts content remains safe in:'))\n\n if (profileName && config.profiles && config.profiles[profileName]) {\n const profile = config.profiles[profileName]\n console.log(chalk.gray(` ${profile.thoughtsRepo}/${profile.reposDir}/${mappedName}`))\n console.log(chalk.gray(` (profile: ${profileName})`))\n } else {\n console.log(chalk.gray(` ${config.thoughtsRepo}/${config.reposDir}/${mappedName}`))\n }\n\n console.log(chalk.gray('Only the local symlinks and configuration were removed.'))\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 updateSymlinksForNewUsers,\n} from './utils/index.js'\nimport { resolveProfileForRepo, getRepoNameFromMapping } from './profile/utils.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): 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 commitMessage = message || `Sync thoughts - ${new Date().toISOString()}`\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 } 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\nfunction createSearchDirectory(thoughtsDir: string): void {\n const searchDir = path.join(thoughtsDir, 'searchable')\n // Remove existing searchable directory if it exists\n if (fs.existsSync(searchDir)) {\n try {\n // Reset permissions so we can delete it\n execSync(`chmod -R 755 \"${searchDir}\"`, { stdio: 'pipe' })\n } catch {\n // Ignore chmod errors\n }\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 console.log(chalk.gray(`Created ${linkedCount} hard links in searchable directory`))\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 createSearchDirectory(thoughtsDir)\n\n // Sync the thoughts repository using profile's thoughtsRepo\n console.log(chalk.blue('Syncing thoughts...'))\n syncThoughts(profileConfig.thoughtsRepo, options.message || '')\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\nfunction getRemoteStatus(repoPath: string): string {\n try {\n execSync('git remote get-url origin', { cwd: repoPath, stdio: 'pipe' })\n\n // Fetch to update remote refs\n try {\n execSync('git fetch', { cwd: repoPath, stdio: 'pipe' })\n } catch {\n // Fetch might fail, continue anyway\n }\n\n // Check if we're ahead/behind\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\n // Try to automatically pull if we're behind\n try {\n execSync('git pull --rebase', {\n stdio: 'pipe',\n cwd: repoPath,\n })\n console.log(chalk.green('✓ Automatically pulled latest changes'))\n\n // Re-check status after pull\n const newStatus = execSync('git status -sb', {\n encoding: 'utf8',\n cwd: repoPath,\n stdio: 'pipe',\n })\n\n if (newStatus.includes('behind')) {\n const newBehind = newStatus.match(/behind (\\d+)/)?.[1] || '?'\n return chalk.yellow(`${newBehind} commits behind remote (after pull)`)\n } else {\n return chalk.green('Up to date with remote (after pull)')\n }\n } catch {\n // Silent fail - status is read-only operation\n return chalk.yellow(`${behind} commits behind remote`)\n }\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}\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 console.log(` Remote: ${getRemoteStatus(expandedRepo)}`)\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 chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport {\n loadThoughtsConfig,\n saveThoughtsConfig,\n getDefaultThoughtsRepo,\n ensureThoughtsRepoExists,\n} from '../utils/index.js'\nimport { sanitizeProfileName, validateProfile } from './utils.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 = getDefaultThoughtsRepo() + `-${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 { 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 .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 // 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 fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport * as p from '@clack/prompts'\nimport { fileURLToPath } from 'url'\nimport { dirname } from 'path'\nimport { AgentProduct } from './registry.js'\n\n// Get the directory of this module\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport interface AgentInitOptions {\n product: AgentProduct\n force?: boolean\n all?: boolean\n maxThinkingTokens?: number\n}\n\nfunction ensureGitignoreEntry(targetDir: string, entry: string, productName: string): void {\n const gitignorePath = path.join(targetDir, '.gitignore')\n\n // Read existing .gitignore or create empty\n let gitignoreContent = ''\n if (fs.existsSync(gitignorePath)) {\n gitignoreContent = fs.readFileSync(gitignorePath, 'utf8')\n }\n\n // Check if entry already exists\n const lines = gitignoreContent.split('\\n')\n if (lines.some(line => line.trim() === entry)) {\n return // Already exists\n }\n\n // Add entry with section comment\n const newContent =\n gitignoreContent +\n (gitignoreContent && !gitignoreContent.endsWith('\\n') ? '\\n' : '') +\n '\\n# ' +\n productName +\n ' local settings\\n' +\n entry +\n '\\n'\n\n fs.writeFileSync(gitignorePath, newContent)\n}\n\n/**\n * Recursively copy a directory\n * @returns Number of files copied\n */\nfunction copyDirectoryRecursive(sourceDir: string, targetDir: string): number {\n let filesCopied = 0\n\n // Create target directory\n fs.mkdirSync(targetDir, { recursive: true })\n\n const entries = fs.readdirSync(sourceDir, { withFileTypes: true })\n\n for (const entry of entries) {\n const sourcePath = path.join(sourceDir, entry.name)\n const targetPath = path.join(targetDir, entry.name)\n\n if (entry.isDirectory()) {\n // Recursively copy subdirectory\n filesCopied += copyDirectoryRecursive(sourcePath, targetPath)\n } else {\n // Copy file\n fs.copyFileSync(sourcePath, targetPath)\n filesCopied++\n }\n }\n\n return filesCopied\n}\n\nexport async function agentInitCommand(options: AgentInitOptions): Promise<void> {\n const { product } = options\n\n try {\n p.intro(chalk.blue(`Initialize ${product.name} Configuration`))\n\n // Check if running in interactive terminal\n if (!process.stdin.isTTY && !options.all) {\n p.log.error('Not running in interactive terminal.')\n p.log.info('Use --all flag to copy all files without prompting.')\n process.exit(1)\n }\n\n const targetDir = process.cwd()\n const agentTargetDir = path.join(targetDir, product.dirName)\n\n // Determine source location\n // Try multiple possible locations for the agent directory\n const possiblePaths = [\n // When installed via npm: package root is one level up from dist\n path.resolve(__dirname, '..', product.sourceDirName),\n // When running from repo: repo root is two levels up from dist\n path.resolve(__dirname, '../..', product.sourceDirName),\n ]\n\n let sourceAgentDir: string | null = null\n for (const candidatePath of possiblePaths) {\n if (fs.existsSync(candidatePath)) {\n sourceAgentDir = candidatePath\n break\n }\n }\n\n // Verify source directory exists\n if (!sourceAgentDir) {\n p.log.error(`Source ${product.dirName} directory not found in expected locations`)\n p.log.info('Searched paths:')\n possiblePaths.forEach(candidatePath => {\n p.log.info(` - ${candidatePath}`)\n })\n p.log.info('Are you running from the thoughtcabinet repository or npm package?')\n process.exit(1)\n }\n\n // Check if agent directory already exists\n if (fs.existsSync(agentTargetDir) && !options.force) {\n const overwrite = await p.confirm({\n message: `${product.dirName} directory already exists. 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 let selectedCategories: string[]\n\n if (options.all) {\n selectedCategories = ['commands', 'agents', 'skills', 'settings']\n } else {\n // Interactive selection\n // Calculate actual file counts\n let commandsCount = 0\n let agentsCount = 0\n\n const commandsDir = path.join(sourceAgentDir, 'commands')\n const agentsDir = path.join(sourceAgentDir, 'agents')\n\n if (fs.existsSync(commandsDir)) {\n commandsCount = fs.readdirSync(commandsDir).length\n }\n\n if (fs.existsSync(agentsDir)) {\n agentsCount = fs.readdirSync(agentsDir).length\n }\n\n let skillsCount = 0\n const skillsDir = path.join(sourceAgentDir, 'skills')\n\n if (fs.existsSync(skillsDir)) {\n // Count skill folders (not files)\n skillsCount = fs\n .readdirSync(skillsDir, { withFileTypes: true })\n .filter(dirent => dirent.isDirectory()).length\n }\n\n p.note(\n 'Use ↑/↓ to move, press Space to select/deselect, press A to select/deselect all, press Enter to confirm. (Subsequent multi-selects apply; Ctrl+C to exit)',\n 'Multi-select instructions',\n )\n const selection = await p.multiselect({\n message: 'What would you like to copy?',\n options: [\n {\n value: 'commands',\n label: 'Commands',\n hint: `${commandsCount} workflow commands (planning, CI, research, etc.)`,\n },\n {\n value: 'agents',\n label: 'Agents',\n hint: `${agentsCount} specialized sub-agents for code analysis`,\n },\n {\n value: 'skills',\n label: 'Skills',\n hint: `${skillsCount} specialized skill packages for extended capabilities`,\n },\n {\n value: 'settings',\n label: 'Settings',\n hint: 'Project permissions configuration',\n },\n ],\n initialValues: ['commands', 'agents', 'skills', 'settings'],\n required: false,\n })\n\n if (p.isCancel(selection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n selectedCategories = selection as string[]\n\n if (selectedCategories.length === 0) {\n p.cancel('No items selected.')\n process.exit(0)\n }\n }\n\n // Create agent directory\n fs.mkdirSync(agentTargetDir, { recursive: true })\n\n let filesCopied = 0\n let filesSkipped = 0\n\n // Wizard-style file selection for each category\n const filesToCopyByCategory: Record<string, string[]> = {}\n\n // If in interactive mode, prompt for file selection per category\n if (!options.all) {\n // Commands file selection (if selected)\n if (selectedCategories.includes('commands')) {\n const sourceDir = path.join(sourceAgentDir, 'commands')\n if (fs.existsSync(sourceDir)) {\n const allFiles = fs.readdirSync(sourceDir)\n const fileSelection = await p.multiselect({\n message: 'Select command files to copy:',\n options: allFiles.map(file => ({\n value: file,\n label: file,\n })),\n initialValues: allFiles,\n required: false,\n })\n\n if (p.isCancel(fileSelection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n filesToCopyByCategory['commands'] = fileSelection as string[]\n\n if (filesToCopyByCategory['commands'].length === 0) {\n filesSkipped += allFiles.length\n }\n }\n }\n\n // Agents file selection (if selected)\n if (selectedCategories.includes('agents')) {\n const sourceDir = path.join(sourceAgentDir, 'agents')\n if (fs.existsSync(sourceDir)) {\n const allFiles = fs.readdirSync(sourceDir)\n const fileSelection = await p.multiselect({\n message: 'Select agent files to copy:',\n options: allFiles.map(file => ({\n value: file,\n label: file,\n })),\n initialValues: allFiles,\n required: false,\n })\n\n if (p.isCancel(fileSelection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n filesToCopyByCategory['agents'] = fileSelection as string[]\n\n if (filesToCopyByCategory['agents'].length === 0) {\n filesSkipped += allFiles.length\n }\n }\n }\n\n // Skills folder selection (if selected)\n if (selectedCategories.includes('skills')) {\n const sourceDir = path.join(sourceAgentDir, 'skills')\n if (fs.existsSync(sourceDir)) {\n // Get skill folders (directories only)\n const allSkills = fs\n .readdirSync(sourceDir, { withFileTypes: true })\n .filter(dirent => dirent.isDirectory())\n .map(dirent => dirent.name)\n\n if (allSkills.length > 0) {\n const skillSelection = await p.multiselect({\n message: 'Select skills to copy:',\n options: allSkills.map(skill => ({\n value: skill,\n label: skill,\n })),\n initialValues: allSkills,\n required: false,\n })\n\n if (p.isCancel(skillSelection)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n filesToCopyByCategory['skills'] = skillSelection as string[]\n }\n }\n }\n }\n\n // Configure settings\n let maxThinkingTokens = options.maxThinkingTokens\n\n // Prompt for settings if in interactive mode and not provided via flags\n if (!options.all && selectedCategories.includes('settings')) {\n if (maxThinkingTokens === undefined) {\n const tokensPrompt = await p.text({\n message: 'Maximum thinking tokens:',\n initialValue: '32000',\n validate: value => {\n const num = parseInt(value, 10)\n if (isNaN(num) || num < 1000) {\n return 'Please enter a valid number (minimum 1000)'\n }\n return undefined\n },\n })\n\n if (p.isCancel(tokensPrompt)) {\n p.cancel('Operation cancelled.')\n process.exit(0)\n }\n\n maxThinkingTokens = parseInt(tokensPrompt as string, 10)\n }\n } else if (selectedCategories.includes('settings')) {\n // Non-interactive mode: use defaults if not provided\n if (maxThinkingTokens === undefined) {\n maxThinkingTokens = 32000\n }\n }\n\n // Copy selected categories\n for (const category of selectedCategories) {\n if (category === 'commands' || category === 'agents') {\n const sourceDir = path.join(sourceAgentDir, category)\n const targetCategoryDir = path.join(agentTargetDir, category)\n\n if (!fs.existsSync(sourceDir)) {\n p.log.warn(`${category} directory not found in source, skipping`)\n continue\n }\n\n // Get all files in category\n const allFiles = fs.readdirSync(sourceDir)\n\n // Determine which files to copy\n let filesToCopy = allFiles\n if (!options.all && filesToCopyByCategory[category]) {\n filesToCopy = filesToCopyByCategory[category]\n }\n\n if (filesToCopy.length === 0) {\n continue\n }\n\n // Copy files\n fs.mkdirSync(targetCategoryDir, { recursive: true })\n\n for (const file of filesToCopy) {\n const sourcePath = path.join(sourceDir, file)\n const targetPath = path.join(targetCategoryDir, file)\n\n fs.copyFileSync(sourcePath, targetPath)\n filesCopied++\n }\n\n filesSkipped += allFiles.length - filesToCopy.length\n p.log.success(`Copied ${filesToCopy.length} ${category} file(s)`)\n } else if (category === 'settings') {\n const settingsPath = path.join(sourceAgentDir, 'settings.template.json')\n const targetSettingsPath = path.join(agentTargetDir, 'settings.json')\n\n if (fs.existsSync(settingsPath)) {\n // Read source settings\n const settingsContent = fs.readFileSync(settingsPath, 'utf8')\n const settings = JSON.parse(settingsContent)\n\n // Merge user's configuration into settings\n if (maxThinkingTokens !== undefined) {\n if (!settings.env) {\n settings.env = {}\n }\n settings.env.MAX_THINKING_TOKENS = maxThinkingTokens.toString()\n }\n\n // Set product-specific environment variables\n if (!settings.env) {\n settings.env = {}\n }\n for (const [key, value] of Object.entries(product.defaultEnvVars)) {\n settings.env[key] = value\n }\n\n // Write modified settings\n fs.writeFileSync(targetSettingsPath, JSON.stringify(settings, null, 2) + '\\n')\n filesCopied++\n p.log.success(`Copied settings.json (maxTokens: ${maxThinkingTokens})`)\n } else {\n p.log.warn('settings.json not found in source, skipping')\n }\n } else if (category === 'skills') {\n const sourceDir = path.join(sourceAgentDir, 'skills')\n const targetCategoryDir = path.join(agentTargetDir, 'skills')\n\n if (!fs.existsSync(sourceDir)) {\n p.log.warn('skills directory not found in source, skipping')\n continue\n }\n\n // Get all skill folders\n const allSkills = fs\n .readdirSync(sourceDir, { withFileTypes: true })\n .filter(dirent => dirent.isDirectory())\n .map(dirent => dirent.name)\n\n // Determine which skills to copy\n let skillsToCopy = allSkills\n if (!options.all && filesToCopyByCategory['skills']) {\n skillsToCopy = filesToCopyByCategory['skills']\n }\n\n if (skillsToCopy.length === 0) {\n continue\n }\n\n // Create skills directory\n fs.mkdirSync(targetCategoryDir, { recursive: true })\n\n // Copy each selected skill folder recursively\n let skillFilesCopied = 0\n for (const skill of skillsToCopy) {\n const sourceSkillPath = path.join(sourceDir, skill)\n const targetSkillPath = path.join(targetCategoryDir, skill)\n\n skillFilesCopied += copyDirectoryRecursive(sourceSkillPath, targetSkillPath)\n }\n\n filesCopied += skillFilesCopied\n filesSkipped += allSkills.length - skillsToCopy.length // Count skipped skills (not files)\n p.log.success(`Copied ${skillsToCopy.length} skill(s) (${skillFilesCopied} files)`)\n }\n }\n\n // Update .gitignore to exclude settings.local.json\n if (selectedCategories.includes('settings')) {\n ensureGitignoreEntry(targetDir, product.gitignoreEntry, product.name)\n p.log.info('Updated .gitignore to exclude settings.local.json')\n }\n\n let message = `Successfully copied ${filesCopied} file(s) to ${agentTargetDir}`\n if (filesSkipped > 0) {\n message += chalk.gray(`\\n Skipped ${filesSkipped} file(s)`)\n }\n message += chalk.gray(`\\n You can now use these commands in ${product.name}.`)\n\n p.outro(message)\n } catch (error) {\n p.log.error(`Error during ${product.name} init: ${error}`)\n process.exit(1)\n }\n}\n","/**\n * Agent Product Registry\n *\n * Manages configuration for different coding agent products (claude-code, codebuddy-code, etc.)\n */\n\nexport interface AgentProduct {\n id: string // 'claude' | 'codebuddy'\n name: string // 'Claude Code' | 'CodeBuddy Code'\n dirName: string // '.claude' | '.codebuddy'\n sourceDirName: string // '.claude' | '.codebuddy'\n envVarPrefix: string // 'CLAUDE' | 'CODEBUDDY'\n defaultEnvVars: Record<string, string>\n gitignoreEntry: string // Relative path to settings.local.json\n}\n\nexport const AGENT_PRODUCTS: Record<string, AgentProduct> = {\n claude: {\n id: 'claude',\n name: 'Claude Code',\n dirName: '.claude',\n sourceDirName: 'src/agent-assets',\n envVarPrefix: 'CLAUDE',\n defaultEnvVars: {\n MAX_THINKING_TOKENS: '32000',\n CLAUDE_BASH_MAINTAIN_WORKING_DIR: '1',\n },\n gitignoreEntry: '.claude/settings.local.json',\n },\n codebuddy: {\n id: 'codebuddy',\n name: 'CodeBuddy Code',\n dirName: '.codebuddy',\n sourceDirName: 'src/agent-assets',\n envVarPrefix: 'CODEBUDDY',\n defaultEnvVars: {\n MAX_THINKING_TOKENS: '32000',\n // Note: Current not implemented in CodeBuddy\n CODEBUDDY_BASH_MAINTAIN_PROJECT_WORKING_DIR: '1',\n },\n gitignoreEntry: '.codebuddy/settings.local.json',\n },\n}\n\n/**\n * Get agent product configuration by ID\n * @throws Error if product ID is unknown\n */\nexport function getAgentProduct(id: string): AgentProduct {\n const product = AGENT_PRODUCTS[id]\n if (!product) {\n const validIds = Object.keys(AGENT_PRODUCTS).join(', ')\n throw new Error(`Unknown agent product: ${id}. Valid options: ${validIds}`)\n }\n return product\n}\n\n/**\n * Get all available agent products\n */\nexport function getAllAgentProducts(): AgentProduct[] {\n return Object.values(AGENT_PRODUCTS)\n}\n","import { Command } from 'commander'\nimport { agentInitCommand } from './agent/init.js'\nimport { getAgentProduct } from './agent/registry.js'\n\nexport function agentCommand(program: Command): void {\n const agent = program.command('agent').description('Manage coding agent configuration')\n\n agent\n .command('init')\n .description('Initialize coding agent configuration in current directory')\n .option('--force', 'Force overwrite of existing agent directory')\n .option('--all', 'Copy all files without prompting')\n .option('--max-thinking-tokens <number>', 'Maximum thinking tokens (default: 32000)', value =>\n parseInt(value, 10),\n )\n .option('--name <name>', 'Agent name to configure (claude|codebuddy)', 'claude')\n .action(async options => {\n const product = getAgentProduct(options.name)\n await agentInitCommand({ ...options, product })\n })\n}\n","import { execSync } from 'child_process'\n\ninterface GitInfo {\n repoRoot: string\n repoName: string\n branch: string\n commit: string\n}\n\nfunction getGitInfo(): GitInfo | null {\n try {\n // Check if git is available and we're in a git repo\n execSync('git rev-parse --is-inside-work-tree', {\n encoding: 'utf8',\n stdio: 'pipe',\n })\n\n const repoRoot = execSync('git rev-parse --show-toplevel', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n\n const repoName = repoRoot.split('/').pop() || ''\n\n // Get current branch - try --show-current first, fall back to --abbrev-ref HEAD\n let branch = ''\n try {\n branch = execSync('git branch --show-current', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n try {\n branch = execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n // No branch yet (fresh repo with no commits)\n branch = ''\n }\n }\n\n // Get commit hash - may fail if no commits yet\n let commit = ''\n try {\n commit = execSync('git rev-parse HEAD', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim()\n } catch {\n // No commits yet\n commit = ''\n }\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 { Command } from 'commander'\nimport { execFileSync } from 'child_process'\nimport fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\n\ninterface WorktreeEntry {\n worktreePath: string\n branch: string\n detached: boolean\n}\n\ninterface GitRunOptions {\n cwd?: string\n}\n\ninterface WorktreeAddOptions {\n branch?: string\n base: string\n path?: string\n detached?: boolean\n}\n\ninterface WorktreeListOptions {\n all?: boolean\n}\n\ninterface WorktreeMergeOptions {\n into?: string\n force?: boolean\n keepSession?: boolean\n keepWorktree?: boolean\n keepBranch?: boolean\n}\n\nfunction run(cmd: string, args: string[], opts: GitRunOptions = {}): string {\n return execFileSync(cmd, args, {\n cwd: opts.cwd,\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'pipe'],\n }).trim()\n}\n\nfunction runOrThrow(cmd: string, args: string[], opts: GitRunOptions = {}): void {\n execFileSync(cmd, args, {\n cwd: opts.cwd,\n stdio: 'inherit',\n })\n}\n\nfunction validateWorktreeHandle(name: string): void {\n // Keep the handle portable across OSes and safe for default paths.\n // Allow: letters, numbers, dot, underscore, dash. Must start with alnum.\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\nfunction isGitRepo(cwd?: string): boolean {\n try {\n run('git', ['rev-parse', '--git-dir'], { cwd })\n return true\n } catch {\n return false\n }\n}\n\nfunction 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\nfunction getMainWorktreeRoot(cwd?: string): string {\n const list = run('git', ['worktree', 'list', '--porcelain'], { cwd })\n const entries = parseWorktreeListPorcelain(list)\n if (entries.length === 0) {\n throw new Error('No git worktrees found')\n }\n // First entry is the main worktree.\n return entries[0].worktreePath\n}\n\nfunction 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\nfunction findWorktree(nameOrBranch: string, cwd?: string): WorktreeEntry {\n const list = run('git', ['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\nfunction hasUncommittedChanges(repoPath: string): boolean {\n const status = run('git', ['status', '--porcelain'], { cwd: repoPath })\n return status.trim().length > 0\n}\n\nfunction setBranchBase(branch: string, base: string, cwd?: string): void {\n runOrThrow('git', ['config', '--local', `branch.${branch}.thc-base`, base], { cwd })\n}\n\nfunction listTmuxSessions(): string[] {\n try {\n const out = run('tmux', ['list-sessions', '-F', '#{session_name}'])\n return out\n .split('\\n')\n .map(s => s.trim())\n .filter(Boolean)\n } catch {\n return []\n }\n}\n\nfunction 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\nfunction tmuxNewSession(sessionName: string, cwd: string): void {\n runOrThrow('tmux', ['new-session', '-d', '-s', sessionName, '-c', cwd])\n}\n\nfunction tmuxKillSession(sessionName: string): void {\n try {\n execFileSync('tmux', ['kill-session', '-t', sessionName], { stdio: 'ignore' })\n } catch {\n // ignore\n }\n}\n\nfunction 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\nfunction legacySessionNameForHandle(handle: string): string {\n return `thc:${handle}`\n}\n\nfunction allSessionNamesForHandle(handle: string): string[] {\n return [sessionNameForHandle(handle), legacySessionNameForHandle(handle)]\n}\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 .action(async (name: string, options: WorktreeAddOptions) => {\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\n fs.mkdirSync(path.dirname(worktreePath), { recursive: true })\n\n const sessionName = sessionNameForHandle(name)\n const sessionCandidates = allSessionNamesForHandle(name)\n const existing = sessionCandidates.find(s => tmuxHasSession(s))\n if (existing) {\n console.error(chalk.red(`Error: tmux session already exists: ${existing}`))\n process.exit(1)\n }\n\n if (options.detached) {\n runOrThrow('git', ['worktree', 'add', '--detach', worktreePath, options.base], {\n cwd: mainRoot,\n })\n } else {\n const branch = (options.branch as string | undefined) ?? name\n runOrThrow('git', ['worktree', 'add', '-b', branch, worktreePath, options.base], {\n cwd: mainRoot,\n })\n setBranchBase(branch, options.base, worktreePath)\n }\n\n tmuxNewSession(sessionName, worktreePath)\n\n console.log(chalk.green('✓ Worktree created'))\n console.log(chalk.gray(`Path: ${worktreePath}`))\n console.log(chalk.gray(`Tmux session: ${sessionName}`))\n console.log(chalk.gray(`Attach: tmux attach -t ${sessionName}`))\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n })\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(async (options: WorktreeListOptions) => {\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 = getWorktreesBaseDir(mainRoot)\n const baseDirResolved = path.resolve(baseDir)\n\n const entries = parseWorktreeListPorcelain(\n run('git', ['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(baseDirResolved + path.sep)\n })\n\n if (filtered.length === 0) {\n console.log(chalk.gray('No worktrees found.'))\n return\n }\n\n console.log('NAME\\tBRANCH\\tTMUX\\tPATH')\n for (const e of filtered) {\n const name = path.basename(e.worktreePath)\n const sessionName = allSessionNamesForHandle(name).find(s => sessions.has(s))\n console.log(`${name}\\t${e.branch}\\t${sessionName ?? '-'}\\t${e.worktreePath}`)\n }\n } catch (error) {\n console.error(chalk.red(`Error: ${(error as Error).message}`))\n process.exit(1)\n }\n })\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(async (name: string, options: WorktreeMergeOptions) => {\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 mainRootResolved = path.resolve(mainRoot)\n\n const wtEntry = findWorktree(name, mainRoot)\n const wtResolved = path.resolve(wtEntry.worktreePath)\n\n if (wtResolved === mainRootResolved) {\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 as string | undefined) ??\n run('git', ['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 if (!options.force && hasUncommittedChanges(wtEntry.worktreePath)) {\n console.error(\n chalk.red(\n 'Error: worktree has uncommitted changes. Commit/stash first or use --force.',\n ),\n )\n process.exit(1)\n }\n\n console.log(chalk.blue(`Rebasing ${wtEntry.branch} onto ${targetBranch}...`))\n runOrThrow('git', ['rebase', targetBranch], { cwd: wtEntry.worktreePath })\n\n console.log(chalk.blue(`Fast-forward merging into ${targetBranch}...`))\n runOrThrow('git', ['switch', targetBranch], { cwd: mainRoot })\n runOrThrow('git', ['merge', '--ff-only', wtEntry.branch], { cwd: mainRoot })\n\n const handle = path.basename(wtEntry.worktreePath)\n const sessionNames = allSessionNamesForHandle(handle)\n\n if (!options.keepSession) {\n for (const s of sessionNames) {\n tmuxKillSession(s)\n }\n }\n\n if (!options.keepWorktree) {\n const removeArgs = ['worktree', 'remove']\n if (options.force) {\n removeArgs.push('--force')\n }\n removeArgs.push(wtEntry.worktreePath)\n\n runOrThrow('git', removeArgs, { cwd: mainRoot })\n\n // Best-effort prune\n try {\n runOrThrow('git', ['worktree', 'prune'], { cwd: mainRoot })\n } catch {\n // ignore\n }\n }\n\n if (!options.keepBranch) {\n // Best-effort delete; should succeed after ff merge.\n try {\n runOrThrow('git', ['branch', '-d', wtEntry.branch], { cwd: mainRoot })\n } catch {\n if (options.force) {\n runOrThrow('git', ['branch', '-D', wtEntry.branch], { cwd: mainRoot })\n } else {\n throw new Error(\n `Failed to delete branch '${wtEntry.branch}'. Re-run with --force to delete it.`,\n )\n }\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}\n\nexport const __test__ = {\n parseWorktreeListPorcelain,\n getWorktreesBaseDir,\n sessionNameForHandle,\n}\n"],"mappings":"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","names":["fs","path","execSync","chalk","path","fs","path","path","os","fs","path","isGitRepo","fs","path","path","fs","path","fs","execSync","chalk","reposDir","fs","path","execSync","chalk","path","fs","chalk","execSync","fs","path","execSync","chalk","execSync","chalk","path","fs","fs","path","execSync","chalk","execSync","chalk","path","fs","chalk","chalk","chalk","p","chalk","chalk","chalk","chalk","chalk","chalk","p","chalk","program","fs","path","chalk","p","__filename","__dirname","program","execSync","program","execFileSync","fs","path","chalk","program","p","dotenv","require"]}
|