thought-cabinet 0.1.12 → 0.1.13
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 +28 -135
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- /package/src/agent-assets/agents/{code-simplifier.md → code-simplifier/code-simplifier.md} +0 -0
- /package/src/agent-assets/agents/{codebase-analyzer.md → codebase-analyzer/codebase-analyzer.md} +0 -0
- /package/src/agent-assets/agents/{codebase-locator.md → codebase-locator/codebase-locator.md} +0 -0
- /package/src/agent-assets/agents/{codebase-pattern-finder.md → codebase-pattern-finder/codebase-pattern-finder.md} +0 -0
- /package/src/agent-assets/agents/{thoughts-analyzer.md → thoughts-analyzer/thoughts-analyzer.md} +0 -0
- /package/src/agent-assets/agents/{thoughts-locator.md → thoughts-locator/thoughts-locator.md} +0 -0
- /package/src/agent-assets/agents/{web-search-researcher.md → web-search-researcher/web-search-researcher.md} +0 -0
package/dist/index.js
CHANGED
|
@@ -2260,7 +2260,6 @@ import { join } from "path";
|
|
|
2260
2260
|
import { existsSync } from "fs";
|
|
2261
2261
|
var home = homedir();
|
|
2262
2262
|
var claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || join(home, ".claude");
|
|
2263
|
-
var codexHome = process.env.CODEX_HOME?.trim() || join(home, ".codex");
|
|
2264
2263
|
var agents = {
|
|
2265
2264
|
"claude-code": {
|
|
2266
2265
|
name: "claude-code",
|
|
@@ -2275,34 +2274,6 @@ var agents = {
|
|
|
2275
2274
|
configDir: ".codebuddy",
|
|
2276
2275
|
globalConfigDir: join(home, ".codebuddy"),
|
|
2277
2276
|
detectInstalled: async () => existsSync(join(process.cwd(), ".codebuddy")) || existsSync(join(home, ".codebuddy"))
|
|
2278
|
-
},
|
|
2279
|
-
cursor: {
|
|
2280
|
-
name: "cursor",
|
|
2281
|
-
displayName: "Cursor",
|
|
2282
|
-
configDir: ".cursor",
|
|
2283
|
-
globalConfigDir: join(home, ".cursor"),
|
|
2284
|
-
detectInstalled: async () => existsSync(join(home, ".cursor"))
|
|
2285
|
-
},
|
|
2286
|
-
codex: {
|
|
2287
|
-
name: "codex",
|
|
2288
|
-
displayName: "Codex",
|
|
2289
|
-
configDir: ".codex",
|
|
2290
|
-
globalConfigDir: codexHome,
|
|
2291
|
-
detectInstalled: async () => existsSync(codexHome)
|
|
2292
|
-
},
|
|
2293
|
-
"gemini-cli": {
|
|
2294
|
-
name: "gemini-cli",
|
|
2295
|
-
displayName: "Gemini CLI",
|
|
2296
|
-
configDir: ".gemini",
|
|
2297
|
-
globalConfigDir: join(home, ".gemini"),
|
|
2298
|
-
detectInstalled: async () => existsSync(join(home, ".gemini"))
|
|
2299
|
-
},
|
|
2300
|
-
cline: {
|
|
2301
|
-
name: "cline",
|
|
2302
|
-
displayName: "Cline",
|
|
2303
|
-
configDir: ".cline",
|
|
2304
|
-
globalConfigDir: join(home, ".cline"),
|
|
2305
|
-
detectInstalled: async () => existsSync(join(home, ".cline"))
|
|
2306
2277
|
}
|
|
2307
2278
|
};
|
|
2308
2279
|
function getAllAgents() {
|
|
@@ -2323,7 +2294,7 @@ function isValidAgentType(value) {
|
|
|
2323
2294
|
|
|
2324
2295
|
// src/commands/agent/discovery.ts
|
|
2325
2296
|
import { readdir, readFile } from "fs/promises";
|
|
2326
|
-
import { join as join2
|
|
2297
|
+
import { join as join2 } from "path";
|
|
2327
2298
|
function parseSkillFrontmatter(content) {
|
|
2328
2299
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
2329
2300
|
if (!match) return null;
|
|
@@ -2368,13 +2339,12 @@ async function discoverMarkdownAssets(basePath, category) {
|
|
|
2368
2339
|
try {
|
|
2369
2340
|
const entries = await readdir(basePath, { withFileTypes: true });
|
|
2370
2341
|
for (const entry of entries) {
|
|
2371
|
-
if (entry.isDirectory()) continue;
|
|
2372
|
-
|
|
2373
|
-
const
|
|
2374
|
-
const name = basename(entry.name, ".md");
|
|
2342
|
+
if (!entry.isDirectory()) continue;
|
|
2343
|
+
const dirPath = join2(basePath, entry.name);
|
|
2344
|
+
const mdFile = join2(dirPath, `${entry.name}.md`);
|
|
2375
2345
|
let description = "";
|
|
2376
2346
|
try {
|
|
2377
|
-
const content = await readFile(
|
|
2347
|
+
const content = await readFile(mdFile, "utf-8");
|
|
2378
2348
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
2379
2349
|
if (match) {
|
|
2380
2350
|
const descMatch = match[1].match(/description:\s*(.+)/);
|
|
@@ -2383,13 +2353,14 @@ async function discoverMarkdownAssets(basePath, category) {
|
|
|
2383
2353
|
}
|
|
2384
2354
|
}
|
|
2385
2355
|
} catch {
|
|
2356
|
+
continue;
|
|
2386
2357
|
}
|
|
2387
2358
|
assets.push({
|
|
2388
|
-
name,
|
|
2359
|
+
name: entry.name,
|
|
2389
2360
|
description,
|
|
2390
|
-
sourcePath:
|
|
2361
|
+
sourcePath: dirPath,
|
|
2391
2362
|
category,
|
|
2392
|
-
isDirectory:
|
|
2363
|
+
isDirectory: true
|
|
2393
2364
|
});
|
|
2394
2365
|
}
|
|
2395
2366
|
} catch {
|
|
@@ -2406,7 +2377,7 @@ async function discoverAllAssets(sourcePath) {
|
|
|
2406
2377
|
|
|
2407
2378
|
// src/commands/agent/installer.ts
|
|
2408
2379
|
import { mkdir, cp, readdir as readdir2, symlink as fsSymlink, lstat, rm, readlink } from "fs/promises";
|
|
2409
|
-
import { join as join3, basename
|
|
2380
|
+
import { join as join3, basename, normalize, resolve, sep, relative, dirname } from "path";
|
|
2410
2381
|
import { platform } from "os";
|
|
2411
2382
|
|
|
2412
2383
|
// src/commands/agent/constants.ts
|
|
@@ -2426,10 +2397,6 @@ function isPathSafe(basePath, targetPath) {
|
|
|
2426
2397
|
const normalizedTarget = normalize(resolve(targetPath));
|
|
2427
2398
|
return normalizedTarget.startsWith(normalizedBase + sep) || normalizedTarget === normalizedBase;
|
|
2428
2399
|
}
|
|
2429
|
-
function getCanonicalDir(category, scope, cwd) {
|
|
2430
|
-
const baseDir = scope === "global" ? getDefaultConfigDir() : join3(cwd || process.cwd(), ".thought-cabinet");
|
|
2431
|
-
return join3(baseDir, CATEGORY_SUBDIRS[category]);
|
|
2432
|
-
}
|
|
2433
2400
|
function getAgentDir(agentType, category, scope, cwd) {
|
|
2434
2401
|
const agent = agents[agentType];
|
|
2435
2402
|
const agentBase = scope === "global" && agent.globalConfigDir ? agent.globalConfigDir : join3(cwd || process.cwd(), agent.configDir);
|
|
@@ -2515,11 +2482,9 @@ async function installAssetForAgent(asset, agentType, options = {}) {
|
|
|
2515
2482
|
};
|
|
2516
2483
|
}
|
|
2517
2484
|
const assetName = sanitizeName(asset.name);
|
|
2518
|
-
const canonicalBase = getCanonicalDir(asset.category, scope, cwd);
|
|
2519
|
-
const canonicalDir = join3(canonicalBase, assetName);
|
|
2520
2485
|
const agentBase = getAgentDir(agentType, asset.category, scope, cwd);
|
|
2521
2486
|
const agentDir = join3(agentBase, assetName);
|
|
2522
|
-
if (!isPathSafe(
|
|
2487
|
+
if (!isPathSafe(agentBase, agentDir)) {
|
|
2523
2488
|
return {
|
|
2524
2489
|
success: false,
|
|
2525
2490
|
path: agentDir,
|
|
@@ -2533,7 +2498,7 @@ async function installAssetForAgent(asset, agentType, options = {}) {
|
|
|
2533
2498
|
await copyDirectoryContents(asset.sourcePath, targetDir);
|
|
2534
2499
|
} else {
|
|
2535
2500
|
await mkdir(targetDir, { recursive: true });
|
|
2536
|
-
const fileName =
|
|
2501
|
+
const fileName = basename(asset.sourcePath);
|
|
2537
2502
|
await cp(asset.sourcePath, join3(targetDir, fileName), { dereference: true });
|
|
2538
2503
|
}
|
|
2539
2504
|
};
|
|
@@ -2542,26 +2507,15 @@ async function installAssetForAgent(asset, agentType, options = {}) {
|
|
|
2542
2507
|
await copyAsset(agentDir);
|
|
2543
2508
|
return { success: true, path: agentDir, mode: "copy" };
|
|
2544
2509
|
}
|
|
2545
|
-
await
|
|
2546
|
-
await
|
|
2547
|
-
const symlinkCreated = await createSymlink(
|
|
2510
|
+
await rm(agentDir, { recursive: true, force: true });
|
|
2511
|
+
await mkdir(dirname(agentDir), { recursive: true });
|
|
2512
|
+
const symlinkCreated = await createSymlink(asset.sourcePath, agentDir);
|
|
2548
2513
|
if (!symlinkCreated) {
|
|
2549
2514
|
await cleanAndCreateDirectory(agentDir);
|
|
2550
2515
|
await copyAsset(agentDir);
|
|
2551
|
-
return {
|
|
2552
|
-
success: true,
|
|
2553
|
-
path: agentDir,
|
|
2554
|
-
canonicalPath: canonicalDir,
|
|
2555
|
-
mode: "symlink",
|
|
2556
|
-
symlinkFailed: true
|
|
2557
|
-
};
|
|
2516
|
+
return { success: true, path: agentDir, mode: "symlink", symlinkFailed: true };
|
|
2558
2517
|
}
|
|
2559
|
-
return {
|
|
2560
|
-
success: true,
|
|
2561
|
-
path: agentDir,
|
|
2562
|
-
canonicalPath: canonicalDir,
|
|
2563
|
-
mode: "symlink"
|
|
2564
|
-
};
|
|
2518
|
+
return { success: true, path: agentDir, mode: "symlink" };
|
|
2565
2519
|
} catch (error) {
|
|
2566
2520
|
return {
|
|
2567
2521
|
success: false,
|
|
@@ -2664,30 +2618,7 @@ async function agentInitCommand(options) {
|
|
|
2664
2618
|
scope = scopeChoice;
|
|
2665
2619
|
}
|
|
2666
2620
|
}
|
|
2667
|
-
|
|
2668
|
-
if (!options.mode && !options.all) {
|
|
2669
|
-
const modeChoice = await p4.select({
|
|
2670
|
-
message: "Installation mode:",
|
|
2671
|
-
options: [
|
|
2672
|
-
{
|
|
2673
|
-
value: "symlink",
|
|
2674
|
-
label: "Symlink (recommended)",
|
|
2675
|
-
hint: "Canonical storage + symlinks; update once, all agents see changes"
|
|
2676
|
-
},
|
|
2677
|
-
{
|
|
2678
|
-
value: "copy",
|
|
2679
|
-
label: "Copy",
|
|
2680
|
-
hint: "Independent copies for each agent"
|
|
2681
|
-
}
|
|
2682
|
-
],
|
|
2683
|
-
initialValue: "symlink"
|
|
2684
|
-
});
|
|
2685
|
-
if (p4.isCancel(modeChoice)) {
|
|
2686
|
-
p4.cancel("Operation cancelled.");
|
|
2687
|
-
process.exit(0);
|
|
2688
|
-
}
|
|
2689
|
-
mode = modeChoice;
|
|
2690
|
-
}
|
|
2621
|
+
const mode = options.mode ?? "symlink";
|
|
2691
2622
|
if (!options.force) {
|
|
2692
2623
|
const cwd2 = process.cwd();
|
|
2693
2624
|
for (const agentType of selectedAgents) {
|
|
@@ -2769,7 +2700,6 @@ async function agentInitCommand(options) {
|
|
|
2769
2700
|
const cwd = process.cwd();
|
|
2770
2701
|
let totalInstalled = 0;
|
|
2771
2702
|
let totalFailed = 0;
|
|
2772
|
-
const symlinkWarnings = [];
|
|
2773
2703
|
const s = p4.spinner();
|
|
2774
2704
|
s.start("Installing assets...");
|
|
2775
2705
|
for (const asset of assetsToInstall) {
|
|
@@ -2778,7 +2708,7 @@ async function agentInitCommand(options) {
|
|
|
2778
2708
|
if (result.success) {
|
|
2779
2709
|
totalInstalled++;
|
|
2780
2710
|
if (result.symlinkFailed) {
|
|
2781
|
-
|
|
2711
|
+
p4.log.warn(
|
|
2782
2712
|
`${asset.name} \u2192 ${agents[agentType].displayName}: symlink failed, copied instead`
|
|
2783
2713
|
);
|
|
2784
2714
|
}
|
|
@@ -2789,12 +2719,6 @@ async function agentInitCommand(options) {
|
|
|
2789
2719
|
}
|
|
2790
2720
|
}
|
|
2791
2721
|
s.stop("Installation complete.");
|
|
2792
|
-
if (symlinkWarnings.length > 0) {
|
|
2793
|
-
p4.log.warn("Symlink warnings:");
|
|
2794
|
-
for (const warning of symlinkWarnings) {
|
|
2795
|
-
p4.log.warn(` ${warning}`);
|
|
2796
|
-
}
|
|
2797
|
-
}
|
|
2798
2722
|
const agentNames = selectedAgents.map((a) => agents[a].displayName).join(", ");
|
|
2799
2723
|
let message = `Installed ${totalInstalled} asset(s) to ${agentNames}`;
|
|
2800
2724
|
if (totalFailed > 0) {
|
|
@@ -2812,7 +2736,7 @@ async function agentInitCommand(options) {
|
|
|
2812
2736
|
// src/commands/agent.ts
|
|
2813
2737
|
function agentCommand(program) {
|
|
2814
2738
|
const agent = program.command("agent").description("Manage coding agent configuration");
|
|
2815
|
-
agent.command("init").description("Initialize coding agent configuration in current directory").option("--target <agents...>", "Target agents (e.g., claude-code codebuddy
|
|
2739
|
+
agent.command("init").description("Initialize coding agent configuration in current directory").option("--target <agents...>", "Target agents (e.g., claude-code codebuddy)").option("-g, --global", "Install to global scope").option("--mode <mode>", "Installation mode: symlink or copy (default: symlink)").option("--source <path>", "Source directory for assets").option("--force", "Force overwrite of existing installations").option("--all", "Install all assets without prompting").action(async (options) => {
|
|
2816
2740
|
const agentTypes = options.target?.map((a) => {
|
|
2817
2741
|
if (!isValidAgentType(a)) {
|
|
2818
2742
|
console.error(`Unknown agent: ${a}`);
|
|
@@ -2963,23 +2887,10 @@ function tmuxKillSession(sessionName) {
|
|
|
2963
2887
|
// src/agent-config.ts
|
|
2964
2888
|
import fs13 from "fs";
|
|
2965
2889
|
import path16 from "path";
|
|
2966
|
-
var CANONICAL_DIR = ".thought-cabinet";
|
|
2967
2890
|
function detectAgentConfigDirs(sourceDir) {
|
|
2968
2891
|
const uniqueDirs = [...new Set(Object.values(agents).map((a) => a.configDir))];
|
|
2969
2892
|
return uniqueDirs.filter((dir) => fs13.existsSync(path16.join(sourceDir, dir)));
|
|
2970
2893
|
}
|
|
2971
|
-
function getCanonicalSymlinkTarget(entryPath, canonicalDir) {
|
|
2972
|
-
try {
|
|
2973
|
-
if (!fs13.lstatSync(entryPath).isSymbolicLink()) return null;
|
|
2974
|
-
const linkTarget = fs13.readlinkSync(entryPath);
|
|
2975
|
-
const resolvedTarget = path16.resolve(path16.dirname(entryPath), linkTarget);
|
|
2976
|
-
const resolvedCanonical = path16.resolve(canonicalDir);
|
|
2977
|
-
const isInsideCanonical = resolvedTarget === resolvedCanonical || resolvedTarget.startsWith(resolvedCanonical + path16.sep);
|
|
2978
|
-
return isInsideCanonical ? path16.relative(resolvedCanonical, resolvedTarget) : null;
|
|
2979
|
-
} catch {
|
|
2980
|
-
return null;
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
2894
|
function symlinkOrCopy(srcPath, destPath, linkTarget) {
|
|
2984
2895
|
try {
|
|
2985
2896
|
fs13.symlinkSync(linkTarget, destPath);
|
|
@@ -2990,19 +2901,15 @@ function symlinkOrCopy(srcPath, destPath, linkTarget) {
|
|
|
2990
2901
|
}
|
|
2991
2902
|
}
|
|
2992
2903
|
}
|
|
2993
|
-
function copyDirWithSymlinkHandling(srcDir, destDir
|
|
2904
|
+
function copyDirWithSymlinkHandling(srcDir, destDir) {
|
|
2994
2905
|
fs13.mkdirSync(destDir, { recursive: true });
|
|
2995
2906
|
for (const entry of fs13.readdirSync(srcDir, { withFileTypes: true })) {
|
|
2996
2907
|
const srcPath = path16.join(srcDir, entry.name);
|
|
2997
2908
|
const destPath = path16.join(destDir, entry.name);
|
|
2998
|
-
|
|
2999
|
-
if (canonicalRelPath !== null) {
|
|
3000
|
-
const newTarget = path16.join(targetCanonicalDir, canonicalRelPath);
|
|
3001
|
-
symlinkOrCopy(srcPath, destPath, path16.relative(path16.dirname(destPath), newTarget));
|
|
3002
|
-
} else if (entry.isSymbolicLink()) {
|
|
2909
|
+
if (entry.isSymbolicLink()) {
|
|
3003
2910
|
symlinkOrCopy(srcPath, destPath, fs13.readlinkSync(srcPath));
|
|
3004
2911
|
} else if (entry.isDirectory()) {
|
|
3005
|
-
copyDirWithSymlinkHandling(srcPath, destPath
|
|
2912
|
+
copyDirWithSymlinkHandling(srcPath, destPath);
|
|
3006
2913
|
} else {
|
|
3007
2914
|
fs13.cpSync(srcPath, destPath);
|
|
3008
2915
|
}
|
|
@@ -3012,26 +2919,15 @@ function copyAgentConfigDirs(options) {
|
|
|
3012
2919
|
const { sourceDir, targetDir } = options;
|
|
3013
2920
|
const copied = [];
|
|
3014
2921
|
const skipped = [];
|
|
3015
|
-
const sourceCanonicalDir = path16.join(sourceDir, CANONICAL_DIR);
|
|
3016
|
-
const targetCanonicalDir = path16.join(targetDir, CANONICAL_DIR);
|
|
3017
|
-
const canonicalCopied = fs13.existsSync(sourceCanonicalDir);
|
|
3018
|
-
if (canonicalCopied) {
|
|
3019
|
-
fs13.cpSync(sourceCanonicalDir, targetCanonicalDir, { recursive: true });
|
|
3020
|
-
}
|
|
3021
2922
|
for (const dirName of detectAgentConfigDirs(sourceDir)) {
|
|
3022
2923
|
try {
|
|
3023
|
-
copyDirWithSymlinkHandling(
|
|
3024
|
-
path16.join(sourceDir, dirName),
|
|
3025
|
-
path16.join(targetDir, dirName),
|
|
3026
|
-
sourceCanonicalDir,
|
|
3027
|
-
targetCanonicalDir
|
|
3028
|
-
);
|
|
2924
|
+
copyDirWithSymlinkHandling(path16.join(sourceDir, dirName), path16.join(targetDir, dirName));
|
|
3029
2925
|
copied.push(dirName);
|
|
3030
2926
|
} catch {
|
|
3031
2927
|
skipped.push(dirName);
|
|
3032
2928
|
}
|
|
3033
2929
|
}
|
|
3034
|
-
return { copied, skipped
|
|
2930
|
+
return { copied, skipped };
|
|
3035
2931
|
}
|
|
3036
2932
|
|
|
3037
2933
|
// src/commands/worktree/add.ts
|
|
@@ -3103,11 +2999,8 @@ async function worktreeAddCommand(name, options) {
|
|
|
3103
2999
|
sourceDir: mainRoot,
|
|
3104
3000
|
targetDir: worktreePath
|
|
3105
3001
|
});
|
|
3106
|
-
if (configResult.copied.length > 0
|
|
3107
|
-
|
|
3108
|
-
if (configResult.canonicalCopied) parts.push(".thought-cabinet");
|
|
3109
|
-
parts.push(...configResult.copied);
|
|
3110
|
-
console.log(chalk16.gray(`Copied config: ${parts.join(", ")}`));
|
|
3002
|
+
if (configResult.copied.length > 0) {
|
|
3003
|
+
console.log(chalk16.gray(`Copied config: ${configResult.copied.join(", ")}`));
|
|
3111
3004
|
}
|
|
3112
3005
|
if (options.thoughts !== false) {
|
|
3113
3006
|
initializeWorktreeThoughts(mainRoot, worktreePath);
|
|
@@ -3631,7 +3524,7 @@ function getBranchNames() {
|
|
|
3631
3524
|
}
|
|
3632
3525
|
}
|
|
3633
3526
|
function getAgentNames() {
|
|
3634
|
-
return ["claude-code", "codebuddy"
|
|
3527
|
+
return ["claude-code", "codebuddy"];
|
|
3635
3528
|
}
|
|
3636
3529
|
|
|
3637
3530
|
// src/completion/handler.ts
|