@alessandroraffa/tangyr 3.0.0 → 3.0.2

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/index.js +760 -604
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1372,8 +1372,8 @@ var require_command = __commonJS({
1372
1372
  "use strict";
1373
1373
  var EventEmitter = __require("events").EventEmitter;
1374
1374
  var childProcess = __require("child_process");
1375
- var path50 = __require("path");
1376
- var fs49 = __require("fs");
1375
+ var path51 = __require("path");
1376
+ var fs50 = __require("fs");
1377
1377
  var process5 = __require("process");
1378
1378
  var { Argument: Argument2, humanReadableArgName } = require_argument();
1379
1379
  var { CommanderError: CommanderError2 } = require_error();
@@ -2367,7 +2367,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2367
2367
  * @param {string} subcommandName
2368
2368
  */
2369
2369
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
2370
- if (fs49.existsSync(executableFile)) return;
2370
+ if (fs50.existsSync(executableFile)) return;
2371
2371
  const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
2372
2372
  const executableMissing = `'${executableFile}' does not exist
2373
2373
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
@@ -2385,11 +2385,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
2385
2385
  let launchWithNode = false;
2386
2386
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
2387
2387
  function findFile(baseDir, baseName) {
2388
- const localBin = path50.resolve(baseDir, baseName);
2389
- if (fs49.existsSync(localBin)) return localBin;
2390
- if (sourceExt.includes(path50.extname(baseName))) return void 0;
2388
+ const localBin = path51.resolve(baseDir, baseName);
2389
+ if (fs50.existsSync(localBin)) return localBin;
2390
+ if (sourceExt.includes(path51.extname(baseName))) return void 0;
2391
2391
  const foundExt = sourceExt.find(
2392
- (ext) => fs49.existsSync(`${localBin}${ext}`)
2392
+ (ext) => fs50.existsSync(`${localBin}${ext}`)
2393
2393
  );
2394
2394
  if (foundExt) return `${localBin}${foundExt}`;
2395
2395
  return void 0;
@@ -2401,21 +2401,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
2401
2401
  if (this._scriptPath) {
2402
2402
  let resolvedScriptPath;
2403
2403
  try {
2404
- resolvedScriptPath = fs49.realpathSync(this._scriptPath);
2404
+ resolvedScriptPath = fs50.realpathSync(this._scriptPath);
2405
2405
  } catch {
2406
2406
  resolvedScriptPath = this._scriptPath;
2407
2407
  }
2408
- executableDir = path50.resolve(
2409
- path50.dirname(resolvedScriptPath),
2408
+ executableDir = path51.resolve(
2409
+ path51.dirname(resolvedScriptPath),
2410
2410
  executableDir
2411
2411
  );
2412
2412
  }
2413
2413
  if (executableDir) {
2414
2414
  let localFile = findFile(executableDir, executableFile);
2415
2415
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
2416
- const legacyName = path50.basename(
2416
+ const legacyName = path51.basename(
2417
2417
  this._scriptPath,
2418
- path50.extname(this._scriptPath)
2418
+ path51.extname(this._scriptPath)
2419
2419
  );
2420
2420
  if (legacyName !== this._name) {
2421
2421
  localFile = findFile(
@@ -2426,7 +2426,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2426
2426
  }
2427
2427
  executableFile = localFile || executableFile;
2428
2428
  }
2429
- launchWithNode = sourceExt.includes(path50.extname(executableFile));
2429
+ launchWithNode = sourceExt.includes(path51.extname(executableFile));
2430
2430
  let proc;
2431
2431
  if (process5.platform !== "win32") {
2432
2432
  if (launchWithNode) {
@@ -3341,7 +3341,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3341
3341
  * @return {Command}
3342
3342
  */
3343
3343
  nameFromFilename(filename) {
3344
- this._name = path50.basename(filename, path50.extname(filename));
3344
+ this._name = path51.basename(filename, path51.extname(filename));
3345
3345
  return this;
3346
3346
  }
3347
3347
  /**
@@ -3355,9 +3355,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
3355
3355
  * @param {string} [path]
3356
3356
  * @return {(string|null|Command)}
3357
3357
  */
3358
- executableDir(path51) {
3359
- if (path51 === void 0) return this._executableDir;
3360
- this._executableDir = path51;
3358
+ executableDir(path52) {
3359
+ if (path52 === void 0) return this._executableDir;
3360
+ this._executableDir = path52;
3361
3361
  return this;
3362
3362
  }
3363
3363
  /**
@@ -3713,17 +3713,17 @@ var require_visit = __commonJS({
3713
3713
  visit.BREAK = BREAK;
3714
3714
  visit.SKIP = SKIP;
3715
3715
  visit.REMOVE = REMOVE;
3716
- function visit_(key, node, visitor, path50) {
3717
- const ctrl = callVisitor(key, node, visitor, path50);
3716
+ function visit_(key, node, visitor, path51) {
3717
+ const ctrl = callVisitor(key, node, visitor, path51);
3718
3718
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3719
- replaceNode(key, path50, ctrl);
3720
- return visit_(key, ctrl, visitor, path50);
3719
+ replaceNode(key, path51, ctrl);
3720
+ return visit_(key, ctrl, visitor, path51);
3721
3721
  }
3722
3722
  if (typeof ctrl !== "symbol") {
3723
3723
  if (identity.isCollection(node)) {
3724
- path50 = Object.freeze(path50.concat(node));
3724
+ path51 = Object.freeze(path51.concat(node));
3725
3725
  for (let i = 0; i < node.items.length; ++i) {
3726
- const ci2 = visit_(i, node.items[i], visitor, path50);
3726
+ const ci2 = visit_(i, node.items[i], visitor, path51);
3727
3727
  if (typeof ci2 === "number")
3728
3728
  i = ci2 - 1;
3729
3729
  else if (ci2 === BREAK)
@@ -3734,13 +3734,13 @@ var require_visit = __commonJS({
3734
3734
  }
3735
3735
  }
3736
3736
  } else if (identity.isPair(node)) {
3737
- path50 = Object.freeze(path50.concat(node));
3738
- const ck = visit_("key", node.key, visitor, path50);
3737
+ path51 = Object.freeze(path51.concat(node));
3738
+ const ck = visit_("key", node.key, visitor, path51);
3739
3739
  if (ck === BREAK)
3740
3740
  return BREAK;
3741
3741
  else if (ck === REMOVE)
3742
3742
  node.key = null;
3743
- const cv = visit_("value", node.value, visitor, path50);
3743
+ const cv = visit_("value", node.value, visitor, path51);
3744
3744
  if (cv === BREAK)
3745
3745
  return BREAK;
3746
3746
  else if (cv === REMOVE)
@@ -3761,17 +3761,17 @@ var require_visit = __commonJS({
3761
3761
  visitAsync.BREAK = BREAK;
3762
3762
  visitAsync.SKIP = SKIP;
3763
3763
  visitAsync.REMOVE = REMOVE;
3764
- async function visitAsync_(key, node, visitor, path50) {
3765
- const ctrl = await callVisitor(key, node, visitor, path50);
3764
+ async function visitAsync_(key, node, visitor, path51) {
3765
+ const ctrl = await callVisitor(key, node, visitor, path51);
3766
3766
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3767
- replaceNode(key, path50, ctrl);
3768
- return visitAsync_(key, ctrl, visitor, path50);
3767
+ replaceNode(key, path51, ctrl);
3768
+ return visitAsync_(key, ctrl, visitor, path51);
3769
3769
  }
3770
3770
  if (typeof ctrl !== "symbol") {
3771
3771
  if (identity.isCollection(node)) {
3772
- path50 = Object.freeze(path50.concat(node));
3772
+ path51 = Object.freeze(path51.concat(node));
3773
3773
  for (let i = 0; i < node.items.length; ++i) {
3774
- const ci2 = await visitAsync_(i, node.items[i], visitor, path50);
3774
+ const ci2 = await visitAsync_(i, node.items[i], visitor, path51);
3775
3775
  if (typeof ci2 === "number")
3776
3776
  i = ci2 - 1;
3777
3777
  else if (ci2 === BREAK)
@@ -3782,13 +3782,13 @@ var require_visit = __commonJS({
3782
3782
  }
3783
3783
  }
3784
3784
  } else if (identity.isPair(node)) {
3785
- path50 = Object.freeze(path50.concat(node));
3786
- const ck = await visitAsync_("key", node.key, visitor, path50);
3785
+ path51 = Object.freeze(path51.concat(node));
3786
+ const ck = await visitAsync_("key", node.key, visitor, path51);
3787
3787
  if (ck === BREAK)
3788
3788
  return BREAK;
3789
3789
  else if (ck === REMOVE)
3790
3790
  node.key = null;
3791
- const cv = await visitAsync_("value", node.value, visitor, path50);
3791
+ const cv = await visitAsync_("value", node.value, visitor, path51);
3792
3792
  if (cv === BREAK)
3793
3793
  return BREAK;
3794
3794
  else if (cv === REMOVE)
@@ -3815,23 +3815,23 @@ var require_visit = __commonJS({
3815
3815
  }
3816
3816
  return visitor;
3817
3817
  }
3818
- function callVisitor(key, node, visitor, path50) {
3818
+ function callVisitor(key, node, visitor, path51) {
3819
3819
  if (typeof visitor === "function")
3820
- return visitor(key, node, path50);
3820
+ return visitor(key, node, path51);
3821
3821
  if (identity.isMap(node))
3822
- return visitor.Map?.(key, node, path50);
3822
+ return visitor.Map?.(key, node, path51);
3823
3823
  if (identity.isSeq(node))
3824
- return visitor.Seq?.(key, node, path50);
3824
+ return visitor.Seq?.(key, node, path51);
3825
3825
  if (identity.isPair(node))
3826
- return visitor.Pair?.(key, node, path50);
3826
+ return visitor.Pair?.(key, node, path51);
3827
3827
  if (identity.isScalar(node))
3828
- return visitor.Scalar?.(key, node, path50);
3828
+ return visitor.Scalar?.(key, node, path51);
3829
3829
  if (identity.isAlias(node))
3830
- return visitor.Alias?.(key, node, path50);
3830
+ return visitor.Alias?.(key, node, path51);
3831
3831
  return void 0;
3832
3832
  }
3833
- function replaceNode(key, path50, node) {
3834
- const parent = path50[path50.length - 1];
3833
+ function replaceNode(key, path51, node) {
3834
+ const parent = path51[path51.length - 1];
3835
3835
  if (identity.isCollection(parent)) {
3836
3836
  parent.items[key] = node;
3837
3837
  } else if (identity.isPair(parent)) {
@@ -4439,10 +4439,10 @@ var require_Collection = __commonJS({
4439
4439
  var createNode = require_createNode();
4440
4440
  var identity = require_identity();
4441
4441
  var Node = require_Node();
4442
- function collectionFromPath(schema, path50, value) {
4442
+ function collectionFromPath(schema, path51, value) {
4443
4443
  let v2 = value;
4444
- for (let i = path50.length - 1; i >= 0; --i) {
4445
- const k2 = path50[i];
4444
+ for (let i = path51.length - 1; i >= 0; --i) {
4445
+ const k2 = path51[i];
4446
4446
  if (typeof k2 === "number" && Number.isInteger(k2) && k2 >= 0) {
4447
4447
  const a = [];
4448
4448
  a[k2] = v2;
@@ -4461,7 +4461,7 @@ var require_Collection = __commonJS({
4461
4461
  sourceObjects: /* @__PURE__ */ new Map()
4462
4462
  });
4463
4463
  }
4464
- var isEmptyPath = (path50) => path50 == null || typeof path50 === "object" && !!path50[Symbol.iterator]().next().done;
4464
+ var isEmptyPath = (path51) => path51 == null || typeof path51 === "object" && !!path51[Symbol.iterator]().next().done;
4465
4465
  var Collection = class extends Node.NodeBase {
4466
4466
  constructor(type, schema) {
4467
4467
  super(type);
@@ -4491,11 +4491,11 @@ var require_Collection = __commonJS({
4491
4491
  * be a Pair instance or a `{ key, value }` object, which may not have a key
4492
4492
  * that already exists in the map.
4493
4493
  */
4494
- addIn(path50, value) {
4495
- if (isEmptyPath(path50))
4494
+ addIn(path51, value) {
4495
+ if (isEmptyPath(path51))
4496
4496
  this.add(value);
4497
4497
  else {
4498
- const [key, ...rest] = path50;
4498
+ const [key, ...rest] = path51;
4499
4499
  const node = this.get(key, true);
4500
4500
  if (identity.isCollection(node))
4501
4501
  node.addIn(rest, value);
@@ -4509,8 +4509,8 @@ var require_Collection = __commonJS({
4509
4509
  * Removes a value from the collection.
4510
4510
  * @returns `true` if the item was found and removed.
4511
4511
  */
4512
- deleteIn(path50) {
4513
- const [key, ...rest] = path50;
4512
+ deleteIn(path51) {
4513
+ const [key, ...rest] = path51;
4514
4514
  if (rest.length === 0)
4515
4515
  return this.delete(key);
4516
4516
  const node = this.get(key, true);
@@ -4524,8 +4524,8 @@ var require_Collection = __commonJS({
4524
4524
  * scalar values from their surrounding node; to disable set `keepScalar` to
4525
4525
  * `true` (collections are always returned intact).
4526
4526
  */
4527
- getIn(path50, keepScalar) {
4528
- const [key, ...rest] = path50;
4527
+ getIn(path51, keepScalar) {
4528
+ const [key, ...rest] = path51;
4529
4529
  const node = this.get(key, true);
4530
4530
  if (rest.length === 0)
4531
4531
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -4543,8 +4543,8 @@ var require_Collection = __commonJS({
4543
4543
  /**
4544
4544
  * Checks if the collection includes a value with the key `key`.
4545
4545
  */
4546
- hasIn(path50) {
4547
- const [key, ...rest] = path50;
4546
+ hasIn(path51) {
4547
+ const [key, ...rest] = path51;
4548
4548
  if (rest.length === 0)
4549
4549
  return this.has(key);
4550
4550
  const node = this.get(key, true);
@@ -4554,8 +4554,8 @@ var require_Collection = __commonJS({
4554
4554
  * Sets a value in this collection. For `!!set`, `value` needs to be a
4555
4555
  * boolean to add/remove the item from the set.
4556
4556
  */
4557
- setIn(path50, value) {
4558
- const [key, ...rest] = path50;
4557
+ setIn(path51, value) {
4558
+ const [key, ...rest] = path51;
4559
4559
  if (rest.length === 0) {
4560
4560
  this.set(key, value);
4561
4561
  } else {
@@ -7067,9 +7067,9 @@ var require_Document = __commonJS({
7067
7067
  this.contents.add(value);
7068
7068
  }
7069
7069
  /** Adds a value to the document. */
7070
- addIn(path50, value) {
7070
+ addIn(path51, value) {
7071
7071
  if (assertCollection(this.contents))
7072
- this.contents.addIn(path50, value);
7072
+ this.contents.addIn(path51, value);
7073
7073
  }
7074
7074
  /**
7075
7075
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -7144,14 +7144,14 @@ var require_Document = __commonJS({
7144
7144
  * Removes a value from the document.
7145
7145
  * @returns `true` if the item was found and removed.
7146
7146
  */
7147
- deleteIn(path50) {
7148
- if (Collection.isEmptyPath(path50)) {
7147
+ deleteIn(path51) {
7148
+ if (Collection.isEmptyPath(path51)) {
7149
7149
  if (this.contents == null)
7150
7150
  return false;
7151
7151
  this.contents = null;
7152
7152
  return true;
7153
7153
  }
7154
- return assertCollection(this.contents) ? this.contents.deleteIn(path50) : false;
7154
+ return assertCollection(this.contents) ? this.contents.deleteIn(path51) : false;
7155
7155
  }
7156
7156
  /**
7157
7157
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -7166,10 +7166,10 @@ var require_Document = __commonJS({
7166
7166
  * scalar values from their surrounding node; to disable set `keepScalar` to
7167
7167
  * `true` (collections are always returned intact).
7168
7168
  */
7169
- getIn(path50, keepScalar) {
7170
- if (Collection.isEmptyPath(path50))
7169
+ getIn(path51, keepScalar) {
7170
+ if (Collection.isEmptyPath(path51))
7171
7171
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
7172
- return identity.isCollection(this.contents) ? this.contents.getIn(path50, keepScalar) : void 0;
7172
+ return identity.isCollection(this.contents) ? this.contents.getIn(path51, keepScalar) : void 0;
7173
7173
  }
7174
7174
  /**
7175
7175
  * Checks if the document includes a value with the key `key`.
@@ -7180,10 +7180,10 @@ var require_Document = __commonJS({
7180
7180
  /**
7181
7181
  * Checks if the document includes a value at `path`.
7182
7182
  */
7183
- hasIn(path50) {
7184
- if (Collection.isEmptyPath(path50))
7183
+ hasIn(path51) {
7184
+ if (Collection.isEmptyPath(path51))
7185
7185
  return this.contents !== void 0;
7186
- return identity.isCollection(this.contents) ? this.contents.hasIn(path50) : false;
7186
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path51) : false;
7187
7187
  }
7188
7188
  /**
7189
7189
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -7200,13 +7200,13 @@ var require_Document = __commonJS({
7200
7200
  * Sets a value in this document. For `!!set`, `value` needs to be a
7201
7201
  * boolean to add/remove the item from the set.
7202
7202
  */
7203
- setIn(path50, value) {
7204
- if (Collection.isEmptyPath(path50)) {
7203
+ setIn(path51, value) {
7204
+ if (Collection.isEmptyPath(path51)) {
7205
7205
  this.contents = value;
7206
7206
  } else if (this.contents == null) {
7207
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path50), value);
7207
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path51), value);
7208
7208
  } else if (assertCollection(this.contents)) {
7209
- this.contents.setIn(path50, value);
7209
+ this.contents.setIn(path51, value);
7210
7210
  }
7211
7211
  }
7212
7212
  /**
@@ -9163,9 +9163,9 @@ var require_cst_visit = __commonJS({
9163
9163
  visit.BREAK = BREAK;
9164
9164
  visit.SKIP = SKIP;
9165
9165
  visit.REMOVE = REMOVE;
9166
- visit.itemAtPath = (cst, path50) => {
9166
+ visit.itemAtPath = (cst, path51) => {
9167
9167
  let item = cst;
9168
- for (const [field, index] of path50) {
9168
+ for (const [field, index] of path51) {
9169
9169
  const tok = item?.[field];
9170
9170
  if (tok && "items" in tok) {
9171
9171
  item = tok.items[index];
@@ -9174,23 +9174,23 @@ var require_cst_visit = __commonJS({
9174
9174
  }
9175
9175
  return item;
9176
9176
  };
9177
- visit.parentCollection = (cst, path50) => {
9178
- const parent = visit.itemAtPath(cst, path50.slice(0, -1));
9179
- const field = path50[path50.length - 1][0];
9177
+ visit.parentCollection = (cst, path51) => {
9178
+ const parent = visit.itemAtPath(cst, path51.slice(0, -1));
9179
+ const field = path51[path51.length - 1][0];
9180
9180
  const coll = parent?.[field];
9181
9181
  if (coll && "items" in coll)
9182
9182
  return coll;
9183
9183
  throw new Error("Parent collection not found");
9184
9184
  };
9185
- function _visit(path50, item, visitor) {
9186
- let ctrl = visitor(item, path50);
9185
+ function _visit(path51, item, visitor) {
9186
+ let ctrl = visitor(item, path51);
9187
9187
  if (typeof ctrl === "symbol")
9188
9188
  return ctrl;
9189
9189
  for (const field of ["key", "value"]) {
9190
9190
  const token = item[field];
9191
9191
  if (token && "items" in token) {
9192
9192
  for (let i = 0; i < token.items.length; ++i) {
9193
- const ci2 = _visit(Object.freeze(path50.concat([[field, i]])), token.items[i], visitor);
9193
+ const ci2 = _visit(Object.freeze(path51.concat([[field, i]])), token.items[i], visitor);
9194
9194
  if (typeof ci2 === "number")
9195
9195
  i = ci2 - 1;
9196
9196
  else if (ci2 === BREAK)
@@ -9201,10 +9201,10 @@ var require_cst_visit = __commonJS({
9201
9201
  }
9202
9202
  }
9203
9203
  if (typeof ctrl === "function" && field === "key")
9204
- ctrl = ctrl(item, path50);
9204
+ ctrl = ctrl(item, path51);
9205
9205
  }
9206
9206
  }
9207
- return typeof ctrl === "function" ? ctrl(item, path50) : ctrl;
9207
+ return typeof ctrl === "function" ? ctrl(item, path51) : ctrl;
9208
9208
  }
9209
9209
  exports2.visit = visit;
9210
9210
  }
@@ -10489,14 +10489,14 @@ var require_parser = __commonJS({
10489
10489
  case "scalar":
10490
10490
  case "single-quoted-scalar":
10491
10491
  case "double-quoted-scalar": {
10492
- const fs49 = this.flowScalar(this.type);
10492
+ const fs50 = this.flowScalar(this.type);
10493
10493
  if (atNextItem || it2.value) {
10494
- map.items.push({ start, key: fs49, sep: [] });
10494
+ map.items.push({ start, key: fs50, sep: [] });
10495
10495
  this.onKeyLine = true;
10496
10496
  } else if (it2.sep) {
10497
- this.stack.push(fs49);
10497
+ this.stack.push(fs50);
10498
10498
  } else {
10499
- Object.assign(it2, { key: fs49, sep: [] });
10499
+ Object.assign(it2, { key: fs50, sep: [] });
10500
10500
  this.onKeyLine = true;
10501
10501
  }
10502
10502
  return;
@@ -10624,13 +10624,13 @@ var require_parser = __commonJS({
10624
10624
  case "scalar":
10625
10625
  case "single-quoted-scalar":
10626
10626
  case "double-quoted-scalar": {
10627
- const fs49 = this.flowScalar(this.type);
10627
+ const fs50 = this.flowScalar(this.type);
10628
10628
  if (!it2 || it2.value)
10629
- fc.items.push({ start: [], key: fs49, sep: [] });
10629
+ fc.items.push({ start: [], key: fs50, sep: [] });
10630
10630
  else if (it2.sep)
10631
- this.stack.push(fs49);
10631
+ this.stack.push(fs50);
10632
10632
  else
10633
- Object.assign(it2, { key: fs49, sep: [] });
10633
+ Object.assign(it2, { key: fs50, sep: [] });
10634
10634
  return;
10635
10635
  }
10636
10636
  case "flow-map-end":
@@ -16114,6 +16114,12 @@ function addManagedLink(manifest, link) {
16114
16114
  manifest.managedLinks.push(link);
16115
16115
  }
16116
16116
  }
16117
+ function parkConflictingPath(destination, scopePath) {
16118
+ const backupPath = resolveBackupPath(destination, scopePath);
16119
+ fs6.mkdirSync(path6.dirname(backupPath), { recursive: true });
16120
+ fs6.renameSync(destination, backupPath);
16121
+ return backupPath;
16122
+ }
16117
16123
 
16118
16124
  // src/core/exit.ts
16119
16125
  var EXIT_FAILURE = 1;
@@ -25152,8 +25158,8 @@ function toConflictPolicy2(value) {
25152
25158
  }
25153
25159
 
25154
25160
  // src/commands/install.ts
25155
- import fs43 from "fs";
25156
- import path43 from "path";
25161
+ import fs44 from "fs";
25162
+ import path44 from "path";
25157
25163
 
25158
25164
  // src/core/channel-state.ts
25159
25165
  import fs32 from "fs";
@@ -26059,9 +26065,91 @@ function sleep(ms2) {
26059
26065
  });
26060
26066
  }
26061
26067
 
26068
+ // src/core/contested-instructions.ts
26069
+ import fs34 from "fs";
26070
+ import path31 from "path";
26071
+ var FOLDS_RULES_INTO_INSTRUCTIONS = {
26072
+ codex: "its own rules slot takes only exec-policy rules, so guidance rules are folded in",
26073
+ opencode: "it has no rules slot of its own, so every rule is folded in"
26074
+ };
26075
+ function markerTarget(destination) {
26076
+ try {
26077
+ if (fs34.lstatSync(destination).isSymbolicLink()) {
26078
+ return null;
26079
+ }
26080
+ const firstNonEmpty = fs34.readFileSync(destination, "utf8").split("\n").find((line) => line.trim().length > 0) ?? "";
26081
+ return extractProvenanceMarker(firstNonEmpty)?.target ?? null;
26082
+ } catch {
26083
+ return null;
26084
+ }
26085
+ }
26086
+ function findContestedInstructions(instructionsByTarget) {
26087
+ const byPath = /* @__PURE__ */ new Map();
26088
+ for (const [target, destination] of instructionsByTarget) {
26089
+ const resolved = path31.resolve(destination);
26090
+ byPath.set(resolved, [...byPath.get(resolved) ?? [], target]);
26091
+ }
26092
+ const contested = [];
26093
+ for (const [destination, claimants] of byPath) {
26094
+ if (claimants.length < 2) {
26095
+ continue;
26096
+ }
26097
+ const losers = claimants.filter(
26098
+ (target) => target in FOLDS_RULES_INTO_INSTRUCTIONS
26099
+ );
26100
+ contested.push({
26101
+ destination,
26102
+ claimants: [...claimants].sort(),
26103
+ losers: losers.sort(),
26104
+ survivor: markerTarget(destination)
26105
+ });
26106
+ }
26107
+ return contested;
26108
+ }
26109
+ function reportContestedInstructions(instructionsByTarget, kitDeclaresRules, logger) {
26110
+ if (!kitDeclaresRules) {
26111
+ return;
26112
+ }
26113
+ for (const contested of findContestedInstructions(instructionsByTarget)) {
26114
+ if (contested.losers.length === 0) {
26115
+ continue;
26116
+ }
26117
+ logger.warn(
26118
+ `
26119
+ ${contested.destination} is the instructions file for ${contested.claimants.join(", ")} at once, and they write it in turn.`
26120
+ );
26121
+ if (contested.survivor) {
26122
+ logger.warn(` The content on disk is ${contested.survivor}'s.`);
26123
+ }
26124
+ for (const target of contested.losers) {
26125
+ logger.warn(
26126
+ ` ${target} does NOT get its rules: ${FOLDS_RULES_INTO_INSTRUCTIONS[target]}, and that content is overwritten here.`
26127
+ );
26128
+ }
26129
+ logger.warn(
26130
+ ` Give those targets an instructions path of their own, or disable them. Their own rules slot, where they have one, is unaffected.`
26131
+ );
26132
+ }
26133
+ }
26134
+ function instructionsByActiveTarget(tools, scope, projectRoot, mappings) {
26135
+ const byTarget = /* @__PURE__ */ new Map();
26136
+ const resolved = resolveTargetPaths({
26137
+ scope,
26138
+ projectRoot,
26139
+ mappings: mappings.platformPaths
26140
+ });
26141
+ for (const tool of tools) {
26142
+ const instructions = resolved[tool]?.instructions;
26143
+ if (typeof instructions === "string" && instructions.length > 0) {
26144
+ byTarget.set(tool, instructions);
26145
+ }
26146
+ }
26147
+ return byTarget;
26148
+ }
26149
+
26062
26150
  // src/adapters/claude-code.ts
26063
- import fs36 from "fs";
26064
- import path34 from "path";
26151
+ import fs37 from "fs";
26152
+ import path35 from "path";
26065
26153
 
26066
26154
  // src/core/shim.ts
26067
26155
  import crypto4 from "crypto";
@@ -26083,8 +26171,8 @@ ${SHIM_BODY}`;
26083
26171
  }
26084
26172
 
26085
26173
  // src/core/skills-slot.ts
26086
- import fs34 from "fs";
26087
- import path31 from "path";
26174
+ import fs35 from "fs";
26175
+ import path32 from "path";
26088
26176
  function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
26089
26177
  if (!isSymlinkPath(destination)) {
26090
26178
  return false;
@@ -26097,7 +26185,7 @@ function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
26097
26185
  }
26098
26186
  function syncSkillsSlot(sync) {
26099
26187
  const { source, destination, logger } = sync;
26100
- if (!fs34.existsSync(source)) {
26188
+ if (!fs35.existsSync(source)) {
26101
26189
  return [
26102
26190
  {
26103
26191
  component: "skills",
@@ -26125,7 +26213,7 @@ function syncSkillsSlot(sync) {
26125
26213
  if (isLegacyWholesaleSymlink) {
26126
26214
  for (const name of foreignSkillNames(source, declaredNames)) {
26127
26215
  logger.info(
26128
- `[dry-run] skills: migrate foreign skill ${path31.join(source, name)} -> ${path31.join(destination, name)}`
26216
+ `[dry-run] skills: migrate foreign skill ${path32.join(source, name)} -> ${path32.join(destination, name)}`
26129
26217
  );
26130
26218
  }
26131
26219
  logger.info(
@@ -26133,9 +26221,9 @@ function syncSkillsSlot(sync) {
26133
26221
  );
26134
26222
  }
26135
26223
  for (const name of declaredNames ?? listSkillDirNames(source)) {
26136
- const skillDestination = path31.join(destination, name);
26224
+ const skillDestination = path32.join(destination, name);
26137
26225
  logger.info(
26138
- `[dry-run] skills: symlink ${path31.join(source, name)} -> ${skillDestination}`
26226
+ `[dry-run] skills: symlink ${path32.join(source, name)} -> ${skillDestination}`
26139
26227
  );
26140
26228
  outcomes2.push({
26141
26229
  component: "skills",
@@ -26162,9 +26250,9 @@ function syncSkillsSlot(sync) {
26162
26250
  }
26163
26251
  function syncSingleSkill(sync, name) {
26164
26252
  const { config, sourceRoot, source, destination } = sync;
26165
- const skillSource = path31.join(source, name);
26166
- const skillDestination = path31.join(destination, name);
26167
- if (!fs34.existsSync(skillSource)) {
26253
+ const skillSource = path32.join(source, name);
26254
+ const skillDestination = path32.join(destination, name);
26255
+ if (!fs35.existsSync(skillSource)) {
26168
26256
  return {
26169
26257
  component: "skills",
26170
26258
  status: "skipped",
@@ -26180,29 +26268,29 @@ function syncSingleSkill(sync, name) {
26180
26268
  };
26181
26269
  }
26182
26270
  if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
26183
- fs34.unlinkSync(skillDestination);
26271
+ fs35.unlinkSync(skillDestination);
26184
26272
  } else if (artifactClass === "unmanaged-conflict" && !sync.onUnmanagedConflict(skillDestination)) {
26185
26273
  return { component: "skills", status: "conflict", path: skillDestination };
26186
26274
  } else if (artifactClass === "managed-symlink") {
26187
- fs34.unlinkSync(skillDestination);
26275
+ fs35.unlinkSync(skillDestination);
26188
26276
  }
26189
26277
  createRelativeSymlink(skillSource, skillDestination, "dir");
26190
26278
  return { component: "skills", status: "success", path: skillDestination };
26191
26279
  }
26192
26280
  function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
26193
26281
  const foreignNames = foreignSkillNames(source, declaredNames);
26194
- fs34.unlinkSync(destination);
26282
+ fs35.unlinkSync(destination);
26195
26283
  ensureDir(destination);
26196
26284
  for (const name of foreignNames) {
26197
- const from = path31.join(source, name);
26198
- const to = path31.join(destination, name);
26199
- if (fs34.existsSync(to)) {
26285
+ const from = path32.join(source, name);
26286
+ const to = path32.join(destination, name);
26287
+ if (fs35.existsSync(to)) {
26200
26288
  logger.warn(
26201
26289
  `skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
26202
26290
  );
26203
26291
  continue;
26204
26292
  }
26205
- fs34.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
26293
+ fs35.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
26206
26294
  logger.warn(
26207
26295
  `skills migration: '${name}' is present under the kit's skills/ but is not declared in its manifest. Copied ${from} -> ${to} so the harness can read it. The original is left in the kit deliberately: this command does not modify a kit. Remove ${from} yourself if it does not belong there, or declare it in tangyr-kit.yaml if it does.`
26208
26296
  );
@@ -26216,44 +26304,44 @@ function foreignSkillNames(source, declaredNames) {
26216
26304
  return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
26217
26305
  }
26218
26306
  function listSkillDirNames(dir) {
26219
- if (!fs34.existsSync(dir)) {
26307
+ if (!fs35.existsSync(dir)) {
26220
26308
  return [];
26221
26309
  }
26222
- return fs34.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
26310
+ return fs35.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
26223
26311
  }
26224
26312
  function isSymlinkPath(filePath) {
26225
26313
  try {
26226
- return fs34.lstatSync(filePath).isSymbolicLink();
26314
+ return fs35.lstatSync(filePath).isSymbolicLink();
26227
26315
  } catch {
26228
26316
  return false;
26229
26317
  }
26230
26318
  }
26231
26319
  function isSymlinkTo2(linkPath, source) {
26232
26320
  try {
26233
- return fs34.realpathSync(linkPath) === fs34.realpathSync(source);
26321
+ return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
26234
26322
  } catch {
26235
26323
  return false;
26236
26324
  }
26237
26325
  }
26238
26326
 
26239
26327
  // src/core/hook-scripts.ts
26240
- import path32 from "path";
26328
+ import path33 from "path";
26241
26329
  function hookScriptsDir(bridge, target, projectRoot) {
26242
26330
  const globalBridge = resolveTargetPath("~/.agents/hooks");
26243
- if (path32.resolve(bridge) === path32.resolve(globalBridge)) {
26331
+ if (path33.resolve(bridge) === path33.resolve(globalBridge)) {
26244
26332
  return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
26245
26333
  }
26246
- const relative = path32.relative(projectRoot ?? process.cwd(), bridge);
26247
- const insideProject = !relative.startsWith("..") && !path32.isAbsolute(relative) && relative !== "";
26334
+ const relative = path33.relative(projectRoot ?? process.cwd(), bridge);
26335
+ const insideProject = !relative.startsWith("..") && !path33.isAbsolute(relative) && relative !== "";
26248
26336
  const variable = PROJECT_DIR_VARIABLE[target];
26249
26337
  if (insideProject && variable) {
26250
- const posix = path32.posix.join(
26251
- relative.split(path32.sep).join("/"),
26338
+ const posix = path33.posix.join(
26339
+ relative.split(path33.sep).join("/"),
26252
26340
  "scripts"
26253
26341
  );
26254
26342
  return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
26255
26343
  }
26256
- return { prefix: path32.join(bridge, "scripts"), machineLocal: true };
26344
+ return { prefix: path33.join(bridge, "scripts"), machineLocal: true };
26257
26345
  }
26258
26346
  var PROJECT_DIR_VARIABLE = {
26259
26347
  "claude-code": "$CLAUDE_PROJECT_DIR"
@@ -26263,19 +26351,19 @@ function machineLocalScriptPathNotice(target, prefix) {
26263
26351
  }
26264
26352
 
26265
26353
  // src/core/instructions-source.ts
26266
- import fs35 from "fs";
26267
- import path33 from "path";
26354
+ import fs36 from "fs";
26355
+ import path34 from "path";
26268
26356
  var PORTABLE_INSTRUCTIONS_NAME = "AGENTS.md";
26269
26357
  var InstructionsSourceMissingError = class extends Error {
26270
26358
  constructor(kitRoot, expected, declaredBy) {
26271
26359
  super(
26272
- `${path33.join(kitRoot, expected)}: instructions source not found (declared by ${declaredBy}). To fix: create that file, or point '${declaredBy}' at the file this kit actually carries. With neither declaration, the kit's ${DEFAULT_ENTRYPOINT} or ${PORTABLE_INSTRUCTIONS_NAME} is used.`
26360
+ `${path34.join(kitRoot, expected)}: instructions source not found (declared by ${declaredBy}). To fix: create that file, or point '${declaredBy}' at the file this kit actually carries. With neither declaration, the kit's ${DEFAULT_ENTRYPOINT} or ${PORTABLE_INSTRUCTIONS_NAME} is used.`
26273
26361
  );
26274
26362
  this.name = "InstructionsSourceMissingError";
26275
26363
  }
26276
26364
  };
26277
26365
  function normalizeLabel(kitRoot, file) {
26278
- return path33.relative(kitRoot, file).split(path33.sep).join("/");
26366
+ return path34.relative(kitRoot, file).split(path34.sep).join("/");
26279
26367
  }
26280
26368
  function isExplicitOverride(configured) {
26281
26369
  const normalize = (value) => value.replace(/\\/gu, "/").replace(/^\.\//u, "");
@@ -26284,8 +26372,8 @@ function isExplicitOverride(configured) {
26284
26372
  function resolveInstructionsSource(kitRoot, config) {
26285
26373
  const configured = config.source.instructions;
26286
26374
  if (isExplicitOverride(configured)) {
26287
- const file = path33.resolve(kitRoot, configured);
26288
- if (!fs35.existsSync(file)) {
26375
+ const file = path34.resolve(kitRoot, configured);
26376
+ if (!fs36.existsSync(file)) {
26289
26377
  throw new InstructionsSourceMissingError(
26290
26378
  kitRoot,
26291
26379
  configured,
@@ -26300,8 +26388,8 @@ function resolveInstructionsSource(kitRoot, config) {
26300
26388
  }
26301
26389
  const declared = resolveKitEntrypointName(kitRoot);
26302
26390
  if (declared !== void 0) {
26303
- const file = path33.resolve(kitRoot, declared);
26304
- if (!fs35.existsSync(file)) {
26391
+ const file = path34.resolve(kitRoot, declared);
26392
+ if (!fs36.existsSync(file)) {
26305
26393
  throw new InstructionsSourceMissingError(
26306
26394
  kitRoot,
26307
26395
  declared,
@@ -26315,13 +26403,13 @@ function resolveInstructionsSource(kitRoot, config) {
26315
26403
  };
26316
26404
  }
26317
26405
  for (const name of [DEFAULT_ENTRYPOINT, PORTABLE_INSTRUCTIONS_NAME]) {
26318
- const file = path33.resolve(kitRoot, name);
26319
- if (fs35.existsSync(file)) {
26406
+ const file = path34.resolve(kitRoot, name);
26407
+ if (fs36.existsSync(file)) {
26320
26408
  return { file, label: name, origin: "convention" };
26321
26409
  }
26322
26410
  }
26323
- const legacy = path33.resolve(kitRoot, LEGACY_ENTRYPOINT);
26324
- if (fs35.existsSync(legacy)) {
26411
+ const legacy = path34.resolve(kitRoot, LEGACY_ENTRYPOINT);
26412
+ if (fs36.existsSync(legacy)) {
26325
26413
  return {
26326
26414
  file: legacy,
26327
26415
  label: LEGACY_ENTRYPOINT,
@@ -26333,7 +26421,7 @@ function resolveInstructionsSource(kitRoot, config) {
26333
26421
  }
26334
26422
  function instructionsSourcePath(kitRoot, config) {
26335
26423
  const resolved = resolveInstructionsSource(kitRoot, config);
26336
- return resolved ? resolved.file : path33.resolve(kitRoot, config.source.instructions);
26424
+ return resolved ? resolved.file : path34.resolve(kitRoot, config.source.instructions);
26337
26425
  }
26338
26426
  function instructionsSourceLabel(kitRoot, config) {
26339
26427
  const resolved = resolveInstructionsSource(kitRoot, config);
@@ -26454,7 +26542,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
26454
26542
  if (!shouldSkipComponent(options, "hooks")) {
26455
26543
  outcomes.push(
26456
26544
  syncHookScriptsBridge({
26457
- source: path34.resolve(sourceRoot, config.source.hooks),
26545
+ source: path35.resolve(sourceRoot, config.source.hooks),
26458
26546
  destination: profile.hook_scripts,
26459
26547
  config,
26460
26548
  sourceRoot,
@@ -26506,13 +26594,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
26506
26594
  }
26507
26595
  function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
26508
26596
  if (!mappings.modelTiers.custom_provider) return;
26509
- const agentsDir = path34.join(sourceRoot, config.source.agents);
26510
- if (!fs36.existsSync(agentsDir)) return;
26511
- for (const agentFile of ts(path34.join(agentsDir, "*.md")).sort()) {
26597
+ const agentsDir = path35.join(sourceRoot, config.source.agents);
26598
+ if (!fs37.existsSync(agentsDir)) return;
26599
+ for (const agentFile of ts(path35.join(agentsDir, "*.md")).sort()) {
26512
26600
  const { data } = parseMarkdownFrontmatter(agentFile);
26513
26601
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
26514
26602
  if (hasProvider) {
26515
- const basename = path34.basename(agentFile);
26603
+ const basename = path35.basename(agentFile);
26516
26604
  addLoss(lossReport, "claude-code", "agents", {
26517
26605
  source: `agents/${basename}`,
26518
26606
  fields: [
@@ -26537,7 +26625,7 @@ function shouldSkipComponent(options, component) {
26537
26625
  var SHIM_MANIFEST_KEY = "claude-code/instructions_shim";
26538
26626
  function lstatOrNull(p) {
26539
26627
  try {
26540
- return fs36.lstatSync(p);
26628
+ return fs37.lstatSync(p);
26541
26629
  } catch {
26542
26630
  return null;
26543
26631
  }
@@ -26549,12 +26637,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26549
26637
  if (shimLink?.isSymbolicLink()) {
26550
26638
  backupFile(shimPath, manifest, scopePath);
26551
26639
  writeManifest(scopePath, manifest);
26552
- fs36.unlinkSync(shimPath);
26640
+ fs37.unlinkSync(shimPath);
26553
26641
  logger?.verbose(
26554
26642
  `instructions-shim: replaced an unmanaged symlink at ${shimPath}`
26555
26643
  );
26556
26644
  }
26557
- if (!fs36.existsSync(shimPath)) {
26645
+ if (!fs37.existsSync(shimPath)) {
26558
26646
  addArtifactToManifest(manifest, {
26559
26647
  relativePath: SHIM_MANIFEST_KEY,
26560
26648
  path: shimPath,
@@ -26562,12 +26650,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26562
26650
  origin: "tangyr-managed"
26563
26651
  });
26564
26652
  writeManifest(scopePath, manifest);
26565
- fs36.mkdirSync(path34.dirname(shimPath), { recursive: true });
26566
- fs36.writeFileSync(shimPath, shimContent);
26653
+ fs37.mkdirSync(path35.dirname(shimPath), { recursive: true });
26654
+ fs37.writeFileSync(shimPath, shimContent);
26567
26655
  logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
26568
26656
  return;
26569
26657
  }
26570
- const existing = fs36.readFileSync(shimPath, "utf8");
26658
+ const existing = fs37.readFileSync(shimPath, "utf8");
26571
26659
  const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
26572
26660
  const marker = extractProvenanceMarker(firstNonEmptyLine);
26573
26661
  if (marker !== null && marker.hash === expectedBodyHash) {
@@ -26584,7 +26672,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26584
26672
  }
26585
26673
  backupFile(shimPath, manifest, scopePath);
26586
26674
  writeManifest(scopePath, manifest);
26587
- fs36.writeFileSync(shimPath, shimContent);
26675
+ fs37.writeFileSync(shimPath, shimContent);
26588
26676
  addArtifactToManifest(manifest, {
26589
26677
  relativePath: SHIM_MANIFEST_KEY,
26590
26678
  path: shimPath,
@@ -26594,10 +26682,10 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26594
26682
  logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
26595
26683
  }
26596
26684
  function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
26597
- const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path34.resolve(sourceRoot, config.source[directComponent.sourceKey]);
26685
+ const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path35.resolve(sourceRoot, config.source[directComponent.sourceKey]);
26598
26686
  const sourceLabel = directComponent.sourceKey === "instructions" ? instructionsSourceLabel(sourceRoot, config) : config.source[directComponent.sourceKey];
26599
26687
  const destination = directComponent.destination;
26600
- if (!fs36.existsSync(source)) {
26688
+ if (!fs37.existsSync(source)) {
26601
26689
  return skippedMissingSource(directComponent.component, source);
26602
26690
  }
26603
26691
  if (options.dryRun) {
@@ -26619,7 +26707,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
26619
26707
  };
26620
26708
  }
26621
26709
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
26622
- fs36.unlinkSync(destination);
26710
+ fs37.unlinkSync(destination);
26623
26711
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
26624
26712
  return {
26625
26713
  component: directComponent.component,
@@ -26627,14 +26715,11 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
26627
26715
  path: destination
26628
26716
  };
26629
26717
  } else if (artifactClass === "managed-symlink") {
26630
- fs36.unlinkSync(destination);
26718
+ fs37.unlinkSync(destination);
26631
26719
  } else if (artifactClass === "managed-compiled") {
26632
- logger.warn(
26633
- `${destination}: replacing another target's compiled instructions file with a link to the kit. A target that appends its rules here (opencode has no rules slot of its own) does not get them. Give it its own instructions path, or disable it.`
26634
- );
26635
- fs36.unlinkSync(destination);
26720
+ fs37.unlinkSync(destination);
26636
26721
  }
26637
- ensureDir(path34.dirname(destination));
26722
+ ensureDir(path35.dirname(destination));
26638
26723
  createRelativeSymlink(source, destination, directComponent.type, {
26639
26724
  logger,
26640
26725
  provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
@@ -26654,7 +26739,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
26654
26739
  return syncSkillsSlot({
26655
26740
  config,
26656
26741
  sourceRoot,
26657
- source: path34.resolve(sourceRoot, config.source.skills),
26742
+ source: path35.resolve(sourceRoot, config.source.skills),
26658
26743
  destination,
26659
26744
  dryRun: options.dryRun,
26660
26745
  logger,
@@ -26688,7 +26773,7 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
26688
26773
  destination,
26689
26774
  settings,
26690
26775
  stringifyJson2,
26691
- !fs36.existsSync(destination),
26776
+ !fs37.existsSync(destination),
26692
26777
  logger
26693
26778
  );
26694
26779
  return {
@@ -26698,8 +26783,8 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
26698
26783
  };
26699
26784
  }
26700
26785
  function syncMcp(config, sourceRoot, options, logger, destination) {
26701
- const source = path34.resolve(sourceRoot, config.source.mcp);
26702
- if (!fs36.existsSync(source)) {
26786
+ const source = path35.resolve(sourceRoot, config.source.mcp);
26787
+ if (!fs37.existsSync(source)) {
26703
26788
  return skippedMissingSource("mcp", source);
26704
26789
  }
26705
26790
  if (options.dryRun) {
@@ -26724,7 +26809,7 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
26724
26809
  destination,
26725
26810
  hostConfig,
26726
26811
  stringifyJson2,
26727
- !fs36.existsSync(destination),
26812
+ !fs37.existsSync(destination),
26728
26813
  logger
26729
26814
  );
26730
26815
  return {
@@ -26734,8 +26819,8 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
26734
26819
  };
26735
26820
  }
26736
26821
  function syncSettings(config, sourceRoot, options, logger, destination) {
26737
- const source = path34.resolve(sourceRoot, config.source.settings);
26738
- if (!fs36.existsSync(source)) {
26822
+ const source = path35.resolve(sourceRoot, config.source.settings);
26823
+ if (!fs37.existsSync(source)) {
26739
26824
  return skippedMissingSource("settings", source);
26740
26825
  }
26741
26826
  if (options.dryRun) {
@@ -26753,7 +26838,7 @@ function syncSettings(config, sourceRoot, options, logger, destination) {
26753
26838
  destination,
26754
26839
  settings,
26755
26840
  stringifyJson2,
26756
- !fs36.existsSync(destination),
26841
+ !fs37.existsSync(destination),
26757
26842
  logger
26758
26843
  );
26759
26844
  return {
@@ -26777,13 +26862,22 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
26777
26862
  if (manifest && scopePath) {
26778
26863
  backupFile(destination, manifest, scopePath);
26779
26864
  writeManifest(scopePath, manifest);
26780
- fs36.rmSync(destination, { recursive: true, force: true });
26865
+ fs37.rmSync(destination, { recursive: true, force: true });
26781
26866
  } else {
26782
- fs36.renameSync(destination, `${destination}.bak.${Date.now()}`);
26867
+ const parked = parkConflictingPath(
26868
+ destination,
26869
+ resolveScopePath(
26870
+ options.scope ?? "global",
26871
+ options.scope === "project" ? options.projectRoot : void 0
26872
+ )
26873
+ );
26874
+ logger.warn(
26875
+ `${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
26876
+ );
26783
26877
  }
26784
26878
  return true;
26785
26879
  }
26786
- fs36.rmSync(destination, { recursive: true, force: true });
26880
+ fs37.rmSync(destination, { recursive: true, force: true });
26787
26881
  return true;
26788
26882
  }
26789
26883
  function skippedMissingSource(component, source) {
@@ -26795,16 +26889,16 @@ function skippedMissingSource(component, source) {
26795
26889
  }
26796
26890
  function isSymlinkTo3(linkPath, source) {
26797
26891
  try {
26798
- return fs36.realpathSync(linkPath) === fs36.realpathSync(source);
26892
+ return fs37.realpathSync(linkPath) === fs37.realpathSync(source);
26799
26893
  } catch {
26800
26894
  return false;
26801
26895
  }
26802
26896
  }
26803
26897
  function readJsonObject3(filePath) {
26804
- if (!fs36.existsSync(filePath)) {
26898
+ if (!fs37.existsSync(filePath)) {
26805
26899
  return {};
26806
26900
  }
26807
- const parsed = JSON.parse(fs36.readFileSync(filePath, "utf8"));
26901
+ const parsed = JSON.parse(fs37.readFileSync(filePath, "utf8"));
26808
26902
  return isRecord3(parsed) ? parsed : {};
26809
26903
  }
26810
26904
  function markManaged(value) {
@@ -26831,13 +26925,13 @@ function isRecord3(value) {
26831
26925
  // src/adapters/codex.ts
26832
26926
  var TOML3 = __toESM(require_toml(), 1);
26833
26927
  import crypto6 from "crypto";
26834
- import fs38 from "fs";
26835
- import path37 from "path";
26928
+ import fs39 from "fs";
26929
+ import path38 from "path";
26836
26930
 
26837
26931
  // src/compiler/agents.ts
26838
26932
  var TOML = __toESM(require_toml(), 1);
26839
26933
  var import_yaml8 = __toESM(require_dist(), 1);
26840
- import path35 from "path";
26934
+ import path36 from "path";
26841
26935
  var writeCapabilityClasses = /* @__PURE__ */ new Set(["filesystem-write", "shell-execution"]);
26842
26936
  var copilotToolAliasesByClass = {
26843
26937
  delegation: "agent",
@@ -26849,7 +26943,7 @@ var copilotToolAliasesByClass = {
26849
26943
  };
26850
26944
  function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
26851
26945
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
26852
- const relativeSource = `agents/${path35.basename(sourceFile)}`;
26946
+ const relativeSource = `agents/${path36.basename(sourceFile)}`;
26853
26947
  if (target === "opencode") {
26854
26948
  return compileOpenCodeAgent(
26855
26949
  sourceFile,
@@ -26890,7 +26984,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
26890
26984
  mappings,
26891
26985
  lossReport
26892
26986
  );
26893
- const overlayKey = `agents/${path35.basename(sourceFile, ".md")}.${target}.yaml`;
26987
+ const overlayKey = `agents/${path36.basename(sourceFile, ".md")}.${target}.yaml`;
26894
26988
  const targetFields = {
26895
26989
  ...translated.fields,
26896
26990
  ...extensions[overlayKey] ?? {}
@@ -26924,7 +27018,7 @@ ${TOML.stringify({
26924
27018
  function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
26925
27019
  if (typeof data.description !== "string" || data.description.trim() === "") {
26926
27020
  throw new Error(
26927
- `${path35.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
27021
+ `${path36.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
26928
27022
  );
26929
27023
  }
26930
27024
  const frontmatter = {
@@ -26978,7 +27072,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
26978
27072
  "permission",
26979
27073
  "permission-coarsening"
26980
27074
  ),
26981
- detail: `${path35.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
27075
+ detail: `${path36.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
26982
27076
  }
26983
27077
  ]
26984
27078
  });
@@ -27003,7 +27097,7 @@ ${(0, import_yaml8.stringify)(frontmatter).trim()}
27003
27097
  function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
27004
27098
  if (typeof data.description !== "string" || data.description.trim() === "") {
27005
27099
  throw new Error(
27006
- `${path35.basename(sourceFile)}: Cursor agent requires a non-empty description field`
27100
+ `${path36.basename(sourceFile)}: Cursor agent requires a non-empty description field`
27007
27101
  );
27008
27102
  }
27009
27103
  const frontmatter = {
@@ -27040,7 +27134,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
27040
27134
  "permission",
27041
27135
  "permission-coarsening"
27042
27136
  ),
27043
- detail: `${path35.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
27137
+ detail: `${path36.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
27044
27138
  }
27045
27139
  ]
27046
27140
  });
@@ -27059,7 +27153,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
27059
27153
  "provider",
27060
27154
  "provider-not-representable"
27061
27155
  ),
27062
- detail: `${path35.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
27156
+ detail: `${path36.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
27063
27157
  }
27064
27158
  ]
27065
27159
  });
@@ -27091,7 +27185,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
27091
27185
  "persona",
27092
27186
  "persona-not-representable"
27093
27187
  ),
27094
- detail: `${path35.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
27188
+ detail: `${path36.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
27095
27189
  }
27096
27190
  ]
27097
27191
  });
@@ -27139,7 +27233,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27139
27233
  field,
27140
27234
  "model-not-representable"
27141
27235
  ),
27142
- detail: `${path35.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
27236
+ detail: `${path36.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
27143
27237
  });
27144
27238
  return;
27145
27239
  }
@@ -27157,9 +27251,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27157
27251
  lossReport,
27158
27252
  target,
27159
27253
  "agents",
27160
- `agents/${path35.basename(sourceFile)}`,
27254
+ `agents/${path36.basename(sourceFile)}`,
27161
27255
  "info",
27162
- `${path35.basename(sourceFile)}: ${field} is delivered through another managed surface.`
27256
+ `${path36.basename(sourceFile)}: ${field} is delivered through another managed surface.`
27163
27257
  );
27164
27258
  return;
27165
27259
  }
@@ -27168,7 +27262,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27168
27262
  field,
27169
27263
  action: entryType,
27170
27264
  severity: resolveLossSeverity("agent-field", field, entryType),
27171
- detail: `${path35.basename(sourceFile)}: ${field} has no emitted field for this target.`
27265
+ detail: `${path36.basename(sourceFile)}: ${field} has no emitted field for this target.`
27172
27266
  });
27173
27267
  }
27174
27268
  function mapToolsToCapabilities(value, mappings) {
@@ -27909,9 +28003,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
27909
28003
  }
27910
28004
 
27911
28005
  // src/compiler/rules.ts
27912
- import path36 from "path";
28006
+ import path37 from "path";
27913
28007
  var import_yaml9 = __toESM(require_dist(), 1);
27914
- import fs37 from "fs";
28008
+ import fs38 from "fs";
27915
28009
  function compileRules(sourceRulesDir, target, _mappings, lossReport) {
27916
28010
  if (target === "copilot") {
27917
28011
  addLoss(lossReport, "copilot", "rules", {
@@ -27948,13 +28042,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
27948
28042
  }
27949
28043
  const appendixParts = [];
27950
28044
  const dotRulesFiles = [];
27951
- for (const ruleFile of ts(path36.join(sourceRulesDir, "*.md")).sort()) {
28045
+ for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
27952
28046
  const parsed = parseRule(ruleFile);
27953
- const name = path36.basename(ruleFile, ".md");
28047
+ const name = path37.basename(ruleFile, ".md");
27954
28048
  if (parsed.mode === "exec-policy") {
27955
28049
  dotRulesFiles.push({
27956
28050
  name: `${name}.rules`,
27957
- content: `${formatProvenanceMarker("toml", `rules/${path36.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
28051
+ content: `${formatProvenanceMarker("toml", `rules/${path37.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
27958
28052
  ${parsed.body}`
27959
28053
  });
27960
28054
  continue;
@@ -27963,7 +28057,7 @@ ${parsed.body}`
27963
28057
 
27964
28058
  ${parsed.body.trim()}`);
27965
28059
  addLoss(lossReport, "codex", "rules", {
27966
- source: `rules/${path36.basename(ruleFile)}`,
28060
+ source: `rules/${path37.basename(ruleFile)}`,
27967
28061
  fields: [
27968
28062
  {
27969
28063
  field: "mode",
@@ -27973,7 +28067,7 @@ ${parsed.body.trim()}`);
27973
28067
  "mode",
27974
28068
  "rule-as-instruction"
27975
28069
  ),
27976
- detail: `${path36.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
28070
+ detail: `${path37.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
27977
28071
  }
27978
28072
  ]
27979
28073
  });
@@ -27981,7 +28075,7 @@ ${parsed.body.trim()}`);
27981
28075
  return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
27982
28076
  }
27983
28077
  function parseRule(ruleFile) {
27984
- const content = fs37.readFileSync(ruleFile, "utf8");
28078
+ const content = fs38.readFileSync(ruleFile, "utf8");
27985
28079
  if (!content.startsWith("---\n")) {
27986
28080
  return { mode: "guidance", body: content };
27987
28081
  }
@@ -28005,14 +28099,14 @@ function isRuleMode(value) {
28005
28099
  }
28006
28100
  function compileOpenCodeRules(sourceRulesDir, lossReport) {
28007
28101
  const appendixParts = [];
28008
- for (const ruleFile of ts(path36.join(sourceRulesDir, "*.md")).sort()) {
28102
+ for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
28009
28103
  const parsed = parseRule(ruleFile);
28010
- const name = path36.basename(ruleFile, ".md");
28104
+ const name = path37.basename(ruleFile, ".md");
28011
28105
  appendixParts.push(`## ${name}
28012
28106
 
28013
28107
  ${parsed.body.trim()}`);
28014
28108
  addLoss(lossReport, "opencode", "rules", {
28015
- source: `rules/${path36.basename(ruleFile)}`,
28109
+ source: `rules/${path37.basename(ruleFile)}`,
28016
28110
  fields: [
28017
28111
  {
28018
28112
  field: "rule",
@@ -28022,7 +28116,7 @@ ${parsed.body.trim()}`);
28022
28116
  "rule",
28023
28117
  "rule-path-scoping"
28024
28118
  ),
28025
- detail: `${path36.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
28119
+ detail: `${path37.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
28026
28120
  }
28027
28121
  ]
28028
28122
  });
@@ -28031,9 +28125,9 @@ ${parsed.body.trim()}`);
28031
28125
  }
28032
28126
  function compileCursorRules(sourceRulesDir, _lossReport) {
28033
28127
  const dotRulesFiles = [];
28034
- for (const ruleFile of ts(path36.join(sourceRulesDir, "*.md")).sort()) {
28035
- const content = fs37.readFileSync(ruleFile, "utf8");
28036
- const name = path36.basename(ruleFile, ".md");
28128
+ for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
28129
+ const content = fs38.readFileSync(ruleFile, "utf8");
28130
+ const name = path37.basename(ruleFile, ".md");
28037
28131
  let frontmatterData = {};
28038
28132
  let body = content;
28039
28133
  if (content.startsWith("---\n")) {
@@ -28062,7 +28156,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
28062
28156
  }
28063
28157
  const marker = formatProvenanceMarker(
28064
28158
  "markdown",
28065
- `rules/${path36.basename(ruleFile)}`,
28159
+ `rules/${path37.basename(ruleFile)}`,
28066
28160
  computeSourceHash(ruleFile),
28067
28161
  "cursor"
28068
28162
  );
@@ -28078,9 +28172,9 @@ ${body}`;
28078
28172
  }
28079
28173
  function compileClineRules(sourceRulesDir, lossReport) {
28080
28174
  const dotRulesFiles = [];
28081
- for (const ruleFile of ts(path36.join(sourceRulesDir, "*.md")).sort()) {
28082
- const content = fs37.readFileSync(ruleFile, "utf8");
28083
- const name = path36.basename(ruleFile, ".md");
28175
+ for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
28176
+ const content = fs38.readFileSync(ruleFile, "utf8");
28177
+ const name = path37.basename(ruleFile, ".md");
28084
28178
  let frontmatterData = {};
28085
28179
  let body = content;
28086
28180
  if (content.startsWith("---\n")) {
@@ -28097,13 +28191,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
28097
28191
  }
28098
28192
  const marker = formatProvenanceMarker(
28099
28193
  "markdown",
28100
- `rules/${path36.basename(ruleFile)}`,
28194
+ `rules/${path37.basename(ruleFile)}`,
28101
28195
  computeSourceHash(ruleFile),
28102
28196
  "cline"
28103
28197
  );
28104
28198
  if (frontmatterData.mode === "exec-policy") {
28105
28199
  addLoss(lossReport, "cline", "rules", {
28106
- source: `rules/${path36.basename(ruleFile)}`,
28200
+ source: `rules/${path37.basename(ruleFile)}`,
28107
28201
  fields: [
28108
28202
  {
28109
28203
  field: "mode",
@@ -28113,7 +28207,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
28113
28207
  "mode",
28114
28208
  "rule-mode-downgrade"
28115
28209
  ),
28116
- detail: `${path36.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28210
+ detail: `${path37.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28117
28211
  }
28118
28212
  ]
28119
28213
  });
@@ -28159,7 +28253,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28159
28253
  rules: profile.rules
28160
28254
  };
28161
28255
  const rules = compileRules(
28162
- path37.join(sourceRoot, config.source.rules),
28256
+ path38.join(sourceRoot, config.source.rules),
28163
28257
  "codex",
28164
28258
  mappings,
28165
28259
  lossReport
@@ -28225,7 +28319,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28225
28319
  if (!shouldSkipComponent2(options, "hooks")) {
28226
28320
  outcomes.push(
28227
28321
  syncHookScriptsBridge({
28228
- source: path37.resolve(sourceRoot, config.source.hooks),
28322
+ source: path38.resolve(sourceRoot, config.source.hooks),
28229
28323
  destination: resolveTargetPath(paths.hook_scripts),
28230
28324
  config,
28231
28325
  sourceRoot,
@@ -28324,9 +28418,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28324
28418
  function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
28325
28419
  const cp = mappings.modelTiers.custom_provider;
28326
28420
  if (!cp) return "";
28327
- const agentsDir = path37.join(sourceRoot, config.source.agents);
28328
- if (!fs38.existsSync(agentsDir)) return "";
28329
- const agentFiles = ts(path37.join(agentsDir, "*.md")).sort();
28421
+ const agentsDir = path38.join(sourceRoot, config.source.agents);
28422
+ if (!fs39.existsSync(agentsDir)) return "";
28423
+ const agentFiles = ts(path38.join(agentsDir, "*.md")).sort();
28330
28424
  const hasProviderAgent = agentFiles.some((agentFile) => {
28331
28425
  const { data } = parseMarkdownFrontmatter(agentFile);
28332
28426
  return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
@@ -28391,7 +28485,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
28391
28485
  }
28392
28486
  ];
28393
28487
  for (const ruleFile of rules.dotRulesFiles) {
28394
- const destination = path37.join(rulesRoot, ruleFile.name);
28488
+ const destination = path38.join(rulesRoot, ruleFile.name);
28395
28489
  if (options.dryRun) {
28396
28490
  logger.info(`[dry-run] rules: write ${destination}`);
28397
28491
  outcomes.push({
@@ -28421,16 +28515,16 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
28421
28515
  function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
28422
28516
  const source = instructionsSourcePath(sourceRoot, config);
28423
28517
  const destination = resolveTargetPath(paths.instructions);
28424
- if (!fs38.existsSync(source)) {
28518
+ if (!fs39.existsSync(source)) {
28425
28519
  return skippedMissingSource2("instructions", source);
28426
28520
  }
28427
- const composed = `${fs38.readFileSync(source, "utf8").trim()}
28521
+ const composed = `${fs39.readFileSync(source, "utf8").trim()}
28428
28522
 
28429
28523
  --- tangyr managed rules ---
28430
28524
  ${agentsAppendix}`.trim();
28431
28525
  const marker = formatProvenanceMarker(
28432
28526
  "markdown",
28433
- path37.basename(instructionsSourceLabel(sourceRoot, config)),
28527
+ path38.basename(instructionsSourceLabel(sourceRoot, config)),
28434
28528
  hashString(composed),
28435
28529
  "codex"
28436
28530
  );
@@ -28457,9 +28551,9 @@ ${composed}
28457
28551
  );
28458
28552
  }
28459
28553
  function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
28460
- const source = path37.resolve(sourceRoot, config.source.skills);
28554
+ const source = path38.resolve(sourceRoot, config.source.skills);
28461
28555
  const destination = resolveTargetPath(paths.skills);
28462
- if (!fs38.existsSync(source)) {
28556
+ if (!fs39.existsSync(source)) {
28463
28557
  return skippedMissingSource2("skills", source);
28464
28558
  }
28465
28559
  if (options.dryRun) {
@@ -28475,29 +28569,29 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
28475
28569
  };
28476
28570
  }
28477
28571
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
28478
- fs38.unlinkSync(destination);
28572
+ fs39.unlinkSync(destination);
28479
28573
  logger.verbose(`Skills: created skills path ${destination}`);
28480
28574
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
28481
28575
  return { component: "skills", status: "conflict", path: destination };
28482
28576
  } else if (artifactClass === "managed-symlink") {
28483
- fs38.unlinkSync(destination);
28577
+ fs39.unlinkSync(destination);
28484
28578
  }
28485
- ensureDir(path37.dirname(destination));
28579
+ ensureDir(path38.dirname(destination));
28486
28580
  createRelativeSymlink(source, destination, "dir");
28487
28581
  logger.verbose(`Skills: created skills path ${destination}`);
28488
28582
  return { component: "skills", status: "success", path: destination };
28489
28583
  }
28490
28584
  function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
28491
- const sourceAgentsRoot = path37.join(sourceRoot, config.source.agents);
28492
- if (!fs38.existsSync(sourceAgentsRoot)) {
28585
+ const sourceAgentsRoot = path38.join(sourceRoot, config.source.agents);
28586
+ if (!fs39.existsSync(sourceAgentsRoot)) {
28493
28587
  return [skippedMissingSource2("agents", sourceAgentsRoot)];
28494
28588
  }
28495
- const sourceAgents = ts(path37.join(sourceAgentsRoot, "*.md")).sort();
28589
+ const sourceAgents = ts(path38.join(sourceAgentsRoot, "*.md")).sort();
28496
28590
  const agentsRoot = resolveTargetPath(paths.agents);
28497
28591
  return sourceAgents.map((agentFile) => {
28498
- const destination = path37.join(
28592
+ const destination = path38.join(
28499
28593
  agentsRoot,
28500
- `${path37.basename(agentFile, ".md")}.toml`
28594
+ `${path38.basename(agentFile, ".md")}.toml`
28501
28595
  );
28502
28596
  const compiled = compileAgent(
28503
28597
  agentFile,
@@ -28575,7 +28669,7 @@ function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, lo
28575
28669
  destination,
28576
28670
  hostHooks,
28577
28671
  stringifyJson3,
28578
- !fs38.existsSync(destination),
28672
+ !fs39.existsSync(destination),
28579
28673
  logger
28580
28674
  );
28581
28675
  return {
@@ -28588,7 +28682,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
28588
28682
  const source = resolveMcpSourceFile(sourceRoot, config);
28589
28683
  const sourceLabel = mcpSourceLabel(config);
28590
28684
  const destination = resolveTargetPath(paths.mcp_shared_file);
28591
- if (!fs38.existsSync(source)) {
28685
+ if (!fs39.existsSync(source)) {
28592
28686
  if (providerToml && !options.dryRun) {
28593
28687
  const changed2 = writeTomlManagedSection(
28594
28688
  destination,
@@ -28603,7 +28697,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
28603
28697
  }
28604
28698
  return skippedMissingSource2("mcp", source);
28605
28699
  }
28606
- const sourceMcpJson = JSON.parse(fs38.readFileSync(source, "utf8"));
28700
+ const sourceMcpJson = JSON.parse(fs39.readFileSync(source, "utf8"));
28607
28701
  const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
28608
28702
  const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
28609
28703
  if (options.dryRun) {
@@ -28625,18 +28719,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
28625
28719
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
28626
28720
  return { component, status: "conflict", path: destination };
28627
28721
  }
28628
- ensureDir(path37.dirname(destination));
28722
+ ensureDir(path38.dirname(destination));
28629
28723
  const clearedLink = clearSymlinkAtDestination(destination);
28630
28724
  if (clearedLink !== null) {
28631
28725
  logger.verbose(
28632
28726
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
28633
28727
  );
28634
28728
  }
28635
- fs38.writeFileSync(destination, content);
28729
+ fs39.writeFileSync(destination, content);
28636
28730
  return { component, status: "success", path: destination };
28637
28731
  }
28638
28732
  function writeTomlManagedSection(destination, managedContent, logger) {
28639
- const current = fs38.existsSync(destination) ? fs38.readFileSync(destination, "utf8") : "";
28733
+ const current = fs39.existsSync(destination) ? fs39.readFileSync(destination, "utf8") : "";
28640
28734
  const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
28641
28735
  if (isFirstWrite) {
28642
28736
  logger.warn(
@@ -28652,8 +28746,8 @@ ${managedMcpEnd}
28652
28746
  if (current === next.trimStart()) {
28653
28747
  return false;
28654
28748
  }
28655
- ensureDir(path37.dirname(destination));
28656
- fs38.writeFileSync(destination, next.trimStart());
28749
+ ensureDir(path38.dirname(destination));
28750
+ fs39.writeFileSync(destination, next.trimStart());
28657
28751
  return true;
28658
28752
  }
28659
28753
  function removeManagedTomlSection(content) {
@@ -28679,18 +28773,27 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
28679
28773
  if (manifest && scopePath) {
28680
28774
  backupFile(destination, manifest, scopePath);
28681
28775
  writeManifest(scopePath, manifest);
28682
- fs38.rmSync(destination, { recursive: true, force: true });
28776
+ fs39.rmSync(destination, { recursive: true, force: true });
28683
28777
  } else {
28684
- fs38.renameSync(destination, `${destination}.bak.${Date.now()}`);
28778
+ const parked = parkConflictingPath(
28779
+ destination,
28780
+ resolveScopePath(
28781
+ options.scope ?? "global",
28782
+ options.scope === "project" ? options.projectRoot : void 0
28783
+ )
28784
+ );
28785
+ logger.warn(
28786
+ `${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
28787
+ );
28685
28788
  }
28686
28789
  return true;
28687
28790
  }
28688
- fs38.rmSync(destination, { recursive: true, force: true });
28791
+ fs39.rmSync(destination, { recursive: true, force: true });
28689
28792
  return true;
28690
28793
  }
28691
28794
  function isCompiledCurrent(destination, expectedContent, expectedHash) {
28692
28795
  try {
28693
- const current = fs38.readFileSync(destination, "utf8");
28796
+ const current = fs39.readFileSync(destination, "utf8");
28694
28797
  const marker = extractProvenanceMarker(current);
28695
28798
  return expectedHash ? marker?.hash === expectedHash && marker.target === "codex" && current === expectedContent : current === expectedContent;
28696
28799
  } catch {
@@ -28709,16 +28812,16 @@ function shouldSkipComponent2(options, component) {
28709
28812
  }
28710
28813
  function isSymlinkTo4(linkPath, source) {
28711
28814
  try {
28712
- return fs38.realpathSync(linkPath) === fs38.realpathSync(source);
28815
+ return fs39.realpathSync(linkPath) === fs39.realpathSync(source);
28713
28816
  } catch {
28714
28817
  return false;
28715
28818
  }
28716
28819
  }
28717
28820
  function readJsonObject4(filePath) {
28718
- if (!fs38.existsSync(filePath)) {
28821
+ if (!fs39.existsSync(filePath)) {
28719
28822
  return {};
28720
28823
  }
28721
- const parsed = JSON.parse(fs38.readFileSync(filePath, "utf8"));
28824
+ const parsed = JSON.parse(fs39.readFileSync(filePath, "utf8"));
28722
28825
  return isRecord5(parsed) ? parsed : {};
28723
28826
  }
28724
28827
  function stringifyJson3(value) {
@@ -28734,16 +28837,16 @@ function hashString(value) {
28734
28837
 
28735
28838
  // src/adapters/copilot.ts
28736
28839
  import crypto7 from "crypto";
28737
- import fs39 from "fs";
28738
- import path39 from "path";
28840
+ import fs40 from "fs";
28841
+ import path40 from "path";
28739
28842
 
28740
28843
  // src/compiler/commands.ts
28741
28844
  var import_yaml10 = __toESM(require_dist(), 1);
28742
- import path38 from "path";
28845
+ import path39 from "path";
28743
28846
  function compileCommandPrompt(sourceFile) {
28744
28847
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
28745
- const relativeSource = `commands/${path38.basename(sourceFile)}`;
28746
- const fields = promptFrontmatter(data, path38.basename(sourceFile, ".md"));
28848
+ const relativeSource = `commands/${path39.basename(sourceFile)}`;
28849
+ const fields = promptFrontmatter(data, path39.basename(sourceFile, ".md"));
28747
28850
  const marker = formatProvenanceMarker(
28748
28851
  "markdown",
28749
28852
  relativeSource,
@@ -28858,7 +28961,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
28858
28961
  if (!shouldSkipComponent3(options, "hooks")) {
28859
28962
  outcomes.push(
28860
28963
  syncHookScriptsBridge({
28861
- source: path39.resolve(sourceRoot, config.source.hooks),
28964
+ source: path40.resolve(sourceRoot, config.source.hooks),
28862
28965
  destination: resolveTargetPath(paths.hook_scripts),
28863
28966
  config,
28864
28967
  sourceRoot,
@@ -28939,13 +29042,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
28939
29042
  }
28940
29043
  function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
28941
29044
  if (!mappings.modelTiers.custom_provider) return;
28942
- const agentsDir = path39.join(sourceRoot, config.source.agents);
28943
- if (!fs39.existsSync(agentsDir)) return;
28944
- for (const agentFile of ts(path39.join(agentsDir, "*.md")).sort()) {
29045
+ const agentsDir = path40.join(sourceRoot, config.source.agents);
29046
+ if (!fs40.existsSync(agentsDir)) return;
29047
+ for (const agentFile of ts(path40.join(agentsDir, "*.md")).sort()) {
28945
29048
  const { data } = parseMarkdownFrontmatter(agentFile);
28946
29049
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
28947
29050
  if (hasProvider) {
28948
- const basename = path39.basename(agentFile);
29051
+ const basename = path40.basename(agentFile);
28949
29052
  addLoss(lossReport, "copilot", "agents", {
28950
29053
  source: `agents/${basename}`,
28951
29054
  fields: [
@@ -28971,22 +29074,22 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
28971
29074
  return [{ component: "instructions", status: "skipped", path: message }];
28972
29075
  }
28973
29076
  const source = instructionsSourcePath(sourceRoot, config);
28974
- if (!fs39.existsSync(source)) {
29077
+ if (!fs40.existsSync(source)) {
28975
29078
  return [skippedMissingSource3("instructions", source)];
28976
29079
  }
28977
- const rawContent = fs39.readFileSync(source, "utf8");
29080
+ const rawContent = fs40.readFileSync(source, "utf8");
28978
29081
  const contentHash = hashString2(rawContent);
28979
29082
  const marker = formatProvenanceMarker(
28980
29083
  "markdown",
28981
- path39.basename(instructionsSourceLabel(sourceRoot, config)),
29084
+ path40.basename(instructionsSourceLabel(sourceRoot, config)),
28982
29085
  contentHash,
28983
29086
  "copilot"
28984
29087
  );
28985
29088
  const composedContent = `${marker}
28986
29089
  ${rawContent}`;
28987
29090
  const projectRoot = options.projectRoot ?? process.cwd();
28988
- const agentsMdDest = path39.resolve(projectRoot, "AGENTS.md");
28989
- const mirrorDest = path39.resolve(
29091
+ const agentsMdDest = path40.resolve(projectRoot, "AGENTS.md");
29092
+ const mirrorDest = path40.resolve(
28990
29093
  projectRoot,
28991
29094
  ".github",
28992
29095
  "copilot-instructions.md"
@@ -29040,14 +29143,14 @@ function writeInstructionsFile(component, destination, content, contentHash, con
29040
29143
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
29041
29144
  return { component, status: "conflict", path: destination };
29042
29145
  }
29043
- ensureDir(path39.dirname(destination));
29146
+ ensureDir(path40.dirname(destination));
29044
29147
  const clearedLink = clearSymlinkAtDestination(destination);
29045
29148
  if (clearedLink !== null) {
29046
29149
  logger.verbose(
29047
29150
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
29048
29151
  );
29049
29152
  }
29050
- fs39.writeFileSync(destination, content);
29153
+ fs40.writeFileSync(destination, content);
29051
29154
  return { component, status: "success", path: destination };
29052
29155
  }
29053
29156
  function hashString2(value) {
@@ -29057,7 +29160,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29057
29160
  return syncSkillsSlot({
29058
29161
  config,
29059
29162
  sourceRoot,
29060
- source: path39.resolve(sourceRoot, config.source.skills),
29163
+ source: path40.resolve(sourceRoot, config.source.skills),
29061
29164
  destination: resolveTargetPath(paths.skills),
29062
29165
  dryRun: options.dryRun,
29063
29166
  logger,
@@ -29072,16 +29175,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29072
29175
  });
29073
29176
  }
29074
29177
  function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29075
- const sourceAgentsRoot = path39.join(sourceRoot, config.source.agents);
29076
- if (!fs39.existsSync(sourceAgentsRoot)) {
29178
+ const sourceAgentsRoot = path40.join(sourceRoot, config.source.agents);
29179
+ if (!fs40.existsSync(sourceAgentsRoot)) {
29077
29180
  return [skippedMissingSource3("agents", sourceAgentsRoot)];
29078
29181
  }
29079
- const sourceAgents = ts(path39.join(sourceAgentsRoot, "*.md")).sort();
29182
+ const sourceAgents = ts(path40.join(sourceAgentsRoot, "*.md")).sort();
29080
29183
  const agentsRoot = resolveTargetPath(paths.agents);
29081
29184
  return sourceAgents.map((agentFile) => {
29082
- const destination = path39.join(
29185
+ const destination = path40.join(
29083
29186
  agentsRoot,
29084
- `${path39.basename(agentFile, ".md")}.agent.md`
29187
+ `${path40.basename(agentFile, ".md")}.agent.md`
29085
29188
  );
29086
29189
  const compiled = compileAgent(
29087
29190
  agentFile,
@@ -29109,16 +29212,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
29109
29212
  });
29110
29213
  }
29111
29214
  function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
29112
- const sourceCommandsRoot = path39.join(sourceRoot, config.source.commands);
29113
- if (!fs39.existsSync(sourceCommandsRoot)) {
29215
+ const sourceCommandsRoot = path40.join(sourceRoot, config.source.commands);
29216
+ if (!fs40.existsSync(sourceCommandsRoot)) {
29114
29217
  return [skippedMissingSource3("commands", sourceCommandsRoot)];
29115
29218
  }
29116
- const sourceCommands = ts(path39.join(sourceCommandsRoot, "*.md")).sort();
29219
+ const sourceCommands = ts(path40.join(sourceCommandsRoot, "*.md")).sort();
29117
29220
  const promptsRoot = resolveTargetPath(paths.prompts);
29118
29221
  return sourceCommands.map((commandFile) => {
29119
- const destination = path39.join(
29222
+ const destination = path40.join(
29120
29223
  promptsRoot,
29121
- `${path39.basename(commandFile, ".md")}.prompt.md`
29224
+ `${path40.basename(commandFile, ".md")}.prompt.md`
29122
29225
  );
29123
29226
  const compiled = compileCommandPrompt(commandFile);
29124
29227
  if (options.dryRun) {
@@ -29142,7 +29245,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
29142
29245
  });
29143
29246
  }
29144
29247
  function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
29145
- const destination = path39.join(
29248
+ const destination = path40.join(
29146
29249
  resolveTargetPath(paths.hooks),
29147
29250
  "tangyr-managed.json"
29148
29251
  );
@@ -29205,10 +29308,10 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
29205
29308
  const source = resolveMcpSourceFile(sourceRoot, config);
29206
29309
  const sourceLabel = mcpSourceLabel(config);
29207
29310
  const destination = resolveTargetPath(paths.mcp_shared_file);
29208
- if (!fs39.existsSync(source)) {
29311
+ if (!fs40.existsSync(source)) {
29209
29312
  return skippedMissingSource3("mcp", source);
29210
29313
  }
29211
- const sourceMcpJson = JSON.parse(fs39.readFileSync(source, "utf8"));
29314
+ const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
29212
29315
  const compiled = compileMcp(
29213
29316
  sourceMcpJson,
29214
29317
  "copilot",
@@ -29238,19 +29341,19 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
29238
29341
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
29239
29342
  return { component, status: "conflict", path: destination };
29240
29343
  }
29241
- ensureDir(path39.dirname(destination));
29344
+ ensureDir(path40.dirname(destination));
29242
29345
  const clearedLink = clearSymlinkAtDestination(destination);
29243
29346
  if (clearedLink !== null) {
29244
29347
  logger.verbose(
29245
29348
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
29246
29349
  );
29247
29350
  }
29248
- fs39.writeFileSync(destination, content);
29351
+ fs40.writeFileSync(destination, content);
29249
29352
  return { component, status: "success", path: destination };
29250
29353
  }
29251
29354
  function isCompiledCurrent2(destination, expectedContent, expectedHash) {
29252
29355
  try {
29253
- const current = fs39.readFileSync(destination, "utf8");
29356
+ const current = fs40.readFileSync(destination, "utf8");
29254
29357
  const marker = extractProvenanceMarker(current);
29255
29358
  return expectedHash ? marker?.hash === expectedHash && marker.target === "copilot" && current === expectedContent : current === expectedContent;
29256
29359
  } catch {
@@ -29272,13 +29375,22 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
29272
29375
  if (manifest && scopePath) {
29273
29376
  backupFile(destination, manifest, scopePath);
29274
29377
  writeManifest(scopePath, manifest);
29275
- fs39.rmSync(destination, { recursive: true, force: true });
29378
+ fs40.rmSync(destination, { recursive: true, force: true });
29276
29379
  } else {
29277
- fs39.renameSync(destination, `${destination}.bak.${Date.now()}`);
29380
+ const parked = parkConflictingPath(
29381
+ destination,
29382
+ resolveScopePath(
29383
+ options.scope ?? "global",
29384
+ options.scope === "project" ? options.projectRoot : void 0
29385
+ )
29386
+ );
29387
+ logger.warn(
29388
+ `${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
29389
+ );
29278
29390
  }
29279
29391
  return true;
29280
29392
  }
29281
- fs39.rmSync(destination, { recursive: true, force: true });
29393
+ fs40.rmSync(destination, { recursive: true, force: true });
29282
29394
  return true;
29283
29395
  }
29284
29396
  function shouldSkipComponent3(options, component) {
@@ -29287,12 +29399,12 @@ function shouldSkipComponent3(options, component) {
29287
29399
  function cleanupLegacyAgents(paths, options, logger) {
29288
29400
  const currentAgentsRoot = resolveTargetPath(paths.agents);
29289
29401
  const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
29290
- if (path39.resolve(currentAgentsRoot) === path39.resolve(legacyAgentsRoot)) {
29402
+ if (path40.resolve(currentAgentsRoot) === path40.resolve(legacyAgentsRoot)) {
29291
29403
  return [];
29292
29404
  }
29293
29405
  const outcomes = [];
29294
29406
  for (const filePath of ts(
29295
- path39.join(legacyAgentsRoot, "*.agent.md")
29407
+ path40.join(legacyAgentsRoot, "*.agent.md")
29296
29408
  ).sort()) {
29297
29409
  if (!isCopilotManagedCompiledFile(filePath)) {
29298
29410
  continue;
@@ -29302,14 +29414,14 @@ function cleanupLegacyAgents(paths, options, logger) {
29302
29414
  outcomes.push({ component: "agents", status: "dry-run", path: filePath });
29303
29415
  continue;
29304
29416
  }
29305
- fs39.rmSync(filePath, { force: true });
29417
+ fs40.rmSync(filePath, { force: true });
29306
29418
  outcomes.push({ component: "agents", status: "success", path: filePath });
29307
29419
  }
29308
29420
  return outcomes;
29309
29421
  }
29310
29422
  function isCopilotManagedCompiledFile(filePath) {
29311
29423
  try {
29312
- return extractProvenanceMarker(fs39.readFileSync(filePath, "utf8"))?.target === "copilot";
29424
+ return extractProvenanceMarker(fs40.readFileSync(filePath, "utf8"))?.target === "copilot";
29313
29425
  } catch {
29314
29426
  return false;
29315
29427
  }
@@ -29324,8 +29436,8 @@ function skippedMissingSource3(component, source) {
29324
29436
 
29325
29437
  // src/adapters/cursor.ts
29326
29438
  import crypto8 from "crypto";
29327
- import fs40 from "fs";
29328
- import path40 from "path";
29439
+ import fs41 from "fs";
29440
+ import path41 from "path";
29329
29441
  function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29330
29442
  const scope = options.scope ?? "global";
29331
29443
  const profile = resolveTargetPaths({
@@ -29437,7 +29549,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
29437
29549
  if (!shouldSkipComponent4(options, "hooks")) {
29438
29550
  outcomes.push(
29439
29551
  syncHookScriptsBridge({
29440
- source: path40.resolve(sourceRoot, config.source.hooks),
29552
+ source: path41.resolve(sourceRoot, config.source.hooks),
29441
29553
  destination: resolveTargetPath(paths.hook_scripts),
29442
29554
  config,
29443
29555
  sourceRoot,
@@ -29502,7 +29614,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
29502
29614
  const composed = composeCursorInstructions(config, sourceRoot, lossReport);
29503
29615
  const marker = formatProvenanceMarker(
29504
29616
  "markdown",
29505
- path40.basename(instructionsSourceLabel(sourceRoot, config)),
29617
+ path41.basename(instructionsSourceLabel(sourceRoot, config)),
29506
29618
  hashString3(composed),
29507
29619
  "cursor"
29508
29620
  );
@@ -29528,7 +29640,7 @@ ${composed}
29528
29640
  }
29529
29641
  function composeCursorInstructions(config, sourceRoot, lossReport) {
29530
29642
  const source = instructionsSourcePath(sourceRoot, config);
29531
- const baseContent = fs40.existsSync(source) ? fs40.readFileSync(source, "utf8").trim() : "";
29643
+ const baseContent = fs41.existsSync(source) ? fs41.readFileSync(source, "utf8").trim() : "";
29532
29644
  const personaContent = extractPrimaryPersonaContent(
29533
29645
  config,
29534
29646
  sourceRoot,
@@ -29541,11 +29653,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
29541
29653
  ${personaContent}`.trim() : baseContent;
29542
29654
  }
29543
29655
  function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29544
- const agentsDir = path40.join(sourceRoot, config.source.agents);
29545
- if (!fs40.existsSync(agentsDir)) {
29656
+ const agentsDir = path41.join(sourceRoot, config.source.agents);
29657
+ if (!fs41.existsSync(agentsDir)) {
29546
29658
  return null;
29547
29659
  }
29548
- const agentFiles = ts(path40.join(agentsDir, "*.md")).sort();
29660
+ const agentFiles = ts(path41.join(agentsDir, "*.md")).sort();
29549
29661
  if (agentFiles.length === 0) {
29550
29662
  return null;
29551
29663
  }
@@ -29568,7 +29680,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29568
29680
  return null;
29569
29681
  }
29570
29682
  addLoss(lossReport, "cursor", "instructions", {
29571
- source: `agents/${path40.basename(primaryFile)}`,
29683
+ source: `agents/${path41.basename(primaryFile)}`,
29572
29684
  fields: [
29573
29685
  {
29574
29686
  field: "persona",
@@ -29578,23 +29690,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29578
29690
  "persona",
29579
29691
  "instructions-shim"
29580
29692
  ),
29581
- detail: `Primary persona from ${path40.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
29693
+ detail: `Primary persona from ${path41.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
29582
29694
  }
29583
29695
  ]
29584
29696
  });
29585
29697
  return body.trim();
29586
29698
  }
29587
29699
  function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29588
- const sourceAgentsRoot = path40.join(sourceRoot, config.source.agents);
29589
- if (!fs40.existsSync(sourceAgentsRoot)) {
29700
+ const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
29701
+ if (!fs41.existsSync(sourceAgentsRoot)) {
29590
29702
  return [skippedMissingSource4("agents", sourceAgentsRoot)];
29591
29703
  }
29592
- const sourceAgents = ts(path40.join(sourceAgentsRoot, "*.md")).sort();
29704
+ const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
29593
29705
  const agentsRoot = resolveTargetPath(paths.agents);
29594
29706
  return sourceAgents.map((agentFile) => {
29595
- const destination = path40.join(
29707
+ const destination = path41.join(
29596
29708
  agentsRoot,
29597
- `${path40.basename(agentFile, ".md")}.md`
29709
+ `${path41.basename(agentFile, ".md")}.md`
29598
29710
  );
29599
29711
  let compiled;
29600
29712
  try {
@@ -29635,14 +29747,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
29635
29747
  });
29636
29748
  }
29637
29749
  function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
29638
- const sourceRulesDir = path40.join(sourceRoot, config.source.rules);
29639
- if (!fs40.existsSync(sourceRulesDir)) {
29750
+ const sourceRulesDir = path41.join(sourceRoot, config.source.rules);
29751
+ if (!fs41.existsSync(sourceRulesDir)) {
29640
29752
  return [skippedMissingSource4("rules", sourceRulesDir)];
29641
29753
  }
29642
29754
  const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
29643
29755
  const rulesDir = resolveTargetPath(paths.rules);
29644
29756
  return compiled.dotRulesFiles.map(({ name, content }) => {
29645
- const destination = path40.join(rulesDir, name);
29757
+ const destination = path41.join(rulesDir, name);
29646
29758
  if (options.dryRun) {
29647
29759
  logger.info(`[dry-run] rules: write ${destination}`);
29648
29760
  return {
@@ -29666,17 +29778,17 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
29666
29778
  });
29667
29779
  }
29668
29780
  function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
29669
- const sourceCommandsRoot = path40.join(sourceRoot, config.source.commands);
29670
- if (!fs40.existsSync(sourceCommandsRoot)) {
29781
+ const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
29782
+ if (!fs41.existsSync(sourceCommandsRoot)) {
29671
29783
  return [skippedMissingSource4("commands", sourceCommandsRoot)];
29672
29784
  }
29673
- const sourceCommands = ts(path40.join(sourceCommandsRoot, "*.md")).sort();
29785
+ const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
29674
29786
  const skillsRoot = resolveTargetPath(paths.skills);
29675
29787
  return sourceCommands.map((commandFile) => {
29676
- const baseName = path40.basename(commandFile, ".md");
29677
- const destination = path40.join(skillsRoot, baseName, "SKILL.md");
29678
- const commandContent = fs40.readFileSync(commandFile, "utf8");
29679
- const relativeSource = `commands/${path40.basename(commandFile)}`;
29788
+ const baseName = path41.basename(commandFile, ".md");
29789
+ const destination = path41.join(skillsRoot, baseName, "SKILL.md");
29790
+ const commandContent = fs41.readFileSync(commandFile, "utf8");
29791
+ const relativeSource = `commands/${path41.basename(commandFile)}`;
29680
29792
  const marker = formatProvenanceMarker(
29681
29793
  "markdown",
29682
29794
  relativeSource,
@@ -29715,8 +29827,8 @@ ${commandContent.trim()}
29715
29827
  });
29716
29828
  }
29717
29829
  function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
29718
- const source = path40.resolve(sourceRoot, config.source.skills);
29719
- if (!fs40.existsSync(source)) {
29830
+ const source = path41.resolve(sourceRoot, config.source.skills);
29831
+ if (!fs41.existsSync(source)) {
29720
29832
  return skippedMissingSource4(component, source);
29721
29833
  }
29722
29834
  if (options.dryRun) {
@@ -29730,18 +29842,18 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
29730
29842
  return { component, status: "skipped-current", path: destination };
29731
29843
  }
29732
29844
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
29733
- fs40.unlinkSync(destination);
29845
+ fs41.unlinkSync(destination);
29734
29846
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
29735
29847
  return { component, status: "conflict", path: destination };
29736
29848
  } else if (artifactClass === "managed-symlink") {
29737
- fs40.unlinkSync(destination);
29849
+ fs41.unlinkSync(destination);
29738
29850
  }
29739
- ensureDir(path40.dirname(destination));
29851
+ ensureDir(path41.dirname(destination));
29740
29852
  createRelativeSymlink(source, destination, "dir");
29741
29853
  logger.verbose(`Skills: created shared skills symlink ${destination}`);
29742
29854
  return { component, status: "success", path: destination };
29743
29855
  }
29744
- if (fs40.existsSync(destination)) {
29856
+ if (fs41.existsSync(destination)) {
29745
29857
  return { component, status: "skipped-current", path: destination };
29746
29858
  }
29747
29859
  ensureDir(destination);
@@ -29782,18 +29894,18 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
29782
29894
  }
29783
29895
  const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
29784
29896
  `;
29785
- ensureDir(path40.dirname(destination));
29786
- fs40.writeFileSync(destination, hooksFileContent);
29897
+ ensureDir(path41.dirname(destination));
29898
+ fs41.writeFileSync(destination, hooksFileContent);
29787
29899
  return { component: "hooks", status: "success", path: destination };
29788
29900
  }
29789
29901
  function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
29790
29902
  const source = resolveMcpSourceFile(sourceRoot, config);
29791
29903
  const sourceLabel = mcpSourceLabel(config);
29792
29904
  const destination = resolveTargetPath(paths.mcp_file);
29793
- if (!fs40.existsSync(source)) {
29905
+ if (!fs41.existsSync(source)) {
29794
29906
  return skippedMissingSource4("mcp", source);
29795
29907
  }
29796
- const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
29908
+ const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
29797
29909
  const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
29798
29910
  if (options.dryRun) {
29799
29911
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -29846,13 +29958,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
29846
29958
  );
29847
29959
  }
29848
29960
  function syncProviderPin(config, sourceRoot, lossReport) {
29849
- const agentsDir = path40.join(sourceRoot, config.source.agents);
29850
- if (!fs40.existsSync(agentsDir)) return;
29851
- for (const agentFile of ts(path40.join(agentsDir, "*.md")).sort()) {
29961
+ const agentsDir = path41.join(sourceRoot, config.source.agents);
29962
+ if (!fs41.existsSync(agentsDir)) return;
29963
+ for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
29852
29964
  const { data } = parseMarkdownFrontmatter(agentFile);
29853
29965
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
29854
29966
  if (hasCustomProvider) {
29855
- const relativeSource = `agents/${path40.basename(agentFile)}`;
29967
+ const relativeSource = `agents/${path41.basename(agentFile)}`;
29856
29968
  addLoss(lossReport, "cursor", "agents", {
29857
29969
  source: relativeSource,
29858
29970
  fields: [
@@ -29864,7 +29976,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
29864
29976
  "provider",
29865
29977
  "provider-not-representable"
29866
29978
  ),
29867
- detail: `${path40.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
29979
+ detail: `${path41.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
29868
29980
  }
29869
29981
  ]
29870
29982
  });
@@ -29879,14 +29991,14 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
29879
29991
  if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
29880
29992
  return { component, status: "conflict", path: destination };
29881
29993
  }
29882
- ensureDir(path40.dirname(destination));
29994
+ ensureDir(path41.dirname(destination));
29883
29995
  const clearedLink = clearSymlinkAtDestination(destination);
29884
29996
  if (clearedLink !== null) {
29885
29997
  logger.verbose(
29886
29998
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
29887
29999
  );
29888
30000
  }
29889
- fs40.writeFileSync(destination, content);
30001
+ fs41.writeFileSync(destination, content);
29890
30002
  return { component, status: "success", path: destination };
29891
30003
  }
29892
30004
  function handleConflict4(destination, config, options, logger, manifest, scopePath) {
@@ -29904,18 +30016,27 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
29904
30016
  if (manifest && scopePath) {
29905
30017
  backupFile(destination, manifest, scopePath);
29906
30018
  writeManifest(scopePath, manifest);
29907
- fs40.rmSync(destination, { recursive: true, force: true });
30019
+ fs41.rmSync(destination, { recursive: true, force: true });
29908
30020
  } else {
29909
- fs40.renameSync(destination, `${destination}.bak.${Date.now()}`);
30021
+ const parked = parkConflictingPath(
30022
+ destination,
30023
+ resolveScopePath(
30024
+ options.scope ?? "global",
30025
+ options.scope === "project" ? options.projectRoot : void 0
30026
+ )
30027
+ );
30028
+ logger.warn(
30029
+ `${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
30030
+ );
29910
30031
  }
29911
30032
  return true;
29912
30033
  }
29913
- fs40.rmSync(destination, { recursive: true, force: true });
30034
+ fs41.rmSync(destination, { recursive: true, force: true });
29914
30035
  return true;
29915
30036
  }
29916
30037
  function isCompiledCurrent3(destination, expectedContent, expectedHash) {
29917
30038
  try {
29918
- const current = fs40.readFileSync(destination, "utf8");
30039
+ const current = fs41.readFileSync(destination, "utf8");
29919
30040
  const marker = extractProvenanceMarker(current);
29920
30041
  return expectedHash ? marker?.hash === expectedHash && marker.target === "cursor" && current === expectedContent : current === expectedContent;
29921
30042
  } catch {
@@ -29934,7 +30055,7 @@ function shouldSkipComponent4(options, component) {
29934
30055
  }
29935
30056
  function isSymlinkTo5(linkPath, source) {
29936
30057
  try {
29937
- return fs40.realpathSync(linkPath) === fs40.realpathSync(source);
30058
+ return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
29938
30059
  } catch {
29939
30060
  return false;
29940
30061
  }
@@ -29945,8 +30066,8 @@ function hashString3(value) {
29945
30066
 
29946
30067
  // src/adapters/cline.ts
29947
30068
  import crypto9 from "crypto";
29948
- import fs41 from "fs";
29949
- import path41 from "path";
30069
+ import fs42 from "fs";
30070
+ import path42 from "path";
29950
30071
  function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29951
30072
  const scope = options.scope ?? "global";
29952
30073
  const profile = resolveTargetPaths({
@@ -30059,7 +30180,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
30059
30180
  function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
30060
30181
  if (scope === "global" || paths.instructions === null) {
30061
30182
  addLoss(lossReport, "cline", "instructions", {
30062
- source: path41.basename(instructionsSourceLabel(sourceRoot, config)),
30183
+ source: path42.basename(instructionsSourceLabel(sourceRoot, config)),
30063
30184
  fields: [
30064
30185
  {
30065
30186
  field: "instructions",
@@ -30081,10 +30202,10 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
30081
30202
  }
30082
30203
  const source = instructionsSourcePath(sourceRoot, config);
30083
30204
  const destination = resolveTargetPath(paths.instructions);
30084
- const baseContent = fs41.existsSync(source) ? fs41.readFileSync(source, "utf8").trim() : "";
30205
+ const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
30085
30206
  const marker = formatProvenanceMarker(
30086
30207
  "markdown",
30087
- path41.basename(instructionsSourceLabel(sourceRoot, config)),
30208
+ path42.basename(instructionsSourceLabel(sourceRoot, config)),
30088
30209
  hashString4(baseContent),
30089
30210
  "cline"
30090
30211
  );
@@ -30109,11 +30230,11 @@ ${baseContent}
30109
30230
  );
30110
30231
  }
30111
30232
  function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
30112
- const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
30113
- if (!fs41.existsSync(sourceAgentsRoot)) {
30233
+ const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
30234
+ if (!fs42.existsSync(sourceAgentsRoot)) {
30114
30235
  return [skippedMissingSource5("agents", sourceAgentsRoot)];
30115
30236
  }
30116
- const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
30237
+ const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
30117
30238
  return sourceAgents.map((agentFile) => {
30118
30239
  compileAgent(agentFile, "cline", mappings, extensions, lossReport);
30119
30240
  if (options.dryRun) {
@@ -30129,14 +30250,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
30129
30250
  });
30130
30251
  }
30131
30252
  function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
30132
- const sourceRulesDir = path41.join(sourceRoot, config.source.rules);
30133
- if (!fs41.existsSync(sourceRulesDir)) {
30253
+ const sourceRulesDir = path42.join(sourceRoot, config.source.rules);
30254
+ if (!fs42.existsSync(sourceRulesDir)) {
30134
30255
  return [skippedMissingSource5("rules", sourceRulesDir)];
30135
30256
  }
30136
30257
  const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
30137
30258
  const rulesDir = resolveTargetPath(paths.rules);
30138
30259
  return compiled.dotRulesFiles.map(({ name, content }) => {
30139
- const destination = path41.join(rulesDir, name);
30260
+ const destination = path42.join(rulesDir, name);
30140
30261
  if (options.dryRun) {
30141
30262
  logger.info(`[dry-run] rules: write ${destination}`);
30142
30263
  return {
@@ -30160,17 +30281,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
30160
30281
  });
30161
30282
  }
30162
30283
  function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30163
- const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
30164
- if (!fs41.existsSync(sourceCommandsRoot)) {
30284
+ const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
30285
+ if (!fs42.existsSync(sourceCommandsRoot)) {
30165
30286
  return [skippedMissingSource5("commands", sourceCommandsRoot)];
30166
30287
  }
30167
- const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
30288
+ const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
30168
30289
  const workflowsRoot = resolveTargetPath(paths.workflows);
30169
30290
  return sourceCommands.map((commandFile) => {
30170
- const baseName = path41.basename(commandFile);
30171
- const destination = path41.join(workflowsRoot, baseName);
30172
- const commandContent = fs41.readFileSync(commandFile, "utf8");
30173
- const relativeSource = `commands/${path41.basename(commandFile)}`;
30291
+ const baseName = path42.basename(commandFile);
30292
+ const destination = path42.join(workflowsRoot, baseName);
30293
+ const commandContent = fs42.readFileSync(commandFile, "utf8");
30294
+ const relativeSource = `commands/${path42.basename(commandFile)}`;
30174
30295
  const marker = formatProvenanceMarker(
30175
30296
  "markdown",
30176
30297
  relativeSource,
@@ -30205,9 +30326,9 @@ ${commandContent.trim()}
30205
30326
  });
30206
30327
  }
30207
30328
  function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30208
- const source = path41.resolve(sourceRoot, config.source.skills);
30329
+ const source = path42.resolve(sourceRoot, config.source.skills);
30209
30330
  const destination = resolveTargetPath(paths.skills);
30210
- if (!fs41.existsSync(source)) {
30331
+ if (!fs42.existsSync(source)) {
30211
30332
  return skippedMissingSource5("skills", source);
30212
30333
  }
30213
30334
  if (options.dryRun) {
@@ -30231,15 +30352,15 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
30231
30352
  // unsynced.
30232
30353
  artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)
30233
30354
  ) {
30234
- fs41.unlinkSync(destination);
30355
+ fs42.unlinkSync(destination);
30235
30356
  } else if (artifactClass === "unmanaged-conflict") {
30236
30357
  if (!handleConflict5(destination, config, options, logger, manifest, scopePath)) {
30237
30358
  return { component: "skills", status: "conflict", path: destination };
30238
30359
  }
30239
30360
  } else if (artifactClass === "managed-symlink") {
30240
- fs41.unlinkSync(destination);
30361
+ fs42.unlinkSync(destination);
30241
30362
  }
30242
- ensureDir(path41.dirname(destination));
30363
+ ensureDir(path42.dirname(destination));
30243
30364
  createRelativeSymlink(source, destination, "dir");
30244
30365
  logger.verbose(`Skills: created Cline skills symlink ${destination}`);
30245
30366
  return { component: "skills", status: "success", path: destination };
@@ -30263,10 +30384,10 @@ function syncMcp5(config, sourceRoot, paths, options, lossReport, logger, manife
30263
30384
  const source = resolveMcpSourceFile(sourceRoot, config);
30264
30385
  const sourceLabel = mcpSourceLabel(config);
30265
30386
  const destination = resolveTargetPath(paths.mcp_file);
30266
- if (!fs41.existsSync(source)) {
30387
+ if (!fs42.existsSync(source)) {
30267
30388
  return skippedMissingSource5("mcp", source);
30268
30389
  }
30269
- const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
30390
+ const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
30270
30391
  const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
30271
30392
  if (options.dryRun) {
30272
30393
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -30309,11 +30430,11 @@ function syncSettings2(lossReport) {
30309
30430
  };
30310
30431
  }
30311
30432
  function syncProviderAndModel(config, sourceRoot, lossReport) {
30312
- const agentsDir = path41.join(sourceRoot, config.source.agents);
30313
- if (!fs41.existsSync(agentsDir)) return;
30314
- for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
30433
+ const agentsDir = path42.join(sourceRoot, config.source.agents);
30434
+ if (!fs42.existsSync(agentsDir)) return;
30435
+ for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
30315
30436
  const { data } = parseMarkdownFrontmatter(agentFile);
30316
- const relativeSource = `agents/${path41.basename(agentFile)}`;
30437
+ const relativeSource = `agents/${path42.basename(agentFile)}`;
30317
30438
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30318
30439
  if (hasCustomProvider) {
30319
30440
  addLoss(lossReport, "cline", "agents", {
@@ -30327,7 +30448,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
30327
30448
  "provider",
30328
30449
  "provider-not-representable"
30329
30450
  ),
30330
- detail: `${path41.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
30451
+ detail: `${path42.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
30331
30452
  }
30332
30453
  ]
30333
30454
  });
@@ -30345,7 +30466,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
30345
30466
  "model",
30346
30467
  "model-not-representable"
30347
30468
  ),
30348
- detail: `${path41.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
30469
+ detail: `${path42.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
30349
30470
  }
30350
30471
  ]
30351
30472
  });
@@ -30360,14 +30481,14 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
30360
30481
  if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
30361
30482
  return { component, status: "conflict", path: destination };
30362
30483
  }
30363
- ensureDir(path41.dirname(destination));
30484
+ ensureDir(path42.dirname(destination));
30364
30485
  const clearedLink = clearSymlinkAtDestination(destination);
30365
30486
  if (clearedLink !== null) {
30366
30487
  logger.verbose(
30367
30488
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
30368
30489
  );
30369
30490
  }
30370
- fs41.writeFileSync(destination, content);
30491
+ fs42.writeFileSync(destination, content);
30371
30492
  return { component, status: "success", path: destination };
30372
30493
  }
30373
30494
  function handleConflict5(destination, config, options, logger, manifest, scopePath) {
@@ -30385,18 +30506,27 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
30385
30506
  if (manifest && scopePath) {
30386
30507
  backupFile(destination, manifest, scopePath);
30387
30508
  writeManifest(scopePath, manifest);
30388
- fs41.rmSync(destination, { recursive: true, force: true });
30509
+ fs42.rmSync(destination, { recursive: true, force: true });
30389
30510
  } else {
30390
- fs41.renameSync(destination, `${destination}.bak.${Date.now()}`);
30511
+ const parked = parkConflictingPath(
30512
+ destination,
30513
+ resolveScopePath(
30514
+ options.scope ?? "global",
30515
+ options.scope === "project" ? options.projectRoot : void 0
30516
+ )
30517
+ );
30518
+ logger.warn(
30519
+ `${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
30520
+ );
30391
30521
  }
30392
30522
  return true;
30393
30523
  }
30394
- fs41.rmSync(destination, { recursive: true, force: true });
30524
+ fs42.rmSync(destination, { recursive: true, force: true });
30395
30525
  return true;
30396
30526
  }
30397
30527
  function isCompiledCurrent4(destination, expectedContent, expectedHash) {
30398
30528
  try {
30399
- const current = fs41.readFileSync(destination, "utf8");
30529
+ const current = fs42.readFileSync(destination, "utf8");
30400
30530
  const marker = extractProvenanceMarker(current);
30401
30531
  return expectedHash ? marker?.hash === expectedHash && marker.target === "cline" && current === expectedContent : current === expectedContent;
30402
30532
  } catch {
@@ -30415,7 +30545,7 @@ function shouldSkipComponent5(options, component) {
30415
30545
  }
30416
30546
  function isSymlinkTo6(linkPath, source) {
30417
30547
  try {
30418
- return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
30548
+ return fs42.realpathSync(linkPath) === fs42.realpathSync(source);
30419
30549
  } catch {
30420
30550
  return false;
30421
30551
  }
@@ -30426,9 +30556,9 @@ function hashString4(value) {
30426
30556
 
30427
30557
  // src/adapters/opencode.ts
30428
30558
  import crypto10 from "crypto";
30429
- import fs42 from "fs";
30559
+ import fs43 from "fs";
30430
30560
  import os6 from "os";
30431
- import path42 from "path";
30561
+ import path43 from "path";
30432
30562
  var import_yaml11 = __toESM(require_dist(), 1);
30433
30563
  function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30434
30564
  const scope = options.scope ?? "global";
@@ -30446,7 +30576,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30446
30576
  config_doc: profile.config_doc
30447
30577
  };
30448
30578
  const rules = compileRules(
30449
- path42.join(sourceRoot, config.source.rules),
30579
+ path43.join(sourceRoot, config.source.rules),
30450
30580
  "opencode",
30451
30581
  mappings,
30452
30582
  lossReport
@@ -30550,14 +30680,14 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30550
30680
  function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
30551
30681
  const source = instructionsSourcePath(sourceRoot, config);
30552
30682
  const destination = resolveTargetPath(paths.instructions);
30553
- const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
30683
+ const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
30554
30684
  const composed = agentsAppendix ? `${baseContent}
30555
30685
 
30556
30686
  --- tangyr managed rules ---
30557
30687
  ${agentsAppendix}`.trim() : baseContent;
30558
30688
  const marker = formatProvenanceMarker(
30559
30689
  "markdown",
30560
- path42.basename(instructionsSourceLabel(sourceRoot, config)),
30690
+ path43.basename(instructionsSourceLabel(sourceRoot, config)),
30561
30691
  hashString5(composed),
30562
30692
  "opencode"
30563
30693
  );
@@ -30584,16 +30714,16 @@ ${composed}
30584
30714
  );
30585
30715
  }
30586
30716
  function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30587
- const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
30588
- if (!fs42.existsSync(sourceAgentsRoot)) {
30717
+ const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
30718
+ if (!fs43.existsSync(sourceAgentsRoot)) {
30589
30719
  return [skippedMissingSource6("agents", sourceAgentsRoot)];
30590
30720
  }
30591
- const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
30721
+ const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
30592
30722
  const agentsRoot = resolveTargetPath(paths.agents);
30593
30723
  return sourceAgents.map((agentFile) => {
30594
- const destination = path42.join(
30724
+ const destination = path43.join(
30595
30725
  agentsRoot,
30596
- `${path42.basename(agentFile, ".md")}.md`
30726
+ `${path43.basename(agentFile, ".md")}.md`
30597
30727
  );
30598
30728
  let compiled;
30599
30729
  try {
@@ -30657,11 +30787,11 @@ function applyProviderModelBinding(compiled, mappings) {
30657
30787
  return `${before}${(0, import_yaml11.stringify)(fields).trim()}${after}`;
30658
30788
  }
30659
30789
  function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30660
- const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
30661
- if (!fs42.existsSync(sourceCommandsRoot)) {
30790
+ const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
30791
+ if (!fs43.existsSync(sourceCommandsRoot)) {
30662
30792
  return [skippedMissingSource6("commands", sourceCommandsRoot)];
30663
30793
  }
30664
- const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
30794
+ const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
30665
30795
  const commandsRoot = resolveTargetPath(paths.commands);
30666
30796
  return sourceCommands.map((commandFile) => {
30667
30797
  const { data, body } = parseCommandFile(commandFile);
@@ -30675,7 +30805,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
30675
30805
  if (typeof data.model === "string") {
30676
30806
  frontmatter.model = data.model;
30677
30807
  }
30678
- const relativeSource = `commands/${path42.basename(commandFile)}`;
30808
+ const relativeSource = `commands/${path43.basename(commandFile)}`;
30679
30809
  const marker = formatProvenanceMarker(
30680
30810
  "markdown",
30681
30811
  relativeSource,
@@ -30691,9 +30821,9 @@ ${body.trimEnd()}
30691
30821
  ` : `${marker}
30692
30822
  ${body.trimEnd()}
30693
30823
  `;
30694
- const destination = path42.join(
30824
+ const destination = path43.join(
30695
30825
  commandsRoot,
30696
- `${path42.basename(commandFile, ".md")}.md`
30826
+ `${path43.basename(commandFile, ".md")}.md`
30697
30827
  );
30698
30828
  if (options.dryRun) {
30699
30829
  logger.info(
@@ -30720,8 +30850,8 @@ ${body.trimEnd()}
30720
30850
  });
30721
30851
  }
30722
30852
  function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
30723
- const source = path42.resolve(sourceRoot, config.source.skills);
30724
- if (!fs42.existsSync(source)) {
30853
+ const source = path43.resolve(sourceRoot, config.source.skills);
30854
+ if (!fs43.existsSync(source)) {
30725
30855
  return skippedMissingSource6(component, source);
30726
30856
  }
30727
30857
  if (options.dryRun) {
@@ -30733,13 +30863,13 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
30733
30863
  return { component, status: "skipped-current", path: destination };
30734
30864
  }
30735
30865
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
30736
- fs42.unlinkSync(destination);
30866
+ fs43.unlinkSync(destination);
30737
30867
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
30738
30868
  return { component, status: "conflict", path: destination };
30739
30869
  } else if (artifactClass === "managed-symlink") {
30740
- fs42.unlinkSync(destination);
30870
+ fs43.unlinkSync(destination);
30741
30871
  }
30742
- ensureDir(path42.dirname(destination));
30872
+ ensureDir(path43.dirname(destination));
30743
30873
  createRelativeSymlink(source, destination, "dir");
30744
30874
  logger.verbose(`Skills: created skills path ${destination}`);
30745
30875
  return { component, status: "success", path: destination };
@@ -30748,13 +30878,13 @@ function syncMcp6(config, sourceRoot, paths, mappings, options, lossReport, logg
30748
30878
  const source = resolveMcpSourceFile(sourceRoot, config);
30749
30879
  const sourceLabel = mcpSourceLabel(config);
30750
30880
  const destination = resolveTargetPath(paths.config_doc);
30751
- if (!fs42.existsSync(source)) {
30881
+ if (!fs43.existsSync(source)) {
30752
30882
  if (!options.dryRun) {
30753
30883
  syncConfigDoc(paths, {}, lossReport, {}, mappings);
30754
30884
  }
30755
30885
  return skippedMissingSource6("mcp", source);
30756
30886
  }
30757
- const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
30887
+ const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
30758
30888
  const mcpJson = compileMcp(
30759
30889
  sourceMcpJson,
30760
30890
  "opencode",
@@ -30820,9 +30950,9 @@ function syncProviderBlock(mappings) {
30820
30950
  function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
30821
30951
  const destination = resolveTargetPath(paths.config_doc);
30822
30952
  let existing = {};
30823
- if (fs42.existsSync(destination)) {
30953
+ if (fs43.existsSync(destination)) {
30824
30954
  try {
30825
- existing = JSON.parse(fs42.readFileSync(destination, "utf8"));
30955
+ existing = JSON.parse(fs43.readFileSync(destination, "utf8"));
30826
30956
  } catch {
30827
30957
  existing = {};
30828
30958
  }
@@ -30847,8 +30977,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
30847
30977
  };
30848
30978
  }
30849
30979
  }
30850
- ensureDir(path42.dirname(destination));
30851
- fs42.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
30980
+ ensureDir(path43.dirname(destination));
30981
+ fs43.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
30852
30982
  `);
30853
30983
  }
30854
30984
  function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
@@ -30859,14 +30989,14 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
30859
30989
  if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
30860
30990
  return { component, status: "conflict", path: destination };
30861
30991
  }
30862
- ensureDir(path42.dirname(destination));
30992
+ ensureDir(path43.dirname(destination));
30863
30993
  const clearedLink = clearSymlinkAtDestination(destination);
30864
30994
  if (clearedLink !== null) {
30865
30995
  logger.verbose(
30866
30996
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
30867
30997
  );
30868
30998
  }
30869
- fs42.writeFileSync(destination, content);
30999
+ fs43.writeFileSync(destination, content);
30870
31000
  return { component, status: "success", path: destination };
30871
31001
  }
30872
31002
  function handleConflict6(destination, config, options, logger, manifest, scopePath) {
@@ -30884,18 +31014,27 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
30884
31014
  if (manifest && scopePath) {
30885
31015
  backupFile(destination, manifest, scopePath);
30886
31016
  writeManifest(scopePath, manifest);
30887
- fs42.rmSync(destination, { recursive: true, force: true });
31017
+ fs43.rmSync(destination, { recursive: true, force: true });
30888
31018
  } else {
30889
- fs42.renameSync(destination, `${destination}.bak.${Date.now()}`);
31019
+ const parked = parkConflictingPath(
31020
+ destination,
31021
+ resolveScopePath(
31022
+ options.scope ?? "global",
31023
+ options.scope === "project" ? options.projectRoot : void 0
31024
+ )
31025
+ );
31026
+ logger.warn(
31027
+ `${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
31028
+ );
30890
31029
  }
30891
31030
  return true;
30892
31031
  }
30893
- fs42.rmSync(destination, { recursive: true, force: true });
31032
+ fs43.rmSync(destination, { recursive: true, force: true });
30894
31033
  return true;
30895
31034
  }
30896
31035
  function isCompiledCurrent5(destination, expectedContent, expectedHash) {
30897
31036
  try {
30898
- const current = fs42.readFileSync(destination, "utf8");
31037
+ const current = fs43.readFileSync(destination, "utf8");
30899
31038
  const marker = extractProvenanceMarker(current);
30900
31039
  return expectedHash ? marker?.hash === expectedHash && marker.target === "opencode" && current === expectedContent : current === expectedContent;
30901
31040
  } catch {
@@ -30914,7 +31053,7 @@ function shouldSkipComponent6(options, component) {
30914
31053
  }
30915
31054
  function isSymlinkTo7(linkPath, source) {
30916
31055
  try {
30917
- return fs42.realpathSync(linkPath) === fs42.realpathSync(source);
31056
+ return fs43.realpathSync(linkPath) === fs43.realpathSync(source);
30918
31057
  } catch {
30919
31058
  return false;
30920
31059
  }
@@ -30923,7 +31062,7 @@ function hashString5(value) {
30923
31062
  return `sha256:${crypto10.createHash("sha256").update(value).digest("hex")}`;
30924
31063
  }
30925
31064
  function parseCommandFile(commandFile) {
30926
- const content = fs42.readFileSync(commandFile, "utf8");
31065
+ const content = fs43.readFileSync(commandFile, "utf8");
30927
31066
  if (!content.startsWith("---\n")) {
30928
31067
  return { data: {}, body: content };
30929
31068
  }
@@ -30943,7 +31082,7 @@ function parseCommandFile(commandFile) {
30943
31082
  // src/commands/install.ts
30944
31083
  function isBackupablePath(targetPath) {
30945
31084
  try {
30946
- const lstat = fs43.lstatSync(targetPath);
31085
+ const lstat = fs44.lstatSync(targetPath);
30947
31086
  return lstat.isSymbolicLink() || lstat.isFile() || lstat.isDirectory();
30948
31087
  } catch {
30949
31088
  return false;
@@ -30980,7 +31119,7 @@ async function runInstallCommand(options, logger) {
30980
31119
  );
30981
31120
  }
30982
31121
  const kitName = resolvedKitName ?? config.kit;
30983
- const kitPath = kitPathOverride ?? (options.kitPath ? path43.resolve(options.kitPath) : config.kitPath);
31122
+ const kitPath = kitPathOverride ?? (options.kitPath ? path44.resolve(options.kitPath) : config.kitPath);
30984
31123
  if (!kitName && !kitPath) {
30985
31124
  logger.error(
30986
31125
  "No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
@@ -31085,8 +31224,8 @@ async function runInstallCommand(options, logger) {
31085
31224
  config: options.config,
31086
31225
  scope
31087
31226
  });
31088
- const skillsSource = path43.resolve(kitInfo.path, config.source.skills);
31089
- const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path43.basename(f.path) === "skills";
31227
+ const skillsSource = path44.resolve(kitInfo.path, config.source.skills);
31228
+ const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path44.basename(f.path) === "skills";
31090
31229
  const foreignSkillsSlots = new Set(
31091
31230
  assessResult.findings.filter(
31092
31231
  (f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
@@ -31124,7 +31263,7 @@ async function runInstallCommand(options, logger) {
31124
31263
  let instructionsLabel;
31125
31264
  try {
31126
31265
  const resolved = resolveInstructionsSource(kitInfo.path, config);
31127
- instructionsLabel = resolved ? path43.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
31266
+ instructionsLabel = resolved ? path44.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
31128
31267
  } catch (err) {
31129
31268
  logger.error(
31130
31269
  `[dry-run] ${err instanceof Error ? err.message : String(err)}`
@@ -31152,7 +31291,7 @@ async function runInstallCommand(options, logger) {
31152
31291
  }
31153
31292
  }
31154
31293
  logger.info(
31155
- `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path43.join(scopePath, "manifest.json")}`
31294
+ `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path44.join(scopePath, "manifest.json")}`
31156
31295
  );
31157
31296
  return;
31158
31297
  }
@@ -31211,7 +31350,7 @@ ACCEPTED CONFLICTS (posture: ${posture}; ${replaceable.length} target(s)):`
31211
31350
  logger.info(` - ${finding.path}`);
31212
31351
  logger.info(` source: ${sources}`);
31213
31352
  logger.info(
31214
- ` action: backup-and-replace${fs43.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
31353
+ ` action: backup-and-replace${fs44.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
31215
31354
  );
31216
31355
  logger.info(` backup: ${backupLocation}`);
31217
31356
  continue;
@@ -31319,6 +31458,11 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
31319
31458
  installLossReport
31320
31459
  );
31321
31460
  }
31461
+ reportContestedInstructions(
31462
+ instructionsByActiveTarget(tools, scope, projectRoot, mappings),
31463
+ (kitInfo.components.rules?.declared.length ?? 0) > 0,
31464
+ logger
31465
+ );
31322
31466
  for (const [relativePath, sourcePath] of collectAllFiles(kitInfo, config)) {
31323
31467
  addFileToManifest(manifest, {
31324
31468
  relativePath,
@@ -31330,20 +31474,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
31330
31474
  writeManifest(scopePath, manifest);
31331
31475
  logger.info(`
31332
31476
  Installation complete: ${installedCount} files installed.`);
31333
- logger.info(`Manifest written to ${path43.join(scopePath, "manifest.json")}`);
31477
+ logger.info(`Manifest written to ${path44.join(scopePath, "manifest.json")}`);
31334
31478
  logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
31335
31479
  logger.info(`Scope: ${scope}`);
31336
31480
  logger.info(`Tools: ${tools.join(", ")}`);
31337
31481
  reportHookRejections(
31338
31482
  installLossReport,
31339
31483
  tools,
31340
- path43.resolve(kitInfo.path, "hooks"),
31484
+ path44.resolve(kitInfo.path, "hooks"),
31341
31485
  kitInfo.components.hooks.declared
31342
31486
  );
31343
31487
  const hooksConflict = reportHooksSourceConflict(
31344
31488
  installLossReport,
31345
31489
  tools,
31346
- path43.resolve(kitInfo.path, "hooks"),
31490
+ path44.resolve(kitInfo.path, "hooks"),
31347
31491
  kitInfo.components.hooks.declared
31348
31492
  );
31349
31493
  if (hooksConflict) {
@@ -31702,7 +31846,7 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
31702
31846
  return 0;
31703
31847
  }
31704
31848
  try {
31705
- const stat = fs43.lstatSync(destination);
31849
+ const stat = fs44.lstatSync(destination);
31706
31850
  if (stat.isFile() && !stat.isSymbolicLink()) {
31707
31851
  logger.warn(
31708
31852
  `${destination}: a regular file occupies the skills slot \u2014 skipping skills. Move or remove it, then re-run install.`
@@ -31730,17 +31874,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
31730
31874
  manifest,
31731
31875
  scopePath
31732
31876
  );
31733
- const skillsSource = path43.resolve(kitInfo.path, config.source.skills);
31877
+ const skillsSource = path44.resolve(kitInfo.path, config.source.skills);
31734
31878
  let count = 0;
31735
31879
  for (const outcome of outcomes) {
31736
31880
  if (outcome.status !== "success" && outcome.status !== "skipped-current") {
31737
31881
  continue;
31738
31882
  }
31739
- const skillName = path43.basename(outcome.path);
31883
+ const skillName = path44.basename(outcome.path);
31740
31884
  addArtifactToManifest(manifest, {
31741
31885
  relativePath: `claude-code/skills/${skillName}`,
31742
31886
  path: outcome.path,
31743
- hash: describeArtifactState(outcome.path) ?? `dir:${path43.join(skillsSource, skillName)}`,
31887
+ hash: describeArtifactState(outcome.path) ?? `dir:${path44.join(skillsSource, skillName)}`,
31744
31888
  origin: "tangyr-managed"
31745
31889
  });
31746
31890
  count++;
@@ -31754,10 +31898,10 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
31754
31898
  logger.verbose(` skipped (operator choice): ${placement.destination}`);
31755
31899
  continue;
31756
31900
  }
31757
- const destDir = path43.dirname(placement.destination);
31758
- fs43.mkdirSync(destDir, { recursive: true });
31901
+ const destDir = path44.dirname(placement.destination);
31902
+ fs44.mkdirSync(destDir, { recursive: true });
31759
31903
  if (placement.type === "symlink") {
31760
- if (fs43.existsSync(placement.destination) || isSymlink2(placement.destination)) {
31904
+ if (fs44.existsSync(placement.destination) || isSymlink2(placement.destination)) {
31761
31905
  removeManagedPath(placement.destination);
31762
31906
  }
31763
31907
  createRelativeSymlink(
@@ -31774,7 +31918,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
31774
31918
  ` symlink: ${placement.source} \u2192 ${placement.destination}`
31775
31919
  );
31776
31920
  } else {
31777
- fs43.copyFileSync(placement.source, placement.destination);
31921
+ fs44.copyFileSync(placement.source, placement.destination);
31778
31922
  logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
31779
31923
  }
31780
31924
  addArtifactToManifest(manifest, {
@@ -32056,11 +32200,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32056
32200
  if (outcome.path === mcpFile2) {
32057
32201
  return "cline/mcp.json";
32058
32202
  }
32059
- if (outcome.path.startsWith(`${workflowsRoot}${path43.sep}`)) {
32060
- return `cline/workflows/${path43.basename(outcome.path)}`;
32203
+ if (outcome.path.startsWith(`${workflowsRoot}${path44.sep}`)) {
32204
+ return `cline/workflows/${path44.basename(outcome.path)}`;
32061
32205
  }
32062
- if (outcome.path.startsWith(`${rulesRoot2}${path43.sep}`)) {
32063
- return `cline/rules/${path43.basename(outcome.path)}`;
32206
+ if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
32207
+ return `cline/rules/${path44.basename(outcome.path)}`;
32064
32208
  }
32065
32209
  return null;
32066
32210
  }
@@ -32096,14 +32240,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32096
32240
  if (outcome.path === permissionsFile) {
32097
32241
  return "cursor/permissions.json";
32098
32242
  }
32099
- if (outcome.path.startsWith(`${agentsRoot2}${path43.sep}`)) {
32100
- return `cursor/agents/${path43.basename(outcome.path)}`;
32243
+ if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
32244
+ return `cursor/agents/${path44.basename(outcome.path)}`;
32101
32245
  }
32102
- if (outcome.path.startsWith(`${rulesRoot2}${path43.sep}`)) {
32103
- return `cursor/rules/${path43.basename(outcome.path)}`;
32246
+ if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
32247
+ return `cursor/rules/${path44.basename(outcome.path)}`;
32104
32248
  }
32105
- if (outcome.path.startsWith(`${skillsRoot2}${path43.sep}`)) {
32106
- const rel = path43.relative(skillsRoot2, outcome.path);
32249
+ if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
32250
+ const rel = path44.relative(skillsRoot2, outcome.path);
32107
32251
  return `cursor/skills/${rel}`;
32108
32252
  }
32109
32253
  return null;
@@ -32129,14 +32273,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32129
32273
  if (outcome.path === skillsSharedRoot) {
32130
32274
  return "opencode/skills_shared";
32131
32275
  }
32132
- if (outcome.path.startsWith(`${agentsRoot2}${path43.sep}`)) {
32133
- return `opencode/agents/${path43.basename(outcome.path)}`;
32276
+ if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
32277
+ return `opencode/agents/${path44.basename(outcome.path)}`;
32134
32278
  }
32135
- if (outcome.path.startsWith(`${commandsRoot}${path43.sep}`)) {
32136
- return `opencode/commands/${path43.basename(outcome.path)}`;
32279
+ if (outcome.path.startsWith(`${commandsRoot}${path44.sep}`)) {
32280
+ return `opencode/commands/${path44.basename(outcome.path)}`;
32137
32281
  }
32138
32282
  if (outcome.path === configDocFile) {
32139
- return `opencode/${path43.basename(outcome.path)}`;
32283
+ return `opencode/${path44.basename(outcome.path)}`;
32140
32284
  }
32141
32285
  return null;
32142
32286
  }
@@ -32153,26 +32297,26 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32153
32297
  const hooksRoot = resolveTargetPath(copilot.hooks);
32154
32298
  const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
32155
32299
  const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
32156
- if (outcome.path.startsWith(`${skillsRoot2}${path43.sep}`)) {
32157
- return `copilot/skills/${path43.relative(skillsRoot2, outcome.path)}`;
32300
+ if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
32301
+ return `copilot/skills/${path44.relative(skillsRoot2, outcome.path)}`;
32158
32302
  }
32159
32303
  if (outcome.path === skillsRoot2) {
32160
32304
  return "copilot/skills";
32161
32305
  }
32162
32306
  if (instructionsMirror !== null && outcome.path === instructionsMirror) {
32163
- return `copilot/${path43.basename(outcome.path)}`;
32307
+ return `copilot/${path44.basename(outcome.path)}`;
32164
32308
  }
32165
- if (outcome.path.startsWith(`${agentsRoot2}${path43.sep}`)) {
32166
- return `copilot/agents/${path43.basename(outcome.path)}`;
32309
+ if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
32310
+ return `copilot/agents/${path44.basename(outcome.path)}`;
32167
32311
  }
32168
- if (outcome.path.startsWith(`${promptsRoot}${path43.sep}`)) {
32169
- return `copilot/prompts/${path43.basename(outcome.path)}`;
32312
+ if (outcome.path.startsWith(`${promptsRoot}${path44.sep}`)) {
32313
+ return `copilot/prompts/${path44.basename(outcome.path)}`;
32170
32314
  }
32171
- if (outcome.path.startsWith(`${hooksRoot}${path43.sep}`)) {
32172
- return `copilot/hooks/${path43.basename(outcome.path)}`;
32315
+ if (outcome.path.startsWith(`${hooksRoot}${path44.sep}`)) {
32316
+ return `copilot/hooks/${path44.basename(outcome.path)}`;
32173
32317
  }
32174
32318
  if (outcome.path === mcpFile2) {
32175
- return `copilot/${path43.basename(outcome.path)}`;
32319
+ return `copilot/${path44.basename(outcome.path)}`;
32176
32320
  }
32177
32321
  return null;
32178
32322
  }
@@ -32189,17 +32333,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32189
32333
  if (outcome.path === skillsRoot) {
32190
32334
  return "codex/skills";
32191
32335
  }
32192
- if (outcome.path.startsWith(`${agentsRoot}${path43.sep}`)) {
32193
- return `codex/agents/${path43.basename(outcome.path)}`;
32336
+ if (outcome.path.startsWith(`${agentsRoot}${path44.sep}`)) {
32337
+ return `codex/agents/${path44.basename(outcome.path)}`;
32194
32338
  }
32195
- if (outcome.path.startsWith(`${rulesRoot}${path43.sep}`)) {
32196
- return `codex/rules/${path43.basename(outcome.path)}`;
32339
+ if (outcome.path.startsWith(`${rulesRoot}${path44.sep}`)) {
32340
+ return `codex/rules/${path44.basename(outcome.path)}`;
32197
32341
  }
32198
32342
  if (outcome.path === hooksFile) {
32199
- return `codex/${path43.basename(outcome.path)}`;
32343
+ return `codex/${path44.basename(outcome.path)}`;
32200
32344
  }
32201
32345
  if (outcome.path === mcpFile) {
32202
- return `codex/${path43.basename(outcome.path)}`;
32346
+ return `codex/${path44.basename(outcome.path)}`;
32203
32347
  }
32204
32348
  return null;
32205
32349
  }
@@ -32268,8 +32412,8 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
32268
32412
  rules: resolvedPaths.rules
32269
32413
  };
32270
32414
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
32271
- const componentDir = path43.join(kitInfo.path, component);
32272
- if (fs43.existsSync(componentDir) && fs43.statSync(componentDir).isDirectory()) {
32415
+ const componentDir = path44.join(kitInfo.path, component);
32416
+ if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
32273
32417
  placements.push({
32274
32418
  source: componentDir,
32275
32419
  destination: targetPath,
@@ -32299,8 +32443,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
32299
32443
  rules: profile.rules
32300
32444
  };
32301
32445
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
32302
- const componentDir = path43.join(kitInfo.path, component);
32303
- if (fs43.existsSync(componentDir) && fs43.statSync(componentDir).isDirectory()) {
32446
+ const componentDir = path44.join(kitInfo.path, component);
32447
+ if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
32304
32448
  placements.push({
32305
32449
  source: componentDir,
32306
32450
  destination: targetPath,
@@ -32316,7 +32460,7 @@ function collectAllFiles(kitInfo, config) {
32316
32460
  const files = /* @__PURE__ */ new Map();
32317
32461
  const entrypoint = resolveInstructionsSource(kitInfo.path, config);
32318
32462
  if (entrypoint) {
32319
- files.set(path43.basename(entrypoint.file), entrypoint.file);
32463
+ files.set(path44.basename(entrypoint.file), entrypoint.file);
32320
32464
  }
32321
32465
  for (const [component, reconciliation] of Object.entries(
32322
32466
  kitInfo.components
@@ -32325,22 +32469,22 @@ function collectAllFiles(kitInfo, config) {
32325
32469
  const missingSet = new Set(reconciliation.missing);
32326
32470
  for (const entry of reconciliation.declared) {
32327
32471
  if (missingSet.has(entry)) continue;
32328
- const relPath = isSkills ? path43.join(component, entry) : path43.join(component, `${entry}.md`);
32329
- files.set(relPath, path43.join(kitInfo.path, relPath));
32472
+ const relPath = isSkills ? path44.join(component, entry) : path44.join(component, `${entry}.md`);
32473
+ files.set(relPath, path44.join(kitInfo.path, relPath));
32330
32474
  }
32331
32475
  }
32332
32476
  return files;
32333
32477
  }
32334
32478
  function readLinkTarget(p) {
32335
32479
  try {
32336
- return fs43.readlinkSync(p);
32480
+ return fs44.readlinkSync(p);
32337
32481
  } catch {
32338
32482
  return null;
32339
32483
  }
32340
32484
  }
32341
32485
  function isSymlink2(p) {
32342
32486
  try {
32343
- return fs43.lstatSync(p).isSymbolicLink();
32487
+ return fs44.lstatSync(p).isSymbolicLink();
32344
32488
  } catch {
32345
32489
  return false;
32346
32490
  }
@@ -32385,14 +32529,14 @@ async function runKitUpdateCommand(options, logger) {
32385
32529
  }
32386
32530
 
32387
32531
  // src/commands/list.ts
32388
- import path44 from "path";
32532
+ import path45 from "path";
32389
32533
  function runListCommand(options, logger) {
32390
32534
  let searchPaths = [];
32391
- let directKitPath = options.kitPath ? path44.resolve(options.kitPath) : void 0;
32535
+ let directKitPath = options.kitPath ? path45.resolve(options.kitPath) : void 0;
32392
32536
  try {
32393
32537
  const { config, configDir } = resolveConfig(options.config);
32394
32538
  searchPaths = config.kitSearchPaths ?? [
32395
- path44.join(configDir, "operating-kits")
32539
+ path45.join(configDir, "operating-kits")
32396
32540
  ];
32397
32541
  directKitPath = directKitPath ?? config.kitPath;
32398
32542
  } catch (err) {
@@ -32467,7 +32611,7 @@ function withDirectKit(kits, directKitPath) {
32467
32611
  return kits;
32468
32612
  }
32469
32613
  const directKit = loadKit(directKitPath);
32470
- if (kits.some((kit) => path44.resolve(kit.path) === directKit.path)) {
32614
+ if (kits.some((kit) => path45.resolve(kit.path) === directKit.path)) {
32471
32615
  return kits;
32472
32616
  }
32473
32617
  return [...kits, directKit];
@@ -32475,8 +32619,8 @@ function withDirectKit(kits, directKitPath) {
32475
32619
 
32476
32620
  // src/commands/probe.ts
32477
32621
  import { spawnSync as spawnSync2 } from "child_process";
32478
- import fs44 from "fs";
32479
- import path45 from "path";
32622
+ import fs45 from "fs";
32623
+ import path46 from "path";
32480
32624
  function runProbeCommand(options, logger) {
32481
32625
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
32482
32626
  options,
@@ -32504,7 +32648,7 @@ function runProbeCommand(options, logger) {
32504
32648
  toProbeRow(
32505
32649
  target,
32506
32650
  key,
32507
- scope === "project" ? path45.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
32651
+ scope === "project" ? path46.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
32508
32652
  )
32509
32653
  );
32510
32654
  }
@@ -32526,7 +32670,7 @@ function toProbeRow(target, key, rawPath) {
32526
32670
  const resolved = resolveTargetPath(rawPath);
32527
32671
  let accessible = false;
32528
32672
  try {
32529
- fs44.accessSync(resolved);
32673
+ fs45.accessSync(resolved);
32530
32674
  accessible = true;
32531
32675
  } catch {
32532
32676
  accessible = false;
@@ -32535,7 +32679,7 @@ function toProbeRow(target, key, rawPath) {
32535
32679
  target,
32536
32680
  key,
32537
32681
  path: resolved,
32538
- exists: fs44.existsSync(resolved),
32682
+ exists: fs45.existsSync(resolved),
32539
32683
  accessible
32540
32684
  };
32541
32685
  }
@@ -32553,7 +32697,7 @@ function codexRuntimeProbeRows() {
32553
32697
  ["binary_snap", "/snap/bin/codex"],
32554
32698
  ["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
32555
32699
  ]) {
32556
- if (fs44.existsSync(candidatePath)) {
32700
+ if (fs45.existsSync(candidatePath)) {
32557
32701
  rows.push(toProbeRow("codex", key, candidatePath));
32558
32702
  }
32559
32703
  }
@@ -32569,8 +32713,8 @@ function commandProbeRows(target, key, command, args) {
32569
32713
 
32570
32714
  // src/commands/status.ts
32571
32715
  import crypto11 from "crypto";
32572
- import fs45 from "fs";
32573
- import path46 from "path";
32716
+ import fs46 from "fs";
32717
+ import path47 from "path";
32574
32718
  function runStatusCommand(options, logger) {
32575
32719
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
32576
32720
  options,
@@ -32676,11 +32820,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
32676
32820
  }
32677
32821
  }
32678
32822
  function sourceMarkdownFiles(sourceRoot, componentPath) {
32679
- const root = path46.join(sourceRoot, componentPath);
32680
- if (!fs45.existsSync(root)) {
32823
+ const root = path47.join(sourceRoot, componentPath);
32824
+ if (!fs46.existsSync(root)) {
32681
32825
  return [];
32682
32826
  }
32683
- return ts(path46.join(root, "*.md")).sort();
32827
+ return ts(path47.join(root, "*.md")).sort();
32684
32828
  }
32685
32829
  function notRepresentableRow(component, detail) {
32686
32830
  return {
@@ -32691,11 +32835,11 @@ function notRepresentableRow(component, detail) {
32691
32835
  };
32692
32836
  }
32693
32837
  function readTargetJson(filePath) {
32694
- if (!fs45.existsSync(filePath)) {
32838
+ if (!fs46.existsSync(filePath)) {
32695
32839
  return { kind: "missing" };
32696
32840
  }
32697
32841
  try {
32698
- const parsed = JSON.parse(fs45.readFileSync(filePath, "utf8"));
32842
+ const parsed = JSON.parse(fs46.readFileSync(filePath, "utf8"));
32699
32843
  return { kind: "object", value: isRecord(parsed) ? parsed : {} };
32700
32844
  } catch (err) {
32701
32845
  return {
@@ -32784,7 +32928,7 @@ function classifyInstructions(filePath, target, expectedHash, config, sourceRoot
32784
32928
  }
32785
32929
  function compiledMcpDocument(config, sourceRoot, target) {
32786
32930
  const source = resolveMcpSourceFile(sourceRoot, config);
32787
- if (!fs45.existsSync(source)) {
32931
+ if (!fs46.existsSync(source)) {
32788
32932
  return {};
32789
32933
  }
32790
32934
  const compiled = compileMcp(
@@ -32797,7 +32941,7 @@ function compiledMcpDocument(config, sourceRoot, target) {
32797
32941
  return isRecord(parsed) ? parsed : {};
32798
32942
  }
32799
32943
  function classifyMcpDocument(config, sourceRoot, target, filePath) {
32800
- if (!fs45.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
32944
+ if (!fs46.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
32801
32945
  return notConfiguredRow("mcp", filePath);
32802
32946
  }
32803
32947
  return classifyJsonDocument(
@@ -32827,12 +32971,12 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
32827
32971
  const rows = [];
32828
32972
  const instructionsSource = instructionsSourcePath(sourceRoot, config);
32829
32973
  const rules = compileRules(
32830
- path46.join(sourceRoot, config.source.rules),
32974
+ path47.join(sourceRoot, config.source.rules),
32831
32975
  "opencode",
32832
32976
  mappings,
32833
32977
  createLossReport()
32834
32978
  );
32835
- const baseInstructions = fs45.existsSync(instructionsSource) ? fs45.readFileSync(instructionsSource, "utf8").trim() : "";
32979
+ const baseInstructions = fs46.existsSync(instructionsSource) ? fs46.readFileSync(instructionsSource, "utf8").trim() : "";
32836
32980
  const composedInstructions = rules.agentsAppendix ? `${baseInstructions}
32837
32981
 
32838
32982
  --- tangyr managed rules ---
@@ -32854,10 +32998,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
32854
32998
  )) {
32855
32999
  rows.push(
32856
33000
  classifyCompiledFile(
32857
- `agents/${path46.basename(agentFile, ".md")}`,
32858
- path46.join(
33001
+ `agents/${path47.basename(agentFile, ".md")}`,
33002
+ path47.join(
32859
33003
  resolveTargetPath(paths.agents),
32860
- `${path46.basename(agentFile, ".md")}.md`
33004
+ `${path47.basename(agentFile, ".md")}.md`
32861
33005
  ),
32862
33006
  "opencode",
32863
33007
  computeSourceHash(agentFile),
@@ -32872,10 +33016,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
32872
33016
  )) {
32873
33017
  rows.push(
32874
33018
  classifyCompiledFile(
32875
- `commands/${path46.basename(commandFile, ".md")}`,
32876
- path46.join(
33019
+ `commands/${path47.basename(commandFile, ".md")}`,
33020
+ path47.join(
32877
33021
  resolveTargetPath(paths.commands),
32878
- `${path46.basename(commandFile, ".md")}.md`
33022
+ `${path47.basename(commandFile, ".md")}.md`
32879
33023
  ),
32880
33024
  "opencode",
32881
33025
  computeSourceHash(commandFile),
@@ -32957,10 +33101,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
32957
33101
  )) {
32958
33102
  rows.push(
32959
33103
  classifyCompiledFile(
32960
- `agents/${path46.basename(agentFile, ".md")}`,
32961
- path46.join(
33104
+ `agents/${path47.basename(agentFile, ".md")}`,
33105
+ path47.join(
32962
33106
  resolveTargetPath(paths.agents),
32963
- `${path46.basename(agentFile, ".md")}.md`
33107
+ `${path47.basename(agentFile, ".md")}.md`
32964
33108
  ),
32965
33109
  "cursor",
32966
33110
  computeSourceHash(agentFile),
@@ -32977,7 +33121,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
32977
33121
  rows.push(
32978
33122
  classifyCompiledFile(
32979
33123
  `rules/${ruleFile.name}`,
32980
- path46.join(resolveTargetPath(paths.rules), ruleFile.name),
33124
+ path47.join(resolveTargetPath(paths.rules), ruleFile.name),
32981
33125
  "cursor",
32982
33126
  void 0,
32983
33127
  config,
@@ -32991,11 +33135,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
32991
33135
  sourceRoot,
32992
33136
  config.source.commands
32993
33137
  )) {
32994
- const baseName = path46.basename(commandFile, ".md");
33138
+ const baseName = path47.basename(commandFile, ".md");
32995
33139
  rows.push(
32996
33140
  classifyCompiledFile(
32997
33141
  `commands/${baseName}`,
32998
- path46.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
33142
+ path47.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
32999
33143
  "cursor",
33000
33144
  computeSourceHash(commandFile),
33001
33145
  config,
@@ -33078,7 +33222,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33078
33222
  rows.push(
33079
33223
  classifyCompiledFile(
33080
33224
  `rules/${ruleFile.name}`,
33081
- path46.join(resolveTargetPath(paths.rules), ruleFile.name),
33225
+ path47.join(resolveTargetPath(paths.rules), ruleFile.name),
33082
33226
  "cline",
33083
33227
  void 0,
33084
33228
  config,
@@ -33094,10 +33238,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33094
33238
  )) {
33095
33239
  rows.push(
33096
33240
  classifyCompiledFile(
33097
- `commands/${path46.basename(commandFile, ".md")}`,
33098
- path46.join(
33241
+ `commands/${path47.basename(commandFile, ".md")}`,
33242
+ path47.join(
33099
33243
  resolveTargetPath(paths.workflows),
33100
- path46.basename(commandFile)
33244
+ path47.basename(commandFile)
33101
33245
  ),
33102
33246
  "cline",
33103
33247
  computeSourceHash(commandFile),
@@ -33138,14 +33282,14 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33138
33282
  return rows;
33139
33283
  }
33140
33284
  function compileRulesFiles(config, sourceRoot, target, mappings) {
33141
- const rulesSource = path46.join(sourceRoot, config.source.rules);
33142
- if (!fs45.existsSync(rulesSource)) {
33285
+ const rulesSource = path47.join(sourceRoot, config.source.rules);
33286
+ if (!fs46.existsSync(rulesSource)) {
33143
33287
  return [];
33144
33288
  }
33145
33289
  return compileRules(rulesSource, target, mappings, createLossReport()).dotRulesFiles;
33146
33290
  }
33147
33291
  function classifyDirectoryPresence(component, dirPath) {
33148
- const present = fs45.existsSync(dirPath) && fs45.statSync(dirPath).isDirectory();
33292
+ const present = fs46.existsSync(dirPath) && fs46.statSync(dirPath).isDirectory();
33149
33293
  return {
33150
33294
  component,
33151
33295
  className: present ? "current" : "missing",
@@ -33164,7 +33308,7 @@ function slotsForScope2(scopeMap, scope, projectRoot) {
33164
33308
  const root = projectRoot ?? process.cwd();
33165
33309
  const resolved = {};
33166
33310
  for (const [slot, value] of Object.entries(projectSlots)) {
33167
- resolved[slot] = typeof value === "string" ? path46.resolve(root, value) : value;
33311
+ resolved[slot] = typeof value === "string" ? path47.resolve(root, value) : value;
33168
33312
  }
33169
33313
  return resolved;
33170
33314
  }
@@ -33184,21 +33328,21 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
33184
33328
  rules: paths.rules
33185
33329
  };
33186
33330
  const rules = compileRules(
33187
- path46.join(sourceRoot, config.source.rules),
33331
+ path47.join(sourceRoot, config.source.rules),
33188
33332
  "codex",
33189
33333
  mappings,
33190
33334
  createLossReport()
33191
33335
  );
33192
- const instructionsSource = fs45.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
33336
+ const instructionsSource = fs46.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
33193
33337
  const composedInstructions = `${instructionsSource}
33194
33338
 
33195
33339
  --- tangyr managed rules ---
33196
33340
  ${rules.agentsAppendix}`.trim();
33197
33341
  const agentFiles = ts(
33198
- path46.join(sourceRoot, config.source.agents, "*.md")
33342
+ path47.join(sourceRoot, config.source.agents, "*.md")
33199
33343
  ).sort();
33200
33344
  const hooksPresent = hooksSourceExists(sourceRoot, config);
33201
- const mcpSource = path46.join(sourceRoot, config.source.mcp);
33345
+ const mcpSource = path47.join(sourceRoot, config.source.mcp);
33202
33346
  const ruleRows = rules.dotRulesFiles.length === 0 ? [
33203
33347
  {
33204
33348
  component: "rules",
@@ -33209,7 +33353,7 @@ ${rules.agentsAppendix}`.trim();
33209
33353
  ] : rules.dotRulesFiles.map(
33210
33354
  (ruleFile) => classifyCompiledFile(
33211
33355
  `rules/${ruleFile.name}`,
33212
- path46.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
33356
+ path47.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
33213
33357
  "codex",
33214
33358
  void 0,
33215
33359
  config,
@@ -33227,10 +33371,10 @@ ${rules.agentsAppendix}`.trim();
33227
33371
  ),
33228
33372
  ...agentFiles.map(
33229
33373
  (agentFile) => classifyCompiledFile(
33230
- `agents/${path46.basename(agentFile, ".md")}`,
33231
- path46.join(
33374
+ `agents/${path47.basename(agentFile, ".md")}`,
33375
+ path47.join(
33232
33376
  resolveTargetPath(codexPaths.agents),
33233
- `${path46.basename(agentFile, ".md")}.toml`
33377
+ `${path47.basename(agentFile, ".md")}.toml`
33234
33378
  ),
33235
33379
  "codex",
33236
33380
  computeSourceHash(agentFile),
@@ -33258,7 +33402,7 @@ ${rules.agentsAppendix}`.trim();
33258
33402
  "hooks",
33259
33403
  resolveTargetPath(codexPaths.hooksSharedFile)
33260
33404
  ),
33261
- fs45.existsSync(mcpSource) ? classifyCompiledFile(
33405
+ fs46.existsSync(mcpSource) ? classifyCompiledFile(
33262
33406
  "mcp",
33263
33407
  resolveTargetPath(codexPaths.mcpSharedFile),
33264
33408
  "codex",
@@ -33324,20 +33468,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33324
33468
  mcpSharedFile: paths.mcp_shared_file
33325
33469
  };
33326
33470
  const agentFiles = ts(
33327
- path46.join(sourceRoot, config.source.agents, "*.md")
33471
+ path47.join(sourceRoot, config.source.agents, "*.md")
33328
33472
  ).sort();
33329
33473
  const commandFiles = ts(
33330
- path46.join(sourceRoot, config.source.commands, "*.md")
33474
+ path47.join(sourceRoot, config.source.commands, "*.md")
33331
33475
  ).sort();
33332
33476
  const hooksPresent = hooksSourceExists(sourceRoot, config);
33333
- const mcpSource = path46.join(sourceRoot, config.source.mcp);
33477
+ const mcpSource = path47.join(sourceRoot, config.source.mcp);
33334
33478
  return [
33335
33479
  ...agentFiles.map(
33336
33480
  (agentFile) => classifyCompiledFile(
33337
- `agents/${path46.basename(agentFile, ".md")}`,
33338
- path46.join(
33481
+ `agents/${path47.basename(agentFile, ".md")}`,
33482
+ path47.join(
33339
33483
  resolveTargetPath(copilotPaths.agents),
33340
- `${path46.basename(agentFile, ".md")}.agent.md`
33484
+ `${path47.basename(agentFile, ".md")}.agent.md`
33341
33485
  ),
33342
33486
  "copilot",
33343
33487
  computeSourceHash(agentFile),
@@ -33354,10 +33498,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33354
33498
  ),
33355
33499
  ...commandFiles.map(
33356
33500
  (commandFile) => classifyCompiledFile(
33357
- `commands/${path46.basename(commandFile, ".md")}`,
33358
- path46.join(
33501
+ `commands/${path47.basename(commandFile, ".md")}`,
33502
+ path47.join(
33359
33503
  resolveTargetPath(copilotPaths.prompts),
33360
- `${path46.basename(commandFile, ".md")}.prompt.md`
33504
+ `${path47.basename(commandFile, ".md")}.prompt.md`
33361
33505
  ),
33362
33506
  "copilot",
33363
33507
  computeSourceHash(commandFile),
@@ -33376,19 +33520,19 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33376
33520
  sourceRoot
33377
33521
  ),
33378
33522
  hooksPresent ? classifyCompiledHooksByProvenance(
33379
- path46.join(
33523
+ path47.join(
33380
33524
  resolveTargetPath(copilotPaths.hooks),
33381
33525
  "tangyr-managed.json"
33382
33526
  ),
33383
33527
  "copilot"
33384
33528
  ) : notConfiguredRow(
33385
33529
  "hooks",
33386
- path46.join(
33530
+ path47.join(
33387
33531
  resolveTargetPath(copilotPaths.hooks),
33388
33532
  "tangyr-managed.json"
33389
33533
  )
33390
33534
  ),
33391
- fs45.existsSync(mcpSource) ? classifyCompiledFile(
33535
+ fs46.existsSync(mcpSource) ? classifyCompiledFile(
33392
33536
  "mcp",
33393
33537
  resolveTargetPath(copilotPaths.mcpSharedFile),
33394
33538
  "copilot",
@@ -33408,7 +33552,7 @@ function notConfiguredRow(component, filePath) {
33408
33552
  }
33409
33553
  function classifyDirectArtifact(artifact, config, sourceRoot) {
33410
33554
  const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
33411
- const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path46.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
33555
+ const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path47.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
33412
33556
  if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
33413
33557
  const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
33414
33558
  if (perSkill) {
@@ -33504,11 +33648,11 @@ function classifyClaudeCodeRows(sourceRoot, config, configDir, scope, projectRoo
33504
33648
  function classifyPerSkillSlot(slotPath, sourceRoot) {
33505
33649
  let entries;
33506
33650
  try {
33507
- const stat = fs45.lstatSync(slotPath);
33651
+ const stat = fs46.lstatSync(slotPath);
33508
33652
  if (!stat.isDirectory() || stat.isSymbolicLink()) {
33509
33653
  return null;
33510
33654
  }
33511
- entries = fs45.readdirSync(slotPath, { withFileTypes: true });
33655
+ entries = fs46.readdirSync(slotPath, { withFileTypes: true });
33512
33656
  } catch {
33513
33657
  return null;
33514
33658
  }
@@ -33517,7 +33661,7 @@ function classifyPerSkillSlot(slotPath, sourceRoot) {
33517
33661
  return null;
33518
33662
  }
33519
33663
  const ours = links.filter(
33520
- (entry) => isOurSymlink(path46.join(slotPath, entry.name), sourceRoot)
33664
+ (entry) => isOurSymlink(path47.join(slotPath, entry.name), sourceRoot)
33521
33665
  );
33522
33666
  if (ours.length === 0) {
33523
33667
  return null;
@@ -33529,9 +33673,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
33529
33673
  classifyHooks(settingsPath),
33530
33674
  classifySettings(
33531
33675
  settingsPath,
33532
- path46.resolve(sourceRoot, config.source.settings)
33676
+ path47.resolve(sourceRoot, config.source.settings)
33533
33677
  ),
33534
- classifyMcp(claudeJsonPath, path46.resolve(sourceRoot, config.source.mcp))
33678
+ classifyMcp(claudeJsonPath, path47.resolve(sourceRoot, config.source.mcp))
33535
33679
  ];
33536
33680
  }
33537
33681
  function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
@@ -33628,14 +33772,14 @@ function classifyMcp(filePath, sourcePath) {
33628
33772
  }
33629
33773
  function isSymlinkCurrent(linkPath, sourcePath) {
33630
33774
  try {
33631
- return fs45.realpathSync(linkPath) === fs45.realpathSync(sourcePath);
33775
+ return fs46.realpathSync(linkPath) === fs46.realpathSync(sourcePath);
33632
33776
  } catch {
33633
33777
  return false;
33634
33778
  }
33635
33779
  }
33636
33780
  function isCompiledCurrent6(filePath, sourcePath) {
33637
33781
  try {
33638
- const marker = extractProvenanceMarker(fs45.readFileSync(filePath, "utf8"));
33782
+ const marker = extractProvenanceMarker(fs46.readFileSync(filePath, "utf8"));
33639
33783
  return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
33640
33784
  } catch {
33641
33785
  return false;
@@ -33665,7 +33809,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
33665
33809
  }
33666
33810
  function readCompiledContent(filePath) {
33667
33811
  try {
33668
- return fs45.readFileSync(filePath, "utf8");
33812
+ return fs46.readFileSync(filePath, "utf8");
33669
33813
  } catch {
33670
33814
  return null;
33671
33815
  }
@@ -33696,8 +33840,8 @@ function hashString6(value) {
33696
33840
  }
33697
33841
 
33698
33842
  // src/commands/sync.ts
33699
- import fs46 from "fs";
33700
- import path47 from "path";
33843
+ import fs47 from "fs";
33844
+ import path48 from "path";
33701
33845
 
33702
33846
  // node_modules/chalk/source/vendor/ansi-styles/index.js
33703
33847
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -34367,18 +34511,30 @@ async function runSyncCommand(options, logger) {
34367
34511
  reportHookRejections(
34368
34512
  lossReport,
34369
34513
  targets,
34370
- path47.resolve(kitInfo.path, "hooks"),
34514
+ path48.resolve(kitInfo.path, "hooks"),
34371
34515
  kitInfo.components.hooks.declared
34372
34516
  );
34373
34517
  const hooksConflict = reportHooksSourceConflict(
34374
34518
  lossReport,
34375
34519
  targets,
34376
- path47.resolve(kitInfo.path, "hooks"),
34520
+ path48.resolve(kitInfo.path, "hooks"),
34377
34521
  kitInfo.components.hooks.declared
34378
34522
  );
34379
34523
  if (hooksConflict) {
34380
34524
  logger.warn(hooksConflict);
34381
34525
  }
34526
+ if (allMappings) {
34527
+ reportContestedInstructions(
34528
+ instructionsByActiveTarget(
34529
+ targets,
34530
+ syncOptions.scope,
34531
+ syncOptions.projectRoot,
34532
+ allMappings
34533
+ ),
34534
+ kitInfo.components.rules.declared.length > 0,
34535
+ logger
34536
+ );
34537
+ }
34382
34538
  }
34383
34539
  writeLossReport(options.lossReport, lossReport);
34384
34540
  printOutcomeTable(results);
@@ -34564,8 +34720,8 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
34564
34720
  }
34565
34721
  }
34566
34722
  function resolveKitFilePath(kitPath, relativePath) {
34567
- const fullPath = path47.join(kitPath, relativePath);
34568
- return fs46.existsSync(fullPath) ? fullPath : null;
34723
+ const fullPath = path48.join(kitPath, relativePath);
34724
+ return fs47.existsSync(fullPath) ? fullPath : null;
34569
34725
  }
34570
34726
  function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
34571
34727
  if (removedSourcePaths.length === 0 || !mappings) {
@@ -34628,9 +34784,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34628
34784
  }
34629
34785
  if (relativePath.startsWith("agents/")) {
34630
34786
  removeManagedCompiledArtifact2(
34631
- path47.join(
34787
+ path48.join(
34632
34788
  resolveTargetPath(paths.agents ?? ""),
34633
- `${path47.parse(relativePath).name}.agent.md`
34789
+ `${path48.parse(relativePath).name}.agent.md`
34634
34790
  ),
34635
34791
  "copilot",
34636
34792
  relativePath,
@@ -34640,9 +34796,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34640
34796
  }
34641
34797
  if (relativePath.startsWith("commands/")) {
34642
34798
  removeManagedCompiledArtifact2(
34643
- path47.join(
34799
+ path48.join(
34644
34800
  resolveTargetPath(paths.prompts ?? ""),
34645
- `${path47.parse(relativePath).name}.prompt.md`
34801
+ `${path48.parse(relativePath).name}.prompt.md`
34646
34802
  ),
34647
34803
  "copilot",
34648
34804
  relativePath,
@@ -34652,7 +34808,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34652
34808
  }
34653
34809
  if (relativePath.endsWith("hooks.json")) {
34654
34810
  removeManagedCompiledArtifact2(
34655
- path47.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
34811
+ path48.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
34656
34812
  "copilot",
34657
34813
  relativePath,
34658
34814
  logger
@@ -34682,9 +34838,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
34682
34838
  }
34683
34839
  if (relativePath.startsWith("agents/")) {
34684
34840
  removeManagedCompiledArtifact2(
34685
- path47.join(
34841
+ path48.join(
34686
34842
  resolveTargetPath(paths.agents ?? ""),
34687
- `${path47.parse(relativePath).name}.toml`
34843
+ `${path48.parse(relativePath).name}.toml`
34688
34844
  ),
34689
34845
  "codex",
34690
34846
  relativePath,
@@ -34694,9 +34850,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
34694
34850
  }
34695
34851
  if (relativePath.startsWith("rules/")) {
34696
34852
  removeManagedCompiledArtifact2(
34697
- path47.join(
34853
+ path48.join(
34698
34854
  resolveTargetPath(paths.rules ?? ""),
34699
- `${path47.parse(relativePath).name}.rules`
34855
+ `${path48.parse(relativePath).name}.rules`
34700
34856
  ),
34701
34857
  "codex",
34702
34858
  relativePath,
@@ -34735,9 +34891,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
34735
34891
  }
34736
34892
  if (relativePath.startsWith("agents/")) {
34737
34893
  removeManagedCompiledArtifact2(
34738
- path47.join(
34894
+ path48.join(
34739
34895
  resolveTargetPath(paths.agents ?? ""),
34740
- `${path47.parse(relativePath).name}.md`
34896
+ `${path48.parse(relativePath).name}.md`
34741
34897
  ),
34742
34898
  "opencode",
34743
34899
  relativePath,
@@ -34747,9 +34903,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
34747
34903
  }
34748
34904
  if (relativePath.startsWith("commands/")) {
34749
34905
  removeManagedCompiledArtifact2(
34750
- path47.join(
34906
+ path48.join(
34751
34907
  resolveTargetPath(paths.commands ?? ""),
34752
- `${path47.parse(relativePath).name}.md`
34908
+ `${path48.parse(relativePath).name}.md`
34753
34909
  ),
34754
34910
  "opencode",
34755
34911
  relativePath,
@@ -34781,9 +34937,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
34781
34937
  }
34782
34938
  if (relativePath.startsWith("agents/")) {
34783
34939
  removeManagedCompiledArtifact2(
34784
- path47.join(
34940
+ path48.join(
34785
34941
  resolveTargetPath(paths.agents ?? ""),
34786
- `${path47.parse(relativePath).name}.md`
34942
+ `${path48.parse(relativePath).name}.md`
34787
34943
  ),
34788
34944
  "cursor",
34789
34945
  relativePath,
@@ -34793,9 +34949,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
34793
34949
  }
34794
34950
  if (relativePath.startsWith("rules/")) {
34795
34951
  removeManagedCompiledArtifact2(
34796
- path47.join(
34952
+ path48.join(
34797
34953
  resolveTargetPath(paths.rules ?? ""),
34798
- `${path47.parse(relativePath).name}.mdc`
34954
+ `${path48.parse(relativePath).name}.mdc`
34799
34955
  ),
34800
34956
  "cursor",
34801
34957
  relativePath,
@@ -34805,9 +34961,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
34805
34961
  }
34806
34962
  if (relativePath.startsWith("commands/")) {
34807
34963
  removeManagedCompiledArtifact2(
34808
- path47.join(
34964
+ path48.join(
34809
34965
  resolveTargetPath(paths.skills ?? ""),
34810
- path47.parse(relativePath).name,
34966
+ path48.parse(relativePath).name,
34811
34967
  "SKILL.md"
34812
34968
  ),
34813
34969
  "cursor",
@@ -34851,9 +35007,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
34851
35007
  }
34852
35008
  if (relativePath.startsWith("rules/")) {
34853
35009
  removeManagedCompiledArtifact2(
34854
- path47.join(
35010
+ path48.join(
34855
35011
  resolveTargetPath(paths.rules ?? ""),
34856
- `${path47.parse(relativePath).name}.md`
35012
+ `${path48.parse(relativePath).name}.md`
34857
35013
  ),
34858
35014
  "cline",
34859
35015
  relativePath,
@@ -34863,9 +35019,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
34863
35019
  }
34864
35020
  if (relativePath.startsWith("commands/")) {
34865
35021
  removeManagedCompiledArtifact2(
34866
- path47.join(
35022
+ path48.join(
34867
35023
  resolveTargetPath(paths.workflows ?? ""),
34868
- path47.basename(relativePath)
35024
+ path48.basename(relativePath)
34869
35025
  ),
34870
35026
  "cline",
34871
35027
  relativePath,
@@ -34883,17 +35039,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
34883
35039
  }
34884
35040
  }
34885
35041
  function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
34886
- if (!fs46.existsSync(artifactPath)) {
35042
+ if (!fs47.existsSync(artifactPath)) {
34887
35043
  return;
34888
35044
  }
34889
- if (!fs46.statSync(artifactPath).isFile()) {
35045
+ if (!fs47.statSync(artifactPath).isFile()) {
34890
35046
  return;
34891
35047
  }
34892
- const marker = extractProvenanceMarker(fs46.readFileSync(artifactPath, "utf8"));
35048
+ const marker = extractProvenanceMarker(fs47.readFileSync(artifactPath, "utf8"));
34893
35049
  if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
34894
35050
  return;
34895
35051
  }
34896
- fs46.rmSync(artifactPath, { force: true });
35052
+ fs47.rmSync(artifactPath, { force: true });
34897
35053
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
34898
35054
  }
34899
35055
  function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
@@ -34924,10 +35080,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
34924
35080
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
34925
35081
  }
34926
35082
  function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
34927
- if (!fs46.existsSync(artifactPath)) {
35083
+ if (!fs47.existsSync(artifactPath)) {
34928
35084
  return;
34929
35085
  }
34930
- const content = fs46.readFileSync(artifactPath, "utf8");
35086
+ const content = fs47.readFileSync(artifactPath, "utf8");
34931
35087
  const startMarker = "# tangyr: managed mcp start";
34932
35088
  const endMarker = "# tangyr: managed mcp end";
34933
35089
  const startIndex = content.indexOf(startMarker);
@@ -34944,19 +35100,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
34944
35100
  const after = content.slice(endIndex + endMarker.length).trimStart();
34945
35101
  const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
34946
35102
  if (cleaned.length === 0) {
34947
- fs46.rmSync(artifactPath, { force: true });
35103
+ fs47.rmSync(artifactPath, { force: true });
34948
35104
  } else {
34949
- fs46.writeFileSync(artifactPath, `${cleaned}
35105
+ fs47.writeFileSync(artifactPath, `${cleaned}
34950
35106
  `);
34951
35107
  }
34952
35108
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
34953
35109
  }
34954
35110
  function readJsonObject5(filePath) {
34955
- if (!fs46.existsSync(filePath)) {
35111
+ if (!fs47.existsSync(filePath)) {
34956
35112
  return null;
34957
35113
  }
34958
35114
  try {
34959
- const parsed = JSON.parse(fs46.readFileSync(filePath, "utf8"));
35115
+ const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
34960
35116
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
34961
35117
  } catch {
34962
35118
  return null;
@@ -34970,10 +35126,10 @@ function readJsonMetadata(value) {
34970
35126
  }
34971
35127
  function writeJsonOrRemove2(filePath, parsed) {
34972
35128
  if (isEmptyJsonValue2(parsed)) {
34973
- fs46.rmSync(filePath, { force: true });
35129
+ fs47.rmSync(filePath, { force: true });
34974
35130
  return;
34975
35131
  }
34976
- fs46.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
35132
+ fs47.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
34977
35133
  `);
34978
35134
  }
34979
35135
  function isEmptyJsonValue2(value) {
@@ -35033,8 +35189,8 @@ function removeManagedHookEntries(value, expectedSource) {
35033
35189
  }
35034
35190
 
35035
35191
  // src/commands/validate.ts
35036
- import fs47 from "fs";
35037
- import path48 from "path";
35192
+ import fs48 from "fs";
35193
+ import path49 from "path";
35038
35194
  var SUPPORTED_KIT_FORMATS2 = [1];
35039
35195
  var SUPPORTED_DISCIPLINE_VERSIONS = [
35040
35196
  "0.14.0",
@@ -35149,12 +35305,12 @@ function checkArchetype(kit) {
35149
35305
  }
35150
35306
  function checkHookScriptsExist(kit) {
35151
35307
  const violations = [];
35152
- const hooksDir = path48.join(kit.path, "hooks");
35308
+ const hooksDir = path49.join(kit.path, "hooks");
35153
35309
  const missingSet = new Set(kit.components.hooks.missing);
35154
35310
  for (const name of kit.components.hooks.declared) {
35155
35311
  if (missingSet.has(name)) continue;
35156
- const declarationPath = path48.join(hooksDir, `${name}.md`);
35157
- if (!fs47.existsSync(declarationPath)) continue;
35312
+ const declarationPath = path49.join(hooksDir, `${name}.md`);
35313
+ if (!fs48.existsSync(declarationPath)) continue;
35158
35314
  let data;
35159
35315
  try {
35160
35316
  ({ data } = parseMarkdownFrontmatter(declarationPath));
@@ -35164,8 +35320,8 @@ function checkHookScriptsExist(kit) {
35164
35320
  if (typeof data.command === "string" && data.command.trim().length > 0) {
35165
35321
  continue;
35166
35322
  }
35167
- const scriptPath = path48.join(hooksDir, "scripts", `${name}.ts`);
35168
- if (!fs47.existsSync(scriptPath)) {
35323
+ const scriptPath = path49.join(hooksDir, "scripts", `${name}.ts`);
35324
+ if (!fs48.existsSync(scriptPath)) {
35169
35325
  violations.push({
35170
35326
  code: "hook-script-missing",
35171
35327
  location: `hooks/scripts/${name}.ts`,
@@ -35178,10 +35334,10 @@ function checkHookScriptsExist(kit) {
35178
35334
  function checkOptionalSourceDocuments(kit) {
35179
35335
  const violations = [];
35180
35336
  for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
35181
- const filePath = path48.join(kit.path, name);
35182
- if (!fs47.existsSync(filePath)) continue;
35337
+ const filePath = path49.join(kit.path, name);
35338
+ if (!fs48.existsSync(filePath)) continue;
35183
35339
  try {
35184
- const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
35340
+ const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
35185
35341
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
35186
35342
  violations.push({
35187
35343
  code: "optional-source-malformed",
@@ -35203,10 +35359,10 @@ function checkSkillSubfolderNames(kit) {
35203
35359
  const notices = [];
35204
35360
  const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
35205
35361
  for (const name of kit.components.skills.declared) {
35206
- const skillDir = path48.join(kit.path, "skills", name);
35362
+ const skillDir = path49.join(kit.path, "skills", name);
35207
35363
  let entries;
35208
35364
  try {
35209
- entries = fs47.readdirSync(skillDir, { withFileTypes: true });
35365
+ entries = fs48.readdirSync(skillDir, { withFileTypes: true });
35210
35366
  } catch {
35211
35367
  continue;
35212
35368
  }
@@ -35224,7 +35380,7 @@ function checkSkillSubfolderNames(kit) {
35224
35380
  return notices;
35225
35381
  }
35226
35382
  function checkHooksSourceForm(kit) {
35227
- const hooksDir = path48.join(kit.path, "hooks");
35383
+ const hooksDir = path49.join(kit.path, "hooks");
35228
35384
  const message = describeHooksSourceConflict(
35229
35385
  hooksDir,
35230
35386
  kit.components.hooks.declared
@@ -35236,12 +35392,12 @@ function checkHooksSourceForm(kit) {
35236
35392
  } : null;
35237
35393
  }
35238
35394
  function checkHookDeclarations(kit) {
35239
- const hooksDir = path48.join(kit.path, "hooks");
35395
+ const hooksDir = path49.join(kit.path, "hooks");
35240
35396
  return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
35241
35397
  (r) => ({
35242
35398
  code: "hook-declaration-invalid",
35243
- location: `hooks/${path48.basename(r.file)}`,
35244
- message: `hooks: '${path48.basename(r.file, ".md")}' was rejected at '${r.field}' \u2014 ${r.reason}. Until this is fixed the hook is not installed on any target; install and sync report it as an error-severity loss and exit 3. To fix: correct the field named above in this file.`
35399
+ location: `hooks/${path49.basename(r.file)}`,
35400
+ message: `hooks: '${path49.basename(r.file, ".md")}' was rejected at '${r.field}' \u2014 ${r.reason}. Until this is fixed the hook is not installed on any target; install and sync report it as an error-severity loss and exit 3. To fix: correct the field named above in this file.`
35245
35401
  })
35246
35402
  );
35247
35403
  }
@@ -35261,11 +35417,11 @@ function checkKitFormatSupported(kit) {
35261
35417
  function checkEntrypointExists(kit) {
35262
35418
  const declared = kit.entrypoint;
35263
35419
  const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
35264
- const entrypointPath = path48.join(kit.path, entrypoint);
35265
- if (fs47.existsSync(entrypointPath)) {
35420
+ const entrypointPath = path49.join(kit.path, entrypoint);
35421
+ if (fs48.existsSync(entrypointPath)) {
35266
35422
  return null;
35267
35423
  }
35268
- const legacyPresent = declared === void 0 && fs47.existsSync(path48.join(kit.path, LEGACY_ENTRYPOINT));
35424
+ const legacyPresent = declared === void 0 && fs48.existsSync(path49.join(kit.path, LEGACY_ENTRYPOINT));
35269
35425
  const remedy = legacyPresent ? `This kit has '${LEGACY_ENTRYPOINT}' but not '${DEFAULT_ENTRYPOINT}'. Until now validate looked for '${LEGACY_ENTRYPOINT}' unconditionally; it now reads the manifest's 'entrypoint', defaulting to '${DEFAULT_ENTRYPOINT}' \u2014 the contract's canonical orientation document, of which '${LEGACY_ENTRYPOINT}' is a target translation. To fix: either add "entrypoint: ${LEGACY_ENTRYPOINT}" to tangyr-kit.yaml to keep the current filename, or rename '${LEGACY_ENTRYPOINT}' to '${DEFAULT_ENTRYPOINT}'.` : declared === void 0 ? `No 'entrypoint' is declared in tangyr-kit.yaml, so '${DEFAULT_ENTRYPOINT}' is expected at the kit root. To fix: create it, or declare the file you use with "entrypoint: <filename>".` : `tangyr-kit.yaml declares "entrypoint: ${declared}", and no such file exists at the kit root. To fix: create it, or correct the declaration.`;
35270
35426
  return {
35271
35427
  code: "entrypoint-missing",
@@ -35324,9 +35480,9 @@ function checkComponentFrontmatter(kit) {
35324
35480
  const missingSet = new Set(kit.components[cat].missing);
35325
35481
  for (const name of kit.components[cat].declared) {
35326
35482
  if (missingSet.has(name)) continue;
35327
- const filePath = cat === "skills" ? path48.join(kit.path, cat, name, "SKILL.md") : path48.join(kit.path, cat, `${name}.md`);
35328
- if (!fs47.existsSync(filePath)) continue;
35329
- const relPath = path48.relative(kit.path, filePath);
35483
+ const filePath = cat === "skills" ? path49.join(kit.path, cat, name, "SKILL.md") : path49.join(kit.path, cat, `${name}.md`);
35484
+ if (!fs48.existsSync(filePath)) continue;
35485
+ const relPath = path49.relative(kit.path, filePath);
35330
35486
  try {
35331
35487
  const { data } = parseMarkdownFrontmatter(filePath);
35332
35488
  for (const field of requiredFields) {
@@ -35351,10 +35507,10 @@ function checkComponentFrontmatter(kit) {
35351
35507
  }
35352
35508
  function checkReservedRootNames(kit) {
35353
35509
  const violations = [];
35354
- if (!fs47.existsSync(kit.path) || !fs47.statSync(kit.path).isDirectory()) {
35510
+ if (!fs48.existsSync(kit.path) || !fs48.statSync(kit.path).isDirectory()) {
35355
35511
  return violations;
35356
35512
  }
35357
- const entries = fs47.readdirSync(kit.path, { withFileTypes: true });
35513
+ const entries = fs48.readdirSync(kit.path, { withFileTypes: true });
35358
35514
  for (const entry of entries) {
35359
35515
  if (RESERVED_ROOT_NAMES.includes(entry.name)) {
35360
35516
  violations.push({
@@ -35371,8 +35527,8 @@ function checkHumanOnlyCommandInvocation(kit) {
35371
35527
  const missingSet = new Set(kit.components.commands.missing);
35372
35528
  for (const name of kit.components.commands.declared) {
35373
35529
  if (missingSet.has(name)) continue;
35374
- const filePath = path48.join(kit.path, "commands", `${name}.md`);
35375
- if (!fs47.existsSync(filePath)) continue;
35530
+ const filePath = path49.join(kit.path, "commands", `${name}.md`);
35531
+ if (!fs48.existsSync(filePath)) continue;
35376
35532
  let data;
35377
35533
  try {
35378
35534
  ({ data } = parseMarkdownFrontmatter(filePath));
@@ -35385,7 +35541,7 @@ function checkHumanOnlyCommandInvocation(kit) {
35385
35541
  if (!barred) {
35386
35542
  violations.push({
35387
35543
  code: "command-human-only-model-invocable",
35388
- location: path48.relative(kit.path, filePath),
35544
+ location: path49.relative(kit.path, filePath),
35389
35545
  message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
35390
35546
  });
35391
35547
  }
@@ -35394,8 +35550,8 @@ function checkHumanOnlyCommandInvocation(kit) {
35394
35550
  }
35395
35551
 
35396
35552
  // src/commands/verify.ts
35397
- import fs48 from "fs";
35398
- import path49 from "path";
35553
+ import fs49 from "fs";
35554
+ import path50 from "path";
35399
35555
  function runVerifyCommand(options, logger) {
35400
35556
  if (options.target && !isKnownTarget(options.target)) {
35401
35557
  throwUnrecognizedTarget(options.target);
@@ -35576,8 +35732,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
35576
35732
  if (!slotPath) {
35577
35733
  continue;
35578
35734
  }
35579
- const fullPath = subPath ? path49.join(slotPath, subPath) : slotPath;
35580
- if (!fs48.existsSync(fullPath)) {
35735
+ const fullPath = subPath ? path50.join(slotPath, subPath) : slotPath;
35736
+ if (!fs49.existsSync(fullPath)) {
35581
35737
  failures.push(
35582
35738
  `claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
35583
35739
  );