permachine 0.5.0 → 0.5.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.
Files changed (2) hide show
  1. package/dist/cli.js +309 -173
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -6458,6 +6458,142 @@ async function isFileTrackedByGit(filePath, cwd) {
6458
6458
  }
6459
6459
  }
6460
6460
 
6461
+ // src/core/git-hooks.ts
6462
+ import fs3 from "node:fs/promises";
6463
+ import path6 from "node:path";
6464
+ import { exec as exec2 } from "node:child_process";
6465
+ import { promisify as promisify2 } from "node:util";
6466
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
6467
+ var execAsync2 = promisify2(exec2);
6468
+ var __filename2 = fileURLToPath3(import.meta.url);
6469
+ var __dirname2 = path6.dirname(__filename2);
6470
+ var HOOK_NAMES = ["post-checkout", "post-merge", "post-commit"];
6471
+ var HOOKS_DIR = ".permachine/hooks";
6472
+ async function installHooks(options = {}) {
6473
+ const warnings = [];
6474
+ if (!await isGitRepository()) {
6475
+ throw new Error('Not a git repository. Run "git init" first.');
6476
+ }
6477
+ const cwd = process.cwd();
6478
+ const existingHooksPath = await getGitConfig("core.hooksPath");
6479
+ if (existingHooksPath && existingHooksPath !== HOOKS_DIR && !options.legacy) {
6480
+ warnings.push(`Git core.hooksPath is already set to: ${existingHooksPath}`, "Use --legacy flag to install hooks in .git/hooks instead");
6481
+ }
6482
+ const useLegacy = options.legacy || existingHooksPath && existingHooksPath !== HOOKS_DIR;
6483
+ if (useLegacy) {
6484
+ return await installLegacyHooks(warnings);
6485
+ } else {
6486
+ return await installHooksPathMethod(warnings);
6487
+ }
6488
+ }
6489
+ async function installHooksPathMethod(warnings) {
6490
+ const cwd = process.cwd();
6491
+ const hooksDir = path6.join(cwd, HOOKS_DIR);
6492
+ await fs3.mkdir(hooksDir, { recursive: true });
6493
+ let templatesDir = path6.join(__dirname2, "../../templates/hooks");
6494
+ if (!await fileExists2(path6.join(templatesDir, "post-checkout"))) {
6495
+ templatesDir = path6.join(__dirname2, "../templates/hooks");
6496
+ }
6497
+ const installedHooks = [];
6498
+ for (const hookName of HOOK_NAMES) {
6499
+ const templatePath = path6.join(templatesDir, hookName);
6500
+ const hookPath = path6.join(hooksDir, hookName);
6501
+ const content = await fs3.readFile(templatePath, "utf-8");
6502
+ await fs3.writeFile(hookPath, content, { mode: 493 });
6503
+ installedHooks.push(hookName);
6504
+ }
6505
+ await setGitConfig("core.hooksPath", HOOKS_DIR);
6506
+ logger.success(`Installed git hooks via core.hooksPath`);
6507
+ return {
6508
+ method: "hooksPath",
6509
+ hooksInstalled: installedHooks,
6510
+ warnings
6511
+ };
6512
+ }
6513
+ async function installLegacyHooks(warnings) {
6514
+ const cwd = process.cwd();
6515
+ const gitHooksDir = path6.join(cwd, ".git/hooks");
6516
+ const installedHooks = [];
6517
+ for (const hookName of HOOK_NAMES) {
6518
+ const hookPath = path6.join(gitHooksDir, hookName);
6519
+ const backupPath = path6.join(gitHooksDir, `${hookName}.pre-mcs`);
6520
+ const hookExists = await fileExists2(hookPath);
6521
+ if (hookExists) {
6522
+ await fs3.rename(hookPath, backupPath);
6523
+ }
6524
+ const hookContent = `#!/bin/sh
6525
+ # Auto-generated by permachine (legacy mode)
6526
+
6527
+ permachine merge --silent
6528
+
6529
+ # Call original hook if it existed
6530
+ if [ -f "${backupPath}" ]; then
6531
+ "${backupPath}" "$@"
6532
+ fi
6533
+
6534
+ exit 0
6535
+ `;
6536
+ await fs3.writeFile(hookPath, hookContent, { mode: 493 });
6537
+ installedHooks.push(hookName);
6538
+ }
6539
+ logger.success("Installed git hooks via legacy .git/hooks wrapping");
6540
+ return {
6541
+ method: "legacy",
6542
+ hooksInstalled: installedHooks,
6543
+ warnings
6544
+ };
6545
+ }
6546
+ async function uninstallHooks() {
6547
+ const cwd = process.cwd();
6548
+ const hooksPath = await getGitConfig("core.hooksPath");
6549
+ if (hooksPath === HOOKS_DIR) {
6550
+ await execAsync2("git config --unset core.hooksPath");
6551
+ const hooksDir = path6.join(cwd, HOOKS_DIR);
6552
+ await fs3.rm(hooksDir, { recursive: true, force: true });
6553
+ logger.success("Uninstalled git hooks (removed core.hooksPath)");
6554
+ } else {
6555
+ const gitHooksDir = path6.join(cwd, ".git/hooks");
6556
+ for (const hookName of HOOK_NAMES) {
6557
+ const hookPath = path6.join(gitHooksDir, hookName);
6558
+ const backupPath = path6.join(gitHooksDir, `${hookName}.pre-mcs`);
6559
+ if (await fileExists2(hookPath)) {
6560
+ await fs3.unlink(hookPath);
6561
+ }
6562
+ if (await fileExists2(backupPath)) {
6563
+ await fs3.rename(backupPath, hookPath);
6564
+ }
6565
+ }
6566
+ logger.success("Uninstalled git hooks (restored original hooks)");
6567
+ }
6568
+ }
6569
+ async function isGitRepository() {
6570
+ try {
6571
+ await execAsync2("git rev-parse --git-dir");
6572
+ return true;
6573
+ } catch {
6574
+ return false;
6575
+ }
6576
+ }
6577
+ async function getGitConfig(key) {
6578
+ try {
6579
+ const { stdout } = await execAsync2(`git config --get ${key}`);
6580
+ return stdout.trim() || null;
6581
+ } catch {
6582
+ return null;
6583
+ }
6584
+ }
6585
+ async function setGitConfig(key, value) {
6586
+ await execAsync2(`git config ${key} "${value}"`);
6587
+ }
6588
+ async function fileExists2(filePath) {
6589
+ try {
6590
+ await fs3.access(filePath);
6591
+ return true;
6592
+ } catch {
6593
+ return false;
6594
+ }
6595
+ }
6596
+
6461
6597
  // node_modules/chokidar/index.js
6462
6598
  import { EventEmitter as EventEmitter2 } from "node:events";
6463
6599
  import { stat as statcb, Stats } from "node:fs";
@@ -6549,7 +6685,7 @@ class ReaddirpStream extends Readable {
6549
6685
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
6550
6686
  const statMethod = opts.lstat ? lstat2 : stat;
6551
6687
  if (wantBigintFsStats) {
6552
- this._stat = (path6) => statMethod(path6, { bigint: true });
6688
+ this._stat = (path7) => statMethod(path7, { bigint: true });
6553
6689
  } else {
6554
6690
  this._stat = statMethod;
6555
6691
  }
@@ -6574,8 +6710,8 @@ class ReaddirpStream extends Readable {
6574
6710
  const par = this.parent;
6575
6711
  const fil = par && par.files;
6576
6712
  if (fil && fil.length > 0) {
6577
- const { path: path6, depth } = par;
6578
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path6));
6713
+ const { path: path7, depth } = par;
6714
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path7));
6579
6715
  const awaited = await Promise.all(slice);
6580
6716
  for (const entry of awaited) {
6581
6717
  if (!entry)
@@ -6615,20 +6751,20 @@ class ReaddirpStream extends Readable {
6615
6751
  this.reading = false;
6616
6752
  }
6617
6753
  }
6618
- async _exploreDir(path6, depth) {
6754
+ async _exploreDir(path7, depth) {
6619
6755
  let files;
6620
6756
  try {
6621
- files = await readdir2(path6, this._rdOptions);
6757
+ files = await readdir2(path7, this._rdOptions);
6622
6758
  } catch (error) {
6623
6759
  this._onError(error);
6624
6760
  }
6625
- return { files, depth, path: path6 };
6761
+ return { files, depth, path: path7 };
6626
6762
  }
6627
- async _formatEntry(dirent, path6) {
6763
+ async _formatEntry(dirent, path7) {
6628
6764
  let entry;
6629
6765
  const basename = this._isDirent ? dirent.name : dirent;
6630
6766
  try {
6631
- const fullPath = presolve(pjoin(path6, basename));
6767
+ const fullPath = presolve(pjoin(path7, basename));
6632
6768
  entry = { path: prelative(this._root, fullPath), fullPath, basename };
6633
6769
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
6634
6770
  } catch (err) {
@@ -7027,16 +7163,16 @@ var delFromSet = (main, prop, item) => {
7027
7163
  };
7028
7164
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
7029
7165
  var FsWatchInstances = new Map;
7030
- function createFsWatchInstance(path6, options, listener, errHandler, emitRaw) {
7166
+ function createFsWatchInstance(path7, options, listener, errHandler, emitRaw) {
7031
7167
  const handleEvent = (rawEvent, evPath) => {
7032
- listener(path6);
7033
- emitRaw(rawEvent, evPath, { watchedPath: path6 });
7034
- if (evPath && path6 !== evPath) {
7035
- fsWatchBroadcast(sp.resolve(path6, evPath), KEY_LISTENERS, sp.join(path6, evPath));
7168
+ listener(path7);
7169
+ emitRaw(rawEvent, evPath, { watchedPath: path7 });
7170
+ if (evPath && path7 !== evPath) {
7171
+ fsWatchBroadcast(sp.resolve(path7, evPath), KEY_LISTENERS, sp.join(path7, evPath));
7036
7172
  }
7037
7173
  };
7038
7174
  try {
7039
- return fs_watch(path6, {
7175
+ return fs_watch(path7, {
7040
7176
  persistent: options.persistent
7041
7177
  }, handleEvent);
7042
7178
  } catch (error) {
@@ -7052,12 +7188,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
7052
7188
  listener(val1, val2, val3);
7053
7189
  });
7054
7190
  };
7055
- var setFsWatchListener = (path6, fullPath, options, handlers) => {
7191
+ var setFsWatchListener = (path7, fullPath, options, handlers) => {
7056
7192
  const { listener, errHandler, rawEmitter } = handlers;
7057
7193
  let cont = FsWatchInstances.get(fullPath);
7058
7194
  let watcher;
7059
7195
  if (!options.persistent) {
7060
- watcher = createFsWatchInstance(path6, options, listener, errHandler, rawEmitter);
7196
+ watcher = createFsWatchInstance(path7, options, listener, errHandler, rawEmitter);
7061
7197
  if (!watcher)
7062
7198
  return;
7063
7199
  return watcher.close.bind(watcher);
@@ -7067,7 +7203,7 @@ var setFsWatchListener = (path6, fullPath, options, handlers) => {
7067
7203
  addAndConvert(cont, KEY_ERR, errHandler);
7068
7204
  addAndConvert(cont, KEY_RAW, rawEmitter);
7069
7205
  } else {
7070
- watcher = createFsWatchInstance(path6, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
7206
+ watcher = createFsWatchInstance(path7, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
7071
7207
  if (!watcher)
7072
7208
  return;
7073
7209
  watcher.on(EV.ERROR, async (error) => {
@@ -7076,7 +7212,7 @@ var setFsWatchListener = (path6, fullPath, options, handlers) => {
7076
7212
  cont.watcherUnusable = true;
7077
7213
  if (isWindows && error.code === "EPERM") {
7078
7214
  try {
7079
- const fd = await open(path6, "r");
7215
+ const fd = await open(path7, "r");
7080
7216
  await fd.close();
7081
7217
  broadcastErr(error);
7082
7218
  } catch (err) {}
@@ -7106,7 +7242,7 @@ var setFsWatchListener = (path6, fullPath, options, handlers) => {
7106
7242
  };
7107
7243
  };
7108
7244
  var FsWatchFileInstances = new Map;
7109
- var setFsWatchFileListener = (path6, fullPath, options, handlers) => {
7245
+ var setFsWatchFileListener = (path7, fullPath, options, handlers) => {
7110
7246
  const { listener, rawEmitter } = handlers;
7111
7247
  let cont = FsWatchFileInstances.get(fullPath);
7112
7248
  const copts = cont && cont.options;
@@ -7128,7 +7264,7 @@ var setFsWatchFileListener = (path6, fullPath, options, handlers) => {
7128
7264
  });
7129
7265
  const currmtime = curr.mtimeMs;
7130
7266
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
7131
- foreach(cont.listeners, (listener2) => listener2(path6, curr));
7267
+ foreach(cont.listeners, (listener2) => listener2(path7, curr));
7132
7268
  }
7133
7269
  })
7134
7270
  };
@@ -7153,13 +7289,13 @@ class NodeFsHandler {
7153
7289
  this.fsw = fsW;
7154
7290
  this._boundHandleError = (error) => fsW._handleError(error);
7155
7291
  }
7156
- _watchWithNodeFs(path6, listener) {
7292
+ _watchWithNodeFs(path7, listener) {
7157
7293
  const opts = this.fsw.options;
7158
- const directory = sp.dirname(path6);
7159
- const basename2 = sp.basename(path6);
7294
+ const directory = sp.dirname(path7);
7295
+ const basename2 = sp.basename(path7);
7160
7296
  const parent = this.fsw._getWatchedDir(directory);
7161
7297
  parent.add(basename2);
7162
- const absolutePath = sp.resolve(path6);
7298
+ const absolutePath = sp.resolve(path7);
7163
7299
  const options = {
7164
7300
  persistent: opts.persistent
7165
7301
  };
@@ -7169,12 +7305,12 @@ class NodeFsHandler {
7169
7305
  if (opts.usePolling) {
7170
7306
  const enableBin = opts.interval !== opts.binaryInterval;
7171
7307
  options.interval = enableBin && isBinaryPath(basename2) ? opts.binaryInterval : opts.interval;
7172
- closer = setFsWatchFileListener(path6, absolutePath, options, {
7308
+ closer = setFsWatchFileListener(path7, absolutePath, options, {
7173
7309
  listener,
7174
7310
  rawEmitter: this.fsw._emitRaw
7175
7311
  });
7176
7312
  } else {
7177
- closer = setFsWatchListener(path6, absolutePath, options, {
7313
+ closer = setFsWatchListener(path7, absolutePath, options, {
7178
7314
  listener,
7179
7315
  errHandler: this._boundHandleError,
7180
7316
  rawEmitter: this.fsw._emitRaw
@@ -7192,7 +7328,7 @@ class NodeFsHandler {
7192
7328
  let prevStats = stats;
7193
7329
  if (parent.has(basename2))
7194
7330
  return;
7195
- const listener = async (path6, newStats) => {
7331
+ const listener = async (path7, newStats) => {
7196
7332
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
7197
7333
  return;
7198
7334
  if (!newStats || newStats.mtimeMs === 0) {
@@ -7206,11 +7342,11 @@ class NodeFsHandler {
7206
7342
  this.fsw._emit(EV.CHANGE, file, newStats2);
7207
7343
  }
7208
7344
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
7209
- this.fsw._closeFile(path6);
7345
+ this.fsw._closeFile(path7);
7210
7346
  prevStats = newStats2;
7211
7347
  const closer2 = this._watchWithNodeFs(file, listener);
7212
7348
  if (closer2)
7213
- this.fsw._addPathCloser(path6, closer2);
7349
+ this.fsw._addPathCloser(path7, closer2);
7214
7350
  } else {
7215
7351
  prevStats = newStats2;
7216
7352
  }
@@ -7234,7 +7370,7 @@ class NodeFsHandler {
7234
7370
  }
7235
7371
  return closer;
7236
7372
  }
7237
- async _handleSymlink(entry, directory, path6, item) {
7373
+ async _handleSymlink(entry, directory, path7, item) {
7238
7374
  if (this.fsw.closed) {
7239
7375
  return;
7240
7376
  }
@@ -7244,7 +7380,7 @@ class NodeFsHandler {
7244
7380
  this.fsw._incrReadyCount();
7245
7381
  let linkPath;
7246
7382
  try {
7247
- linkPath = await fsrealpath(path6);
7383
+ linkPath = await fsrealpath(path7);
7248
7384
  } catch (e) {
7249
7385
  this.fsw._emitReady();
7250
7386
  return true;
@@ -7254,12 +7390,12 @@ class NodeFsHandler {
7254
7390
  if (dir.has(item)) {
7255
7391
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
7256
7392
  this.fsw._symlinkPaths.set(full, linkPath);
7257
- this.fsw._emit(EV.CHANGE, path6, entry.stats);
7393
+ this.fsw._emit(EV.CHANGE, path7, entry.stats);
7258
7394
  }
7259
7395
  } else {
7260
7396
  dir.add(item);
7261
7397
  this.fsw._symlinkPaths.set(full, linkPath);
7262
- this.fsw._emit(EV.ADD, path6, entry.stats);
7398
+ this.fsw._emit(EV.ADD, path7, entry.stats);
7263
7399
  }
7264
7400
  this.fsw._emitReady();
7265
7401
  return true;
@@ -7289,9 +7425,9 @@ class NodeFsHandler {
7289
7425
  return;
7290
7426
  }
7291
7427
  const item = entry.path;
7292
- let path6 = sp.join(directory, item);
7428
+ let path7 = sp.join(directory, item);
7293
7429
  current.add(item);
7294
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path6, item)) {
7430
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path7, item)) {
7295
7431
  return;
7296
7432
  }
7297
7433
  if (this.fsw.closed) {
@@ -7300,8 +7436,8 @@ class NodeFsHandler {
7300
7436
  }
7301
7437
  if (item === target || !target && !previous.has(item)) {
7302
7438
  this.fsw._incrReadyCount();
7303
- path6 = sp.join(dir, sp.relative(dir, path6));
7304
- this._addToNodeFs(path6, initialAdd, wh, depth + 1);
7439
+ path7 = sp.join(dir, sp.relative(dir, path7));
7440
+ this._addToNodeFs(path7, initialAdd, wh, depth + 1);
7305
7441
  }
7306
7442
  }).on(EV.ERROR, this._boundHandleError);
7307
7443
  return new Promise((resolve2, reject) => {
@@ -7350,13 +7486,13 @@ class NodeFsHandler {
7350
7486
  }
7351
7487
  return closer;
7352
7488
  }
7353
- async _addToNodeFs(path6, initialAdd, priorWh, depth, target) {
7489
+ async _addToNodeFs(path7, initialAdd, priorWh, depth, target) {
7354
7490
  const ready = this.fsw._emitReady;
7355
- if (this.fsw._isIgnored(path6) || this.fsw.closed) {
7491
+ if (this.fsw._isIgnored(path7) || this.fsw.closed) {
7356
7492
  ready();
7357
7493
  return false;
7358
7494
  }
7359
- const wh = this.fsw._getWatchHelpers(path6);
7495
+ const wh = this.fsw._getWatchHelpers(path7);
7360
7496
  if (priorWh) {
7361
7497
  wh.filterPath = (entry) => priorWh.filterPath(entry);
7362
7498
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -7372,8 +7508,8 @@ class NodeFsHandler {
7372
7508
  const follow = this.fsw.options.followSymlinks;
7373
7509
  let closer;
7374
7510
  if (stats.isDirectory()) {
7375
- const absPath = sp.resolve(path6);
7376
- const targetPath = follow ? await fsrealpath(path6) : path6;
7511
+ const absPath = sp.resolve(path7);
7512
+ const targetPath = follow ? await fsrealpath(path7) : path7;
7377
7513
  if (this.fsw.closed)
7378
7514
  return;
7379
7515
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -7383,29 +7519,29 @@ class NodeFsHandler {
7383
7519
  this.fsw._symlinkPaths.set(absPath, targetPath);
7384
7520
  }
7385
7521
  } else if (stats.isSymbolicLink()) {
7386
- const targetPath = follow ? await fsrealpath(path6) : path6;
7522
+ const targetPath = follow ? await fsrealpath(path7) : path7;
7387
7523
  if (this.fsw.closed)
7388
7524
  return;
7389
7525
  const parent = sp.dirname(wh.watchPath);
7390
7526
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
7391
7527
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
7392
- closer = await this._handleDir(parent, stats, initialAdd, depth, path6, wh, targetPath);
7528
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path7, wh, targetPath);
7393
7529
  if (this.fsw.closed)
7394
7530
  return;
7395
7531
  if (targetPath !== undefined) {
7396
- this.fsw._symlinkPaths.set(sp.resolve(path6), targetPath);
7532
+ this.fsw._symlinkPaths.set(sp.resolve(path7), targetPath);
7397
7533
  }
7398
7534
  } else {
7399
7535
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
7400
7536
  }
7401
7537
  ready();
7402
7538
  if (closer)
7403
- this.fsw._addPathCloser(path6, closer);
7539
+ this.fsw._addPathCloser(path7, closer);
7404
7540
  return false;
7405
7541
  } catch (error) {
7406
7542
  if (this.fsw._handleError(error)) {
7407
7543
  ready();
7408
- return path6;
7544
+ return path7;
7409
7545
  }
7410
7546
  }
7411
7547
  }
@@ -7449,24 +7585,24 @@ function createPattern(matcher) {
7449
7585
  }
7450
7586
  return () => false;
7451
7587
  }
7452
- function normalizePath(path6) {
7453
- if (typeof path6 !== "string")
7588
+ function normalizePath(path7) {
7589
+ if (typeof path7 !== "string")
7454
7590
  throw new Error("string expected");
7455
- path6 = sp2.normalize(path6);
7456
- path6 = path6.replace(/\\/g, "/");
7591
+ path7 = sp2.normalize(path7);
7592
+ path7 = path7.replace(/\\/g, "/");
7457
7593
  let prepend = false;
7458
- if (path6.startsWith("//"))
7594
+ if (path7.startsWith("//"))
7459
7595
  prepend = true;
7460
- path6 = path6.replace(DOUBLE_SLASH_RE, "/");
7596
+ path7 = path7.replace(DOUBLE_SLASH_RE, "/");
7461
7597
  if (prepend)
7462
- path6 = "/" + path6;
7463
- return path6;
7598
+ path7 = "/" + path7;
7599
+ return path7;
7464
7600
  }
7465
7601
  function matchPatterns(patterns, testString, stats) {
7466
- const path6 = normalizePath(testString);
7602
+ const path7 = normalizePath(testString);
7467
7603
  for (let index = 0;index < patterns.length; index++) {
7468
7604
  const pattern = patterns[index];
7469
- if (pattern(path6, stats)) {
7605
+ if (pattern(path7, stats)) {
7470
7606
  return true;
7471
7607
  }
7472
7608
  }
@@ -7504,19 +7640,19 @@ var toUnix = (string) => {
7504
7640
  }
7505
7641
  return str;
7506
7642
  };
7507
- var normalizePathToUnix = (path6) => toUnix(sp2.normalize(toUnix(path6)));
7508
- var normalizeIgnored = (cwd = "") => (path6) => {
7509
- if (typeof path6 === "string") {
7510
- return normalizePathToUnix(sp2.isAbsolute(path6) ? path6 : sp2.join(cwd, path6));
7643
+ var normalizePathToUnix = (path7) => toUnix(sp2.normalize(toUnix(path7)));
7644
+ var normalizeIgnored = (cwd = "") => (path7) => {
7645
+ if (typeof path7 === "string") {
7646
+ return normalizePathToUnix(sp2.isAbsolute(path7) ? path7 : sp2.join(cwd, path7));
7511
7647
  } else {
7512
- return path6;
7648
+ return path7;
7513
7649
  }
7514
7650
  };
7515
- var getAbsolutePath = (path6, cwd) => {
7516
- if (sp2.isAbsolute(path6)) {
7517
- return path6;
7651
+ var getAbsolutePath = (path7, cwd) => {
7652
+ if (sp2.isAbsolute(path7)) {
7653
+ return path7;
7518
7654
  }
7519
- return sp2.join(cwd, path6);
7655
+ return sp2.join(cwd, path7);
7520
7656
  };
7521
7657
  var EMPTY_SET = Object.freeze(new Set);
7522
7658
 
@@ -7583,10 +7719,10 @@ class WatchHelper {
7583
7719
  dirParts;
7584
7720
  followSymlinks;
7585
7721
  statMethod;
7586
- constructor(path6, follow, fsw) {
7722
+ constructor(path7, follow, fsw) {
7587
7723
  this.fsw = fsw;
7588
- const watchPath = path6;
7589
- this.path = path6 = path6.replace(REPLACER_RE, "");
7724
+ const watchPath = path7;
7725
+ this.path = path7 = path7.replace(REPLACER_RE, "");
7590
7726
  this.watchPath = watchPath;
7591
7727
  this.fullWatchPath = sp2.resolve(watchPath);
7592
7728
  this.dirParts = [];
@@ -7717,20 +7853,20 @@ class FSWatcher extends EventEmitter2 {
7717
7853
  this._closePromise = undefined;
7718
7854
  let paths = unifyPaths(paths_);
7719
7855
  if (cwd) {
7720
- paths = paths.map((path6) => {
7721
- const absPath = getAbsolutePath(path6, cwd);
7856
+ paths = paths.map((path7) => {
7857
+ const absPath = getAbsolutePath(path7, cwd);
7722
7858
  return absPath;
7723
7859
  });
7724
7860
  }
7725
- paths.forEach((path6) => {
7726
- this._removeIgnoredPath(path6);
7861
+ paths.forEach((path7) => {
7862
+ this._removeIgnoredPath(path7);
7727
7863
  });
7728
7864
  this._userIgnored = undefined;
7729
7865
  if (!this._readyCount)
7730
7866
  this._readyCount = 0;
7731
7867
  this._readyCount += paths.length;
7732
- Promise.all(paths.map(async (path6) => {
7733
- const res = await this._nodeFsHandler._addToNodeFs(path6, !_internal, undefined, 0, _origAdd);
7868
+ Promise.all(paths.map(async (path7) => {
7869
+ const res = await this._nodeFsHandler._addToNodeFs(path7, !_internal, undefined, 0, _origAdd);
7734
7870
  if (res)
7735
7871
  this._emitReady();
7736
7872
  return res;
@@ -7749,17 +7885,17 @@ class FSWatcher extends EventEmitter2 {
7749
7885
  return this;
7750
7886
  const paths = unifyPaths(paths_);
7751
7887
  const { cwd } = this.options;
7752
- paths.forEach((path6) => {
7753
- if (!sp2.isAbsolute(path6) && !this._closers.has(path6)) {
7888
+ paths.forEach((path7) => {
7889
+ if (!sp2.isAbsolute(path7) && !this._closers.has(path7)) {
7754
7890
  if (cwd)
7755
- path6 = sp2.join(cwd, path6);
7756
- path6 = sp2.resolve(path6);
7891
+ path7 = sp2.join(cwd, path7);
7892
+ path7 = sp2.resolve(path7);
7757
7893
  }
7758
- this._closePath(path6);
7759
- this._addIgnoredPath(path6);
7760
- if (this._watched.has(path6)) {
7894
+ this._closePath(path7);
7895
+ this._addIgnoredPath(path7);
7896
+ if (this._watched.has(path7)) {
7761
7897
  this._addIgnoredPath({
7762
- path: path6,
7898
+ path: path7,
7763
7899
  recursive: true
7764
7900
  });
7765
7901
  }
@@ -7808,38 +7944,38 @@ class FSWatcher extends EventEmitter2 {
7808
7944
  if (event !== EVENTS.ERROR)
7809
7945
  this.emit(EVENTS.ALL, event, ...args);
7810
7946
  }
7811
- async _emit(event, path6, stats) {
7947
+ async _emit(event, path7, stats) {
7812
7948
  if (this.closed)
7813
7949
  return;
7814
7950
  const opts = this.options;
7815
7951
  if (isWindows)
7816
- path6 = sp2.normalize(path6);
7952
+ path7 = sp2.normalize(path7);
7817
7953
  if (opts.cwd)
7818
- path6 = sp2.relative(opts.cwd, path6);
7819
- const args = [path6];
7954
+ path7 = sp2.relative(opts.cwd, path7);
7955
+ const args = [path7];
7820
7956
  if (stats != null)
7821
7957
  args.push(stats);
7822
7958
  const awf = opts.awaitWriteFinish;
7823
7959
  let pw;
7824
- if (awf && (pw = this._pendingWrites.get(path6))) {
7960
+ if (awf && (pw = this._pendingWrites.get(path7))) {
7825
7961
  pw.lastChange = new Date;
7826
7962
  return this;
7827
7963
  }
7828
7964
  if (opts.atomic) {
7829
7965
  if (event === EVENTS.UNLINK) {
7830
- this._pendingUnlinks.set(path6, [event, ...args]);
7966
+ this._pendingUnlinks.set(path7, [event, ...args]);
7831
7967
  setTimeout(() => {
7832
- this._pendingUnlinks.forEach((entry, path7) => {
7968
+ this._pendingUnlinks.forEach((entry, path8) => {
7833
7969
  this.emit(...entry);
7834
7970
  this.emit(EVENTS.ALL, ...entry);
7835
- this._pendingUnlinks.delete(path7);
7971
+ this._pendingUnlinks.delete(path8);
7836
7972
  });
7837
7973
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
7838
7974
  return this;
7839
7975
  }
7840
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path6)) {
7976
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path7)) {
7841
7977
  event = EVENTS.CHANGE;
7842
- this._pendingUnlinks.delete(path6);
7978
+ this._pendingUnlinks.delete(path7);
7843
7979
  }
7844
7980
  }
7845
7981
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -7857,16 +7993,16 @@ class FSWatcher extends EventEmitter2 {
7857
7993
  this.emitWithAll(event, args);
7858
7994
  }
7859
7995
  };
7860
- this._awaitWriteFinish(path6, awf.stabilityThreshold, event, awfEmit);
7996
+ this._awaitWriteFinish(path7, awf.stabilityThreshold, event, awfEmit);
7861
7997
  return this;
7862
7998
  }
7863
7999
  if (event === EVENTS.CHANGE) {
7864
- const isThrottled = !this._throttle(EVENTS.CHANGE, path6, 50);
8000
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path7, 50);
7865
8001
  if (isThrottled)
7866
8002
  return this;
7867
8003
  }
7868
8004
  if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
7869
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path6) : path6;
8005
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path7) : path7;
7870
8006
  let stats2;
7871
8007
  try {
7872
8008
  stats2 = await stat3(fullPath);
@@ -7885,23 +8021,23 @@ class FSWatcher extends EventEmitter2 {
7885
8021
  }
7886
8022
  return error || this.closed;
7887
8023
  }
7888
- _throttle(actionType, path6, timeout) {
8024
+ _throttle(actionType, path7, timeout) {
7889
8025
  if (!this._throttled.has(actionType)) {
7890
8026
  this._throttled.set(actionType, new Map);
7891
8027
  }
7892
8028
  const action = this._throttled.get(actionType);
7893
8029
  if (!action)
7894
8030
  throw new Error("invalid throttle");
7895
- const actionPath = action.get(path6);
8031
+ const actionPath = action.get(path7);
7896
8032
  if (actionPath) {
7897
8033
  actionPath.count++;
7898
8034
  return false;
7899
8035
  }
7900
8036
  let timeoutObject;
7901
8037
  const clear = () => {
7902
- const item = action.get(path6);
8038
+ const item = action.get(path7);
7903
8039
  const count = item ? item.count : 0;
7904
- action.delete(path6);
8040
+ action.delete(path7);
7905
8041
  clearTimeout(timeoutObject);
7906
8042
  if (item)
7907
8043
  clearTimeout(item.timeoutObject);
@@ -7909,50 +8045,50 @@ class FSWatcher extends EventEmitter2 {
7909
8045
  };
7910
8046
  timeoutObject = setTimeout(clear, timeout);
7911
8047
  const thr = { timeoutObject, clear, count: 0 };
7912
- action.set(path6, thr);
8048
+ action.set(path7, thr);
7913
8049
  return thr;
7914
8050
  }
7915
8051
  _incrReadyCount() {
7916
8052
  return this._readyCount++;
7917
8053
  }
7918
- _awaitWriteFinish(path6, threshold, event, awfEmit) {
8054
+ _awaitWriteFinish(path7, threshold, event, awfEmit) {
7919
8055
  const awf = this.options.awaitWriteFinish;
7920
8056
  if (typeof awf !== "object")
7921
8057
  return;
7922
8058
  const pollInterval = awf.pollInterval;
7923
8059
  let timeoutHandler;
7924
- let fullPath = path6;
7925
- if (this.options.cwd && !sp2.isAbsolute(path6)) {
7926
- fullPath = sp2.join(this.options.cwd, path6);
8060
+ let fullPath = path7;
8061
+ if (this.options.cwd && !sp2.isAbsolute(path7)) {
8062
+ fullPath = sp2.join(this.options.cwd, path7);
7927
8063
  }
7928
8064
  const now = new Date;
7929
8065
  const writes = this._pendingWrites;
7930
8066
  function awaitWriteFinishFn(prevStat) {
7931
8067
  statcb(fullPath, (err, curStat) => {
7932
- if (err || !writes.has(path6)) {
8068
+ if (err || !writes.has(path7)) {
7933
8069
  if (err && err.code !== "ENOENT")
7934
8070
  awfEmit(err);
7935
8071
  return;
7936
8072
  }
7937
8073
  const now2 = Number(new Date);
7938
8074
  if (prevStat && curStat.size !== prevStat.size) {
7939
- writes.get(path6).lastChange = now2;
8075
+ writes.get(path7).lastChange = now2;
7940
8076
  }
7941
- const pw = writes.get(path6);
8077
+ const pw = writes.get(path7);
7942
8078
  const df = now2 - pw.lastChange;
7943
8079
  if (df >= threshold) {
7944
- writes.delete(path6);
8080
+ writes.delete(path7);
7945
8081
  awfEmit(undefined, curStat);
7946
8082
  } else {
7947
8083
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
7948
8084
  }
7949
8085
  });
7950
8086
  }
7951
- if (!writes.has(path6)) {
7952
- writes.set(path6, {
8087
+ if (!writes.has(path7)) {
8088
+ writes.set(path7, {
7953
8089
  lastChange: now,
7954
8090
  cancelWait: () => {
7955
- writes.delete(path6);
8091
+ writes.delete(path7);
7956
8092
  clearTimeout(timeoutHandler);
7957
8093
  return event;
7958
8094
  }
@@ -7960,8 +8096,8 @@ class FSWatcher extends EventEmitter2 {
7960
8096
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
7961
8097
  }
7962
8098
  }
7963
- _isIgnored(path6, stats) {
7964
- if (this.options.atomic && DOT_RE.test(path6))
8099
+ _isIgnored(path7, stats) {
8100
+ if (this.options.atomic && DOT_RE.test(path7))
7965
8101
  return true;
7966
8102
  if (!this._userIgnored) {
7967
8103
  const { cwd } = this.options;
@@ -7971,13 +8107,13 @@ class FSWatcher extends EventEmitter2 {
7971
8107
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
7972
8108
  this._userIgnored = anymatch(list, undefined);
7973
8109
  }
7974
- return this._userIgnored(path6, stats);
8110
+ return this._userIgnored(path7, stats);
7975
8111
  }
7976
- _isntIgnored(path6, stat4) {
7977
- return !this._isIgnored(path6, stat4);
8112
+ _isntIgnored(path7, stat4) {
8113
+ return !this._isIgnored(path7, stat4);
7978
8114
  }
7979
- _getWatchHelpers(path6) {
7980
- return new WatchHelper(path6, this.options.followSymlinks, this);
8115
+ _getWatchHelpers(path7) {
8116
+ return new WatchHelper(path7, this.options.followSymlinks, this);
7981
8117
  }
7982
8118
  _getWatchedDir(directory) {
7983
8119
  const dir = sp2.resolve(directory);
@@ -7991,57 +8127,57 @@ class FSWatcher extends EventEmitter2 {
7991
8127
  return Boolean(Number(stats.mode) & 256);
7992
8128
  }
7993
8129
  _remove(directory, item, isDirectory) {
7994
- const path6 = sp2.join(directory, item);
7995
- const fullPath = sp2.resolve(path6);
7996
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path6) || this._watched.has(fullPath);
7997
- if (!this._throttle("remove", path6, 100))
8130
+ const path7 = sp2.join(directory, item);
8131
+ const fullPath = sp2.resolve(path7);
8132
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path7) || this._watched.has(fullPath);
8133
+ if (!this._throttle("remove", path7, 100))
7998
8134
  return;
7999
8135
  if (!isDirectory && this._watched.size === 1) {
8000
8136
  this.add(directory, item, true);
8001
8137
  }
8002
- const wp = this._getWatchedDir(path6);
8138
+ const wp = this._getWatchedDir(path7);
8003
8139
  const nestedDirectoryChildren = wp.getChildren();
8004
- nestedDirectoryChildren.forEach((nested) => this._remove(path6, nested));
8140
+ nestedDirectoryChildren.forEach((nested) => this._remove(path7, nested));
8005
8141
  const parent = this._getWatchedDir(directory);
8006
8142
  const wasTracked = parent.has(item);
8007
8143
  parent.remove(item);
8008
8144
  if (this._symlinkPaths.has(fullPath)) {
8009
8145
  this._symlinkPaths.delete(fullPath);
8010
8146
  }
8011
- let relPath = path6;
8147
+ let relPath = path7;
8012
8148
  if (this.options.cwd)
8013
- relPath = sp2.relative(this.options.cwd, path6);
8149
+ relPath = sp2.relative(this.options.cwd, path7);
8014
8150
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
8015
8151
  const event = this._pendingWrites.get(relPath).cancelWait();
8016
8152
  if (event === EVENTS.ADD)
8017
8153
  return;
8018
8154
  }
8019
- this._watched.delete(path6);
8155
+ this._watched.delete(path7);
8020
8156
  this._watched.delete(fullPath);
8021
8157
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
8022
- if (wasTracked && !this._isIgnored(path6))
8023
- this._emit(eventName, path6);
8024
- this._closePath(path6);
8158
+ if (wasTracked && !this._isIgnored(path7))
8159
+ this._emit(eventName, path7);
8160
+ this._closePath(path7);
8025
8161
  }
8026
- _closePath(path6) {
8027
- this._closeFile(path6);
8028
- const dir = sp2.dirname(path6);
8029
- this._getWatchedDir(dir).remove(sp2.basename(path6));
8162
+ _closePath(path7) {
8163
+ this._closeFile(path7);
8164
+ const dir = sp2.dirname(path7);
8165
+ this._getWatchedDir(dir).remove(sp2.basename(path7));
8030
8166
  }
8031
- _closeFile(path6) {
8032
- const closers = this._closers.get(path6);
8167
+ _closeFile(path7) {
8168
+ const closers = this._closers.get(path7);
8033
8169
  if (!closers)
8034
8170
  return;
8035
8171
  closers.forEach((closer) => closer());
8036
- this._closers.delete(path6);
8172
+ this._closers.delete(path7);
8037
8173
  }
8038
- _addPathCloser(path6, closer) {
8174
+ _addPathCloser(path7, closer) {
8039
8175
  if (!closer)
8040
8176
  return;
8041
- let list = this._closers.get(path6);
8177
+ let list = this._closers.get(path7);
8042
8178
  if (!list) {
8043
8179
  list = [];
8044
- this._closers.set(path6, list);
8180
+ this._closers.set(path7, list);
8045
8181
  }
8046
8182
  list.push(closer);
8047
8183
  }
@@ -8071,7 +8207,7 @@ function watch(paths, options = {}) {
8071
8207
  var chokidar_default = { watch, FSWatcher };
8072
8208
 
8073
8209
  // src/core/watcher.ts
8074
- import path6 from "node:path";
8210
+ import path7 from "node:path";
8075
8211
  function formatTime() {
8076
8212
  const now = new Date;
8077
8213
  const hours = String(now.getHours()).padStart(2, "0");
@@ -8104,7 +8240,7 @@ function getWatchPaths(operations) {
8104
8240
  return Array.from(paths);
8105
8241
  }
8106
8242
  async function handleFileChange(changedPath, state, options) {
8107
- const relPath = path6.relative(options.cwd || process.cwd(), changedPath);
8243
+ const relPath = path7.relative(options.cwd || process.cwd(), changedPath);
8108
8244
  if (!logger.isSilent() && !options.verbose) {
8109
8245
  console.log(`[${formatTime()}] Changed: ${relPath}`);
8110
8246
  }
@@ -8118,9 +8254,9 @@ async function handleFileChange(changedPath, state, options) {
8118
8254
  for (const op of affectedOps) {
8119
8255
  const result = await performMerge(op);
8120
8256
  if (result.success && result.changed) {
8121
- const baseFile = op.basePath ? path6.basename(op.basePath) : "";
8122
- const machineFile = path6.basename(op.machinePath);
8123
- const outputFile = path6.basename(op.outputPath);
8257
+ const baseFile = op.basePath ? path7.basename(op.basePath) : "";
8258
+ const machineFile = path7.basename(op.machinePath);
8259
+ const outputFile = path7.basename(op.outputPath);
8124
8260
  if (!logger.isSilent()) {
8125
8261
  if (baseFile) {
8126
8262
  console.log(`[${formatTime()}] Merged ${baseFile} + ${machineFile} → ${outputFile}`);
@@ -8131,7 +8267,7 @@ async function handleFileChange(changedPath, state, options) {
8131
8267
  } else if (!result.success && result.error) {
8132
8268
  logger.error(`Failed to merge: ${result.error.message}`);
8133
8269
  } else if (options.verbose && !result.changed) {
8134
- logger.info(`No changes needed for ${path6.basename(op.outputPath)}`);
8270
+ logger.info(`No changes needed for ${path7.basename(op.outputPath)}`);
8135
8271
  }
8136
8272
  }
8137
8273
  if (!logger.isSilent() && !options.verbose) {
@@ -8162,7 +8298,7 @@ async function startWatcher(machineName, options = {}) {
8162
8298
  if (!logger.isSilent()) {
8163
8299
  console.log(`✓ Watching ${watchPaths.length} file(s) for changes...`);
8164
8300
  for (const watchPath of watchPaths) {
8165
- console.log(` - ${path6.relative(cwd, watchPath)}`);
8301
+ console.log(` - ${path7.relative(cwd, watchPath)}`);
8166
8302
  }
8167
8303
  console.log("");
8168
8304
  }
@@ -8175,9 +8311,9 @@ async function startWatcher(machineName, options = {}) {
8175
8311
  }
8176
8312
  });
8177
8313
  watcher.on("change", (changedPath) => {
8178
- const absolutePath = path6.resolve(cwd, changedPath);
8314
+ const absolutePath = path7.resolve(cwd, changedPath);
8179
8315
  if (options.verbose) {
8180
- logger.info(`File changed: ${path6.relative(cwd, absolutePath)}`);
8316
+ logger.info(`File changed: ${path7.relative(cwd, absolutePath)}`);
8181
8317
  }
8182
8318
  const existingTimer = state.debounceTimers.get(absolutePath);
8183
8319
  if (existingTimer) {
@@ -8190,9 +8326,9 @@ async function startWatcher(machineName, options = {}) {
8190
8326
  state.debounceTimers.set(absolutePath, timer);
8191
8327
  });
8192
8328
  watcher.on("add", async (addedPath) => {
8193
- const absolutePath = path6.resolve(cwd, addedPath);
8329
+ const absolutePath = path7.resolve(cwd, addedPath);
8194
8330
  if (options.verbose) {
8195
- logger.info(`File added: ${path6.relative(cwd, absolutePath)}`);
8331
+ logger.info(`File added: ${path7.relative(cwd, absolutePath)}`);
8196
8332
  }
8197
8333
  const newOperations = await scanForMergeOperations(machineName, cwd);
8198
8334
  state.operations = newOperations;
@@ -8201,7 +8337,7 @@ async function startWatcher(machineName, options = {}) {
8201
8337
  });
8202
8338
  watcher.on("unlink", (deletedPath) => {
8203
8339
  if (options.verbose) {
8204
- const relPath = path6.relative(cwd, deletedPath);
8340
+ const relPath = path7.relative(cwd, deletedPath);
8205
8341
  logger.warn(`File deleted: ${relPath}`);
8206
8342
  logger.info("Run merge manually or restart watch to update operations");
8207
8343
  }
@@ -8222,17 +8358,17 @@ async function startWatcher(machineName, options = {}) {
8222
8358
  }
8223
8359
 
8224
8360
  // src/cli.ts
8225
- import fs3 from "node:fs/promises";
8226
- import path7 from "node:path";
8227
- import { fileURLToPath as fileURLToPath3 } from "node:url";
8361
+ import fs4 from "node:fs/promises";
8362
+ import path8 from "node:path";
8363
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
8228
8364
  import { createInterface } from "node:readline";
8229
- var __filename2 = fileURLToPath3(import.meta.url);
8230
- var __dirname2 = path7.dirname(__filename2);
8365
+ var __filename3 = fileURLToPath4(import.meta.url);
8366
+ var __dirname3 = path8.dirname(__filename3);
8231
8367
  async function checkExistingOutputFiles(operations) {
8232
8368
  const existing = [];
8233
8369
  for (const op of operations) {
8234
8370
  try {
8235
- await fs3.access(op.outputPath);
8371
+ await fs4.access(op.outputPath);
8236
8372
  existing.push(op.outputPath);
8237
8373
  } catch {}
8238
8374
  }
@@ -8243,8 +8379,8 @@ async function checkTrackedOutputFiles(operations) {
8243
8379
  const cwd = process.cwd();
8244
8380
  for (const op of operations) {
8245
8381
  try {
8246
- await fs3.access(op.outputPath);
8247
- const relativePath = path7.relative(cwd, op.outputPath);
8382
+ await fs4.access(op.outputPath);
8383
+ const relativePath = path8.relative(cwd, op.outputPath);
8248
8384
  const isTracked = await isFileTrackedByGit(relativePath, cwd);
8249
8385
  if (isTracked) {
8250
8386
  tracked.push(op.outputPath);
@@ -8324,7 +8460,7 @@ async function handleInit(argv) {
8324
8460
  if (trackedFiles.length > 0 && !argv["no-gitignore"]) {
8325
8461
  logger.warn("⚠️ Warning: The following files will be overwritten and untracked from git:");
8326
8462
  for (const file of trackedFiles) {
8327
- logger.warn(` - ${path7.relative(process.cwd(), file)}`);
8463
+ logger.warn(` - ${path8.relative(process.cwd(), file)}`);
8328
8464
  }
8329
8465
  logger.info("");
8330
8466
  const confirmed = argv.yes || await promptConfirmation("Do you want to continue?");
@@ -8392,7 +8528,7 @@ async function handleMerge(argv) {
8392
8528
  if (trackedFiles.length > 0) {
8393
8529
  logger.warn("⚠️ Warning: The following files will be overwritten and untracked from git:");
8394
8530
  for (const file of trackedFiles) {
8395
- logger.warn(` - ${path7.relative(process.cwd(), file)}`);
8531
+ logger.warn(` - ${path8.relative(process.cwd(), file)}`);
8396
8532
  }
8397
8533
  logger.info("");
8398
8534
  const confirmed = argv.yes || await promptConfirmation("Do you want to continue?");
@@ -8430,11 +8566,11 @@ async function handleInfo(argv) {
8430
8566
  const operations = await scanForMergeOperations(machineName);
8431
8567
  console.log(`Machine name: ${machineName}`);
8432
8568
  console.log(`Repository: ${process.cwd()}`);
8433
- const { exec: exec2 } = await import("node:child_process");
8434
- const { promisify: promisify2 } = await import("node:util");
8435
- const execAsync2 = promisify2(exec2);
8569
+ const { exec: exec3 } = await import("node:child_process");
8570
+ const { promisify: promisify3 } = await import("node:util");
8571
+ const execAsync3 = promisify3(exec3);
8436
8572
  try {
8437
- const { stdout } = await execAsync2("git config --get core.hooksPath");
8573
+ const { stdout } = await execAsync3("git config --get core.hooksPath");
8438
8574
  const hooksPath = stdout.trim();
8439
8575
  if (hooksPath) {
8440
8576
  console.log(`Hooks method: core.hooksPath`);
@@ -8447,9 +8583,9 @@ async function handleInfo(argv) {
8447
8583
  }
8448
8584
  console.log(`Tracked patterns: ${operations.length}`);
8449
8585
  for (const op of operations) {
8450
- const baseName = op.basePath ? path7.basename(op.basePath) : "(none)";
8451
- const machineName2 = path7.basename(op.machinePath);
8452
- const outputName = path7.basename(op.outputPath);
8586
+ const baseName = op.basePath ? path8.basename(op.basePath) : "(none)";
8587
+ const machineName2 = path8.basename(op.machinePath);
8588
+ const outputName = path8.basename(op.outputPath);
8453
8589
  console.log(` - ${baseName} + ${machineName2} → ${outputName}`);
8454
8590
  }
8455
8591
  if (operations.length > 0) {
@@ -8459,7 +8595,7 @@ async function handleInfo(argv) {
8459
8595
  if (existingFiles.length > 0) {
8460
8596
  console.log("Existing output files:");
8461
8597
  for (const file of existingFiles) {
8462
- console.log(` - ${path7.relative(process.cwd(), file)}`);
8598
+ console.log(` - ${path8.relative(process.cwd(), file)}`);
8463
8599
  }
8464
8600
  }
8465
8601
  }
@@ -8542,8 +8678,8 @@ DOCUMENTATION:
8542
8678
  }
8543
8679
  async function showVersion() {
8544
8680
  try {
8545
- const packageJsonPath = path7.join(__dirname2, "../package.json");
8546
- const packageJson = JSON.parse(await fs3.readFile(packageJsonPath, "utf-8"));
8681
+ const packageJsonPath = path8.join(__dirname3, "../package.json");
8682
+ const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
8547
8683
  console.log(packageJson.version);
8548
8684
  } catch {
8549
8685
  console.log("unknown");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "permachine",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Automatically merge machine-specific config files with base configs using git hooks",
5
5
  "type": "module",
6
6
  "bin": {