oh-my-customcode 1.1.99 → 1.1.101

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/cli/index.js CHANGED
@@ -47,8 +47,9 @@ var __esm = (fn, res, err) => () => {
47
47
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
48
48
 
49
49
  // src/utils/home.ts
50
+ import { realpathSync } from "node:fs";
50
51
  import { homedir, userInfo } from "node:os";
51
- import { parse, sep } from "node:path";
52
+ import { basename, dirname, isAbsolute, join, parse, sep } from "node:path";
52
53
  function readEnvHome() {
53
54
  return process.env.HOME;
54
55
  }
@@ -94,16 +95,35 @@ function isPathWithin(path, base) {
94
95
  const prefix = strippedBase.endsWith(sep) || strippedBase.endsWith("/") ? strippedBase : strippedBase + sep;
95
96
  return path.startsWith(prefix);
96
97
  }
98
+ function realpathOrSelf(p) {
99
+ if (p === "" || !isAbsolute(p)) {
100
+ return p;
101
+ }
102
+ const tail = [];
103
+ let current = p;
104
+ let parent = dirname(current);
105
+ while (parent !== current) {
106
+ try {
107
+ return join(realpathSync(current), ...tail);
108
+ } catch {}
109
+ tail.unshift(basename(current));
110
+ current = parent;
111
+ parent = dirname(current);
112
+ }
113
+ return p;
114
+ }
97
115
  function isUnderHome(path, home) {
98
- return isPathWithin(path, home ?? resolveHomeDir());
116
+ const base = home ?? resolveHomeDir();
117
+ const paths = [path, realpathOrSelf(path)];
118
+ const bases = [base, realpathOrSelf(base)];
119
+ return paths.some((p) => bases.some((b) => isPathWithin(p, b)));
99
120
  }
100
- function shortenHome(path, home) {
101
- const base = stripTrailingSeparators(home ?? resolveHomeDir());
121
+ function tildeRelative(path, rawBase) {
122
+ const base = stripTrailingSeparators(rawBase);
102
123
  if (!isPathWithin(path, base)) {
103
- return path;
124
+ return;
104
125
  }
105
- const strippedPath = stripTrailingSeparators(path);
106
- if (strippedPath === base) {
126
+ if (stripTrailingSeparators(path) === base) {
107
127
  return "~";
108
128
  }
109
129
  let rest = path.slice(base.length);
@@ -112,13 +132,31 @@ function shortenHome(path, home) {
112
132
  }
113
133
  return `~${sep}${rest}`;
114
134
  }
135
+ function shortenHome(path, home) {
136
+ const base = home ?? resolveHomeDir();
137
+ const realPath = realpathOrSelf(path);
138
+ const realBase = realpathOrSelf(base);
139
+ const candidates = [
140
+ [path, base],
141
+ [path, realBase],
142
+ [realPath, base],
143
+ [realPath, realBase]
144
+ ];
145
+ for (const [p, b] of candidates) {
146
+ const shortened = tildeRelative(p, b);
147
+ if (shortened !== undefined) {
148
+ return shortened;
149
+ }
150
+ }
151
+ return path;
152
+ }
115
153
  var init_home = () => {};
116
154
 
117
155
  // src/core/registry.ts
118
- import { realpathSync } from "node:fs";
156
+ import { realpathSync as realpathSync2 } from "node:fs";
119
157
  import { mkdir, readFile, writeFile } from "node:fs/promises";
120
158
  import { tmpdir } from "node:os";
121
- import { basename, join, resolve, sep as sep2 } from "node:path";
159
+ import { basename as basename2, join as join2, resolve, sep as sep2 } from "node:path";
122
160
  function isTempPath(projectPath) {
123
161
  const normalized = resolve(projectPath);
124
162
  const candidates = new Set;
@@ -133,7 +171,7 @@ function isTempPath(projectPath) {
133
171
  candidates.add("/var/folders");
134
172
  for (const candidate of [...candidates]) {
135
173
  try {
136
- candidates.add(realpathSync(candidate));
174
+ candidates.add(realpathSync2(candidate));
137
175
  } catch {}
138
176
  }
139
177
  for (const candidate of candidates) {
@@ -153,10 +191,10 @@ function registryDir(home) {
153
191
  if (resolved === "") {
154
192
  throw new Error("Could not determine the home directory for the project registry");
155
193
  }
156
- return join(resolved, ".oh-my-customcode");
194
+ return join2(resolved, ".oh-my-customcode");
157
195
  }
158
196
  function registryPath() {
159
- return join(registryDir(), "projects.json");
197
+ return join2(registryDir(), "projects.json");
160
198
  }
161
199
  function emptyRegistry() {
162
200
  return { projects: {} };
@@ -257,14 +295,14 @@ async function migrateFromLockfiles(searchDirs) {
257
295
  } catch {
258
296
  return;
259
297
  }
260
- const entry = await parseLockFile(join(dir, ".omcustom.lock.json"));
298
+ const entry = await parseLockFile(join2(dir, ".omcustom.lock.json"));
261
299
  if (entry !== null) {
262
300
  discovered.set(resolve(dir), entry);
263
301
  return;
264
302
  }
265
303
  if (depth < MAX_DEPTH) {
266
304
  const subdirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && !SCAN_SKIP_DIRS.has(e.name));
267
- await Promise.all(subdirs.map((sub) => scan(join(dir, sub.name), depth + 1)));
305
+ await Promise.all(subdirs.map((sub) => scan(join2(dir, sub.name), depth + 1)));
268
306
  }
269
307
  }
270
308
  await Promise.all(searchDirs.map((dir) => scan(dir, 0).catch(() => {})));
@@ -297,7 +335,7 @@ var init_package = __esm(() => {
297
335
  workspaces: [
298
336
  "packages/*"
299
337
  ],
300
- version: "1.1.99",
338
+ version: "1.1.101",
301
339
  description: "Batteries-included agent harness for Claude Code",
302
340
  type: "module",
303
341
  bin: {
@@ -7293,7 +7331,7 @@ var require_public_api = __commonJS(function(exports) {
7293
7331
  });
7294
7332
 
7295
7333
  // src/utils/fs.ts
7296
- import { dirname as dirname2, isAbsolute, join as join3, relative, resolve as resolve2, sep as sep3 } from "node:path";
7334
+ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join4, relative, resolve as resolve2, sep as sep3 } from "node:path";
7297
7335
  import { fileURLToPath } from "node:url";
7298
7336
  function validatePreserveFilePath(filePath, projectRoot) {
7299
7337
  if (!filePath || filePath.trim() === "") {
@@ -7302,7 +7340,7 @@ function validatePreserveFilePath(filePath, projectRoot) {
7302
7340
  reason: "Path cannot be empty"
7303
7341
  };
7304
7342
  }
7305
- if (isAbsolute(filePath)) {
7343
+ if (isAbsolute2(filePath)) {
7306
7344
  return {
7307
7345
  valid: false,
7308
7346
  reason: "Absolute paths are not allowed"
@@ -7310,7 +7348,7 @@ function validatePreserveFilePath(filePath, projectRoot) {
7310
7348
  }
7311
7349
  const resolvedPath = resolve2(projectRoot, filePath);
7312
7350
  const relativePath = relative(projectRoot, resolvedPath);
7313
- if (relativePath.startsWith("..") || isAbsolute(relativePath)) {
7351
+ if (relativePath.startsWith("..") || isAbsolute2(relativePath)) {
7314
7352
  return {
7315
7353
  valid: false,
7316
7354
  reason: "Path cannot traverse outside project root"
@@ -7452,17 +7490,17 @@ async function readTextFile(path) {
7452
7490
  }
7453
7491
  async function writeTextFile(path, content) {
7454
7492
  const fs = await import("node:fs/promises");
7455
- await ensureDirectory(dirname2(path));
7493
+ await ensureDirectory(dirname3(path));
7456
7494
  await fs.writeFile(path, content, "utf-8");
7457
7495
  }
7458
7496
  function getPackageRoot() {
7459
7497
  const currentFile = fileURLToPath(import.meta.url);
7460
- const currentDir = dirname2(currentFile);
7498
+ const currentDir = dirname3(currentFile);
7461
7499
  return resolve2(currentDir, "..", "..");
7462
7500
  }
7463
7501
  function resolveTemplatePath(relativePath) {
7464
7502
  const packageRoot = getPackageRoot();
7465
- return join3(packageRoot, "templates", relativePath);
7503
+ return join4(packageRoot, "templates", relativePath);
7466
7504
  }
7467
7505
  async function listFiles(dir, options = {}) {
7468
7506
  const fs = await import("node:fs/promises");
@@ -7484,7 +7522,7 @@ async function listFiles(dir, options = {}) {
7484
7522
  }
7485
7523
  async function copyFile(src, dest) {
7486
7524
  const fs = await import("node:fs/promises");
7487
- await ensureDirectory(dirname2(dest));
7525
+ await ensureDirectory(dirname3(dest));
7488
7526
  await fs.copyFile(src, dest);
7489
7527
  }
7490
7528
  async function createTempDir(prefix = "omcustom-") {
@@ -7505,9 +7543,9 @@ var UTF8_BOM = "\uFEFF";
7505
7543
  var init_fs = () => {};
7506
7544
 
7507
7545
  // src/cli/projects.ts
7508
- import { basename as basename4, join as join11, resolve as resolve3 } from "node:path";
7546
+ import { basename as basename5, join as join12, resolve as resolve3 } from "node:path";
7509
7547
  async function readLockFile(projectDir) {
7510
- const lockFilePath = join11(projectDir, ".omcustom.lock.json");
7548
+ const lockFilePath = join12(projectDir, ".omcustom.lock.json");
7511
7549
  try {
7512
7550
  const fs = await import("node:fs/promises");
7513
7551
  const content = await fs.readFile(lockFilePath, "utf-8");
@@ -7577,7 +7615,7 @@ async function findProjects(options = {}) {
7577
7615
  if (!isUnderHome(projectPath, home))
7578
7616
  continue;
7579
7617
  results.push({
7580
- name: basename4(projectPath),
7618
+ name: basename5(projectPath),
7581
7619
  path: projectPath,
7582
7620
  version: entry.version || null,
7583
7621
  installedAt: entry.installedAt || null,
@@ -7603,7 +7641,7 @@ async function _scanDirForLockfiles(dir, depth, seen, results, home, currentVers
7603
7641
  if (isUnderHome(dir, home)) {
7604
7642
  const version = lockFile.version || lockFile.templateVersion || null;
7605
7643
  results.push({
7606
- name: basename4(dir),
7644
+ name: basename5(dir),
7607
7645
  path: dir,
7608
7646
  version,
7609
7647
  installedAt: lockFile.installedAt || null,
@@ -7616,7 +7654,7 @@ async function _scanDirForLockfiles(dir, depth, seen, results, home, currentVers
7616
7654
  }
7617
7655
  if (depth < 3) {
7618
7656
  const subdirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && !SCAN_SKIP_DIRS2.has(e.name));
7619
- await Promise.all(subdirs.map((sub) => _scanDirForLockfiles(join11(dir, sub.name), depth + 1, seen, results, home, currentVersion, fs).catch(() => {})));
7657
+ await Promise.all(subdirs.map((sub) => _scanDirForLockfiles(join12(dir, sub.name), depth + 1, seen, results, home, currentVersion, fs).catch(() => {})));
7620
7658
  }
7621
7659
  }
7622
7660
  async function _findProjectsFromLockfiles(options, currentVersion) {
@@ -7640,7 +7678,7 @@ async function _findProjectsFromLockfiles(options, currentVersion) {
7640
7678
  }
7641
7679
  async function writeLockFile(projectDir, version, existing) {
7642
7680
  const fs = await import("node:fs/promises");
7643
- const lockFilePath = join11(projectDir, ".omcustom.lock.json");
7681
+ const lockFilePath = join12(projectDir, ".omcustom.lock.json");
7644
7682
  const now = new Date().toISOString();
7645
7683
  const merged = {
7646
7684
  ...existing || {},
@@ -7699,7 +7737,7 @@ oh-my-customcode 적용 프로젝트 (${projects.length}개):`);
7699
7737
  현재 설치 버전: v${currentVersion}`);
7700
7738
  }
7701
7739
  function buildMigrationSearchDirs(home, extraPaths = []) {
7702
- return [...home ? DEFAULT_SEARCH_DIRS.map((d) => join11(home, d)) : [], ...extraPaths];
7740
+ return [...home ? DEFAULT_SEARCH_DIRS.map((d) => join12(home, d)) : [], ...extraPaths];
7703
7741
  }
7704
7742
  async function runMigration(options) {
7705
7743
  await Promise.resolve().then(() => init_registry());
@@ -11935,7 +11973,7 @@ init_package();
11935
11973
  import { execSync as execSync2, spawnSync } from "node:child_process";
11936
11974
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
11937
11975
  import { homedir as homedir2 } from "node:os";
11938
- import { dirname, join as join2 } from "node:path";
11976
+ import { dirname as dirname2, join as join3 } from "node:path";
11939
11977
  import { createInterface } from "node:readline/promises";
11940
11978
 
11941
11979
  // node_modules/.bun/i18next@26.0.2+ff0372d108591aba/node_modules/i18next/dist/esm/i18next.js
@@ -15233,7 +15271,7 @@ var i18n = {
15233
15271
  // src/core/self-update.ts
15234
15272
  var DEFAULT_PACKAGE_NAME = "oh-my-customcode";
15235
15273
  var DEFAULT_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
15236
- var DEFAULT_CACHE_PATH = join2(homedir2(), ".oh-my-customcode", "self-update-cache.json");
15274
+ var DEFAULT_CACHE_PATH = join3(homedir2(), ".oh-my-customcode", "self-update-cache.json");
15237
15275
  var MS_EPOCH_THRESHOLD = 1000000000000;
15238
15276
  function normalizeVersion(version) {
15239
15277
  return version.trim().replace(/^v/i, "").split("-")[0] || "";
@@ -15330,7 +15368,7 @@ function readSelfUpdateCache(cachePath) {
15330
15368
  return null;
15331
15369
  }
15332
15370
  function writeCache(cachePath, latestVersion, now) {
15333
- const dir = dirname(cachePath);
15371
+ const dir = dirname2(cachePath);
15334
15372
  if (!existsSync(dir)) {
15335
15373
  mkdirSync(dir, { recursive: true });
15336
15374
  }
@@ -16087,7 +16125,7 @@ function installCodex(deps = defaultDeps) {
16087
16125
 
16088
16126
  // src/core/config.ts
16089
16127
  init_fs();
16090
- import { join as join4 } from "node:path";
16128
+ import { join as join5 } from "node:path";
16091
16129
  var CONFIG_FILE = ".omcustomrc.json";
16092
16130
  var CURRENT_CONFIG_VERSION = 1;
16093
16131
  function getDefaultConfig() {
@@ -16127,7 +16165,7 @@ function getDefaultPreferences() {
16127
16165
  };
16128
16166
  }
16129
16167
  function getConfigPath(targetDir) {
16130
- return join4(targetDir, CONFIG_FILE);
16168
+ return join5(targetDir, CONFIG_FILE);
16131
16169
  }
16132
16170
  async function loadConfig(targetDir) {
16133
16171
  const configPath = getConfigPath(targetDir);
@@ -16225,9 +16263,9 @@ function migrateConfig(config) {
16225
16263
  // src/core/doctor-framework.ts
16226
16264
  init_fs();
16227
16265
  import { readFile as readFile2 } from "node:fs/promises";
16228
- import { join as join5 } from "node:path";
16266
+ import { join as join6 } from "node:path";
16229
16267
  async function getInstalledVersion(targetDir) {
16230
- const rcPath = join5(targetDir, ".omcustomrc.json");
16268
+ const rcPath = join6(targetDir, ".omcustomrc.json");
16231
16269
  if (!await fileExists(rcPath))
16232
16270
  return null;
16233
16271
  try {
@@ -16299,7 +16337,7 @@ init_fs();
16299
16337
  import { createHash } from "node:crypto";
16300
16338
  import { createReadStream } from "node:fs";
16301
16339
  import { readdir, stat } from "node:fs/promises";
16302
- import { join as join6, relative as relative2 } from "node:path";
16340
+ import { join as join7, relative as relative2 } from "node:path";
16303
16341
  var LOCKFILE_NAME = ".omcustom.lock.json";
16304
16342
  var LOCKFILE_VERSION = 1;
16305
16343
  var LOCKFILE_COMPONENTS = [
@@ -16328,7 +16366,7 @@ function computeFileHash(filePath) {
16328
16366
  });
16329
16367
  }
16330
16368
  async function readLockfile(targetDir) {
16331
- const lockfilePath = join6(targetDir, LOCKFILE_NAME);
16369
+ const lockfilePath = join7(targetDir, LOCKFILE_NAME);
16332
16370
  const exists = await fileExists(lockfilePath);
16333
16371
  if (!exists) {
16334
16372
  debug("lockfile.not_found", { path: lockfilePath });
@@ -16352,7 +16390,7 @@ async function readLockfile(targetDir) {
16352
16390
  }
16353
16391
  }
16354
16392
  async function writeLockfile(targetDir, lockfile) {
16355
- const lockfilePath = join6(targetDir, LOCKFILE_NAME);
16393
+ const lockfilePath = join7(targetDir, LOCKFILE_NAME);
16356
16394
  await writeJsonFile(lockfilePath, lockfile);
16357
16395
  debug("lockfile.written", { path: lockfilePath });
16358
16396
  }
@@ -16377,7 +16415,7 @@ async function collectFiles(dir, projectRoot, isTopLevel) {
16377
16415
  if (isTopLevel && entry.startsWith(".") && entry !== ".claude") {
16378
16416
  continue;
16379
16417
  }
16380
- const fullPath = join6(dir, entry);
16418
+ const fullPath = join7(dir, entry);
16381
16419
  let fileStat;
16382
16420
  try {
16383
16421
  fileStat = await stat(fullPath);
@@ -16395,7 +16433,7 @@ async function collectFiles(dir, projectRoot, isTopLevel) {
16395
16433
  }
16396
16434
  async function generateLockfile(targetDir, generatorVersion, templateVersion) {
16397
16435
  const files = {};
16398
- const componentRoots = COMPONENT_PATHS.map(([prefix]) => join6(targetDir, prefix));
16436
+ const componentRoots = COMPONENT_PATHS.map(([prefix]) => join7(targetDir, prefix));
16399
16437
  for (const componentRoot of componentRoots) {
16400
16438
  const exists = await fileExists(componentRoot);
16401
16439
  if (!exists) {
@@ -16435,8 +16473,8 @@ async function generateLockfile(targetDir, generatorVersion, templateVersion) {
16435
16473
  async function generateAndWriteLockfileForDir(targetDir) {
16436
16474
  try {
16437
16475
  const packageRoot = getPackageRoot();
16438
- const manifest = await readJsonFile(join6(packageRoot, "templates", "manifest.json"));
16439
- const { version: generatorVersion } = await readJsonFile(join6(packageRoot, "package.json"));
16476
+ const manifest = await readJsonFile(join7(packageRoot, "templates", "manifest.json"));
16477
+ const { version: generatorVersion } = await readJsonFile(join7(packageRoot, "package.json"));
16440
16478
  const lockfile = await generateLockfile(targetDir, generatorVersion, manifest.version);
16441
16479
  await writeLockfile(targetDir, lockfile);
16442
16480
  return { fileCount: Object.keys(lockfile.files).length };
@@ -17186,7 +17224,7 @@ async function doctorCommand(options = {}) {
17186
17224
 
17187
17225
  // src/cli/init.ts
17188
17226
  init_package();
17189
- import { join as join13 } from "node:path";
17227
+ import { join as join14 } from "node:path";
17190
17228
 
17191
17229
  // src/core/installer.ts
17192
17230
  init_fs();
@@ -17197,11 +17235,11 @@ import {
17197
17235
  rename,
17198
17236
  stat as stat2
17199
17237
  } from "node:fs/promises";
17200
- import { basename as basename3, dirname as dirname4, join as join8 } from "node:path";
17238
+ import { basename as basename4, dirname as dirname5, join as join9 } from "node:path";
17201
17239
 
17202
17240
  // src/core/file-preservation.ts
17203
17241
  init_fs();
17204
- import { basename as basename2, join as join7 } from "node:path";
17242
+ import { basename as basename3, join as join8 } from "node:path";
17205
17243
 
17206
17244
  // src/core/hook-group-merge.ts
17207
17245
  var LEGACY_OMCUSTOM_DESCRIPTIONS = [
@@ -17335,8 +17373,8 @@ function matchesGlobPattern(filePath, pattern) {
17335
17373
  return regex.test(filePath);
17336
17374
  }
17337
17375
  async function extractSingleFile(fileName, rootDir, tempDir, result) {
17338
- const srcPath = join7(rootDir, fileName);
17339
- const destPath = join7(tempDir, fileName);
17376
+ const srcPath = join8(rootDir, fileName);
17377
+ const destPath = join8(tempDir, fileName);
17340
17378
  try {
17341
17379
  if (await fileExists(srcPath)) {
17342
17380
  await copyFile(srcPath, destPath);
@@ -17350,8 +17388,8 @@ async function extractSingleFile(fileName, rootDir, tempDir, result) {
17350
17388
  }
17351
17389
  }
17352
17390
  async function extractSingleDir(dirName, rootDir, tempDir, result) {
17353
- const srcPath = join7(rootDir, dirName);
17354
- const destPath = join7(tempDir, dirName);
17391
+ const srcPath = join8(rootDir, dirName);
17392
+ const destPath = join8(tempDir, dirName);
17355
17393
  try {
17356
17394
  if (await fileExists(srcPath)) {
17357
17395
  await copyDirectory(srcPath, destPath, { overwrite: true, preserveTimestamps: true });
@@ -17388,8 +17426,8 @@ async function restoreCriticalFiles(rootDir, preservation) {
17388
17426
  failures: []
17389
17427
  };
17390
17428
  for (const fileName of preservation.extractedFiles) {
17391
- const preservedPath = join7(preservation.tempDir, fileName);
17392
- const targetPath = join7(rootDir, fileName);
17429
+ const preservedPath = join8(preservation.tempDir, fileName);
17430
+ const targetPath = join8(rootDir, fileName);
17393
17431
  try {
17394
17432
  if (fileName.endsWith(".json")) {
17395
17433
  await mergeJsonFile(preservedPath, targetPath);
@@ -17405,8 +17443,8 @@ async function restoreCriticalFiles(rootDir, preservation) {
17405
17443
  }
17406
17444
  }
17407
17445
  for (const dirName of preservation.extractedDirs) {
17408
- const preservedPath = join7(preservation.tempDir, dirName);
17409
- const targetPath = join7(rootDir, dirName);
17446
+ const preservedPath = join8(preservation.tempDir, dirName);
17447
+ const targetPath = join8(rootDir, dirName);
17410
17448
  try {
17411
17449
  await copyDirectory(preservedPath, targetPath, {
17412
17450
  overwrite: false,
@@ -17431,14 +17469,14 @@ async function mergeJsonFile(preservedPath, targetPath) {
17431
17469
  if (await fileExists(targetPath)) {
17432
17470
  const { data: targetData } = parseJsonText(await readTextFile(targetPath));
17433
17471
  const merged = deepMerge(targetData, preservedData);
17434
- if (HOOKS_MERGE_FILES.has(basename2(targetPath)) && isGeneratedHookBlock(targetData.hooks)) {
17472
+ if (HOOKS_MERGE_FILES.has(basename3(targetPath)) && isGeneratedHookBlock(targetData.hooks)) {
17435
17473
  merged.hooks = mergeHookBlocks(preservedData.hooks, targetData.hooks);
17436
17474
  }
17437
17475
  await writeTextFile(targetPath, stringifyJson(merged, format));
17438
- debug("preserve.merged_json", { file: basename2(targetPath) });
17476
+ debug("preserve.merged_json", { file: basename3(targetPath) });
17439
17477
  } else {
17440
17478
  await copyFile(preservedPath, targetPath);
17441
- debug("preserve.copied_json", { file: basename2(targetPath) });
17479
+ debug("preserve.copied_json", { file: basename3(targetPath) });
17442
17480
  }
17443
17481
  }
17444
17482
  function deepMerge(target, source) {
@@ -17776,7 +17814,7 @@ function migrateHookCommands(settings) {
17776
17814
 
17777
17815
  // src/core/hooks-settings.ts
17778
17816
  init_fs();
17779
- import { dirname as dirname3 } from "node:path";
17817
+ import { dirname as dirname4 } from "node:path";
17780
17818
  var IDENT_CHAR = /[A-Za-z0-9_.]/;
17781
17819
  var IDENT_START = /[A-Za-z_]/;
17782
17820
  function consumeSingleCharOp(input, i) {
@@ -18280,7 +18318,7 @@ async function mergeHooksIntoSettings(settingsPath, hooksJsonPath, options = {})
18280
18318
  }
18281
18319
  const settings = existing.ok ? existing.settings : {};
18282
18320
  settings.hooks = preserve ? mergeHookBlocks(settings.hooks, hooks) : hooks;
18283
- await ensureDirectory(dirname3(settingsPath));
18321
+ await ensureDirectory(dirname4(settingsPath));
18284
18322
  await writeTextFile(settingsPath, stringifyJson(settings, { bom: existing.bom, trailingNewline: true }));
18285
18323
  return { warnings };
18286
18324
  }
@@ -18317,7 +18355,7 @@ function shouldInstallAgent(agentDomain, filterDomain) {
18317
18355
  var DEFAULT_LANGUAGE2 = "en";
18318
18356
  function getTemplateDir() {
18319
18357
  const packageRoot = getPackageRoot();
18320
- return join8(packageRoot, "templates");
18358
+ return join9(packageRoot, "templates");
18321
18359
  }
18322
18360
  function createInstallResult(targetDir) {
18323
18361
  return {
@@ -18339,7 +18377,7 @@ async function handleBackup(targetDir, shouldBackup, result) {
18339
18377
  if (!shouldBackup)
18340
18378
  return null;
18341
18379
  const layout = getProviderLayout();
18342
- const rootDir = join8(targetDir, layout.rootDir);
18380
+ const rootDir = join9(targetDir, layout.rootDir);
18343
18381
  let preservation = null;
18344
18382
  if (await fileExists(rootDir)) {
18345
18383
  await Promise.resolve().then(() => init_fs());
@@ -18396,8 +18434,8 @@ async function installSingleComponent(targetDir, component, options, result) {
18396
18434
  }
18397
18435
  async function installStatusline(targetDir, options, _result) {
18398
18436
  const layout = getProviderLayout();
18399
- const srcPath = resolveTemplatePath(join8(layout.rootDir, "statusline.sh"));
18400
- const destPath = join8(targetDir, layout.rootDir, "statusline.sh");
18437
+ const srcPath = resolveTemplatePath(join9(layout.rootDir, "statusline.sh"));
18438
+ const destPath = join9(targetDir, layout.rootDir, "statusline.sh");
18401
18439
  if (!await fileExists(srcPath)) {
18402
18440
  debug("install.statusline_not_found", { path: srcPath });
18403
18441
  return;
@@ -18415,9 +18453,9 @@ async function installStatusline(targetDir, options, _result) {
18415
18453
  }
18416
18454
  async function installSchemas(targetDir, options, _result) {
18417
18455
  const layout = getProviderLayout();
18418
- const relPath = join8(layout.rootDir, "schemas", "tool-inputs.json");
18456
+ const relPath = join9(layout.rootDir, "schemas", "tool-inputs.json");
18419
18457
  const srcPath = resolveTemplatePath(relPath);
18420
- const destPath = join8(targetDir, relPath);
18458
+ const destPath = join9(targetDir, relPath);
18421
18459
  if (!await fileExists(srcPath)) {
18422
18460
  debug("install.schemas_not_found", { path: srcPath });
18423
18461
  return;
@@ -18428,13 +18466,13 @@ async function installSchemas(targetDir, options, _result) {
18428
18466
  return;
18429
18467
  }
18430
18468
  }
18431
- await ensureDirectory(dirname4(destPath));
18469
+ await ensureDirectory(dirname5(destPath));
18432
18470
  await copyFile(srcPath, destPath);
18433
18471
  debug("install.schemas_installed", {});
18434
18472
  }
18435
18473
  async function installTestsConfig(targetDir, options, _result) {
18436
- const srcPath = resolveTemplatePath(join8("tests", "tsconfig.json"));
18437
- const destPath = join8(targetDir, "tests", "tsconfig.json");
18474
+ const srcPath = resolveTemplatePath(join9("tests", "tsconfig.json"));
18475
+ const destPath = join9(targetDir, "tests", "tsconfig.json");
18438
18476
  if (!await fileExists(srcPath)) {
18439
18477
  debug("install.tests_config_not_found", { path: srcPath });
18440
18478
  return;
@@ -18484,7 +18522,7 @@ async function mergeStatusLineIntoExisting(settingsPath, existing, format, defau
18484
18522
  }
18485
18523
  async function installSettingsLocal(targetDir, result) {
18486
18524
  const layout = getProviderLayout();
18487
- const settingsPath = join8(targetDir, layout.rootDir, "settings.local.json");
18525
+ const settingsPath = join9(targetDir, layout.rootDir, "settings.local.json");
18488
18526
  const statusLineConfig = {
18489
18527
  statusLine: {
18490
18528
  type: "command",
@@ -18507,8 +18545,8 @@ async function installSettingsLocal(targetDir, result) {
18507
18545
  }
18508
18546
  async function installHooksSettings(targetDir, _options, result) {
18509
18547
  const layout = getProviderLayout();
18510
- const hooksJsonPath = join8(targetDir, getComponentPath("hooks"), "hooks.json");
18511
- const settingsPath = join8(targetDir, layout.rootDir, "settings.local.json");
18548
+ const hooksJsonPath = join9(targetDir, getComponentPath("hooks"), "hooks.json");
18549
+ const settingsPath = join9(targetDir, layout.rootDir, "settings.local.json");
18512
18550
  if (!await fileExists(hooksJsonPath)) {
18513
18551
  debug("install.hooks_settings_skipped", { reason: "hooks.json not installed" });
18514
18552
  return;
@@ -18530,7 +18568,7 @@ async function installHooksSettings(targetDir, _options, result) {
18530
18568
  var BOM = "\uFEFF";
18531
18569
  async function migrateRestoredHookCommands(targetDir, result) {
18532
18570
  const layout = getProviderLayout();
18533
- const settingsPath = join8(targetDir, layout.rootDir, "settings.local.json");
18571
+ const settingsPath = join9(targetDir, layout.rootDir, "settings.local.json");
18534
18572
  if (!await fileExists(settingsPath)) {
18535
18573
  return;
18536
18574
  }
@@ -18616,7 +18654,7 @@ async function install(options) {
18616
18654
  await installEntryDocWithTracking(options.targetDir, options, result);
18617
18655
  if (preservation) {
18618
18656
  const layout = getProviderLayout();
18619
- const rootDir = join8(options.targetDir, layout.rootDir);
18657
+ const rootDir = join9(options.targetDir, layout.rootDir);
18620
18658
  const restoration = await restoreCriticalFiles(rootDir, preservation);
18621
18659
  if (restoration.restoredFiles.length > 0 || restoration.restoredDirs.length > 0) {
18622
18660
  info("install.restored", {
@@ -18654,7 +18692,7 @@ async function install(options) {
18654
18692
  async function getTemplateManifest() {
18655
18693
  const packageRoot = getPackageRoot();
18656
18694
  const layout = getProviderLayout();
18657
- const manifestPath = join8(packageRoot, "templates", layout.manifestFile);
18695
+ const manifestPath = join9(packageRoot, "templates", layout.manifestFile);
18658
18696
  if (await fileExists(manifestPath)) {
18659
18697
  return readJsonFile(manifestPath);
18660
18698
  }
@@ -18677,10 +18715,10 @@ async function installSkillsWithScopeFilter(srcPath, destPath, options) {
18677
18715
  await ensureDirectory(destPath);
18678
18716
  const entries = await readdir2(srcPath);
18679
18717
  for (const entry of entries) {
18680
- const entrySrcPath = join8(srcPath, entry);
18718
+ const entrySrcPath = join9(srcPath, entry);
18681
18719
  if (!(await stat2(entrySrcPath)).isDirectory())
18682
18720
  continue;
18683
- const skillMdPath = join8(entrySrcPath, "SKILL.md");
18721
+ const skillMdPath = join9(entrySrcPath, "SKILL.md");
18684
18722
  if (await fileExists(skillMdPath)) {
18685
18723
  const content = await fsReadFile(skillMdPath, "utf-8");
18686
18724
  const scope = getSkillScope(content);
@@ -18689,7 +18727,7 @@ async function installSkillsWithScopeFilter(srcPath, destPath, options) {
18689
18727
  continue;
18690
18728
  }
18691
18729
  }
18692
- await copyDirectory(entrySrcPath, join8(destPath, entry), {
18730
+ await copyDirectory(entrySrcPath, join9(destPath, entry), {
18693
18731
  overwrite: !!(options.force || options.backup),
18694
18732
  preserveSymlinks: true,
18695
18733
  preserveTimestamps: true
@@ -18700,10 +18738,10 @@ async function installAgentsWithDomainFilter(srcPath, destPath, options) {
18700
18738
  await ensureDirectory(destPath);
18701
18739
  const entries = await readdir2(srcPath);
18702
18740
  for (const entry of entries) {
18703
- const entrySrcPath = join8(srcPath, entry);
18741
+ const entrySrcPath = join9(srcPath, entry);
18704
18742
  const entryStat = await stat2(entrySrcPath);
18705
18743
  if (entryStat.isDirectory()) {
18706
- await copyDirectory(entrySrcPath, join8(destPath, entry), {
18744
+ await copyDirectory(entrySrcPath, join9(destPath, entry), {
18707
18745
  overwrite: !!(options.force || options.backup),
18708
18746
  preserveSymlinks: true,
18709
18747
  preserveTimestamps: true
@@ -18720,7 +18758,7 @@ async function installAgentsWithDomainFilter(srcPath, destPath, options) {
18720
18758
  continue;
18721
18759
  }
18722
18760
  }
18723
- await copyFile(entrySrcPath, join8(destPath, entry));
18761
+ await copyFile(entrySrcPath, join9(destPath, entry));
18724
18762
  }
18725
18763
  }
18726
18764
  async function installComponent(targetDir, component, options) {
@@ -18728,7 +18766,7 @@ async function installComponent(targetDir, component, options) {
18728
18766
  return false;
18729
18767
  }
18730
18768
  const templatePath = getComponentPath(component);
18731
- const destPath = join8(targetDir, templatePath);
18769
+ const destPath = join9(targetDir, templatePath);
18732
18770
  const destExists = await fileExists(destPath);
18733
18771
  if (destExists && !options.force && !options.backup) {
18734
18772
  debug("install.component_skipped", { component });
@@ -18762,7 +18800,7 @@ async function installEntryDoc(targetDir, language, overwrite = false) {
18762
18800
  const layout = getProviderLayout();
18763
18801
  const templateFile = getEntryTemplateName(language);
18764
18802
  const srcPath = resolveTemplatePath(templateFile);
18765
- const destPath = join8(targetDir, layout.entryFile);
18803
+ const destPath = join9(targetDir, layout.entryFile);
18766
18804
  if (!await fileExists(srcPath)) {
18767
18805
  warn("install.entry_md_not_found", { language, path: srcPath, entry: layout.entryFile });
18768
18806
  return false;
@@ -18782,8 +18820,8 @@ async function installEntryDoc(targetDir, language, overwrite = false) {
18782
18820
  return true;
18783
18821
  }
18784
18822
  async function backupExisting(sourcePath, backupDir) {
18785
- const name = basename3(sourcePath);
18786
- const backupPath = join8(backupDir, name);
18823
+ const name = basename4(sourcePath);
18824
+ const backupPath = join9(backupDir, name);
18787
18825
  await rename(sourcePath, backupPath);
18788
18826
  return backupPath;
18789
18827
  }
@@ -18792,7 +18830,7 @@ async function checkExistingPaths(targetDir) {
18792
18830
  const pathsToCheck = [layout.entryFile, layout.rootDir, "guides"];
18793
18831
  const existingPaths = [];
18794
18832
  for (const relativePath of pathsToCheck) {
18795
- const fullPath = join8(targetDir, relativePath);
18833
+ const fullPath = join9(targetDir, relativePath);
18796
18834
  if (await fileExists(fullPath)) {
18797
18835
  existingPaths.push(relativePath);
18798
18836
  }
@@ -18806,11 +18844,11 @@ async function backupExistingInstallation(targetDir) {
18806
18844
  return [];
18807
18845
  }
18808
18846
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
18809
- const backupDir = join8(targetDir, `${layout.backupDirPrefix}${timestamp}`);
18847
+ const backupDir = join9(targetDir, `${layout.backupDirPrefix}${timestamp}`);
18810
18848
  await ensureDirectory(backupDir);
18811
18849
  const backedUpPaths = [];
18812
18850
  for (const relativePath of existingPaths) {
18813
- const fullPath = join8(targetDir, relativePath);
18851
+ const fullPath = join9(targetDir, relativePath);
18814
18852
  try {
18815
18853
  const backupPath = await backupExisting(fullPath, backupDir);
18816
18854
  backedUpPaths.push(backupPath);
@@ -18826,12 +18864,12 @@ async function backupExistingInstallation(targetDir) {
18826
18864
  // src/core/mcp-config.ts
18827
18865
  init_fs();
18828
18866
  import { writeFile as writeFile2 } from "node:fs/promises";
18829
- import { join as join9 } from "node:path";
18867
+ import { join as join10 } from "node:path";
18830
18868
  async function generateMCPConfig(targetDir) {
18831
18869
  const layout = getProviderLayout();
18832
- const mcpConfigPath = join9(targetDir, ".mcp.json");
18833
- const ontologyDir = join9(layout.rootDir, "ontology");
18834
- const ontologyExists = await fileExists(join9(targetDir, ontologyDir));
18870
+ const mcpConfigPath = join10(targetDir, ".mcp.json");
18871
+ const ontologyDir = join10(layout.rootDir, "ontology");
18872
+ const ontologyExists = await fileExists(join10(targetDir, ontologyDir));
18835
18873
  if (!ontologyExists) {
18836
18874
  return;
18837
18875
  }
@@ -18873,7 +18911,7 @@ async function generateMCPConfig(targetDir) {
18873
18911
  // src/core/ontology-rag-setup.ts
18874
18912
  init_fs();
18875
18913
  import { execSync as execSync5 } from "node:child_process";
18876
- import { join as join10 } from "node:path";
18914
+ import { join as join11 } from "node:path";
18877
18915
  var MIN_PYTHON_MINOR = 10;
18878
18916
  var DETECTION_TIMEOUT_MS = 3000;
18879
18917
  var INSTALL_TIMEOUT_MS = 90000;
@@ -18924,7 +18962,7 @@ function createVenvWithPython3(targetDir) {
18924
18962
  }
18925
18963
  function installOntologyRagEditable(targetDir, useUv) {
18926
18964
  const packageRoot = getPackageRoot();
18927
- const ontologyPkgPath = join10(packageRoot, "packages", "ontology-rag");
18965
+ const ontologyPkgPath = join11(packageRoot, "packages", "ontology-rag");
18928
18966
  if (useUv) {
18929
18967
  execSync5(`uv pip install --python .venv/bin/python -e "${ontologyPkgPath}"`, {
18930
18968
  cwd: targetDir,
@@ -18997,7 +19035,7 @@ async function setupOntologyRag(targetDir) {
18997
19035
  reason
18998
19036
  };
18999
19037
  }
19000
- const venvPython = join10(targetDir, ".venv", "bin", "python");
19038
+ const venvPython = join11(targetDir, ".venv", "bin", "python");
19001
19039
  const venvReady = await fileExists(venvPython);
19002
19040
  if (!venvReady) {
19003
19041
  const reason = ".venv/bin/python missing after install — environment may be incomplete. " + "Run `uv pip install -e packages/ontology-rag` manually to complete setup.";
@@ -19023,12 +19061,12 @@ init_package();
19023
19061
  init_projects();
19024
19062
  import { existsSync as existsSync2 } from "node:fs";
19025
19063
  import { copyFile as copyFile2, cp } from "node:fs/promises";
19026
- import { join as join12 } from "node:path";
19064
+ import { join as join13 } from "node:path";
19027
19065
  init_fs();
19028
19066
  init_registry();
19029
19067
  async function checkExistingInstallation(targetDir) {
19030
19068
  const layout = getProviderLayout();
19031
- const rootDir = join12(targetDir, layout.rootDir);
19069
+ const rootDir = join13(targetDir, layout.rootDir);
19032
19070
  return fileExists(rootDir);
19033
19071
  }
19034
19072
  async function installFromSnapshot(targetDir, snapshotPath, options) {
@@ -19040,7 +19078,7 @@ async function installFromSnapshot(targetDir, snapshotPath, options) {
19040
19078
  };
19041
19079
  }
19042
19080
  const layout = getProviderLayout();
19043
- const snapshotClaude = join12(snapshotPath, layout.rootDir);
19081
+ const snapshotClaude = join13(snapshotPath, layout.rootDir);
19044
19082
  if (!existsSync2(snapshotClaude)) {
19045
19083
  return {
19046
19084
  success: false,
@@ -19054,24 +19092,24 @@ async function installFromSnapshot(targetDir, snapshotPath, options) {
19054
19092
  if (exists && !options.force) {
19055
19093
  console.log(i18n.t("cli.init.exists", { rootDir: layout.rootDir }));
19056
19094
  console.log(i18n.t("cli.init.backing_up"));
19057
- const backupDir = join12(targetDir, `.claude-backup-${new Date().toISOString().replace(/[:.]/g, "-").slice(0, -1)}`);
19058
- await cp(join12(targetDir, layout.rootDir), backupDir, { recursive: true });
19095
+ const backupDir = join13(targetDir, `.claude-backup-${new Date().toISOString().replace(/[:.]/g, "-").slice(0, -1)}`);
19096
+ await cp(join13(targetDir, layout.rootDir), backupDir, { recursive: true });
19059
19097
  console.log(` Backed up to: ${backupDir}`);
19060
19098
  }
19061
- await cp(snapshotClaude, join12(targetDir, layout.rootDir), {
19099
+ await cp(snapshotClaude, join13(targetDir, layout.rootDir), {
19062
19100
  recursive: true,
19063
19101
  force: true
19064
19102
  });
19065
- const snapshotGuides = join12(snapshotPath, "guides");
19103
+ const snapshotGuides = join13(snapshotPath, "guides");
19066
19104
  if (existsSync2(snapshotGuides)) {
19067
- await cp(snapshotGuides, join12(targetDir, "guides"), {
19105
+ await cp(snapshotGuides, join13(targetDir, "guides"), {
19068
19106
  recursive: true,
19069
19107
  force: true
19070
19108
  });
19071
19109
  }
19072
- const snapshotEntry = join12(snapshotPath, layout.entryFile);
19110
+ const snapshotEntry = join13(snapshotPath, layout.entryFile);
19073
19111
  if (existsSync2(snapshotEntry)) {
19074
- await copyFile2(snapshotEntry, join12(targetDir, layout.entryFile));
19112
+ await copyFile2(snapshotEntry, join13(targetDir, layout.entryFile));
19075
19113
  }
19076
19114
  try {
19077
19115
  const existing = await readLockFile(targetDir);
@@ -19954,7 +19992,7 @@ async function runInitWizard(options) {
19954
19992
  // src/cli/init.ts
19955
19993
  async function checkExistingInstallation2(targetDir) {
19956
19994
  const layout = getProviderLayout();
19957
- const rootDir = join13(targetDir, layout.rootDir);
19995
+ const rootDir = join14(targetDir, layout.rootDir);
19958
19996
  return fileExists(rootDir);
19959
19997
  }
19960
19998
  var PROVIDER_SUBDIR_COMPONENTS = new Set([
@@ -19968,13 +20006,13 @@ var PROVIDER_SUBDIR_COMPONENTS = new Set([
19968
20006
  function componentToPath(targetDir, component) {
19969
20007
  if (component === "entry-md") {
19970
20008
  const layout = getProviderLayout();
19971
- return join13(targetDir, layout.entryFile);
20009
+ return join14(targetDir, layout.entryFile);
19972
20010
  }
19973
20011
  if (PROVIDER_SUBDIR_COMPONENTS.has(component)) {
19974
20012
  const layout = getProviderLayout();
19975
- return join13(targetDir, layout.rootDir, component);
20013
+ return join14(targetDir, layout.rootDir, component);
19976
20014
  }
19977
- return join13(targetDir, component);
20015
+ return join14(targetDir, component);
19978
20016
  }
19979
20017
  function buildInstalledPaths(targetDir, components) {
19980
20018
  return components.map((component) => componentToPath(targetDir, component));
@@ -20097,7 +20135,7 @@ async function initCommand(options) {
20097
20135
  }
20098
20136
 
20099
20137
  // src/cli/list.ts
20100
- import { basename as basename5, dirname as dirname5, join as join14, relative as relative3 } from "node:path";
20138
+ import { basename as basename6, dirname as dirname6, join as join15, relative as relative3 } from "node:path";
20101
20139
  init_fs();
20102
20140
  var ALLOWED_TOP_LEVEL_KEYS = new Set(["name", "type", "description", "version", "category"]);
20103
20141
  function parseKeyValue(line) {
@@ -20144,7 +20182,7 @@ function parseYamlMetadata(content) {
20144
20182
  return result;
20145
20183
  }
20146
20184
  function extractAgentTypeFromFilename(filename) {
20147
- const name = basename5(filename, ".md");
20185
+ const name = basename6(filename, ".md");
20148
20186
  const prefixMap = {
20149
20187
  lang: "language",
20150
20188
  be: "backend",
@@ -20162,17 +20200,17 @@ function extractAgentTypeFromFilename(filename) {
20162
20200
  return prefixMap[prefix] || "unknown";
20163
20201
  }
20164
20202
  function extractSkillCategoryFromPath(skillPath, baseDir, rootDir) {
20165
- const relativePath = relative3(join14(baseDir, rootDir, "skills"), skillPath);
20203
+ const relativePath = relative3(join15(baseDir, rootDir, "skills"), skillPath);
20166
20204
  const parts = relativePath.split("/").filter(Boolean);
20167
20205
  return parts[0] || "unknown";
20168
20206
  }
20169
20207
  function extractGuideCategoryFromPath(guidePath, baseDir) {
20170
- const relativePath = relative3(join14(baseDir, "guides"), guidePath);
20208
+ const relativePath = relative3(join15(baseDir, "guides"), guidePath);
20171
20209
  const parts = relativePath.split("/").filter(Boolean);
20172
20210
  return parts[0] || "unknown";
20173
20211
  }
20174
20212
  function extractRulePriorityFromFilename(filename) {
20175
- const name = basename5(filename, ".md");
20213
+ const name = basename6(filename, ".md");
20176
20214
  const parts = name.split("-");
20177
20215
  return parts[0] || "unknown";
20178
20216
  }
@@ -20261,7 +20299,7 @@ async function tryExtractMarkdownDescription(mdPath, options = {}) {
20261
20299
  }
20262
20300
  }
20263
20301
  async function getAgents(targetDir, rootDir = ".claude", config) {
20264
- const agentsDir = join14(targetDir, rootDir, "agents");
20302
+ const agentsDir = join15(targetDir, rootDir, "agents");
20265
20303
  if (!await fileExists(agentsDir))
20266
20304
  return [];
20267
20305
  try {
@@ -20270,8 +20308,8 @@ async function getAgents(targetDir, rootDir = ".claude", config) {
20270
20308
  const customAgentPaths = new Set(customComponents.filter((c) => c.type === "agent").map((c) => c.path));
20271
20309
  const agentMdFiles = await listFiles(agentsDir, { recursive: false, pattern: "*.md" });
20272
20310
  const agents = await Promise.all(agentMdFiles.map(async (agentMdPath) => {
20273
- const filename = basename5(agentMdPath);
20274
- const name = basename5(filename, ".md");
20311
+ const filename = basename6(agentMdPath);
20312
+ const name = basename6(filename, ".md");
20275
20313
  const description = await tryExtractMarkdownDescription(agentMdPath);
20276
20314
  const relativePath = relative3(targetDir, agentMdPath);
20277
20315
  return {
@@ -20289,7 +20327,7 @@ async function getAgents(targetDir, rootDir = ".claude", config) {
20289
20327
  }
20290
20328
  }
20291
20329
  async function getSkills(targetDir, rootDir = ".claude", config) {
20292
- const skillsDir = join14(targetDir, rootDir, "skills");
20330
+ const skillsDir = join15(targetDir, rootDir, "skills");
20293
20331
  if (!await fileExists(skillsDir))
20294
20332
  return [];
20295
20333
  try {
@@ -20298,12 +20336,12 @@ async function getSkills(targetDir, rootDir = ".claude", config) {
20298
20336
  const customSkillPaths = new Set(customComponents.filter((c) => c.type === "skill").map((c) => c.path));
20299
20337
  const skillMdFiles = await listFiles(skillsDir, { recursive: true, pattern: "SKILL.md" });
20300
20338
  const skills = await Promise.all(skillMdFiles.map(async (skillMdPath) => {
20301
- const skillDir = dirname5(skillMdPath);
20302
- const indexYamlPath = join14(skillDir, "index.yaml");
20339
+ const skillDir = dirname6(skillMdPath);
20340
+ const indexYamlPath = join15(skillDir, "index.yaml");
20303
20341
  const { description, version } = await tryReadIndexYamlMetadata(indexYamlPath);
20304
20342
  const relativePath = relative3(targetDir, skillDir);
20305
20343
  return {
20306
- name: basename5(skillDir),
20344
+ name: basename6(skillDir),
20307
20345
  type: "skill",
20308
20346
  category: extractSkillCategoryFromPath(skillDir, targetDir, rootDir),
20309
20347
  path: relativePath,
@@ -20318,7 +20356,7 @@ async function getSkills(targetDir, rootDir = ".claude", config) {
20318
20356
  }
20319
20357
  }
20320
20358
  async function getGuides(targetDir, config) {
20321
- const guidesDir = join14(targetDir, "guides");
20359
+ const guidesDir = join15(targetDir, "guides");
20322
20360
  if (!await fileExists(guidesDir))
20323
20361
  return [];
20324
20362
  try {
@@ -20330,7 +20368,7 @@ async function getGuides(targetDir, config) {
20330
20368
  const description = await tryExtractMarkdownDescription(guideMdPath, { maxLength: 100 });
20331
20369
  const relativePath = relative3(targetDir, guideMdPath);
20332
20370
  return {
20333
- name: basename5(guideMdPath, ".md"),
20371
+ name: basename6(guideMdPath, ".md"),
20334
20372
  type: "guide",
20335
20373
  category: extractGuideCategoryFromPath(guideMdPath, targetDir),
20336
20374
  path: relativePath,
@@ -20345,7 +20383,7 @@ async function getGuides(targetDir, config) {
20345
20383
  }
20346
20384
  var RULE_PRIORITY_ORDER = { MUST: 0, SHOULD: 1, MAY: 2 };
20347
20385
  async function getRules(targetDir, rootDir = ".claude", config) {
20348
- const rulesDir = join14(targetDir, rootDir, "rules");
20386
+ const rulesDir = join15(targetDir, rootDir, "rules");
20349
20387
  if (!await fileExists(rulesDir))
20350
20388
  return [];
20351
20389
  try {
@@ -20354,13 +20392,13 @@ async function getRules(targetDir, rootDir = ".claude", config) {
20354
20392
  const customRulePaths = new Set(customComponents.filter((c) => c.type === "rule").map((c) => c.path));
20355
20393
  const ruleMdFiles = await listFiles(rulesDir, { recursive: false, pattern: "*.md" });
20356
20394
  const rules = await Promise.all(ruleMdFiles.map(async (ruleMdPath) => {
20357
- const filename = basename5(ruleMdPath);
20395
+ const filename = basename6(ruleMdPath);
20358
20396
  const description = await tryExtractMarkdownDescription(ruleMdPath, {
20359
20397
  cleanFormatting: true
20360
20398
  });
20361
20399
  const relativePath = relative3(targetDir, ruleMdPath);
20362
20400
  return {
20363
- name: basename5(ruleMdPath, ".md"),
20401
+ name: basename6(ruleMdPath, ".md"),
20364
20402
  type: extractRulePriorityFromFilename(filename),
20365
20403
  path: relativePath,
20366
20404
  description,
@@ -20417,7 +20455,7 @@ function formatAsJson(components) {
20417
20455
  console.log(JSON.stringify(components, null, 2));
20418
20456
  }
20419
20457
  async function getHooks(targetDir, rootDir = ".claude") {
20420
- const hooksDir = join14(targetDir, rootDir, "hooks");
20458
+ const hooksDir = join15(targetDir, rootDir, "hooks");
20421
20459
  if (!await fileExists(hooksDir))
20422
20460
  return [];
20423
20461
  try {
@@ -20426,7 +20464,7 @@ async function getHooks(targetDir, rootDir = ".claude") {
20426
20464
  const hookYamls = await listFiles(hooksDir, { recursive: true, pattern: "*.yaml" });
20427
20465
  const allFiles = [...hookFiles, ...hookConfigs, ...hookYamls];
20428
20466
  return allFiles.map((hookPath) => ({
20429
- name: basename5(hookPath),
20467
+ name: basename6(hookPath),
20430
20468
  type: "hook",
20431
20469
  path: relative3(targetDir, hookPath)
20432
20470
  })).sort((a, b) => a.name.localeCompare(b.name));
@@ -20435,7 +20473,7 @@ async function getHooks(targetDir, rootDir = ".claude") {
20435
20473
  }
20436
20474
  }
20437
20475
  async function getContexts(targetDir, rootDir = ".claude") {
20438
- const contextsDir = join14(targetDir, rootDir, "contexts");
20476
+ const contextsDir = join15(targetDir, rootDir, "contexts");
20439
20477
  if (!await fileExists(contextsDir))
20440
20478
  return [];
20441
20479
  try {
@@ -20446,7 +20484,7 @@ async function getContexts(targetDir, rootDir = ".claude") {
20446
20484
  const ext = ctxPath.endsWith(".md") ? ".md" : ".yaml";
20447
20485
  const description = ext === ".md" ? await tryExtractMarkdownDescription(ctxPath, { maxLength: 100 }) : undefined;
20448
20486
  return {
20449
- name: basename5(ctxPath, ext),
20487
+ name: basename6(ctxPath, ext),
20450
20488
  type: "context",
20451
20489
  path: relative3(targetDir, ctxPath),
20452
20490
  description
@@ -20828,22 +20866,22 @@ async function securityCommand(_options = {}) {
20828
20866
 
20829
20867
  // src/cli/serve-commands.ts
20830
20868
  import { spawnSync as spawnSync2 } from "node:child_process";
20831
- import { join as join16 } from "node:path";
20869
+ import { join as join17 } from "node:path";
20832
20870
 
20833
20871
  // src/cli/serve.ts
20834
20872
  import { spawn } from "node:child_process";
20835
20873
  import { existsSync as existsSync3 } from "node:fs";
20836
20874
  import { readFile as readFile3, unlink, writeFile as writeFile3 } from "node:fs/promises";
20837
- import { join as join15 } from "node:path";
20875
+ import { join as join16 } from "node:path";
20838
20876
  var DEFAULT_PORT = 4321;
20839
- var PID_FILE = join15(process.env.HOME ?? "~", ".omcustom-serve.pid");
20877
+ var PID_FILE = join16(process.env.HOME ?? "~", ".omcustom-serve.pid");
20840
20878
  function findServeBuildDir(projectRoot, options) {
20841
- const localBuild = join15(projectRoot, "packages", "serve", "build");
20842
- if (existsSync3(join15(localBuild, "index.js")))
20879
+ const localBuild = join16(projectRoot, "packages", "serve", "build");
20880
+ if (existsSync3(join16(localBuild, "index.js")))
20843
20881
  return localBuild;
20844
20882
  if (options?.skipNpmFallback !== true) {
20845
- const npmBuild = join15(import.meta.dirname, "..", "..", "packages", "serve", "build");
20846
- if (existsSync3(join15(npmBuild, "index.js")))
20883
+ const npmBuild = join16(import.meta.dirname, "..", "..", "packages", "serve", "build");
20884
+ if (existsSync3(join16(npmBuild, "index.js")))
20847
20885
  return npmBuild;
20848
20886
  }
20849
20887
  return null;
@@ -20871,7 +20909,7 @@ async function startServeBackground(projectRoot, port = DEFAULT_PORT, buildDirOp
20871
20909
  if (buildDir === null) {
20872
20910
  return;
20873
20911
  }
20874
- const child = spawn("node", [join15(buildDir, "index.js")], {
20912
+ const child = spawn("node", [join16(buildDir, "index.js")], {
20875
20913
  env: {
20876
20914
  ...process.env,
20877
20915
  OMCUSTOM_PORT: String(port),
@@ -20948,7 +20986,7 @@ function runForeground(projectRoot, port, buildDirOpts) {
20948
20986
  process.exit(1);
20949
20987
  }
20950
20988
  console.log(`Web UI: http://localhost:${port}`);
20951
- spawnSync2("node", [join16(buildDir, "index.js")], {
20989
+ spawnSync2("node", [join17(buildDir, "index.js")], {
20952
20990
  env: {
20953
20991
  ...process.env,
20954
20992
  OMCUSTOM_PORT: String(port),
@@ -20967,12 +21005,12 @@ import { resolve as resolve4 } from "node:path";
20967
21005
  init_fs();
20968
21006
  import { existsSync as existsSync4 } from "node:fs";
20969
21007
  import { cp as cp2, mkdir as mkdir2 } from "node:fs/promises";
20970
- import { join as join17 } from "node:path";
21008
+ import { join as join18 } from "node:path";
20971
21009
  async function loadVersions() {
20972
21010
  try {
20973
21011
  const packageRoot = getPackageRoot();
20974
- const manifest = await readJsonFile(join17(packageRoot, "templates", "manifest.json"));
20975
- const pkg = await readJsonFile(join17(packageRoot, "package.json"));
21012
+ const manifest = await readJsonFile(join18(packageRoot, "templates", "manifest.json"));
21013
+ const pkg = await readJsonFile(join18(packageRoot, "package.json"));
20976
21014
  return { generatorVersion: pkg.version, templateVersion: manifest.version };
20977
21015
  } catch {
20978
21016
  return { generatorVersion: "0.0.0", templateVersion: "0.0.0" };
@@ -21042,7 +21080,7 @@ async function countFiles(dir) {
21042
21080
  return 0;
21043
21081
  }
21044
21082
  for (const entry of entries) {
21045
- const full = join17(current, entry);
21083
+ const full = join18(current, entry);
21046
21084
  try {
21047
21085
  const s = await stat(full);
21048
21086
  if (s.isDirectory()) {
@@ -21057,19 +21095,19 @@ async function countFiles(dir) {
21057
21095
  return walk(dir);
21058
21096
  }
21059
21097
  async function exportSnapshot(targetDir, outputPath) {
21060
- const claudeDir = join17(targetDir, ".claude");
21061
- const guidesDir = join17(targetDir, "guides");
21098
+ const claudeDir = join18(targetDir, ".claude");
21099
+ const guidesDir = join18(targetDir, "guides");
21062
21100
  if (!existsSync4(claudeDir)) {
21063
21101
  return { success: false, exportPath: outputPath, fileCount: 0 };
21064
21102
  }
21065
21103
  await mkdir2(outputPath, { recursive: true });
21066
- const destClaude = join17(outputPath, ".claude");
21104
+ const destClaude = join18(outputPath, ".claude");
21067
21105
  await cp2(claudeDir, destClaude, {
21068
21106
  recursive: true,
21069
21107
  filter: isExportable
21070
21108
  });
21071
21109
  if (existsSync4(guidesDir)) {
21072
- await cp2(guidesDir, join17(outputPath, "guides"), { recursive: true });
21110
+ await cp2(guidesDir, join18(outputPath, "guides"), { recursive: true });
21073
21111
  }
21074
21112
  const lockfile = await generateCurrentLockfile(targetDir);
21075
21113
  if (lockfile) {
@@ -21153,7 +21191,7 @@ import { constants as osConstants } from "node:os";
21153
21191
 
21154
21192
  // src/core/updater.ts
21155
21193
  init_package();
21156
- import { join as join18 } from "node:path";
21194
+ import { join as join19 } from "node:path";
21157
21195
  init_fs();
21158
21196
 
21159
21197
  // src/core/entry-merger.ts
@@ -21408,7 +21446,7 @@ function resolveCustomizations(customizations, configPreserveFiles, targetDir) {
21408
21446
  }
21409
21447
  async function updateEntryDoc(targetDir, config, options) {
21410
21448
  const layout = getProviderLayout();
21411
- const entryPath = join18(targetDir, layout.entryFile);
21449
+ const entryPath = join19(targetDir, layout.entryFile);
21412
21450
  const templateName = getEntryTemplateName2(config.language);
21413
21451
  const templatePath = resolveTemplatePath(templateName);
21414
21452
  if (!await fileExists(templatePath)) {
@@ -21446,7 +21484,7 @@ async function backfillStatusLineRefreshInterval(targetDir, options) {
21446
21484
  return;
21447
21485
  }
21448
21486
  const layout = getProviderLayout();
21449
- const settingsPath = join18(targetDir, layout.rootDir, "settings.local.json");
21487
+ const settingsPath = join19(targetDir, layout.rootDir, "settings.local.json");
21450
21488
  if (!await fileExists(settingsPath)) {
21451
21489
  return;
21452
21490
  }
@@ -21472,7 +21510,7 @@ async function migrateHookCommandsInSettingsLocal(targetDir, options) {
21472
21510
  return;
21473
21511
  }
21474
21512
  const layout = getProviderLayout();
21475
- const settingsPath = join18(targetDir, layout.rootDir, "settings.local.json");
21513
+ const settingsPath = join19(targetDir, layout.rootDir, "settings.local.json");
21476
21514
  if (!await fileExists(settingsPath)) {
21477
21515
  return;
21478
21516
  }
@@ -21567,7 +21605,7 @@ async function regenerateLockfile(targetDir, result) {
21567
21605
  }
21568
21606
  }
21569
21607
  async function shouldSkipSelfUpdate2(targetDir, result) {
21570
- const targetPkgPath = join18(targetDir, "package.json");
21608
+ const targetPkgPath = join19(targetDir, "package.json");
21571
21609
  if (await fileExists(targetPkgPath)) {
21572
21610
  const targetPkg = await readJsonFile(targetPkgPath);
21573
21611
  if (targetPkg.name === "oh-my-customcode") {
@@ -21706,11 +21744,11 @@ async function collectProtectedSkipPaths(srcPath, destPath, componentPath, force
21706
21744
  const warnedPaths = [];
21707
21745
  const updatedPaths = [];
21708
21746
  for (const p of protectedRelative) {
21709
- const targetFilePath = join18(targetDir, componentPath, p);
21747
+ const targetFilePath = join19(targetDir, componentPath, p);
21710
21748
  const lockfileKey = `${componentPath}/${p}`.replace(/\\/g, "/");
21711
21749
  const shouldSkip = await shouldSkipProtectedFile(targetFilePath, lockfileKey, lockfile);
21712
21750
  if (shouldSkip) {
21713
- skipPaths.push(path.relative(destPath, join18(destPath, p)));
21751
+ skipPaths.push(path.relative(destPath, join19(destPath, p)));
21714
21752
  warnedPaths.push(p);
21715
21753
  } else {
21716
21754
  updatedPaths.push(p);
@@ -21756,7 +21794,7 @@ async function updateComponent(targetDir, component, customizations, options, co
21756
21794
  const preservedFiles = [];
21757
21795
  const componentPath = getComponentPath2(component);
21758
21796
  const srcPath = resolveTemplatePath(componentPath);
21759
- const destPath = join18(targetDir, componentPath);
21797
+ const destPath = join19(targetDir, componentPath);
21760
21798
  const customComponents = config.customComponents || [];
21761
21799
  const skipPaths = [];
21762
21800
  if (customizations && !options.forceOverwriteAll) {
@@ -21798,7 +21836,7 @@ async function updateComponent(targetDir, component, customizations, options, co
21798
21836
  }
21799
21837
  skipPaths.push(...protectedSkipPaths);
21800
21838
  const path = await import("node:path");
21801
- const normalizedSkipPaths = skipPaths.map((p) => path.relative(destPath, join18(targetDir, p)));
21839
+ const normalizedSkipPaths = skipPaths.map((p) => path.relative(destPath, join19(targetDir, p)));
21802
21840
  const uniqueSkipPaths = [...new Set(normalizedSkipPaths)];
21803
21841
  await copyDirectory(srcPath, destPath, {
21804
21842
  overwrite: true,
@@ -21827,7 +21865,7 @@ async function syncRootLevelFiles(targetDir, options, customizations) {
21827
21865
  const preserved = [];
21828
21866
  const preserveSet = new Set(customizations && !options.forceOverwriteAll ? customizations.preserveFiles : []);
21829
21867
  for (const fileName of ROOT_LEVEL_FILES) {
21830
- const srcPath = resolveTemplatePath(join18(layout.rootDir, fileName));
21868
+ const srcPath = resolveTemplatePath(join19(layout.rootDir, fileName));
21831
21869
  if (!await fileExists(srcPath)) {
21832
21870
  continue;
21833
21871
  }
@@ -21836,8 +21874,8 @@ async function syncRootLevelFiles(targetDir, options, customizations) {
21836
21874
  preserved.push(relPath);
21837
21875
  continue;
21838
21876
  }
21839
- const destPath = join18(targetDir, layout.rootDir, fileName);
21840
- await ensureDirectory(join18(destPath, ".."));
21877
+ const destPath = join19(targetDir, layout.rootDir, fileName);
21878
+ await ensureDirectory(join19(destPath, ".."));
21841
21879
  await fs.copyFile(srcPath, destPath);
21842
21880
  if (fileName.endsWith(".sh")) {
21843
21881
  await fs.chmod(destPath, 493);
@@ -21872,7 +21910,7 @@ async function removeDeprecatedFiles(targetDir, options) {
21872
21910
  });
21873
21911
  continue;
21874
21912
  }
21875
- const fullPath = join18(targetDir, entry.path);
21913
+ const fullPath = join19(targetDir, entry.path);
21876
21914
  if (await fileExists(fullPath)) {
21877
21915
  await fs.unlink(fullPath);
21878
21916
  removed.push(entry.path);
@@ -21913,7 +21951,7 @@ async function syncNamespaceInFile(targetFilePath, upstreamFilePath) {
21913
21951
  async function processNamespaceSyncEntry(entry, relPath, fullSrcPath, destPath, componentPath, lockfile) {
21914
21952
  if (!entry.isFile() || !entry.name.endsWith(".md"))
21915
21953
  return null;
21916
- const targetFilePath = join18(destPath, relPath);
21954
+ const targetFilePath = join19(destPath, relPath);
21917
21955
  const lockfileKey = `${componentPath}/${relPath}`.replace(/\\/g, "/");
21918
21956
  const shouldSkip = await shouldSkipProtectedFile(targetFilePath, lockfileKey, lockfile);
21919
21957
  if (shouldSkip)
@@ -21928,7 +21966,7 @@ async function applyNamespaceSync(targetDir, component, lockfile) {
21928
21966
  return [];
21929
21967
  const componentPath = getComponentPath2(component);
21930
21968
  const srcPath = resolveTemplatePath(componentPath);
21931
- const destPath = join18(targetDir, componentPath);
21969
+ const destPath = join19(targetDir, componentPath);
21932
21970
  const fs = await import("node:fs/promises");
21933
21971
  const synced = [];
21934
21972
  const queue = [{ dir: srcPath, relDir: "" }];
@@ -21942,7 +21980,7 @@ async function applyNamespaceSync(targetDir, component, lockfile) {
21942
21980
  }
21943
21981
  for (const entry of entries) {
21944
21982
  const relPath = relDir ? `${relDir}/${entry.name}` : entry.name;
21945
- const fullSrcPath = join18(dir, entry.name);
21983
+ const fullSrcPath = join19(dir, entry.name);
21946
21984
  if (entry.isDirectory()) {
21947
21985
  queue.push({ dir: fullSrcPath, relDir: relPath });
21948
21986
  continue;
@@ -21965,26 +22003,26 @@ function getComponentPath2(component) {
21965
22003
  }
21966
22004
  async function backupInstallation(targetDir) {
21967
22005
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
21968
- const backupDir = join18(targetDir, `.omcustom-backup-${timestamp}`);
22006
+ const backupDir = join19(targetDir, `.omcustom-backup-${timestamp}`);
21969
22007
  const fs = await import("node:fs/promises");
21970
22008
  await ensureDirectory(backupDir);
21971
22009
  const layout = getProviderLayout();
21972
22010
  const dirsToBackup = [layout.rootDir, "guides"];
21973
22011
  for (const dir of dirsToBackup) {
21974
- const srcPath = join18(targetDir, dir);
22012
+ const srcPath = join19(targetDir, dir);
21975
22013
  if (await fileExists(srcPath)) {
21976
- const destPath = join18(backupDir, dir);
22014
+ const destPath = join19(backupDir, dir);
21977
22015
  await copyDirectory(srcPath, destPath, { overwrite: true });
21978
22016
  }
21979
22017
  }
21980
- const entryPath = join18(targetDir, layout.entryFile);
22018
+ const entryPath = join19(targetDir, layout.entryFile);
21981
22019
  if (await fileExists(entryPath)) {
21982
- await fs.copyFile(entryPath, join18(backupDir, layout.entryFile));
22020
+ await fs.copyFile(entryPath, join19(backupDir, layout.entryFile));
21983
22021
  }
21984
22022
  return backupDir;
21985
22023
  }
21986
22024
  async function loadCustomizationManifest(targetDir) {
21987
- const manifestPath = join18(targetDir, CUSTOMIZATION_MANIFEST_FILE);
22025
+ const manifestPath = join19(targetDir, CUSTOMIZATION_MANIFEST_FILE);
21988
22026
  if (await fileExists(manifestPath)) {
21989
22027
  return readJsonFile(manifestPath);
21990
22028
  }