@alessandroraffa/tangyr 4.0.0 → 4.2.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 path52 = __require("path");
1376
- var fs51 = __require("fs");
1375
+ var path53 = __require("path");
1376
+ var fs52 = __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 (fs51.existsSync(executableFile)) return;
2370
+ if (fs52.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 = path52.resolve(baseDir, baseName);
2389
- if (fs51.existsSync(localBin)) return localBin;
2390
- if (sourceExt.includes(path52.extname(baseName))) return void 0;
2388
+ const localBin = path53.resolve(baseDir, baseName);
2389
+ if (fs52.existsSync(localBin)) return localBin;
2390
+ if (sourceExt.includes(path53.extname(baseName))) return void 0;
2391
2391
  const foundExt = sourceExt.find(
2392
- (ext) => fs51.existsSync(`${localBin}${ext}`)
2392
+ (ext) => fs52.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 = fs51.realpathSync(this._scriptPath);
2404
+ resolvedScriptPath = fs52.realpathSync(this._scriptPath);
2405
2405
  } catch {
2406
2406
  resolvedScriptPath = this._scriptPath;
2407
2407
  }
2408
- executableDir = path52.resolve(
2409
- path52.dirname(resolvedScriptPath),
2408
+ executableDir = path53.resolve(
2409
+ path53.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 = path52.basename(
2416
+ const legacyName = path53.basename(
2417
2417
  this._scriptPath,
2418
- path52.extname(this._scriptPath)
2418
+ path53.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(path52.extname(executableFile));
2429
+ launchWithNode = sourceExt.includes(path53.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 = path52.basename(filename, path52.extname(filename));
3344
+ this._name = path53.basename(filename, path53.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(path53) {
3359
- if (path53 === void 0) return this._executableDir;
3360
- this._executableDir = path53;
3358
+ executableDir(path54) {
3359
+ if (path54 === void 0) return this._executableDir;
3360
+ this._executableDir = path54;
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, path52) {
3717
- const ctrl = callVisitor(key, node, visitor, path52);
3716
+ function visit_(key, node, visitor, path53) {
3717
+ const ctrl = callVisitor(key, node, visitor, path53);
3718
3718
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3719
- replaceNode(key, path52, ctrl);
3720
- return visit_(key, ctrl, visitor, path52);
3719
+ replaceNode(key, path53, ctrl);
3720
+ return visit_(key, ctrl, visitor, path53);
3721
3721
  }
3722
3722
  if (typeof ctrl !== "symbol") {
3723
3723
  if (identity.isCollection(node)) {
3724
- path52 = Object.freeze(path52.concat(node));
3724
+ path53 = Object.freeze(path53.concat(node));
3725
3725
  for (let i = 0; i < node.items.length; ++i) {
3726
- const ci2 = visit_(i, node.items[i], visitor, path52);
3726
+ const ci2 = visit_(i, node.items[i], visitor, path53);
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
- path52 = Object.freeze(path52.concat(node));
3738
- const ck = visit_("key", node.key, visitor, path52);
3737
+ path53 = Object.freeze(path53.concat(node));
3738
+ const ck = visit_("key", node.key, visitor, path53);
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, path52);
3743
+ const cv = visit_("value", node.value, visitor, path53);
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, path52) {
3765
- const ctrl = await callVisitor(key, node, visitor, path52);
3764
+ async function visitAsync_(key, node, visitor, path53) {
3765
+ const ctrl = await callVisitor(key, node, visitor, path53);
3766
3766
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3767
- replaceNode(key, path52, ctrl);
3768
- return visitAsync_(key, ctrl, visitor, path52);
3767
+ replaceNode(key, path53, ctrl);
3768
+ return visitAsync_(key, ctrl, visitor, path53);
3769
3769
  }
3770
3770
  if (typeof ctrl !== "symbol") {
3771
3771
  if (identity.isCollection(node)) {
3772
- path52 = Object.freeze(path52.concat(node));
3772
+ path53 = Object.freeze(path53.concat(node));
3773
3773
  for (let i = 0; i < node.items.length; ++i) {
3774
- const ci2 = await visitAsync_(i, node.items[i], visitor, path52);
3774
+ const ci2 = await visitAsync_(i, node.items[i], visitor, path53);
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
- path52 = Object.freeze(path52.concat(node));
3786
- const ck = await visitAsync_("key", node.key, visitor, path52);
3785
+ path53 = Object.freeze(path53.concat(node));
3786
+ const ck = await visitAsync_("key", node.key, visitor, path53);
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, path52);
3791
+ const cv = await visitAsync_("value", node.value, visitor, path53);
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, path52) {
3818
+ function callVisitor(key, node, visitor, path53) {
3819
3819
  if (typeof visitor === "function")
3820
- return visitor(key, node, path52);
3820
+ return visitor(key, node, path53);
3821
3821
  if (identity.isMap(node))
3822
- return visitor.Map?.(key, node, path52);
3822
+ return visitor.Map?.(key, node, path53);
3823
3823
  if (identity.isSeq(node))
3824
- return visitor.Seq?.(key, node, path52);
3824
+ return visitor.Seq?.(key, node, path53);
3825
3825
  if (identity.isPair(node))
3826
- return visitor.Pair?.(key, node, path52);
3826
+ return visitor.Pair?.(key, node, path53);
3827
3827
  if (identity.isScalar(node))
3828
- return visitor.Scalar?.(key, node, path52);
3828
+ return visitor.Scalar?.(key, node, path53);
3829
3829
  if (identity.isAlias(node))
3830
- return visitor.Alias?.(key, node, path52);
3830
+ return visitor.Alias?.(key, node, path53);
3831
3831
  return void 0;
3832
3832
  }
3833
- function replaceNode(key, path52, node) {
3834
- const parent = path52[path52.length - 1];
3833
+ function replaceNode(key, path53, node) {
3834
+ const parent = path53[path53.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, path52, value) {
4442
+ function collectionFromPath(schema, path53, value) {
4443
4443
  let v2 = value;
4444
- for (let i = path52.length - 1; i >= 0; --i) {
4445
- const k2 = path52[i];
4444
+ for (let i = path53.length - 1; i >= 0; --i) {
4445
+ const k2 = path53[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 = (path52) => path52 == null || typeof path52 === "object" && !!path52[Symbol.iterator]().next().done;
4464
+ var isEmptyPath = (path53) => path53 == null || typeof path53 === "object" && !!path53[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(path52, value) {
4495
- if (isEmptyPath(path52))
4494
+ addIn(path53, value) {
4495
+ if (isEmptyPath(path53))
4496
4496
  this.add(value);
4497
4497
  else {
4498
- const [key, ...rest] = path52;
4498
+ const [key, ...rest] = path53;
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(path52) {
4513
- const [key, ...rest] = path52;
4512
+ deleteIn(path53) {
4513
+ const [key, ...rest] = path53;
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(path52, keepScalar) {
4528
- const [key, ...rest] = path52;
4527
+ getIn(path53, keepScalar) {
4528
+ const [key, ...rest] = path53;
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(path52) {
4547
- const [key, ...rest] = path52;
4546
+ hasIn(path53) {
4547
+ const [key, ...rest] = path53;
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(path52, value) {
4558
- const [key, ...rest] = path52;
4557
+ setIn(path53, value) {
4558
+ const [key, ...rest] = path53;
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(path52, value) {
7070
+ addIn(path53, value) {
7071
7071
  if (assertCollection(this.contents))
7072
- this.contents.addIn(path52, value);
7072
+ this.contents.addIn(path53, 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(path52) {
7148
- if (Collection.isEmptyPath(path52)) {
7147
+ deleteIn(path53) {
7148
+ if (Collection.isEmptyPath(path53)) {
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(path52) : false;
7154
+ return assertCollection(this.contents) ? this.contents.deleteIn(path53) : 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(path52, keepScalar) {
7170
- if (Collection.isEmptyPath(path52))
7169
+ getIn(path53, keepScalar) {
7170
+ if (Collection.isEmptyPath(path53))
7171
7171
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
7172
- return identity.isCollection(this.contents) ? this.contents.getIn(path52, keepScalar) : void 0;
7172
+ return identity.isCollection(this.contents) ? this.contents.getIn(path53, 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(path52) {
7184
- if (Collection.isEmptyPath(path52))
7183
+ hasIn(path53) {
7184
+ if (Collection.isEmptyPath(path53))
7185
7185
  return this.contents !== void 0;
7186
- return identity.isCollection(this.contents) ? this.contents.hasIn(path52) : false;
7186
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path53) : 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(path52, value) {
7204
- if (Collection.isEmptyPath(path52)) {
7203
+ setIn(path53, value) {
7204
+ if (Collection.isEmptyPath(path53)) {
7205
7205
  this.contents = value;
7206
7206
  } else if (this.contents == null) {
7207
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path52), value);
7207
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path53), value);
7208
7208
  } else if (assertCollection(this.contents)) {
7209
- this.contents.setIn(path52, value);
7209
+ this.contents.setIn(path53, 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, path52) => {
9166
+ visit.itemAtPath = (cst, path53) => {
9167
9167
  let item = cst;
9168
- for (const [field, index] of path52) {
9168
+ for (const [field, index] of path53) {
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, path52) => {
9178
- const parent = visit.itemAtPath(cst, path52.slice(0, -1));
9179
- const field = path52[path52.length - 1][0];
9177
+ visit.parentCollection = (cst, path53) => {
9178
+ const parent = visit.itemAtPath(cst, path53.slice(0, -1));
9179
+ const field = path53[path53.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(path52, item, visitor) {
9186
- let ctrl = visitor(item, path52);
9185
+ function _visit(path53, item, visitor) {
9186
+ let ctrl = visitor(item, path53);
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(path52.concat([[field, i]])), token.items[i], visitor);
9193
+ const ci2 = _visit(Object.freeze(path53.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, path52);
9204
+ ctrl = ctrl(item, path53);
9205
9205
  }
9206
9206
  }
9207
- return typeof ctrl === "function" ? ctrl(item, path52) : ctrl;
9207
+ return typeof ctrl === "function" ? ctrl(item, path53) : 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 fs51 = this.flowScalar(this.type);
10492
+ const fs52 = this.flowScalar(this.type);
10493
10493
  if (atNextItem || it2.value) {
10494
- map.items.push({ start, key: fs51, sep: [] });
10494
+ map.items.push({ start, key: fs52, sep: [] });
10495
10495
  this.onKeyLine = true;
10496
10496
  } else if (it2.sep) {
10497
- this.stack.push(fs51);
10497
+ this.stack.push(fs52);
10498
10498
  } else {
10499
- Object.assign(it2, { key: fs51, sep: [] });
10499
+ Object.assign(it2, { key: fs52, 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 fs51 = this.flowScalar(this.type);
10627
+ const fs52 = this.flowScalar(this.type);
10628
10628
  if (!it2 || it2.value)
10629
- fc.items.push({ start: [], key: fs51, sep: [] });
10629
+ fc.items.push({ start: [], key: fs52, sep: [] });
10630
10630
  else if (it2.sep)
10631
- this.stack.push(fs51);
10631
+ this.stack.push(fs52);
10632
10632
  else
10633
- Object.assign(it2, { key: fs51, sep: [] });
10633
+ Object.assign(it2, { key: fs52, sep: [] });
10634
10634
  return;
10635
10635
  }
10636
10636
  case "flow-map-end":
@@ -16497,7 +16497,10 @@ function resolveCopilotProfile(scope, projectRoot, mappings) {
16497
16497
  hooks: r(slotMap, "hooks"),
16498
16498
  hook_scripts: r(slotMap, "hook_scripts"),
16499
16499
  mcp_shared_file: r(slotMap, "mcp_shared_file"),
16500
- instructions
16500
+ instructions,
16501
+ // Project-only, like instructions: `.github/instructions` is a repository
16502
+ // surface and has no user-level equivalent Copilot documents.
16503
+ rules: r(slotMap, "rules")
16501
16504
  };
16502
16505
  }
16503
16506
  function resolveCodexProfile(scope, projectRoot, mappings) {
@@ -21988,7 +21991,7 @@ function reportHooksSourceConflict(report, targets, hooksDir, hookNames) {
21988
21991
 
21989
21992
  // src/adapters/hook-scripts-bridge.ts
21990
21993
  import fs25 from "fs";
21991
- import path22 from "path";
21994
+ import path23 from "path";
21992
21995
 
21993
21996
  // src/utils/fs.ts
21994
21997
  import fs23 from "fs";
@@ -22118,8 +22121,62 @@ function compareArtifactState(recorded, artifactPath) {
22118
22121
  return current === recorded ? "current" : "modified";
22119
22122
  }
22120
22123
 
22124
+ // src/core/shared-artifacts.ts
22125
+ import path22 from "path";
22126
+ var SHARED_NAMESPACE = "shared";
22127
+ var SHARED_INSTRUCTIONS_KEY = `${SHARED_NAMESPACE}/AGENTS.md`;
22128
+ var SHARED_INSTRUCTIONS_FILE = "AGENTS.md";
22129
+ var SHARED_HOOK_SCRIPTS_KEY = `${SHARED_NAMESPACE}/hook_scripts`;
22130
+ function sharedArtifactKey(destination, scope, projectRoot) {
22131
+ if (scope !== "project") {
22132
+ return null;
22133
+ }
22134
+ const root = projectRoot ?? process.cwd();
22135
+ const shared = path22.resolve(root, SHARED_INSTRUCTIONS_FILE);
22136
+ return path22.resolve(destination) === shared ? SHARED_INSTRUCTIONS_KEY : null;
22137
+ }
22138
+ function resolveSharedArtifactKey(key, scope, projectRoot) {
22139
+ if (key !== SHARED_INSTRUCTIONS_KEY || scope !== "project") {
22140
+ return null;
22141
+ }
22142
+ return path22.join(projectRoot ?? process.cwd(), SHARED_INSTRUCTIONS_FILE);
22143
+ }
22144
+ var SHARED_SKILLS_PREFIX = `${SHARED_NAMESPACE}/skills`;
22145
+ function sharedKeyForDestination(destination, scope, projectRoot, platformPaths) {
22146
+ const instructions = sharedArtifactKey(destination, scope, projectRoot);
22147
+ if (instructions) {
22148
+ return instructions;
22149
+ }
22150
+ const resolved = path22.resolve(destination);
22151
+ let profiles;
22152
+ try {
22153
+ profiles = resolveTargetPaths({
22154
+ scope,
22155
+ projectRoot,
22156
+ mappings: platformPaths
22157
+ });
22158
+ } catch {
22159
+ return null;
22160
+ }
22161
+ if (resolved === path22.resolve(profiles.codex.hook_scripts)) {
22162
+ return SHARED_HOOK_SCRIPTS_KEY;
22163
+ }
22164
+ const skillsRoot = path22.resolve(profiles.opencode.skills_shared);
22165
+ if (resolved.startsWith(`${skillsRoot}${path22.sep}`)) {
22166
+ const inside = path22.relative(skillsRoot, resolved).split(path22.sep).join("/");
22167
+ return `${SHARED_SKILLS_PREFIX}/${inside}`;
22168
+ }
22169
+ return null;
22170
+ }
22171
+ function resolveSharedSkillsKey(key, sharedSkillsRoot) {
22172
+ if (!key.startsWith(`${SHARED_SKILLS_PREFIX}/`) || !sharedSkillsRoot) {
22173
+ return null;
22174
+ }
22175
+ const inside = key.slice(SHARED_SKILLS_PREFIX.length + 1);
22176
+ return path22.join(sharedSkillsRoot, ...inside.split("/"));
22177
+ }
22178
+
22121
22179
  // src/adapters/hook-scripts-bridge.ts
22122
- var SHARED_HOOK_SCRIPTS_KEY = "shared/hook_scripts";
22123
22180
  function syncHookScriptsBridge(args) {
22124
22181
  const { source, destination, config, sourceRoot, options, logger } = args;
22125
22182
  if (!fs25.existsSync(source)) {
@@ -22144,7 +22201,7 @@ function syncHookScriptsBridge(args) {
22144
22201
  } else if (artifactClass === "managed-symlink") {
22145
22202
  fs25.unlinkSync(destination);
22146
22203
  }
22147
- ensureDir(path22.dirname(destination));
22204
+ ensureDir(path23.dirname(destination));
22148
22205
  createRelativeSymlink(source, destination, "dir");
22149
22206
  if (args.manifest) {
22150
22207
  const state = describeArtifactState(destination);
@@ -22173,26 +22230,6 @@ function isSymlinkTo(linkPath, source) {
22173
22230
  }
22174
22231
  }
22175
22232
 
22176
- // src/core/shared-artifacts.ts
22177
- import path23 from "path";
22178
- var SHARED_NAMESPACE = "shared";
22179
- var SHARED_INSTRUCTIONS_KEY = `${SHARED_NAMESPACE}/AGENTS.md`;
22180
- var SHARED_INSTRUCTIONS_FILE = "AGENTS.md";
22181
- function sharedArtifactKey(destination, scope, projectRoot) {
22182
- if (scope !== "project") {
22183
- return null;
22184
- }
22185
- const root = projectRoot ?? process.cwd();
22186
- const shared = path23.resolve(root, SHARED_INSTRUCTIONS_FILE);
22187
- return path23.resolve(destination) === shared ? SHARED_INSTRUCTIONS_KEY : null;
22188
- }
22189
- function resolveSharedArtifactKey(key, scope, projectRoot) {
22190
- if (key !== SHARED_INSTRUCTIONS_KEY || scope !== "project") {
22191
- return null;
22192
- }
22193
- return path23.join(projectRoot ?? process.cwd(), SHARED_INSTRUCTIONS_FILE);
22194
- }
22195
-
22196
22233
  // src/core/remove.ts
22197
22234
  import fs26 from "fs";
22198
22235
  function removeManagedPath(managedPath) {
@@ -22313,6 +22350,7 @@ async function runUninstallCommand(options, logger) {
22313
22350
  const claudeRoots = scope === "global" && selectedTools.has("claude-code") ? resolveClaudeRootsForUninstall(manifest, runtime) : [];
22314
22351
  let removedCount = 0;
22315
22352
  const removedParentDirs = /* @__PURE__ */ new Set();
22353
+ const keptSurfaces = [];
22316
22354
  for (const file of useManifestPathRemoval ? manifestArtifacts : []) {
22317
22355
  if (isMergeSurfaceKey(file.relativePath)) {
22318
22356
  const surfacePath = file.path ?? resolveManifestKeyToPath(
@@ -22324,6 +22362,9 @@ async function runUninstallCommand(options, logger) {
22324
22362
  if (surfacePath && stripTangyrFromMergeSurface(surfacePath, logger)) {
22325
22363
  removedParentDirs.add(path24.dirname(surfacePath));
22326
22364
  removedCount++;
22365
+ if (fs27.existsSync(surfacePath)) {
22366
+ keptSurfaces.push(surfacePath);
22367
+ }
22327
22368
  } else {
22328
22369
  logger.verbose(
22329
22370
  ` left in place (merge surface, nothing of ours in it): ${surfacePath ?? file.relativePath}`
@@ -22426,10 +22467,6 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
22426
22467
  logger.verbose(` removed manifest: ${manifestPath}`);
22427
22468
  }
22428
22469
  pruneEmptyDirs(path24.join(scopePath, "backups"), logger);
22429
- const pruneBoundary = path24.dirname(scopePath);
22430
- for (const dir of removedParentDirs) {
22431
- pruneEmptyAncestors(dir, pruneBoundary, logger);
22432
- }
22433
22470
  try {
22434
22471
  const remaining = fs27.readdirSync(scopePath);
22435
22472
  if (remaining.length === 0) {
@@ -22452,6 +22489,22 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
22452
22489
  } else {
22453
22490
  logger.verbose(" no manifest to update after partial residue cleanup");
22454
22491
  }
22492
+ const pruneBoundary = path24.dirname(scopePath);
22493
+ for (const dir of removedParentDirs) {
22494
+ pruneEmptyAncestors(dir, pruneBoundary, logger);
22495
+ }
22496
+ if (keptSurfaces.length > 0) {
22497
+ logger.warn(
22498
+ `
22499
+ ${String(keptSurfaces.length)} shared file(s) kept, with Tangyr's own block removed from each:`
22500
+ );
22501
+ for (const surface of keptSurfaces) {
22502
+ logger.warn(` ${surface}`);
22503
+ }
22504
+ logger.warn(
22505
+ " What remains in them was not written with a marker of ours, so it is left rather than guessed at. Delete what you no longer want."
22506
+ );
22507
+ }
22455
22508
  logger.info(`
22456
22509
  Uninstallation complete: ${removedCount} file(s) removed.`);
22457
22510
  }
@@ -22467,6 +22520,13 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
22467
22520
  if (component === "hook_scripts") {
22468
22521
  return resolveSharedHookScriptsPath(runtime, scope, projectRoot);
22469
22522
  }
22523
+ const sharedSkill = resolveSharedSkillsKey(
22524
+ key,
22525
+ resolveSharedSkillsPath(runtime, scope, projectRoot)
22526
+ );
22527
+ if (sharedSkill) {
22528
+ return sharedSkill;
22529
+ }
22470
22530
  return resolveSharedArtifactKey(key, scope, projectRoot);
22471
22531
  }
22472
22532
  if (tool === "claude-code") {
@@ -23864,6 +23924,27 @@ function resolveSharedHookScriptsPath(runtime, scope, projectRoot) {
23864
23924
  }
23865
23925
  return resolveTargetPath("~/.agents/hooks");
23866
23926
  }
23927
+ function resolveSharedSkillsPath(runtime, scope, projectRoot) {
23928
+ if (runtime) {
23929
+ try {
23930
+ const mappings = loadMappings(
23931
+ runtime.sourceRoot,
23932
+ runtime.config,
23933
+ runtime.configDir
23934
+ );
23935
+ return resolveTargetPaths({
23936
+ scope,
23937
+ projectRoot,
23938
+ mappings: mappings.platformPaths
23939
+ }).opencode.skills_shared;
23940
+ } catch {
23941
+ }
23942
+ }
23943
+ if (scope === "project") {
23944
+ return path24.join(projectRoot ?? process.cwd(), ".agents", "skills");
23945
+ }
23946
+ return resolveTargetPath("~/.agents/skills");
23947
+ }
23867
23948
  function resolveOpenCodePaths(runtime, scope = "global", projectRoot) {
23868
23949
  if (runtime) {
23869
23950
  try {
@@ -25220,8 +25301,8 @@ function toConflictPolicy2(value) {
25220
25301
  }
25221
25302
 
25222
25303
  // src/commands/install.ts
25223
- import fs45 from "fs";
25224
- import path45 from "path";
25304
+ import fs46 from "fs";
25305
+ import path46 from "path";
25225
25306
 
25226
25307
  // src/core/channel-state.ts
25227
25308
  import fs32 from "fs";
@@ -26168,12 +26249,15 @@ function findContestedInstructions(instructionsByTarget) {
26168
26249
  }
26169
26250
  return contested;
26170
26251
  }
26171
- function reportContestedInstructions(instructionsByTarget, kitDeclaresRules, logger) {
26252
+ function reportContestedInstructions(instructionsByTarget, kitDeclaresRules, logger, missingByTarget) {
26172
26253
  if (!kitDeclaresRules) {
26173
26254
  return;
26174
26255
  }
26175
26256
  for (const contested of findContestedInstructions(instructionsByTarget)) {
26176
- if (contested.losers.length === 0) {
26257
+ const losers = missingByTarget ? contested.losers.filter(
26258
+ (target) => (missingByTarget.get(target)?.length ?? 0) > 0
26259
+ ) : contested.losers;
26260
+ if (losers.length === 0) {
26177
26261
  continue;
26178
26262
  }
26179
26263
  logger.warn(
@@ -26183,7 +26267,7 @@ ${contested.destination} is the instructions file for ${contested.claimants.join
26183
26267
  if (contested.survivor) {
26184
26268
  logger.warn(` The content on disk is ${contested.survivor}'s.`);
26185
26269
  }
26186
- for (const target of contested.losers) {
26270
+ for (const target of losers) {
26187
26271
  logger.warn(
26188
26272
  ` ${target} does NOT get its rules: ${FOLDS_RULES_INTO_INSTRUCTIONS[target]}, and that content is overwritten here.`
26189
26273
  );
@@ -26206,12 +26290,141 @@ function instructionsByActiveTarget(tools, scope, projectRoot, mappings) {
26206
26290
  byTarget.set(tool, instructions);
26207
26291
  }
26208
26292
  }
26293
+ if (scope === "project" && projectRoot && tools.includes("copilot")) {
26294
+ byTarget.set("copilot", path31.join(projectRoot, "AGENTS.md"));
26295
+ }
26209
26296
  return byTarget;
26210
26297
  }
26211
26298
 
26299
+ // src/core/rules-coverage.ts
26300
+ import fs35 from "fs";
26301
+ import path32 from "path";
26302
+ function readingSurfaces(profile) {
26303
+ const record = profile;
26304
+ return {
26305
+ slot: typeof record?.rules === "string" ? record.rules : null,
26306
+ instructions: typeof record?.instructions === "string" ? record.instructions : null
26307
+ };
26308
+ }
26309
+ function inRulesSlot(slot, rule) {
26310
+ let entries;
26311
+ try {
26312
+ entries = fs35.readdirSync(slot);
26313
+ } catch {
26314
+ return false;
26315
+ }
26316
+ return entries.some(
26317
+ (entry) => entry === rule || entry.startsWith(`${rule}.`)
26318
+ );
26319
+ }
26320
+ function inInstructions(instructions, rule) {
26321
+ let content;
26322
+ try {
26323
+ content = fs35.readFileSync(instructions, "utf8");
26324
+ } catch {
26325
+ return false;
26326
+ }
26327
+ return content.split("\n").some((line) => line.trim() === `## ${rule}`);
26328
+ }
26329
+ function recordedRulesLoss(lossReport, target) {
26330
+ const entries = lossReport.targets[target]?.rules ?? [];
26331
+ for (const artifact of entries) {
26332
+ for (const field of artifact.fields) {
26333
+ if (field.detail.length > 0) {
26334
+ return field.detail;
26335
+ }
26336
+ }
26337
+ }
26338
+ return null;
26339
+ }
26340
+ function measureRulesCoverage(tools, declaredRules, scope, projectRoot, mappings, lossReport, instructionsByTarget) {
26341
+ const resolved = resolveTargetPaths({
26342
+ scope,
26343
+ projectRoot,
26344
+ mappings: mappings.platformPaths
26345
+ });
26346
+ const contestedByPath = new Map(
26347
+ findContestedInstructions(instructionsByTarget).map((contested) => [
26348
+ contested.destination,
26349
+ contested
26350
+ ])
26351
+ );
26352
+ return tools.map((target) => {
26353
+ const surfaces = readingSurfaces(resolved[target]);
26354
+ const missing = declaredRules.filter((rule) => {
26355
+ if (surfaces.slot && inRulesSlot(surfaces.slot, rule)) {
26356
+ return false;
26357
+ }
26358
+ return !(surfaces.instructions && inInstructions(surfaces.instructions, rule));
26359
+ });
26360
+ return {
26361
+ target,
26362
+ missing,
26363
+ declared: declaredRules.length,
26364
+ reason: missing.length === 0 ? null : explain(target, surfaces, contestedByPath, lossReport, projectRoot)
26365
+ };
26366
+ });
26367
+ }
26368
+ function explain(target, surfaces, contestedByPath, lossReport, projectRoot) {
26369
+ if (surfaces.instructions) {
26370
+ const contested = contestedByPath.get(path32.resolve(surfaces.instructions));
26371
+ if (contested && contested.survivor !== null && contested.survivor !== target) {
26372
+ return `its rules are folded into ${display(surfaces.instructions, projectRoot)}, which ${contested.survivor} wrote last`;
26373
+ }
26374
+ }
26375
+ const recorded = recordedRulesLoss(lossReport, target);
26376
+ if (recorded) {
26377
+ return recorded;
26378
+ }
26379
+ if (!surfaces.slot) {
26380
+ return "it has no rules surface in this scope";
26381
+ }
26382
+ return `not in ${display(surfaces.slot, projectRoot)}, nor folded into the instructions file`;
26383
+ }
26384
+ function display(target, projectRoot) {
26385
+ if (!projectRoot) {
26386
+ return target;
26387
+ }
26388
+ const relative = path32.relative(projectRoot, target);
26389
+ return relative.startsWith("..") ? target : relative;
26390
+ }
26391
+ function reportRulesCoverage(coverage, logger) {
26392
+ if (coverage.length === 0 || coverage[0].declared === 0) {
26393
+ return;
26394
+ }
26395
+ const complete = coverage.every((entry) => entry.missing.length === 0);
26396
+ const say = complete ? (line) => {
26397
+ logger.verbose(line);
26398
+ } : (line) => {
26399
+ logger.warn(line);
26400
+ };
26401
+ const declared = coverage[0].declared;
26402
+ const width = Math.max(...coverage.map((entry) => entry.target.length));
26403
+ say(
26404
+ `
26405
+ Rules reaching each target (${String(declared)} declared, measured on disk):`
26406
+ );
26407
+ for (const entry of coverage) {
26408
+ const delivered = declared - entry.missing.length;
26409
+ const counts = `${String(delivered)}/${String(declared)}`;
26410
+ const head = ` ${entry.target.padEnd(width)} ${counts}`;
26411
+ if (entry.missing.length === 0) {
26412
+ say(head);
26413
+ continue;
26414
+ }
26415
+ say(`${head} missing: ${entry.missing.join(", ")}`);
26416
+ if (entry.reason) {
26417
+ say(` ${" ".repeat(width)} ${entry.reason}`);
26418
+ }
26419
+ }
26420
+ }
26421
+ function missingRulesByTarget(coverage) {
26422
+ return new Map(coverage.map((entry) => [entry.target, entry.missing]));
26423
+ }
26424
+
26212
26425
  // src/adapters/claude-code.ts
26213
- import fs37 from "fs";
26214
- import path35 from "path";
26426
+ import fs38 from "fs";
26427
+ import path36 from "path";
26215
26428
 
26216
26429
  // src/core/shim.ts
26217
26430
  import crypto4 from "crypto";
@@ -26233,8 +26446,8 @@ ${SHIM_BODY}`;
26233
26446
  }
26234
26447
 
26235
26448
  // src/core/skills-slot.ts
26236
- import fs35 from "fs";
26237
- import path32 from "path";
26449
+ import fs36 from "fs";
26450
+ import path33 from "path";
26238
26451
  function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
26239
26452
  if (!isSymlinkPath(destination)) {
26240
26453
  return false;
@@ -26247,7 +26460,7 @@ function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
26247
26460
  }
26248
26461
  function syncSkillsSlot(sync) {
26249
26462
  const { source, destination, logger } = sync;
26250
- if (!fs35.existsSync(source)) {
26463
+ if (!fs36.existsSync(source)) {
26251
26464
  return [
26252
26465
  {
26253
26466
  component: "skills",
@@ -26275,7 +26488,7 @@ function syncSkillsSlot(sync) {
26275
26488
  if (isLegacyWholesaleSymlink) {
26276
26489
  for (const name of foreignSkillNames(source, declaredNames)) {
26277
26490
  logger.info(
26278
- `[dry-run] skills: migrate foreign skill ${path32.join(source, name)} -> ${path32.join(destination, name)}`
26491
+ `[dry-run] skills: migrate foreign skill ${path33.join(source, name)} -> ${path33.join(destination, name)}`
26279
26492
  );
26280
26493
  }
26281
26494
  logger.info(
@@ -26283,9 +26496,9 @@ function syncSkillsSlot(sync) {
26283
26496
  );
26284
26497
  }
26285
26498
  for (const name of declaredNames ?? listSkillDirNames(source)) {
26286
- const skillDestination = path32.join(destination, name);
26499
+ const skillDestination = path33.join(destination, name);
26287
26500
  logger.info(
26288
- `[dry-run] skills: symlink ${path32.join(source, name)} -> ${skillDestination}`
26501
+ `[dry-run] skills: symlink ${path33.join(source, name)} -> ${skillDestination}`
26289
26502
  );
26290
26503
  outcomes2.push({
26291
26504
  component: "skills",
@@ -26312,9 +26525,9 @@ function syncSkillsSlot(sync) {
26312
26525
  }
26313
26526
  function syncSingleSkill(sync, name) {
26314
26527
  const { config, sourceRoot, source, destination } = sync;
26315
- const skillSource = path32.join(source, name);
26316
- const skillDestination = path32.join(destination, name);
26317
- if (!fs35.existsSync(skillSource)) {
26528
+ const skillSource = path33.join(source, name);
26529
+ const skillDestination = path33.join(destination, name);
26530
+ if (!fs36.existsSync(skillSource)) {
26318
26531
  return {
26319
26532
  component: "skills",
26320
26533
  status: "skipped",
@@ -26330,29 +26543,29 @@ function syncSingleSkill(sync, name) {
26330
26543
  };
26331
26544
  }
26332
26545
  if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
26333
- fs35.unlinkSync(skillDestination);
26546
+ fs36.unlinkSync(skillDestination);
26334
26547
  } else if (artifactClass === "unmanaged-conflict" && !sync.onUnmanagedConflict(skillDestination)) {
26335
26548
  return { component: "skills", status: "conflict", path: skillDestination };
26336
26549
  } else if (artifactClass === "managed-symlink") {
26337
- fs35.unlinkSync(skillDestination);
26550
+ fs36.unlinkSync(skillDestination);
26338
26551
  }
26339
26552
  createRelativeSymlink(skillSource, skillDestination, "dir");
26340
26553
  return { component: "skills", status: "success", path: skillDestination };
26341
26554
  }
26342
26555
  function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
26343
26556
  const foreignNames = foreignSkillNames(source, declaredNames);
26344
- fs35.unlinkSync(destination);
26557
+ fs36.unlinkSync(destination);
26345
26558
  ensureDir(destination);
26346
26559
  for (const name of foreignNames) {
26347
- const from = path32.join(source, name);
26348
- const to = path32.join(destination, name);
26349
- if (fs35.existsSync(to)) {
26560
+ const from = path33.join(source, name);
26561
+ const to = path33.join(destination, name);
26562
+ if (fs36.existsSync(to)) {
26350
26563
  logger.warn(
26351
26564
  `skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
26352
26565
  );
26353
26566
  continue;
26354
26567
  }
26355
- fs35.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
26568
+ fs36.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
26356
26569
  logger.warn(
26357
26570
  `skills migration: '${name}' is present under the kit's skills/ but is not declared in its manifest. Copied ${from} -> ${to} so the harness can read it. The original is left in the kit deliberately: this command does not modify a kit. Remove ${from} yourself if it does not belong there, or declare it in tangyr-kit.yaml if it does.`
26358
26571
  );
@@ -26366,44 +26579,44 @@ function foreignSkillNames(source, declaredNames) {
26366
26579
  return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
26367
26580
  }
26368
26581
  function listSkillDirNames(dir) {
26369
- if (!fs35.existsSync(dir)) {
26582
+ if (!fs36.existsSync(dir)) {
26370
26583
  return [];
26371
26584
  }
26372
- return fs35.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
26585
+ return fs36.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
26373
26586
  }
26374
26587
  function isSymlinkPath(filePath) {
26375
26588
  try {
26376
- return fs35.lstatSync(filePath).isSymbolicLink();
26589
+ return fs36.lstatSync(filePath).isSymbolicLink();
26377
26590
  } catch {
26378
26591
  return false;
26379
26592
  }
26380
26593
  }
26381
26594
  function isSymlinkTo2(linkPath, source) {
26382
26595
  try {
26383
- return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
26596
+ return fs36.realpathSync(linkPath) === fs36.realpathSync(source);
26384
26597
  } catch {
26385
26598
  return false;
26386
26599
  }
26387
26600
  }
26388
26601
 
26389
26602
  // src/core/hook-scripts.ts
26390
- import path33 from "path";
26603
+ import path34 from "path";
26391
26604
  function hookScriptsDir(bridge, target, projectRoot) {
26392
26605
  const globalBridge = resolveTargetPath("~/.agents/hooks");
26393
- if (path33.resolve(bridge) === path33.resolve(globalBridge)) {
26606
+ if (path34.resolve(bridge) === path34.resolve(globalBridge)) {
26394
26607
  return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
26395
26608
  }
26396
- const relative = path33.relative(projectRoot ?? process.cwd(), bridge);
26397
- const insideProject = !relative.startsWith("..") && !path33.isAbsolute(relative) && relative !== "";
26609
+ const relative = path34.relative(projectRoot ?? process.cwd(), bridge);
26610
+ const insideProject = !relative.startsWith("..") && !path34.isAbsolute(relative) && relative !== "";
26398
26611
  const variable = PROJECT_DIR_VARIABLE[target];
26399
26612
  if (insideProject && variable) {
26400
- const posix = path33.posix.join(
26401
- relative.split(path33.sep).join("/"),
26613
+ const posix = path34.posix.join(
26614
+ relative.split(path34.sep).join("/"),
26402
26615
  "scripts"
26403
26616
  );
26404
26617
  return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
26405
26618
  }
26406
- return { prefix: path33.join(bridge, "scripts"), machineLocal: true };
26619
+ return { prefix: path34.join(bridge, "scripts"), machineLocal: true };
26407
26620
  }
26408
26621
  var PROJECT_DIR_VARIABLE = {
26409
26622
  "claude-code": "$CLAUDE_PROJECT_DIR"
@@ -26413,19 +26626,19 @@ function machineLocalScriptPathNotice(target, prefix) {
26413
26626
  }
26414
26627
 
26415
26628
  // src/core/instructions-source.ts
26416
- import fs36 from "fs";
26417
- import path34 from "path";
26629
+ import fs37 from "fs";
26630
+ import path35 from "path";
26418
26631
  var PORTABLE_INSTRUCTIONS_NAME = "AGENTS.md";
26419
26632
  var InstructionsSourceMissingError = class extends Error {
26420
26633
  constructor(kitRoot, expected, declaredBy) {
26421
26634
  super(
26422
- `${path34.join(kitRoot, expected)}: instructions source not found (declared by ${declaredBy}). To fix: create that file, or point '${declaredBy}' at the file this kit actually carries. With neither declaration, the kit's ${DEFAULT_ENTRYPOINT} or ${PORTABLE_INSTRUCTIONS_NAME} is used.`
26635
+ `${path35.join(kitRoot, expected)}: instructions source not found (declared by ${declaredBy}). To fix: create that file, or point '${declaredBy}' at the file this kit actually carries. With neither declaration, the kit's ${DEFAULT_ENTRYPOINT} or ${PORTABLE_INSTRUCTIONS_NAME} is used.`
26423
26636
  );
26424
26637
  this.name = "InstructionsSourceMissingError";
26425
26638
  }
26426
26639
  };
26427
26640
  function normalizeLabel(kitRoot, file) {
26428
- return path34.relative(kitRoot, file).split(path34.sep).join("/");
26641
+ return path35.relative(kitRoot, file).split(path35.sep).join("/");
26429
26642
  }
26430
26643
  function isExplicitOverride(configured) {
26431
26644
  const normalize = (value) => value.replace(/\\/gu, "/").replace(/^\.\//u, "");
@@ -26434,8 +26647,8 @@ function isExplicitOverride(configured) {
26434
26647
  function resolveInstructionsSource(kitRoot, config) {
26435
26648
  const configured = config.source.instructions;
26436
26649
  if (isExplicitOverride(configured)) {
26437
- const file = path34.resolve(kitRoot, configured);
26438
- if (!fs36.existsSync(file)) {
26650
+ const file = path35.resolve(kitRoot, configured);
26651
+ if (!fs37.existsSync(file)) {
26439
26652
  throw new InstructionsSourceMissingError(
26440
26653
  kitRoot,
26441
26654
  configured,
@@ -26450,8 +26663,8 @@ function resolveInstructionsSource(kitRoot, config) {
26450
26663
  }
26451
26664
  const declared = resolveKitEntrypointName(kitRoot);
26452
26665
  if (declared !== void 0) {
26453
- const file = path34.resolve(kitRoot, declared);
26454
- if (!fs36.existsSync(file)) {
26666
+ const file = path35.resolve(kitRoot, declared);
26667
+ if (!fs37.existsSync(file)) {
26455
26668
  throw new InstructionsSourceMissingError(
26456
26669
  kitRoot,
26457
26670
  declared,
@@ -26465,13 +26678,13 @@ function resolveInstructionsSource(kitRoot, config) {
26465
26678
  };
26466
26679
  }
26467
26680
  for (const name of [DEFAULT_ENTRYPOINT, PORTABLE_INSTRUCTIONS_NAME]) {
26468
- const file = path34.resolve(kitRoot, name);
26469
- if (fs36.existsSync(file)) {
26681
+ const file = path35.resolve(kitRoot, name);
26682
+ if (fs37.existsSync(file)) {
26470
26683
  return { file, label: name, origin: "convention" };
26471
26684
  }
26472
26685
  }
26473
- const legacy = path34.resolve(kitRoot, LEGACY_ENTRYPOINT);
26474
- if (fs36.existsSync(legacy)) {
26686
+ const legacy = path35.resolve(kitRoot, LEGACY_ENTRYPOINT);
26687
+ if (fs37.existsSync(legacy)) {
26475
26688
  return {
26476
26689
  file: legacy,
26477
26690
  label: LEGACY_ENTRYPOINT,
@@ -26483,7 +26696,7 @@ function resolveInstructionsSource(kitRoot, config) {
26483
26696
  }
26484
26697
  function instructionsSourcePath(kitRoot, config) {
26485
26698
  const resolved = resolveInstructionsSource(kitRoot, config);
26486
- return resolved ? resolved.file : path34.resolve(kitRoot, config.source.instructions);
26699
+ return resolved ? resolved.file : path35.resolve(kitRoot, config.source.instructions);
26487
26700
  }
26488
26701
  function instructionsSourceLabel(kitRoot, config) {
26489
26702
  const resolved = resolveInstructionsSource(kitRoot, config);
@@ -26604,7 +26817,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
26604
26817
  if (!shouldSkipComponent(options, "hooks")) {
26605
26818
  outcomes.push(
26606
26819
  syncHookScriptsBridge({
26607
- source: path35.resolve(sourceRoot, config.source.hooks),
26820
+ source: path36.resolve(sourceRoot, config.source.hooks),
26608
26821
  destination: profile.hook_scripts,
26609
26822
  config,
26610
26823
  sourceRoot,
@@ -26656,13 +26869,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
26656
26869
  }
26657
26870
  function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
26658
26871
  if (!mappings.modelTiers.custom_provider) return;
26659
- const agentsDir = path35.join(sourceRoot, config.source.agents);
26660
- if (!fs37.existsSync(agentsDir)) return;
26661
- for (const agentFile of ts(path35.join(agentsDir, "*.md")).sort()) {
26872
+ const agentsDir = path36.join(sourceRoot, config.source.agents);
26873
+ if (!fs38.existsSync(agentsDir)) return;
26874
+ for (const agentFile of ts(path36.join(agentsDir, "*.md")).sort()) {
26662
26875
  const { data } = parseMarkdownFrontmatter(agentFile);
26663
26876
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
26664
26877
  if (hasProvider) {
26665
- const basename = path35.basename(agentFile);
26878
+ const basename = path36.basename(agentFile);
26666
26879
  addLoss(lossReport, "claude-code", "agents", {
26667
26880
  source: `agents/${basename}`,
26668
26881
  fields: [
@@ -26687,7 +26900,7 @@ function shouldSkipComponent(options, component) {
26687
26900
  var SHIM_MANIFEST_KEY = "claude-code/instructions_shim";
26688
26901
  function lstatOrNull(p) {
26689
26902
  try {
26690
- return fs37.lstatSync(p);
26903
+ return fs38.lstatSync(p);
26691
26904
  } catch {
26692
26905
  return null;
26693
26906
  }
@@ -26699,12 +26912,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26699
26912
  if (shimLink?.isSymbolicLink()) {
26700
26913
  backupFile(shimPath, manifest, scopePath);
26701
26914
  writeManifest(scopePath, manifest);
26702
- fs37.unlinkSync(shimPath);
26915
+ fs38.unlinkSync(shimPath);
26703
26916
  logger?.verbose(
26704
26917
  `instructions-shim: replaced an unmanaged symlink at ${shimPath}`
26705
26918
  );
26706
26919
  }
26707
- if (!fs37.existsSync(shimPath)) {
26920
+ if (!fs38.existsSync(shimPath)) {
26708
26921
  addArtifactToManifest(manifest, {
26709
26922
  relativePath: SHIM_MANIFEST_KEY,
26710
26923
  path: shimPath,
@@ -26712,12 +26925,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26712
26925
  origin: "tangyr-managed"
26713
26926
  });
26714
26927
  writeManifest(scopePath, manifest);
26715
- fs37.mkdirSync(path35.dirname(shimPath), { recursive: true });
26716
- fs37.writeFileSync(shimPath, shimContent);
26928
+ fs38.mkdirSync(path36.dirname(shimPath), { recursive: true });
26929
+ fs38.writeFileSync(shimPath, shimContent);
26717
26930
  logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
26718
26931
  return;
26719
26932
  }
26720
- const existing = fs37.readFileSync(shimPath, "utf8");
26933
+ const existing = fs38.readFileSync(shimPath, "utf8");
26721
26934
  const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
26722
26935
  const marker = extractProvenanceMarker(firstNonEmptyLine);
26723
26936
  if (marker !== null && marker.hash === expectedBodyHash) {
@@ -26734,7 +26947,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26734
26947
  }
26735
26948
  backupFile(shimPath, manifest, scopePath);
26736
26949
  writeManifest(scopePath, manifest);
26737
- fs37.writeFileSync(shimPath, shimContent);
26950
+ fs38.writeFileSync(shimPath, shimContent);
26738
26951
  addArtifactToManifest(manifest, {
26739
26952
  relativePath: SHIM_MANIFEST_KEY,
26740
26953
  path: shimPath,
@@ -26744,10 +26957,10 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26744
26957
  logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
26745
26958
  }
26746
26959
  function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
26747
- const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path35.resolve(sourceRoot, config.source[directComponent.sourceKey]);
26960
+ const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path36.resolve(sourceRoot, config.source[directComponent.sourceKey]);
26748
26961
  const sourceLabel = directComponent.sourceKey === "instructions" ? instructionsSourceLabel(sourceRoot, config) : config.source[directComponent.sourceKey];
26749
26962
  const destination = directComponent.destination;
26750
- if (!fs37.existsSync(source)) {
26963
+ if (!fs38.existsSync(source)) {
26751
26964
  return skippedMissingSource(directComponent.component, source);
26752
26965
  }
26753
26966
  if (options.dryRun) {
@@ -26769,7 +26982,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
26769
26982
  };
26770
26983
  }
26771
26984
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
26772
- fs37.unlinkSync(destination);
26985
+ fs38.unlinkSync(destination);
26773
26986
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
26774
26987
  return {
26775
26988
  component: directComponent.component,
@@ -26777,11 +26990,11 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
26777
26990
  path: destination
26778
26991
  };
26779
26992
  } else if (artifactClass === "managed-symlink") {
26780
- fs37.unlinkSync(destination);
26993
+ fs38.unlinkSync(destination);
26781
26994
  } else if (artifactClass === "managed-compiled") {
26782
- fs37.unlinkSync(destination);
26995
+ fs38.unlinkSync(destination);
26783
26996
  }
26784
- ensureDir(path35.dirname(destination));
26997
+ ensureDir(path36.dirname(destination));
26785
26998
  createRelativeSymlink(source, destination, directComponent.type, {
26786
26999
  logger,
26787
27000
  provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
@@ -26801,7 +27014,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
26801
27014
  return syncSkillsSlot({
26802
27015
  config,
26803
27016
  sourceRoot,
26804
- source: path35.resolve(sourceRoot, config.source.skills),
27017
+ source: path36.resolve(sourceRoot, config.source.skills),
26805
27018
  destination,
26806
27019
  dryRun: options.dryRun,
26807
27020
  logger,
@@ -26835,7 +27048,7 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
26835
27048
  destination,
26836
27049
  settings,
26837
27050
  stringifyJson2,
26838
- !fs37.existsSync(destination),
27051
+ !fs38.existsSync(destination),
26839
27052
  logger
26840
27053
  );
26841
27054
  return {
@@ -26845,8 +27058,8 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
26845
27058
  };
26846
27059
  }
26847
27060
  function syncMcp(config, sourceRoot, options, logger, destination) {
26848
- const source = path35.resolve(sourceRoot, config.source.mcp);
26849
- if (!fs37.existsSync(source)) {
27061
+ const source = path36.resolve(sourceRoot, config.source.mcp);
27062
+ if (!fs38.existsSync(source)) {
26850
27063
  return skippedMissingSource("mcp", source);
26851
27064
  }
26852
27065
  if (options.dryRun) {
@@ -26871,7 +27084,7 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
26871
27084
  destination,
26872
27085
  hostConfig,
26873
27086
  stringifyJson2,
26874
- !fs37.existsSync(destination),
27087
+ !fs38.existsSync(destination),
26875
27088
  logger
26876
27089
  );
26877
27090
  return {
@@ -26881,8 +27094,8 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
26881
27094
  };
26882
27095
  }
26883
27096
  function syncSettings(config, sourceRoot, options, logger, destination) {
26884
- const source = path35.resolve(sourceRoot, config.source.settings);
26885
- if (!fs37.existsSync(source)) {
27097
+ const source = path36.resolve(sourceRoot, config.source.settings);
27098
+ if (!fs38.existsSync(source)) {
26886
27099
  return skippedMissingSource("settings", source);
26887
27100
  }
26888
27101
  if (options.dryRun) {
@@ -26900,7 +27113,7 @@ function syncSettings(config, sourceRoot, options, logger, destination) {
26900
27113
  destination,
26901
27114
  settings,
26902
27115
  stringifyJson2,
26903
- !fs37.existsSync(destination),
27116
+ !fs38.existsSync(destination),
26904
27117
  logger
26905
27118
  );
26906
27119
  return {
@@ -26924,7 +27137,7 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
26924
27137
  if (manifest && scopePath) {
26925
27138
  backupFile(destination, manifest, scopePath);
26926
27139
  writeManifest(scopePath, manifest);
26927
- fs37.rmSync(destination, { recursive: true, force: true });
27140
+ fs38.rmSync(destination, { recursive: true, force: true });
26928
27141
  } else {
26929
27142
  const parked = parkConflictingPath(
26930
27143
  destination,
@@ -26939,7 +27152,7 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
26939
27152
  }
26940
27153
  return true;
26941
27154
  }
26942
- fs37.rmSync(destination, { recursive: true, force: true });
27155
+ fs38.rmSync(destination, { recursive: true, force: true });
26943
27156
  return true;
26944
27157
  }
26945
27158
  function skippedMissingSource(component, source) {
@@ -26951,16 +27164,16 @@ function skippedMissingSource(component, source) {
26951
27164
  }
26952
27165
  function isSymlinkTo3(linkPath, source) {
26953
27166
  try {
26954
- return fs37.realpathSync(linkPath) === fs37.realpathSync(source);
27167
+ return fs38.realpathSync(linkPath) === fs38.realpathSync(source);
26955
27168
  } catch {
26956
27169
  return false;
26957
27170
  }
26958
27171
  }
26959
27172
  function readJsonObject3(filePath) {
26960
- if (!fs37.existsSync(filePath)) {
27173
+ if (!fs38.existsSync(filePath)) {
26961
27174
  return {};
26962
27175
  }
26963
- const parsed = JSON.parse(fs37.readFileSync(filePath, "utf8"));
27176
+ const parsed = JSON.parse(fs38.readFileSync(filePath, "utf8"));
26964
27177
  return isRecord3(parsed) ? parsed : {};
26965
27178
  }
26966
27179
  function markManaged(value) {
@@ -26987,13 +27200,13 @@ function isRecord3(value) {
26987
27200
  // src/adapters/codex.ts
26988
27201
  var TOML3 = __toESM(require_toml(), 1);
26989
27202
  import crypto6 from "crypto";
26990
- import fs40 from "fs";
26991
- import path39 from "path";
27203
+ import fs41 from "fs";
27204
+ import path40 from "path";
26992
27205
 
26993
27206
  // src/compiler/agents.ts
26994
27207
  var TOML = __toESM(require_toml(), 1);
26995
27208
  var import_yaml8 = __toESM(require_dist(), 1);
26996
- import path36 from "path";
27209
+ import path37 from "path";
26997
27210
  var writeCapabilityClasses = /* @__PURE__ */ new Set(["filesystem-write", "shell-execution"]);
26998
27211
  var copilotToolAliasesByClass = {
26999
27212
  delegation: "agent",
@@ -27005,7 +27218,7 @@ var copilotToolAliasesByClass = {
27005
27218
  };
27006
27219
  function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
27007
27220
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
27008
- const relativeSource = `agents/${path36.basename(sourceFile)}`;
27221
+ const relativeSource = `agents/${path37.basename(sourceFile)}`;
27009
27222
  if (target === "opencode") {
27010
27223
  return compileOpenCodeAgent(
27011
27224
  sourceFile,
@@ -27046,7 +27259,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
27046
27259
  mappings,
27047
27260
  lossReport
27048
27261
  );
27049
- const overlayKey = `agents/${path36.basename(sourceFile, ".md")}.${target}.yaml`;
27262
+ const overlayKey = `agents/${path37.basename(sourceFile, ".md")}.${target}.yaml`;
27050
27263
  const targetFields = {
27051
27264
  ...translated.fields,
27052
27265
  ...extensions[overlayKey] ?? {}
@@ -27080,7 +27293,7 @@ ${TOML.stringify({
27080
27293
  function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
27081
27294
  if (typeof data.description !== "string" || data.description.trim() === "") {
27082
27295
  throw new Error(
27083
- `${path36.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
27296
+ `${path37.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
27084
27297
  );
27085
27298
  }
27086
27299
  const frontmatter = {
@@ -27134,7 +27347,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
27134
27347
  "permission",
27135
27348
  "permission-coarsening"
27136
27349
  ),
27137
- detail: `${path36.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
27350
+ detail: `${path37.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
27138
27351
  }
27139
27352
  ]
27140
27353
  });
@@ -27159,7 +27372,7 @@ ${(0, import_yaml8.stringify)(frontmatter).trim()}
27159
27372
  function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
27160
27373
  if (typeof data.description !== "string" || data.description.trim() === "") {
27161
27374
  throw new Error(
27162
- `${path36.basename(sourceFile)}: Cursor agent requires a non-empty description field`
27375
+ `${path37.basename(sourceFile)}: Cursor agent requires a non-empty description field`
27163
27376
  );
27164
27377
  }
27165
27378
  const frontmatter = {
@@ -27196,7 +27409,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
27196
27409
  "permission",
27197
27410
  "permission-coarsening"
27198
27411
  ),
27199
- detail: `${path36.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
27412
+ detail: `${path37.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
27200
27413
  }
27201
27414
  ]
27202
27415
  });
@@ -27215,7 +27428,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
27215
27428
  "provider",
27216
27429
  "provider-not-representable"
27217
27430
  ),
27218
- detail: `${path36.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
27431
+ detail: `${path37.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
27219
27432
  }
27220
27433
  ]
27221
27434
  });
@@ -27247,7 +27460,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
27247
27460
  "persona",
27248
27461
  "persona-not-representable"
27249
27462
  ),
27250
- detail: `${path36.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
27463
+ detail: `${path37.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
27251
27464
  }
27252
27465
  ]
27253
27466
  });
@@ -27295,7 +27508,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27295
27508
  field,
27296
27509
  "model-not-representable"
27297
27510
  ),
27298
- detail: `${path36.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
27511
+ detail: `${path37.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
27299
27512
  });
27300
27513
  return;
27301
27514
  }
@@ -27313,9 +27526,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27313
27526
  lossReport,
27314
27527
  target,
27315
27528
  "agents",
27316
- `agents/${path36.basename(sourceFile)}`,
27529
+ `agents/${path37.basename(sourceFile)}`,
27317
27530
  "info",
27318
- `${path36.basename(sourceFile)}: ${field} is delivered through another managed surface.`
27531
+ `${path37.basename(sourceFile)}: ${field} is delivered through another managed surface.`
27319
27532
  );
27320
27533
  return;
27321
27534
  }
@@ -27324,7 +27537,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27324
27537
  field,
27325
27538
  action: entryType,
27326
27539
  severity: resolveLossSeverity("agent-field", field, entryType),
27327
- detail: `${path36.basename(sourceFile)}: ${field} has no emitted field for this target.`
27540
+ detail: `${path37.basename(sourceFile)}: ${field} has no emitted field for this target.`
27328
27541
  });
27329
27542
  }
27330
27543
  function mapToolsToCapabilities(value, mappings) {
@@ -27788,13 +28001,13 @@ function addHookLoss(lossReport, target, eventName, sourceLabel, severity, reaso
27788
28001
 
27789
28002
  // src/compiler/command-as-skill.ts
27790
28003
  var import_yaml9 = __toESM(require_dist(), 1);
27791
- import fs38 from "fs";
27792
- import path37 from "path";
28004
+ import fs39 from "fs";
28005
+ import path38 from "path";
27793
28006
  var CARRIED_OVER = ["argument-hint", "agent", "launch"];
27794
28007
  function compileCommandAsSkill(commandFile, target) {
27795
- const name = path37.basename(commandFile, ".md");
28008
+ const name = path38.basename(commandFile, ".md");
27796
28009
  const { data, body } = parseMarkdownFrontmatter(commandFile);
27797
- const relativeSource = `commands/${path37.basename(commandFile)}`;
28010
+ const relativeSource = `commands/${path38.basename(commandFile)}`;
27798
28011
  const description = typeof data.description === "string" && data.description.trim().length > 0 ? data.description.trim() : `The ${name} command.`;
27799
28012
  const frontmatter = { name, description };
27800
28013
  for (const key of CARRIED_OVER) {
@@ -27817,11 +28030,11 @@ ${body.trim()}
27817
28030
  return { name, content, relativeSource };
27818
28031
  }
27819
28032
  function compileCommandsAsSkills(commandsRoot, target) {
27820
- if (!fs38.existsSync(commandsRoot)) {
28033
+ if (!fs39.existsSync(commandsRoot)) {
27821
28034
  return [];
27822
28035
  }
27823
- return fs38.readdirSync(commandsRoot).filter((entry) => entry.endsWith(".md")).sort().map(
27824
- (entry) => compileCommandAsSkill(path37.join(commandsRoot, entry), target)
28036
+ return fs39.readdirSync(commandsRoot).filter((entry) => entry.endsWith(".md")).sort().map(
28037
+ (entry) => compileCommandAsSkill(path38.join(commandsRoot, entry), target)
27825
28038
  );
27826
28039
  }
27827
28040
 
@@ -28104,9 +28317,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
28104
28317
  }
28105
28318
 
28106
28319
  // src/compiler/rules.ts
28107
- import path38 from "path";
28320
+ import path39 from "path";
28108
28321
  var import_yaml10 = __toESM(require_dist(), 1);
28109
- import fs39 from "fs";
28322
+ import fs40 from "fs";
28110
28323
  function compileRules(sourceRulesDir, target, _mappings, lossReport) {
28111
28324
  if (target === "copilot") {
28112
28325
  addLoss(lossReport, "copilot", "rules", {
@@ -28143,13 +28356,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
28143
28356
  }
28144
28357
  const appendixParts = [];
28145
28358
  const dotRulesFiles = [];
28146
- for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28359
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28147
28360
  const parsed = parseRule(ruleFile);
28148
- const name = path38.basename(ruleFile, ".md");
28361
+ const name = path39.basename(ruleFile, ".md");
28149
28362
  if (parsed.mode === "exec-policy") {
28150
28363
  dotRulesFiles.push({
28151
28364
  name: `${name}.rules`,
28152
- content: `${formatProvenanceMarker("toml", `rules/${path38.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
28365
+ content: `${formatProvenanceMarker("toml", `rules/${path39.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
28153
28366
  ${parsed.body}`
28154
28367
  });
28155
28368
  continue;
@@ -28158,7 +28371,7 @@ ${parsed.body}`
28158
28371
 
28159
28372
  ${parsed.body.trim()}`);
28160
28373
  addLoss(lossReport, "codex", "rules", {
28161
- source: `rules/${path38.basename(ruleFile)}`,
28374
+ source: `rules/${path39.basename(ruleFile)}`,
28162
28375
  fields: [
28163
28376
  {
28164
28377
  field: "mode",
@@ -28168,7 +28381,7 @@ ${parsed.body.trim()}`);
28168
28381
  "mode",
28169
28382
  "rule-as-instruction"
28170
28383
  ),
28171
- detail: `${path38.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
28384
+ detail: `${path39.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
28172
28385
  }
28173
28386
  ]
28174
28387
  });
@@ -28176,7 +28389,7 @@ ${parsed.body.trim()}`);
28176
28389
  return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
28177
28390
  }
28178
28391
  function parseRule(ruleFile) {
28179
- const content = fs39.readFileSync(ruleFile, "utf8");
28392
+ const content = fs40.readFileSync(ruleFile, "utf8");
28180
28393
  if (!content.startsWith("---\n")) {
28181
28394
  return { mode: "guidance", body: content };
28182
28395
  }
@@ -28200,14 +28413,14 @@ function isRuleMode(value) {
28200
28413
  }
28201
28414
  function compileOpenCodeRules(sourceRulesDir, lossReport) {
28202
28415
  const appendixParts = [];
28203
- for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28416
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28204
28417
  const parsed = parseRule(ruleFile);
28205
- const name = path38.basename(ruleFile, ".md");
28418
+ const name = path39.basename(ruleFile, ".md");
28206
28419
  appendixParts.push(`## ${name}
28207
28420
 
28208
28421
  ${parsed.body.trim()}`);
28209
28422
  addLoss(lossReport, "opencode", "rules", {
28210
- source: `rules/${path38.basename(ruleFile)}`,
28423
+ source: `rules/${path39.basename(ruleFile)}`,
28211
28424
  fields: [
28212
28425
  {
28213
28426
  field: "rule",
@@ -28217,7 +28430,7 @@ ${parsed.body.trim()}`);
28217
28430
  "rule",
28218
28431
  "rule-path-scoping"
28219
28432
  ),
28220
- detail: `${path38.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
28433
+ detail: `${path39.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
28221
28434
  }
28222
28435
  ]
28223
28436
  });
@@ -28226,9 +28439,9 @@ ${parsed.body.trim()}`);
28226
28439
  }
28227
28440
  function compileCursorRules(sourceRulesDir, _lossReport) {
28228
28441
  const dotRulesFiles = [];
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");
28442
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28443
+ const content = fs40.readFileSync(ruleFile, "utf8");
28444
+ const name = path39.basename(ruleFile, ".md");
28232
28445
  let frontmatterData = {};
28233
28446
  let body = content;
28234
28447
  if (content.startsWith("---\n")) {
@@ -28257,7 +28470,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
28257
28470
  }
28258
28471
  const marker = formatProvenanceMarker(
28259
28472
  "markdown",
28260
- `rules/${path38.basename(ruleFile)}`,
28473
+ `rules/${path39.basename(ruleFile)}`,
28261
28474
  computeSourceHash(ruleFile),
28262
28475
  "cursor"
28263
28476
  );
@@ -28273,9 +28486,9 @@ ${body}`;
28273
28486
  }
28274
28487
  function compileClineRules(sourceRulesDir, lossReport) {
28275
28488
  const dotRulesFiles = [];
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");
28489
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28490
+ const content = fs40.readFileSync(ruleFile, "utf8");
28491
+ const name = path39.basename(ruleFile, ".md");
28279
28492
  let frontmatterData = {};
28280
28493
  let body = content;
28281
28494
  if (content.startsWith("---\n")) {
@@ -28292,13 +28505,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
28292
28505
  }
28293
28506
  const marker = formatProvenanceMarker(
28294
28507
  "markdown",
28295
- `rules/${path38.basename(ruleFile)}`,
28508
+ `rules/${path39.basename(ruleFile)}`,
28296
28509
  computeSourceHash(ruleFile),
28297
28510
  "cline"
28298
28511
  );
28299
28512
  if (frontmatterData.mode === "exec-policy") {
28300
28513
  addLoss(lossReport, "cline", "rules", {
28301
- source: `rules/${path38.basename(ruleFile)}`,
28514
+ source: `rules/${path39.basename(ruleFile)}`,
28302
28515
  fields: [
28303
28516
  {
28304
28517
  field: "mode",
@@ -28308,7 +28521,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
28308
28521
  "mode",
28309
28522
  "rule-mode-downgrade"
28310
28523
  ),
28311
- detail: `${path38.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28524
+ detail: `${path39.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28312
28525
  }
28313
28526
  ]
28314
28527
  });
@@ -28327,6 +28540,36 @@ ${frontmatterYaml}${body}`;
28327
28540
  }
28328
28541
  return { agentsAppendix: "", dotRulesFiles };
28329
28542
  }
28543
+ function compileCopilotRules(sourceRulesDir) {
28544
+ if (!fs40.existsSync(sourceRulesDir)) {
28545
+ return [];
28546
+ }
28547
+ const files = [];
28548
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28549
+ const name = path39.basename(ruleFile, ".md");
28550
+ const { data } = parseMarkdownFrontmatter(ruleFile);
28551
+ const { body } = parseRule(ruleFile);
28552
+ const declared = data.paths;
28553
+ const applyTo = Array.isArray(declared) ? declared.filter((p) => typeof p === "string").join(", ") : typeof declared === "string" && declared.trim() !== "" ? declared.trim() : "**";
28554
+ const frontmatter = [
28555
+ "---",
28556
+ `applyTo: ${JSON.stringify(applyTo)}`,
28557
+ "x-tangyr:",
28558
+ ` source: rules/${path39.basename(ruleFile)}`,
28559
+ ` hash: ${computeSourceHash(ruleFile)}`,
28560
+ " target: copilot",
28561
+ "---"
28562
+ ].join("\n");
28563
+ files.push({
28564
+ name: `${name}.instructions.md`,
28565
+ content: `${frontmatter}
28566
+
28567
+ ${body.trim()}
28568
+ `
28569
+ });
28570
+ }
28571
+ return files;
28572
+ }
28330
28573
 
28331
28574
  // src/adapters/codex.ts
28332
28575
  var skippedComponents = ["settings", "lsp", "output-styles"];
@@ -28349,7 +28592,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28349
28592
  rules: profile.rules
28350
28593
  };
28351
28594
  const rules = compileRules(
28352
- path39.join(sourceRoot, config.source.rules),
28595
+ path40.join(sourceRoot, config.source.rules),
28353
28596
  "codex",
28354
28597
  mappings,
28355
28598
  lossReport
@@ -28429,7 +28672,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28429
28672
  if (!shouldSkipComponent2(options, "hooks")) {
28430
28673
  outcomes.push(
28431
28674
  syncHookScriptsBridge({
28432
- source: path39.resolve(sourceRoot, config.source.hooks),
28675
+ source: path40.resolve(sourceRoot, config.source.hooks),
28433
28676
  destination: resolveTargetPath(paths.hook_scripts),
28434
28677
  config,
28435
28678
  sourceRoot,
@@ -28528,9 +28771,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28528
28771
  function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
28529
28772
  const cp = mappings.modelTiers.custom_provider;
28530
28773
  if (!cp) return "";
28531
- const agentsDir = path39.join(sourceRoot, config.source.agents);
28532
- if (!fs40.existsSync(agentsDir)) return "";
28533
- const agentFiles = ts(path39.join(agentsDir, "*.md")).sort();
28774
+ const agentsDir = path40.join(sourceRoot, config.source.agents);
28775
+ if (!fs41.existsSync(agentsDir)) return "";
28776
+ const agentFiles = ts(path40.join(agentsDir, "*.md")).sort();
28534
28777
  const hasProviderAgent = agentFiles.some((agentFile) => {
28535
28778
  const { data } = parseMarkdownFrontmatter(agentFile);
28536
28779
  return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
@@ -28595,7 +28838,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
28595
28838
  }
28596
28839
  ];
28597
28840
  for (const ruleFile of rules.dotRulesFiles) {
28598
- const destination = path39.join(rulesRoot, ruleFile.name);
28841
+ const destination = path40.join(rulesRoot, ruleFile.name);
28599
28842
  if (options.dryRun) {
28600
28843
  logger.info(`[dry-run] rules: write ${destination}`);
28601
28844
  outcomes.push({
@@ -28625,16 +28868,16 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
28625
28868
  function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
28626
28869
  const source = instructionsSourcePath(sourceRoot, config);
28627
28870
  const destination = resolveTargetPath(paths.instructions);
28628
- if (!fs40.existsSync(source)) {
28871
+ if (!fs41.existsSync(source)) {
28629
28872
  return skippedMissingSource2("instructions", source);
28630
28873
  }
28631
- const composed = `${fs40.readFileSync(source, "utf8").trim()}
28874
+ const composed = `${fs41.readFileSync(source, "utf8").trim()}
28632
28875
 
28633
28876
  --- tangyr managed rules ---
28634
28877
  ${agentsAppendix}`.trim();
28635
28878
  const marker = formatProvenanceMarker(
28636
28879
  "markdown",
28637
- path39.basename(instructionsSourceLabel(sourceRoot, config)),
28880
+ path40.basename(instructionsSourceLabel(sourceRoot, config)),
28638
28881
  hashString(composed),
28639
28882
  "codex"
28640
28883
  );
@@ -28664,7 +28907,7 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
28664
28907
  return syncSkillsSlot({
28665
28908
  config,
28666
28909
  sourceRoot,
28667
- source: path39.resolve(sourceRoot, config.source.skills),
28910
+ source: path40.resolve(sourceRoot, config.source.skills),
28668
28911
  destination: resolveTargetPath(paths.skills),
28669
28912
  dryRun: options.dryRun,
28670
28913
  logger,
@@ -28679,13 +28922,13 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
28679
28922
  });
28680
28923
  }
28681
28924
  function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, logger, manifest, scopePath) {
28682
- const commandsRoot = path39.resolve(sourceRoot, config.source.commands);
28683
- if (!fs40.existsSync(commandsRoot)) {
28925
+ const commandsRoot = path40.resolve(sourceRoot, config.source.commands);
28926
+ if (!fs41.existsSync(commandsRoot)) {
28684
28927
  return [skippedMissingSource2("commands", commandsRoot)];
28685
28928
  }
28686
28929
  const skillsRoot = resolveTargetPath(paths.skills);
28687
28930
  return compileCommandsAsSkills(commandsRoot, "codex").map((skill) => {
28688
- const destination = path39.join(skillsRoot, skill.name, "SKILL.md");
28931
+ const destination = path40.join(skillsRoot, skill.name, "SKILL.md");
28689
28932
  if (options.dryRun) {
28690
28933
  logger.info(
28691
28934
  `[dry-run] commands: compile ${skill.relativeSource} -> ${destination}`
@@ -28711,16 +28954,16 @@ function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, l
28711
28954
  });
28712
28955
  }
28713
28956
  function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
28714
- const sourceAgentsRoot = path39.join(sourceRoot, config.source.agents);
28715
- if (!fs40.existsSync(sourceAgentsRoot)) {
28957
+ const sourceAgentsRoot = path40.join(sourceRoot, config.source.agents);
28958
+ if (!fs41.existsSync(sourceAgentsRoot)) {
28716
28959
  return [skippedMissingSource2("agents", sourceAgentsRoot)];
28717
28960
  }
28718
- const sourceAgents = ts(path39.join(sourceAgentsRoot, "*.md")).sort();
28961
+ const sourceAgents = ts(path40.join(sourceAgentsRoot, "*.md")).sort();
28719
28962
  const agentsRoot = resolveTargetPath(paths.agents);
28720
28963
  return sourceAgents.map((agentFile) => {
28721
- const destination = path39.join(
28964
+ const destination = path40.join(
28722
28965
  agentsRoot,
28723
- `${path39.basename(agentFile, ".md")}.toml`
28966
+ `${path40.basename(agentFile, ".md")}.toml`
28724
28967
  );
28725
28968
  const compiled = compileAgent(
28726
28969
  agentFile,
@@ -28798,7 +29041,7 @@ function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, lo
28798
29041
  destination,
28799
29042
  hostHooks,
28800
29043
  stringifyJson3,
28801
- !fs40.existsSync(destination),
29044
+ !fs41.existsSync(destination),
28802
29045
  logger
28803
29046
  );
28804
29047
  return {
@@ -28811,7 +29054,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
28811
29054
  const source = resolveMcpSourceFile(sourceRoot, config);
28812
29055
  const sourceLabel = mcpSourceLabel(config);
28813
29056
  const destination = resolveTargetPath(paths.mcp_shared_file);
28814
- if (!fs40.existsSync(source)) {
29057
+ if (!fs41.existsSync(source)) {
28815
29058
  if (providerToml && !options.dryRun) {
28816
29059
  const changed2 = writeTomlManagedSection(
28817
29060
  destination,
@@ -28826,7 +29069,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
28826
29069
  }
28827
29070
  return skippedMissingSource2("mcp", source);
28828
29071
  }
28829
- const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
29072
+ const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
28830
29073
  const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
28831
29074
  const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
28832
29075
  if (options.dryRun) {
@@ -28851,18 +29094,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
28851
29094
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
28852
29095
  return { component, status: "conflict", path: destination };
28853
29096
  }
28854
- ensureDir(path39.dirname(destination));
29097
+ ensureDir(path40.dirname(destination));
28855
29098
  const clearedLink = clearSymlinkAtDestination(destination);
28856
29099
  if (clearedLink !== null) {
28857
29100
  logger.verbose(
28858
29101
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
28859
29102
  );
28860
29103
  }
28861
- fs40.writeFileSync(destination, content);
29104
+ fs41.writeFileSync(destination, content);
28862
29105
  return { component, status: "success", path: destination };
28863
29106
  }
28864
29107
  function writeTomlManagedSection(destination, managedContent, logger) {
28865
- const current = fs40.existsSync(destination) ? fs40.readFileSync(destination, "utf8") : "";
29108
+ const current = fs41.existsSync(destination) ? fs41.readFileSync(destination, "utf8") : "";
28866
29109
  const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
28867
29110
  if (isFirstWrite) {
28868
29111
  logger.warn(
@@ -28878,8 +29121,8 @@ ${managedMcpEnd}
28878
29121
  if (current === next.trimStart()) {
28879
29122
  return false;
28880
29123
  }
28881
- ensureDir(path39.dirname(destination));
28882
- fs40.writeFileSync(destination, next.trimStart());
29124
+ ensureDir(path40.dirname(destination));
29125
+ fs41.writeFileSync(destination, next.trimStart());
28883
29126
  return true;
28884
29127
  }
28885
29128
  function removeManagedTomlSection(content) {
@@ -28905,7 +29148,7 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
28905
29148
  if (manifest && scopePath) {
28906
29149
  backupFile(destination, manifest, scopePath);
28907
29150
  writeManifest(scopePath, manifest);
28908
- fs40.rmSync(destination, { recursive: true, force: true });
29151
+ fs41.rmSync(destination, { recursive: true, force: true });
28909
29152
  } else {
28910
29153
  const parked = parkConflictingPath(
28911
29154
  destination,
@@ -28920,12 +29163,12 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
28920
29163
  }
28921
29164
  return true;
28922
29165
  }
28923
- fs40.rmSync(destination, { recursive: true, force: true });
29166
+ fs41.rmSync(destination, { recursive: true, force: true });
28924
29167
  return true;
28925
29168
  }
28926
29169
  function isCompiledCurrent(destination, expectedContent, _expectedHash) {
28927
29170
  try {
28928
- return fs40.readFileSync(destination, "utf8") === expectedContent;
29171
+ return fs41.readFileSync(destination, "utf8") === expectedContent;
28929
29172
  } catch {
28930
29173
  return false;
28931
29174
  }
@@ -28941,10 +29184,10 @@ function shouldSkipComponent2(options, component) {
28941
29184
  return Boolean(options.component && options.component !== component);
28942
29185
  }
28943
29186
  function readJsonObject4(filePath) {
28944
- if (!fs40.existsSync(filePath)) {
29187
+ if (!fs41.existsSync(filePath)) {
28945
29188
  return {};
28946
29189
  }
28947
- const parsed = JSON.parse(fs40.readFileSync(filePath, "utf8"));
29190
+ const parsed = JSON.parse(fs41.readFileSync(filePath, "utf8"));
28948
29191
  return isRecord5(parsed) ? parsed : {};
28949
29192
  }
28950
29193
  function stringifyJson3(value) {
@@ -28960,16 +29203,16 @@ function hashString(value) {
28960
29203
 
28961
29204
  // src/adapters/copilot.ts
28962
29205
  import crypto7 from "crypto";
28963
- import fs41 from "fs";
28964
- import path41 from "path";
29206
+ import fs42 from "fs";
29207
+ import path42 from "path";
28965
29208
 
28966
29209
  // src/compiler/commands.ts
28967
29210
  var import_yaml11 = __toESM(require_dist(), 1);
28968
- import path40 from "path";
29211
+ import path41 from "path";
28969
29212
  function compileCommandPrompt(sourceFile) {
28970
29213
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
28971
- const relativeSource = `commands/${path40.basename(sourceFile)}`;
28972
- const fields = promptFrontmatter(data, path40.basename(sourceFile, ".md"));
29214
+ const relativeSource = `commands/${path41.basename(sourceFile)}`;
29215
+ const fields = promptFrontmatter(data, path41.basename(sourceFile, ".md"));
28973
29216
  const marker = formatProvenanceMarker(
28974
29217
  "markdown",
28975
29218
  relativeSource,
@@ -29002,12 +29245,7 @@ function promptFrontmatter(data, defaultName) {
29002
29245
  }
29003
29246
 
29004
29247
  // src/adapters/copilot.ts
29005
- var skippedComponents2 = [
29006
- "rules",
29007
- "settings",
29008
- "lsp",
29009
- "output-styles"
29010
- ];
29248
+ var skippedComponents2 = ["settings", "lsp", "output-styles"];
29011
29249
  var legacyCopilotAgentsPath = "~/.copilot/agents";
29012
29250
  function syncCopilot(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29013
29251
  const scope = options.scope ?? "global";
@@ -29018,6 +29256,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29018
29256
  }).copilot;
29019
29257
  const paths = {
29020
29258
  agents: profile.agents,
29259
+ rules: profile.rules,
29021
29260
  skills: profile.skills,
29022
29261
  prompts: profile.prompts,
29023
29262
  hooks: profile.hooks,
@@ -29051,6 +29290,36 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29051
29290
  )
29052
29291
  );
29053
29292
  }
29293
+ if (!shouldSkipComponent3(options, "rules") && !paths.rules) {
29294
+ addLoss(lossReport, "copilot", "rules", {
29295
+ source: "rules",
29296
+ fields: [
29297
+ {
29298
+ field: "rules",
29299
+ action: "rule-path-scoping",
29300
+ severity: resolveLossSeverity(
29301
+ "agent-field",
29302
+ "rules",
29303
+ "rule-path-scoping"
29304
+ ),
29305
+ detail: "Rules: no user-level rules surface for Copilot; `.github/instructions` is a repository path and has no global equivalent"
29306
+ }
29307
+ ]
29308
+ });
29309
+ }
29310
+ if (!shouldSkipComponent3(options, "rules") && paths.rules) {
29311
+ outcomes.push(
29312
+ ...syncRules2(
29313
+ config,
29314
+ sourceRoot,
29315
+ paths.rules,
29316
+ options,
29317
+ logger,
29318
+ manifest,
29319
+ scopePath
29320
+ )
29321
+ );
29322
+ }
29054
29323
  if (!shouldSkipComponent3(options, "agents")) {
29055
29324
  outcomes.push(...cleanupLegacyAgents(paths, options, logger));
29056
29325
  outcomes.push(
@@ -29084,7 +29353,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29084
29353
  if (!shouldSkipComponent3(options, "hooks")) {
29085
29354
  outcomes.push(
29086
29355
  syncHookScriptsBridge({
29087
- source: path41.resolve(sourceRoot, config.source.hooks),
29356
+ source: path42.resolve(sourceRoot, config.source.hooks),
29088
29357
  destination: resolveTargetPath(paths.hook_scripts),
29089
29358
  config,
29090
29359
  sourceRoot,
@@ -29165,13 +29434,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29165
29434
  }
29166
29435
  function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
29167
29436
  if (!mappings.modelTiers.custom_provider) return;
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()) {
29437
+ const agentsDir = path42.join(sourceRoot, config.source.agents);
29438
+ if (!fs42.existsSync(agentsDir)) return;
29439
+ for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
29171
29440
  const { data } = parseMarkdownFrontmatter(agentFile);
29172
29441
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
29173
29442
  if (hasProvider) {
29174
- const basename = path41.basename(agentFile);
29443
+ const basename = path42.basename(agentFile);
29175
29444
  addLoss(lossReport, "copilot", "agents", {
29176
29445
  source: `agents/${basename}`,
29177
29446
  fields: [
@@ -29197,22 +29466,22 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
29197
29466
  return [{ component: "instructions", status: "skipped", path: message }];
29198
29467
  }
29199
29468
  const source = instructionsSourcePath(sourceRoot, config);
29200
- if (!fs41.existsSync(source)) {
29469
+ if (!fs42.existsSync(source)) {
29201
29470
  return [skippedMissingSource3("instructions", source)];
29202
29471
  }
29203
- const rawContent = fs41.readFileSync(source, "utf8");
29472
+ const rawContent = fs42.readFileSync(source, "utf8");
29204
29473
  const contentHash = hashString2(rawContent);
29205
29474
  const marker = formatProvenanceMarker(
29206
29475
  "markdown",
29207
- path41.basename(instructionsSourceLabel(sourceRoot, config)),
29476
+ path42.basename(instructionsSourceLabel(sourceRoot, config)),
29208
29477
  contentHash,
29209
29478
  "copilot"
29210
29479
  );
29211
29480
  const composedContent = `${marker}
29212
29481
  ${rawContent}`;
29213
29482
  const projectRoot = options.projectRoot ?? process.cwd();
29214
- const agentsMdDest = path41.resolve(projectRoot, "AGENTS.md");
29215
- const mirrorDest = path41.resolve(
29483
+ const agentsMdDest = path42.resolve(projectRoot, "AGENTS.md");
29484
+ const mirrorDest = path42.resolve(
29216
29485
  projectRoot,
29217
29486
  ".github",
29218
29487
  "copilot-instructions.md"
@@ -29266,14 +29535,14 @@ function writeInstructionsFile(component, destination, content, contentHash, con
29266
29535
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
29267
29536
  return { component, status: "conflict", path: destination };
29268
29537
  }
29269
- ensureDir(path41.dirname(destination));
29538
+ ensureDir(path42.dirname(destination));
29270
29539
  const clearedLink = clearSymlinkAtDestination(destination);
29271
29540
  if (clearedLink !== null) {
29272
29541
  logger.verbose(
29273
29542
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
29274
29543
  );
29275
29544
  }
29276
- fs41.writeFileSync(destination, content);
29545
+ fs42.writeFileSync(destination, content);
29277
29546
  return { component, status: "success", path: destination };
29278
29547
  }
29279
29548
  function hashString2(value) {
@@ -29283,7 +29552,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29283
29552
  return syncSkillsSlot({
29284
29553
  config,
29285
29554
  sourceRoot,
29286
- source: path41.resolve(sourceRoot, config.source.skills),
29555
+ source: path42.resolve(sourceRoot, config.source.skills),
29287
29556
  destination: resolveTargetPath(paths.skills),
29288
29557
  dryRun: options.dryRun,
29289
29558
  logger,
@@ -29298,16 +29567,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29298
29567
  });
29299
29568
  }
29300
29569
  function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29301
- const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
29302
- if (!fs41.existsSync(sourceAgentsRoot)) {
29570
+ const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
29571
+ if (!fs42.existsSync(sourceAgentsRoot)) {
29303
29572
  return [skippedMissingSource3("agents", sourceAgentsRoot)];
29304
29573
  }
29305
- const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
29574
+ const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
29306
29575
  const agentsRoot = resolveTargetPath(paths.agents);
29307
29576
  return sourceAgents.map((agentFile) => {
29308
- const destination = path41.join(
29577
+ const destination = path42.join(
29309
29578
  agentsRoot,
29310
- `${path41.basename(agentFile, ".md")}.agent.md`
29579
+ `${path42.basename(agentFile, ".md")}.agent.md`
29311
29580
  );
29312
29581
  const compiled = compileAgent(
29313
29582
  agentFile,
@@ -29335,16 +29604,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
29335
29604
  });
29336
29605
  }
29337
29606
  function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
29338
- const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
29339
- if (!fs41.existsSync(sourceCommandsRoot)) {
29607
+ const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
29608
+ if (!fs42.existsSync(sourceCommandsRoot)) {
29340
29609
  return [skippedMissingSource3("commands", sourceCommandsRoot)];
29341
29610
  }
29342
- const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
29611
+ const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
29343
29612
  const promptsRoot = resolveTargetPath(paths.prompts);
29344
29613
  return sourceCommands.map((commandFile) => {
29345
- const destination = path41.join(
29614
+ const destination = path42.join(
29346
29615
  promptsRoot,
29347
- `${path41.basename(commandFile, ".md")}.prompt.md`
29616
+ `${path42.basename(commandFile, ".md")}.prompt.md`
29348
29617
  );
29349
29618
  const compiled = compileCommandPrompt(commandFile);
29350
29619
  if (options.dryRun) {
@@ -29368,7 +29637,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
29368
29637
  });
29369
29638
  }
29370
29639
  function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
29371
- const destination = path41.join(
29640
+ const destination = path42.join(
29372
29641
  resolveTargetPath(paths.hooks),
29373
29642
  "tangyr-managed.json"
29374
29643
  );
@@ -29431,10 +29700,10 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
29431
29700
  const source = resolveMcpSourceFile(sourceRoot, config);
29432
29701
  const sourceLabel = mcpSourceLabel(config);
29433
29702
  const destination = resolveTargetPath(paths.mcp_shared_file);
29434
- if (!fs41.existsSync(source)) {
29703
+ if (!fs42.existsSync(source)) {
29435
29704
  return skippedMissingSource3("mcp", source);
29436
29705
  }
29437
- const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
29706
+ const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
29438
29707
  const compiled = compileMcp(
29439
29708
  sourceMcpJson,
29440
29709
  "copilot",
@@ -29456,6 +29725,36 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
29456
29725
  logger
29457
29726
  );
29458
29727
  }
29728
+ function syncRules2(config, sourceRoot, rulesSlot, options, logger, manifest, scopePath) {
29729
+ const sourceRulesDir = path42.resolve(sourceRoot, config.source.rules);
29730
+ if (!fs42.existsSync(sourceRulesDir)) {
29731
+ return [skippedMissingSource3("rules", sourceRulesDir)];
29732
+ }
29733
+ const destinationRoot = resolveTargetPath(rulesSlot);
29734
+ return compileCopilotRules(sourceRulesDir).map((file) => {
29735
+ const destination = path42.join(destinationRoot, file.name);
29736
+ if (options.dryRun) {
29737
+ logger.info(`[dry-run] rules: compile -> ${destination}`);
29738
+ return {
29739
+ component: "rules",
29740
+ status: "dry-run",
29741
+ path: destination
29742
+ };
29743
+ }
29744
+ return writeCompiledArtifact2(
29745
+ "rules",
29746
+ destination,
29747
+ file.content,
29748
+ void 0,
29749
+ config,
29750
+ sourceRoot,
29751
+ options,
29752
+ logger,
29753
+ manifest,
29754
+ scopePath
29755
+ );
29756
+ });
29757
+ }
29459
29758
  function writeCompiledArtifact2(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
29460
29759
  if (!options.force && isCompiledCurrent2(destination, content, expectedHash)) {
29461
29760
  return { component, status: "skipped-current", path: destination };
@@ -29467,19 +29766,19 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
29467
29766
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
29468
29767
  return { component, status: "conflict", path: destination };
29469
29768
  }
29470
- ensureDir(path41.dirname(destination));
29769
+ ensureDir(path42.dirname(destination));
29471
29770
  const clearedLink = clearSymlinkAtDestination(destination);
29472
29771
  if (clearedLink !== null) {
29473
29772
  logger.verbose(
29474
29773
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
29475
29774
  );
29476
29775
  }
29477
- fs41.writeFileSync(destination, content);
29776
+ fs42.writeFileSync(destination, content);
29478
29777
  return { component, status: "success", path: destination };
29479
29778
  }
29480
29779
  function isCompiledCurrent2(destination, expectedContent, _expectedHash) {
29481
29780
  try {
29482
- return fs41.readFileSync(destination, "utf8") === expectedContent;
29781
+ return fs42.readFileSync(destination, "utf8") === expectedContent;
29483
29782
  } catch {
29484
29783
  return false;
29485
29784
  }
@@ -29499,7 +29798,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
29499
29798
  if (manifest && scopePath) {
29500
29799
  backupFile(destination, manifest, scopePath);
29501
29800
  writeManifest(scopePath, manifest);
29502
- fs41.rmSync(destination, { recursive: true, force: true });
29801
+ fs42.rmSync(destination, { recursive: true, force: true });
29503
29802
  } else {
29504
29803
  const parked = parkConflictingPath(
29505
29804
  destination,
@@ -29514,7 +29813,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
29514
29813
  }
29515
29814
  return true;
29516
29815
  }
29517
- fs41.rmSync(destination, { recursive: true, force: true });
29816
+ fs42.rmSync(destination, { recursive: true, force: true });
29518
29817
  return true;
29519
29818
  }
29520
29819
  function shouldSkipComponent3(options, component) {
@@ -29523,12 +29822,12 @@ function shouldSkipComponent3(options, component) {
29523
29822
  function cleanupLegacyAgents(paths, options, logger) {
29524
29823
  const currentAgentsRoot = resolveTargetPath(paths.agents);
29525
29824
  const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
29526
- if (path41.resolve(currentAgentsRoot) === path41.resolve(legacyAgentsRoot)) {
29825
+ if (path42.resolve(currentAgentsRoot) === path42.resolve(legacyAgentsRoot)) {
29527
29826
  return [];
29528
29827
  }
29529
29828
  const outcomes = [];
29530
29829
  for (const filePath of ts(
29531
- path41.join(legacyAgentsRoot, "*.agent.md")
29830
+ path42.join(legacyAgentsRoot, "*.agent.md")
29532
29831
  ).sort()) {
29533
29832
  if (!isCopilotManagedCompiledFile(filePath)) {
29534
29833
  continue;
@@ -29538,14 +29837,14 @@ function cleanupLegacyAgents(paths, options, logger) {
29538
29837
  outcomes.push({ component: "agents", status: "dry-run", path: filePath });
29539
29838
  continue;
29540
29839
  }
29541
- fs41.rmSync(filePath, { force: true });
29840
+ fs42.rmSync(filePath, { force: true });
29542
29841
  outcomes.push({ component: "agents", status: "success", path: filePath });
29543
29842
  }
29544
29843
  return outcomes;
29545
29844
  }
29546
29845
  function isCopilotManagedCompiledFile(filePath) {
29547
29846
  try {
29548
- return extractProvenanceMarker(fs41.readFileSync(filePath, "utf8"))?.target === "copilot";
29847
+ return extractProvenanceMarker(fs42.readFileSync(filePath, "utf8"))?.target === "copilot";
29549
29848
  } catch {
29550
29849
  return false;
29551
29850
  }
@@ -29560,8 +29859,8 @@ function skippedMissingSource3(component, source) {
29560
29859
 
29561
29860
  // src/adapters/cursor.ts
29562
29861
  import crypto8 from "crypto";
29563
- import fs42 from "fs";
29564
- import path42 from "path";
29862
+ import fs43 from "fs";
29863
+ import path43 from "path";
29565
29864
  function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29566
29865
  const scope = options.scope ?? "global";
29567
29866
  const profile = resolveTargetPaths({
@@ -29614,7 +29913,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
29614
29913
  }
29615
29914
  if (!shouldSkipComponent4(options, "rules")) {
29616
29915
  outcomes.push(
29617
- ...syncRules2(
29916
+ ...syncRules3(
29618
29917
  config,
29619
29918
  sourceRoot,
29620
29919
  paths,
@@ -29673,7 +29972,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
29673
29972
  if (!shouldSkipComponent4(options, "hooks")) {
29674
29973
  outcomes.push(
29675
29974
  syncHookScriptsBridge({
29676
- source: path42.resolve(sourceRoot, config.source.hooks),
29975
+ source: path43.resolve(sourceRoot, config.source.hooks),
29677
29976
  destination: resolveTargetPath(paths.hook_scripts),
29678
29977
  config,
29679
29978
  sourceRoot,
@@ -29738,7 +30037,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
29738
30037
  const composed = composeCursorInstructions(config, sourceRoot, lossReport);
29739
30038
  const marker = formatProvenanceMarker(
29740
30039
  "markdown",
29741
- path42.basename(instructionsSourceLabel(sourceRoot, config)),
30040
+ path43.basename(instructionsSourceLabel(sourceRoot, config)),
29742
30041
  hashString3(composed),
29743
30042
  "cursor"
29744
30043
  );
@@ -29764,7 +30063,7 @@ ${composed}
29764
30063
  }
29765
30064
  function composeCursorInstructions(config, sourceRoot, lossReport) {
29766
30065
  const source = instructionsSourcePath(sourceRoot, config);
29767
- const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
30066
+ const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
29768
30067
  const personaContent = extractPrimaryPersonaContent(
29769
30068
  config,
29770
30069
  sourceRoot,
@@ -29777,11 +30076,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
29777
30076
  ${personaContent}`.trim() : baseContent;
29778
30077
  }
29779
30078
  function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29780
- const agentsDir = path42.join(sourceRoot, config.source.agents);
29781
- if (!fs42.existsSync(agentsDir)) {
30079
+ const agentsDir = path43.join(sourceRoot, config.source.agents);
30080
+ if (!fs43.existsSync(agentsDir)) {
29782
30081
  return null;
29783
30082
  }
29784
- const agentFiles = ts(path42.join(agentsDir, "*.md")).sort();
30083
+ const agentFiles = ts(path43.join(agentsDir, "*.md")).sort();
29785
30084
  if (agentFiles.length === 0) {
29786
30085
  return null;
29787
30086
  }
@@ -29804,7 +30103,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29804
30103
  return null;
29805
30104
  }
29806
30105
  addLoss(lossReport, "cursor", "instructions", {
29807
- source: `agents/${path42.basename(primaryFile)}`,
30106
+ source: `agents/${path43.basename(primaryFile)}`,
29808
30107
  fields: [
29809
30108
  {
29810
30109
  field: "persona",
@@ -29814,23 +30113,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29814
30113
  "persona",
29815
30114
  "instructions-shim"
29816
30115
  ),
29817
- detail: `Primary persona from ${path42.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
30116
+ detail: `Primary persona from ${path43.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
29818
30117
  }
29819
30118
  ]
29820
30119
  });
29821
30120
  return body.trim();
29822
30121
  }
29823
30122
  function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29824
- const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
29825
- if (!fs42.existsSync(sourceAgentsRoot)) {
30123
+ const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
30124
+ if (!fs43.existsSync(sourceAgentsRoot)) {
29826
30125
  return [skippedMissingSource4("agents", sourceAgentsRoot)];
29827
30126
  }
29828
- const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
30127
+ const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
29829
30128
  const agentsRoot = resolveTargetPath(paths.agents);
29830
30129
  return sourceAgents.map((agentFile) => {
29831
- const destination = path42.join(
30130
+ const destination = path43.join(
29832
30131
  agentsRoot,
29833
- `${path42.basename(agentFile, ".md")}.md`
30132
+ `${path43.basename(agentFile, ".md")}.md`
29834
30133
  );
29835
30134
  let compiled;
29836
30135
  try {
@@ -29870,15 +30169,15 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
29870
30169
  );
29871
30170
  });
29872
30171
  }
29873
- function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
29874
- const sourceRulesDir = path42.join(sourceRoot, config.source.rules);
29875
- if (!fs42.existsSync(sourceRulesDir)) {
30172
+ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
30173
+ const sourceRulesDir = path43.join(sourceRoot, config.source.rules);
30174
+ if (!fs43.existsSync(sourceRulesDir)) {
29876
30175
  return [skippedMissingSource4("rules", sourceRulesDir)];
29877
30176
  }
29878
30177
  const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
29879
30178
  const rulesDir = resolveTargetPath(paths.rules);
29880
30179
  return compiled.dotRulesFiles.map(({ name, content }) => {
29881
- const destination = path42.join(rulesDir, name);
30180
+ const destination = path43.join(rulesDir, name);
29882
30181
  if (options.dryRun) {
29883
30182
  logger.info(`[dry-run] rules: write ${destination}`);
29884
30183
  return {
@@ -29902,15 +30201,15 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
29902
30201
  });
29903
30202
  }
29904
30203
  function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
29905
- const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
29906
- if (!fs42.existsSync(sourceCommandsRoot)) {
30204
+ const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
30205
+ if (!fs43.existsSync(sourceCommandsRoot)) {
29907
30206
  return [skippedMissingSource4("commands", sourceCommandsRoot)];
29908
30207
  }
29909
- const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
30208
+ const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
29910
30209
  const skillsRoot = resolveTargetPath(paths.skills);
29911
30210
  return sourceCommands.map((commandFile) => {
29912
- const baseName = path42.basename(commandFile, ".md");
29913
- const destination = path42.join(skillsRoot, baseName, "SKILL.md");
30211
+ const baseName = path43.basename(commandFile, ".md");
30212
+ const destination = path43.join(skillsRoot, baseName, "SKILL.md");
29914
30213
  const { content } = compileCommandAsSkill(commandFile, "cursor");
29915
30214
  if (options.dryRun) {
29916
30215
  logger.info(
@@ -29940,7 +30239,7 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, _
29940
30239
  return syncSkillsSlot({
29941
30240
  config,
29942
30241
  sourceRoot,
29943
- source: path42.resolve(sourceRoot, config.source.skills),
30242
+ source: path43.resolve(sourceRoot, config.source.skills),
29944
30243
  destination,
29945
30244
  dryRun: options.dryRun,
29946
30245
  logger,
@@ -29988,18 +30287,18 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
29988
30287
  }
29989
30288
  const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
29990
30289
  `;
29991
- ensureDir(path42.dirname(destination));
29992
- fs42.writeFileSync(destination, hooksFileContent);
30290
+ ensureDir(path43.dirname(destination));
30291
+ fs43.writeFileSync(destination, hooksFileContent);
29993
30292
  return { component: "hooks", status: "success", path: destination };
29994
30293
  }
29995
30294
  function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
29996
30295
  const source = resolveMcpSourceFile(sourceRoot, config);
29997
30296
  const sourceLabel = mcpSourceLabel(config);
29998
30297
  const destination = resolveTargetPath(paths.mcp_file);
29999
- if (!fs42.existsSync(source)) {
30298
+ if (!fs43.existsSync(source)) {
30000
30299
  return skippedMissingSource4("mcp", source);
30001
30300
  }
30002
- const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
30301
+ const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
30003
30302
  const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
30004
30303
  if (options.dryRun) {
30005
30304
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -30052,13 +30351,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
30052
30351
  );
30053
30352
  }
30054
30353
  function syncProviderPin(config, sourceRoot, lossReport) {
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()) {
30354
+ const agentsDir = path43.join(sourceRoot, config.source.agents);
30355
+ if (!fs43.existsSync(agentsDir)) return;
30356
+ for (const agentFile of ts(path43.join(agentsDir, "*.md")).sort()) {
30058
30357
  const { data } = parseMarkdownFrontmatter(agentFile);
30059
30358
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30060
30359
  if (hasCustomProvider) {
30061
- const relativeSource = `agents/${path42.basename(agentFile)}`;
30360
+ const relativeSource = `agents/${path43.basename(agentFile)}`;
30062
30361
  addLoss(lossReport, "cursor", "agents", {
30063
30362
  source: relativeSource,
30064
30363
  fields: [
@@ -30070,7 +30369,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
30070
30369
  "provider",
30071
30370
  "provider-not-representable"
30072
30371
  ),
30073
- detail: `${path42.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
30372
+ detail: `${path43.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
30074
30373
  }
30075
30374
  ]
30076
30375
  });
@@ -30088,14 +30387,14 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
30088
30387
  if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
30089
30388
  return { component, status: "conflict", path: destination };
30090
30389
  }
30091
- ensureDir(path42.dirname(destination));
30390
+ ensureDir(path43.dirname(destination));
30092
30391
  const clearedLink = clearSymlinkAtDestination(destination);
30093
30392
  if (clearedLink !== null) {
30094
30393
  logger.verbose(
30095
30394
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
30096
30395
  );
30097
30396
  }
30098
- fs42.writeFileSync(destination, content);
30397
+ fs43.writeFileSync(destination, content);
30099
30398
  return { component, status: "success", path: destination };
30100
30399
  }
30101
30400
  function handleConflict4(destination, config, options, logger, manifest, scopePath) {
@@ -30113,7 +30412,7 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
30113
30412
  if (manifest && scopePath) {
30114
30413
  backupFile(destination, manifest, scopePath);
30115
30414
  writeManifest(scopePath, manifest);
30116
- fs42.rmSync(destination, { recursive: true, force: true });
30415
+ fs43.rmSync(destination, { recursive: true, force: true });
30117
30416
  } else {
30118
30417
  const parked = parkConflictingPath(
30119
30418
  destination,
@@ -30128,12 +30427,12 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
30128
30427
  }
30129
30428
  return true;
30130
30429
  }
30131
- fs42.rmSync(destination, { recursive: true, force: true });
30430
+ fs43.rmSync(destination, { recursive: true, force: true });
30132
30431
  return true;
30133
30432
  }
30134
30433
  function isCompiledCurrent3(destination, expectedContent, _expectedHash) {
30135
30434
  try {
30136
- return fs42.readFileSync(destination, "utf8") === expectedContent;
30435
+ return fs43.readFileSync(destination, "utf8") === expectedContent;
30137
30436
  } catch {
30138
30437
  return false;
30139
30438
  }
@@ -30154,8 +30453,8 @@ function hashString3(value) {
30154
30453
 
30155
30454
  // src/adapters/cline.ts
30156
30455
  import crypto9 from "crypto";
30157
- import fs43 from "fs";
30158
- import path43 from "path";
30456
+ import fs44 from "fs";
30457
+ import path44 from "path";
30159
30458
  function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30160
30459
  const scope = options.scope ?? "global";
30161
30460
  const profile = resolveTargetPaths({
@@ -30202,7 +30501,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
30202
30501
  }
30203
30502
  if (!shouldSkipComponent5(options, "rules")) {
30204
30503
  outcomes.push(
30205
- ...syncRules3(
30504
+ ...syncRules4(
30206
30505
  config,
30207
30506
  sourceRoot,
30208
30507
  paths,
@@ -30268,7 +30567,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
30268
30567
  function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
30269
30568
  if (scope === "global" || paths.instructions === null) {
30270
30569
  addLoss(lossReport, "cline", "instructions", {
30271
- source: path43.basename(instructionsSourceLabel(sourceRoot, config)),
30570
+ source: path44.basename(instructionsSourceLabel(sourceRoot, config)),
30272
30571
  fields: [
30273
30572
  {
30274
30573
  field: "instructions",
@@ -30290,10 +30589,10 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
30290
30589
  }
30291
30590
  const source = instructionsSourcePath(sourceRoot, config);
30292
30591
  const destination = resolveTargetPath(paths.instructions);
30293
- const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
30592
+ const baseContent = fs44.existsSync(source) ? fs44.readFileSync(source, "utf8").trim() : "";
30294
30593
  const marker = formatProvenanceMarker(
30295
30594
  "markdown",
30296
- path43.basename(instructionsSourceLabel(sourceRoot, config)),
30595
+ path44.basename(instructionsSourceLabel(sourceRoot, config)),
30297
30596
  hashString4(baseContent),
30298
30597
  "cline"
30299
30598
  );
@@ -30318,11 +30617,11 @@ ${baseContent}
30318
30617
  );
30319
30618
  }
30320
30619
  function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
30321
- const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
30322
- if (!fs43.existsSync(sourceAgentsRoot)) {
30620
+ const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
30621
+ if (!fs44.existsSync(sourceAgentsRoot)) {
30323
30622
  return [skippedMissingSource5("agents", sourceAgentsRoot)];
30324
30623
  }
30325
- const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
30624
+ const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
30326
30625
  return sourceAgents.map((agentFile) => {
30327
30626
  compileAgent(agentFile, "cline", mappings, extensions, lossReport);
30328
30627
  if (options.dryRun) {
@@ -30337,15 +30636,15 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
30337
30636
  };
30338
30637
  });
30339
30638
  }
30340
- function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
30341
- const sourceRulesDir = path43.join(sourceRoot, config.source.rules);
30342
- if (!fs43.existsSync(sourceRulesDir)) {
30639
+ function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
30640
+ const sourceRulesDir = path44.join(sourceRoot, config.source.rules);
30641
+ if (!fs44.existsSync(sourceRulesDir)) {
30343
30642
  return [skippedMissingSource5("rules", sourceRulesDir)];
30344
30643
  }
30345
30644
  const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
30346
30645
  const rulesDir = resolveTargetPath(paths.rules);
30347
30646
  return compiled.dotRulesFiles.map(({ name, content }) => {
30348
- const destination = path43.join(rulesDir, name);
30647
+ const destination = path44.join(rulesDir, name);
30349
30648
  if (options.dryRun) {
30350
30649
  logger.info(`[dry-run] rules: write ${destination}`);
30351
30650
  return {
@@ -30369,17 +30668,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
30369
30668
  });
30370
30669
  }
30371
30670
  function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30372
- const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
30373
- if (!fs43.existsSync(sourceCommandsRoot)) {
30671
+ const sourceCommandsRoot = path44.join(sourceRoot, config.source.commands);
30672
+ if (!fs44.existsSync(sourceCommandsRoot)) {
30374
30673
  return [skippedMissingSource5("commands", sourceCommandsRoot)];
30375
30674
  }
30376
- const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
30675
+ const sourceCommands = ts(path44.join(sourceCommandsRoot, "*.md")).sort();
30377
30676
  const workflowsRoot = resolveTargetPath(paths.workflows);
30378
30677
  return sourceCommands.map((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)}`;
30678
+ const baseName = path44.basename(commandFile);
30679
+ const destination = path44.join(workflowsRoot, baseName);
30680
+ const commandContent = fs44.readFileSync(commandFile, "utf8");
30681
+ const relativeSource = `commands/${path44.basename(commandFile)}`;
30383
30682
  const marker = formatProvenanceMarker(
30384
30683
  "markdown",
30385
30684
  relativeSource,
@@ -30417,7 +30716,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
30417
30716
  return syncSkillsSlot({
30418
30717
  config,
30419
30718
  sourceRoot,
30420
- source: path43.resolve(sourceRoot, config.source.skills),
30719
+ source: path44.resolve(sourceRoot, config.source.skills),
30421
30720
  destination: resolveTargetPath(paths.skills),
30422
30721
  dryRun: options.dryRun,
30423
30722
  logger,
@@ -30450,10 +30749,10 @@ function syncMcp5(config, sourceRoot, paths, options, lossReport, logger, manife
30450
30749
  const source = resolveMcpSourceFile(sourceRoot, config);
30451
30750
  const sourceLabel = mcpSourceLabel(config);
30452
30751
  const destination = resolveTargetPath(paths.mcp_file);
30453
- if (!fs43.existsSync(source)) {
30752
+ if (!fs44.existsSync(source)) {
30454
30753
  return skippedMissingSource5("mcp", source);
30455
30754
  }
30456
- const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
30755
+ const sourceMcpJson = JSON.parse(fs44.readFileSync(source, "utf8"));
30457
30756
  const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
30458
30757
  if (options.dryRun) {
30459
30758
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -30496,11 +30795,11 @@ function syncSettings2(lossReport) {
30496
30795
  };
30497
30796
  }
30498
30797
  function syncProviderAndModel(config, sourceRoot, lossReport) {
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()) {
30798
+ const agentsDir = path44.join(sourceRoot, config.source.agents);
30799
+ if (!fs44.existsSync(agentsDir)) return;
30800
+ for (const agentFile of ts(path44.join(agentsDir, "*.md")).sort()) {
30502
30801
  const { data } = parseMarkdownFrontmatter(agentFile);
30503
- const relativeSource = `agents/${path43.basename(agentFile)}`;
30802
+ const relativeSource = `agents/${path44.basename(agentFile)}`;
30504
30803
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30505
30804
  if (hasCustomProvider) {
30506
30805
  addLoss(lossReport, "cline", "agents", {
@@ -30514,7 +30813,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
30514
30813
  "provider",
30515
30814
  "provider-not-representable"
30516
30815
  ),
30517
- detail: `${path43.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
30816
+ detail: `${path44.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
30518
30817
  }
30519
30818
  ]
30520
30819
  });
@@ -30532,7 +30831,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
30532
30831
  "model",
30533
30832
  "model-not-representable"
30534
30833
  ),
30535
- detail: `${path43.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
30834
+ detail: `${path44.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
30536
30835
  }
30537
30836
  ]
30538
30837
  });
@@ -30550,14 +30849,14 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
30550
30849
  if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
30551
30850
  return { component, status: "conflict", path: destination };
30552
30851
  }
30553
- ensureDir(path43.dirname(destination));
30852
+ ensureDir(path44.dirname(destination));
30554
30853
  const clearedLink = clearSymlinkAtDestination(destination);
30555
30854
  if (clearedLink !== null) {
30556
30855
  logger.verbose(
30557
30856
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
30558
30857
  );
30559
30858
  }
30560
- fs43.writeFileSync(destination, content);
30859
+ fs44.writeFileSync(destination, content);
30561
30860
  return { component, status: "success", path: destination };
30562
30861
  }
30563
30862
  function handleConflict5(destination, config, options, logger, manifest, scopePath) {
@@ -30575,7 +30874,7 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
30575
30874
  if (manifest && scopePath) {
30576
30875
  backupFile(destination, manifest, scopePath);
30577
30876
  writeManifest(scopePath, manifest);
30578
- fs43.rmSync(destination, { recursive: true, force: true });
30877
+ fs44.rmSync(destination, { recursive: true, force: true });
30579
30878
  } else {
30580
30879
  const parked = parkConflictingPath(
30581
30880
  destination,
@@ -30590,12 +30889,12 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
30590
30889
  }
30591
30890
  return true;
30592
30891
  }
30593
- fs43.rmSync(destination, { recursive: true, force: true });
30892
+ fs44.rmSync(destination, { recursive: true, force: true });
30594
30893
  return true;
30595
30894
  }
30596
30895
  function isCompiledCurrent4(destination, expectedContent, _expectedHash) {
30597
30896
  try {
30598
- return fs43.readFileSync(destination, "utf8") === expectedContent;
30897
+ return fs44.readFileSync(destination, "utf8") === expectedContent;
30599
30898
  } catch {
30600
30899
  return false;
30601
30900
  }
@@ -30616,9 +30915,9 @@ function hashString4(value) {
30616
30915
 
30617
30916
  // src/adapters/opencode.ts
30618
30917
  import crypto10 from "crypto";
30619
- import fs44 from "fs";
30918
+ import fs45 from "fs";
30620
30919
  import os6 from "os";
30621
- import path44 from "path";
30920
+ import path45 from "path";
30622
30921
  var import_yaml12 = __toESM(require_dist(), 1);
30623
30922
  function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30624
30923
  const scope = options.scope ?? "global";
@@ -30636,7 +30935,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30636
30935
  config_doc: profile.config_doc
30637
30936
  };
30638
30937
  const rules = compileRules(
30639
- path44.join(sourceRoot, config.source.rules),
30938
+ path45.join(sourceRoot, config.source.rules),
30640
30939
  "opencode",
30641
30940
  mappings,
30642
30941
  lossReport
@@ -30644,7 +30943,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30644
30943
  const outcomes = [];
30645
30944
  if (!shouldSkipComponent6(options, "instructions")) {
30646
30945
  outcomes.push(
30647
- syncInstructions4(
30946
+ ...syncInstructions4(
30648
30947
  config,
30649
30948
  sourceRoot,
30650
30949
  paths,
@@ -30740,14 +31039,14 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30740
31039
  function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
30741
31040
  const source = instructionsSourcePath(sourceRoot, config);
30742
31041
  const destination = resolveTargetPath(paths.instructions);
30743
- const baseContent = fs44.existsSync(source) ? fs44.readFileSync(source, "utf8").trim() : "";
31042
+ const baseContent = fs45.existsSync(source) ? fs45.readFileSync(source, "utf8").trim() : "";
30744
31043
  const composed = agentsAppendix ? `${baseContent}
30745
31044
 
30746
31045
  --- tangyr managed rules ---
30747
31046
  ${agentsAppendix}`.trim() : baseContent;
30748
31047
  const marker = formatProvenanceMarker(
30749
31048
  "markdown",
30750
- path44.basename(instructionsSourceLabel(sourceRoot, config)),
31049
+ path45.basename(instructionsSourceLabel(sourceRoot, config)),
30751
31050
  hashString5(composed),
30752
31051
  "opencode"
30753
31052
  );
@@ -30758,9 +31057,11 @@ ${composed}
30758
31057
  logger.info(
30759
31058
  `[dry-run] instructions: generate ${source} + rules appendix -> ${destination}`
30760
31059
  );
30761
- return { component: "instructions", status: "dry-run", path: destination };
31060
+ return [
31061
+ { component: "instructions", status: "dry-run", path: destination }
31062
+ ];
30762
31063
  }
30763
- return writeCompiledArtifact5(
31064
+ const written = writeCompiledArtifact5(
30764
31065
  "instructions",
30765
31066
  destination,
30766
31067
  content,
@@ -30772,18 +31073,60 @@ ${composed}
30772
31073
  manifest,
30773
31074
  scopePath
30774
31075
  );
31076
+ const declared = declareInstructions(paths);
31077
+ return declared === null ? [written] : [
31078
+ written,
31079
+ { component: "instructions", status: "success", path: declared }
31080
+ ];
31081
+ }
31082
+ function declaredInstructionsPath(paths) {
31083
+ const configDir = path45.dirname(resolveTargetPath(paths.config_doc));
31084
+ const instructions = resolveTargetPath(paths.instructions);
31085
+ const relative = path45.relative(configDir, instructions);
31086
+ if (relative === "AGENTS.md" || relative.startsWith("..")) {
31087
+ return null;
31088
+ }
31089
+ return relative.split(path45.sep).join("/");
31090
+ }
31091
+ function withDeclaredInstructions(existing, reference) {
31092
+ const listed = Array.isArray(existing) ? existing.filter((entry) => typeof entry === "string") : [];
31093
+ return listed.includes(reference) ? listed : [...listed, reference];
31094
+ }
31095
+ function declareInstructions(paths) {
31096
+ const reference = declaredInstructionsPath(paths);
31097
+ if (reference === null) {
31098
+ return null;
31099
+ }
31100
+ const destination = resolveTargetPath(paths.config_doc);
31101
+ let existing = {};
31102
+ if (fs45.existsSync(destination)) {
31103
+ try {
31104
+ existing = JSON.parse(fs45.readFileSync(destination, "utf8"));
31105
+ } catch {
31106
+ existing = {};
31107
+ }
31108
+ }
31109
+ const config = {
31110
+ $schema: "https://opencode.ai/config.json",
31111
+ ...existing,
31112
+ instructions: withDeclaredInstructions(existing.instructions, reference)
31113
+ };
31114
+ ensureDir(path45.dirname(destination));
31115
+ fs45.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31116
+ `);
31117
+ return destination;
30775
31118
  }
30776
31119
  function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30777
- const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
30778
- if (!fs44.existsSync(sourceAgentsRoot)) {
31120
+ const sourceAgentsRoot = path45.join(sourceRoot, config.source.agents);
31121
+ if (!fs45.existsSync(sourceAgentsRoot)) {
30779
31122
  return [skippedMissingSource6("agents", sourceAgentsRoot)];
30780
31123
  }
30781
- const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
31124
+ const sourceAgents = ts(path45.join(sourceAgentsRoot, "*.md")).sort();
30782
31125
  const agentsRoot = resolveTargetPath(paths.agents);
30783
31126
  return sourceAgents.map((agentFile) => {
30784
- const destination = path44.join(
31127
+ const destination = path45.join(
30785
31128
  agentsRoot,
30786
- `${path44.basename(agentFile, ".md")}.md`
31129
+ `${path45.basename(agentFile, ".md")}.md`
30787
31130
  );
30788
31131
  let compiled;
30789
31132
  try {
@@ -30847,11 +31190,11 @@ function applyProviderModelBinding(compiled, mappings) {
30847
31190
  return `${before}${(0, import_yaml12.stringify)(fields).trim()}${after}`;
30848
31191
  }
30849
31192
  function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30850
- const sourceCommandsRoot = path44.join(sourceRoot, config.source.commands);
30851
- if (!fs44.existsSync(sourceCommandsRoot)) {
31193
+ const sourceCommandsRoot = path45.join(sourceRoot, config.source.commands);
31194
+ if (!fs45.existsSync(sourceCommandsRoot)) {
30852
31195
  return [skippedMissingSource6("commands", sourceCommandsRoot)];
30853
31196
  }
30854
- const sourceCommands = ts(path44.join(sourceCommandsRoot, "*.md")).sort();
31197
+ const sourceCommands = ts(path45.join(sourceCommandsRoot, "*.md")).sort();
30855
31198
  const commandsRoot = resolveTargetPath(paths.commands);
30856
31199
  return sourceCommands.map((commandFile) => {
30857
31200
  const { data, body } = parseCommandFile(commandFile);
@@ -30865,7 +31208,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
30865
31208
  if (typeof data.model === "string") {
30866
31209
  frontmatter.model = data.model;
30867
31210
  }
30868
- const relativeSource = `commands/${path44.basename(commandFile)}`;
31211
+ const relativeSource = `commands/${path45.basename(commandFile)}`;
30869
31212
  const marker = formatProvenanceMarker(
30870
31213
  "markdown",
30871
31214
  relativeSource,
@@ -30881,9 +31224,9 @@ ${body.trimEnd()}
30881
31224
  ` : `${marker}
30882
31225
  ${body.trimEnd()}
30883
31226
  `;
30884
- const destination = path44.join(
31227
+ const destination = path45.join(
30885
31228
  commandsRoot,
30886
- `${path44.basename(commandFile, ".md")}.md`
31229
+ `${path45.basename(commandFile, ".md")}.md`
30887
31230
  );
30888
31231
  if (options.dryRun) {
30889
31232
  logger.info(
@@ -30913,7 +31256,7 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
30913
31256
  return syncSkillsSlot({
30914
31257
  config,
30915
31258
  sourceRoot,
30916
- source: path44.resolve(sourceRoot, config.source.skills),
31259
+ source: path45.resolve(sourceRoot, config.source.skills),
30917
31260
  destination,
30918
31261
  dryRun: options.dryRun,
30919
31262
  logger,
@@ -30931,13 +31274,13 @@ function syncMcp6(config, sourceRoot, paths, mappings, options, lossReport, logg
30931
31274
  const source = resolveMcpSourceFile(sourceRoot, config);
30932
31275
  const sourceLabel = mcpSourceLabel(config);
30933
31276
  const destination = resolveTargetPath(paths.config_doc);
30934
- if (!fs44.existsSync(source)) {
31277
+ if (!fs45.existsSync(source)) {
30935
31278
  if (!options.dryRun) {
30936
31279
  syncConfigDoc(paths, {}, lossReport, {}, mappings);
30937
31280
  }
30938
31281
  return skippedMissingSource6("mcp", source);
30939
31282
  }
30940
- const sourceMcpJson = JSON.parse(fs44.readFileSync(source, "utf8"));
31283
+ const sourceMcpJson = JSON.parse(fs45.readFileSync(source, "utf8"));
30941
31284
  const mcpJson = compileMcp(
30942
31285
  sourceMcpJson,
30943
31286
  "opencode",
@@ -31003,9 +31346,9 @@ function syncProviderBlock(mappings) {
31003
31346
  function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
31004
31347
  const destination = resolveTargetPath(paths.config_doc);
31005
31348
  let existing = {};
31006
- if (fs44.existsSync(destination)) {
31349
+ if (fs45.existsSync(destination)) {
31007
31350
  try {
31008
- existing = JSON.parse(fs44.readFileSync(destination, "utf8"));
31351
+ existing = JSON.parse(fs45.readFileSync(destination, "utf8"));
31009
31352
  } catch {
31010
31353
  existing = {};
31011
31354
  }
@@ -31018,6 +31361,13 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
31018
31361
  ...mcpEntries
31019
31362
  }
31020
31363
  };
31364
+ const instructionsRef = declaredInstructionsPath(paths);
31365
+ if (instructionsRef !== null) {
31366
+ config.instructions = withDeclaredInstructions(
31367
+ existing.instructions,
31368
+ instructionsRef
31369
+ );
31370
+ }
31021
31371
  if (Object.keys(permissionMap).length > 0) {
31022
31372
  config.permission = permissionMap;
31023
31373
  }
@@ -31030,8 +31380,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
31030
31380
  };
31031
31381
  }
31032
31382
  }
31033
- ensureDir(path44.dirname(destination));
31034
- fs44.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31383
+ ensureDir(path45.dirname(destination));
31384
+ fs45.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31035
31385
  `);
31036
31386
  }
31037
31387
  function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
@@ -31045,14 +31395,14 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
31045
31395
  if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
31046
31396
  return { component, status: "conflict", path: destination };
31047
31397
  }
31048
- ensureDir(path44.dirname(destination));
31398
+ ensureDir(path45.dirname(destination));
31049
31399
  const clearedLink = clearSymlinkAtDestination(destination);
31050
31400
  if (clearedLink !== null) {
31051
31401
  logger.verbose(
31052
31402
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
31053
31403
  );
31054
31404
  }
31055
- fs44.writeFileSync(destination, content);
31405
+ fs45.writeFileSync(destination, content);
31056
31406
  return { component, status: "success", path: destination };
31057
31407
  }
31058
31408
  function handleConflict6(destination, config, options, logger, manifest, scopePath) {
@@ -31070,7 +31420,7 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
31070
31420
  if (manifest && scopePath) {
31071
31421
  backupFile(destination, manifest, scopePath);
31072
31422
  writeManifest(scopePath, manifest);
31073
- fs44.rmSync(destination, { recursive: true, force: true });
31423
+ fs45.rmSync(destination, { recursive: true, force: true });
31074
31424
  } else {
31075
31425
  const parked = parkConflictingPath(
31076
31426
  destination,
@@ -31085,12 +31435,12 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
31085
31435
  }
31086
31436
  return true;
31087
31437
  }
31088
- fs44.rmSync(destination, { recursive: true, force: true });
31438
+ fs45.rmSync(destination, { recursive: true, force: true });
31089
31439
  return true;
31090
31440
  }
31091
31441
  function isCompiledCurrent5(destination, expectedContent, _expectedHash) {
31092
31442
  try {
31093
- return fs44.readFileSync(destination, "utf8") === expectedContent;
31443
+ return fs45.readFileSync(destination, "utf8") === expectedContent;
31094
31444
  } catch {
31095
31445
  return false;
31096
31446
  }
@@ -31109,7 +31459,7 @@ function hashString5(value) {
31109
31459
  return `sha256:${crypto10.createHash("sha256").update(value).digest("hex")}`;
31110
31460
  }
31111
31461
  function parseCommandFile(commandFile) {
31112
- const content = fs44.readFileSync(commandFile, "utf8");
31462
+ const content = fs45.readFileSync(commandFile, "utf8");
31113
31463
  if (!content.startsWith("---\n")) {
31114
31464
  return { data: {}, body: content };
31115
31465
  }
@@ -31129,7 +31479,7 @@ function parseCommandFile(commandFile) {
31129
31479
  // src/commands/install.ts
31130
31480
  function isBackupablePath(targetPath) {
31131
31481
  try {
31132
- const lstat = fs45.lstatSync(targetPath);
31482
+ const lstat = fs46.lstatSync(targetPath);
31133
31483
  return lstat.isSymbolicLink() || lstat.isFile() || lstat.isDirectory();
31134
31484
  } catch {
31135
31485
  return false;
@@ -31166,7 +31516,7 @@ async function runInstallCommand(options, logger) {
31166
31516
  );
31167
31517
  }
31168
31518
  const kitName = resolvedKitName ?? config.kit;
31169
- const kitPath = kitPathOverride ?? (options.kitPath ? path45.resolve(options.kitPath) : config.kitPath);
31519
+ const kitPath = kitPathOverride ?? (options.kitPath ? path46.resolve(options.kitPath) : config.kitPath);
31170
31520
  if (!kitName && !kitPath) {
31171
31521
  logger.error(
31172
31522
  "No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
@@ -31271,8 +31621,8 @@ async function runInstallCommand(options, logger) {
31271
31621
  config: options.config,
31272
31622
  scope
31273
31623
  });
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";
31624
+ const skillsSource = path46.resolve(kitInfo.path, config.source.skills);
31625
+ const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path46.basename(f.path) === "skills";
31276
31626
  const foreignSkillsSlots = new Set(
31277
31627
  assessResult.findings.filter(
31278
31628
  (f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
@@ -31310,7 +31660,7 @@ async function runInstallCommand(options, logger) {
31310
31660
  let instructionsLabel;
31311
31661
  try {
31312
31662
  const resolved = resolveInstructionsSource(kitInfo.path, config);
31313
- instructionsLabel = resolved ? path45.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
31663
+ instructionsLabel = resolved ? path46.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
31314
31664
  } catch (err) {
31315
31665
  logger.error(
31316
31666
  `[dry-run] ${err instanceof Error ? err.message : String(err)}`
@@ -31338,7 +31688,7 @@ async function runInstallCommand(options, logger) {
31338
31688
  }
31339
31689
  }
31340
31690
  logger.info(
31341
- `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path45.join(scopePath, "manifest.json")}`
31691
+ `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path46.join(scopePath, "manifest.json")}`
31342
31692
  );
31343
31693
  return;
31344
31694
  }
@@ -31397,7 +31747,7 @@ ACCEPTED CONFLICTS (posture: ${posture}; ${replaceable.length} target(s)):`
31397
31747
  logger.info(` - ${finding.path}`);
31398
31748
  logger.info(` source: ${sources}`);
31399
31749
  logger.info(
31400
- ` action: backup-and-replace${fs45.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
31750
+ ` action: backup-and-replace${fs46.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
31401
31751
  );
31402
31752
  logger.info(` backup: ${backupLocation}`);
31403
31753
  continue;
@@ -31505,11 +31855,28 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
31505
31855
  installLossReport
31506
31856
  );
31507
31857
  }
31858
+ const instructionsByTarget = instructionsByActiveTarget(
31859
+ tools,
31860
+ scope,
31861
+ projectRoot,
31862
+ mappings
31863
+ );
31864
+ const rulesCoverage = measureRulesCoverage(
31865
+ tools,
31866
+ kitInfo.components.rules?.declared ?? [],
31867
+ scope,
31868
+ projectRoot,
31869
+ mappings,
31870
+ installLossReport,
31871
+ instructionsByTarget
31872
+ );
31508
31873
  reportContestedInstructions(
31509
- instructionsByActiveTarget(tools, scope, projectRoot, mappings),
31874
+ instructionsByTarget,
31510
31875
  (kitInfo.components.rules?.declared.length ?? 0) > 0,
31511
- logger
31876
+ logger,
31877
+ missingRulesByTarget(rulesCoverage)
31512
31878
  );
31879
+ reportRulesCoverage(rulesCoverage, logger);
31513
31880
  for (const [relativePath, sourcePath] of collectAllFiles(kitInfo, config)) {
31514
31881
  addFileToManifest(manifest, {
31515
31882
  relativePath,
@@ -31521,20 +31888,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
31521
31888
  writeManifest(scopePath, manifest);
31522
31889
  logger.info(`
31523
31890
  Installation complete: ${installedCount} files installed.`);
31524
- logger.info(`Manifest written to ${path45.join(scopePath, "manifest.json")}`);
31891
+ logger.info(`Manifest written to ${path46.join(scopePath, "manifest.json")}`);
31525
31892
  logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
31526
31893
  logger.info(`Scope: ${scope}`);
31527
31894
  logger.info(`Tools: ${tools.join(", ")}`);
31528
31895
  reportHookRejections(
31529
31896
  installLossReport,
31530
31897
  tools,
31531
- path45.resolve(kitInfo.path, "hooks"),
31898
+ path46.resolve(kitInfo.path, "hooks"),
31532
31899
  kitInfo.components.hooks.declared
31533
31900
  );
31534
31901
  const hooksConflict = reportHooksSourceConflict(
31535
31902
  installLossReport,
31536
31903
  tools,
31537
- path45.resolve(kitInfo.path, "hooks"),
31904
+ path46.resolve(kitInfo.path, "hooks"),
31538
31905
  kitInfo.components.hooks.declared
31539
31906
  );
31540
31907
  if (hooksConflict) {
@@ -31840,7 +32207,8 @@ function installClaudeCodeAdapterSlots(args) {
31840
32207
  profile,
31841
32208
  outcome,
31842
32209
  scope,
31843
- projectRoot
32210
+ projectRoot,
32211
+ mappings
31844
32212
  );
31845
32213
  if (!key) {
31846
32214
  continue;
@@ -31865,8 +32233,13 @@ function installClaudeCodeAdapterSlots(args) {
31865
32233
  }
31866
32234
  return count;
31867
32235
  }
31868
- function claudeCodeOutcomeToManifestKey(profile, outcome, scope, projectRoot) {
31869
- const shared = sharedArtifactKey(outcome.path, scope, projectRoot);
32236
+ function claudeCodeOutcomeToManifestKey(profile, outcome, scope, projectRoot, mappings) {
32237
+ const shared = sharedKeyForDestination(
32238
+ outcome.path,
32239
+ scope,
32240
+ projectRoot,
32241
+ mappings.platformPaths
32242
+ );
31870
32243
  if (shared) {
31871
32244
  return shared;
31872
32245
  }
@@ -31893,7 +32266,7 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
31893
32266
  return 0;
31894
32267
  }
31895
32268
  try {
31896
- const stat = fs45.lstatSync(destination);
32269
+ const stat = fs46.lstatSync(destination);
31897
32270
  if (stat.isFile() && !stat.isSymbolicLink()) {
31898
32271
  logger.warn(
31899
32272
  `${destination}: a regular file occupies the skills slot \u2014 skipping skills. Move or remove it, then re-run install.`
@@ -31921,17 +32294,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
31921
32294
  manifest,
31922
32295
  scopePath
31923
32296
  );
31924
- const skillsSource = path45.resolve(kitInfo.path, config.source.skills);
32297
+ const skillsSource = path46.resolve(kitInfo.path, config.source.skills);
31925
32298
  let count = 0;
31926
32299
  for (const outcome of outcomes) {
31927
32300
  if (outcome.status !== "success" && outcome.status !== "skipped-current") {
31928
32301
  continue;
31929
32302
  }
31930
- const skillName = path45.basename(outcome.path);
32303
+ const skillName = path46.basename(outcome.path);
31931
32304
  addArtifactToManifest(manifest, {
31932
32305
  relativePath: `claude-code/skills/${skillName}`,
31933
32306
  path: outcome.path,
31934
- hash: describeArtifactState(outcome.path) ?? `dir:${path45.join(skillsSource, skillName)}`,
32307
+ hash: describeArtifactState(outcome.path) ?? `dir:${path46.join(skillsSource, skillName)}`,
31935
32308
  origin: "tangyr-managed"
31936
32309
  });
31937
32310
  count++;
@@ -31945,10 +32318,10 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
31945
32318
  logger.verbose(` skipped (operator choice): ${placement.destination}`);
31946
32319
  continue;
31947
32320
  }
31948
- const destDir = path45.dirname(placement.destination);
31949
- fs45.mkdirSync(destDir, { recursive: true });
32321
+ const destDir = path46.dirname(placement.destination);
32322
+ fs46.mkdirSync(destDir, { recursive: true });
31950
32323
  if (placement.type === "symlink") {
31951
- if (fs45.existsSync(placement.destination) || isSymlink2(placement.destination)) {
32324
+ if (fs46.existsSync(placement.destination) || isSymlink2(placement.destination)) {
31952
32325
  removeManagedPath(placement.destination);
31953
32326
  }
31954
32327
  createRelativeSymlink(
@@ -31965,7 +32338,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
31965
32338
  ` symlink: ${placement.source} \u2192 ${placement.destination}`
31966
32339
  );
31967
32340
  } else {
31968
- fs45.copyFileSync(placement.source, placement.destination);
32341
+ fs46.copyFileSync(placement.source, placement.destination);
31969
32342
  logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
31970
32343
  }
31971
32344
  addArtifactToManifest(manifest, {
@@ -32215,7 +32588,12 @@ function countInstalledArtifacts(outcomes) {
32215
32588
  ).length;
32216
32589
  }
32217
32590
  function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", projectRoot) {
32218
- const shared = sharedArtifactKey(outcome.path, scope, projectRoot);
32591
+ const shared = sharedKeyForDestination(
32592
+ outcome.path,
32593
+ scope,
32594
+ projectRoot,
32595
+ mappings.platformPaths
32596
+ );
32219
32597
  if (shared) {
32220
32598
  return shared;
32221
32599
  }
@@ -32257,11 +32635,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32257
32635
  if (outcome.path === mcpFile2) {
32258
32636
  return "cline/mcp.json";
32259
32637
  }
32260
- if (outcome.path.startsWith(`${workflowsRoot}${path45.sep}`)) {
32261
- return `cline/workflows/${path45.basename(outcome.path)}`;
32638
+ if (outcome.path.startsWith(`${workflowsRoot}${path46.sep}`)) {
32639
+ return `cline/workflows/${path46.basename(outcome.path)}`;
32262
32640
  }
32263
- if (outcome.path.startsWith(`${rulesRoot2}${path45.sep}`)) {
32264
- return `cline/rules/${path45.basename(outcome.path)}`;
32641
+ if (outcome.path.startsWith(`${rulesRoot2}${path46.sep}`)) {
32642
+ return `cline/rules/${path46.basename(outcome.path)}`;
32265
32643
  }
32266
32644
  return null;
32267
32645
  }
@@ -32297,14 +32675,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32297
32675
  if (outcome.path === permissionsFile) {
32298
32676
  return "cursor/permissions.json";
32299
32677
  }
32300
- if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
32301
- return `cursor/agents/${path45.basename(outcome.path)}`;
32678
+ if (outcome.path.startsWith(`${agentsRoot2}${path46.sep}`)) {
32679
+ return `cursor/agents/${path46.basename(outcome.path)}`;
32302
32680
  }
32303
- if (outcome.path.startsWith(`${rulesRoot2}${path45.sep}`)) {
32304
- return `cursor/rules/${path45.basename(outcome.path)}`;
32681
+ if (outcome.path.startsWith(`${rulesRoot2}${path46.sep}`)) {
32682
+ return `cursor/rules/${path46.basename(outcome.path)}`;
32305
32683
  }
32306
- if (outcome.path.startsWith(`${skillsRoot2}${path45.sep}`)) {
32307
- const rel = path45.relative(skillsRoot2, outcome.path);
32684
+ if (outcome.path.startsWith(`${skillsRoot2}${path46.sep}`)) {
32685
+ const rel = path46.relative(skillsRoot2, outcome.path);
32308
32686
  return `cursor/skills/${rel}`;
32309
32687
  }
32310
32688
  return null;
@@ -32330,14 +32708,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32330
32708
  if (outcome.path === skillsSharedRoot) {
32331
32709
  return "opencode/skills_shared";
32332
32710
  }
32333
- if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
32334
- return `opencode/agents/${path45.basename(outcome.path)}`;
32711
+ if (outcome.path.startsWith(`${agentsRoot2}${path46.sep}`)) {
32712
+ return `opencode/agents/${path46.basename(outcome.path)}`;
32335
32713
  }
32336
- if (outcome.path.startsWith(`${commandsRoot}${path45.sep}`)) {
32337
- return `opencode/commands/${path45.basename(outcome.path)}`;
32714
+ if (outcome.path.startsWith(`${commandsRoot}${path46.sep}`)) {
32715
+ return `opencode/commands/${path46.basename(outcome.path)}`;
32338
32716
  }
32339
32717
  if (outcome.path === configDocFile) {
32340
- return `opencode/${path45.basename(outcome.path)}`;
32718
+ return `opencode/${path46.basename(outcome.path)}`;
32341
32719
  }
32342
32720
  return null;
32343
32721
  }
@@ -32354,26 +32732,29 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32354
32732
  const hooksRoot = resolveTargetPath(copilot.hooks);
32355
32733
  const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
32356
32734
  const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
32357
- if (outcome.path.startsWith(`${skillsRoot2}${path45.sep}`)) {
32358
- return `copilot/skills/${path45.relative(skillsRoot2, outcome.path)}`;
32735
+ if (copilot.rules !== null && outcome.path.startsWith(`${resolveTargetPath(copilot.rules)}${path46.sep}`)) {
32736
+ return `copilot/rules/${path46.relative(resolveTargetPath(copilot.rules), outcome.path)}`;
32737
+ }
32738
+ if (outcome.path.startsWith(`${skillsRoot2}${path46.sep}`)) {
32739
+ return `copilot/skills/${path46.relative(skillsRoot2, outcome.path)}`;
32359
32740
  }
32360
32741
  if (outcome.path === skillsRoot2) {
32361
32742
  return "copilot/skills";
32362
32743
  }
32363
32744
  if (instructionsMirror !== null && outcome.path === instructionsMirror) {
32364
- return `copilot/${path45.basename(outcome.path)}`;
32745
+ return `copilot/${path46.basename(outcome.path)}`;
32365
32746
  }
32366
- if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
32367
- return `copilot/agents/${path45.basename(outcome.path)}`;
32747
+ if (outcome.path.startsWith(`${agentsRoot2}${path46.sep}`)) {
32748
+ return `copilot/agents/${path46.basename(outcome.path)}`;
32368
32749
  }
32369
- if (outcome.path.startsWith(`${promptsRoot}${path45.sep}`)) {
32370
- return `copilot/prompts/${path45.basename(outcome.path)}`;
32750
+ if (outcome.path.startsWith(`${promptsRoot}${path46.sep}`)) {
32751
+ return `copilot/prompts/${path46.basename(outcome.path)}`;
32371
32752
  }
32372
- if (outcome.path.startsWith(`${hooksRoot}${path45.sep}`)) {
32373
- return `copilot/hooks/${path45.basename(outcome.path)}`;
32753
+ if (outcome.path.startsWith(`${hooksRoot}${path46.sep}`)) {
32754
+ return `copilot/hooks/${path46.basename(outcome.path)}`;
32374
32755
  }
32375
32756
  if (outcome.path === mcpFile2) {
32376
- return `copilot/${path45.basename(outcome.path)}`;
32757
+ return `copilot/${path46.basename(outcome.path)}`;
32377
32758
  }
32378
32759
  return null;
32379
32760
  }
@@ -32390,17 +32771,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32390
32771
  if (outcome.path === skillsRoot) {
32391
32772
  return "codex/skills";
32392
32773
  }
32393
- if (outcome.path.startsWith(`${agentsRoot}${path45.sep}`)) {
32394
- return `codex/agents/${path45.basename(outcome.path)}`;
32774
+ if (outcome.path.startsWith(`${agentsRoot}${path46.sep}`)) {
32775
+ return `codex/agents/${path46.basename(outcome.path)}`;
32395
32776
  }
32396
- if (outcome.path.startsWith(`${rulesRoot}${path45.sep}`)) {
32397
- return `codex/rules/${path45.basename(outcome.path)}`;
32777
+ if (outcome.path.startsWith(`${rulesRoot}${path46.sep}`)) {
32778
+ return `codex/rules/${path46.basename(outcome.path)}`;
32398
32779
  }
32399
32780
  if (outcome.path === hooksFile) {
32400
- return `codex/${path45.basename(outcome.path)}`;
32781
+ return `codex/${path46.basename(outcome.path)}`;
32401
32782
  }
32402
32783
  if (outcome.path === mcpFile) {
32403
- return `codex/${path45.basename(outcome.path)}`;
32784
+ return `codex/${path46.basename(outcome.path)}`;
32404
32785
  }
32405
32786
  return null;
32406
32787
  }
@@ -32469,8 +32850,8 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
32469
32850
  rules: resolvedPaths.rules
32470
32851
  };
32471
32852
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
32472
- const componentDir = path45.join(kitInfo.path, component);
32473
- if (fs45.existsSync(componentDir) && fs45.statSync(componentDir).isDirectory()) {
32853
+ const componentDir = path46.join(kitInfo.path, component);
32854
+ if (fs46.existsSync(componentDir) && fs46.statSync(componentDir).isDirectory()) {
32474
32855
  placements.push({
32475
32856
  source: componentDir,
32476
32857
  destination: targetPath,
@@ -32500,8 +32881,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
32500
32881
  rules: profile.rules
32501
32882
  };
32502
32883
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
32503
- const componentDir = path45.join(kitInfo.path, component);
32504
- if (fs45.existsSync(componentDir) && fs45.statSync(componentDir).isDirectory()) {
32884
+ const componentDir = path46.join(kitInfo.path, component);
32885
+ if (fs46.existsSync(componentDir) && fs46.statSync(componentDir).isDirectory()) {
32505
32886
  placements.push({
32506
32887
  source: componentDir,
32507
32888
  destination: targetPath,
@@ -32517,7 +32898,7 @@ function collectAllFiles(kitInfo, config) {
32517
32898
  const files = /* @__PURE__ */ new Map();
32518
32899
  const entrypoint = resolveInstructionsSource(kitInfo.path, config);
32519
32900
  if (entrypoint) {
32520
- files.set(path45.basename(entrypoint.file), entrypoint.file);
32901
+ files.set(path46.basename(entrypoint.file), entrypoint.file);
32521
32902
  }
32522
32903
  for (const [component, reconciliation] of Object.entries(
32523
32904
  kitInfo.components
@@ -32526,22 +32907,22 @@ function collectAllFiles(kitInfo, config) {
32526
32907
  const missingSet = new Set(reconciliation.missing);
32527
32908
  for (const entry of reconciliation.declared) {
32528
32909
  if (missingSet.has(entry)) continue;
32529
- const relPath = isSkills ? path45.join(component, entry) : path45.join(component, `${entry}.md`);
32530
- files.set(relPath, path45.join(kitInfo.path, relPath));
32910
+ const relPath = isSkills ? path46.join(component, entry) : path46.join(component, `${entry}.md`);
32911
+ files.set(relPath, path46.join(kitInfo.path, relPath));
32531
32912
  }
32532
32913
  }
32533
32914
  return files;
32534
32915
  }
32535
32916
  function readLinkTarget(p) {
32536
32917
  try {
32537
- return fs45.readlinkSync(p);
32918
+ return fs46.readlinkSync(p);
32538
32919
  } catch {
32539
32920
  return null;
32540
32921
  }
32541
32922
  }
32542
32923
  function isSymlink2(p) {
32543
32924
  try {
32544
- return fs45.lstatSync(p).isSymbolicLink();
32925
+ return fs46.lstatSync(p).isSymbolicLink();
32545
32926
  } catch {
32546
32927
  return false;
32547
32928
  }
@@ -32560,10 +32941,10 @@ function skillsSubPathKey(tool, outcomePath, mappings, scope, projectRoot) {
32560
32941
  continue;
32561
32942
  }
32562
32943
  const root = resolveTargetPath(slot);
32563
- if (!outcomePath.startsWith(`${root}${path45.sep}`)) {
32944
+ if (!outcomePath.startsWith(`${root}${path46.sep}`)) {
32564
32945
  continue;
32565
32946
  }
32566
- const inside = path45.relative(root, outcomePath).split(path45.sep).join("/");
32947
+ const inside = path46.relative(root, outcomePath).split(path46.sep).join("/");
32567
32948
  return `${tool}/skills/${inside}`;
32568
32949
  }
32569
32950
  return null;
@@ -32608,14 +32989,14 @@ async function runKitUpdateCommand(options, logger) {
32608
32989
  }
32609
32990
 
32610
32991
  // src/commands/list.ts
32611
- import path46 from "path";
32992
+ import path47 from "path";
32612
32993
  function runListCommand(options, logger) {
32613
32994
  let searchPaths = [];
32614
- let directKitPath = options.kitPath ? path46.resolve(options.kitPath) : void 0;
32995
+ let directKitPath = options.kitPath ? path47.resolve(options.kitPath) : void 0;
32615
32996
  try {
32616
32997
  const { config, configDir } = resolveConfig(options.config);
32617
32998
  searchPaths = config.kitSearchPaths ?? [
32618
- path46.join(configDir, "operating-kits")
32999
+ path47.join(configDir, "operating-kits")
32619
33000
  ];
32620
33001
  directKitPath = directKitPath ?? config.kitPath;
32621
33002
  } catch (err) {
@@ -32690,7 +33071,7 @@ function withDirectKit(kits, directKitPath) {
32690
33071
  return kits;
32691
33072
  }
32692
33073
  const directKit = loadKit(directKitPath);
32693
- if (kits.some((kit) => path46.resolve(kit.path) === directKit.path)) {
33074
+ if (kits.some((kit) => path47.resolve(kit.path) === directKit.path)) {
32694
33075
  return kits;
32695
33076
  }
32696
33077
  return [...kits, directKit];
@@ -32698,8 +33079,8 @@ function withDirectKit(kits, directKitPath) {
32698
33079
 
32699
33080
  // src/commands/probe.ts
32700
33081
  import { spawnSync as spawnSync2 } from "child_process";
32701
- import fs46 from "fs";
32702
- import path47 from "path";
33082
+ import fs47 from "fs";
33083
+ import path48 from "path";
32703
33084
  function runProbeCommand(options, logger) {
32704
33085
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
32705
33086
  options,
@@ -32727,7 +33108,7 @@ function runProbeCommand(options, logger) {
32727
33108
  toProbeRow(
32728
33109
  target,
32729
33110
  key,
32730
- scope === "project" ? path47.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
33111
+ scope === "project" ? path48.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
32731
33112
  )
32732
33113
  );
32733
33114
  }
@@ -32749,7 +33130,7 @@ function toProbeRow(target, key, rawPath) {
32749
33130
  const resolved = resolveTargetPath(rawPath);
32750
33131
  let accessible = false;
32751
33132
  try {
32752
- fs46.accessSync(resolved);
33133
+ fs47.accessSync(resolved);
32753
33134
  accessible = true;
32754
33135
  } catch {
32755
33136
  accessible = false;
@@ -32758,7 +33139,7 @@ function toProbeRow(target, key, rawPath) {
32758
33139
  target,
32759
33140
  key,
32760
33141
  path: resolved,
32761
- exists: fs46.existsSync(resolved),
33142
+ exists: fs47.existsSync(resolved),
32762
33143
  accessible
32763
33144
  };
32764
33145
  }
@@ -32776,7 +33157,7 @@ function codexRuntimeProbeRows() {
32776
33157
  ["binary_snap", "/snap/bin/codex"],
32777
33158
  ["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
32778
33159
  ]) {
32779
- if (fs46.existsSync(candidatePath)) {
33160
+ if (fs47.existsSync(candidatePath)) {
32780
33161
  rows.push(toProbeRow("codex", key, candidatePath));
32781
33162
  }
32782
33163
  }
@@ -32792,8 +33173,8 @@ function commandProbeRows(target, key, command, args) {
32792
33173
 
32793
33174
  // src/commands/status.ts
32794
33175
  import crypto11 from "crypto";
32795
- import fs47 from "fs";
32796
- import path48 from "path";
33176
+ import fs48 from "fs";
33177
+ import path49 from "path";
32797
33178
  function runStatusCommand(options, logger) {
32798
33179
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
32799
33180
  options,
@@ -32899,11 +33280,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
32899
33280
  }
32900
33281
  }
32901
33282
  function sourceMarkdownFiles(sourceRoot, componentPath) {
32902
- const root = path48.join(sourceRoot, componentPath);
32903
- if (!fs47.existsSync(root)) {
33283
+ const root = path49.join(sourceRoot, componentPath);
33284
+ if (!fs48.existsSync(root)) {
32904
33285
  return [];
32905
33286
  }
32906
- return ts(path48.join(root, "*.md")).sort();
33287
+ return ts(path49.join(root, "*.md")).sort();
32907
33288
  }
32908
33289
  function notRepresentableRow(component, detail) {
32909
33290
  return {
@@ -32914,11 +33295,11 @@ function notRepresentableRow(component, detail) {
32914
33295
  };
32915
33296
  }
32916
33297
  function readTargetJson(filePath) {
32917
- if (!fs47.existsSync(filePath)) {
33298
+ if (!fs48.existsSync(filePath)) {
32918
33299
  return { kind: "missing" };
32919
33300
  }
32920
33301
  try {
32921
- const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
33302
+ const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
32922
33303
  return { kind: "object", value: isRecord(parsed) ? parsed : {} };
32923
33304
  } catch (err) {
32924
33305
  return {
@@ -33007,7 +33388,7 @@ function classifyInstructions(filePath, target, expectedHash, config, sourceRoot
33007
33388
  }
33008
33389
  function compiledMcpDocument(config, sourceRoot, target) {
33009
33390
  const source = resolveMcpSourceFile(sourceRoot, config);
33010
- if (!fs47.existsSync(source)) {
33391
+ if (!fs48.existsSync(source)) {
33011
33392
  return {};
33012
33393
  }
33013
33394
  const compiled = compileMcp(
@@ -33020,7 +33401,7 @@ function compiledMcpDocument(config, sourceRoot, target) {
33020
33401
  return isRecord(parsed) ? parsed : {};
33021
33402
  }
33022
33403
  function classifyMcpDocument(config, sourceRoot, target, filePath) {
33023
- if (!fs47.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
33404
+ if (!fs48.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
33024
33405
  return notConfiguredRow("mcp", filePath);
33025
33406
  }
33026
33407
  return classifyJsonDocument(
@@ -33050,12 +33431,12 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
33050
33431
  const rows = [];
33051
33432
  const instructionsSource = instructionsSourcePath(sourceRoot, config);
33052
33433
  const rules = compileRules(
33053
- path48.join(sourceRoot, config.source.rules),
33434
+ path49.join(sourceRoot, config.source.rules),
33054
33435
  "opencode",
33055
33436
  mappings,
33056
33437
  createLossReport()
33057
33438
  );
33058
- const baseInstructions = fs47.existsSync(instructionsSource) ? fs47.readFileSync(instructionsSource, "utf8").trim() : "";
33439
+ const baseInstructions = fs48.existsSync(instructionsSource) ? fs48.readFileSync(instructionsSource, "utf8").trim() : "";
33059
33440
  const composedInstructions = rules.agentsAppendix ? `${baseInstructions}
33060
33441
 
33061
33442
  --- tangyr managed rules ---
@@ -33077,10 +33458,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
33077
33458
  )) {
33078
33459
  rows.push(
33079
33460
  classifyCompiledFile(
33080
- `agents/${path48.basename(agentFile, ".md")}`,
33081
- path48.join(
33461
+ `agents/${path49.basename(agentFile, ".md")}`,
33462
+ path49.join(
33082
33463
  resolveTargetPath(paths.agents),
33083
- `${path48.basename(agentFile, ".md")}.md`
33464
+ `${path49.basename(agentFile, ".md")}.md`
33084
33465
  ),
33085
33466
  "opencode",
33086
33467
  computeSourceHash(agentFile),
@@ -33095,10 +33476,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
33095
33476
  )) {
33096
33477
  rows.push(
33097
33478
  classifyCompiledFile(
33098
- `commands/${path48.basename(commandFile, ".md")}`,
33099
- path48.join(
33479
+ `commands/${path49.basename(commandFile, ".md")}`,
33480
+ path49.join(
33100
33481
  resolveTargetPath(paths.commands),
33101
- `${path48.basename(commandFile, ".md")}.md`
33482
+ `${path49.basename(commandFile, ".md")}.md`
33102
33483
  ),
33103
33484
  "opencode",
33104
33485
  computeSourceHash(commandFile),
@@ -33180,10 +33561,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33180
33561
  )) {
33181
33562
  rows.push(
33182
33563
  classifyCompiledFile(
33183
- `agents/${path48.basename(agentFile, ".md")}`,
33184
- path48.join(
33564
+ `agents/${path49.basename(agentFile, ".md")}`,
33565
+ path49.join(
33185
33566
  resolveTargetPath(paths.agents),
33186
- `${path48.basename(agentFile, ".md")}.md`
33567
+ `${path49.basename(agentFile, ".md")}.md`
33187
33568
  ),
33188
33569
  "cursor",
33189
33570
  computeSourceHash(agentFile),
@@ -33200,7 +33581,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33200
33581
  rows.push(
33201
33582
  classifyCompiledFile(
33202
33583
  `rules/${ruleFile.name}`,
33203
- path48.join(resolveTargetPath(paths.rules), ruleFile.name),
33584
+ path49.join(resolveTargetPath(paths.rules), ruleFile.name),
33204
33585
  "cursor",
33205
33586
  void 0,
33206
33587
  config,
@@ -33214,11 +33595,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33214
33595
  sourceRoot,
33215
33596
  config.source.commands
33216
33597
  )) {
33217
- const baseName = path48.basename(commandFile, ".md");
33598
+ const baseName = path49.basename(commandFile, ".md");
33218
33599
  rows.push(
33219
33600
  classifyCompiledFile(
33220
33601
  `commands/${baseName}`,
33221
- path48.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
33602
+ path49.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
33222
33603
  "cursor",
33223
33604
  computeSourceHash(commandFile),
33224
33605
  config,
@@ -33301,7 +33682,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33301
33682
  rows.push(
33302
33683
  classifyCompiledFile(
33303
33684
  `rules/${ruleFile.name}`,
33304
- path48.join(resolveTargetPath(paths.rules), ruleFile.name),
33685
+ path49.join(resolveTargetPath(paths.rules), ruleFile.name),
33305
33686
  "cline",
33306
33687
  void 0,
33307
33688
  config,
@@ -33317,10 +33698,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33317
33698
  )) {
33318
33699
  rows.push(
33319
33700
  classifyCompiledFile(
33320
- `commands/${path48.basename(commandFile, ".md")}`,
33321
- path48.join(
33701
+ `commands/${path49.basename(commandFile, ".md")}`,
33702
+ path49.join(
33322
33703
  resolveTargetPath(paths.workflows),
33323
- path48.basename(commandFile)
33704
+ path49.basename(commandFile)
33324
33705
  ),
33325
33706
  "cline",
33326
33707
  computeSourceHash(commandFile),
@@ -33361,14 +33742,14 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33361
33742
  return rows;
33362
33743
  }
33363
33744
  function compileRulesFiles(config, sourceRoot, target, mappings) {
33364
- const rulesSource = path48.join(sourceRoot, config.source.rules);
33365
- if (!fs47.existsSync(rulesSource)) {
33745
+ const rulesSource = path49.join(sourceRoot, config.source.rules);
33746
+ if (!fs48.existsSync(rulesSource)) {
33366
33747
  return [];
33367
33748
  }
33368
33749
  return compileRules(rulesSource, target, mappings, createLossReport()).dotRulesFiles;
33369
33750
  }
33370
33751
  function classifyDirectoryPresence(component, dirPath) {
33371
- const present = fs47.existsSync(dirPath) && fs47.statSync(dirPath).isDirectory();
33752
+ const present = fs48.existsSync(dirPath) && fs48.statSync(dirPath).isDirectory();
33372
33753
  return {
33373
33754
  component,
33374
33755
  className: present ? "current" : "missing",
@@ -33387,7 +33768,7 @@ function slotsForScope2(scopeMap, scope, projectRoot) {
33387
33768
  const root = projectRoot ?? process.cwd();
33388
33769
  const resolved = {};
33389
33770
  for (const [slot, value] of Object.entries(projectSlots)) {
33390
- resolved[slot] = typeof value === "string" ? path48.resolve(root, value) : value;
33771
+ resolved[slot] = typeof value === "string" ? path49.resolve(root, value) : value;
33391
33772
  }
33392
33773
  return resolved;
33393
33774
  }
@@ -33407,21 +33788,21 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
33407
33788
  rules: paths.rules
33408
33789
  };
33409
33790
  const rules = compileRules(
33410
- path48.join(sourceRoot, config.source.rules),
33791
+ path49.join(sourceRoot, config.source.rules),
33411
33792
  "codex",
33412
33793
  mappings,
33413
33794
  createLossReport()
33414
33795
  );
33415
- const instructionsSource = fs47.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
33796
+ const instructionsSource = fs48.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
33416
33797
  const composedInstructions = `${instructionsSource}
33417
33798
 
33418
33799
  --- tangyr managed rules ---
33419
33800
  ${rules.agentsAppendix}`.trim();
33420
33801
  const agentFiles = ts(
33421
- path48.join(sourceRoot, config.source.agents, "*.md")
33802
+ path49.join(sourceRoot, config.source.agents, "*.md")
33422
33803
  ).sort();
33423
33804
  const hooksPresent = hooksSourceExists(sourceRoot, config);
33424
- const mcpSource = path48.join(sourceRoot, config.source.mcp);
33805
+ const mcpSource = path49.join(sourceRoot, config.source.mcp);
33425
33806
  const ruleRows = rules.dotRulesFiles.length === 0 ? [
33426
33807
  {
33427
33808
  component: "rules",
@@ -33432,7 +33813,7 @@ ${rules.agentsAppendix}`.trim();
33432
33813
  ] : rules.dotRulesFiles.map(
33433
33814
  (ruleFile) => classifyCompiledFile(
33434
33815
  `rules/${ruleFile.name}`,
33435
- path48.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
33816
+ path49.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
33436
33817
  "codex",
33437
33818
  void 0,
33438
33819
  config,
@@ -33450,10 +33831,10 @@ ${rules.agentsAppendix}`.trim();
33450
33831
  ),
33451
33832
  ...agentFiles.map(
33452
33833
  (agentFile) => classifyCompiledFile(
33453
- `agents/${path48.basename(agentFile, ".md")}`,
33454
- path48.join(
33834
+ `agents/${path49.basename(agentFile, ".md")}`,
33835
+ path49.join(
33455
33836
  resolveTargetPath(codexPaths.agents),
33456
- `${path48.basename(agentFile, ".md")}.toml`
33837
+ `${path49.basename(agentFile, ".md")}.toml`
33457
33838
  ),
33458
33839
  "codex",
33459
33840
  computeSourceHash(agentFile),
@@ -33481,7 +33862,7 @@ ${rules.agentsAppendix}`.trim();
33481
33862
  "hooks",
33482
33863
  resolveTargetPath(codexPaths.hooksSharedFile)
33483
33864
  ),
33484
- fs47.existsSync(mcpSource) ? classifyCompiledFile(
33865
+ fs48.existsSync(mcpSource) ? classifyCompiledFile(
33485
33866
  "mcp",
33486
33867
  resolveTargetPath(codexPaths.mcpSharedFile),
33487
33868
  "codex",
@@ -33547,20 +33928,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33547
33928
  mcpSharedFile: paths.mcp_shared_file
33548
33929
  };
33549
33930
  const agentFiles = ts(
33550
- path48.join(sourceRoot, config.source.agents, "*.md")
33931
+ path49.join(sourceRoot, config.source.agents, "*.md")
33551
33932
  ).sort();
33552
33933
  const commandFiles = ts(
33553
- path48.join(sourceRoot, config.source.commands, "*.md")
33934
+ path49.join(sourceRoot, config.source.commands, "*.md")
33554
33935
  ).sort();
33555
33936
  const hooksPresent = hooksSourceExists(sourceRoot, config);
33556
- const mcpSource = path48.join(sourceRoot, config.source.mcp);
33937
+ const mcpSource = path49.join(sourceRoot, config.source.mcp);
33557
33938
  return [
33558
33939
  ...agentFiles.map(
33559
33940
  (agentFile) => classifyCompiledFile(
33560
- `agents/${path48.basename(agentFile, ".md")}`,
33561
- path48.join(
33941
+ `agents/${path49.basename(agentFile, ".md")}`,
33942
+ path49.join(
33562
33943
  resolveTargetPath(copilotPaths.agents),
33563
- `${path48.basename(agentFile, ".md")}.agent.md`
33944
+ `${path49.basename(agentFile, ".md")}.agent.md`
33564
33945
  ),
33565
33946
  "copilot",
33566
33947
  computeSourceHash(agentFile),
@@ -33577,10 +33958,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33577
33958
  ),
33578
33959
  ...commandFiles.map(
33579
33960
  (commandFile) => classifyCompiledFile(
33580
- `commands/${path48.basename(commandFile, ".md")}`,
33581
- path48.join(
33961
+ `commands/${path49.basename(commandFile, ".md")}`,
33962
+ path49.join(
33582
33963
  resolveTargetPath(copilotPaths.prompts),
33583
- `${path48.basename(commandFile, ".md")}.prompt.md`
33964
+ `${path49.basename(commandFile, ".md")}.prompt.md`
33584
33965
  ),
33585
33966
  "copilot",
33586
33967
  computeSourceHash(commandFile),
@@ -33599,19 +33980,19 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33599
33980
  sourceRoot
33600
33981
  ),
33601
33982
  hooksPresent ? classifyCompiledHooksByProvenance(
33602
- path48.join(
33983
+ path49.join(
33603
33984
  resolveTargetPath(copilotPaths.hooks),
33604
33985
  "tangyr-managed.json"
33605
33986
  ),
33606
33987
  "copilot"
33607
33988
  ) : notConfiguredRow(
33608
33989
  "hooks",
33609
- path48.join(
33990
+ path49.join(
33610
33991
  resolveTargetPath(copilotPaths.hooks),
33611
33992
  "tangyr-managed.json"
33612
33993
  )
33613
33994
  ),
33614
- fs47.existsSync(mcpSource) ? classifyCompiledFile(
33995
+ fs48.existsSync(mcpSource) ? classifyCompiledFile(
33615
33996
  "mcp",
33616
33997
  resolveTargetPath(copilotPaths.mcpSharedFile),
33617
33998
  "copilot",
@@ -33631,7 +34012,7 @@ function notConfiguredRow(component, filePath) {
33631
34012
  }
33632
34013
  function classifyDirectArtifact(artifact, config, sourceRoot) {
33633
34014
  const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
33634
- const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path48.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
34015
+ const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path49.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
33635
34016
  if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
33636
34017
  const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
33637
34018
  if (perSkill) {
@@ -33727,11 +34108,11 @@ function classifyClaudeCodeRows(sourceRoot, config, configDir, scope, projectRoo
33727
34108
  function classifyPerSkillSlot(slotPath, sourceRoot) {
33728
34109
  let entries;
33729
34110
  try {
33730
- const stat = fs47.lstatSync(slotPath);
34111
+ const stat = fs48.lstatSync(slotPath);
33731
34112
  if (!stat.isDirectory() || stat.isSymbolicLink()) {
33732
34113
  return null;
33733
34114
  }
33734
- entries = fs47.readdirSync(slotPath, { withFileTypes: true });
34115
+ entries = fs48.readdirSync(slotPath, { withFileTypes: true });
33735
34116
  } catch {
33736
34117
  return null;
33737
34118
  }
@@ -33743,7 +34124,7 @@ function classifyPerSkillSlot(slotPath, sourceRoot) {
33743
34124
  return null;
33744
34125
  }
33745
34126
  const ours = links.filter(
33746
- (entry) => isOurSymlink(path48.join(slotPath, entry.name), sourceRoot)
34127
+ (entry) => isOurSymlink(path49.join(slotPath, entry.name), sourceRoot)
33747
34128
  );
33748
34129
  if (ours.length === 0) {
33749
34130
  return null;
@@ -33755,9 +34136,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
33755
34136
  classifyHooks(settingsPath),
33756
34137
  classifySettings(
33757
34138
  settingsPath,
33758
- path48.resolve(sourceRoot, config.source.settings)
34139
+ path49.resolve(sourceRoot, config.source.settings)
33759
34140
  ),
33760
- classifyMcp(claudeJsonPath, path48.resolve(sourceRoot, config.source.mcp))
34141
+ classifyMcp(claudeJsonPath, path49.resolve(sourceRoot, config.source.mcp))
33761
34142
  ];
33762
34143
  }
33763
34144
  function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
@@ -33854,14 +34235,14 @@ function classifyMcp(filePath, sourcePath) {
33854
34235
  }
33855
34236
  function isSymlinkCurrent(linkPath, sourcePath) {
33856
34237
  try {
33857
- return fs47.realpathSync(linkPath) === fs47.realpathSync(sourcePath);
34238
+ return fs48.realpathSync(linkPath) === fs48.realpathSync(sourcePath);
33858
34239
  } catch {
33859
34240
  return false;
33860
34241
  }
33861
34242
  }
33862
34243
  function isCompiledCurrent6(filePath, sourcePath) {
33863
34244
  try {
33864
- const marker = extractProvenanceMarker(fs47.readFileSync(filePath, "utf8"));
34245
+ const marker = extractProvenanceMarker(fs48.readFileSync(filePath, "utf8"));
33865
34246
  return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
33866
34247
  } catch {
33867
34248
  return false;
@@ -33891,7 +34272,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
33891
34272
  }
33892
34273
  function readCompiledContent(filePath) {
33893
34274
  try {
33894
- return fs47.readFileSync(filePath, "utf8");
34275
+ return fs48.readFileSync(filePath, "utf8");
33895
34276
  } catch {
33896
34277
  return null;
33897
34278
  }
@@ -33922,8 +34303,8 @@ function hashString6(value) {
33922
34303
  }
33923
34304
 
33924
34305
  // src/commands/sync.ts
33925
- import fs48 from "fs";
33926
- import path49 from "path";
34306
+ import fs49 from "fs";
34307
+ import path50 from "path";
33927
34308
 
33928
34309
  // node_modules/chalk/source/vendor/ansi-styles/index.js
33929
34310
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -34593,29 +34974,41 @@ async function runSyncCommand(options, logger) {
34593
34974
  reportHookRejections(
34594
34975
  lossReport,
34595
34976
  targets,
34596
- path49.resolve(kitInfo.path, "hooks"),
34977
+ path50.resolve(kitInfo.path, "hooks"),
34597
34978
  kitInfo.components.hooks.declared
34598
34979
  );
34599
34980
  const hooksConflict = reportHooksSourceConflict(
34600
34981
  lossReport,
34601
34982
  targets,
34602
- path49.resolve(kitInfo.path, "hooks"),
34983
+ path50.resolve(kitInfo.path, "hooks"),
34603
34984
  kitInfo.components.hooks.declared
34604
34985
  );
34605
34986
  if (hooksConflict) {
34606
34987
  logger.warn(hooksConflict);
34607
34988
  }
34608
34989
  if (allMappings) {
34990
+ const instructionsByTarget = instructionsByActiveTarget(
34991
+ targets,
34992
+ syncOptions.scope,
34993
+ syncOptions.projectRoot,
34994
+ allMappings
34995
+ );
34996
+ const rulesCoverage = measureRulesCoverage(
34997
+ targets,
34998
+ kitInfo.components.rules.declared,
34999
+ syncOptions.scope,
35000
+ syncOptions.projectRoot,
35001
+ allMappings,
35002
+ lossReport,
35003
+ instructionsByTarget
35004
+ );
34609
35005
  reportContestedInstructions(
34610
- instructionsByActiveTarget(
34611
- targets,
34612
- syncOptions.scope,
34613
- syncOptions.projectRoot,
34614
- allMappings
34615
- ),
35006
+ instructionsByTarget,
34616
35007
  kitInfo.components.rules.declared.length > 0,
34617
- logger
35008
+ logger,
35009
+ missingRulesByTarget(rulesCoverage)
34618
35010
  );
35011
+ reportRulesCoverage(rulesCoverage, logger);
34619
35012
  }
34620
35013
  }
34621
35014
  writeLossReport(options.lossReport, lossReport);
@@ -34802,8 +35195,8 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
34802
35195
  }
34803
35196
  }
34804
35197
  function resolveKitFilePath(kitPath, relativePath) {
34805
- const fullPath = path49.join(kitPath, relativePath);
34806
- return fs48.existsSync(fullPath) ? fullPath : null;
35198
+ const fullPath = path50.join(kitPath, relativePath);
35199
+ return fs49.existsSync(fullPath) ? fullPath : null;
34807
35200
  }
34808
35201
  function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
34809
35202
  if (removedSourcePaths.length === 0 || !mappings) {
@@ -34866,9 +35259,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34866
35259
  }
34867
35260
  if (relativePath.startsWith("agents/")) {
34868
35261
  removeManagedCompiledArtifact2(
34869
- path49.join(
35262
+ path50.join(
34870
35263
  resolveTargetPath(paths.agents ?? ""),
34871
- `${path49.parse(relativePath).name}.agent.md`
35264
+ `${path50.parse(relativePath).name}.agent.md`
34872
35265
  ),
34873
35266
  "copilot",
34874
35267
  relativePath,
@@ -34878,9 +35271,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34878
35271
  }
34879
35272
  if (relativePath.startsWith("commands/")) {
34880
35273
  removeManagedCompiledArtifact2(
34881
- path49.join(
35274
+ path50.join(
34882
35275
  resolveTargetPath(paths.prompts ?? ""),
34883
- `${path49.parse(relativePath).name}.prompt.md`
35276
+ `${path50.parse(relativePath).name}.prompt.md`
34884
35277
  ),
34885
35278
  "copilot",
34886
35279
  relativePath,
@@ -34890,7 +35283,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34890
35283
  }
34891
35284
  if (relativePath.endsWith("hooks.json")) {
34892
35285
  removeManagedCompiledArtifact2(
34893
- path49.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
35286
+ path50.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
34894
35287
  "copilot",
34895
35288
  relativePath,
34896
35289
  logger
@@ -34920,9 +35313,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
34920
35313
  }
34921
35314
  if (relativePath.startsWith("agents/")) {
34922
35315
  removeManagedCompiledArtifact2(
34923
- path49.join(
35316
+ path50.join(
34924
35317
  resolveTargetPath(paths.agents ?? ""),
34925
- `${path49.parse(relativePath).name}.toml`
35318
+ `${path50.parse(relativePath).name}.toml`
34926
35319
  ),
34927
35320
  "codex",
34928
35321
  relativePath,
@@ -34932,9 +35325,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
34932
35325
  }
34933
35326
  if (relativePath.startsWith("rules/")) {
34934
35327
  removeManagedCompiledArtifact2(
34935
- path49.join(
35328
+ path50.join(
34936
35329
  resolveTargetPath(paths.rules ?? ""),
34937
- `${path49.parse(relativePath).name}.rules`
35330
+ `${path50.parse(relativePath).name}.rules`
34938
35331
  ),
34939
35332
  "codex",
34940
35333
  relativePath,
@@ -34973,9 +35366,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
34973
35366
  }
34974
35367
  if (relativePath.startsWith("agents/")) {
34975
35368
  removeManagedCompiledArtifact2(
34976
- path49.join(
35369
+ path50.join(
34977
35370
  resolveTargetPath(paths.agents ?? ""),
34978
- `${path49.parse(relativePath).name}.md`
35371
+ `${path50.parse(relativePath).name}.md`
34979
35372
  ),
34980
35373
  "opencode",
34981
35374
  relativePath,
@@ -34985,9 +35378,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
34985
35378
  }
34986
35379
  if (relativePath.startsWith("commands/")) {
34987
35380
  removeManagedCompiledArtifact2(
34988
- path49.join(
35381
+ path50.join(
34989
35382
  resolveTargetPath(paths.commands ?? ""),
34990
- `${path49.parse(relativePath).name}.md`
35383
+ `${path50.parse(relativePath).name}.md`
34991
35384
  ),
34992
35385
  "opencode",
34993
35386
  relativePath,
@@ -35019,9 +35412,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35019
35412
  }
35020
35413
  if (relativePath.startsWith("agents/")) {
35021
35414
  removeManagedCompiledArtifact2(
35022
- path49.join(
35415
+ path50.join(
35023
35416
  resolveTargetPath(paths.agents ?? ""),
35024
- `${path49.parse(relativePath).name}.md`
35417
+ `${path50.parse(relativePath).name}.md`
35025
35418
  ),
35026
35419
  "cursor",
35027
35420
  relativePath,
@@ -35031,9 +35424,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35031
35424
  }
35032
35425
  if (relativePath.startsWith("rules/")) {
35033
35426
  removeManagedCompiledArtifact2(
35034
- path49.join(
35427
+ path50.join(
35035
35428
  resolveTargetPath(paths.rules ?? ""),
35036
- `${path49.parse(relativePath).name}.mdc`
35429
+ `${path50.parse(relativePath).name}.mdc`
35037
35430
  ),
35038
35431
  "cursor",
35039
35432
  relativePath,
@@ -35043,9 +35436,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35043
35436
  }
35044
35437
  if (relativePath.startsWith("commands/")) {
35045
35438
  removeManagedCompiledArtifact2(
35046
- path49.join(
35439
+ path50.join(
35047
35440
  resolveTargetPath(paths.skills ?? ""),
35048
- path49.parse(relativePath).name,
35441
+ path50.parse(relativePath).name,
35049
35442
  "SKILL.md"
35050
35443
  ),
35051
35444
  "cursor",
@@ -35089,9 +35482,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35089
35482
  }
35090
35483
  if (relativePath.startsWith("rules/")) {
35091
35484
  removeManagedCompiledArtifact2(
35092
- path49.join(
35485
+ path50.join(
35093
35486
  resolveTargetPath(paths.rules ?? ""),
35094
- `${path49.parse(relativePath).name}.md`
35487
+ `${path50.parse(relativePath).name}.md`
35095
35488
  ),
35096
35489
  "cline",
35097
35490
  relativePath,
@@ -35101,9 +35494,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35101
35494
  }
35102
35495
  if (relativePath.startsWith("commands/")) {
35103
35496
  removeManagedCompiledArtifact2(
35104
- path49.join(
35497
+ path50.join(
35105
35498
  resolveTargetPath(paths.workflows ?? ""),
35106
- path49.basename(relativePath)
35499
+ path50.basename(relativePath)
35107
35500
  ),
35108
35501
  "cline",
35109
35502
  relativePath,
@@ -35121,17 +35514,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35121
35514
  }
35122
35515
  }
35123
35516
  function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
35124
- if (!fs48.existsSync(artifactPath)) {
35517
+ if (!fs49.existsSync(artifactPath)) {
35125
35518
  return;
35126
35519
  }
35127
- if (!fs48.statSync(artifactPath).isFile()) {
35520
+ if (!fs49.statSync(artifactPath).isFile()) {
35128
35521
  return;
35129
35522
  }
35130
- const marker = extractProvenanceMarker(fs48.readFileSync(artifactPath, "utf8"));
35523
+ const marker = extractProvenanceMarker(fs49.readFileSync(artifactPath, "utf8"));
35131
35524
  if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
35132
35525
  return;
35133
35526
  }
35134
- fs48.rmSync(artifactPath, { force: true });
35527
+ fs49.rmSync(artifactPath, { force: true });
35135
35528
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
35136
35529
  }
35137
35530
  function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
@@ -35162,10 +35555,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
35162
35555
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
35163
35556
  }
35164
35557
  function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
35165
- if (!fs48.existsSync(artifactPath)) {
35558
+ if (!fs49.existsSync(artifactPath)) {
35166
35559
  return;
35167
35560
  }
35168
- const content = fs48.readFileSync(artifactPath, "utf8");
35561
+ const content = fs49.readFileSync(artifactPath, "utf8");
35169
35562
  const startMarker = "# tangyr: managed mcp start";
35170
35563
  const endMarker = "# tangyr: managed mcp end";
35171
35564
  const startIndex = content.indexOf(startMarker);
@@ -35182,19 +35575,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
35182
35575
  const after = content.slice(endIndex + endMarker.length).trimStart();
35183
35576
  const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
35184
35577
  if (cleaned.length === 0) {
35185
- fs48.rmSync(artifactPath, { force: true });
35578
+ fs49.rmSync(artifactPath, { force: true });
35186
35579
  } else {
35187
- fs48.writeFileSync(artifactPath, `${cleaned}
35580
+ fs49.writeFileSync(artifactPath, `${cleaned}
35188
35581
  `);
35189
35582
  }
35190
35583
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
35191
35584
  }
35192
35585
  function readJsonObject5(filePath) {
35193
- if (!fs48.existsSync(filePath)) {
35586
+ if (!fs49.existsSync(filePath)) {
35194
35587
  return null;
35195
35588
  }
35196
35589
  try {
35197
- const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
35590
+ const parsed = JSON.parse(fs49.readFileSync(filePath, "utf8"));
35198
35591
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
35199
35592
  } catch {
35200
35593
  return null;
@@ -35208,10 +35601,10 @@ function readJsonMetadata(value) {
35208
35601
  }
35209
35602
  function writeJsonOrRemove2(filePath, parsed) {
35210
35603
  if (isEmptyJsonValue2(parsed)) {
35211
- fs48.rmSync(filePath, { force: true });
35604
+ fs49.rmSync(filePath, { force: true });
35212
35605
  return;
35213
35606
  }
35214
- fs48.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
35607
+ fs49.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
35215
35608
  `);
35216
35609
  }
35217
35610
  function isEmptyJsonValue2(value) {
@@ -35271,8 +35664,8 @@ function removeManagedHookEntries(value, expectedSource) {
35271
35664
  }
35272
35665
 
35273
35666
  // src/commands/validate.ts
35274
- import fs49 from "fs";
35275
- import path50 from "path";
35667
+ import fs50 from "fs";
35668
+ import path51 from "path";
35276
35669
  var SUPPORTED_KIT_FORMATS2 = [1];
35277
35670
  var SUPPORTED_DISCIPLINE_VERSIONS = [
35278
35671
  "0.14.0",
@@ -35387,12 +35780,12 @@ function checkArchetype(kit) {
35387
35780
  }
35388
35781
  function checkHookScriptsExist(kit) {
35389
35782
  const violations = [];
35390
- const hooksDir = path50.join(kit.path, "hooks");
35783
+ const hooksDir = path51.join(kit.path, "hooks");
35391
35784
  const missingSet = new Set(kit.components.hooks.missing);
35392
35785
  for (const name of kit.components.hooks.declared) {
35393
35786
  if (missingSet.has(name)) continue;
35394
- const declarationPath = path50.join(hooksDir, `${name}.md`);
35395
- if (!fs49.existsSync(declarationPath)) continue;
35787
+ const declarationPath = path51.join(hooksDir, `${name}.md`);
35788
+ if (!fs50.existsSync(declarationPath)) continue;
35396
35789
  let data;
35397
35790
  try {
35398
35791
  ({ data } = parseMarkdownFrontmatter(declarationPath));
@@ -35402,8 +35795,8 @@ function checkHookScriptsExist(kit) {
35402
35795
  if (typeof data.command === "string" && data.command.trim().length > 0) {
35403
35796
  continue;
35404
35797
  }
35405
- const scriptPath = path50.join(hooksDir, "scripts", `${name}.ts`);
35406
- if (!fs49.existsSync(scriptPath)) {
35798
+ const scriptPath = path51.join(hooksDir, "scripts", `${name}.ts`);
35799
+ if (!fs50.existsSync(scriptPath)) {
35407
35800
  violations.push({
35408
35801
  code: "hook-script-missing",
35409
35802
  location: `hooks/scripts/${name}.ts`,
@@ -35416,10 +35809,10 @@ function checkHookScriptsExist(kit) {
35416
35809
  function checkOptionalSourceDocuments(kit) {
35417
35810
  const violations = [];
35418
35811
  for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
35419
- const filePath = path50.join(kit.path, name);
35420
- if (!fs49.existsSync(filePath)) continue;
35812
+ const filePath = path51.join(kit.path, name);
35813
+ if (!fs50.existsSync(filePath)) continue;
35421
35814
  try {
35422
- const parsed = JSON.parse(fs49.readFileSync(filePath, "utf8"));
35815
+ const parsed = JSON.parse(fs50.readFileSync(filePath, "utf8"));
35423
35816
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
35424
35817
  violations.push({
35425
35818
  code: "optional-source-malformed",
@@ -35441,10 +35834,10 @@ function checkSkillSubfolderNames(kit) {
35441
35834
  const notices = [];
35442
35835
  const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
35443
35836
  for (const name of kit.components.skills.declared) {
35444
- const skillDir = path50.join(kit.path, "skills", name);
35837
+ const skillDir = path51.join(kit.path, "skills", name);
35445
35838
  let entries;
35446
35839
  try {
35447
- entries = fs49.readdirSync(skillDir, { withFileTypes: true });
35840
+ entries = fs50.readdirSync(skillDir, { withFileTypes: true });
35448
35841
  } catch {
35449
35842
  continue;
35450
35843
  }
@@ -35462,7 +35855,7 @@ function checkSkillSubfolderNames(kit) {
35462
35855
  return notices;
35463
35856
  }
35464
35857
  function checkHooksSourceForm(kit) {
35465
- const hooksDir = path50.join(kit.path, "hooks");
35858
+ const hooksDir = path51.join(kit.path, "hooks");
35466
35859
  const message = describeHooksSourceConflict(
35467
35860
  hooksDir,
35468
35861
  kit.components.hooks.declared
@@ -35474,12 +35867,12 @@ function checkHooksSourceForm(kit) {
35474
35867
  } : null;
35475
35868
  }
35476
35869
  function checkHookDeclarations(kit) {
35477
- const hooksDir = path50.join(kit.path, "hooks");
35870
+ const hooksDir = path51.join(kit.path, "hooks");
35478
35871
  return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
35479
35872
  (r) => ({
35480
35873
  code: "hook-declaration-invalid",
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.`
35874
+ location: `hooks/${path51.basename(r.file)}`,
35875
+ message: `hooks: '${path51.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.`
35483
35876
  })
35484
35877
  );
35485
35878
  }
@@ -35499,11 +35892,11 @@ function checkKitFormatSupported(kit) {
35499
35892
  function checkEntrypointExists(kit) {
35500
35893
  const declared = kit.entrypoint;
35501
35894
  const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
35502
- const entrypointPath = path50.join(kit.path, entrypoint);
35503
- if (fs49.existsSync(entrypointPath)) {
35895
+ const entrypointPath = path51.join(kit.path, entrypoint);
35896
+ if (fs50.existsSync(entrypointPath)) {
35504
35897
  return null;
35505
35898
  }
35506
- const legacyPresent = declared === void 0 && fs49.existsSync(path50.join(kit.path, LEGACY_ENTRYPOINT));
35899
+ const legacyPresent = declared === void 0 && fs50.existsSync(path51.join(kit.path, LEGACY_ENTRYPOINT));
35507
35900
  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.`;
35508
35901
  return {
35509
35902
  code: "entrypoint-missing",
@@ -35562,9 +35955,9 @@ function checkComponentFrontmatter(kit) {
35562
35955
  const missingSet = new Set(kit.components[cat].missing);
35563
35956
  for (const name of kit.components[cat].declared) {
35564
35957
  if (missingSet.has(name)) continue;
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);
35958
+ const filePath = cat === "skills" ? path51.join(kit.path, cat, name, "SKILL.md") : path51.join(kit.path, cat, `${name}.md`);
35959
+ if (!fs50.existsSync(filePath)) continue;
35960
+ const relPath = path51.relative(kit.path, filePath);
35568
35961
  try {
35569
35962
  const { data } = parseMarkdownFrontmatter(filePath);
35570
35963
  for (const field of requiredFields) {
@@ -35589,10 +35982,10 @@ function checkComponentFrontmatter(kit) {
35589
35982
  }
35590
35983
  function checkReservedRootNames(kit) {
35591
35984
  const violations = [];
35592
- if (!fs49.existsSync(kit.path) || !fs49.statSync(kit.path).isDirectory()) {
35985
+ if (!fs50.existsSync(kit.path) || !fs50.statSync(kit.path).isDirectory()) {
35593
35986
  return violations;
35594
35987
  }
35595
- const entries = fs49.readdirSync(kit.path, { withFileTypes: true });
35988
+ const entries = fs50.readdirSync(kit.path, { withFileTypes: true });
35596
35989
  for (const entry of entries) {
35597
35990
  if (RESERVED_ROOT_NAMES.includes(entry.name)) {
35598
35991
  violations.push({
@@ -35609,8 +36002,8 @@ function checkHumanOnlyCommandInvocation(kit) {
35609
36002
  const missingSet = new Set(kit.components.commands.missing);
35610
36003
  for (const name of kit.components.commands.declared) {
35611
36004
  if (missingSet.has(name)) continue;
35612
- const filePath = path50.join(kit.path, "commands", `${name}.md`);
35613
- if (!fs49.existsSync(filePath)) continue;
36005
+ const filePath = path51.join(kit.path, "commands", `${name}.md`);
36006
+ if (!fs50.existsSync(filePath)) continue;
35614
36007
  let data;
35615
36008
  try {
35616
36009
  ({ data } = parseMarkdownFrontmatter(filePath));
@@ -35623,7 +36016,7 @@ function checkHumanOnlyCommandInvocation(kit) {
35623
36016
  if (!barred) {
35624
36017
  violations.push({
35625
36018
  code: "command-human-only-model-invocable",
35626
- location: path50.relative(kit.path, filePath),
36019
+ location: path51.relative(kit.path, filePath),
35627
36020
  message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
35628
36021
  });
35629
36022
  }
@@ -35632,8 +36025,8 @@ function checkHumanOnlyCommandInvocation(kit) {
35632
36025
  }
35633
36026
 
35634
36027
  // src/commands/verify.ts
35635
- import fs50 from "fs";
35636
- import path51 from "path";
36028
+ import fs51 from "fs";
36029
+ import path52 from "path";
35637
36030
  function runVerifyCommand(options, logger) {
35638
36031
  if (options.target && !isKnownTarget(options.target)) {
35639
36032
  throwUnrecognizedTarget(options.target);
@@ -35814,8 +36207,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
35814
36207
  if (!slotPath) {
35815
36208
  continue;
35816
36209
  }
35817
- const fullPath = subPath ? path51.join(slotPath, subPath) : slotPath;
35818
- if (!fs50.existsSync(fullPath)) {
36210
+ const fullPath = subPath ? path52.join(slotPath, subPath) : slotPath;
36211
+ if (!fs51.existsSync(fullPath)) {
35819
36212
  failures.push(
35820
36213
  `claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
35821
36214
  );