oh-my-customcode 0.24.2 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -31,6 +31,20 @@ var __toESM = (mod, isNodeMode, target) => {
31
31
  return to;
32
32
  };
33
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+ var __returnValue = (v) => v;
35
+ function __exportSetter(name, newValue) {
36
+ this[name] = __returnValue.bind(null, newValue);
37
+ }
38
+ var __export = (target, all) => {
39
+ for (var name in all)
40
+ __defProp(target, name, {
41
+ get: all[name],
42
+ enumerable: true,
43
+ configurable: true,
44
+ set: __exportSetter.bind(all, name)
45
+ });
46
+ };
47
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
34
48
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
35
49
 
36
50
  // node_modules/commander/lib/error.js
@@ -9028,6 +9042,281 @@ var require_public_api = __commonJS((exports) => {
9028
9042
  exports.stringify = stringify;
9029
9043
  });
9030
9044
 
9045
+ // src/utils/fs.ts
9046
+ var exports_fs = {};
9047
+ __export(exports_fs, {
9048
+ writeTextFile: () => writeTextFile,
9049
+ writeJsonFile: () => writeJsonFile,
9050
+ validatePreserveFilePath: () => validatePreserveFilePath,
9051
+ resolveTemplatePath: () => resolveTemplatePath,
9052
+ resolvePath: () => resolvePath,
9053
+ remove: () => remove,
9054
+ readTextFile: () => readTextFile,
9055
+ readJsonFile: () => readJsonFile,
9056
+ normalizePath: () => normalizePath,
9057
+ move: () => move,
9058
+ listFiles: () => listFiles,
9059
+ isAbsolutePath: () => isAbsolutePath,
9060
+ getRelativePath: () => getRelativePath,
9061
+ getPackageRoot: () => getPackageRoot,
9062
+ getFileStats: () => getFileStats,
9063
+ filesAreIdentical: () => filesAreIdentical,
9064
+ fileExists: () => fileExists,
9065
+ ensureDirectory: () => ensureDirectory,
9066
+ createTempDir: () => createTempDir,
9067
+ copyFile: () => copyFile,
9068
+ copyDirectory: () => copyDirectory,
9069
+ calculateChecksum: () => calculateChecksum
9070
+ });
9071
+ import { dirname as dirname2, isAbsolute, join as join2, relative, resolve, sep } from "node:path";
9072
+ import { fileURLToPath } from "node:url";
9073
+ function validatePreserveFilePath(filePath, projectRoot) {
9074
+ if (!filePath || filePath.trim() === "") {
9075
+ return {
9076
+ valid: false,
9077
+ reason: "Path cannot be empty"
9078
+ };
9079
+ }
9080
+ if (isAbsolute(filePath)) {
9081
+ return {
9082
+ valid: false,
9083
+ reason: "Absolute paths are not allowed"
9084
+ };
9085
+ }
9086
+ const resolvedPath = resolve(projectRoot, filePath);
9087
+ const relativePath = relative(projectRoot, resolvedPath);
9088
+ if (relativePath.startsWith("..") || isAbsolute(relativePath)) {
9089
+ return {
9090
+ valid: false,
9091
+ reason: "Path cannot traverse outside project root"
9092
+ };
9093
+ }
9094
+ return { valid: true };
9095
+ }
9096
+ async function fileExists(path) {
9097
+ const fs = await import("node:fs/promises");
9098
+ try {
9099
+ await fs.access(path);
9100
+ return true;
9101
+ } catch {
9102
+ return false;
9103
+ }
9104
+ }
9105
+ async function ensureDirectory(path) {
9106
+ const fs = await import("node:fs/promises");
9107
+ await fs.mkdir(path, { recursive: true });
9108
+ }
9109
+ function shouldSkipEntry(entryName, options) {
9110
+ if (options.exclude?.some((pattern) => matchesPattern(entryName, pattern))) {
9111
+ return true;
9112
+ }
9113
+ if (options.include && !options.include.some((pattern) => matchesPattern(entryName, pattern))) {
9114
+ return true;
9115
+ }
9116
+ return false;
9117
+ }
9118
+ async function handleSymlink(srcPath, destPath, options, fs) {
9119
+ const destExists = await fileExists(destPath);
9120
+ if (destExists && !options.overwrite) {
9121
+ return;
9122
+ }
9123
+ if (options.preserveSymlinks !== false) {
9124
+ await copyPreservedSymlink(srcPath, destPath, destExists, fs);
9125
+ } else {
9126
+ await copyFollowedSymlink(srcPath, destPath, destExists, options, fs);
9127
+ }
9128
+ }
9129
+ async function copyPreservedSymlink(srcPath, destPath, destExists, fs) {
9130
+ const linkTarget = await fs.readlink(srcPath);
9131
+ if (destExists) {
9132
+ await fs.unlink(destPath);
9133
+ }
9134
+ await fs.symlink(linkTarget, destPath);
9135
+ }
9136
+ async function copyFollowedSymlink(srcPath, destPath, destExists, options, fs) {
9137
+ const realPath = await fs.realpath(srcPath);
9138
+ const stat = await fs.stat(realPath);
9139
+ if (stat.isDirectory()) {
9140
+ await copyDirectory(realPath, destPath, options);
9141
+ return;
9142
+ }
9143
+ if (destExists) {
9144
+ await fs.unlink(destPath);
9145
+ }
9146
+ await fs.copyFile(realPath, destPath);
9147
+ }
9148
+ async function handleFile(srcPath, destPath, options, fs) {
9149
+ const destExists = await fileExists(destPath);
9150
+ if (destExists && !options.overwrite) {
9151
+ return;
9152
+ }
9153
+ await fs.copyFile(srcPath, destPath);
9154
+ if (options.preserveTimestamps) {
9155
+ const stats = await fs.stat(srcPath);
9156
+ await fs.utimes(destPath, stats.atime, stats.mtime);
9157
+ }
9158
+ }
9159
+ function shouldSkipPath(destPath, destRoot, skipPaths) {
9160
+ if (!skipPaths || skipPaths.length === 0) {
9161
+ return false;
9162
+ }
9163
+ const relativePath = relative(destRoot, destPath);
9164
+ for (const skipPath of skipPaths) {
9165
+ if (skipPath.endsWith("/")) {
9166
+ const dirPath = skipPath.slice(0, -1);
9167
+ if (relativePath === dirPath || relativePath.startsWith(dirPath + sep)) {
9168
+ return true;
9169
+ }
9170
+ } else {
9171
+ if (relativePath === skipPath) {
9172
+ return true;
9173
+ }
9174
+ }
9175
+ }
9176
+ return false;
9177
+ }
9178
+ async function copyDirectory(src, dest, options = {}) {
9179
+ const fs = await import("node:fs/promises");
9180
+ const path = await import("node:path");
9181
+ await ensureDirectory(dest);
9182
+ const entries = await fs.readdir(src, { withFileTypes: true });
9183
+ for (const entry of entries) {
9184
+ if (shouldSkipEntry(entry.name, options)) {
9185
+ continue;
9186
+ }
9187
+ const srcPath = path.join(src, entry.name);
9188
+ const destPath = path.join(dest, entry.name);
9189
+ if (shouldSkipPath(destPath, dest, options.skipPaths)) {
9190
+ continue;
9191
+ }
9192
+ if (entry.isSymbolicLink()) {
9193
+ await handleSymlink(srcPath, destPath, options, fs);
9194
+ } else if (entry.isDirectory()) {
9195
+ await copyDirectory(srcPath, destPath, options);
9196
+ } else if (entry.isFile()) {
9197
+ await handleFile(srcPath, destPath, options, fs);
9198
+ }
9199
+ }
9200
+ }
9201
+ async function readJsonFile(path) {
9202
+ const fs = await import("node:fs/promises");
9203
+ const content = await fs.readFile(path, "utf-8");
9204
+ return JSON.parse(content);
9205
+ }
9206
+ async function writeJsonFile(path, data) {
9207
+ const fs = await import("node:fs/promises");
9208
+ const content = JSON.stringify(data, null, 2);
9209
+ await fs.writeFile(path, content, "utf-8");
9210
+ }
9211
+ async function readTextFile(path) {
9212
+ const fs = await import("node:fs/promises");
9213
+ return fs.readFile(path, "utf-8");
9214
+ }
9215
+ async function writeTextFile(path, content) {
9216
+ const fs = await import("node:fs/promises");
9217
+ await ensureDirectory(dirname2(path));
9218
+ await fs.writeFile(path, content, "utf-8");
9219
+ }
9220
+ async function remove(path) {
9221
+ const fs = await import("node:fs/promises");
9222
+ const stat = await fs.stat(path);
9223
+ if (stat.isDirectory()) {
9224
+ await fs.rm(path, { recursive: true, force: true });
9225
+ } else {
9226
+ await fs.unlink(path);
9227
+ }
9228
+ }
9229
+ function getPackageRoot() {
9230
+ const currentFile = fileURLToPath(import.meta.url);
9231
+ const currentDir = dirname2(currentFile);
9232
+ return resolve(currentDir, "..", "..");
9233
+ }
9234
+ function resolveTemplatePath(relativePath) {
9235
+ const packageRoot = getPackageRoot();
9236
+ return join2(packageRoot, "templates", relativePath);
9237
+ }
9238
+ async function listFiles(dir2, options = {}) {
9239
+ const fs = await import("node:fs/promises");
9240
+ const path = await import("node:path");
9241
+ const files = [];
9242
+ const entries = await fs.readdir(dir2, { withFileTypes: true });
9243
+ for (const entry of entries) {
9244
+ const fullPath = path.join(dir2, entry.name);
9245
+ if (entry.isDirectory() && options.recursive) {
9246
+ const subFiles = await listFiles(fullPath, options);
9247
+ files.push(...subFiles);
9248
+ } else if (entry.isFile()) {
9249
+ if (!options.pattern || matchesPattern(entry.name, options.pattern)) {
9250
+ files.push(fullPath);
9251
+ }
9252
+ }
9253
+ }
9254
+ return files;
9255
+ }
9256
+ async function getFileStats(path) {
9257
+ const fs = await import("node:fs/promises");
9258
+ const stats = await fs.stat(path);
9259
+ return {
9260
+ size: stats.size,
9261
+ created: stats.birthtime,
9262
+ modified: stats.mtime,
9263
+ isDirectory: stats.isDirectory(),
9264
+ isFile: stats.isFile()
9265
+ };
9266
+ }
9267
+ async function copyFile(src, dest) {
9268
+ const fs = await import("node:fs/promises");
9269
+ await ensureDirectory(dirname2(dest));
9270
+ await fs.copyFile(src, dest);
9271
+ }
9272
+ async function move(src, dest) {
9273
+ const fs = await import("node:fs/promises");
9274
+ await ensureDirectory(dirname2(dest));
9275
+ await fs.rename(src, dest);
9276
+ }
9277
+ async function createTempDir(prefix = "omcustom-") {
9278
+ const fs = await import("node:fs/promises");
9279
+ const os = await import("node:os");
9280
+ const path = await import("node:path");
9281
+ const tempBase = os.tmpdir();
9282
+ const tempDir = path.join(tempBase, `${prefix}${Date.now()}`);
9283
+ await fs.mkdir(tempDir, { recursive: true });
9284
+ return tempDir;
9285
+ }
9286
+ async function calculateChecksum(path) {
9287
+ const fs = await import("node:fs/promises");
9288
+ const crypto = await import("node:crypto");
9289
+ const content = await fs.readFile(path);
9290
+ const hash = crypto.createHash("md5");
9291
+ hash.update(content);
9292
+ return hash.digest("hex");
9293
+ }
9294
+ async function filesAreIdentical(path1, path2) {
9295
+ const [checksum1, checksum2] = await Promise.all([
9296
+ calculateChecksum(path1),
9297
+ calculateChecksum(path2)
9298
+ ]);
9299
+ return checksum1 === checksum2;
9300
+ }
9301
+ function matchesPattern(filename, pattern) {
9302
+ const regexPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".");
9303
+ const regex = new RegExp(`^${regexPattern}$`);
9304
+ return regex.test(filename);
9305
+ }
9306
+ function getRelativePath(basePath, fullPath) {
9307
+ return relative(basePath, fullPath);
9308
+ }
9309
+ function normalizePath(inputPath) {
9310
+ return inputPath.replace(/\\/g, "/");
9311
+ }
9312
+ function isAbsolutePath(inputPath) {
9313
+ return isAbsolute(inputPath);
9314
+ }
9315
+ function resolvePath(...paths) {
9316
+ return resolve(...paths);
9317
+ }
9318
+ var init_fs = () => {};
9319
+
9031
9320
  // src/cli/index.ts
9032
9321
  import { createRequire as createRequire2 } from "node:module";
9033
9322
 
@@ -12626,196 +12915,9 @@ var $visit = visit.visit;
12626
12915
  var $visitAsync = visit.visitAsync;
12627
12916
 
12628
12917
  // src/core/config.ts
12918
+ init_fs();
12629
12919
  import { join as join3 } from "node:path";
12630
12920
 
12631
- // src/utils/fs.ts
12632
- import { dirname as dirname2, isAbsolute, join as join2, relative, resolve, sep } from "node:path";
12633
- import { fileURLToPath } from "node:url";
12634
- function validatePreserveFilePath(filePath, projectRoot) {
12635
- if (!filePath || filePath.trim() === "") {
12636
- return {
12637
- valid: false,
12638
- reason: "Path cannot be empty"
12639
- };
12640
- }
12641
- if (isAbsolute(filePath)) {
12642
- return {
12643
- valid: false,
12644
- reason: "Absolute paths are not allowed"
12645
- };
12646
- }
12647
- const resolvedPath = resolve(projectRoot, filePath);
12648
- const relativePath = relative(projectRoot, resolvedPath);
12649
- if (relativePath.startsWith("..") || isAbsolute(relativePath)) {
12650
- return {
12651
- valid: false,
12652
- reason: "Path cannot traverse outside project root"
12653
- };
12654
- }
12655
- return { valid: true };
12656
- }
12657
- async function fileExists(path) {
12658
- const fs = await import("node:fs/promises");
12659
- try {
12660
- await fs.access(path);
12661
- return true;
12662
- } catch {
12663
- return false;
12664
- }
12665
- }
12666
- async function ensureDirectory(path) {
12667
- const fs = await import("node:fs/promises");
12668
- await fs.mkdir(path, { recursive: true });
12669
- }
12670
- function shouldSkipEntry(entryName, options) {
12671
- if (options.exclude?.some((pattern) => matchesPattern(entryName, pattern))) {
12672
- return true;
12673
- }
12674
- if (options.include && !options.include.some((pattern) => matchesPattern(entryName, pattern))) {
12675
- return true;
12676
- }
12677
- return false;
12678
- }
12679
- async function handleSymlink(srcPath, destPath, options, fs) {
12680
- const destExists = await fileExists(destPath);
12681
- if (destExists && !options.overwrite) {
12682
- return;
12683
- }
12684
- if (options.preserveSymlinks !== false) {
12685
- await copyPreservedSymlink(srcPath, destPath, destExists, fs);
12686
- } else {
12687
- await copyFollowedSymlink(srcPath, destPath, destExists, options, fs);
12688
- }
12689
- }
12690
- async function copyPreservedSymlink(srcPath, destPath, destExists, fs) {
12691
- const linkTarget = await fs.readlink(srcPath);
12692
- if (destExists) {
12693
- await fs.unlink(destPath);
12694
- }
12695
- await fs.symlink(linkTarget, destPath);
12696
- }
12697
- async function copyFollowedSymlink(srcPath, destPath, destExists, options, fs) {
12698
- const realPath = await fs.realpath(srcPath);
12699
- const stat = await fs.stat(realPath);
12700
- if (stat.isDirectory()) {
12701
- await copyDirectory(realPath, destPath, options);
12702
- return;
12703
- }
12704
- if (destExists) {
12705
- await fs.unlink(destPath);
12706
- }
12707
- await fs.copyFile(realPath, destPath);
12708
- }
12709
- async function handleFile(srcPath, destPath, options, fs) {
12710
- const destExists = await fileExists(destPath);
12711
- if (destExists && !options.overwrite) {
12712
- return;
12713
- }
12714
- await fs.copyFile(srcPath, destPath);
12715
- if (options.preserveTimestamps) {
12716
- const stats = await fs.stat(srcPath);
12717
- await fs.utimes(destPath, stats.atime, stats.mtime);
12718
- }
12719
- }
12720
- function shouldSkipPath(destPath, destRoot, skipPaths) {
12721
- if (!skipPaths || skipPaths.length === 0) {
12722
- return false;
12723
- }
12724
- const relativePath = relative(destRoot, destPath);
12725
- for (const skipPath of skipPaths) {
12726
- if (skipPath.endsWith("/")) {
12727
- const dirPath = skipPath.slice(0, -1);
12728
- if (relativePath === dirPath || relativePath.startsWith(dirPath + sep)) {
12729
- return true;
12730
- }
12731
- } else {
12732
- if (relativePath === skipPath) {
12733
- return true;
12734
- }
12735
- }
12736
- }
12737
- return false;
12738
- }
12739
- async function copyDirectory(src, dest, options = {}) {
12740
- const fs = await import("node:fs/promises");
12741
- const path = await import("node:path");
12742
- await ensureDirectory(dest);
12743
- const entries = await fs.readdir(src, { withFileTypes: true });
12744
- for (const entry of entries) {
12745
- if (shouldSkipEntry(entry.name, options)) {
12746
- continue;
12747
- }
12748
- const srcPath = path.join(src, entry.name);
12749
- const destPath = path.join(dest, entry.name);
12750
- if (shouldSkipPath(destPath, dest, options.skipPaths)) {
12751
- continue;
12752
- }
12753
- if (entry.isSymbolicLink()) {
12754
- await handleSymlink(srcPath, destPath, options, fs);
12755
- } else if (entry.isDirectory()) {
12756
- await copyDirectory(srcPath, destPath, options);
12757
- } else if (entry.isFile()) {
12758
- await handleFile(srcPath, destPath, options, fs);
12759
- }
12760
- }
12761
- }
12762
- async function readJsonFile(path) {
12763
- const fs = await import("node:fs/promises");
12764
- const content = await fs.readFile(path, "utf-8");
12765
- return JSON.parse(content);
12766
- }
12767
- async function writeJsonFile(path, data) {
12768
- const fs = await import("node:fs/promises");
12769
- const content = JSON.stringify(data, null, 2);
12770
- await fs.writeFile(path, content, "utf-8");
12771
- }
12772
- async function readTextFile(path) {
12773
- const fs = await import("node:fs/promises");
12774
- return fs.readFile(path, "utf-8");
12775
- }
12776
- async function writeTextFile(path, content) {
12777
- const fs = await import("node:fs/promises");
12778
- await ensureDirectory(dirname2(path));
12779
- await fs.writeFile(path, content, "utf-8");
12780
- }
12781
- function getPackageRoot() {
12782
- const currentFile = fileURLToPath(import.meta.url);
12783
- const currentDir = dirname2(currentFile);
12784
- return resolve(currentDir, "..", "..");
12785
- }
12786
- function resolveTemplatePath(relativePath) {
12787
- const packageRoot = getPackageRoot();
12788
- return join2(packageRoot, "templates", relativePath);
12789
- }
12790
- async function listFiles(dir2, options = {}) {
12791
- const fs = await import("node:fs/promises");
12792
- const path = await import("node:path");
12793
- const files = [];
12794
- const entries = await fs.readdir(dir2, { withFileTypes: true });
12795
- for (const entry of entries) {
12796
- const fullPath = path.join(dir2, entry.name);
12797
- if (entry.isDirectory() && options.recursive) {
12798
- const subFiles = await listFiles(fullPath, options);
12799
- files.push(...subFiles);
12800
- } else if (entry.isFile()) {
12801
- if (!options.pattern || matchesPattern(entry.name, options.pattern)) {
12802
- files.push(fullPath);
12803
- }
12804
- }
12805
- }
12806
- return files;
12807
- }
12808
- async function copyFile(src, dest) {
12809
- const fs = await import("node:fs/promises");
12810
- await ensureDirectory(dirname2(dest));
12811
- await fs.copyFile(src, dest);
12812
- }
12813
- function matchesPattern(filename, pattern) {
12814
- const regexPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".");
12815
- const regex = new RegExp(`^${regexPattern}$`);
12816
- return regex.test(filename);
12817
- }
12818
-
12819
12921
  // src/utils/logger.ts
12820
12922
  var currentOptions = {
12821
12923
  level: "info",
@@ -13026,7 +13128,12 @@ function getDefaultConfig() {
13026
13128
  checkIntervalHours: 24,
13027
13129
  autoApplyMinor: false
13028
13130
  },
13029
- preserveFiles: [],
13131
+ preserveFiles: [
13132
+ ".claude/settings.json",
13133
+ ".claude/settings.local.json",
13134
+ ".claude/agent-memory/",
13135
+ ".claude/agent-memory-local/"
13136
+ ],
13030
13137
  customComponents: []
13031
13138
  };
13032
13139
  }
@@ -13670,11 +13777,141 @@ async function doctorCommand(options = {}) {
13670
13777
  }
13671
13778
 
13672
13779
  // src/cli/init.ts
13673
- import { join as join6 } from "node:path";
13780
+ import { join as join7 } from "node:path";
13674
13781
 
13675
13782
  // src/core/installer.ts
13783
+ init_fs();
13676
13784
  import { readFile as fsReadFile, writeFile as fsWriteFile, rename } from "node:fs/promises";
13785
+ import { basename as basename2, join as join5 } from "node:path";
13786
+
13787
+ // src/core/file-preservation.ts
13788
+ init_fs();
13677
13789
  import { basename, join as join4 } from "node:path";
13790
+ var DEFAULT_CRITICAL_FILES = ["settings.json", "settings.local.json"];
13791
+ var DEFAULT_CRITICAL_DIRECTORIES = ["agent-memory", "agent-memory-local"];
13792
+ async function extractSingleFile(fileName, rootDir, tempDir, result) {
13793
+ const srcPath = join4(rootDir, fileName);
13794
+ const destPath = join4(tempDir, fileName);
13795
+ try {
13796
+ if (await fileExists(srcPath)) {
13797
+ await copyFile(srcPath, destPath);
13798
+ result.extractedFiles.push(fileName);
13799
+ debug("preserve.extracted_file", { file: fileName });
13800
+ }
13801
+ } catch (err) {
13802
+ const reason = err instanceof Error ? err.message : String(err);
13803
+ result.failures.push({ path: fileName, reason });
13804
+ warn("preserve.extract_failed", { file: fileName, error: reason });
13805
+ }
13806
+ }
13807
+ async function extractSingleDir(dirName, rootDir, tempDir, result) {
13808
+ const srcPath = join4(rootDir, dirName);
13809
+ const destPath = join4(tempDir, dirName);
13810
+ try {
13811
+ if (await fileExists(srcPath)) {
13812
+ await copyDirectory(srcPath, destPath, { overwrite: true, preserveTimestamps: true });
13813
+ result.extractedDirs.push(dirName);
13814
+ debug("preserve.extracted_dir", { dir: dirName });
13815
+ }
13816
+ } catch (err) {
13817
+ const reason = err instanceof Error ? err.message : String(err);
13818
+ result.failures.push({ path: dirName, reason });
13819
+ warn("preserve.extract_dir_failed", { dir: dirName, error: reason });
13820
+ }
13821
+ }
13822
+ async function extractCriticalFiles(rootDir, tempDir, additionalFiles = []) {
13823
+ const result = {
13824
+ tempDir,
13825
+ extractedFiles: [],
13826
+ extractedDirs: [],
13827
+ failures: []
13828
+ };
13829
+ await ensureDirectory(tempDir);
13830
+ const filesToExtract = [...DEFAULT_CRITICAL_FILES, ...additionalFiles];
13831
+ for (const fileName of filesToExtract) {
13832
+ await extractSingleFile(fileName, rootDir, tempDir, result);
13833
+ }
13834
+ for (const dirName of DEFAULT_CRITICAL_DIRECTORIES) {
13835
+ await extractSingleDir(dirName, rootDir, tempDir, result);
13836
+ }
13837
+ return result;
13838
+ }
13839
+ async function restoreCriticalFiles(rootDir, preservation) {
13840
+ const result = {
13841
+ restoredFiles: [],
13842
+ restoredDirs: [],
13843
+ failures: []
13844
+ };
13845
+ for (const fileName of preservation.extractedFiles) {
13846
+ const preservedPath = join4(preservation.tempDir, fileName);
13847
+ const targetPath = join4(rootDir, fileName);
13848
+ try {
13849
+ if (fileName.endsWith(".json")) {
13850
+ await mergeJsonFile(preservedPath, targetPath);
13851
+ } else {
13852
+ await copyFile(preservedPath, targetPath);
13853
+ }
13854
+ result.restoredFiles.push(fileName);
13855
+ debug("preserve.restored_file", { file: fileName });
13856
+ } catch (err) {
13857
+ const reason = err instanceof Error ? err.message : String(err);
13858
+ result.failures.push({ path: fileName, reason });
13859
+ warn("preserve.restore_failed", { file: fileName, error: reason });
13860
+ }
13861
+ }
13862
+ for (const dirName of preservation.extractedDirs) {
13863
+ const preservedPath = join4(preservation.tempDir, dirName);
13864
+ const targetPath = join4(rootDir, dirName);
13865
+ try {
13866
+ await copyDirectory(preservedPath, targetPath, {
13867
+ overwrite: false,
13868
+ preserveTimestamps: true
13869
+ });
13870
+ result.restoredDirs.push(dirName);
13871
+ debug("preserve.restored_dir", { dir: dirName });
13872
+ } catch (err) {
13873
+ const reason = err instanceof Error ? err.message : String(err);
13874
+ result.failures.push({ path: dirName, reason });
13875
+ warn("preserve.restore_dir_failed", { dir: dirName, error: reason });
13876
+ }
13877
+ }
13878
+ return result;
13879
+ }
13880
+ async function mergeJsonFile(preservedPath, targetPath) {
13881
+ const preservedData = await readJsonFile(preservedPath);
13882
+ if (await fileExists(targetPath)) {
13883
+ const targetData = await readJsonFile(targetPath);
13884
+ const merged = deepMerge(targetData, preservedData);
13885
+ await writeJsonFile(targetPath, merged);
13886
+ debug("preserve.merged_json", { file: basename(targetPath) });
13887
+ } else {
13888
+ await copyFile(preservedPath, targetPath);
13889
+ debug("preserve.copied_json", { file: basename(targetPath) });
13890
+ }
13891
+ }
13892
+ function deepMerge(target, source) {
13893
+ const result = { ...target };
13894
+ for (const key of Object.keys(source)) {
13895
+ const sourceVal = source[key];
13896
+ const targetVal = result[key];
13897
+ if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal !== null && typeof targetVal === "object" && !Array.isArray(targetVal)) {
13898
+ result[key] = deepMerge(targetVal, sourceVal);
13899
+ } else {
13900
+ result[key] = sourceVal;
13901
+ }
13902
+ }
13903
+ return result;
13904
+ }
13905
+ async function cleanupPreservation(tempDir) {
13906
+ try {
13907
+ const { rm } = await import("node:fs/promises");
13908
+ await rm(tempDir, { recursive: true, force: true });
13909
+ debug("preserve.cleanup", { dir: tempDir });
13910
+ } catch (err) {
13911
+ const reason = err instanceof Error ? err.message : String(err);
13912
+ warn("preserve.cleanup_failed", { dir: tempDir, error: reason });
13913
+ }
13914
+ }
13678
13915
 
13679
13916
  // src/core/git-workflow.ts
13680
13917
  import { execFileSync } from "node:child_process";
@@ -13927,7 +14164,7 @@ function getDefaultWorkflow() {
13927
14164
  var DEFAULT_LANGUAGE2 = "en";
13928
14165
  function getTemplateDir() {
13929
14166
  const packageRoot = getPackageRoot();
13930
- return join4(packageRoot, "templates");
14167
+ return join5(packageRoot, "templates");
13931
14168
  }
13932
14169
  function createInstallResult(targetDir) {
13933
14170
  return {
@@ -13947,12 +14184,27 @@ async function ensureTargetDirectory(targetDir) {
13947
14184
  }
13948
14185
  async function handleBackup(targetDir, shouldBackup, result) {
13949
14186
  if (!shouldBackup)
13950
- return;
14187
+ return null;
14188
+ const layout = getProviderLayout();
14189
+ const rootDir = join5(targetDir, layout.rootDir);
14190
+ let preservation = null;
14191
+ if (await fileExists(rootDir)) {
14192
+ const { createTempDir: createTempDir2 } = await Promise.resolve().then(() => (init_fs(), exports_fs));
14193
+ const tempDir = await createTempDir2("omcustom-preserve-");
14194
+ preservation = await extractCriticalFiles(rootDir, tempDir);
14195
+ if (preservation.extractedFiles.length > 0 || preservation.extractedDirs.length > 0) {
14196
+ info("install.preserved", {
14197
+ files: String(preservation.extractedFiles.length),
14198
+ dirs: String(preservation.extractedDirs.length)
14199
+ });
14200
+ }
14201
+ }
13951
14202
  const backupPaths = await backupExistingInstallation(targetDir);
13952
14203
  result.backedUpPaths.push(...backupPaths);
13953
14204
  if (backupPaths.length > 0) {
13954
14205
  info("install.backup", { path: backupPaths[0] });
13955
14206
  }
14207
+ return preservation;
13956
14208
  }
13957
14209
  async function checkAndWarnExisting(targetDir, force, backup, result) {
13958
14210
  if (force || backup)
@@ -13991,8 +14243,8 @@ async function installSingleComponent(targetDir, component, options, result) {
13991
14243
  }
13992
14244
  async function installStatusline(targetDir, options, _result) {
13993
14245
  const layout = getProviderLayout();
13994
- const srcPath = resolveTemplatePath(join4(layout.rootDir, "statusline.sh"));
13995
- const destPath = join4(targetDir, layout.rootDir, "statusline.sh");
14246
+ const srcPath = resolveTemplatePath(join5(layout.rootDir, "statusline.sh"));
14247
+ const destPath = join5(targetDir, layout.rootDir, "statusline.sh");
13996
14248
  if (!await fileExists(srcPath)) {
13997
14249
  debug("install.statusline_not_found", { path: srcPath });
13998
14250
  return;
@@ -14010,7 +14262,7 @@ async function installStatusline(targetDir, options, _result) {
14010
14262
  }
14011
14263
  async function installSettingsLocal(targetDir, result) {
14012
14264
  const layout = getProviderLayout();
14013
- const settingsPath = join4(targetDir, layout.rootDir, "settings.local.json");
14265
+ const settingsPath = join5(targetDir, layout.rootDir, "settings.local.json");
14014
14266
  const statusLineConfig = {
14015
14267
  statusLine: {
14016
14268
  type: "command",
@@ -14058,13 +14310,30 @@ async function install(options) {
14058
14310
  try {
14059
14311
  info("install.start", { targetDir: options.targetDir });
14060
14312
  await ensureTargetDirectory(options.targetDir);
14061
- await handleBackup(options.targetDir, !!options.backup, result);
14313
+ const preservation = await handleBackup(options.targetDir, !!options.backup, result);
14062
14314
  await checkAndWarnExisting(options.targetDir, !!options.force, !!options.backup, result);
14063
14315
  await verifyTemplateDirectory();
14064
14316
  await installAllComponents(options.targetDir, options, result);
14065
14317
  await installStatusline(options.targetDir, options, result);
14066
14318
  await installSettingsLocal(options.targetDir, result);
14067
14319
  await installEntryDocWithTracking(options.targetDir, options, result);
14320
+ if (preservation) {
14321
+ const layout = getProviderLayout();
14322
+ const rootDir = join5(options.targetDir, layout.rootDir);
14323
+ const restoration = await restoreCriticalFiles(rootDir, preservation);
14324
+ if (restoration.restoredFiles.length > 0 || restoration.restoredDirs.length > 0) {
14325
+ info("install.restored", {
14326
+ files: String(restoration.restoredFiles.length),
14327
+ dirs: String(restoration.restoredDirs.length)
14328
+ });
14329
+ }
14330
+ if (restoration.failures.length > 0) {
14331
+ for (const failure of restoration.failures) {
14332
+ result.warnings.push(`Failed to restore ${failure.path}: ${failure.reason}`);
14333
+ }
14334
+ }
14335
+ await cleanupPreservation(preservation.tempDir);
14336
+ }
14068
14337
  await updateInstallConfig(options.targetDir, options, result.installedComponents);
14069
14338
  result.success = true;
14070
14339
  success("install.success");
@@ -14083,7 +14352,7 @@ async function installComponent(targetDir, component, options) {
14083
14352
  return false;
14084
14353
  }
14085
14354
  const templatePath = getComponentPath(component);
14086
- const destPath = join4(targetDir, templatePath);
14355
+ const destPath = join5(targetDir, templatePath);
14087
14356
  const destExists = await fileExists(destPath);
14088
14357
  if (destExists && !options.force && !options.backup) {
14089
14358
  debug("install.component_skipped", { component });
@@ -14111,7 +14380,7 @@ async function installEntryDoc(targetDir, language, overwrite = false) {
14111
14380
  const layout = getProviderLayout();
14112
14381
  const templateFile = getEntryTemplateName(language);
14113
14382
  const srcPath = resolveTemplatePath(templateFile);
14114
- const destPath = join4(targetDir, layout.entryFile);
14383
+ const destPath = join5(targetDir, layout.entryFile);
14115
14384
  if (!await fileExists(srcPath)) {
14116
14385
  warn("install.entry_md_not_found", { language, path: srcPath, entry: layout.entryFile });
14117
14386
  return false;
@@ -14131,8 +14400,8 @@ async function installEntryDoc(targetDir, language, overwrite = false) {
14131
14400
  return true;
14132
14401
  }
14133
14402
  async function backupExisting(sourcePath, backupDir) {
14134
- const name = basename(sourcePath);
14135
- const backupPath = join4(backupDir, name);
14403
+ const name = basename2(sourcePath);
14404
+ const backupPath = join5(backupDir, name);
14136
14405
  await rename(sourcePath, backupPath);
14137
14406
  return backupPath;
14138
14407
  }
@@ -14141,7 +14410,7 @@ async function checkExistingPaths(targetDir) {
14141
14410
  const pathsToCheck = [layout.entryFile, layout.rootDir, "guides"];
14142
14411
  const existingPaths = [];
14143
14412
  for (const relativePath of pathsToCheck) {
14144
- const fullPath = join4(targetDir, relativePath);
14413
+ const fullPath = join5(targetDir, relativePath);
14145
14414
  if (await fileExists(fullPath)) {
14146
14415
  existingPaths.push(relativePath);
14147
14416
  }
@@ -14155,11 +14424,11 @@ async function backupExistingInstallation(targetDir) {
14155
14424
  return [];
14156
14425
  }
14157
14426
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
14158
- const backupDir = join4(targetDir, `${layout.backupDirPrefix}${timestamp}`);
14427
+ const backupDir = join5(targetDir, `${layout.backupDirPrefix}${timestamp}`);
14159
14428
  await ensureDirectory(backupDir);
14160
14429
  const backedUpPaths = [];
14161
14430
  for (const relativePath of existingPaths) {
14162
- const fullPath = join4(targetDir, relativePath);
14431
+ const fullPath = join5(targetDir, relativePath);
14163
14432
  try {
14164
14433
  const backupPath = await backupExisting(fullPath, backupDir);
14165
14434
  backedUpPaths.push(backupPath);
@@ -14173,14 +14442,15 @@ async function backupExistingInstallation(targetDir) {
14173
14442
  }
14174
14443
 
14175
14444
  // src/core/mcp-config.ts
14445
+ init_fs();
14176
14446
  import { execSync as execSync3 } from "node:child_process";
14177
14447
  import { writeFile } from "node:fs/promises";
14178
- import { join as join5 } from "node:path";
14448
+ import { join as join6 } from "node:path";
14179
14449
  async function generateMCPConfig(targetDir) {
14180
14450
  const layout = getProviderLayout();
14181
- const mcpConfigPath = join5(targetDir, ".mcp.json");
14182
- const ontologyDir = join5(layout.rootDir, "ontology");
14183
- const ontologyExists = await fileExists(join5(targetDir, ontologyDir));
14451
+ const mcpConfigPath = join6(targetDir, ".mcp.json");
14452
+ const ontologyDir = join6(layout.rootDir, "ontology");
14453
+ const ontologyExists = await fileExists(join6(targetDir, ontologyDir));
14184
14454
  if (!ontologyExists) {
14185
14455
  return;
14186
14456
  }
@@ -14234,9 +14504,10 @@ async function checkUvAvailable() {
14234
14504
  }
14235
14505
 
14236
14506
  // src/cli/init.ts
14507
+ init_fs();
14237
14508
  async function checkExistingInstallation(targetDir) {
14238
14509
  const layout = getProviderLayout();
14239
- const rootDir = join6(targetDir, layout.rootDir);
14510
+ const rootDir = join7(targetDir, layout.rootDir);
14240
14511
  return fileExists(rootDir);
14241
14512
  }
14242
14513
  var PROVIDER_SUBDIR_COMPONENTS = new Set([
@@ -14250,13 +14521,13 @@ var PROVIDER_SUBDIR_COMPONENTS = new Set([
14250
14521
  function componentToPath(targetDir, component) {
14251
14522
  if (component === "entry-md") {
14252
14523
  const layout = getProviderLayout();
14253
- return join6(targetDir, layout.entryFile);
14524
+ return join7(targetDir, layout.entryFile);
14254
14525
  }
14255
14526
  if (PROVIDER_SUBDIR_COMPONENTS.has(component)) {
14256
14527
  const layout = getProviderLayout();
14257
- return join6(targetDir, layout.rootDir, component);
14528
+ return join7(targetDir, layout.rootDir, component);
14258
14529
  }
14259
- return join6(targetDir, component);
14530
+ return join7(targetDir, component);
14260
14531
  }
14261
14532
  function buildInstalledPaths(targetDir, components) {
14262
14533
  return components.map((component) => componentToPath(targetDir, component));
@@ -14336,7 +14607,8 @@ async function initCommand(options) {
14336
14607
  }
14337
14608
 
14338
14609
  // src/cli/list.ts
14339
- import { basename as basename2, dirname as dirname3, join as join7, relative as relative2 } from "node:path";
14610
+ import { basename as basename3, dirname as dirname3, join as join8, relative as relative2 } from "node:path";
14611
+ init_fs();
14340
14612
  var ALLOWED_TOP_LEVEL_KEYS = new Set(["name", "type", "description", "version", "category"]);
14341
14613
  function parseKeyValue(line) {
14342
14614
  const colonIndex = line.indexOf(":");
@@ -14382,7 +14654,7 @@ function parseYamlMetadata(content) {
14382
14654
  return result;
14383
14655
  }
14384
14656
  function extractAgentTypeFromFilename(filename) {
14385
- const name = basename2(filename, ".md");
14657
+ const name = basename3(filename, ".md");
14386
14658
  const prefixMap = {
14387
14659
  lang: "language",
14388
14660
  be: "backend",
@@ -14400,17 +14672,17 @@ function extractAgentTypeFromFilename(filename) {
14400
14672
  return prefixMap[prefix] || "unknown";
14401
14673
  }
14402
14674
  function extractSkillCategoryFromPath(skillPath, baseDir, rootDir) {
14403
- const relativePath = relative2(join7(baseDir, rootDir, "skills"), skillPath);
14675
+ const relativePath = relative2(join8(baseDir, rootDir, "skills"), skillPath);
14404
14676
  const parts = relativePath.split("/").filter(Boolean);
14405
14677
  return parts[0] || "unknown";
14406
14678
  }
14407
14679
  function extractGuideCategoryFromPath(guidePath, baseDir) {
14408
- const relativePath = relative2(join7(baseDir, "guides"), guidePath);
14680
+ const relativePath = relative2(join8(baseDir, "guides"), guidePath);
14409
14681
  const parts = relativePath.split("/").filter(Boolean);
14410
14682
  return parts[0] || "unknown";
14411
14683
  }
14412
14684
  function extractRulePriorityFromFilename(filename) {
14413
- const name = basename2(filename, ".md");
14685
+ const name = basename3(filename, ".md");
14414
14686
  const parts = name.split("-");
14415
14687
  return parts[0] || "unknown";
14416
14688
  }
@@ -14499,7 +14771,7 @@ async function tryExtractMarkdownDescription(mdPath, options = {}) {
14499
14771
  }
14500
14772
  }
14501
14773
  async function getAgents(targetDir, rootDir = ".claude", config) {
14502
- const agentsDir = join7(targetDir, rootDir, "agents");
14774
+ const agentsDir = join8(targetDir, rootDir, "agents");
14503
14775
  if (!await fileExists(agentsDir))
14504
14776
  return [];
14505
14777
  try {
@@ -14508,8 +14780,8 @@ async function getAgents(targetDir, rootDir = ".claude", config) {
14508
14780
  const customAgentPaths = new Set(customComponents.filter((c) => c.type === "agent").map((c) => c.path));
14509
14781
  const agentMdFiles = await listFiles(agentsDir, { recursive: false, pattern: "*.md" });
14510
14782
  const agents = await Promise.all(agentMdFiles.map(async (agentMdPath) => {
14511
- const filename = basename2(agentMdPath);
14512
- const name = basename2(filename, ".md");
14783
+ const filename = basename3(agentMdPath);
14784
+ const name = basename3(filename, ".md");
14513
14785
  const description = await tryExtractMarkdownDescription(agentMdPath);
14514
14786
  const relativePath = relative2(targetDir, agentMdPath);
14515
14787
  return {
@@ -14527,7 +14799,7 @@ async function getAgents(targetDir, rootDir = ".claude", config) {
14527
14799
  }
14528
14800
  }
14529
14801
  async function getSkills(targetDir, rootDir = ".claude", config) {
14530
- const skillsDir = join7(targetDir, rootDir, "skills");
14802
+ const skillsDir = join8(targetDir, rootDir, "skills");
14531
14803
  if (!await fileExists(skillsDir))
14532
14804
  return [];
14533
14805
  try {
@@ -14537,11 +14809,11 @@ async function getSkills(targetDir, rootDir = ".claude", config) {
14537
14809
  const skillMdFiles = await listFiles(skillsDir, { recursive: true, pattern: "SKILL.md" });
14538
14810
  const skills = await Promise.all(skillMdFiles.map(async (skillMdPath) => {
14539
14811
  const skillDir = dirname3(skillMdPath);
14540
- const indexYamlPath = join7(skillDir, "index.yaml");
14812
+ const indexYamlPath = join8(skillDir, "index.yaml");
14541
14813
  const { description, version } = await tryReadIndexYamlMetadata(indexYamlPath);
14542
14814
  const relativePath = relative2(targetDir, skillDir);
14543
14815
  return {
14544
- name: basename2(skillDir),
14816
+ name: basename3(skillDir),
14545
14817
  type: "skill",
14546
14818
  category: extractSkillCategoryFromPath(skillDir, targetDir, rootDir),
14547
14819
  path: relativePath,
@@ -14556,7 +14828,7 @@ async function getSkills(targetDir, rootDir = ".claude", config) {
14556
14828
  }
14557
14829
  }
14558
14830
  async function getGuides(targetDir, config) {
14559
- const guidesDir = join7(targetDir, "guides");
14831
+ const guidesDir = join8(targetDir, "guides");
14560
14832
  if (!await fileExists(guidesDir))
14561
14833
  return [];
14562
14834
  try {
@@ -14568,7 +14840,7 @@ async function getGuides(targetDir, config) {
14568
14840
  const description = await tryExtractMarkdownDescription(guideMdPath, { maxLength: 100 });
14569
14841
  const relativePath = relative2(targetDir, guideMdPath);
14570
14842
  return {
14571
- name: basename2(guideMdPath, ".md"),
14843
+ name: basename3(guideMdPath, ".md"),
14572
14844
  type: "guide",
14573
14845
  category: extractGuideCategoryFromPath(guideMdPath, targetDir),
14574
14846
  path: relativePath,
@@ -14583,7 +14855,7 @@ async function getGuides(targetDir, config) {
14583
14855
  }
14584
14856
  var RULE_PRIORITY_ORDER = { MUST: 0, SHOULD: 1, MAY: 2 };
14585
14857
  async function getRules(targetDir, rootDir = ".claude", config) {
14586
- const rulesDir = join7(targetDir, rootDir, "rules");
14858
+ const rulesDir = join8(targetDir, rootDir, "rules");
14587
14859
  if (!await fileExists(rulesDir))
14588
14860
  return [];
14589
14861
  try {
@@ -14592,13 +14864,13 @@ async function getRules(targetDir, rootDir = ".claude", config) {
14592
14864
  const customRulePaths = new Set(customComponents.filter((c) => c.type === "rule").map((c) => c.path));
14593
14865
  const ruleMdFiles = await listFiles(rulesDir, { recursive: false, pattern: "*.md" });
14594
14866
  const rules = await Promise.all(ruleMdFiles.map(async (ruleMdPath) => {
14595
- const filename = basename2(ruleMdPath);
14867
+ const filename = basename3(ruleMdPath);
14596
14868
  const description = await tryExtractMarkdownDescription(ruleMdPath, {
14597
14869
  cleanFormatting: true
14598
14870
  });
14599
14871
  const relativePath = relative2(targetDir, ruleMdPath);
14600
14872
  return {
14601
- name: basename2(ruleMdPath, ".md"),
14873
+ name: basename3(ruleMdPath, ".md"),
14602
14874
  type: extractRulePriorityFromFilename(filename),
14603
14875
  path: relativePath,
14604
14876
  description,
@@ -14655,7 +14927,7 @@ function formatAsJson(components) {
14655
14927
  console.log(JSON.stringify(components, null, 2));
14656
14928
  }
14657
14929
  async function getHooks(targetDir, rootDir = ".claude") {
14658
- const hooksDir = join7(targetDir, rootDir, "hooks");
14930
+ const hooksDir = join8(targetDir, rootDir, "hooks");
14659
14931
  if (!await fileExists(hooksDir))
14660
14932
  return [];
14661
14933
  try {
@@ -14664,7 +14936,7 @@ async function getHooks(targetDir, rootDir = ".claude") {
14664
14936
  const hookYamls = await listFiles(hooksDir, { recursive: true, pattern: "*.yaml" });
14665
14937
  const allFiles = [...hookFiles, ...hookConfigs, ...hookYamls];
14666
14938
  return allFiles.map((hookPath) => ({
14667
- name: basename2(hookPath),
14939
+ name: basename3(hookPath),
14668
14940
  type: "hook",
14669
14941
  path: relative2(targetDir, hookPath)
14670
14942
  })).sort((a, b) => a.name.localeCompare(b.name));
@@ -14673,7 +14945,7 @@ async function getHooks(targetDir, rootDir = ".claude") {
14673
14945
  }
14674
14946
  }
14675
14947
  async function getContexts(targetDir, rootDir = ".claude") {
14676
- const contextsDir = join7(targetDir, rootDir, "contexts");
14948
+ const contextsDir = join8(targetDir, rootDir, "contexts");
14677
14949
  if (!await fileExists(contextsDir))
14678
14950
  return [];
14679
14951
  try {
@@ -14684,7 +14956,7 @@ async function getContexts(targetDir, rootDir = ".claude") {
14684
14956
  const ext = ctxPath.endsWith(".md") ? ".md" : ".yaml";
14685
14957
  const description = ext === ".md" ? await tryExtractMarkdownDescription(ctxPath, { maxLength: 100 }) : undefined;
14686
14958
  return {
14687
- name: basename2(ctxPath, ext),
14959
+ name: basename3(ctxPath, ext),
14688
14960
  type: "context",
14689
14961
  path: relative2(targetDir, ctxPath),
14690
14962
  description
@@ -15062,7 +15334,8 @@ async function securityCommand(_options = {}) {
15062
15334
  }
15063
15335
 
15064
15336
  // src/core/updater.ts
15065
- import { join as join8 } from "node:path";
15337
+ init_fs();
15338
+ import { join as join9 } from "node:path";
15066
15339
 
15067
15340
  // src/core/entry-merger.ts
15068
15341
  var MANAGED_START = "<!-- omcustom:start -->";
@@ -15311,7 +15584,7 @@ function resolveCustomizations(customizations, configPreserveFiles, targetDir) {
15311
15584
  }
15312
15585
  async function updateEntryDoc(targetDir, config, options) {
15313
15586
  const layout = getProviderLayout();
15314
- const entryPath = join8(targetDir, layout.entryFile);
15587
+ const entryPath = join9(targetDir, layout.entryFile);
15315
15588
  const templateName = getEntryTemplateName2(config.language);
15316
15589
  const templatePath = resolveTemplatePath(templateName);
15317
15590
  if (!await fileExists(templatePath)) {
@@ -15445,7 +15718,7 @@ async function updateComponent(targetDir, component, customizations, options, co
15445
15718
  const preservedFiles = [];
15446
15719
  const componentPath = getComponentPath2(component);
15447
15720
  const srcPath = resolveTemplatePath(componentPath);
15448
- const destPath = join8(targetDir, componentPath);
15721
+ const destPath = join9(targetDir, componentPath);
15449
15722
  const customComponents = config.customComponents || [];
15450
15723
  const skipPaths = [];
15451
15724
  if (customizations && !options.forceOverwriteAll) {
@@ -15459,7 +15732,7 @@ async function updateComponent(targetDir, component, customizations, options, co
15459
15732
  }
15460
15733
  }
15461
15734
  const path3 = await import("node:path");
15462
- const normalizedSkipPaths = skipPaths.map((p) => path3.relative(destPath, join8(targetDir, p)));
15735
+ const normalizedSkipPaths = skipPaths.map((p) => path3.relative(destPath, join9(targetDir, p)));
15463
15736
  await copyDirectory(srcPath, destPath, {
15464
15737
  overwrite: true,
15465
15738
  skipPaths: normalizedSkipPaths.length > 0 ? normalizedSkipPaths : undefined
@@ -15479,12 +15752,12 @@ async function syncRootLevelFiles(targetDir, options) {
15479
15752
  const layout = getProviderLayout();
15480
15753
  const synced = [];
15481
15754
  for (const fileName of ROOT_LEVEL_FILES) {
15482
- const srcPath = resolveTemplatePath(join8(layout.rootDir, fileName));
15755
+ const srcPath = resolveTemplatePath(join9(layout.rootDir, fileName));
15483
15756
  if (!await fileExists(srcPath)) {
15484
15757
  continue;
15485
15758
  }
15486
- const destPath = join8(targetDir, layout.rootDir, fileName);
15487
- await ensureDirectory(join8(destPath, ".."));
15759
+ const destPath = join9(targetDir, layout.rootDir, fileName);
15760
+ await ensureDirectory(join9(destPath, ".."));
15488
15761
  await fs3.copyFile(srcPath, destPath);
15489
15762
  if (fileName.endsWith(".sh")) {
15490
15763
  await fs3.chmod(destPath, 493);
@@ -15519,7 +15792,7 @@ async function removeDeprecatedFiles(targetDir, options) {
15519
15792
  });
15520
15793
  continue;
15521
15794
  }
15522
- const fullPath = join8(targetDir, entry.path);
15795
+ const fullPath = join9(targetDir, entry.path);
15523
15796
  if (await fileExists(fullPath)) {
15524
15797
  await fs3.unlink(fullPath);
15525
15798
  removed.push(entry.path);
@@ -15543,26 +15816,26 @@ function getComponentPath2(component) {
15543
15816
  }
15544
15817
  async function backupInstallation(targetDir) {
15545
15818
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
15546
- const backupDir = join8(targetDir, `.omcustom-backup-${timestamp}`);
15819
+ const backupDir = join9(targetDir, `.omcustom-backup-${timestamp}`);
15547
15820
  const fs3 = await import("node:fs/promises");
15548
15821
  await ensureDirectory(backupDir);
15549
15822
  const layout = getProviderLayout();
15550
15823
  const dirsToBackup = [layout.rootDir, "guides"];
15551
15824
  for (const dir2 of dirsToBackup) {
15552
- const srcPath = join8(targetDir, dir2);
15825
+ const srcPath = join9(targetDir, dir2);
15553
15826
  if (await fileExists(srcPath)) {
15554
- const destPath = join8(backupDir, dir2);
15827
+ const destPath = join9(backupDir, dir2);
15555
15828
  await copyDirectory(srcPath, destPath, { overwrite: true });
15556
15829
  }
15557
15830
  }
15558
- const entryPath = join8(targetDir, layout.entryFile);
15831
+ const entryPath = join9(targetDir, layout.entryFile);
15559
15832
  if (await fileExists(entryPath)) {
15560
- await fs3.copyFile(entryPath, join8(backupDir, layout.entryFile));
15833
+ await fs3.copyFile(entryPath, join9(backupDir, layout.entryFile));
15561
15834
  }
15562
15835
  return backupDir;
15563
15836
  }
15564
15837
  async function loadCustomizationManifest(targetDir) {
15565
- const manifestPath = join8(targetDir, CUSTOMIZATION_MANIFEST_FILE);
15838
+ const manifestPath = join9(targetDir, CUSTOMIZATION_MANIFEST_FILE);
15566
15839
  if (await fileExists(manifestPath)) {
15567
15840
  return readJsonFile(manifestPath);
15568
15841
  }