@alessandroraffa/tangyr 3.0.4 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js 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 path51 = __require("path");
1376
- var fs50 = __require("fs");
1375
+ var path52 = __require("path");
1376
+ var fs51 = __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 (fs50.existsSync(executableFile)) return;
2370
+ if (fs51.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 = path51.resolve(baseDir, baseName);
2389
- if (fs50.existsSync(localBin)) return localBin;
2390
- if (sourceExt.includes(path51.extname(baseName))) return void 0;
2388
+ const localBin = path52.resolve(baseDir, baseName);
2389
+ if (fs51.existsSync(localBin)) return localBin;
2390
+ if (sourceExt.includes(path52.extname(baseName))) return void 0;
2391
2391
  const foundExt = sourceExt.find(
2392
- (ext) => fs50.existsSync(`${localBin}${ext}`)
2392
+ (ext) => fs51.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 = fs50.realpathSync(this._scriptPath);
2404
+ resolvedScriptPath = fs51.realpathSync(this._scriptPath);
2405
2405
  } catch {
2406
2406
  resolvedScriptPath = this._scriptPath;
2407
2407
  }
2408
- executableDir = path51.resolve(
2409
- path51.dirname(resolvedScriptPath),
2408
+ executableDir = path52.resolve(
2409
+ path52.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 = path51.basename(
2416
+ const legacyName = path52.basename(
2417
2417
  this._scriptPath,
2418
- path51.extname(this._scriptPath)
2418
+ path52.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(path51.extname(executableFile));
2429
+ launchWithNode = sourceExt.includes(path52.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 = path51.basename(filename, path51.extname(filename));
3344
+ this._name = path52.basename(filename, path52.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(path52) {
3359
- if (path52 === void 0) return this._executableDir;
3360
- this._executableDir = path52;
3358
+ executableDir(path53) {
3359
+ if (path53 === void 0) return this._executableDir;
3360
+ this._executableDir = path53;
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, path51) {
3717
- const ctrl = callVisitor(key, node, visitor, path51);
3716
+ function visit_(key, node, visitor, path52) {
3717
+ const ctrl = callVisitor(key, node, visitor, path52);
3718
3718
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3719
- replaceNode(key, path51, ctrl);
3720
- return visit_(key, ctrl, visitor, path51);
3719
+ replaceNode(key, path52, ctrl);
3720
+ return visit_(key, ctrl, visitor, path52);
3721
3721
  }
3722
3722
  if (typeof ctrl !== "symbol") {
3723
3723
  if (identity.isCollection(node)) {
3724
- path51 = Object.freeze(path51.concat(node));
3724
+ path52 = Object.freeze(path52.concat(node));
3725
3725
  for (let i = 0; i < node.items.length; ++i) {
3726
- const ci2 = visit_(i, node.items[i], visitor, path51);
3726
+ const ci2 = visit_(i, node.items[i], visitor, path52);
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
- path51 = Object.freeze(path51.concat(node));
3738
- const ck = visit_("key", node.key, visitor, path51);
3737
+ path52 = Object.freeze(path52.concat(node));
3738
+ const ck = visit_("key", node.key, visitor, path52);
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, path51);
3743
+ const cv = visit_("value", node.value, visitor, path52);
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, path51) {
3765
- const ctrl = await callVisitor(key, node, visitor, path51);
3764
+ async function visitAsync_(key, node, visitor, path52) {
3765
+ const ctrl = await callVisitor(key, node, visitor, path52);
3766
3766
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3767
- replaceNode(key, path51, ctrl);
3768
- return visitAsync_(key, ctrl, visitor, path51);
3767
+ replaceNode(key, path52, ctrl);
3768
+ return visitAsync_(key, ctrl, visitor, path52);
3769
3769
  }
3770
3770
  if (typeof ctrl !== "symbol") {
3771
3771
  if (identity.isCollection(node)) {
3772
- path51 = Object.freeze(path51.concat(node));
3772
+ path52 = Object.freeze(path52.concat(node));
3773
3773
  for (let i = 0; i < node.items.length; ++i) {
3774
- const ci2 = await visitAsync_(i, node.items[i], visitor, path51);
3774
+ const ci2 = await visitAsync_(i, node.items[i], visitor, path52);
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
- path51 = Object.freeze(path51.concat(node));
3786
- const ck = await visitAsync_("key", node.key, visitor, path51);
3785
+ path52 = Object.freeze(path52.concat(node));
3786
+ const ck = await visitAsync_("key", node.key, visitor, path52);
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, path51);
3791
+ const cv = await visitAsync_("value", node.value, visitor, path52);
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, path51) {
3818
+ function callVisitor(key, node, visitor, path52) {
3819
3819
  if (typeof visitor === "function")
3820
- return visitor(key, node, path51);
3820
+ return visitor(key, node, path52);
3821
3821
  if (identity.isMap(node))
3822
- return visitor.Map?.(key, node, path51);
3822
+ return visitor.Map?.(key, node, path52);
3823
3823
  if (identity.isSeq(node))
3824
- return visitor.Seq?.(key, node, path51);
3824
+ return visitor.Seq?.(key, node, path52);
3825
3825
  if (identity.isPair(node))
3826
- return visitor.Pair?.(key, node, path51);
3826
+ return visitor.Pair?.(key, node, path52);
3827
3827
  if (identity.isScalar(node))
3828
- return visitor.Scalar?.(key, node, path51);
3828
+ return visitor.Scalar?.(key, node, path52);
3829
3829
  if (identity.isAlias(node))
3830
- return visitor.Alias?.(key, node, path51);
3830
+ return visitor.Alias?.(key, node, path52);
3831
3831
  return void 0;
3832
3832
  }
3833
- function replaceNode(key, path51, node) {
3834
- const parent = path51[path51.length - 1];
3833
+ function replaceNode(key, path52, node) {
3834
+ const parent = path52[path52.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, path51, value) {
4442
+ function collectionFromPath(schema, path52, value) {
4443
4443
  let v2 = value;
4444
- for (let i = path51.length - 1; i >= 0; --i) {
4445
- const k2 = path51[i];
4444
+ for (let i = path52.length - 1; i >= 0; --i) {
4445
+ const k2 = path52[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 = (path51) => path51 == null || typeof path51 === "object" && !!path51[Symbol.iterator]().next().done;
4464
+ var isEmptyPath = (path52) => path52 == null || typeof path52 === "object" && !!path52[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(path51, value) {
4495
- if (isEmptyPath(path51))
4494
+ addIn(path52, value) {
4495
+ if (isEmptyPath(path52))
4496
4496
  this.add(value);
4497
4497
  else {
4498
- const [key, ...rest] = path51;
4498
+ const [key, ...rest] = path52;
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(path51) {
4513
- const [key, ...rest] = path51;
4512
+ deleteIn(path52) {
4513
+ const [key, ...rest] = path52;
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(path51, keepScalar) {
4528
- const [key, ...rest] = path51;
4527
+ getIn(path52, keepScalar) {
4528
+ const [key, ...rest] = path52;
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(path51) {
4547
- const [key, ...rest] = path51;
4546
+ hasIn(path52) {
4547
+ const [key, ...rest] = path52;
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(path51, value) {
4558
- const [key, ...rest] = path51;
4557
+ setIn(path52, value) {
4558
+ const [key, ...rest] = path52;
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(path51, value) {
7070
+ addIn(path52, value) {
7071
7071
  if (assertCollection(this.contents))
7072
- this.contents.addIn(path51, value);
7072
+ this.contents.addIn(path52, 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(path51) {
7148
- if (Collection.isEmptyPath(path51)) {
7147
+ deleteIn(path52) {
7148
+ if (Collection.isEmptyPath(path52)) {
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(path51) : false;
7154
+ return assertCollection(this.contents) ? this.contents.deleteIn(path52) : 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(path51, keepScalar) {
7170
- if (Collection.isEmptyPath(path51))
7169
+ getIn(path52, keepScalar) {
7170
+ if (Collection.isEmptyPath(path52))
7171
7171
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
7172
- return identity.isCollection(this.contents) ? this.contents.getIn(path51, keepScalar) : void 0;
7172
+ return identity.isCollection(this.contents) ? this.contents.getIn(path52, 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(path51) {
7184
- if (Collection.isEmptyPath(path51))
7183
+ hasIn(path52) {
7184
+ if (Collection.isEmptyPath(path52))
7185
7185
  return this.contents !== void 0;
7186
- return identity.isCollection(this.contents) ? this.contents.hasIn(path51) : false;
7186
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path52) : 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(path51, value) {
7204
- if (Collection.isEmptyPath(path51)) {
7203
+ setIn(path52, value) {
7204
+ if (Collection.isEmptyPath(path52)) {
7205
7205
  this.contents = value;
7206
7206
  } else if (this.contents == null) {
7207
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path51), value);
7207
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path52), value);
7208
7208
  } else if (assertCollection(this.contents)) {
7209
- this.contents.setIn(path51, value);
7209
+ this.contents.setIn(path52, 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, path51) => {
9166
+ visit.itemAtPath = (cst, path52) => {
9167
9167
  let item = cst;
9168
- for (const [field, index] of path51) {
9168
+ for (const [field, index] of path52) {
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, path51) => {
9178
- const parent = visit.itemAtPath(cst, path51.slice(0, -1));
9179
- const field = path51[path51.length - 1][0];
9177
+ visit.parentCollection = (cst, path52) => {
9178
+ const parent = visit.itemAtPath(cst, path52.slice(0, -1));
9179
+ const field = path52[path52.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(path51, item, visitor) {
9186
- let ctrl = visitor(item, path51);
9185
+ function _visit(path52, item, visitor) {
9186
+ let ctrl = visitor(item, path52);
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(path51.concat([[field, i]])), token.items[i], visitor);
9193
+ const ci2 = _visit(Object.freeze(path52.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, path51);
9204
+ ctrl = ctrl(item, path52);
9205
9205
  }
9206
9206
  }
9207
- return typeof ctrl === "function" ? ctrl(item, path51) : ctrl;
9207
+ return typeof ctrl === "function" ? ctrl(item, path52) : 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 fs50 = this.flowScalar(this.type);
10492
+ const fs51 = this.flowScalar(this.type);
10493
10493
  if (atNextItem || it2.value) {
10494
- map.items.push({ start, key: fs50, sep: [] });
10494
+ map.items.push({ start, key: fs51, sep: [] });
10495
10495
  this.onKeyLine = true;
10496
10496
  } else if (it2.sep) {
10497
- this.stack.push(fs50);
10497
+ this.stack.push(fs51);
10498
10498
  } else {
10499
- Object.assign(it2, { key: fs50, sep: [] });
10499
+ Object.assign(it2, { key: fs51, 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 fs50 = this.flowScalar(this.type);
10627
+ const fs51 = this.flowScalar(this.type);
10628
10628
  if (!it2 || it2.value)
10629
- fc.items.push({ start: [], key: fs50, sep: [] });
10629
+ fc.items.push({ start: [], key: fs51, sep: [] });
10630
10630
  else if (it2.sep)
10631
- this.stack.push(fs50);
10631
+ this.stack.push(fs51);
10632
10632
  else
10633
- Object.assign(it2, { key: fs50, sep: [] });
10633
+ Object.assign(it2, { key: fs51, sep: [] });
10634
10634
  return;
10635
10635
  }
10636
10636
  case "flow-map-end":
@@ -15320,6 +15320,13 @@ function extractProvenanceMarker(content) {
15320
15320
  if (jsonProvenance) {
15321
15321
  return jsonProvenance;
15322
15322
  }
15323
+ const yamlMarker = /(?:^|\n)x-(?:tangyr|proteus):\s*\n\s+source:\s*(\S+)\s*\n\s+hash:\s*(sha256:[a-f0-9]+)\s*\n\s+target:\s*(\S+)/u.exec(
15324
+ content
15325
+ );
15326
+ const yamlProvenance = markerFromMatch(yamlMarker);
15327
+ if (yamlProvenance) {
15328
+ return yamlProvenance;
15329
+ }
15323
15330
  return null;
15324
15331
  }
15325
15332
  function markerFromMatch(match) {
@@ -25213,8 +25220,8 @@ function toConflictPolicy2(value) {
25213
25220
  }
25214
25221
 
25215
25222
  // src/commands/install.ts
25216
- import fs44 from "fs";
25217
- import path44 from "path";
25223
+ import fs45 from "fs";
25224
+ import path45 from "path";
25218
25225
 
25219
25226
  // src/core/channel-state.ts
25220
25227
  import fs32 from "fs";
@@ -26980,8 +26987,8 @@ function isRecord3(value) {
26980
26987
  // src/adapters/codex.ts
26981
26988
  var TOML3 = __toESM(require_toml(), 1);
26982
26989
  import crypto6 from "crypto";
26983
- import fs39 from "fs";
26984
- import path38 from "path";
26990
+ import fs40 from "fs";
26991
+ import path39 from "path";
26985
26992
 
26986
26993
  // src/compiler/agents.ts
26987
26994
  var TOML = __toESM(require_toml(), 1);
@@ -27779,6 +27786,45 @@ function addHookLoss(lossReport, target, eventName, sourceLabel, severity, reaso
27779
27786
  });
27780
27787
  }
27781
27788
 
27789
+ // src/compiler/command-as-skill.ts
27790
+ var import_yaml9 = __toESM(require_dist(), 1);
27791
+ import fs38 from "fs";
27792
+ import path37 from "path";
27793
+ var CARRIED_OVER = ["argument-hint", "agent", "launch"];
27794
+ function compileCommandAsSkill(commandFile, target) {
27795
+ const name = path37.basename(commandFile, ".md");
27796
+ const { data, body } = parseMarkdownFrontmatter(commandFile);
27797
+ const relativeSource = `commands/${path37.basename(commandFile)}`;
27798
+ const description = typeof data.description === "string" && data.description.trim().length > 0 ? data.description.trim() : `The ${name} command.`;
27799
+ const frontmatter = { name, description };
27800
+ for (const key of CARRIED_OVER) {
27801
+ if (data[key] !== void 0) {
27802
+ frontmatter[key] = data[key];
27803
+ }
27804
+ }
27805
+ frontmatter["disable-model-invocation"] = true;
27806
+ frontmatter["x-tangyr"] = {
27807
+ source: relativeSource,
27808
+ hash: computeSourceHash(commandFile),
27809
+ target
27810
+ };
27811
+ const content = `---
27812
+ ${(0, import_yaml9.stringify)(frontmatter).trimEnd()}
27813
+ ---
27814
+
27815
+ ${body.trim()}
27816
+ `;
27817
+ return { name, content, relativeSource };
27818
+ }
27819
+ function compileCommandsAsSkills(commandsRoot, target) {
27820
+ if (!fs38.existsSync(commandsRoot)) {
27821
+ return [];
27822
+ }
27823
+ return fs38.readdirSync(commandsRoot).filter((entry) => entry.endsWith(".md")).sort().map(
27824
+ (entry) => compileCommandAsSkill(path37.join(commandsRoot, entry), target)
27825
+ );
27826
+ }
27827
+
27782
27828
  // src/compiler/mcp.ts
27783
27829
  var TOML2 = __toESM(require_toml(), 1);
27784
27830
  import crypto5 from "crypto";
@@ -28058,9 +28104,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
28058
28104
  }
28059
28105
 
28060
28106
  // src/compiler/rules.ts
28061
- import path37 from "path";
28062
- var import_yaml9 = __toESM(require_dist(), 1);
28063
- import fs38 from "fs";
28107
+ import path38 from "path";
28108
+ var import_yaml10 = __toESM(require_dist(), 1);
28109
+ import fs39 from "fs";
28064
28110
  function compileRules(sourceRulesDir, target, _mappings, lossReport) {
28065
28111
  if (target === "copilot") {
28066
28112
  addLoss(lossReport, "copilot", "rules", {
@@ -28097,13 +28143,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
28097
28143
  }
28098
28144
  const appendixParts = [];
28099
28145
  const dotRulesFiles = [];
28100
- for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
28146
+ for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28101
28147
  const parsed = parseRule(ruleFile);
28102
- const name = path37.basename(ruleFile, ".md");
28148
+ const name = path38.basename(ruleFile, ".md");
28103
28149
  if (parsed.mode === "exec-policy") {
28104
28150
  dotRulesFiles.push({
28105
28151
  name: `${name}.rules`,
28106
- content: `${formatProvenanceMarker("toml", `rules/${path37.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
28152
+ content: `${formatProvenanceMarker("toml", `rules/${path38.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
28107
28153
  ${parsed.body}`
28108
28154
  });
28109
28155
  continue;
@@ -28112,7 +28158,7 @@ ${parsed.body}`
28112
28158
 
28113
28159
  ${parsed.body.trim()}`);
28114
28160
  addLoss(lossReport, "codex", "rules", {
28115
- source: `rules/${path37.basename(ruleFile)}`,
28161
+ source: `rules/${path38.basename(ruleFile)}`,
28116
28162
  fields: [
28117
28163
  {
28118
28164
  field: "mode",
@@ -28122,7 +28168,7 @@ ${parsed.body.trim()}`);
28122
28168
  "mode",
28123
28169
  "rule-as-instruction"
28124
28170
  ),
28125
- detail: `${path37.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
28171
+ detail: `${path38.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
28126
28172
  }
28127
28173
  ]
28128
28174
  });
@@ -28130,7 +28176,7 @@ ${parsed.body.trim()}`);
28130
28176
  return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
28131
28177
  }
28132
28178
  function parseRule(ruleFile) {
28133
- const content = fs38.readFileSync(ruleFile, "utf8");
28179
+ const content = fs39.readFileSync(ruleFile, "utf8");
28134
28180
  if (!content.startsWith("---\n")) {
28135
28181
  return { mode: "guidance", body: content };
28136
28182
  }
@@ -28138,7 +28184,7 @@ function parseRule(ruleFile) {
28138
28184
  if (endIndex === -1) {
28139
28185
  throw new Error(`${ruleFile}: frontmatter is not closed`);
28140
28186
  }
28141
- const frontmatter = (0, import_yaml9.parse)(content.slice(4, endIndex));
28187
+ const frontmatter = (0, import_yaml10.parse)(content.slice(4, endIndex));
28142
28188
  const mode = isRuleMode(frontmatter) ? frontmatter.mode : "guidance";
28143
28189
  return {
28144
28190
  mode,
@@ -28154,14 +28200,14 @@ function isRuleMode(value) {
28154
28200
  }
28155
28201
  function compileOpenCodeRules(sourceRulesDir, lossReport) {
28156
28202
  const appendixParts = [];
28157
- for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
28203
+ for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28158
28204
  const parsed = parseRule(ruleFile);
28159
- const name = path37.basename(ruleFile, ".md");
28205
+ const name = path38.basename(ruleFile, ".md");
28160
28206
  appendixParts.push(`## ${name}
28161
28207
 
28162
28208
  ${parsed.body.trim()}`);
28163
28209
  addLoss(lossReport, "opencode", "rules", {
28164
- source: `rules/${path37.basename(ruleFile)}`,
28210
+ source: `rules/${path38.basename(ruleFile)}`,
28165
28211
  fields: [
28166
28212
  {
28167
28213
  field: "rule",
@@ -28171,7 +28217,7 @@ ${parsed.body.trim()}`);
28171
28217
  "rule",
28172
28218
  "rule-path-scoping"
28173
28219
  ),
28174
- detail: `${path37.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
28220
+ detail: `${path38.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
28175
28221
  }
28176
28222
  ]
28177
28223
  });
@@ -28180,9 +28226,9 @@ ${parsed.body.trim()}`);
28180
28226
  }
28181
28227
  function compileCursorRules(sourceRulesDir, _lossReport) {
28182
28228
  const dotRulesFiles = [];
28183
- for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
28184
- const content = fs38.readFileSync(ruleFile, "utf8");
28185
- const name = path37.basename(ruleFile, ".md");
28229
+ for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28230
+ const content = fs39.readFileSync(ruleFile, "utf8");
28231
+ const name = path38.basename(ruleFile, ".md");
28186
28232
  let frontmatterData = {};
28187
28233
  let body = content;
28188
28234
  if (content.startsWith("---\n")) {
@@ -28190,7 +28236,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
28190
28236
  if (endIndex !== -1) {
28191
28237
  const frontmatterStr = content.slice(4, endIndex);
28192
28238
  try {
28193
- frontmatterData = (0, import_yaml9.parse)(frontmatterStr) ?? {};
28239
+ frontmatterData = (0, import_yaml10.parse)(frontmatterStr) ?? {};
28194
28240
  } catch {
28195
28241
  frontmatterData = {};
28196
28242
  }
@@ -28211,7 +28257,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
28211
28257
  }
28212
28258
  const marker = formatProvenanceMarker(
28213
28259
  "markdown",
28214
- `rules/${path37.basename(ruleFile)}`,
28260
+ `rules/${path38.basename(ruleFile)}`,
28215
28261
  computeSourceHash(ruleFile),
28216
28262
  "cursor"
28217
28263
  );
@@ -28227,9 +28273,9 @@ ${body}`;
28227
28273
  }
28228
28274
  function compileClineRules(sourceRulesDir, lossReport) {
28229
28275
  const dotRulesFiles = [];
28230
- for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
28231
- const content = fs38.readFileSync(ruleFile, "utf8");
28232
- const name = path37.basename(ruleFile, ".md");
28276
+ for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28277
+ const content = fs39.readFileSync(ruleFile, "utf8");
28278
+ const name = path38.basename(ruleFile, ".md");
28233
28279
  let frontmatterData = {};
28234
28280
  let body = content;
28235
28281
  if (content.startsWith("---\n")) {
@@ -28237,7 +28283,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
28237
28283
  if (endIndex !== -1) {
28238
28284
  const frontmatterStr = content.slice(4, endIndex);
28239
28285
  try {
28240
- frontmatterData = (0, import_yaml9.parse)(frontmatterStr) ?? {};
28286
+ frontmatterData = (0, import_yaml10.parse)(frontmatterStr) ?? {};
28241
28287
  } catch {
28242
28288
  frontmatterData = {};
28243
28289
  }
@@ -28246,13 +28292,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
28246
28292
  }
28247
28293
  const marker = formatProvenanceMarker(
28248
28294
  "markdown",
28249
- `rules/${path37.basename(ruleFile)}`,
28295
+ `rules/${path38.basename(ruleFile)}`,
28250
28296
  computeSourceHash(ruleFile),
28251
28297
  "cline"
28252
28298
  );
28253
28299
  if (frontmatterData.mode === "exec-policy") {
28254
28300
  addLoss(lossReport, "cline", "rules", {
28255
- source: `rules/${path37.basename(ruleFile)}`,
28301
+ source: `rules/${path38.basename(ruleFile)}`,
28256
28302
  fields: [
28257
28303
  {
28258
28304
  field: "mode",
@@ -28262,7 +28308,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
28262
28308
  "mode",
28263
28309
  "rule-mode-downgrade"
28264
28310
  ),
28265
- detail: `${path37.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28311
+ detail: `${path38.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28266
28312
  }
28267
28313
  ]
28268
28314
  });
@@ -28283,12 +28329,7 @@ ${frontmatterYaml}${body}`;
28283
28329
  }
28284
28330
 
28285
28331
  // src/adapters/codex.ts
28286
- var skippedComponents = [
28287
- "commands",
28288
- "settings",
28289
- "lsp",
28290
- "output-styles"
28291
- ];
28332
+ var skippedComponents = ["settings", "lsp", "output-styles"];
28292
28333
  var managedMcpStart = "# tangyr: managed mcp start";
28293
28334
  var managedMcpEnd = "# tangyr: managed mcp end";
28294
28335
  function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
@@ -28308,7 +28349,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28308
28349
  rules: profile.rules
28309
28350
  };
28310
28351
  const rules = compileRules(
28311
- path38.join(sourceRoot, config.source.rules),
28352
+ path39.join(sourceRoot, config.source.rules),
28312
28353
  "codex",
28313
28354
  mappings,
28314
28355
  lossReport
@@ -28344,7 +28385,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28344
28385
  }
28345
28386
  if (!shouldSkipComponent2(options, "skills")) {
28346
28387
  outcomes.push(
28347
- syncSkills(
28388
+ ...syncSkills(
28348
28389
  config,
28349
28390
  sourceRoot,
28350
28391
  paths,
@@ -28355,6 +28396,20 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28355
28396
  )
28356
28397
  );
28357
28398
  }
28399
+ if (!shouldSkipComponent2(options, "commands")) {
28400
+ outcomes.push(
28401
+ ...syncCommandsAsSkills(
28402
+ config,
28403
+ sourceRoot,
28404
+ paths,
28405
+ options,
28406
+ lossReport,
28407
+ logger,
28408
+ manifest,
28409
+ scopePath
28410
+ )
28411
+ );
28412
+ }
28358
28413
  if (!shouldSkipComponent2(options, "agents")) {
28359
28414
  outcomes.push(
28360
28415
  ...syncAgents(
@@ -28374,7 +28429,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28374
28429
  if (!shouldSkipComponent2(options, "hooks")) {
28375
28430
  outcomes.push(
28376
28431
  syncHookScriptsBridge({
28377
- source: path38.resolve(sourceRoot, config.source.hooks),
28432
+ source: path39.resolve(sourceRoot, config.source.hooks),
28378
28433
  destination: resolveTargetPath(paths.hook_scripts),
28379
28434
  config,
28380
28435
  sourceRoot,
@@ -28473,9 +28528,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28473
28528
  function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
28474
28529
  const cp = mappings.modelTiers.custom_provider;
28475
28530
  if (!cp) return "";
28476
- const agentsDir = path38.join(sourceRoot, config.source.agents);
28477
- if (!fs39.existsSync(agentsDir)) return "";
28478
- const agentFiles = ts(path38.join(agentsDir, "*.md")).sort();
28531
+ const agentsDir = path39.join(sourceRoot, config.source.agents);
28532
+ if (!fs40.existsSync(agentsDir)) return "";
28533
+ const agentFiles = ts(path39.join(agentsDir, "*.md")).sort();
28479
28534
  const hasProviderAgent = agentFiles.some((agentFile) => {
28480
28535
  const { data } = parseMarkdownFrontmatter(agentFile);
28481
28536
  return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
@@ -28540,7 +28595,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
28540
28595
  }
28541
28596
  ];
28542
28597
  for (const ruleFile of rules.dotRulesFiles) {
28543
- const destination = path38.join(rulesRoot, ruleFile.name);
28598
+ const destination = path39.join(rulesRoot, ruleFile.name);
28544
28599
  if (options.dryRun) {
28545
28600
  logger.info(`[dry-run] rules: write ${destination}`);
28546
28601
  outcomes.push({
@@ -28570,16 +28625,16 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
28570
28625
  function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
28571
28626
  const source = instructionsSourcePath(sourceRoot, config);
28572
28627
  const destination = resolveTargetPath(paths.instructions);
28573
- if (!fs39.existsSync(source)) {
28628
+ if (!fs40.existsSync(source)) {
28574
28629
  return skippedMissingSource2("instructions", source);
28575
28630
  }
28576
- const composed = `${fs39.readFileSync(source, "utf8").trim()}
28631
+ const composed = `${fs40.readFileSync(source, "utf8").trim()}
28577
28632
 
28578
28633
  --- tangyr managed rules ---
28579
28634
  ${agentsAppendix}`.trim();
28580
28635
  const marker = formatProvenanceMarker(
28581
28636
  "markdown",
28582
- path38.basename(instructionsSourceLabel(sourceRoot, config)),
28637
+ path39.basename(instructionsSourceLabel(sourceRoot, config)),
28583
28638
  hashString(composed),
28584
28639
  "codex"
28585
28640
  );
@@ -28606,47 +28661,66 @@ ${composed}
28606
28661
  );
28607
28662
  }
28608
28663
  function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
28609
- const source = path38.resolve(sourceRoot, config.source.skills);
28610
- const destination = resolveTargetPath(paths.skills);
28611
- if (!fs39.existsSync(source)) {
28612
- return skippedMissingSource2("skills", source);
28613
- }
28614
- if (options.dryRun) {
28615
- logger.info(`[dry-run] skills: symlink ${source} -> ${destination}`);
28616
- return { component: "skills", status: "dry-run", path: destination };
28617
- }
28618
- const artifactClass = classifyArtifact(destination, config, sourceRoot);
28619
- if (artifactClass === "managed-symlink" && isSymlinkTo4(destination, source)) {
28620
- return {
28621
- component: "skills",
28622
- status: "skipped-current",
28623
- path: destination
28624
- };
28625
- }
28626
- if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
28627
- fs39.unlinkSync(destination);
28628
- logger.verbose(`Skills: created skills path ${destination}`);
28629
- } else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
28630
- return { component: "skills", status: "conflict", path: destination };
28631
- } else if (artifactClass === "managed-symlink") {
28632
- fs39.unlinkSync(destination);
28664
+ return syncSkillsSlot({
28665
+ config,
28666
+ sourceRoot,
28667
+ source: path39.resolve(sourceRoot, config.source.skills),
28668
+ destination: resolveTargetPath(paths.skills),
28669
+ dryRun: options.dryRun,
28670
+ logger,
28671
+ onUnmanagedConflict: (conflictPath) => handleConflict2(
28672
+ conflictPath,
28673
+ config,
28674
+ options,
28675
+ logger,
28676
+ manifest,
28677
+ scopePath
28678
+ )
28679
+ });
28680
+ }
28681
+ function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, logger, manifest, scopePath) {
28682
+ const commandsRoot = path39.resolve(sourceRoot, config.source.commands);
28683
+ if (!fs40.existsSync(commandsRoot)) {
28684
+ return [skippedMissingSource2("commands", commandsRoot)];
28633
28685
  }
28634
- ensureDir(path38.dirname(destination));
28635
- createRelativeSymlink(source, destination, "dir");
28636
- logger.verbose(`Skills: created skills path ${destination}`);
28637
- return { component: "skills", status: "success", path: destination };
28686
+ const skillsRoot = resolveTargetPath(paths.skills);
28687
+ return compileCommandsAsSkills(commandsRoot, "codex").map((skill) => {
28688
+ const destination = path39.join(skillsRoot, skill.name, "SKILL.md");
28689
+ if (options.dryRun) {
28690
+ logger.info(
28691
+ `[dry-run] commands: compile ${skill.relativeSource} -> ${destination}`
28692
+ );
28693
+ return {
28694
+ component: "commands",
28695
+ status: "dry-run",
28696
+ path: destination
28697
+ };
28698
+ }
28699
+ return writeCompiledArtifact(
28700
+ "commands",
28701
+ destination,
28702
+ skill.content,
28703
+ void 0,
28704
+ config,
28705
+ sourceRoot,
28706
+ options,
28707
+ logger,
28708
+ manifest,
28709
+ scopePath
28710
+ );
28711
+ });
28638
28712
  }
28639
28713
  function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
28640
- const sourceAgentsRoot = path38.join(sourceRoot, config.source.agents);
28641
- if (!fs39.existsSync(sourceAgentsRoot)) {
28714
+ const sourceAgentsRoot = path39.join(sourceRoot, config.source.agents);
28715
+ if (!fs40.existsSync(sourceAgentsRoot)) {
28642
28716
  return [skippedMissingSource2("agents", sourceAgentsRoot)];
28643
28717
  }
28644
- const sourceAgents = ts(path38.join(sourceAgentsRoot, "*.md")).sort();
28718
+ const sourceAgents = ts(path39.join(sourceAgentsRoot, "*.md")).sort();
28645
28719
  const agentsRoot = resolveTargetPath(paths.agents);
28646
28720
  return sourceAgents.map((agentFile) => {
28647
- const destination = path38.join(
28721
+ const destination = path39.join(
28648
28722
  agentsRoot,
28649
- `${path38.basename(agentFile, ".md")}.toml`
28723
+ `${path39.basename(agentFile, ".md")}.toml`
28650
28724
  );
28651
28725
  const compiled = compileAgent(
28652
28726
  agentFile,
@@ -28724,7 +28798,7 @@ function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, lo
28724
28798
  destination,
28725
28799
  hostHooks,
28726
28800
  stringifyJson3,
28727
- !fs39.existsSync(destination),
28801
+ !fs40.existsSync(destination),
28728
28802
  logger
28729
28803
  );
28730
28804
  return {
@@ -28737,7 +28811,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
28737
28811
  const source = resolveMcpSourceFile(sourceRoot, config);
28738
28812
  const sourceLabel = mcpSourceLabel(config);
28739
28813
  const destination = resolveTargetPath(paths.mcp_shared_file);
28740
- if (!fs39.existsSync(source)) {
28814
+ if (!fs40.existsSync(source)) {
28741
28815
  if (providerToml && !options.dryRun) {
28742
28816
  const changed2 = writeTomlManagedSection(
28743
28817
  destination,
@@ -28752,7 +28826,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
28752
28826
  }
28753
28827
  return skippedMissingSource2("mcp", source);
28754
28828
  }
28755
- const sourceMcpJson = JSON.parse(fs39.readFileSync(source, "utf8"));
28829
+ const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
28756
28830
  const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
28757
28831
  const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
28758
28832
  if (options.dryRun) {
@@ -28777,18 +28851,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
28777
28851
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
28778
28852
  return { component, status: "conflict", path: destination };
28779
28853
  }
28780
- ensureDir(path38.dirname(destination));
28854
+ ensureDir(path39.dirname(destination));
28781
28855
  const clearedLink = clearSymlinkAtDestination(destination);
28782
28856
  if (clearedLink !== null) {
28783
28857
  logger.verbose(
28784
28858
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
28785
28859
  );
28786
28860
  }
28787
- fs39.writeFileSync(destination, content);
28861
+ fs40.writeFileSync(destination, content);
28788
28862
  return { component, status: "success", path: destination };
28789
28863
  }
28790
28864
  function writeTomlManagedSection(destination, managedContent, logger) {
28791
- const current = fs39.existsSync(destination) ? fs39.readFileSync(destination, "utf8") : "";
28865
+ const current = fs40.existsSync(destination) ? fs40.readFileSync(destination, "utf8") : "";
28792
28866
  const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
28793
28867
  if (isFirstWrite) {
28794
28868
  logger.warn(
@@ -28804,8 +28878,8 @@ ${managedMcpEnd}
28804
28878
  if (current === next.trimStart()) {
28805
28879
  return false;
28806
28880
  }
28807
- ensureDir(path38.dirname(destination));
28808
- fs39.writeFileSync(destination, next.trimStart());
28881
+ ensureDir(path39.dirname(destination));
28882
+ fs40.writeFileSync(destination, next.trimStart());
28809
28883
  return true;
28810
28884
  }
28811
28885
  function removeManagedTomlSection(content) {
@@ -28831,7 +28905,7 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
28831
28905
  if (manifest && scopePath) {
28832
28906
  backupFile(destination, manifest, scopePath);
28833
28907
  writeManifest(scopePath, manifest);
28834
- fs39.rmSync(destination, { recursive: true, force: true });
28908
+ fs40.rmSync(destination, { recursive: true, force: true });
28835
28909
  } else {
28836
28910
  const parked = parkConflictingPath(
28837
28911
  destination,
@@ -28846,12 +28920,12 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
28846
28920
  }
28847
28921
  return true;
28848
28922
  }
28849
- fs39.rmSync(destination, { recursive: true, force: true });
28923
+ fs40.rmSync(destination, { recursive: true, force: true });
28850
28924
  return true;
28851
28925
  }
28852
28926
  function isCompiledCurrent(destination, expectedContent, _expectedHash) {
28853
28927
  try {
28854
- return fs39.readFileSync(destination, "utf8") === expectedContent;
28928
+ return fs40.readFileSync(destination, "utf8") === expectedContent;
28855
28929
  } catch {
28856
28930
  return false;
28857
28931
  }
@@ -28866,18 +28940,11 @@ function skippedMissingSource2(component, source) {
28866
28940
  function shouldSkipComponent2(options, component) {
28867
28941
  return Boolean(options.component && options.component !== component);
28868
28942
  }
28869
- function isSymlinkTo4(linkPath, source) {
28870
- try {
28871
- return fs39.realpathSync(linkPath) === fs39.realpathSync(source);
28872
- } catch {
28873
- return false;
28874
- }
28875
- }
28876
28943
  function readJsonObject4(filePath) {
28877
- if (!fs39.existsSync(filePath)) {
28944
+ if (!fs40.existsSync(filePath)) {
28878
28945
  return {};
28879
28946
  }
28880
- const parsed = JSON.parse(fs39.readFileSync(filePath, "utf8"));
28947
+ const parsed = JSON.parse(fs40.readFileSync(filePath, "utf8"));
28881
28948
  return isRecord5(parsed) ? parsed : {};
28882
28949
  }
28883
28950
  function stringifyJson3(value) {
@@ -28893,16 +28960,16 @@ function hashString(value) {
28893
28960
 
28894
28961
  // src/adapters/copilot.ts
28895
28962
  import crypto7 from "crypto";
28896
- import fs40 from "fs";
28897
- import path40 from "path";
28963
+ import fs41 from "fs";
28964
+ import path41 from "path";
28898
28965
 
28899
28966
  // src/compiler/commands.ts
28900
- var import_yaml10 = __toESM(require_dist(), 1);
28901
- import path39 from "path";
28967
+ var import_yaml11 = __toESM(require_dist(), 1);
28968
+ import path40 from "path";
28902
28969
  function compileCommandPrompt(sourceFile) {
28903
28970
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
28904
- const relativeSource = `commands/${path39.basename(sourceFile)}`;
28905
- const fields = promptFrontmatter(data, path39.basename(sourceFile, ".md"));
28971
+ const relativeSource = `commands/${path40.basename(sourceFile)}`;
28972
+ const fields = promptFrontmatter(data, path40.basename(sourceFile, ".md"));
28906
28973
  const marker = formatProvenanceMarker(
28907
28974
  "markdown",
28908
28975
  relativeSource,
@@ -28911,7 +28978,7 @@ function compileCommandPrompt(sourceFile) {
28911
28978
  );
28912
28979
  return `${marker}
28913
28980
  ---
28914
- ${(0, import_yaml10.stringify)(fields).trim()}
28981
+ ${(0, import_yaml11.stringify)(fields).trim()}
28915
28982
  ---
28916
28983
 
28917
28984
  ${body.trimEnd()}
@@ -29017,7 +29084,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29017
29084
  if (!shouldSkipComponent3(options, "hooks")) {
29018
29085
  outcomes.push(
29019
29086
  syncHookScriptsBridge({
29020
- source: path40.resolve(sourceRoot, config.source.hooks),
29087
+ source: path41.resolve(sourceRoot, config.source.hooks),
29021
29088
  destination: resolveTargetPath(paths.hook_scripts),
29022
29089
  config,
29023
29090
  sourceRoot,
@@ -29098,13 +29165,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29098
29165
  }
29099
29166
  function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
29100
29167
  if (!mappings.modelTiers.custom_provider) return;
29101
- const agentsDir = path40.join(sourceRoot, config.source.agents);
29102
- if (!fs40.existsSync(agentsDir)) return;
29103
- for (const agentFile of ts(path40.join(agentsDir, "*.md")).sort()) {
29168
+ const agentsDir = path41.join(sourceRoot, config.source.agents);
29169
+ if (!fs41.existsSync(agentsDir)) return;
29170
+ for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
29104
29171
  const { data } = parseMarkdownFrontmatter(agentFile);
29105
29172
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
29106
29173
  if (hasProvider) {
29107
- const basename = path40.basename(agentFile);
29174
+ const basename = path41.basename(agentFile);
29108
29175
  addLoss(lossReport, "copilot", "agents", {
29109
29176
  source: `agents/${basename}`,
29110
29177
  fields: [
@@ -29130,22 +29197,22 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
29130
29197
  return [{ component: "instructions", status: "skipped", path: message }];
29131
29198
  }
29132
29199
  const source = instructionsSourcePath(sourceRoot, config);
29133
- if (!fs40.existsSync(source)) {
29200
+ if (!fs41.existsSync(source)) {
29134
29201
  return [skippedMissingSource3("instructions", source)];
29135
29202
  }
29136
- const rawContent = fs40.readFileSync(source, "utf8");
29203
+ const rawContent = fs41.readFileSync(source, "utf8");
29137
29204
  const contentHash = hashString2(rawContent);
29138
29205
  const marker = formatProvenanceMarker(
29139
29206
  "markdown",
29140
- path40.basename(instructionsSourceLabel(sourceRoot, config)),
29207
+ path41.basename(instructionsSourceLabel(sourceRoot, config)),
29141
29208
  contentHash,
29142
29209
  "copilot"
29143
29210
  );
29144
29211
  const composedContent = `${marker}
29145
29212
  ${rawContent}`;
29146
29213
  const projectRoot = options.projectRoot ?? process.cwd();
29147
- const agentsMdDest = path40.resolve(projectRoot, "AGENTS.md");
29148
- const mirrorDest = path40.resolve(
29214
+ const agentsMdDest = path41.resolve(projectRoot, "AGENTS.md");
29215
+ const mirrorDest = path41.resolve(
29149
29216
  projectRoot,
29150
29217
  ".github",
29151
29218
  "copilot-instructions.md"
@@ -29199,14 +29266,14 @@ function writeInstructionsFile(component, destination, content, contentHash, con
29199
29266
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
29200
29267
  return { component, status: "conflict", path: destination };
29201
29268
  }
29202
- ensureDir(path40.dirname(destination));
29269
+ ensureDir(path41.dirname(destination));
29203
29270
  const clearedLink = clearSymlinkAtDestination(destination);
29204
29271
  if (clearedLink !== null) {
29205
29272
  logger.verbose(
29206
29273
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
29207
29274
  );
29208
29275
  }
29209
- fs40.writeFileSync(destination, content);
29276
+ fs41.writeFileSync(destination, content);
29210
29277
  return { component, status: "success", path: destination };
29211
29278
  }
29212
29279
  function hashString2(value) {
@@ -29216,7 +29283,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29216
29283
  return syncSkillsSlot({
29217
29284
  config,
29218
29285
  sourceRoot,
29219
- source: path40.resolve(sourceRoot, config.source.skills),
29286
+ source: path41.resolve(sourceRoot, config.source.skills),
29220
29287
  destination: resolveTargetPath(paths.skills),
29221
29288
  dryRun: options.dryRun,
29222
29289
  logger,
@@ -29231,16 +29298,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29231
29298
  });
29232
29299
  }
29233
29300
  function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29234
- const sourceAgentsRoot = path40.join(sourceRoot, config.source.agents);
29235
- if (!fs40.existsSync(sourceAgentsRoot)) {
29301
+ const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
29302
+ if (!fs41.existsSync(sourceAgentsRoot)) {
29236
29303
  return [skippedMissingSource3("agents", sourceAgentsRoot)];
29237
29304
  }
29238
- const sourceAgents = ts(path40.join(sourceAgentsRoot, "*.md")).sort();
29305
+ const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
29239
29306
  const agentsRoot = resolveTargetPath(paths.agents);
29240
29307
  return sourceAgents.map((agentFile) => {
29241
- const destination = path40.join(
29308
+ const destination = path41.join(
29242
29309
  agentsRoot,
29243
- `${path40.basename(agentFile, ".md")}.agent.md`
29310
+ `${path41.basename(agentFile, ".md")}.agent.md`
29244
29311
  );
29245
29312
  const compiled = compileAgent(
29246
29313
  agentFile,
@@ -29268,16 +29335,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
29268
29335
  });
29269
29336
  }
29270
29337
  function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
29271
- const sourceCommandsRoot = path40.join(sourceRoot, config.source.commands);
29272
- if (!fs40.existsSync(sourceCommandsRoot)) {
29338
+ const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
29339
+ if (!fs41.existsSync(sourceCommandsRoot)) {
29273
29340
  return [skippedMissingSource3("commands", sourceCommandsRoot)];
29274
29341
  }
29275
- const sourceCommands = ts(path40.join(sourceCommandsRoot, "*.md")).sort();
29342
+ const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
29276
29343
  const promptsRoot = resolveTargetPath(paths.prompts);
29277
29344
  return sourceCommands.map((commandFile) => {
29278
- const destination = path40.join(
29345
+ const destination = path41.join(
29279
29346
  promptsRoot,
29280
- `${path40.basename(commandFile, ".md")}.prompt.md`
29347
+ `${path41.basename(commandFile, ".md")}.prompt.md`
29281
29348
  );
29282
29349
  const compiled = compileCommandPrompt(commandFile);
29283
29350
  if (options.dryRun) {
@@ -29301,7 +29368,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
29301
29368
  });
29302
29369
  }
29303
29370
  function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
29304
- const destination = path40.join(
29371
+ const destination = path41.join(
29305
29372
  resolveTargetPath(paths.hooks),
29306
29373
  "tangyr-managed.json"
29307
29374
  );
@@ -29364,10 +29431,10 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
29364
29431
  const source = resolveMcpSourceFile(sourceRoot, config);
29365
29432
  const sourceLabel = mcpSourceLabel(config);
29366
29433
  const destination = resolveTargetPath(paths.mcp_shared_file);
29367
- if (!fs40.existsSync(source)) {
29434
+ if (!fs41.existsSync(source)) {
29368
29435
  return skippedMissingSource3("mcp", source);
29369
29436
  }
29370
- const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
29437
+ const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
29371
29438
  const compiled = compileMcp(
29372
29439
  sourceMcpJson,
29373
29440
  "copilot",
@@ -29400,19 +29467,19 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
29400
29467
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
29401
29468
  return { component, status: "conflict", path: destination };
29402
29469
  }
29403
- ensureDir(path40.dirname(destination));
29470
+ ensureDir(path41.dirname(destination));
29404
29471
  const clearedLink = clearSymlinkAtDestination(destination);
29405
29472
  if (clearedLink !== null) {
29406
29473
  logger.verbose(
29407
29474
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
29408
29475
  );
29409
29476
  }
29410
- fs40.writeFileSync(destination, content);
29477
+ fs41.writeFileSync(destination, content);
29411
29478
  return { component, status: "success", path: destination };
29412
29479
  }
29413
29480
  function isCompiledCurrent2(destination, expectedContent, _expectedHash) {
29414
29481
  try {
29415
- return fs40.readFileSync(destination, "utf8") === expectedContent;
29482
+ return fs41.readFileSync(destination, "utf8") === expectedContent;
29416
29483
  } catch {
29417
29484
  return false;
29418
29485
  }
@@ -29432,7 +29499,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
29432
29499
  if (manifest && scopePath) {
29433
29500
  backupFile(destination, manifest, scopePath);
29434
29501
  writeManifest(scopePath, manifest);
29435
- fs40.rmSync(destination, { recursive: true, force: true });
29502
+ fs41.rmSync(destination, { recursive: true, force: true });
29436
29503
  } else {
29437
29504
  const parked = parkConflictingPath(
29438
29505
  destination,
@@ -29447,7 +29514,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
29447
29514
  }
29448
29515
  return true;
29449
29516
  }
29450
- fs40.rmSync(destination, { recursive: true, force: true });
29517
+ fs41.rmSync(destination, { recursive: true, force: true });
29451
29518
  return true;
29452
29519
  }
29453
29520
  function shouldSkipComponent3(options, component) {
@@ -29456,12 +29523,12 @@ function shouldSkipComponent3(options, component) {
29456
29523
  function cleanupLegacyAgents(paths, options, logger) {
29457
29524
  const currentAgentsRoot = resolveTargetPath(paths.agents);
29458
29525
  const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
29459
- if (path40.resolve(currentAgentsRoot) === path40.resolve(legacyAgentsRoot)) {
29526
+ if (path41.resolve(currentAgentsRoot) === path41.resolve(legacyAgentsRoot)) {
29460
29527
  return [];
29461
29528
  }
29462
29529
  const outcomes = [];
29463
29530
  for (const filePath of ts(
29464
- path40.join(legacyAgentsRoot, "*.agent.md")
29531
+ path41.join(legacyAgentsRoot, "*.agent.md")
29465
29532
  ).sort()) {
29466
29533
  if (!isCopilotManagedCompiledFile(filePath)) {
29467
29534
  continue;
@@ -29471,14 +29538,14 @@ function cleanupLegacyAgents(paths, options, logger) {
29471
29538
  outcomes.push({ component: "agents", status: "dry-run", path: filePath });
29472
29539
  continue;
29473
29540
  }
29474
- fs40.rmSync(filePath, { force: true });
29541
+ fs41.rmSync(filePath, { force: true });
29475
29542
  outcomes.push({ component: "agents", status: "success", path: filePath });
29476
29543
  }
29477
29544
  return outcomes;
29478
29545
  }
29479
29546
  function isCopilotManagedCompiledFile(filePath) {
29480
29547
  try {
29481
- return extractProvenanceMarker(fs40.readFileSync(filePath, "utf8"))?.target === "copilot";
29548
+ return extractProvenanceMarker(fs41.readFileSync(filePath, "utf8"))?.target === "copilot";
29482
29549
  } catch {
29483
29550
  return false;
29484
29551
  }
@@ -29493,8 +29560,8 @@ function skippedMissingSource3(component, source) {
29493
29560
 
29494
29561
  // src/adapters/cursor.ts
29495
29562
  import crypto8 from "crypto";
29496
- import fs41 from "fs";
29497
- import path41 from "path";
29563
+ import fs42 from "fs";
29564
+ import path42 from "path";
29498
29565
  function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29499
29566
  const scope = options.scope ?? "global";
29500
29567
  const profile = resolveTargetPaths({
@@ -29562,7 +29629,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
29562
29629
  }
29563
29630
  if (!shouldSkipComponent4(options, "skills")) {
29564
29631
  outcomes.push(
29565
- syncSkills3(
29632
+ ...syncSkills3(
29566
29633
  config,
29567
29634
  sourceRoot,
29568
29635
  options,
@@ -29576,7 +29643,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
29576
29643
  )
29577
29644
  );
29578
29645
  outcomes.push(
29579
- syncSkills3(
29646
+ ...syncSkills3(
29580
29647
  config,
29581
29648
  sourceRoot,
29582
29649
  options,
@@ -29606,7 +29673,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
29606
29673
  if (!shouldSkipComponent4(options, "hooks")) {
29607
29674
  outcomes.push(
29608
29675
  syncHookScriptsBridge({
29609
- source: path41.resolve(sourceRoot, config.source.hooks),
29676
+ source: path42.resolve(sourceRoot, config.source.hooks),
29610
29677
  destination: resolveTargetPath(paths.hook_scripts),
29611
29678
  config,
29612
29679
  sourceRoot,
@@ -29671,7 +29738,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
29671
29738
  const composed = composeCursorInstructions(config, sourceRoot, lossReport);
29672
29739
  const marker = formatProvenanceMarker(
29673
29740
  "markdown",
29674
- path41.basename(instructionsSourceLabel(sourceRoot, config)),
29741
+ path42.basename(instructionsSourceLabel(sourceRoot, config)),
29675
29742
  hashString3(composed),
29676
29743
  "cursor"
29677
29744
  );
@@ -29697,7 +29764,7 @@ ${composed}
29697
29764
  }
29698
29765
  function composeCursorInstructions(config, sourceRoot, lossReport) {
29699
29766
  const source = instructionsSourcePath(sourceRoot, config);
29700
- const baseContent = fs41.existsSync(source) ? fs41.readFileSync(source, "utf8").trim() : "";
29767
+ const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
29701
29768
  const personaContent = extractPrimaryPersonaContent(
29702
29769
  config,
29703
29770
  sourceRoot,
@@ -29710,11 +29777,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
29710
29777
  ${personaContent}`.trim() : baseContent;
29711
29778
  }
29712
29779
  function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29713
- const agentsDir = path41.join(sourceRoot, config.source.agents);
29714
- if (!fs41.existsSync(agentsDir)) {
29780
+ const agentsDir = path42.join(sourceRoot, config.source.agents);
29781
+ if (!fs42.existsSync(agentsDir)) {
29715
29782
  return null;
29716
29783
  }
29717
- const agentFiles = ts(path41.join(agentsDir, "*.md")).sort();
29784
+ const agentFiles = ts(path42.join(agentsDir, "*.md")).sort();
29718
29785
  if (agentFiles.length === 0) {
29719
29786
  return null;
29720
29787
  }
@@ -29737,7 +29804,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29737
29804
  return null;
29738
29805
  }
29739
29806
  addLoss(lossReport, "cursor", "instructions", {
29740
- source: `agents/${path41.basename(primaryFile)}`,
29807
+ source: `agents/${path42.basename(primaryFile)}`,
29741
29808
  fields: [
29742
29809
  {
29743
29810
  field: "persona",
@@ -29747,23 +29814,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29747
29814
  "persona",
29748
29815
  "instructions-shim"
29749
29816
  ),
29750
- detail: `Primary persona from ${path41.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
29817
+ detail: `Primary persona from ${path42.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
29751
29818
  }
29752
29819
  ]
29753
29820
  });
29754
29821
  return body.trim();
29755
29822
  }
29756
29823
  function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29757
- const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
29758
- if (!fs41.existsSync(sourceAgentsRoot)) {
29824
+ const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
29825
+ if (!fs42.existsSync(sourceAgentsRoot)) {
29759
29826
  return [skippedMissingSource4("agents", sourceAgentsRoot)];
29760
29827
  }
29761
- const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
29828
+ const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
29762
29829
  const agentsRoot = resolveTargetPath(paths.agents);
29763
29830
  return sourceAgents.map((agentFile) => {
29764
- const destination = path41.join(
29831
+ const destination = path42.join(
29765
29832
  agentsRoot,
29766
- `${path41.basename(agentFile, ".md")}.md`
29833
+ `${path42.basename(agentFile, ".md")}.md`
29767
29834
  );
29768
29835
  let compiled;
29769
29836
  try {
@@ -29804,14 +29871,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
29804
29871
  });
29805
29872
  }
29806
29873
  function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
29807
- const sourceRulesDir = path41.join(sourceRoot, config.source.rules);
29808
- if (!fs41.existsSync(sourceRulesDir)) {
29874
+ const sourceRulesDir = path42.join(sourceRoot, config.source.rules);
29875
+ if (!fs42.existsSync(sourceRulesDir)) {
29809
29876
  return [skippedMissingSource4("rules", sourceRulesDir)];
29810
29877
  }
29811
29878
  const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
29812
29879
  const rulesDir = resolveTargetPath(paths.rules);
29813
29880
  return compiled.dotRulesFiles.map(({ name, content }) => {
29814
- const destination = path41.join(rulesDir, name);
29881
+ const destination = path42.join(rulesDir, name);
29815
29882
  if (options.dryRun) {
29816
29883
  logger.info(`[dry-run] rules: write ${destination}`);
29817
29884
  return {
@@ -29835,30 +29902,16 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
29835
29902
  });
29836
29903
  }
29837
29904
  function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
29838
- const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
29839
- if (!fs41.existsSync(sourceCommandsRoot)) {
29905
+ const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
29906
+ if (!fs42.existsSync(sourceCommandsRoot)) {
29840
29907
  return [skippedMissingSource4("commands", sourceCommandsRoot)];
29841
29908
  }
29842
- const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
29909
+ const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
29843
29910
  const skillsRoot = resolveTargetPath(paths.skills);
29844
29911
  return sourceCommands.map((commandFile) => {
29845
- const baseName = path41.basename(commandFile, ".md");
29846
- const destination = path41.join(skillsRoot, baseName, "SKILL.md");
29847
- const commandContent = fs41.readFileSync(commandFile, "utf8");
29848
- const relativeSource = `commands/${path41.basename(commandFile)}`;
29849
- const marker = formatProvenanceMarker(
29850
- "markdown",
29851
- relativeSource,
29852
- computeSourceHash(commandFile),
29853
- "cursor"
29854
- );
29855
- const content = `${marker}
29856
- ---
29857
- disable-model-invocation: true
29858
- ---
29859
-
29860
- ${commandContent.trim()}
29861
- `;
29912
+ const baseName = path42.basename(commandFile, ".md");
29913
+ const destination = path42.join(skillsRoot, baseName, "SKILL.md");
29914
+ const { content } = compileCommandAsSkill(commandFile, "cursor");
29862
29915
  if (options.dryRun) {
29863
29916
  logger.info(
29864
29917
  `[dry-run] commands: compile ${commandFile} -> ${destination}`
@@ -29883,39 +29936,23 @@ ${commandContent.trim()}
29883
29936
  );
29884
29937
  });
29885
29938
  }
29886
- function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
29887
- const source = path41.resolve(sourceRoot, config.source.skills);
29888
- if (!fs41.existsSync(source)) {
29889
- return skippedMissingSource4(component, source);
29890
- }
29891
- if (options.dryRun) {
29892
- const verb = asSymlink ? "symlink" : "ensuredir";
29893
- logger.info(`[dry-run] ${component}: ${verb} ${source} -> ${destination}`);
29894
- return { component, status: "dry-run", path: destination };
29895
- }
29896
- if (asSymlink) {
29897
- const artifactClass = classifyArtifact(destination, config, sourceRoot);
29898
- if (artifactClass === "managed-symlink" && isSymlinkTo5(destination, source)) {
29899
- return { component, status: "skipped-current", path: destination };
29900
- }
29901
- if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
29902
- fs41.unlinkSync(destination);
29903
- } else if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
29904
- return { component, status: "conflict", path: destination };
29905
- } else if (artifactClass === "managed-symlink") {
29906
- fs41.unlinkSync(destination);
29907
- }
29908
- ensureDir(path41.dirname(destination));
29909
- createRelativeSymlink(source, destination, "dir");
29910
- logger.verbose(`Skills: created shared skills symlink ${destination}`);
29911
- return { component, status: "success", path: destination };
29912
- }
29913
- if (fs41.existsSync(destination)) {
29914
- return { component, status: "skipped-current", path: destination };
29915
- }
29916
- ensureDir(destination);
29917
- logger.verbose(`Skills: ensured Cursor-local skills dir ${destination}`);
29918
- return { component, status: "success", path: destination };
29939
+ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, _component = "skills", destination = "", _asSymlink = false) {
29940
+ return syncSkillsSlot({
29941
+ config,
29942
+ sourceRoot,
29943
+ source: path42.resolve(sourceRoot, config.source.skills),
29944
+ destination,
29945
+ dryRun: options.dryRun,
29946
+ logger,
29947
+ onUnmanagedConflict: (conflictPath) => handleConflict4(
29948
+ conflictPath,
29949
+ config,
29950
+ options,
29951
+ logger,
29952
+ manifest,
29953
+ scopePath
29954
+ )
29955
+ });
29919
29956
  }
29920
29957
  function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, logger) {
29921
29958
  const scripts = hookScriptsDir(
@@ -29951,18 +29988,18 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
29951
29988
  }
29952
29989
  const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
29953
29990
  `;
29954
- ensureDir(path41.dirname(destination));
29955
- fs41.writeFileSync(destination, hooksFileContent);
29991
+ ensureDir(path42.dirname(destination));
29992
+ fs42.writeFileSync(destination, hooksFileContent);
29956
29993
  return { component: "hooks", status: "success", path: destination };
29957
29994
  }
29958
29995
  function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
29959
29996
  const source = resolveMcpSourceFile(sourceRoot, config);
29960
29997
  const sourceLabel = mcpSourceLabel(config);
29961
29998
  const destination = resolveTargetPath(paths.mcp_file);
29962
- if (!fs41.existsSync(source)) {
29999
+ if (!fs42.existsSync(source)) {
29963
30000
  return skippedMissingSource4("mcp", source);
29964
30001
  }
29965
- const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
30002
+ const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
29966
30003
  const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
29967
30004
  if (options.dryRun) {
29968
30005
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -30015,13 +30052,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
30015
30052
  );
30016
30053
  }
30017
30054
  function syncProviderPin(config, sourceRoot, lossReport) {
30018
- const agentsDir = path41.join(sourceRoot, config.source.agents);
30019
- if (!fs41.existsSync(agentsDir)) return;
30020
- for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
30055
+ const agentsDir = path42.join(sourceRoot, config.source.agents);
30056
+ if (!fs42.existsSync(agentsDir)) return;
30057
+ for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
30021
30058
  const { data } = parseMarkdownFrontmatter(agentFile);
30022
30059
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30023
30060
  if (hasCustomProvider) {
30024
- const relativeSource = `agents/${path41.basename(agentFile)}`;
30061
+ const relativeSource = `agents/${path42.basename(agentFile)}`;
30025
30062
  addLoss(lossReport, "cursor", "agents", {
30026
30063
  source: relativeSource,
30027
30064
  fields: [
@@ -30033,7 +30070,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
30033
30070
  "provider",
30034
30071
  "provider-not-representable"
30035
30072
  ),
30036
- detail: `${path41.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
30073
+ detail: `${path42.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
30037
30074
  }
30038
30075
  ]
30039
30076
  });
@@ -30051,14 +30088,14 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
30051
30088
  if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
30052
30089
  return { component, status: "conflict", path: destination };
30053
30090
  }
30054
- ensureDir(path41.dirname(destination));
30091
+ ensureDir(path42.dirname(destination));
30055
30092
  const clearedLink = clearSymlinkAtDestination(destination);
30056
30093
  if (clearedLink !== null) {
30057
30094
  logger.verbose(
30058
30095
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
30059
30096
  );
30060
30097
  }
30061
- fs41.writeFileSync(destination, content);
30098
+ fs42.writeFileSync(destination, content);
30062
30099
  return { component, status: "success", path: destination };
30063
30100
  }
30064
30101
  function handleConflict4(destination, config, options, logger, manifest, scopePath) {
@@ -30076,7 +30113,7 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
30076
30113
  if (manifest && scopePath) {
30077
30114
  backupFile(destination, manifest, scopePath);
30078
30115
  writeManifest(scopePath, manifest);
30079
- fs41.rmSync(destination, { recursive: true, force: true });
30116
+ fs42.rmSync(destination, { recursive: true, force: true });
30080
30117
  } else {
30081
30118
  const parked = parkConflictingPath(
30082
30119
  destination,
@@ -30091,12 +30128,12 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
30091
30128
  }
30092
30129
  return true;
30093
30130
  }
30094
- fs41.rmSync(destination, { recursive: true, force: true });
30131
+ fs42.rmSync(destination, { recursive: true, force: true });
30095
30132
  return true;
30096
30133
  }
30097
30134
  function isCompiledCurrent3(destination, expectedContent, _expectedHash) {
30098
30135
  try {
30099
- return fs41.readFileSync(destination, "utf8") === expectedContent;
30136
+ return fs42.readFileSync(destination, "utf8") === expectedContent;
30100
30137
  } catch {
30101
30138
  return false;
30102
30139
  }
@@ -30111,21 +30148,14 @@ function skippedMissingSource4(component, source) {
30111
30148
  function shouldSkipComponent4(options, component) {
30112
30149
  return Boolean(options.component && options.component !== component);
30113
30150
  }
30114
- function isSymlinkTo5(linkPath, source) {
30115
- try {
30116
- return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
30117
- } catch {
30118
- return false;
30119
- }
30120
- }
30121
30151
  function hashString3(value) {
30122
30152
  return `sha256:${crypto8.createHash("sha256").update(value).digest("hex")}`;
30123
30153
  }
30124
30154
 
30125
30155
  // src/adapters/cline.ts
30126
30156
  import crypto9 from "crypto";
30127
- import fs42 from "fs";
30128
- import path42 from "path";
30157
+ import fs43 from "fs";
30158
+ import path43 from "path";
30129
30159
  function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30130
30160
  const scope = options.scope ?? "global";
30131
30161
  const profile = resolveTargetPaths({
@@ -30200,7 +30230,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
30200
30230
  }
30201
30231
  if (!shouldSkipComponent5(options, "skills")) {
30202
30232
  outcomes.push(
30203
- syncSkills4(
30233
+ ...syncSkills4(
30204
30234
  config,
30205
30235
  sourceRoot,
30206
30236
  paths,
@@ -30238,7 +30268,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
30238
30268
  function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
30239
30269
  if (scope === "global" || paths.instructions === null) {
30240
30270
  addLoss(lossReport, "cline", "instructions", {
30241
- source: path42.basename(instructionsSourceLabel(sourceRoot, config)),
30271
+ source: path43.basename(instructionsSourceLabel(sourceRoot, config)),
30242
30272
  fields: [
30243
30273
  {
30244
30274
  field: "instructions",
@@ -30260,10 +30290,10 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
30260
30290
  }
30261
30291
  const source = instructionsSourcePath(sourceRoot, config);
30262
30292
  const destination = resolveTargetPath(paths.instructions);
30263
- const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
30293
+ const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
30264
30294
  const marker = formatProvenanceMarker(
30265
30295
  "markdown",
30266
- path42.basename(instructionsSourceLabel(sourceRoot, config)),
30296
+ path43.basename(instructionsSourceLabel(sourceRoot, config)),
30267
30297
  hashString4(baseContent),
30268
30298
  "cline"
30269
30299
  );
@@ -30288,11 +30318,11 @@ ${baseContent}
30288
30318
  );
30289
30319
  }
30290
30320
  function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
30291
- const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
30292
- if (!fs42.existsSync(sourceAgentsRoot)) {
30321
+ const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
30322
+ if (!fs43.existsSync(sourceAgentsRoot)) {
30293
30323
  return [skippedMissingSource5("agents", sourceAgentsRoot)];
30294
30324
  }
30295
- const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
30325
+ const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
30296
30326
  return sourceAgents.map((agentFile) => {
30297
30327
  compileAgent(agentFile, "cline", mappings, extensions, lossReport);
30298
30328
  if (options.dryRun) {
@@ -30308,14 +30338,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
30308
30338
  });
30309
30339
  }
30310
30340
  function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
30311
- const sourceRulesDir = path42.join(sourceRoot, config.source.rules);
30312
- if (!fs42.existsSync(sourceRulesDir)) {
30341
+ const sourceRulesDir = path43.join(sourceRoot, config.source.rules);
30342
+ if (!fs43.existsSync(sourceRulesDir)) {
30313
30343
  return [skippedMissingSource5("rules", sourceRulesDir)];
30314
30344
  }
30315
30345
  const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
30316
30346
  const rulesDir = resolveTargetPath(paths.rules);
30317
30347
  return compiled.dotRulesFiles.map(({ name, content }) => {
30318
- const destination = path42.join(rulesDir, name);
30348
+ const destination = path43.join(rulesDir, name);
30319
30349
  if (options.dryRun) {
30320
30350
  logger.info(`[dry-run] rules: write ${destination}`);
30321
30351
  return {
@@ -30339,17 +30369,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
30339
30369
  });
30340
30370
  }
30341
30371
  function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30342
- const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
30343
- if (!fs42.existsSync(sourceCommandsRoot)) {
30372
+ const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
30373
+ if (!fs43.existsSync(sourceCommandsRoot)) {
30344
30374
  return [skippedMissingSource5("commands", sourceCommandsRoot)];
30345
30375
  }
30346
- const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
30376
+ const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
30347
30377
  const workflowsRoot = resolveTargetPath(paths.workflows);
30348
30378
  return sourceCommands.map((commandFile) => {
30349
- const baseName = path42.basename(commandFile);
30350
- const destination = path42.join(workflowsRoot, baseName);
30351
- const commandContent = fs42.readFileSync(commandFile, "utf8");
30352
- const relativeSource = `commands/${path42.basename(commandFile)}`;
30379
+ const baseName = path43.basename(commandFile);
30380
+ const destination = path43.join(workflowsRoot, baseName);
30381
+ const commandContent = fs43.readFileSync(commandFile, "utf8");
30382
+ const relativeSource = `commands/${path43.basename(commandFile)}`;
30353
30383
  const marker = formatProvenanceMarker(
30354
30384
  "markdown",
30355
30385
  relativeSource,
@@ -30384,44 +30414,22 @@ ${commandContent.trim()}
30384
30414
  });
30385
30415
  }
30386
30416
  function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30387
- const source = path42.resolve(sourceRoot, config.source.skills);
30388
- const destination = resolveTargetPath(paths.skills);
30389
- if (!fs42.existsSync(source)) {
30390
- return skippedMissingSource5("skills", source);
30391
- }
30392
- if (options.dryRun) {
30393
- logger.info(`[dry-run] skills: symlink ${source} -> ${destination}`);
30394
- return { component: "skills", status: "dry-run", path: destination };
30395
- }
30396
- const artifactClass = classifyArtifact(destination, config, sourceRoot);
30397
- if (artifactClass === "managed-symlink" && isSymlinkTo6(destination, source)) {
30398
- return {
30399
- component: "skills",
30400
- status: "skipped-current",
30401
- path: destination
30402
- };
30403
- }
30404
- if (
30405
- // A stale symlink from a superseded source root. Every other adapter
30406
- // unlinks it here; this one did not, so classifyArtifact's `managed-stale`
30407
- // matched no branch, fell through, and handed symlinkSync a path that
30408
- // already existed. Measured: sync died with "EEXIST: file already exists,
30409
- // symlink … -> ~/.cline/skills" and every component after skills went
30410
- // unsynced.
30411
- artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)
30412
- ) {
30413
- fs42.unlinkSync(destination);
30414
- } else if (artifactClass === "unmanaged-conflict") {
30415
- if (!handleConflict5(destination, config, options, logger, manifest, scopePath)) {
30416
- return { component: "skills", status: "conflict", path: destination };
30417
- }
30418
- } else if (artifactClass === "managed-symlink") {
30419
- fs42.unlinkSync(destination);
30420
- }
30421
- ensureDir(path42.dirname(destination));
30422
- createRelativeSymlink(source, destination, "dir");
30423
- logger.verbose(`Skills: created Cline skills symlink ${destination}`);
30424
- return { component: "skills", status: "success", path: destination };
30417
+ return syncSkillsSlot({
30418
+ config,
30419
+ sourceRoot,
30420
+ source: path43.resolve(sourceRoot, config.source.skills),
30421
+ destination: resolveTargetPath(paths.skills),
30422
+ dryRun: options.dryRun,
30423
+ logger,
30424
+ onUnmanagedConflict: (conflictPath) => handleConflict5(
30425
+ conflictPath,
30426
+ config,
30427
+ options,
30428
+ logger,
30429
+ manifest,
30430
+ scopePath
30431
+ )
30432
+ });
30425
30433
  }
30426
30434
  function syncHooks5(config, sourceRoot, mappings, options, lossReport, logger) {
30427
30435
  const hooksSource = loadKitHooksSource(sourceRoot, config);
@@ -30442,10 +30450,10 @@ function syncMcp5(config, sourceRoot, paths, options, lossReport, logger, manife
30442
30450
  const source = resolveMcpSourceFile(sourceRoot, config);
30443
30451
  const sourceLabel = mcpSourceLabel(config);
30444
30452
  const destination = resolveTargetPath(paths.mcp_file);
30445
- if (!fs42.existsSync(source)) {
30453
+ if (!fs43.existsSync(source)) {
30446
30454
  return skippedMissingSource5("mcp", source);
30447
30455
  }
30448
- const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
30456
+ const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
30449
30457
  const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
30450
30458
  if (options.dryRun) {
30451
30459
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -30488,11 +30496,11 @@ function syncSettings2(lossReport) {
30488
30496
  };
30489
30497
  }
30490
30498
  function syncProviderAndModel(config, sourceRoot, lossReport) {
30491
- const agentsDir = path42.join(sourceRoot, config.source.agents);
30492
- if (!fs42.existsSync(agentsDir)) return;
30493
- for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
30499
+ const agentsDir = path43.join(sourceRoot, config.source.agents);
30500
+ if (!fs43.existsSync(agentsDir)) return;
30501
+ for (const agentFile of ts(path43.join(agentsDir, "*.md")).sort()) {
30494
30502
  const { data } = parseMarkdownFrontmatter(agentFile);
30495
- const relativeSource = `agents/${path42.basename(agentFile)}`;
30503
+ const relativeSource = `agents/${path43.basename(agentFile)}`;
30496
30504
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30497
30505
  if (hasCustomProvider) {
30498
30506
  addLoss(lossReport, "cline", "agents", {
@@ -30506,7 +30514,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
30506
30514
  "provider",
30507
30515
  "provider-not-representable"
30508
30516
  ),
30509
- detail: `${path42.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
30517
+ detail: `${path43.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
30510
30518
  }
30511
30519
  ]
30512
30520
  });
@@ -30524,7 +30532,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
30524
30532
  "model",
30525
30533
  "model-not-representable"
30526
30534
  ),
30527
- detail: `${path42.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
30535
+ detail: `${path43.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
30528
30536
  }
30529
30537
  ]
30530
30538
  });
@@ -30542,14 +30550,14 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
30542
30550
  if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
30543
30551
  return { component, status: "conflict", path: destination };
30544
30552
  }
30545
- ensureDir(path42.dirname(destination));
30553
+ ensureDir(path43.dirname(destination));
30546
30554
  const clearedLink = clearSymlinkAtDestination(destination);
30547
30555
  if (clearedLink !== null) {
30548
30556
  logger.verbose(
30549
30557
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
30550
30558
  );
30551
30559
  }
30552
- fs42.writeFileSync(destination, content);
30560
+ fs43.writeFileSync(destination, content);
30553
30561
  return { component, status: "success", path: destination };
30554
30562
  }
30555
30563
  function handleConflict5(destination, config, options, logger, manifest, scopePath) {
@@ -30567,7 +30575,7 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
30567
30575
  if (manifest && scopePath) {
30568
30576
  backupFile(destination, manifest, scopePath);
30569
30577
  writeManifest(scopePath, manifest);
30570
- fs42.rmSync(destination, { recursive: true, force: true });
30578
+ fs43.rmSync(destination, { recursive: true, force: true });
30571
30579
  } else {
30572
30580
  const parked = parkConflictingPath(
30573
30581
  destination,
@@ -30582,12 +30590,12 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
30582
30590
  }
30583
30591
  return true;
30584
30592
  }
30585
- fs42.rmSync(destination, { recursive: true, force: true });
30593
+ fs43.rmSync(destination, { recursive: true, force: true });
30586
30594
  return true;
30587
30595
  }
30588
30596
  function isCompiledCurrent4(destination, expectedContent, _expectedHash) {
30589
30597
  try {
30590
- return fs42.readFileSync(destination, "utf8") === expectedContent;
30598
+ return fs43.readFileSync(destination, "utf8") === expectedContent;
30591
30599
  } catch {
30592
30600
  return false;
30593
30601
  }
@@ -30602,23 +30610,16 @@ function skippedMissingSource5(component, source) {
30602
30610
  function shouldSkipComponent5(options, component) {
30603
30611
  return Boolean(options.component && options.component !== component);
30604
30612
  }
30605
- function isSymlinkTo6(linkPath, source) {
30606
- try {
30607
- return fs42.realpathSync(linkPath) === fs42.realpathSync(source);
30608
- } catch {
30609
- return false;
30610
- }
30611
- }
30612
30613
  function hashString4(value) {
30613
30614
  return `sha256:${crypto9.createHash("sha256").update(value).digest("hex")}`;
30614
30615
  }
30615
30616
 
30616
30617
  // src/adapters/opencode.ts
30617
30618
  import crypto10 from "crypto";
30618
- import fs43 from "fs";
30619
+ import fs44 from "fs";
30619
30620
  import os6 from "os";
30620
- import path43 from "path";
30621
- var import_yaml11 = __toESM(require_dist(), 1);
30621
+ import path44 from "path";
30622
+ var import_yaml12 = __toESM(require_dist(), 1);
30622
30623
  function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30623
30624
  const scope = options.scope ?? "global";
30624
30625
  const profile = resolveTargetPaths({
@@ -30635,7 +30636,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30635
30636
  config_doc: profile.config_doc
30636
30637
  };
30637
30638
  const rules = compileRules(
30638
- path43.join(sourceRoot, config.source.rules),
30639
+ path44.join(sourceRoot, config.source.rules),
30639
30640
  "opencode",
30640
30641
  mappings,
30641
30642
  lossReport
@@ -30686,7 +30687,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30686
30687
  }
30687
30688
  if (!shouldSkipComponent6(options, "skills")) {
30688
30689
  outcomes.push(
30689
- syncSkills5(
30690
+ ...syncSkills5(
30690
30691
  config,
30691
30692
  sourceRoot,
30692
30693
  paths,
@@ -30699,7 +30700,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30699
30700
  )
30700
30701
  );
30701
30702
  outcomes.push(
30702
- syncSkills5(
30703
+ ...syncSkills5(
30703
30704
  config,
30704
30705
  sourceRoot,
30705
30706
  paths,
@@ -30739,14 +30740,14 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30739
30740
  function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
30740
30741
  const source = instructionsSourcePath(sourceRoot, config);
30741
30742
  const destination = resolveTargetPath(paths.instructions);
30742
- const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
30743
+ const baseContent = fs44.existsSync(source) ? fs44.readFileSync(source, "utf8").trim() : "";
30743
30744
  const composed = agentsAppendix ? `${baseContent}
30744
30745
 
30745
30746
  --- tangyr managed rules ---
30746
30747
  ${agentsAppendix}`.trim() : baseContent;
30747
30748
  const marker = formatProvenanceMarker(
30748
30749
  "markdown",
30749
- path43.basename(instructionsSourceLabel(sourceRoot, config)),
30750
+ path44.basename(instructionsSourceLabel(sourceRoot, config)),
30750
30751
  hashString5(composed),
30751
30752
  "opencode"
30752
30753
  );
@@ -30773,16 +30774,16 @@ ${composed}
30773
30774
  );
30774
30775
  }
30775
30776
  function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30776
- const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
30777
- if (!fs43.existsSync(sourceAgentsRoot)) {
30777
+ const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
30778
+ if (!fs44.existsSync(sourceAgentsRoot)) {
30778
30779
  return [skippedMissingSource6("agents", sourceAgentsRoot)];
30779
30780
  }
30780
- const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
30781
+ const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
30781
30782
  const agentsRoot = resolveTargetPath(paths.agents);
30782
30783
  return sourceAgents.map((agentFile) => {
30783
- const destination = path43.join(
30784
+ const destination = path44.join(
30784
30785
  agentsRoot,
30785
- `${path43.basename(agentFile, ".md")}.md`
30786
+ `${path44.basename(agentFile, ".md")}.md`
30786
30787
  );
30787
30788
  let compiled;
30788
30789
  try {
@@ -30838,19 +30839,19 @@ function applyProviderModelBinding(compiled, mappings) {
30838
30839
  const after = compiled.slice(fmEnd);
30839
30840
  let fields;
30840
30841
  try {
30841
- fields = (0, import_yaml11.parse)(yamlBlock) ?? {};
30842
+ fields = (0, import_yaml12.parse)(yamlBlock) ?? {};
30842
30843
  } catch {
30843
30844
  return compiled;
30844
30845
  }
30845
30846
  fields.model = modelValue;
30846
- return `${before}${(0, import_yaml11.stringify)(fields).trim()}${after}`;
30847
+ return `${before}${(0, import_yaml12.stringify)(fields).trim()}${after}`;
30847
30848
  }
30848
30849
  function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30849
- const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
30850
- if (!fs43.existsSync(sourceCommandsRoot)) {
30850
+ const sourceCommandsRoot = path44.join(sourceRoot, config.source.commands);
30851
+ if (!fs44.existsSync(sourceCommandsRoot)) {
30851
30852
  return [skippedMissingSource6("commands", sourceCommandsRoot)];
30852
30853
  }
30853
- const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
30854
+ const sourceCommands = ts(path44.join(sourceCommandsRoot, "*.md")).sort();
30854
30855
  const commandsRoot = resolveTargetPath(paths.commands);
30855
30856
  return sourceCommands.map((commandFile) => {
30856
30857
  const { data, body } = parseCommandFile(commandFile);
@@ -30864,7 +30865,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
30864
30865
  if (typeof data.model === "string") {
30865
30866
  frontmatter.model = data.model;
30866
30867
  }
30867
- const relativeSource = `commands/${path43.basename(commandFile)}`;
30868
+ const relativeSource = `commands/${path44.basename(commandFile)}`;
30868
30869
  const marker = formatProvenanceMarker(
30869
30870
  "markdown",
30870
30871
  relativeSource,
@@ -30873,16 +30874,16 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
30873
30874
  );
30874
30875
  const content = Object.keys(frontmatter).length > 0 ? `${marker}
30875
30876
  ---
30876
- ${(0, import_yaml11.stringify)(frontmatter).trim()}
30877
+ ${(0, import_yaml12.stringify)(frontmatter).trim()}
30877
30878
  ---
30878
30879
 
30879
30880
  ${body.trimEnd()}
30880
30881
  ` : `${marker}
30881
30882
  ${body.trimEnd()}
30882
30883
  `;
30883
- const destination = path43.join(
30884
+ const destination = path44.join(
30884
30885
  commandsRoot,
30885
- `${path43.basename(commandFile, ".md")}.md`
30886
+ `${path44.basename(commandFile, ".md")}.md`
30886
30887
  );
30887
30888
  if (options.dryRun) {
30888
30889
  logger.info(
@@ -30908,42 +30909,35 @@ ${body.trimEnd()}
30908
30909
  );
30909
30910
  });
30910
30911
  }
30911
- function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
30912
- const source = path43.resolve(sourceRoot, config.source.skills);
30913
- if (!fs43.existsSync(source)) {
30914
- return skippedMissingSource6(component, source);
30915
- }
30916
- if (options.dryRun) {
30917
- logger.info(`[dry-run] ${component}: symlink ${source} -> ${destination}`);
30918
- return { component, status: "dry-run", path: destination };
30919
- }
30920
- const artifactClass = classifyArtifact(destination, config, sourceRoot);
30921
- if (artifactClass === "managed-symlink" && isSymlinkTo7(destination, source)) {
30922
- return { component, status: "skipped-current", path: destination };
30923
- }
30924
- if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
30925
- fs43.unlinkSync(destination);
30926
- } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
30927
- return { component, status: "conflict", path: destination };
30928
- } else if (artifactClass === "managed-symlink") {
30929
- fs43.unlinkSync(destination);
30930
- }
30931
- ensureDir(path43.dirname(destination));
30932
- createRelativeSymlink(source, destination, "dir");
30933
- logger.verbose(`Skills: created skills path ${destination}`);
30934
- return { component, status: "success", path: destination };
30912
+ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, _component = "skills", destination = "") {
30913
+ return syncSkillsSlot({
30914
+ config,
30915
+ sourceRoot,
30916
+ source: path44.resolve(sourceRoot, config.source.skills),
30917
+ destination,
30918
+ dryRun: options.dryRun,
30919
+ logger,
30920
+ onUnmanagedConflict: (conflictPath) => handleConflict6(
30921
+ conflictPath,
30922
+ config,
30923
+ options,
30924
+ logger,
30925
+ manifest,
30926
+ scopePath
30927
+ )
30928
+ });
30935
30929
  }
30936
30930
  function syncMcp6(config, sourceRoot, paths, mappings, options, lossReport, logger) {
30937
30931
  const source = resolveMcpSourceFile(sourceRoot, config);
30938
30932
  const sourceLabel = mcpSourceLabel(config);
30939
30933
  const destination = resolveTargetPath(paths.config_doc);
30940
- if (!fs43.existsSync(source)) {
30934
+ if (!fs44.existsSync(source)) {
30941
30935
  if (!options.dryRun) {
30942
30936
  syncConfigDoc(paths, {}, lossReport, {}, mappings);
30943
30937
  }
30944
30938
  return skippedMissingSource6("mcp", source);
30945
30939
  }
30946
- const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
30940
+ const sourceMcpJson = JSON.parse(fs44.readFileSync(source, "utf8"));
30947
30941
  const mcpJson = compileMcp(
30948
30942
  sourceMcpJson,
30949
30943
  "opencode",
@@ -31009,9 +31003,9 @@ function syncProviderBlock(mappings) {
31009
31003
  function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
31010
31004
  const destination = resolveTargetPath(paths.config_doc);
31011
31005
  let existing = {};
31012
- if (fs43.existsSync(destination)) {
31006
+ if (fs44.existsSync(destination)) {
31013
31007
  try {
31014
- existing = JSON.parse(fs43.readFileSync(destination, "utf8"));
31008
+ existing = JSON.parse(fs44.readFileSync(destination, "utf8"));
31015
31009
  } catch {
31016
31010
  existing = {};
31017
31011
  }
@@ -31036,8 +31030,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
31036
31030
  };
31037
31031
  }
31038
31032
  }
31039
- ensureDir(path43.dirname(destination));
31040
- fs43.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31033
+ ensureDir(path44.dirname(destination));
31034
+ fs44.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31041
31035
  `);
31042
31036
  }
31043
31037
  function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
@@ -31051,14 +31045,14 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
31051
31045
  if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
31052
31046
  return { component, status: "conflict", path: destination };
31053
31047
  }
31054
- ensureDir(path43.dirname(destination));
31048
+ ensureDir(path44.dirname(destination));
31055
31049
  const clearedLink = clearSymlinkAtDestination(destination);
31056
31050
  if (clearedLink !== null) {
31057
31051
  logger.verbose(
31058
31052
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
31059
31053
  );
31060
31054
  }
31061
- fs43.writeFileSync(destination, content);
31055
+ fs44.writeFileSync(destination, content);
31062
31056
  return { component, status: "success", path: destination };
31063
31057
  }
31064
31058
  function handleConflict6(destination, config, options, logger, manifest, scopePath) {
@@ -31076,7 +31070,7 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
31076
31070
  if (manifest && scopePath) {
31077
31071
  backupFile(destination, manifest, scopePath);
31078
31072
  writeManifest(scopePath, manifest);
31079
- fs43.rmSync(destination, { recursive: true, force: true });
31073
+ fs44.rmSync(destination, { recursive: true, force: true });
31080
31074
  } else {
31081
31075
  const parked = parkConflictingPath(
31082
31076
  destination,
@@ -31091,12 +31085,12 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
31091
31085
  }
31092
31086
  return true;
31093
31087
  }
31094
- fs43.rmSync(destination, { recursive: true, force: true });
31088
+ fs44.rmSync(destination, { recursive: true, force: true });
31095
31089
  return true;
31096
31090
  }
31097
31091
  function isCompiledCurrent5(destination, expectedContent, _expectedHash) {
31098
31092
  try {
31099
- return fs43.readFileSync(destination, "utf8") === expectedContent;
31093
+ return fs44.readFileSync(destination, "utf8") === expectedContent;
31100
31094
  } catch {
31101
31095
  return false;
31102
31096
  }
@@ -31111,18 +31105,11 @@ function skippedMissingSource6(component, source) {
31111
31105
  function shouldSkipComponent6(options, component) {
31112
31106
  return Boolean(options.component && options.component !== component);
31113
31107
  }
31114
- function isSymlinkTo7(linkPath, source) {
31115
- try {
31116
- return fs43.realpathSync(linkPath) === fs43.realpathSync(source);
31117
- } catch {
31118
- return false;
31119
- }
31120
- }
31121
31108
  function hashString5(value) {
31122
31109
  return `sha256:${crypto10.createHash("sha256").update(value).digest("hex")}`;
31123
31110
  }
31124
31111
  function parseCommandFile(commandFile) {
31125
- const content = fs43.readFileSync(commandFile, "utf8");
31112
+ const content = fs44.readFileSync(commandFile, "utf8");
31126
31113
  if (!content.startsWith("---\n")) {
31127
31114
  return { data: {}, body: content };
31128
31115
  }
@@ -31131,7 +31118,7 @@ function parseCommandFile(commandFile) {
31131
31118
  return { data: {}, body: content };
31132
31119
  }
31133
31120
  try {
31134
- const data = (0, import_yaml11.parse)(content.slice(4, endIndex)) ?? {};
31121
+ const data = (0, import_yaml12.parse)(content.slice(4, endIndex)) ?? {};
31135
31122
  const body = content.slice(endIndex + "\n---".length).replace(/^\n/u, "");
31136
31123
  return { data, body };
31137
31124
  } catch {
@@ -31142,7 +31129,7 @@ function parseCommandFile(commandFile) {
31142
31129
  // src/commands/install.ts
31143
31130
  function isBackupablePath(targetPath) {
31144
31131
  try {
31145
- const lstat = fs44.lstatSync(targetPath);
31132
+ const lstat = fs45.lstatSync(targetPath);
31146
31133
  return lstat.isSymbolicLink() || lstat.isFile() || lstat.isDirectory();
31147
31134
  } catch {
31148
31135
  return false;
@@ -31179,7 +31166,7 @@ async function runInstallCommand(options, logger) {
31179
31166
  );
31180
31167
  }
31181
31168
  const kitName = resolvedKitName ?? config.kit;
31182
- const kitPath = kitPathOverride ?? (options.kitPath ? path44.resolve(options.kitPath) : config.kitPath);
31169
+ const kitPath = kitPathOverride ?? (options.kitPath ? path45.resolve(options.kitPath) : config.kitPath);
31183
31170
  if (!kitName && !kitPath) {
31184
31171
  logger.error(
31185
31172
  "No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
@@ -31284,8 +31271,8 @@ async function runInstallCommand(options, logger) {
31284
31271
  config: options.config,
31285
31272
  scope
31286
31273
  });
31287
- const skillsSource = path44.resolve(kitInfo.path, config.source.skills);
31288
- const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path44.basename(f.path) === "skills";
31274
+ const skillsSource = path45.resolve(kitInfo.path, config.source.skills);
31275
+ const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path45.basename(f.path) === "skills";
31289
31276
  const foreignSkillsSlots = new Set(
31290
31277
  assessResult.findings.filter(
31291
31278
  (f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
@@ -31323,7 +31310,7 @@ async function runInstallCommand(options, logger) {
31323
31310
  let instructionsLabel;
31324
31311
  try {
31325
31312
  const resolved = resolveInstructionsSource(kitInfo.path, config);
31326
- instructionsLabel = resolved ? path44.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
31313
+ instructionsLabel = resolved ? path45.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
31327
31314
  } catch (err) {
31328
31315
  logger.error(
31329
31316
  `[dry-run] ${err instanceof Error ? err.message : String(err)}`
@@ -31351,7 +31338,7 @@ async function runInstallCommand(options, logger) {
31351
31338
  }
31352
31339
  }
31353
31340
  logger.info(
31354
- `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path44.join(scopePath, "manifest.json")}`
31341
+ `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path45.join(scopePath, "manifest.json")}`
31355
31342
  );
31356
31343
  return;
31357
31344
  }
@@ -31410,7 +31397,7 @@ ACCEPTED CONFLICTS (posture: ${posture}; ${replaceable.length} target(s)):`
31410
31397
  logger.info(` - ${finding.path}`);
31411
31398
  logger.info(` source: ${sources}`);
31412
31399
  logger.info(
31413
- ` action: backup-and-replace${fs44.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
31400
+ ` action: backup-and-replace${fs45.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
31414
31401
  );
31415
31402
  logger.info(` backup: ${backupLocation}`);
31416
31403
  continue;
@@ -31534,20 +31521,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
31534
31521
  writeManifest(scopePath, manifest);
31535
31522
  logger.info(`
31536
31523
  Installation complete: ${installedCount} files installed.`);
31537
- logger.info(`Manifest written to ${path44.join(scopePath, "manifest.json")}`);
31524
+ logger.info(`Manifest written to ${path45.join(scopePath, "manifest.json")}`);
31538
31525
  logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
31539
31526
  logger.info(`Scope: ${scope}`);
31540
31527
  logger.info(`Tools: ${tools.join(", ")}`);
31541
31528
  reportHookRejections(
31542
31529
  installLossReport,
31543
31530
  tools,
31544
- path44.resolve(kitInfo.path, "hooks"),
31531
+ path45.resolve(kitInfo.path, "hooks"),
31545
31532
  kitInfo.components.hooks.declared
31546
31533
  );
31547
31534
  const hooksConflict = reportHooksSourceConflict(
31548
31535
  installLossReport,
31549
31536
  tools,
31550
- path44.resolve(kitInfo.path, "hooks"),
31537
+ path45.resolve(kitInfo.path, "hooks"),
31551
31538
  kitInfo.components.hooks.declared
31552
31539
  );
31553
31540
  if (hooksConflict) {
@@ -31906,7 +31893,7 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
31906
31893
  return 0;
31907
31894
  }
31908
31895
  try {
31909
- const stat = fs44.lstatSync(destination);
31896
+ const stat = fs45.lstatSync(destination);
31910
31897
  if (stat.isFile() && !stat.isSymbolicLink()) {
31911
31898
  logger.warn(
31912
31899
  `${destination}: a regular file occupies the skills slot \u2014 skipping skills. Move or remove it, then re-run install.`
@@ -31934,17 +31921,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
31934
31921
  manifest,
31935
31922
  scopePath
31936
31923
  );
31937
- const skillsSource = path44.resolve(kitInfo.path, config.source.skills);
31924
+ const skillsSource = path45.resolve(kitInfo.path, config.source.skills);
31938
31925
  let count = 0;
31939
31926
  for (const outcome of outcomes) {
31940
31927
  if (outcome.status !== "success" && outcome.status !== "skipped-current") {
31941
31928
  continue;
31942
31929
  }
31943
- const skillName = path44.basename(outcome.path);
31930
+ const skillName = path45.basename(outcome.path);
31944
31931
  addArtifactToManifest(manifest, {
31945
31932
  relativePath: `claude-code/skills/${skillName}`,
31946
31933
  path: outcome.path,
31947
- hash: describeArtifactState(outcome.path) ?? `dir:${path44.join(skillsSource, skillName)}`,
31934
+ hash: describeArtifactState(outcome.path) ?? `dir:${path45.join(skillsSource, skillName)}`,
31948
31935
  origin: "tangyr-managed"
31949
31936
  });
31950
31937
  count++;
@@ -31958,10 +31945,10 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
31958
31945
  logger.verbose(` skipped (operator choice): ${placement.destination}`);
31959
31946
  continue;
31960
31947
  }
31961
- const destDir = path44.dirname(placement.destination);
31962
- fs44.mkdirSync(destDir, { recursive: true });
31948
+ const destDir = path45.dirname(placement.destination);
31949
+ fs45.mkdirSync(destDir, { recursive: true });
31963
31950
  if (placement.type === "symlink") {
31964
- if (fs44.existsSync(placement.destination) || isSymlink2(placement.destination)) {
31951
+ if (fs45.existsSync(placement.destination) || isSymlink2(placement.destination)) {
31965
31952
  removeManagedPath(placement.destination);
31966
31953
  }
31967
31954
  createRelativeSymlink(
@@ -31978,7 +31965,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
31978
31965
  ` symlink: ${placement.source} \u2192 ${placement.destination}`
31979
31966
  );
31980
31967
  } else {
31981
- fs44.copyFileSync(placement.source, placement.destination);
31968
+ fs45.copyFileSync(placement.source, placement.destination);
31982
31969
  logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
31983
31970
  }
31984
31971
  addArtifactToManifest(manifest, {
@@ -32240,6 +32227,16 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32240
32227
  }
32241
32228
  throwUnrecognizedTarget(tool);
32242
32229
  }
32230
+ const skillsSlotKey = skillsSubPathKey(
32231
+ tool,
32232
+ outcome.path,
32233
+ mappings,
32234
+ scope,
32235
+ projectRoot
32236
+ );
32237
+ if (skillsSlotKey) {
32238
+ return skillsSlotKey;
32239
+ }
32243
32240
  if (tool === "cline") {
32244
32241
  const profile2 = resolveTargetPaths({
32245
32242
  scope,
@@ -32260,11 +32257,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32260
32257
  if (outcome.path === mcpFile2) {
32261
32258
  return "cline/mcp.json";
32262
32259
  }
32263
- if (outcome.path.startsWith(`${workflowsRoot}${path44.sep}`)) {
32264
- return `cline/workflows/${path44.basename(outcome.path)}`;
32260
+ if (outcome.path.startsWith(`${workflowsRoot}${path45.sep}`)) {
32261
+ return `cline/workflows/${path45.basename(outcome.path)}`;
32265
32262
  }
32266
- if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
32267
- return `cline/rules/${path44.basename(outcome.path)}`;
32263
+ if (outcome.path.startsWith(`${rulesRoot2}${path45.sep}`)) {
32264
+ return `cline/rules/${path45.basename(outcome.path)}`;
32268
32265
  }
32269
32266
  return null;
32270
32267
  }
@@ -32300,14 +32297,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32300
32297
  if (outcome.path === permissionsFile) {
32301
32298
  return "cursor/permissions.json";
32302
32299
  }
32303
- if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
32304
- return `cursor/agents/${path44.basename(outcome.path)}`;
32300
+ if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
32301
+ return `cursor/agents/${path45.basename(outcome.path)}`;
32305
32302
  }
32306
- if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
32307
- return `cursor/rules/${path44.basename(outcome.path)}`;
32303
+ if (outcome.path.startsWith(`${rulesRoot2}${path45.sep}`)) {
32304
+ return `cursor/rules/${path45.basename(outcome.path)}`;
32308
32305
  }
32309
- if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
32310
- const rel = path44.relative(skillsRoot2, outcome.path);
32306
+ if (outcome.path.startsWith(`${skillsRoot2}${path45.sep}`)) {
32307
+ const rel = path45.relative(skillsRoot2, outcome.path);
32311
32308
  return `cursor/skills/${rel}`;
32312
32309
  }
32313
32310
  return null;
@@ -32333,14 +32330,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32333
32330
  if (outcome.path === skillsSharedRoot) {
32334
32331
  return "opencode/skills_shared";
32335
32332
  }
32336
- if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
32337
- return `opencode/agents/${path44.basename(outcome.path)}`;
32333
+ if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
32334
+ return `opencode/agents/${path45.basename(outcome.path)}`;
32338
32335
  }
32339
- if (outcome.path.startsWith(`${commandsRoot}${path44.sep}`)) {
32340
- return `opencode/commands/${path44.basename(outcome.path)}`;
32336
+ if (outcome.path.startsWith(`${commandsRoot}${path45.sep}`)) {
32337
+ return `opencode/commands/${path45.basename(outcome.path)}`;
32341
32338
  }
32342
32339
  if (outcome.path === configDocFile) {
32343
- return `opencode/${path44.basename(outcome.path)}`;
32340
+ return `opencode/${path45.basename(outcome.path)}`;
32344
32341
  }
32345
32342
  return null;
32346
32343
  }
@@ -32357,26 +32354,26 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32357
32354
  const hooksRoot = resolveTargetPath(copilot.hooks);
32358
32355
  const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
32359
32356
  const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
32360
- if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
32361
- return `copilot/skills/${path44.relative(skillsRoot2, outcome.path)}`;
32357
+ if (outcome.path.startsWith(`${skillsRoot2}${path45.sep}`)) {
32358
+ return `copilot/skills/${path45.relative(skillsRoot2, outcome.path)}`;
32362
32359
  }
32363
32360
  if (outcome.path === skillsRoot2) {
32364
32361
  return "copilot/skills";
32365
32362
  }
32366
32363
  if (instructionsMirror !== null && outcome.path === instructionsMirror) {
32367
- return `copilot/${path44.basename(outcome.path)}`;
32364
+ return `copilot/${path45.basename(outcome.path)}`;
32368
32365
  }
32369
- if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
32370
- return `copilot/agents/${path44.basename(outcome.path)}`;
32366
+ if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
32367
+ return `copilot/agents/${path45.basename(outcome.path)}`;
32371
32368
  }
32372
- if (outcome.path.startsWith(`${promptsRoot}${path44.sep}`)) {
32373
- return `copilot/prompts/${path44.basename(outcome.path)}`;
32369
+ if (outcome.path.startsWith(`${promptsRoot}${path45.sep}`)) {
32370
+ return `copilot/prompts/${path45.basename(outcome.path)}`;
32374
32371
  }
32375
- if (outcome.path.startsWith(`${hooksRoot}${path44.sep}`)) {
32376
- return `copilot/hooks/${path44.basename(outcome.path)}`;
32372
+ if (outcome.path.startsWith(`${hooksRoot}${path45.sep}`)) {
32373
+ return `copilot/hooks/${path45.basename(outcome.path)}`;
32377
32374
  }
32378
32375
  if (outcome.path === mcpFile2) {
32379
- return `copilot/${path44.basename(outcome.path)}`;
32376
+ return `copilot/${path45.basename(outcome.path)}`;
32380
32377
  }
32381
32378
  return null;
32382
32379
  }
@@ -32393,17 +32390,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32393
32390
  if (outcome.path === skillsRoot) {
32394
32391
  return "codex/skills";
32395
32392
  }
32396
- if (outcome.path.startsWith(`${agentsRoot}${path44.sep}`)) {
32397
- return `codex/agents/${path44.basename(outcome.path)}`;
32393
+ if (outcome.path.startsWith(`${agentsRoot}${path45.sep}`)) {
32394
+ return `codex/agents/${path45.basename(outcome.path)}`;
32398
32395
  }
32399
- if (outcome.path.startsWith(`${rulesRoot}${path44.sep}`)) {
32400
- return `codex/rules/${path44.basename(outcome.path)}`;
32396
+ if (outcome.path.startsWith(`${rulesRoot}${path45.sep}`)) {
32397
+ return `codex/rules/${path45.basename(outcome.path)}`;
32401
32398
  }
32402
32399
  if (outcome.path === hooksFile) {
32403
- return `codex/${path44.basename(outcome.path)}`;
32400
+ return `codex/${path45.basename(outcome.path)}`;
32404
32401
  }
32405
32402
  if (outcome.path === mcpFile) {
32406
- return `codex/${path44.basename(outcome.path)}`;
32403
+ return `codex/${path45.basename(outcome.path)}`;
32407
32404
  }
32408
32405
  return null;
32409
32406
  }
@@ -32472,8 +32469,8 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
32472
32469
  rules: resolvedPaths.rules
32473
32470
  };
32474
32471
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
32475
- const componentDir = path44.join(kitInfo.path, component);
32476
- if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
32472
+ const componentDir = path45.join(kitInfo.path, component);
32473
+ if (fs45.existsSync(componentDir) && fs45.statSync(componentDir).isDirectory()) {
32477
32474
  placements.push({
32478
32475
  source: componentDir,
32479
32476
  destination: targetPath,
@@ -32503,8 +32500,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
32503
32500
  rules: profile.rules
32504
32501
  };
32505
32502
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
32506
- const componentDir = path44.join(kitInfo.path, component);
32507
- if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
32503
+ const componentDir = path45.join(kitInfo.path, component);
32504
+ if (fs45.existsSync(componentDir) && fs45.statSync(componentDir).isDirectory()) {
32508
32505
  placements.push({
32509
32506
  source: componentDir,
32510
32507
  destination: targetPath,
@@ -32520,7 +32517,7 @@ function collectAllFiles(kitInfo, config) {
32520
32517
  const files = /* @__PURE__ */ new Map();
32521
32518
  const entrypoint = resolveInstructionsSource(kitInfo.path, config);
32522
32519
  if (entrypoint) {
32523
- files.set(path44.basename(entrypoint.file), entrypoint.file);
32520
+ files.set(path45.basename(entrypoint.file), entrypoint.file);
32524
32521
  }
32525
32522
  for (const [component, reconciliation] of Object.entries(
32526
32523
  kitInfo.components
@@ -32529,26 +32526,48 @@ function collectAllFiles(kitInfo, config) {
32529
32526
  const missingSet = new Set(reconciliation.missing);
32530
32527
  for (const entry of reconciliation.declared) {
32531
32528
  if (missingSet.has(entry)) continue;
32532
- const relPath = isSkills ? path44.join(component, entry) : path44.join(component, `${entry}.md`);
32533
- files.set(relPath, path44.join(kitInfo.path, relPath));
32529
+ const relPath = isSkills ? path45.join(component, entry) : path45.join(component, `${entry}.md`);
32530
+ files.set(relPath, path45.join(kitInfo.path, relPath));
32534
32531
  }
32535
32532
  }
32536
32533
  return files;
32537
32534
  }
32538
32535
  function readLinkTarget(p) {
32539
32536
  try {
32540
- return fs44.readlinkSync(p);
32537
+ return fs45.readlinkSync(p);
32541
32538
  } catch {
32542
32539
  return null;
32543
32540
  }
32544
32541
  }
32545
32542
  function isSymlink2(p) {
32546
32543
  try {
32547
- return fs44.lstatSync(p).isSymbolicLink();
32544
+ return fs45.lstatSync(p).isSymbolicLink();
32548
32545
  } catch {
32549
32546
  return false;
32550
32547
  }
32551
32548
  }
32549
+ function skillsSubPathKey(tool, outcomePath, mappings, scope, projectRoot) {
32550
+ const profile = resolveTargetPaths({
32551
+ scope,
32552
+ projectRoot,
32553
+ mappings: mappings.platformPaths
32554
+ })[tool];
32555
+ if (!profile) {
32556
+ return null;
32557
+ }
32558
+ for (const slot of [profile.skills, profile.skills_shared]) {
32559
+ if (typeof slot !== "string" || slot.length === 0) {
32560
+ continue;
32561
+ }
32562
+ const root = resolveTargetPath(slot);
32563
+ if (!outcomePath.startsWith(`${root}${path45.sep}`)) {
32564
+ continue;
32565
+ }
32566
+ const inside = path45.relative(root, outcomePath).split(path45.sep).join("/");
32567
+ return `${tool}/skills/${inside}`;
32568
+ }
32569
+ return null;
32570
+ }
32552
32571
 
32553
32572
  // src/commands/kit.ts
32554
32573
  async function runKitUpdateCommand(options, logger) {
@@ -32589,14 +32608,14 @@ async function runKitUpdateCommand(options, logger) {
32589
32608
  }
32590
32609
 
32591
32610
  // src/commands/list.ts
32592
- import path45 from "path";
32611
+ import path46 from "path";
32593
32612
  function runListCommand(options, logger) {
32594
32613
  let searchPaths = [];
32595
- let directKitPath = options.kitPath ? path45.resolve(options.kitPath) : void 0;
32614
+ let directKitPath = options.kitPath ? path46.resolve(options.kitPath) : void 0;
32596
32615
  try {
32597
32616
  const { config, configDir } = resolveConfig(options.config);
32598
32617
  searchPaths = config.kitSearchPaths ?? [
32599
- path45.join(configDir, "operating-kits")
32618
+ path46.join(configDir, "operating-kits")
32600
32619
  ];
32601
32620
  directKitPath = directKitPath ?? config.kitPath;
32602
32621
  } catch (err) {
@@ -32671,7 +32690,7 @@ function withDirectKit(kits, directKitPath) {
32671
32690
  return kits;
32672
32691
  }
32673
32692
  const directKit = loadKit(directKitPath);
32674
- if (kits.some((kit) => path45.resolve(kit.path) === directKit.path)) {
32693
+ if (kits.some((kit) => path46.resolve(kit.path) === directKit.path)) {
32675
32694
  return kits;
32676
32695
  }
32677
32696
  return [...kits, directKit];
@@ -32679,8 +32698,8 @@ function withDirectKit(kits, directKitPath) {
32679
32698
 
32680
32699
  // src/commands/probe.ts
32681
32700
  import { spawnSync as spawnSync2 } from "child_process";
32682
- import fs45 from "fs";
32683
- import path46 from "path";
32701
+ import fs46 from "fs";
32702
+ import path47 from "path";
32684
32703
  function runProbeCommand(options, logger) {
32685
32704
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
32686
32705
  options,
@@ -32708,7 +32727,7 @@ function runProbeCommand(options, logger) {
32708
32727
  toProbeRow(
32709
32728
  target,
32710
32729
  key,
32711
- scope === "project" ? path46.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
32730
+ scope === "project" ? path47.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
32712
32731
  )
32713
32732
  );
32714
32733
  }
@@ -32730,7 +32749,7 @@ function toProbeRow(target, key, rawPath) {
32730
32749
  const resolved = resolveTargetPath(rawPath);
32731
32750
  let accessible = false;
32732
32751
  try {
32733
- fs45.accessSync(resolved);
32752
+ fs46.accessSync(resolved);
32734
32753
  accessible = true;
32735
32754
  } catch {
32736
32755
  accessible = false;
@@ -32739,7 +32758,7 @@ function toProbeRow(target, key, rawPath) {
32739
32758
  target,
32740
32759
  key,
32741
32760
  path: resolved,
32742
- exists: fs45.existsSync(resolved),
32761
+ exists: fs46.existsSync(resolved),
32743
32762
  accessible
32744
32763
  };
32745
32764
  }
@@ -32757,7 +32776,7 @@ function codexRuntimeProbeRows() {
32757
32776
  ["binary_snap", "/snap/bin/codex"],
32758
32777
  ["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
32759
32778
  ]) {
32760
- if (fs45.existsSync(candidatePath)) {
32779
+ if (fs46.existsSync(candidatePath)) {
32761
32780
  rows.push(toProbeRow("codex", key, candidatePath));
32762
32781
  }
32763
32782
  }
@@ -32773,8 +32792,8 @@ function commandProbeRows(target, key, command, args) {
32773
32792
 
32774
32793
  // src/commands/status.ts
32775
32794
  import crypto11 from "crypto";
32776
- import fs46 from "fs";
32777
- import path47 from "path";
32795
+ import fs47 from "fs";
32796
+ import path48 from "path";
32778
32797
  function runStatusCommand(options, logger) {
32779
32798
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
32780
32799
  options,
@@ -32880,11 +32899,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
32880
32899
  }
32881
32900
  }
32882
32901
  function sourceMarkdownFiles(sourceRoot, componentPath) {
32883
- const root = path47.join(sourceRoot, componentPath);
32884
- if (!fs46.existsSync(root)) {
32902
+ const root = path48.join(sourceRoot, componentPath);
32903
+ if (!fs47.existsSync(root)) {
32885
32904
  return [];
32886
32905
  }
32887
- return ts(path47.join(root, "*.md")).sort();
32906
+ return ts(path48.join(root, "*.md")).sort();
32888
32907
  }
32889
32908
  function notRepresentableRow(component, detail) {
32890
32909
  return {
@@ -32895,11 +32914,11 @@ function notRepresentableRow(component, detail) {
32895
32914
  };
32896
32915
  }
32897
32916
  function readTargetJson(filePath) {
32898
- if (!fs46.existsSync(filePath)) {
32917
+ if (!fs47.existsSync(filePath)) {
32899
32918
  return { kind: "missing" };
32900
32919
  }
32901
32920
  try {
32902
- const parsed = JSON.parse(fs46.readFileSync(filePath, "utf8"));
32921
+ const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
32903
32922
  return { kind: "object", value: isRecord(parsed) ? parsed : {} };
32904
32923
  } catch (err) {
32905
32924
  return {
@@ -32988,7 +33007,7 @@ function classifyInstructions(filePath, target, expectedHash, config, sourceRoot
32988
33007
  }
32989
33008
  function compiledMcpDocument(config, sourceRoot, target) {
32990
33009
  const source = resolveMcpSourceFile(sourceRoot, config);
32991
- if (!fs46.existsSync(source)) {
33010
+ if (!fs47.existsSync(source)) {
32992
33011
  return {};
32993
33012
  }
32994
33013
  const compiled = compileMcp(
@@ -33001,7 +33020,7 @@ function compiledMcpDocument(config, sourceRoot, target) {
33001
33020
  return isRecord(parsed) ? parsed : {};
33002
33021
  }
33003
33022
  function classifyMcpDocument(config, sourceRoot, target, filePath) {
33004
- if (!fs46.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
33023
+ if (!fs47.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
33005
33024
  return notConfiguredRow("mcp", filePath);
33006
33025
  }
33007
33026
  return classifyJsonDocument(
@@ -33031,12 +33050,12 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
33031
33050
  const rows = [];
33032
33051
  const instructionsSource = instructionsSourcePath(sourceRoot, config);
33033
33052
  const rules = compileRules(
33034
- path47.join(sourceRoot, config.source.rules),
33053
+ path48.join(sourceRoot, config.source.rules),
33035
33054
  "opencode",
33036
33055
  mappings,
33037
33056
  createLossReport()
33038
33057
  );
33039
- const baseInstructions = fs46.existsSync(instructionsSource) ? fs46.readFileSync(instructionsSource, "utf8").trim() : "";
33058
+ const baseInstructions = fs47.existsSync(instructionsSource) ? fs47.readFileSync(instructionsSource, "utf8").trim() : "";
33040
33059
  const composedInstructions = rules.agentsAppendix ? `${baseInstructions}
33041
33060
 
33042
33061
  --- tangyr managed rules ---
@@ -33058,10 +33077,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
33058
33077
  )) {
33059
33078
  rows.push(
33060
33079
  classifyCompiledFile(
33061
- `agents/${path47.basename(agentFile, ".md")}`,
33062
- path47.join(
33080
+ `agents/${path48.basename(agentFile, ".md")}`,
33081
+ path48.join(
33063
33082
  resolveTargetPath(paths.agents),
33064
- `${path47.basename(agentFile, ".md")}.md`
33083
+ `${path48.basename(agentFile, ".md")}.md`
33065
33084
  ),
33066
33085
  "opencode",
33067
33086
  computeSourceHash(agentFile),
@@ -33076,10 +33095,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
33076
33095
  )) {
33077
33096
  rows.push(
33078
33097
  classifyCompiledFile(
33079
- `commands/${path47.basename(commandFile, ".md")}`,
33080
- path47.join(
33098
+ `commands/${path48.basename(commandFile, ".md")}`,
33099
+ path48.join(
33081
33100
  resolveTargetPath(paths.commands),
33082
- `${path47.basename(commandFile, ".md")}.md`
33101
+ `${path48.basename(commandFile, ".md")}.md`
33083
33102
  ),
33084
33103
  "opencode",
33085
33104
  computeSourceHash(commandFile),
@@ -33161,10 +33180,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33161
33180
  )) {
33162
33181
  rows.push(
33163
33182
  classifyCompiledFile(
33164
- `agents/${path47.basename(agentFile, ".md")}`,
33165
- path47.join(
33183
+ `agents/${path48.basename(agentFile, ".md")}`,
33184
+ path48.join(
33166
33185
  resolveTargetPath(paths.agents),
33167
- `${path47.basename(agentFile, ".md")}.md`
33186
+ `${path48.basename(agentFile, ".md")}.md`
33168
33187
  ),
33169
33188
  "cursor",
33170
33189
  computeSourceHash(agentFile),
@@ -33181,7 +33200,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33181
33200
  rows.push(
33182
33201
  classifyCompiledFile(
33183
33202
  `rules/${ruleFile.name}`,
33184
- path47.join(resolveTargetPath(paths.rules), ruleFile.name),
33203
+ path48.join(resolveTargetPath(paths.rules), ruleFile.name),
33185
33204
  "cursor",
33186
33205
  void 0,
33187
33206
  config,
@@ -33195,11 +33214,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33195
33214
  sourceRoot,
33196
33215
  config.source.commands
33197
33216
  )) {
33198
- const baseName = path47.basename(commandFile, ".md");
33217
+ const baseName = path48.basename(commandFile, ".md");
33199
33218
  rows.push(
33200
33219
  classifyCompiledFile(
33201
33220
  `commands/${baseName}`,
33202
- path47.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
33221
+ path48.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
33203
33222
  "cursor",
33204
33223
  computeSourceHash(commandFile),
33205
33224
  config,
@@ -33282,7 +33301,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33282
33301
  rows.push(
33283
33302
  classifyCompiledFile(
33284
33303
  `rules/${ruleFile.name}`,
33285
- path47.join(resolveTargetPath(paths.rules), ruleFile.name),
33304
+ path48.join(resolveTargetPath(paths.rules), ruleFile.name),
33286
33305
  "cline",
33287
33306
  void 0,
33288
33307
  config,
@@ -33298,10 +33317,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33298
33317
  )) {
33299
33318
  rows.push(
33300
33319
  classifyCompiledFile(
33301
- `commands/${path47.basename(commandFile, ".md")}`,
33302
- path47.join(
33320
+ `commands/${path48.basename(commandFile, ".md")}`,
33321
+ path48.join(
33303
33322
  resolveTargetPath(paths.workflows),
33304
- path47.basename(commandFile)
33323
+ path48.basename(commandFile)
33305
33324
  ),
33306
33325
  "cline",
33307
33326
  computeSourceHash(commandFile),
@@ -33342,14 +33361,14 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33342
33361
  return rows;
33343
33362
  }
33344
33363
  function compileRulesFiles(config, sourceRoot, target, mappings) {
33345
- const rulesSource = path47.join(sourceRoot, config.source.rules);
33346
- if (!fs46.existsSync(rulesSource)) {
33364
+ const rulesSource = path48.join(sourceRoot, config.source.rules);
33365
+ if (!fs47.existsSync(rulesSource)) {
33347
33366
  return [];
33348
33367
  }
33349
33368
  return compileRules(rulesSource, target, mappings, createLossReport()).dotRulesFiles;
33350
33369
  }
33351
33370
  function classifyDirectoryPresence(component, dirPath) {
33352
- const present = fs46.existsSync(dirPath) && fs46.statSync(dirPath).isDirectory();
33371
+ const present = fs47.existsSync(dirPath) && fs47.statSync(dirPath).isDirectory();
33353
33372
  return {
33354
33373
  component,
33355
33374
  className: present ? "current" : "missing",
@@ -33368,7 +33387,7 @@ function slotsForScope2(scopeMap, scope, projectRoot) {
33368
33387
  const root = projectRoot ?? process.cwd();
33369
33388
  const resolved = {};
33370
33389
  for (const [slot, value] of Object.entries(projectSlots)) {
33371
- resolved[slot] = typeof value === "string" ? path47.resolve(root, value) : value;
33390
+ resolved[slot] = typeof value === "string" ? path48.resolve(root, value) : value;
33372
33391
  }
33373
33392
  return resolved;
33374
33393
  }
@@ -33388,21 +33407,21 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
33388
33407
  rules: paths.rules
33389
33408
  };
33390
33409
  const rules = compileRules(
33391
- path47.join(sourceRoot, config.source.rules),
33410
+ path48.join(sourceRoot, config.source.rules),
33392
33411
  "codex",
33393
33412
  mappings,
33394
33413
  createLossReport()
33395
33414
  );
33396
- const instructionsSource = fs46.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
33415
+ const instructionsSource = fs47.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
33397
33416
  const composedInstructions = `${instructionsSource}
33398
33417
 
33399
33418
  --- tangyr managed rules ---
33400
33419
  ${rules.agentsAppendix}`.trim();
33401
33420
  const agentFiles = ts(
33402
- path47.join(sourceRoot, config.source.agents, "*.md")
33421
+ path48.join(sourceRoot, config.source.agents, "*.md")
33403
33422
  ).sort();
33404
33423
  const hooksPresent = hooksSourceExists(sourceRoot, config);
33405
- const mcpSource = path47.join(sourceRoot, config.source.mcp);
33424
+ const mcpSource = path48.join(sourceRoot, config.source.mcp);
33406
33425
  const ruleRows = rules.dotRulesFiles.length === 0 ? [
33407
33426
  {
33408
33427
  component: "rules",
@@ -33413,7 +33432,7 @@ ${rules.agentsAppendix}`.trim();
33413
33432
  ] : rules.dotRulesFiles.map(
33414
33433
  (ruleFile) => classifyCompiledFile(
33415
33434
  `rules/${ruleFile.name}`,
33416
- path47.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
33435
+ path48.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
33417
33436
  "codex",
33418
33437
  void 0,
33419
33438
  config,
@@ -33431,10 +33450,10 @@ ${rules.agentsAppendix}`.trim();
33431
33450
  ),
33432
33451
  ...agentFiles.map(
33433
33452
  (agentFile) => classifyCompiledFile(
33434
- `agents/${path47.basename(agentFile, ".md")}`,
33435
- path47.join(
33453
+ `agents/${path48.basename(agentFile, ".md")}`,
33454
+ path48.join(
33436
33455
  resolveTargetPath(codexPaths.agents),
33437
- `${path47.basename(agentFile, ".md")}.toml`
33456
+ `${path48.basename(agentFile, ".md")}.toml`
33438
33457
  ),
33439
33458
  "codex",
33440
33459
  computeSourceHash(agentFile),
@@ -33462,7 +33481,7 @@ ${rules.agentsAppendix}`.trim();
33462
33481
  "hooks",
33463
33482
  resolveTargetPath(codexPaths.hooksSharedFile)
33464
33483
  ),
33465
- fs46.existsSync(mcpSource) ? classifyCompiledFile(
33484
+ fs47.existsSync(mcpSource) ? classifyCompiledFile(
33466
33485
  "mcp",
33467
33486
  resolveTargetPath(codexPaths.mcpSharedFile),
33468
33487
  "codex",
@@ -33528,20 +33547,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33528
33547
  mcpSharedFile: paths.mcp_shared_file
33529
33548
  };
33530
33549
  const agentFiles = ts(
33531
- path47.join(sourceRoot, config.source.agents, "*.md")
33550
+ path48.join(sourceRoot, config.source.agents, "*.md")
33532
33551
  ).sort();
33533
33552
  const commandFiles = ts(
33534
- path47.join(sourceRoot, config.source.commands, "*.md")
33553
+ path48.join(sourceRoot, config.source.commands, "*.md")
33535
33554
  ).sort();
33536
33555
  const hooksPresent = hooksSourceExists(sourceRoot, config);
33537
- const mcpSource = path47.join(sourceRoot, config.source.mcp);
33556
+ const mcpSource = path48.join(sourceRoot, config.source.mcp);
33538
33557
  return [
33539
33558
  ...agentFiles.map(
33540
33559
  (agentFile) => classifyCompiledFile(
33541
- `agents/${path47.basename(agentFile, ".md")}`,
33542
- path47.join(
33560
+ `agents/${path48.basename(agentFile, ".md")}`,
33561
+ path48.join(
33543
33562
  resolveTargetPath(copilotPaths.agents),
33544
- `${path47.basename(agentFile, ".md")}.agent.md`
33563
+ `${path48.basename(agentFile, ".md")}.agent.md`
33545
33564
  ),
33546
33565
  "copilot",
33547
33566
  computeSourceHash(agentFile),
@@ -33558,10 +33577,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33558
33577
  ),
33559
33578
  ...commandFiles.map(
33560
33579
  (commandFile) => classifyCompiledFile(
33561
- `commands/${path47.basename(commandFile, ".md")}`,
33562
- path47.join(
33580
+ `commands/${path48.basename(commandFile, ".md")}`,
33581
+ path48.join(
33563
33582
  resolveTargetPath(copilotPaths.prompts),
33564
- `${path47.basename(commandFile, ".md")}.prompt.md`
33583
+ `${path48.basename(commandFile, ".md")}.prompt.md`
33565
33584
  ),
33566
33585
  "copilot",
33567
33586
  computeSourceHash(commandFile),
@@ -33580,19 +33599,19 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33580
33599
  sourceRoot
33581
33600
  ),
33582
33601
  hooksPresent ? classifyCompiledHooksByProvenance(
33583
- path47.join(
33602
+ path48.join(
33584
33603
  resolveTargetPath(copilotPaths.hooks),
33585
33604
  "tangyr-managed.json"
33586
33605
  ),
33587
33606
  "copilot"
33588
33607
  ) : notConfiguredRow(
33589
33608
  "hooks",
33590
- path47.join(
33609
+ path48.join(
33591
33610
  resolveTargetPath(copilotPaths.hooks),
33592
33611
  "tangyr-managed.json"
33593
33612
  )
33594
33613
  ),
33595
- fs46.existsSync(mcpSource) ? classifyCompiledFile(
33614
+ fs47.existsSync(mcpSource) ? classifyCompiledFile(
33596
33615
  "mcp",
33597
33616
  resolveTargetPath(copilotPaths.mcpSharedFile),
33598
33617
  "copilot",
@@ -33612,7 +33631,7 @@ function notConfiguredRow(component, filePath) {
33612
33631
  }
33613
33632
  function classifyDirectArtifact(artifact, config, sourceRoot) {
33614
33633
  const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
33615
- const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path47.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
33634
+ const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path48.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
33616
33635
  if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
33617
33636
  const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
33618
33637
  if (perSkill) {
@@ -33708,20 +33727,23 @@ function classifyClaudeCodeRows(sourceRoot, config, configDir, scope, projectRoo
33708
33727
  function classifyPerSkillSlot(slotPath, sourceRoot) {
33709
33728
  let entries;
33710
33729
  try {
33711
- const stat = fs46.lstatSync(slotPath);
33730
+ const stat = fs47.lstatSync(slotPath);
33712
33731
  if (!stat.isDirectory() || stat.isSymbolicLink()) {
33713
33732
  return null;
33714
33733
  }
33715
- entries = fs46.readdirSync(slotPath, { withFileTypes: true });
33734
+ entries = fs47.readdirSync(slotPath, { withFileTypes: true });
33716
33735
  } catch {
33717
33736
  return null;
33718
33737
  }
33738
+ if (entries.length === 0) {
33739
+ return "managed-symlink";
33740
+ }
33719
33741
  const links = entries.filter((entry) => entry.isSymbolicLink());
33720
33742
  if (links.length === 0) {
33721
33743
  return null;
33722
33744
  }
33723
33745
  const ours = links.filter(
33724
- (entry) => isOurSymlink(path47.join(slotPath, entry.name), sourceRoot)
33746
+ (entry) => isOurSymlink(path48.join(slotPath, entry.name), sourceRoot)
33725
33747
  );
33726
33748
  if (ours.length === 0) {
33727
33749
  return null;
@@ -33733,9 +33755,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
33733
33755
  classifyHooks(settingsPath),
33734
33756
  classifySettings(
33735
33757
  settingsPath,
33736
- path47.resolve(sourceRoot, config.source.settings)
33758
+ path48.resolve(sourceRoot, config.source.settings)
33737
33759
  ),
33738
- classifyMcp(claudeJsonPath, path47.resolve(sourceRoot, config.source.mcp))
33760
+ classifyMcp(claudeJsonPath, path48.resolve(sourceRoot, config.source.mcp))
33739
33761
  ];
33740
33762
  }
33741
33763
  function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
@@ -33832,14 +33854,14 @@ function classifyMcp(filePath, sourcePath) {
33832
33854
  }
33833
33855
  function isSymlinkCurrent(linkPath, sourcePath) {
33834
33856
  try {
33835
- return fs46.realpathSync(linkPath) === fs46.realpathSync(sourcePath);
33857
+ return fs47.realpathSync(linkPath) === fs47.realpathSync(sourcePath);
33836
33858
  } catch {
33837
33859
  return false;
33838
33860
  }
33839
33861
  }
33840
33862
  function isCompiledCurrent6(filePath, sourcePath) {
33841
33863
  try {
33842
- const marker = extractProvenanceMarker(fs46.readFileSync(filePath, "utf8"));
33864
+ const marker = extractProvenanceMarker(fs47.readFileSync(filePath, "utf8"));
33843
33865
  return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
33844
33866
  } catch {
33845
33867
  return false;
@@ -33869,7 +33891,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
33869
33891
  }
33870
33892
  function readCompiledContent(filePath) {
33871
33893
  try {
33872
- return fs46.readFileSync(filePath, "utf8");
33894
+ return fs47.readFileSync(filePath, "utf8");
33873
33895
  } catch {
33874
33896
  return null;
33875
33897
  }
@@ -33900,8 +33922,8 @@ function hashString6(value) {
33900
33922
  }
33901
33923
 
33902
33924
  // src/commands/sync.ts
33903
- import fs47 from "fs";
33904
- import path48 from "path";
33925
+ import fs48 from "fs";
33926
+ import path49 from "path";
33905
33927
 
33906
33928
  // node_modules/chalk/source/vendor/ansi-styles/index.js
33907
33929
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -34571,13 +34593,13 @@ async function runSyncCommand(options, logger) {
34571
34593
  reportHookRejections(
34572
34594
  lossReport,
34573
34595
  targets,
34574
- path48.resolve(kitInfo.path, "hooks"),
34596
+ path49.resolve(kitInfo.path, "hooks"),
34575
34597
  kitInfo.components.hooks.declared
34576
34598
  );
34577
34599
  const hooksConflict = reportHooksSourceConflict(
34578
34600
  lossReport,
34579
34601
  targets,
34580
- path48.resolve(kitInfo.path, "hooks"),
34602
+ path49.resolve(kitInfo.path, "hooks"),
34581
34603
  kitInfo.components.hooks.declared
34582
34604
  );
34583
34605
  if (hooksConflict) {
@@ -34780,8 +34802,8 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
34780
34802
  }
34781
34803
  }
34782
34804
  function resolveKitFilePath(kitPath, relativePath) {
34783
- const fullPath = path48.join(kitPath, relativePath);
34784
- return fs47.existsSync(fullPath) ? fullPath : null;
34805
+ const fullPath = path49.join(kitPath, relativePath);
34806
+ return fs48.existsSync(fullPath) ? fullPath : null;
34785
34807
  }
34786
34808
  function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
34787
34809
  if (removedSourcePaths.length === 0 || !mappings) {
@@ -34844,9 +34866,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34844
34866
  }
34845
34867
  if (relativePath.startsWith("agents/")) {
34846
34868
  removeManagedCompiledArtifact2(
34847
- path48.join(
34869
+ path49.join(
34848
34870
  resolveTargetPath(paths.agents ?? ""),
34849
- `${path48.parse(relativePath).name}.agent.md`
34871
+ `${path49.parse(relativePath).name}.agent.md`
34850
34872
  ),
34851
34873
  "copilot",
34852
34874
  relativePath,
@@ -34856,9 +34878,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34856
34878
  }
34857
34879
  if (relativePath.startsWith("commands/")) {
34858
34880
  removeManagedCompiledArtifact2(
34859
- path48.join(
34881
+ path49.join(
34860
34882
  resolveTargetPath(paths.prompts ?? ""),
34861
- `${path48.parse(relativePath).name}.prompt.md`
34883
+ `${path49.parse(relativePath).name}.prompt.md`
34862
34884
  ),
34863
34885
  "copilot",
34864
34886
  relativePath,
@@ -34868,7 +34890,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34868
34890
  }
34869
34891
  if (relativePath.endsWith("hooks.json")) {
34870
34892
  removeManagedCompiledArtifact2(
34871
- path48.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
34893
+ path49.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
34872
34894
  "copilot",
34873
34895
  relativePath,
34874
34896
  logger
@@ -34898,9 +34920,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
34898
34920
  }
34899
34921
  if (relativePath.startsWith("agents/")) {
34900
34922
  removeManagedCompiledArtifact2(
34901
- path48.join(
34923
+ path49.join(
34902
34924
  resolveTargetPath(paths.agents ?? ""),
34903
- `${path48.parse(relativePath).name}.toml`
34925
+ `${path49.parse(relativePath).name}.toml`
34904
34926
  ),
34905
34927
  "codex",
34906
34928
  relativePath,
@@ -34910,9 +34932,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
34910
34932
  }
34911
34933
  if (relativePath.startsWith("rules/")) {
34912
34934
  removeManagedCompiledArtifact2(
34913
- path48.join(
34935
+ path49.join(
34914
34936
  resolveTargetPath(paths.rules ?? ""),
34915
- `${path48.parse(relativePath).name}.rules`
34937
+ `${path49.parse(relativePath).name}.rules`
34916
34938
  ),
34917
34939
  "codex",
34918
34940
  relativePath,
@@ -34951,9 +34973,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
34951
34973
  }
34952
34974
  if (relativePath.startsWith("agents/")) {
34953
34975
  removeManagedCompiledArtifact2(
34954
- path48.join(
34976
+ path49.join(
34955
34977
  resolveTargetPath(paths.agents ?? ""),
34956
- `${path48.parse(relativePath).name}.md`
34978
+ `${path49.parse(relativePath).name}.md`
34957
34979
  ),
34958
34980
  "opencode",
34959
34981
  relativePath,
@@ -34963,9 +34985,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
34963
34985
  }
34964
34986
  if (relativePath.startsWith("commands/")) {
34965
34987
  removeManagedCompiledArtifact2(
34966
- path48.join(
34988
+ path49.join(
34967
34989
  resolveTargetPath(paths.commands ?? ""),
34968
- `${path48.parse(relativePath).name}.md`
34990
+ `${path49.parse(relativePath).name}.md`
34969
34991
  ),
34970
34992
  "opencode",
34971
34993
  relativePath,
@@ -34997,9 +35019,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
34997
35019
  }
34998
35020
  if (relativePath.startsWith("agents/")) {
34999
35021
  removeManagedCompiledArtifact2(
35000
- path48.join(
35022
+ path49.join(
35001
35023
  resolveTargetPath(paths.agents ?? ""),
35002
- `${path48.parse(relativePath).name}.md`
35024
+ `${path49.parse(relativePath).name}.md`
35003
35025
  ),
35004
35026
  "cursor",
35005
35027
  relativePath,
@@ -35009,9 +35031,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35009
35031
  }
35010
35032
  if (relativePath.startsWith("rules/")) {
35011
35033
  removeManagedCompiledArtifact2(
35012
- path48.join(
35034
+ path49.join(
35013
35035
  resolveTargetPath(paths.rules ?? ""),
35014
- `${path48.parse(relativePath).name}.mdc`
35036
+ `${path49.parse(relativePath).name}.mdc`
35015
35037
  ),
35016
35038
  "cursor",
35017
35039
  relativePath,
@@ -35021,9 +35043,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35021
35043
  }
35022
35044
  if (relativePath.startsWith("commands/")) {
35023
35045
  removeManagedCompiledArtifact2(
35024
- path48.join(
35046
+ path49.join(
35025
35047
  resolveTargetPath(paths.skills ?? ""),
35026
- path48.parse(relativePath).name,
35048
+ path49.parse(relativePath).name,
35027
35049
  "SKILL.md"
35028
35050
  ),
35029
35051
  "cursor",
@@ -35067,9 +35089,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35067
35089
  }
35068
35090
  if (relativePath.startsWith("rules/")) {
35069
35091
  removeManagedCompiledArtifact2(
35070
- path48.join(
35092
+ path49.join(
35071
35093
  resolveTargetPath(paths.rules ?? ""),
35072
- `${path48.parse(relativePath).name}.md`
35094
+ `${path49.parse(relativePath).name}.md`
35073
35095
  ),
35074
35096
  "cline",
35075
35097
  relativePath,
@@ -35079,9 +35101,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35079
35101
  }
35080
35102
  if (relativePath.startsWith("commands/")) {
35081
35103
  removeManagedCompiledArtifact2(
35082
- path48.join(
35104
+ path49.join(
35083
35105
  resolveTargetPath(paths.workflows ?? ""),
35084
- path48.basename(relativePath)
35106
+ path49.basename(relativePath)
35085
35107
  ),
35086
35108
  "cline",
35087
35109
  relativePath,
@@ -35099,17 +35121,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35099
35121
  }
35100
35122
  }
35101
35123
  function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
35102
- if (!fs47.existsSync(artifactPath)) {
35124
+ if (!fs48.existsSync(artifactPath)) {
35103
35125
  return;
35104
35126
  }
35105
- if (!fs47.statSync(artifactPath).isFile()) {
35127
+ if (!fs48.statSync(artifactPath).isFile()) {
35106
35128
  return;
35107
35129
  }
35108
- const marker = extractProvenanceMarker(fs47.readFileSync(artifactPath, "utf8"));
35130
+ const marker = extractProvenanceMarker(fs48.readFileSync(artifactPath, "utf8"));
35109
35131
  if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
35110
35132
  return;
35111
35133
  }
35112
- fs47.rmSync(artifactPath, { force: true });
35134
+ fs48.rmSync(artifactPath, { force: true });
35113
35135
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
35114
35136
  }
35115
35137
  function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
@@ -35140,10 +35162,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
35140
35162
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
35141
35163
  }
35142
35164
  function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
35143
- if (!fs47.existsSync(artifactPath)) {
35165
+ if (!fs48.existsSync(artifactPath)) {
35144
35166
  return;
35145
35167
  }
35146
- const content = fs47.readFileSync(artifactPath, "utf8");
35168
+ const content = fs48.readFileSync(artifactPath, "utf8");
35147
35169
  const startMarker = "# tangyr: managed mcp start";
35148
35170
  const endMarker = "# tangyr: managed mcp end";
35149
35171
  const startIndex = content.indexOf(startMarker);
@@ -35160,19 +35182,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
35160
35182
  const after = content.slice(endIndex + endMarker.length).trimStart();
35161
35183
  const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
35162
35184
  if (cleaned.length === 0) {
35163
- fs47.rmSync(artifactPath, { force: true });
35185
+ fs48.rmSync(artifactPath, { force: true });
35164
35186
  } else {
35165
- fs47.writeFileSync(artifactPath, `${cleaned}
35187
+ fs48.writeFileSync(artifactPath, `${cleaned}
35166
35188
  `);
35167
35189
  }
35168
35190
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
35169
35191
  }
35170
35192
  function readJsonObject5(filePath) {
35171
- if (!fs47.existsSync(filePath)) {
35193
+ if (!fs48.existsSync(filePath)) {
35172
35194
  return null;
35173
35195
  }
35174
35196
  try {
35175
- const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
35197
+ const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
35176
35198
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
35177
35199
  } catch {
35178
35200
  return null;
@@ -35186,10 +35208,10 @@ function readJsonMetadata(value) {
35186
35208
  }
35187
35209
  function writeJsonOrRemove2(filePath, parsed) {
35188
35210
  if (isEmptyJsonValue2(parsed)) {
35189
- fs47.rmSync(filePath, { force: true });
35211
+ fs48.rmSync(filePath, { force: true });
35190
35212
  return;
35191
35213
  }
35192
- fs47.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
35214
+ fs48.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
35193
35215
  `);
35194
35216
  }
35195
35217
  function isEmptyJsonValue2(value) {
@@ -35249,8 +35271,8 @@ function removeManagedHookEntries(value, expectedSource) {
35249
35271
  }
35250
35272
 
35251
35273
  // src/commands/validate.ts
35252
- import fs48 from "fs";
35253
- import path49 from "path";
35274
+ import fs49 from "fs";
35275
+ import path50 from "path";
35254
35276
  var SUPPORTED_KIT_FORMATS2 = [1];
35255
35277
  var SUPPORTED_DISCIPLINE_VERSIONS = [
35256
35278
  "0.14.0",
@@ -35365,12 +35387,12 @@ function checkArchetype(kit) {
35365
35387
  }
35366
35388
  function checkHookScriptsExist(kit) {
35367
35389
  const violations = [];
35368
- const hooksDir = path49.join(kit.path, "hooks");
35390
+ const hooksDir = path50.join(kit.path, "hooks");
35369
35391
  const missingSet = new Set(kit.components.hooks.missing);
35370
35392
  for (const name of kit.components.hooks.declared) {
35371
35393
  if (missingSet.has(name)) continue;
35372
- const declarationPath = path49.join(hooksDir, `${name}.md`);
35373
- if (!fs48.existsSync(declarationPath)) continue;
35394
+ const declarationPath = path50.join(hooksDir, `${name}.md`);
35395
+ if (!fs49.existsSync(declarationPath)) continue;
35374
35396
  let data;
35375
35397
  try {
35376
35398
  ({ data } = parseMarkdownFrontmatter(declarationPath));
@@ -35380,8 +35402,8 @@ function checkHookScriptsExist(kit) {
35380
35402
  if (typeof data.command === "string" && data.command.trim().length > 0) {
35381
35403
  continue;
35382
35404
  }
35383
- const scriptPath = path49.join(hooksDir, "scripts", `${name}.ts`);
35384
- if (!fs48.existsSync(scriptPath)) {
35405
+ const scriptPath = path50.join(hooksDir, "scripts", `${name}.ts`);
35406
+ if (!fs49.existsSync(scriptPath)) {
35385
35407
  violations.push({
35386
35408
  code: "hook-script-missing",
35387
35409
  location: `hooks/scripts/${name}.ts`,
@@ -35394,10 +35416,10 @@ function checkHookScriptsExist(kit) {
35394
35416
  function checkOptionalSourceDocuments(kit) {
35395
35417
  const violations = [];
35396
35418
  for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
35397
- const filePath = path49.join(kit.path, name);
35398
- if (!fs48.existsSync(filePath)) continue;
35419
+ const filePath = path50.join(kit.path, name);
35420
+ if (!fs49.existsSync(filePath)) continue;
35399
35421
  try {
35400
- const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
35422
+ const parsed = JSON.parse(fs49.readFileSync(filePath, "utf8"));
35401
35423
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
35402
35424
  violations.push({
35403
35425
  code: "optional-source-malformed",
@@ -35419,10 +35441,10 @@ function checkSkillSubfolderNames(kit) {
35419
35441
  const notices = [];
35420
35442
  const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
35421
35443
  for (const name of kit.components.skills.declared) {
35422
- const skillDir = path49.join(kit.path, "skills", name);
35444
+ const skillDir = path50.join(kit.path, "skills", name);
35423
35445
  let entries;
35424
35446
  try {
35425
- entries = fs48.readdirSync(skillDir, { withFileTypes: true });
35447
+ entries = fs49.readdirSync(skillDir, { withFileTypes: true });
35426
35448
  } catch {
35427
35449
  continue;
35428
35450
  }
@@ -35440,7 +35462,7 @@ function checkSkillSubfolderNames(kit) {
35440
35462
  return notices;
35441
35463
  }
35442
35464
  function checkHooksSourceForm(kit) {
35443
- const hooksDir = path49.join(kit.path, "hooks");
35465
+ const hooksDir = path50.join(kit.path, "hooks");
35444
35466
  const message = describeHooksSourceConflict(
35445
35467
  hooksDir,
35446
35468
  kit.components.hooks.declared
@@ -35452,12 +35474,12 @@ function checkHooksSourceForm(kit) {
35452
35474
  } : null;
35453
35475
  }
35454
35476
  function checkHookDeclarations(kit) {
35455
- const hooksDir = path49.join(kit.path, "hooks");
35477
+ const hooksDir = path50.join(kit.path, "hooks");
35456
35478
  return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
35457
35479
  (r) => ({
35458
35480
  code: "hook-declaration-invalid",
35459
- location: `hooks/${path49.basename(r.file)}`,
35460
- 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.`
35481
+ location: `hooks/${path50.basename(r.file)}`,
35482
+ message: `hooks: '${path50.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.`
35461
35483
  })
35462
35484
  );
35463
35485
  }
@@ -35477,11 +35499,11 @@ function checkKitFormatSupported(kit) {
35477
35499
  function checkEntrypointExists(kit) {
35478
35500
  const declared = kit.entrypoint;
35479
35501
  const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
35480
- const entrypointPath = path49.join(kit.path, entrypoint);
35481
- if (fs48.existsSync(entrypointPath)) {
35502
+ const entrypointPath = path50.join(kit.path, entrypoint);
35503
+ if (fs49.existsSync(entrypointPath)) {
35482
35504
  return null;
35483
35505
  }
35484
- const legacyPresent = declared === void 0 && fs48.existsSync(path49.join(kit.path, LEGACY_ENTRYPOINT));
35506
+ const legacyPresent = declared === void 0 && fs49.existsSync(path50.join(kit.path, LEGACY_ENTRYPOINT));
35485
35507
  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.`;
35486
35508
  return {
35487
35509
  code: "entrypoint-missing",
@@ -35540,9 +35562,9 @@ function checkComponentFrontmatter(kit) {
35540
35562
  const missingSet = new Set(kit.components[cat].missing);
35541
35563
  for (const name of kit.components[cat].declared) {
35542
35564
  if (missingSet.has(name)) continue;
35543
- const filePath = cat === "skills" ? path49.join(kit.path, cat, name, "SKILL.md") : path49.join(kit.path, cat, `${name}.md`);
35544
- if (!fs48.existsSync(filePath)) continue;
35545
- const relPath = path49.relative(kit.path, filePath);
35565
+ const filePath = cat === "skills" ? path50.join(kit.path, cat, name, "SKILL.md") : path50.join(kit.path, cat, `${name}.md`);
35566
+ if (!fs49.existsSync(filePath)) continue;
35567
+ const relPath = path50.relative(kit.path, filePath);
35546
35568
  try {
35547
35569
  const { data } = parseMarkdownFrontmatter(filePath);
35548
35570
  for (const field of requiredFields) {
@@ -35567,10 +35589,10 @@ function checkComponentFrontmatter(kit) {
35567
35589
  }
35568
35590
  function checkReservedRootNames(kit) {
35569
35591
  const violations = [];
35570
- if (!fs48.existsSync(kit.path) || !fs48.statSync(kit.path).isDirectory()) {
35592
+ if (!fs49.existsSync(kit.path) || !fs49.statSync(kit.path).isDirectory()) {
35571
35593
  return violations;
35572
35594
  }
35573
- const entries = fs48.readdirSync(kit.path, { withFileTypes: true });
35595
+ const entries = fs49.readdirSync(kit.path, { withFileTypes: true });
35574
35596
  for (const entry of entries) {
35575
35597
  if (RESERVED_ROOT_NAMES.includes(entry.name)) {
35576
35598
  violations.push({
@@ -35587,8 +35609,8 @@ function checkHumanOnlyCommandInvocation(kit) {
35587
35609
  const missingSet = new Set(kit.components.commands.missing);
35588
35610
  for (const name of kit.components.commands.declared) {
35589
35611
  if (missingSet.has(name)) continue;
35590
- const filePath = path49.join(kit.path, "commands", `${name}.md`);
35591
- if (!fs48.existsSync(filePath)) continue;
35612
+ const filePath = path50.join(kit.path, "commands", `${name}.md`);
35613
+ if (!fs49.existsSync(filePath)) continue;
35592
35614
  let data;
35593
35615
  try {
35594
35616
  ({ data } = parseMarkdownFrontmatter(filePath));
@@ -35601,7 +35623,7 @@ function checkHumanOnlyCommandInvocation(kit) {
35601
35623
  if (!barred) {
35602
35624
  violations.push({
35603
35625
  code: "command-human-only-model-invocable",
35604
- location: path49.relative(kit.path, filePath),
35626
+ location: path50.relative(kit.path, filePath),
35605
35627
  message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
35606
35628
  });
35607
35629
  }
@@ -35610,8 +35632,8 @@ function checkHumanOnlyCommandInvocation(kit) {
35610
35632
  }
35611
35633
 
35612
35634
  // src/commands/verify.ts
35613
- import fs49 from "fs";
35614
- import path50 from "path";
35635
+ import fs50 from "fs";
35636
+ import path51 from "path";
35615
35637
  function runVerifyCommand(options, logger) {
35616
35638
  if (options.target && !isKnownTarget(options.target)) {
35617
35639
  throwUnrecognizedTarget(options.target);
@@ -35792,8 +35814,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
35792
35814
  if (!slotPath) {
35793
35815
  continue;
35794
35816
  }
35795
- const fullPath = subPath ? path50.join(slotPath, subPath) : slotPath;
35796
- if (!fs49.existsSync(fullPath)) {
35817
+ const fullPath = subPath ? path51.join(slotPath, subPath) : slotPath;
35818
+ if (!fs50.existsSync(fullPath)) {
35797
35819
  failures.push(
35798
35820
  `claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
35799
35821
  );