@alessandroraffa/tangyr 4.1.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1372,8 +1372,8 @@ var require_command = __commonJS({
1372
1372
  "use strict";
1373
1373
  var EventEmitter = __require("events").EventEmitter;
1374
1374
  var childProcess = __require("child_process");
1375
- var 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":
@@ -21625,6 +21625,19 @@ var lossSeverityByEntryType = {
21625
21625
  "rule-as-instruction": "info",
21626
21626
  "rule-mode-downgrade": "warning",
21627
21627
  "rule-path-scoping": "warning",
21628
+ // The rule is not there. Measured on the files each target reads, after every
21629
+ // target has written, so this says what arrived rather than what a compiler
21630
+ // intended — the two have disagreed, most often where several targets write
21631
+ // one instructions file and only the last writer's content survives.
21632
+ //
21633
+ // Error by the severity ladder's own definition: `warning` is "a real
21634
+ // reduction in fidelity that still produces a working artifact", and an
21635
+ // absent rule is not reduced, it is absent. `error` is "an intent that could
21636
+ // not be emitted at all and requires a manual step or a kit change", which is
21637
+ // exactly the remedy the run prints: give the target an instructions path of
21638
+ // its own, or disable it. `acceptedLoss` is how a project that has decided to
21639
+ // live with it says so.
21640
+ "rule-not-delivered": "error",
21628
21641
  "hook-event-drop": "warning",
21629
21642
  // A declaration the parser refuses installs nothing, anywhere, and used to
21630
21643
  // do so silently. Error severity is what makes install and sync exit 3.
@@ -21991,7 +22004,7 @@ function reportHooksSourceConflict(report, targets, hooksDir, hookNames) {
21991
22004
 
21992
22005
  // src/adapters/hook-scripts-bridge.ts
21993
22006
  import fs25 from "fs";
21994
- import path22 from "path";
22007
+ import path23 from "path";
21995
22008
 
21996
22009
  // src/utils/fs.ts
21997
22010
  import fs23 from "fs";
@@ -22121,8 +22134,62 @@ function compareArtifactState(recorded, artifactPath) {
22121
22134
  return current === recorded ? "current" : "modified";
22122
22135
  }
22123
22136
 
22137
+ // src/core/shared-artifacts.ts
22138
+ import path22 from "path";
22139
+ var SHARED_NAMESPACE = "shared";
22140
+ var SHARED_INSTRUCTIONS_KEY = `${SHARED_NAMESPACE}/AGENTS.md`;
22141
+ var SHARED_INSTRUCTIONS_FILE = "AGENTS.md";
22142
+ var SHARED_HOOK_SCRIPTS_KEY = `${SHARED_NAMESPACE}/hook_scripts`;
22143
+ function sharedArtifactKey(destination, scope, projectRoot) {
22144
+ if (scope !== "project") {
22145
+ return null;
22146
+ }
22147
+ const root = projectRoot ?? process.cwd();
22148
+ const shared = path22.resolve(root, SHARED_INSTRUCTIONS_FILE);
22149
+ return path22.resolve(destination) === shared ? SHARED_INSTRUCTIONS_KEY : null;
22150
+ }
22151
+ function resolveSharedArtifactKey(key, scope, projectRoot) {
22152
+ if (key !== SHARED_INSTRUCTIONS_KEY || scope !== "project") {
22153
+ return null;
22154
+ }
22155
+ return path22.join(projectRoot ?? process.cwd(), SHARED_INSTRUCTIONS_FILE);
22156
+ }
22157
+ var SHARED_SKILLS_PREFIX = `${SHARED_NAMESPACE}/skills`;
22158
+ function sharedKeyForDestination(destination, scope, projectRoot, platformPaths) {
22159
+ const instructions = sharedArtifactKey(destination, scope, projectRoot);
22160
+ if (instructions) {
22161
+ return instructions;
22162
+ }
22163
+ const resolved = path22.resolve(destination);
22164
+ let profiles;
22165
+ try {
22166
+ profiles = resolveTargetPaths({
22167
+ scope,
22168
+ projectRoot,
22169
+ mappings: platformPaths
22170
+ });
22171
+ } catch {
22172
+ return null;
22173
+ }
22174
+ if (resolved === path22.resolve(profiles.codex.hook_scripts)) {
22175
+ return SHARED_HOOK_SCRIPTS_KEY;
22176
+ }
22177
+ const skillsRoot = path22.resolve(profiles.opencode.skills_shared);
22178
+ if (resolved.startsWith(`${skillsRoot}${path22.sep}`)) {
22179
+ const inside = path22.relative(skillsRoot, resolved).split(path22.sep).join("/");
22180
+ return `${SHARED_SKILLS_PREFIX}/${inside}`;
22181
+ }
22182
+ return null;
22183
+ }
22184
+ function resolveSharedSkillsKey(key, sharedSkillsRoot) {
22185
+ if (!key.startsWith(`${SHARED_SKILLS_PREFIX}/`) || !sharedSkillsRoot) {
22186
+ return null;
22187
+ }
22188
+ const inside = key.slice(SHARED_SKILLS_PREFIX.length + 1);
22189
+ return path22.join(sharedSkillsRoot, ...inside.split("/"));
22190
+ }
22191
+
22124
22192
  // src/adapters/hook-scripts-bridge.ts
22125
- var SHARED_HOOK_SCRIPTS_KEY = "shared/hook_scripts";
22126
22193
  function syncHookScriptsBridge(args) {
22127
22194
  const { source, destination, config, sourceRoot, options, logger } = args;
22128
22195
  if (!fs25.existsSync(source)) {
@@ -22147,7 +22214,7 @@ function syncHookScriptsBridge(args) {
22147
22214
  } else if (artifactClass === "managed-symlink") {
22148
22215
  fs25.unlinkSync(destination);
22149
22216
  }
22150
- ensureDir(path22.dirname(destination));
22217
+ ensureDir(path23.dirname(destination));
22151
22218
  createRelativeSymlink(source, destination, "dir");
22152
22219
  if (args.manifest) {
22153
22220
  const state = describeArtifactState(destination);
@@ -22176,26 +22243,6 @@ function isSymlinkTo(linkPath, source) {
22176
22243
  }
22177
22244
  }
22178
22245
 
22179
- // src/core/shared-artifacts.ts
22180
- import path23 from "path";
22181
- var SHARED_NAMESPACE = "shared";
22182
- var SHARED_INSTRUCTIONS_KEY = `${SHARED_NAMESPACE}/AGENTS.md`;
22183
- var SHARED_INSTRUCTIONS_FILE = "AGENTS.md";
22184
- function sharedArtifactKey(destination, scope, projectRoot) {
22185
- if (scope !== "project") {
22186
- return null;
22187
- }
22188
- const root = projectRoot ?? process.cwd();
22189
- const shared = path23.resolve(root, SHARED_INSTRUCTIONS_FILE);
22190
- return path23.resolve(destination) === shared ? SHARED_INSTRUCTIONS_KEY : null;
22191
- }
22192
- function resolveSharedArtifactKey(key, scope, projectRoot) {
22193
- if (key !== SHARED_INSTRUCTIONS_KEY || scope !== "project") {
22194
- return null;
22195
- }
22196
- return path23.join(projectRoot ?? process.cwd(), SHARED_INSTRUCTIONS_FILE);
22197
- }
22198
-
22199
22246
  // src/core/remove.ts
22200
22247
  import fs26 from "fs";
22201
22248
  function removeManagedPath(managedPath) {
@@ -22316,6 +22363,7 @@ async function runUninstallCommand(options, logger) {
22316
22363
  const claudeRoots = scope === "global" && selectedTools.has("claude-code") ? resolveClaudeRootsForUninstall(manifest, runtime) : [];
22317
22364
  let removedCount = 0;
22318
22365
  const removedParentDirs = /* @__PURE__ */ new Set();
22366
+ const keptSurfaces = [];
22319
22367
  for (const file of useManifestPathRemoval ? manifestArtifacts : []) {
22320
22368
  if (isMergeSurfaceKey(file.relativePath)) {
22321
22369
  const surfacePath = file.path ?? resolveManifestKeyToPath(
@@ -22327,6 +22375,9 @@ async function runUninstallCommand(options, logger) {
22327
22375
  if (surfacePath && stripTangyrFromMergeSurface(surfacePath, logger)) {
22328
22376
  removedParentDirs.add(path24.dirname(surfacePath));
22329
22377
  removedCount++;
22378
+ if (fs27.existsSync(surfacePath)) {
22379
+ keptSurfaces.push(surfacePath);
22380
+ }
22330
22381
  } else {
22331
22382
  logger.verbose(
22332
22383
  ` left in place (merge surface, nothing of ours in it): ${surfacePath ?? file.relativePath}`
@@ -22429,10 +22480,6 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
22429
22480
  logger.verbose(` removed manifest: ${manifestPath}`);
22430
22481
  }
22431
22482
  pruneEmptyDirs(path24.join(scopePath, "backups"), logger);
22432
- const pruneBoundary = path24.dirname(scopePath);
22433
- for (const dir of removedParentDirs) {
22434
- pruneEmptyAncestors(dir, pruneBoundary, logger);
22435
- }
22436
22483
  try {
22437
22484
  const remaining = fs27.readdirSync(scopePath);
22438
22485
  if (remaining.length === 0) {
@@ -22455,6 +22502,22 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
22455
22502
  } else {
22456
22503
  logger.verbose(" no manifest to update after partial residue cleanup");
22457
22504
  }
22505
+ const pruneBoundary = path24.dirname(scopePath);
22506
+ for (const dir of removedParentDirs) {
22507
+ pruneEmptyAncestors(dir, pruneBoundary, logger);
22508
+ }
22509
+ if (keptSurfaces.length > 0) {
22510
+ logger.warn(
22511
+ `
22512
+ ${String(keptSurfaces.length)} shared file(s) kept, with Tangyr's own block removed from each:`
22513
+ );
22514
+ for (const surface of keptSurfaces) {
22515
+ logger.warn(` ${surface}`);
22516
+ }
22517
+ logger.warn(
22518
+ " 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."
22519
+ );
22520
+ }
22458
22521
  logger.info(`
22459
22522
  Uninstallation complete: ${removedCount} file(s) removed.`);
22460
22523
  }
@@ -22470,6 +22533,13 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
22470
22533
  if (component === "hook_scripts") {
22471
22534
  return resolveSharedHookScriptsPath(runtime, scope, projectRoot);
22472
22535
  }
22536
+ const sharedSkill = resolveSharedSkillsKey(
22537
+ key,
22538
+ resolveSharedSkillsPath(runtime, scope, projectRoot)
22539
+ );
22540
+ if (sharedSkill) {
22541
+ return sharedSkill;
22542
+ }
22473
22543
  return resolveSharedArtifactKey(key, scope, projectRoot);
22474
22544
  }
22475
22545
  if (tool === "claude-code") {
@@ -23867,6 +23937,27 @@ function resolveSharedHookScriptsPath(runtime, scope, projectRoot) {
23867
23937
  }
23868
23938
  return resolveTargetPath("~/.agents/hooks");
23869
23939
  }
23940
+ function resolveSharedSkillsPath(runtime, scope, projectRoot) {
23941
+ if (runtime) {
23942
+ try {
23943
+ const mappings = loadMappings(
23944
+ runtime.sourceRoot,
23945
+ runtime.config,
23946
+ runtime.configDir
23947
+ );
23948
+ return resolveTargetPaths({
23949
+ scope,
23950
+ projectRoot,
23951
+ mappings: mappings.platformPaths
23952
+ }).opencode.skills_shared;
23953
+ } catch {
23954
+ }
23955
+ }
23956
+ if (scope === "project") {
23957
+ return path24.join(projectRoot ?? process.cwd(), ".agents", "skills");
23958
+ }
23959
+ return resolveTargetPath("~/.agents/skills");
23960
+ }
23870
23961
  function resolveOpenCodePaths(runtime, scope = "global", projectRoot) {
23871
23962
  if (runtime) {
23872
23963
  try {
@@ -25223,8 +25314,8 @@ function toConflictPolicy2(value) {
25223
25314
  }
25224
25315
 
25225
25316
  // src/commands/install.ts
25226
- import fs45 from "fs";
25227
- import path45 from "path";
25317
+ import fs46 from "fs";
25318
+ import path46 from "path";
25228
25319
 
25229
25320
  // src/core/channel-state.ts
25230
25321
  import fs32 from "fs";
@@ -26171,12 +26262,15 @@ function findContestedInstructions(instructionsByTarget) {
26171
26262
  }
26172
26263
  return contested;
26173
26264
  }
26174
- function reportContestedInstructions(instructionsByTarget, kitDeclaresRules, logger) {
26265
+ function reportContestedInstructions(instructionsByTarget, kitDeclaresRules, logger, missingByTarget) {
26175
26266
  if (!kitDeclaresRules) {
26176
26267
  return;
26177
26268
  }
26178
26269
  for (const contested of findContestedInstructions(instructionsByTarget)) {
26179
- if (contested.losers.length === 0) {
26270
+ const losers = missingByTarget ? contested.losers.filter(
26271
+ (target) => (missingByTarget.get(target)?.length ?? 0) > 0
26272
+ ) : contested.losers;
26273
+ if (losers.length === 0) {
26180
26274
  continue;
26181
26275
  }
26182
26276
  logger.warn(
@@ -26186,7 +26280,7 @@ ${contested.destination} is the instructions file for ${contested.claimants.join
26186
26280
  if (contested.survivor) {
26187
26281
  logger.warn(` The content on disk is ${contested.survivor}'s.`);
26188
26282
  }
26189
- for (const target of contested.losers) {
26283
+ for (const target of losers) {
26190
26284
  logger.warn(
26191
26285
  ` ${target} does NOT get its rules: ${FOLDS_RULES_INTO_INSTRUCTIONS[target]}, and that content is overwritten here.`
26192
26286
  );
@@ -26209,12 +26303,161 @@ function instructionsByActiveTarget(tools, scope, projectRoot, mappings) {
26209
26303
  byTarget.set(tool, instructions);
26210
26304
  }
26211
26305
  }
26306
+ if (scope === "project" && projectRoot && tools.includes("copilot")) {
26307
+ byTarget.set("copilot", path31.join(projectRoot, "AGENTS.md"));
26308
+ }
26212
26309
  return byTarget;
26213
26310
  }
26214
26311
 
26312
+ // src/core/rules-coverage.ts
26313
+ import fs35 from "fs";
26314
+ import path32 from "path";
26315
+ function readingSurfaces(profile) {
26316
+ const record = profile;
26317
+ return {
26318
+ slot: typeof record?.rules === "string" ? record.rules : null,
26319
+ instructions: typeof record?.instructions === "string" ? record.instructions : null
26320
+ };
26321
+ }
26322
+ function inRulesSlot(slot, rule) {
26323
+ let entries;
26324
+ try {
26325
+ entries = fs35.readdirSync(slot);
26326
+ } catch {
26327
+ return false;
26328
+ }
26329
+ return entries.some(
26330
+ (entry) => entry === rule || entry.startsWith(`${rule}.`)
26331
+ );
26332
+ }
26333
+ function inInstructions(instructions, rule) {
26334
+ let content;
26335
+ try {
26336
+ content = fs35.readFileSync(instructions, "utf8");
26337
+ } catch {
26338
+ return false;
26339
+ }
26340
+ return content.split("\n").some((line) => line.trim() === `## ${rule}`);
26341
+ }
26342
+ function recordedRulesLoss(lossReport, target) {
26343
+ const entries = lossReport.targets[target]?.rules ?? [];
26344
+ for (const artifact of entries) {
26345
+ for (const field of artifact.fields) {
26346
+ if (field.detail.length > 0) {
26347
+ return field.detail;
26348
+ }
26349
+ }
26350
+ }
26351
+ return null;
26352
+ }
26353
+ function measureRulesCoverage(tools, declaredRules, scope, projectRoot, mappings, lossReport, instructionsByTarget) {
26354
+ const resolved = resolveTargetPaths({
26355
+ scope,
26356
+ projectRoot,
26357
+ mappings: mappings.platformPaths
26358
+ });
26359
+ const contestedByPath = new Map(
26360
+ findContestedInstructions(instructionsByTarget).map((contested) => [
26361
+ contested.destination,
26362
+ contested
26363
+ ])
26364
+ );
26365
+ return tools.map((target) => {
26366
+ const surfaces = readingSurfaces(resolved[target]);
26367
+ const missing = declaredRules.filter((rule) => {
26368
+ if (surfaces.slot && inRulesSlot(surfaces.slot, rule)) {
26369
+ return false;
26370
+ }
26371
+ return !(surfaces.instructions && inInstructions(surfaces.instructions, rule));
26372
+ });
26373
+ return {
26374
+ target,
26375
+ missing,
26376
+ declared: declaredRules.length,
26377
+ reason: missing.length === 0 ? null : explain(target, surfaces, contestedByPath, lossReport, projectRoot)
26378
+ };
26379
+ });
26380
+ }
26381
+ function explain(target, surfaces, contestedByPath, lossReport, projectRoot) {
26382
+ if (surfaces.instructions) {
26383
+ const contested = contestedByPath.get(path32.resolve(surfaces.instructions));
26384
+ if (contested && contested.survivor !== null && contested.survivor !== target) {
26385
+ return `its rules are folded into ${display(surfaces.instructions, projectRoot)}, which ${contested.survivor} wrote last`;
26386
+ }
26387
+ }
26388
+ const recorded = recordedRulesLoss(lossReport, target);
26389
+ if (recorded) {
26390
+ return recorded;
26391
+ }
26392
+ if (!surfaces.slot) {
26393
+ return "it has no rules surface in this scope";
26394
+ }
26395
+ return `not in ${display(surfaces.slot, projectRoot)}, nor folded into the instructions file`;
26396
+ }
26397
+ function display(target, projectRoot) {
26398
+ if (!projectRoot) {
26399
+ return target;
26400
+ }
26401
+ const relative = path32.relative(projectRoot, target);
26402
+ return relative.startsWith("..") ? target : relative;
26403
+ }
26404
+ function reportRulesCoverage(coverage, logger) {
26405
+ if (coverage.length === 0 || coverage[0].declared === 0) {
26406
+ return;
26407
+ }
26408
+ const complete = coverage.every((entry) => entry.missing.length === 0);
26409
+ const say = complete ? (line) => {
26410
+ logger.verbose(line);
26411
+ } : (line) => {
26412
+ logger.warn(line);
26413
+ };
26414
+ const declared = coverage[0].declared;
26415
+ const width = Math.max(...coverage.map((entry) => entry.target.length));
26416
+ say(
26417
+ `
26418
+ Rules reaching each target (${String(declared)} declared, measured on disk):`
26419
+ );
26420
+ for (const entry of coverage) {
26421
+ const delivered = declared - entry.missing.length;
26422
+ const counts = `${String(delivered)}/${String(declared)}`;
26423
+ const head = ` ${entry.target.padEnd(width)} ${counts}`;
26424
+ if (entry.missing.length === 0) {
26425
+ say(head);
26426
+ continue;
26427
+ }
26428
+ say(`${head} missing: ${entry.missing.join(", ")}`);
26429
+ if (entry.reason) {
26430
+ say(` ${" ".repeat(width)} ${entry.reason}`);
26431
+ }
26432
+ }
26433
+ }
26434
+ function missingRulesByTarget(coverage) {
26435
+ return new Map(coverage.map((entry) => [entry.target, entry.missing]));
26436
+ }
26437
+ function recordRulesCoverageLoss(coverage, lossReport) {
26438
+ for (const entry of coverage) {
26439
+ if (entry.missing.length === 0) {
26440
+ continue;
26441
+ }
26442
+ addLoss(lossReport, entry.target, "rules", {
26443
+ source: "rules",
26444
+ fields: entry.missing.map((rule) => ({
26445
+ field: rule,
26446
+ action: "rule-not-delivered",
26447
+ severity: resolveLossSeverity(
26448
+ "agent-field",
26449
+ rule,
26450
+ "rule-not-delivered"
26451
+ ),
26452
+ detail: `${rule}: not readable by ${entry.target}${entry.reason ? ` \u2014 ${entry.reason}` : ""}`
26453
+ }))
26454
+ });
26455
+ }
26456
+ }
26457
+
26215
26458
  // src/adapters/claude-code.ts
26216
- import fs37 from "fs";
26217
- import path35 from "path";
26459
+ import fs38 from "fs";
26460
+ import path36 from "path";
26218
26461
 
26219
26462
  // src/core/shim.ts
26220
26463
  import crypto4 from "crypto";
@@ -26236,8 +26479,8 @@ ${SHIM_BODY}`;
26236
26479
  }
26237
26480
 
26238
26481
  // src/core/skills-slot.ts
26239
- import fs35 from "fs";
26240
- import path32 from "path";
26482
+ import fs36 from "fs";
26483
+ import path33 from "path";
26241
26484
  function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
26242
26485
  if (!isSymlinkPath(destination)) {
26243
26486
  return false;
@@ -26250,7 +26493,7 @@ function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
26250
26493
  }
26251
26494
  function syncSkillsSlot(sync) {
26252
26495
  const { source, destination, logger } = sync;
26253
- if (!fs35.existsSync(source)) {
26496
+ if (!fs36.existsSync(source)) {
26254
26497
  return [
26255
26498
  {
26256
26499
  component: "skills",
@@ -26278,7 +26521,7 @@ function syncSkillsSlot(sync) {
26278
26521
  if (isLegacyWholesaleSymlink) {
26279
26522
  for (const name of foreignSkillNames(source, declaredNames)) {
26280
26523
  logger.info(
26281
- `[dry-run] skills: migrate foreign skill ${path32.join(source, name)} -> ${path32.join(destination, name)}`
26524
+ `[dry-run] skills: migrate foreign skill ${path33.join(source, name)} -> ${path33.join(destination, name)}`
26282
26525
  );
26283
26526
  }
26284
26527
  logger.info(
@@ -26286,9 +26529,9 @@ function syncSkillsSlot(sync) {
26286
26529
  );
26287
26530
  }
26288
26531
  for (const name of declaredNames ?? listSkillDirNames(source)) {
26289
- const skillDestination = path32.join(destination, name);
26532
+ const skillDestination = path33.join(destination, name);
26290
26533
  logger.info(
26291
- `[dry-run] skills: symlink ${path32.join(source, name)} -> ${skillDestination}`
26534
+ `[dry-run] skills: symlink ${path33.join(source, name)} -> ${skillDestination}`
26292
26535
  );
26293
26536
  outcomes2.push({
26294
26537
  component: "skills",
@@ -26315,9 +26558,9 @@ function syncSkillsSlot(sync) {
26315
26558
  }
26316
26559
  function syncSingleSkill(sync, name) {
26317
26560
  const { config, sourceRoot, source, destination } = sync;
26318
- const skillSource = path32.join(source, name);
26319
- const skillDestination = path32.join(destination, name);
26320
- if (!fs35.existsSync(skillSource)) {
26561
+ const skillSource = path33.join(source, name);
26562
+ const skillDestination = path33.join(destination, name);
26563
+ if (!fs36.existsSync(skillSource)) {
26321
26564
  return {
26322
26565
  component: "skills",
26323
26566
  status: "skipped",
@@ -26333,29 +26576,29 @@ function syncSingleSkill(sync, name) {
26333
26576
  };
26334
26577
  }
26335
26578
  if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
26336
- fs35.unlinkSync(skillDestination);
26579
+ fs36.unlinkSync(skillDestination);
26337
26580
  } else if (artifactClass === "unmanaged-conflict" && !sync.onUnmanagedConflict(skillDestination)) {
26338
26581
  return { component: "skills", status: "conflict", path: skillDestination };
26339
26582
  } else if (artifactClass === "managed-symlink") {
26340
- fs35.unlinkSync(skillDestination);
26583
+ fs36.unlinkSync(skillDestination);
26341
26584
  }
26342
26585
  createRelativeSymlink(skillSource, skillDestination, "dir");
26343
26586
  return { component: "skills", status: "success", path: skillDestination };
26344
26587
  }
26345
26588
  function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
26346
26589
  const foreignNames = foreignSkillNames(source, declaredNames);
26347
- fs35.unlinkSync(destination);
26590
+ fs36.unlinkSync(destination);
26348
26591
  ensureDir(destination);
26349
26592
  for (const name of foreignNames) {
26350
- const from = path32.join(source, name);
26351
- const to = path32.join(destination, name);
26352
- if (fs35.existsSync(to)) {
26593
+ const from = path33.join(source, name);
26594
+ const to = path33.join(destination, name);
26595
+ if (fs36.existsSync(to)) {
26353
26596
  logger.warn(
26354
26597
  `skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
26355
26598
  );
26356
26599
  continue;
26357
26600
  }
26358
- fs35.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
26601
+ fs36.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
26359
26602
  logger.warn(
26360
26603
  `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.`
26361
26604
  );
@@ -26369,44 +26612,44 @@ function foreignSkillNames(source, declaredNames) {
26369
26612
  return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
26370
26613
  }
26371
26614
  function listSkillDirNames(dir) {
26372
- if (!fs35.existsSync(dir)) {
26615
+ if (!fs36.existsSync(dir)) {
26373
26616
  return [];
26374
26617
  }
26375
- return fs35.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
26618
+ return fs36.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
26376
26619
  }
26377
26620
  function isSymlinkPath(filePath) {
26378
26621
  try {
26379
- return fs35.lstatSync(filePath).isSymbolicLink();
26622
+ return fs36.lstatSync(filePath).isSymbolicLink();
26380
26623
  } catch {
26381
26624
  return false;
26382
26625
  }
26383
26626
  }
26384
26627
  function isSymlinkTo2(linkPath, source) {
26385
26628
  try {
26386
- return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
26629
+ return fs36.realpathSync(linkPath) === fs36.realpathSync(source);
26387
26630
  } catch {
26388
26631
  return false;
26389
26632
  }
26390
26633
  }
26391
26634
 
26392
26635
  // src/core/hook-scripts.ts
26393
- import path33 from "path";
26636
+ import path34 from "path";
26394
26637
  function hookScriptsDir(bridge, target, projectRoot) {
26395
26638
  const globalBridge = resolveTargetPath("~/.agents/hooks");
26396
- if (path33.resolve(bridge) === path33.resolve(globalBridge)) {
26639
+ if (path34.resolve(bridge) === path34.resolve(globalBridge)) {
26397
26640
  return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
26398
26641
  }
26399
- const relative = path33.relative(projectRoot ?? process.cwd(), bridge);
26400
- const insideProject = !relative.startsWith("..") && !path33.isAbsolute(relative) && relative !== "";
26642
+ const relative = path34.relative(projectRoot ?? process.cwd(), bridge);
26643
+ const insideProject = !relative.startsWith("..") && !path34.isAbsolute(relative) && relative !== "";
26401
26644
  const variable = PROJECT_DIR_VARIABLE[target];
26402
26645
  if (insideProject && variable) {
26403
- const posix = path33.posix.join(
26404
- relative.split(path33.sep).join("/"),
26646
+ const posix = path34.posix.join(
26647
+ relative.split(path34.sep).join("/"),
26405
26648
  "scripts"
26406
26649
  );
26407
26650
  return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
26408
26651
  }
26409
- return { prefix: path33.join(bridge, "scripts"), machineLocal: true };
26652
+ return { prefix: path34.join(bridge, "scripts"), machineLocal: true };
26410
26653
  }
26411
26654
  var PROJECT_DIR_VARIABLE = {
26412
26655
  "claude-code": "$CLAUDE_PROJECT_DIR"
@@ -26416,19 +26659,19 @@ function machineLocalScriptPathNotice(target, prefix) {
26416
26659
  }
26417
26660
 
26418
26661
  // src/core/instructions-source.ts
26419
- import fs36 from "fs";
26420
- import path34 from "path";
26662
+ import fs37 from "fs";
26663
+ import path35 from "path";
26421
26664
  var PORTABLE_INSTRUCTIONS_NAME = "AGENTS.md";
26422
26665
  var InstructionsSourceMissingError = class extends Error {
26423
26666
  constructor(kitRoot, expected, declaredBy) {
26424
26667
  super(
26425
- `${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.`
26668
+ `${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.`
26426
26669
  );
26427
26670
  this.name = "InstructionsSourceMissingError";
26428
26671
  }
26429
26672
  };
26430
26673
  function normalizeLabel(kitRoot, file) {
26431
- return path34.relative(kitRoot, file).split(path34.sep).join("/");
26674
+ return path35.relative(kitRoot, file).split(path35.sep).join("/");
26432
26675
  }
26433
26676
  function isExplicitOverride(configured) {
26434
26677
  const normalize = (value) => value.replace(/\\/gu, "/").replace(/^\.\//u, "");
@@ -26437,8 +26680,8 @@ function isExplicitOverride(configured) {
26437
26680
  function resolveInstructionsSource(kitRoot, config) {
26438
26681
  const configured = config.source.instructions;
26439
26682
  if (isExplicitOverride(configured)) {
26440
- const file = path34.resolve(kitRoot, configured);
26441
- if (!fs36.existsSync(file)) {
26683
+ const file = path35.resolve(kitRoot, configured);
26684
+ if (!fs37.existsSync(file)) {
26442
26685
  throw new InstructionsSourceMissingError(
26443
26686
  kitRoot,
26444
26687
  configured,
@@ -26453,8 +26696,8 @@ function resolveInstructionsSource(kitRoot, config) {
26453
26696
  }
26454
26697
  const declared = resolveKitEntrypointName(kitRoot);
26455
26698
  if (declared !== void 0) {
26456
- const file = path34.resolve(kitRoot, declared);
26457
- if (!fs36.existsSync(file)) {
26699
+ const file = path35.resolve(kitRoot, declared);
26700
+ if (!fs37.existsSync(file)) {
26458
26701
  throw new InstructionsSourceMissingError(
26459
26702
  kitRoot,
26460
26703
  declared,
@@ -26468,13 +26711,13 @@ function resolveInstructionsSource(kitRoot, config) {
26468
26711
  };
26469
26712
  }
26470
26713
  for (const name of [DEFAULT_ENTRYPOINT, PORTABLE_INSTRUCTIONS_NAME]) {
26471
- const file = path34.resolve(kitRoot, name);
26472
- if (fs36.existsSync(file)) {
26714
+ const file = path35.resolve(kitRoot, name);
26715
+ if (fs37.existsSync(file)) {
26473
26716
  return { file, label: name, origin: "convention" };
26474
26717
  }
26475
26718
  }
26476
- const legacy = path34.resolve(kitRoot, LEGACY_ENTRYPOINT);
26477
- if (fs36.existsSync(legacy)) {
26719
+ const legacy = path35.resolve(kitRoot, LEGACY_ENTRYPOINT);
26720
+ if (fs37.existsSync(legacy)) {
26478
26721
  return {
26479
26722
  file: legacy,
26480
26723
  label: LEGACY_ENTRYPOINT,
@@ -26486,7 +26729,7 @@ function resolveInstructionsSource(kitRoot, config) {
26486
26729
  }
26487
26730
  function instructionsSourcePath(kitRoot, config) {
26488
26731
  const resolved = resolveInstructionsSource(kitRoot, config);
26489
- return resolved ? resolved.file : path34.resolve(kitRoot, config.source.instructions);
26732
+ return resolved ? resolved.file : path35.resolve(kitRoot, config.source.instructions);
26490
26733
  }
26491
26734
  function instructionsSourceLabel(kitRoot, config) {
26492
26735
  const resolved = resolveInstructionsSource(kitRoot, config);
@@ -26607,7 +26850,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
26607
26850
  if (!shouldSkipComponent(options, "hooks")) {
26608
26851
  outcomes.push(
26609
26852
  syncHookScriptsBridge({
26610
- source: path35.resolve(sourceRoot, config.source.hooks),
26853
+ source: path36.resolve(sourceRoot, config.source.hooks),
26611
26854
  destination: profile.hook_scripts,
26612
26855
  config,
26613
26856
  sourceRoot,
@@ -26659,13 +26902,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
26659
26902
  }
26660
26903
  function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
26661
26904
  if (!mappings.modelTiers.custom_provider) return;
26662
- const agentsDir = path35.join(sourceRoot, config.source.agents);
26663
- if (!fs37.existsSync(agentsDir)) return;
26664
- for (const agentFile of ts(path35.join(agentsDir, "*.md")).sort()) {
26905
+ const agentsDir = path36.join(sourceRoot, config.source.agents);
26906
+ if (!fs38.existsSync(agentsDir)) return;
26907
+ for (const agentFile of ts(path36.join(agentsDir, "*.md")).sort()) {
26665
26908
  const { data } = parseMarkdownFrontmatter(agentFile);
26666
26909
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
26667
26910
  if (hasProvider) {
26668
- const basename = path35.basename(agentFile);
26911
+ const basename = path36.basename(agentFile);
26669
26912
  addLoss(lossReport, "claude-code", "agents", {
26670
26913
  source: `agents/${basename}`,
26671
26914
  fields: [
@@ -26690,7 +26933,7 @@ function shouldSkipComponent(options, component) {
26690
26933
  var SHIM_MANIFEST_KEY = "claude-code/instructions_shim";
26691
26934
  function lstatOrNull(p) {
26692
26935
  try {
26693
- return fs37.lstatSync(p);
26936
+ return fs38.lstatSync(p);
26694
26937
  } catch {
26695
26938
  return null;
26696
26939
  }
@@ -26702,12 +26945,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26702
26945
  if (shimLink?.isSymbolicLink()) {
26703
26946
  backupFile(shimPath, manifest, scopePath);
26704
26947
  writeManifest(scopePath, manifest);
26705
- fs37.unlinkSync(shimPath);
26948
+ fs38.unlinkSync(shimPath);
26706
26949
  logger?.verbose(
26707
26950
  `instructions-shim: replaced an unmanaged symlink at ${shimPath}`
26708
26951
  );
26709
26952
  }
26710
- if (!fs37.existsSync(shimPath)) {
26953
+ if (!fs38.existsSync(shimPath)) {
26711
26954
  addArtifactToManifest(manifest, {
26712
26955
  relativePath: SHIM_MANIFEST_KEY,
26713
26956
  path: shimPath,
@@ -26715,12 +26958,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26715
26958
  origin: "tangyr-managed"
26716
26959
  });
26717
26960
  writeManifest(scopePath, manifest);
26718
- fs37.mkdirSync(path35.dirname(shimPath), { recursive: true });
26719
- fs37.writeFileSync(shimPath, shimContent);
26961
+ fs38.mkdirSync(path36.dirname(shimPath), { recursive: true });
26962
+ fs38.writeFileSync(shimPath, shimContent);
26720
26963
  logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
26721
26964
  return;
26722
26965
  }
26723
- const existing = fs37.readFileSync(shimPath, "utf8");
26966
+ const existing = fs38.readFileSync(shimPath, "utf8");
26724
26967
  const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
26725
26968
  const marker = extractProvenanceMarker(firstNonEmptyLine);
26726
26969
  if (marker !== null && marker.hash === expectedBodyHash) {
@@ -26737,7 +26980,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26737
26980
  }
26738
26981
  backupFile(shimPath, manifest, scopePath);
26739
26982
  writeManifest(scopePath, manifest);
26740
- fs37.writeFileSync(shimPath, shimContent);
26983
+ fs38.writeFileSync(shimPath, shimContent);
26741
26984
  addArtifactToManifest(manifest, {
26742
26985
  relativePath: SHIM_MANIFEST_KEY,
26743
26986
  path: shimPath,
@@ -26747,10 +26990,10 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
26747
26990
  logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
26748
26991
  }
26749
26992
  function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
26750
- const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path35.resolve(sourceRoot, config.source[directComponent.sourceKey]);
26993
+ const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path36.resolve(sourceRoot, config.source[directComponent.sourceKey]);
26751
26994
  const sourceLabel = directComponent.sourceKey === "instructions" ? instructionsSourceLabel(sourceRoot, config) : config.source[directComponent.sourceKey];
26752
26995
  const destination = directComponent.destination;
26753
- if (!fs37.existsSync(source)) {
26996
+ if (!fs38.existsSync(source)) {
26754
26997
  return skippedMissingSource(directComponent.component, source);
26755
26998
  }
26756
26999
  if (options.dryRun) {
@@ -26772,7 +27015,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
26772
27015
  };
26773
27016
  }
26774
27017
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
26775
- fs37.unlinkSync(destination);
27018
+ fs38.unlinkSync(destination);
26776
27019
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
26777
27020
  return {
26778
27021
  component: directComponent.component,
@@ -26780,11 +27023,11 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
26780
27023
  path: destination
26781
27024
  };
26782
27025
  } else if (artifactClass === "managed-symlink") {
26783
- fs37.unlinkSync(destination);
27026
+ fs38.unlinkSync(destination);
26784
27027
  } else if (artifactClass === "managed-compiled") {
26785
- fs37.unlinkSync(destination);
27028
+ fs38.unlinkSync(destination);
26786
27029
  }
26787
- ensureDir(path35.dirname(destination));
27030
+ ensureDir(path36.dirname(destination));
26788
27031
  createRelativeSymlink(source, destination, directComponent.type, {
26789
27032
  logger,
26790
27033
  provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
@@ -26804,7 +27047,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
26804
27047
  return syncSkillsSlot({
26805
27048
  config,
26806
27049
  sourceRoot,
26807
- source: path35.resolve(sourceRoot, config.source.skills),
27050
+ source: path36.resolve(sourceRoot, config.source.skills),
26808
27051
  destination,
26809
27052
  dryRun: options.dryRun,
26810
27053
  logger,
@@ -26838,7 +27081,7 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
26838
27081
  destination,
26839
27082
  settings,
26840
27083
  stringifyJson2,
26841
- !fs37.existsSync(destination),
27084
+ !fs38.existsSync(destination),
26842
27085
  logger
26843
27086
  );
26844
27087
  return {
@@ -26848,8 +27091,8 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
26848
27091
  };
26849
27092
  }
26850
27093
  function syncMcp(config, sourceRoot, options, logger, destination) {
26851
- const source = path35.resolve(sourceRoot, config.source.mcp);
26852
- if (!fs37.existsSync(source)) {
27094
+ const source = path36.resolve(sourceRoot, config.source.mcp);
27095
+ if (!fs38.existsSync(source)) {
26853
27096
  return skippedMissingSource("mcp", source);
26854
27097
  }
26855
27098
  if (options.dryRun) {
@@ -26874,7 +27117,7 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
26874
27117
  destination,
26875
27118
  hostConfig,
26876
27119
  stringifyJson2,
26877
- !fs37.existsSync(destination),
27120
+ !fs38.existsSync(destination),
26878
27121
  logger
26879
27122
  );
26880
27123
  return {
@@ -26884,8 +27127,8 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
26884
27127
  };
26885
27128
  }
26886
27129
  function syncSettings(config, sourceRoot, options, logger, destination) {
26887
- const source = path35.resolve(sourceRoot, config.source.settings);
26888
- if (!fs37.existsSync(source)) {
27130
+ const source = path36.resolve(sourceRoot, config.source.settings);
27131
+ if (!fs38.existsSync(source)) {
26889
27132
  return skippedMissingSource("settings", source);
26890
27133
  }
26891
27134
  if (options.dryRun) {
@@ -26903,7 +27146,7 @@ function syncSettings(config, sourceRoot, options, logger, destination) {
26903
27146
  destination,
26904
27147
  settings,
26905
27148
  stringifyJson2,
26906
- !fs37.existsSync(destination),
27149
+ !fs38.existsSync(destination),
26907
27150
  logger
26908
27151
  );
26909
27152
  return {
@@ -26927,7 +27170,7 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
26927
27170
  if (manifest && scopePath) {
26928
27171
  backupFile(destination, manifest, scopePath);
26929
27172
  writeManifest(scopePath, manifest);
26930
- fs37.rmSync(destination, { recursive: true, force: true });
27173
+ fs38.rmSync(destination, { recursive: true, force: true });
26931
27174
  } else {
26932
27175
  const parked = parkConflictingPath(
26933
27176
  destination,
@@ -26942,7 +27185,7 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
26942
27185
  }
26943
27186
  return true;
26944
27187
  }
26945
- fs37.rmSync(destination, { recursive: true, force: true });
27188
+ fs38.rmSync(destination, { recursive: true, force: true });
26946
27189
  return true;
26947
27190
  }
26948
27191
  function skippedMissingSource(component, source) {
@@ -26954,16 +27197,16 @@ function skippedMissingSource(component, source) {
26954
27197
  }
26955
27198
  function isSymlinkTo3(linkPath, source) {
26956
27199
  try {
26957
- return fs37.realpathSync(linkPath) === fs37.realpathSync(source);
27200
+ return fs38.realpathSync(linkPath) === fs38.realpathSync(source);
26958
27201
  } catch {
26959
27202
  return false;
26960
27203
  }
26961
27204
  }
26962
27205
  function readJsonObject3(filePath) {
26963
- if (!fs37.existsSync(filePath)) {
27206
+ if (!fs38.existsSync(filePath)) {
26964
27207
  return {};
26965
27208
  }
26966
- const parsed = JSON.parse(fs37.readFileSync(filePath, "utf8"));
27209
+ const parsed = JSON.parse(fs38.readFileSync(filePath, "utf8"));
26967
27210
  return isRecord3(parsed) ? parsed : {};
26968
27211
  }
26969
27212
  function markManaged(value) {
@@ -26990,13 +27233,13 @@ function isRecord3(value) {
26990
27233
  // src/adapters/codex.ts
26991
27234
  var TOML3 = __toESM(require_toml(), 1);
26992
27235
  import crypto6 from "crypto";
26993
- import fs40 from "fs";
26994
- import path39 from "path";
27236
+ import fs41 from "fs";
27237
+ import path40 from "path";
26995
27238
 
26996
27239
  // src/compiler/agents.ts
26997
27240
  var TOML = __toESM(require_toml(), 1);
26998
27241
  var import_yaml8 = __toESM(require_dist(), 1);
26999
- import path36 from "path";
27242
+ import path37 from "path";
27000
27243
  var writeCapabilityClasses = /* @__PURE__ */ new Set(["filesystem-write", "shell-execution"]);
27001
27244
  var copilotToolAliasesByClass = {
27002
27245
  delegation: "agent",
@@ -27008,7 +27251,7 @@ var copilotToolAliasesByClass = {
27008
27251
  };
27009
27252
  function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
27010
27253
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
27011
- const relativeSource = `agents/${path36.basename(sourceFile)}`;
27254
+ const relativeSource = `agents/${path37.basename(sourceFile)}`;
27012
27255
  if (target === "opencode") {
27013
27256
  return compileOpenCodeAgent(
27014
27257
  sourceFile,
@@ -27049,7 +27292,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
27049
27292
  mappings,
27050
27293
  lossReport
27051
27294
  );
27052
- const overlayKey = `agents/${path36.basename(sourceFile, ".md")}.${target}.yaml`;
27295
+ const overlayKey = `agents/${path37.basename(sourceFile, ".md")}.${target}.yaml`;
27053
27296
  const targetFields = {
27054
27297
  ...translated.fields,
27055
27298
  ...extensions[overlayKey] ?? {}
@@ -27083,7 +27326,7 @@ ${TOML.stringify({
27083
27326
  function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
27084
27327
  if (typeof data.description !== "string" || data.description.trim() === "") {
27085
27328
  throw new Error(
27086
- `${path36.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
27329
+ `${path37.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
27087
27330
  );
27088
27331
  }
27089
27332
  const frontmatter = {
@@ -27137,7 +27380,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
27137
27380
  "permission",
27138
27381
  "permission-coarsening"
27139
27382
  ),
27140
- detail: `${path36.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
27383
+ detail: `${path37.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
27141
27384
  }
27142
27385
  ]
27143
27386
  });
@@ -27162,7 +27405,7 @@ ${(0, import_yaml8.stringify)(frontmatter).trim()}
27162
27405
  function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
27163
27406
  if (typeof data.description !== "string" || data.description.trim() === "") {
27164
27407
  throw new Error(
27165
- `${path36.basename(sourceFile)}: Cursor agent requires a non-empty description field`
27408
+ `${path37.basename(sourceFile)}: Cursor agent requires a non-empty description field`
27166
27409
  );
27167
27410
  }
27168
27411
  const frontmatter = {
@@ -27199,7 +27442,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
27199
27442
  "permission",
27200
27443
  "permission-coarsening"
27201
27444
  ),
27202
- detail: `${path36.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
27445
+ detail: `${path37.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
27203
27446
  }
27204
27447
  ]
27205
27448
  });
@@ -27218,7 +27461,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
27218
27461
  "provider",
27219
27462
  "provider-not-representable"
27220
27463
  ),
27221
- detail: `${path36.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
27464
+ detail: `${path37.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
27222
27465
  }
27223
27466
  ]
27224
27467
  });
@@ -27250,7 +27493,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
27250
27493
  "persona",
27251
27494
  "persona-not-representable"
27252
27495
  ),
27253
- 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.`
27496
+ 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.`
27254
27497
  }
27255
27498
  ]
27256
27499
  });
@@ -27298,7 +27541,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27298
27541
  field,
27299
27542
  "model-not-representable"
27300
27543
  ),
27301
- detail: `${path36.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
27544
+ detail: `${path37.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
27302
27545
  });
27303
27546
  return;
27304
27547
  }
@@ -27316,9 +27559,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27316
27559
  lossReport,
27317
27560
  target,
27318
27561
  "agents",
27319
- `agents/${path36.basename(sourceFile)}`,
27562
+ `agents/${path37.basename(sourceFile)}`,
27320
27563
  "info",
27321
- `${path36.basename(sourceFile)}: ${field} is delivered through another managed surface.`
27564
+ `${path37.basename(sourceFile)}: ${field} is delivered through another managed surface.`
27322
27565
  );
27323
27566
  return;
27324
27567
  }
@@ -27327,7 +27570,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27327
27570
  field,
27328
27571
  action: entryType,
27329
27572
  severity: resolveLossSeverity("agent-field", field, entryType),
27330
- detail: `${path36.basename(sourceFile)}: ${field} has no emitted field for this target.`
27573
+ detail: `${path37.basename(sourceFile)}: ${field} has no emitted field for this target.`
27331
27574
  });
27332
27575
  }
27333
27576
  function mapToolsToCapabilities(value, mappings) {
@@ -27515,23 +27758,6 @@ function compileOpenCodeHooks(sourceHooksJson, lossReport, sourceLabel) {
27515
27758
  ]
27516
27759
  });
27517
27760
  }
27518
- if (Object.keys(sourceHooks).length === 0) {
27519
- addLoss(lossReport, "opencode", "hooks", {
27520
- source: sourceLabel,
27521
- fields: [
27522
- {
27523
- field: "hooks",
27524
- action: "hook-as-plugin",
27525
- severity: resolveLossSeverity(
27526
- "agent-field",
27527
- "hooks",
27528
- "hook-as-plugin"
27529
- ),
27530
- detail: "OpenCode exposes hooks only as plugin code \u2014 no declarative hook file emitted"
27531
- }
27532
- ]
27533
- });
27534
- }
27535
27761
  return { payload: {}, translated: 0, dropped: 0, droppedEvents: [] };
27536
27762
  }
27537
27763
  function compileClineHooks(sourceHooksJson, lossReport, sourceLabel) {
@@ -27553,23 +27779,6 @@ function compileClineHooks(sourceHooksJson, lossReport, sourceLabel) {
27553
27779
  ]
27554
27780
  });
27555
27781
  }
27556
- if (Object.keys(sourceHooks).length === 0) {
27557
- addLoss(lossReport, "cline", "hooks", {
27558
- source: sourceLabel,
27559
- fields: [
27560
- {
27561
- field: "hooks",
27562
- action: "hook-as-plugin",
27563
- severity: resolveLossSeverity(
27564
- "agent-field",
27565
- "hooks",
27566
- "hook-as-plugin"
27567
- ),
27568
- detail: "Cline exposes hooks only as @cline/sdk AgentPlugin TypeScript/JS code \u2014 no declarative hook file emitted"
27569
- }
27570
- ]
27571
- });
27572
- }
27573
27782
  return { payload: {}, translated: 0, dropped: 0, droppedEvents: [] };
27574
27783
  }
27575
27784
  function compileCopilotHooks(sourceHooksJson, mappings, lossReport, sourceLabel) {
@@ -27791,13 +28000,13 @@ function addHookLoss(lossReport, target, eventName, sourceLabel, severity, reaso
27791
28000
 
27792
28001
  // src/compiler/command-as-skill.ts
27793
28002
  var import_yaml9 = __toESM(require_dist(), 1);
27794
- import fs38 from "fs";
27795
- import path37 from "path";
28003
+ import fs39 from "fs";
28004
+ import path38 from "path";
27796
28005
  var CARRIED_OVER = ["argument-hint", "agent", "launch"];
27797
28006
  function compileCommandAsSkill(commandFile, target) {
27798
- const name = path37.basename(commandFile, ".md");
28007
+ const name = path38.basename(commandFile, ".md");
27799
28008
  const { data, body } = parseMarkdownFrontmatter(commandFile);
27800
- const relativeSource = `commands/${path37.basename(commandFile)}`;
28009
+ const relativeSource = `commands/${path38.basename(commandFile)}`;
27801
28010
  const description = typeof data.description === "string" && data.description.trim().length > 0 ? data.description.trim() : `The ${name} command.`;
27802
28011
  const frontmatter = { name, description };
27803
28012
  for (const key of CARRIED_OVER) {
@@ -27820,11 +28029,11 @@ ${body.trim()}
27820
28029
  return { name, content, relativeSource };
27821
28030
  }
27822
28031
  function compileCommandsAsSkills(commandsRoot, target) {
27823
- if (!fs38.existsSync(commandsRoot)) {
28032
+ if (!fs39.existsSync(commandsRoot)) {
27824
28033
  return [];
27825
28034
  }
27826
- return fs38.readdirSync(commandsRoot).filter((entry) => entry.endsWith(".md")).sort().map(
27827
- (entry) => compileCommandAsSkill(path37.join(commandsRoot, entry), target)
28035
+ return fs39.readdirSync(commandsRoot).filter((entry) => entry.endsWith(".md")).sort().map(
28036
+ (entry) => compileCommandAsSkill(path38.join(commandsRoot, entry), target)
27828
28037
  );
27829
28038
  }
27830
28039
 
@@ -28107,9 +28316,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
28107
28316
  }
28108
28317
 
28109
28318
  // src/compiler/rules.ts
28110
- import path38 from "path";
28319
+ import path39 from "path";
28111
28320
  var import_yaml10 = __toESM(require_dist(), 1);
28112
- import fs39 from "fs";
28321
+ import fs40 from "fs";
28113
28322
  function compileRules(sourceRulesDir, target, _mappings, lossReport) {
28114
28323
  if (target === "copilot") {
28115
28324
  addLoss(lossReport, "copilot", "rules", {
@@ -28146,13 +28355,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
28146
28355
  }
28147
28356
  const appendixParts = [];
28148
28357
  const dotRulesFiles = [];
28149
- for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28358
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28150
28359
  const parsed = parseRule(ruleFile);
28151
- const name = path38.basename(ruleFile, ".md");
28360
+ const name = path39.basename(ruleFile, ".md");
28152
28361
  if (parsed.mode === "exec-policy") {
28153
28362
  dotRulesFiles.push({
28154
28363
  name: `${name}.rules`,
28155
- content: `${formatProvenanceMarker("toml", `rules/${path38.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
28364
+ content: `${formatProvenanceMarker("toml", `rules/${path39.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
28156
28365
  ${parsed.body}`
28157
28366
  });
28158
28367
  continue;
@@ -28161,7 +28370,7 @@ ${parsed.body}`
28161
28370
 
28162
28371
  ${parsed.body.trim()}`);
28163
28372
  addLoss(lossReport, "codex", "rules", {
28164
- source: `rules/${path38.basename(ruleFile)}`,
28373
+ source: `rules/${path39.basename(ruleFile)}`,
28165
28374
  fields: [
28166
28375
  {
28167
28376
  field: "mode",
@@ -28171,7 +28380,7 @@ ${parsed.body.trim()}`);
28171
28380
  "mode",
28172
28381
  "rule-as-instruction"
28173
28382
  ),
28174
- detail: `${path38.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
28383
+ detail: `${path39.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
28175
28384
  }
28176
28385
  ]
28177
28386
  });
@@ -28179,7 +28388,7 @@ ${parsed.body.trim()}`);
28179
28388
  return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
28180
28389
  }
28181
28390
  function parseRule(ruleFile) {
28182
- const content = fs39.readFileSync(ruleFile, "utf8");
28391
+ const content = fs40.readFileSync(ruleFile, "utf8");
28183
28392
  if (!content.startsWith("---\n")) {
28184
28393
  return { mode: "guidance", body: content };
28185
28394
  }
@@ -28203,14 +28412,14 @@ function isRuleMode(value) {
28203
28412
  }
28204
28413
  function compileOpenCodeRules(sourceRulesDir, lossReport) {
28205
28414
  const appendixParts = [];
28206
- for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28415
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28207
28416
  const parsed = parseRule(ruleFile);
28208
- const name = path38.basename(ruleFile, ".md");
28417
+ const name = path39.basename(ruleFile, ".md");
28209
28418
  appendixParts.push(`## ${name}
28210
28419
 
28211
28420
  ${parsed.body.trim()}`);
28212
28421
  addLoss(lossReport, "opencode", "rules", {
28213
- source: `rules/${path38.basename(ruleFile)}`,
28422
+ source: `rules/${path39.basename(ruleFile)}`,
28214
28423
  fields: [
28215
28424
  {
28216
28425
  field: "rule",
@@ -28220,7 +28429,7 @@ ${parsed.body.trim()}`);
28220
28429
  "rule",
28221
28430
  "rule-path-scoping"
28222
28431
  ),
28223
- detail: `${path38.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
28432
+ detail: `${path39.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
28224
28433
  }
28225
28434
  ]
28226
28435
  });
@@ -28229,9 +28438,9 @@ ${parsed.body.trim()}`);
28229
28438
  }
28230
28439
  function compileCursorRules(sourceRulesDir, _lossReport) {
28231
28440
  const dotRulesFiles = [];
28232
- for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28233
- const content = fs39.readFileSync(ruleFile, "utf8");
28234
- const name = path38.basename(ruleFile, ".md");
28441
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28442
+ const content = fs40.readFileSync(ruleFile, "utf8");
28443
+ const name = path39.basename(ruleFile, ".md");
28235
28444
  let frontmatterData = {};
28236
28445
  let body = content;
28237
28446
  if (content.startsWith("---\n")) {
@@ -28260,7 +28469,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
28260
28469
  }
28261
28470
  const marker = formatProvenanceMarker(
28262
28471
  "markdown",
28263
- `rules/${path38.basename(ruleFile)}`,
28472
+ `rules/${path39.basename(ruleFile)}`,
28264
28473
  computeSourceHash(ruleFile),
28265
28474
  "cursor"
28266
28475
  );
@@ -28276,9 +28485,9 @@ ${body}`;
28276
28485
  }
28277
28486
  function compileClineRules(sourceRulesDir, lossReport) {
28278
28487
  const dotRulesFiles = [];
28279
- for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28280
- const content = fs39.readFileSync(ruleFile, "utf8");
28281
- const name = path38.basename(ruleFile, ".md");
28488
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28489
+ const content = fs40.readFileSync(ruleFile, "utf8");
28490
+ const name = path39.basename(ruleFile, ".md");
28282
28491
  let frontmatterData = {};
28283
28492
  let body = content;
28284
28493
  if (content.startsWith("---\n")) {
@@ -28295,13 +28504,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
28295
28504
  }
28296
28505
  const marker = formatProvenanceMarker(
28297
28506
  "markdown",
28298
- `rules/${path38.basename(ruleFile)}`,
28507
+ `rules/${path39.basename(ruleFile)}`,
28299
28508
  computeSourceHash(ruleFile),
28300
28509
  "cline"
28301
28510
  );
28302
28511
  if (frontmatterData.mode === "exec-policy") {
28303
28512
  addLoss(lossReport, "cline", "rules", {
28304
- source: `rules/${path38.basename(ruleFile)}`,
28513
+ source: `rules/${path39.basename(ruleFile)}`,
28305
28514
  fields: [
28306
28515
  {
28307
28516
  field: "mode",
@@ -28311,7 +28520,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
28311
28520
  "mode",
28312
28521
  "rule-mode-downgrade"
28313
28522
  ),
28314
- detail: `${path38.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28523
+ detail: `${path39.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28315
28524
  }
28316
28525
  ]
28317
28526
  });
@@ -28331,12 +28540,12 @@ ${frontmatterYaml}${body}`;
28331
28540
  return { agentsAppendix: "", dotRulesFiles };
28332
28541
  }
28333
28542
  function compileCopilotRules(sourceRulesDir) {
28334
- if (!fs39.existsSync(sourceRulesDir)) {
28543
+ if (!fs40.existsSync(sourceRulesDir)) {
28335
28544
  return [];
28336
28545
  }
28337
28546
  const files = [];
28338
- for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
28339
- const name = path38.basename(ruleFile, ".md");
28547
+ for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
28548
+ const name = path39.basename(ruleFile, ".md");
28340
28549
  const { data } = parseMarkdownFrontmatter(ruleFile);
28341
28550
  const { body } = parseRule(ruleFile);
28342
28551
  const declared = data.paths;
@@ -28345,7 +28554,7 @@ function compileCopilotRules(sourceRulesDir) {
28345
28554
  "---",
28346
28555
  `applyTo: ${JSON.stringify(applyTo)}`,
28347
28556
  "x-tangyr:",
28348
- ` source: rules/${path38.basename(ruleFile)}`,
28557
+ ` source: rules/${path39.basename(ruleFile)}`,
28349
28558
  ` hash: ${computeSourceHash(ruleFile)}`,
28350
28559
  " target: copilot",
28351
28560
  "---"
@@ -28382,7 +28591,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28382
28591
  rules: profile.rules
28383
28592
  };
28384
28593
  const rules = compileRules(
28385
- path39.join(sourceRoot, config.source.rules),
28594
+ path40.join(sourceRoot, config.source.rules),
28386
28595
  "codex",
28387
28596
  mappings,
28388
28597
  lossReport
@@ -28462,7 +28671,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28462
28671
  if (!shouldSkipComponent2(options, "hooks")) {
28463
28672
  outcomes.push(
28464
28673
  syncHookScriptsBridge({
28465
- source: path39.resolve(sourceRoot, config.source.hooks),
28674
+ source: path40.resolve(sourceRoot, config.source.hooks),
28466
28675
  destination: resolveTargetPath(paths.hook_scripts),
28467
28676
  config,
28468
28677
  sourceRoot,
@@ -28561,9 +28770,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28561
28770
  function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
28562
28771
  const cp = mappings.modelTiers.custom_provider;
28563
28772
  if (!cp) return "";
28564
- const agentsDir = path39.join(sourceRoot, config.source.agents);
28565
- if (!fs40.existsSync(agentsDir)) return "";
28566
- const agentFiles = ts(path39.join(agentsDir, "*.md")).sort();
28773
+ const agentsDir = path40.join(sourceRoot, config.source.agents);
28774
+ if (!fs41.existsSync(agentsDir)) return "";
28775
+ const agentFiles = ts(path40.join(agentsDir, "*.md")).sort();
28567
28776
  const hasProviderAgent = agentFiles.some((agentFile) => {
28568
28777
  const { data } = parseMarkdownFrontmatter(agentFile);
28569
28778
  return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
@@ -28628,7 +28837,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
28628
28837
  }
28629
28838
  ];
28630
28839
  for (const ruleFile of rules.dotRulesFiles) {
28631
- const destination = path39.join(rulesRoot, ruleFile.name);
28840
+ const destination = path40.join(rulesRoot, ruleFile.name);
28632
28841
  if (options.dryRun) {
28633
28842
  logger.info(`[dry-run] rules: write ${destination}`);
28634
28843
  outcomes.push({
@@ -28658,16 +28867,16 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
28658
28867
  function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
28659
28868
  const source = instructionsSourcePath(sourceRoot, config);
28660
28869
  const destination = resolveTargetPath(paths.instructions);
28661
- if (!fs40.existsSync(source)) {
28870
+ if (!fs41.existsSync(source)) {
28662
28871
  return skippedMissingSource2("instructions", source);
28663
28872
  }
28664
- const composed = `${fs40.readFileSync(source, "utf8").trim()}
28873
+ const composed = `${fs41.readFileSync(source, "utf8").trim()}
28665
28874
 
28666
28875
  --- tangyr managed rules ---
28667
28876
  ${agentsAppendix}`.trim();
28668
28877
  const marker = formatProvenanceMarker(
28669
28878
  "markdown",
28670
- path39.basename(instructionsSourceLabel(sourceRoot, config)),
28879
+ path40.basename(instructionsSourceLabel(sourceRoot, config)),
28671
28880
  hashString(composed),
28672
28881
  "codex"
28673
28882
  );
@@ -28697,7 +28906,7 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
28697
28906
  return syncSkillsSlot({
28698
28907
  config,
28699
28908
  sourceRoot,
28700
- source: path39.resolve(sourceRoot, config.source.skills),
28909
+ source: path40.resolve(sourceRoot, config.source.skills),
28701
28910
  destination: resolveTargetPath(paths.skills),
28702
28911
  dryRun: options.dryRun,
28703
28912
  logger,
@@ -28712,13 +28921,13 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
28712
28921
  });
28713
28922
  }
28714
28923
  function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, logger, manifest, scopePath) {
28715
- const commandsRoot = path39.resolve(sourceRoot, config.source.commands);
28716
- if (!fs40.existsSync(commandsRoot)) {
28924
+ const commandsRoot = path40.resolve(sourceRoot, config.source.commands);
28925
+ if (!fs41.existsSync(commandsRoot)) {
28717
28926
  return [skippedMissingSource2("commands", commandsRoot)];
28718
28927
  }
28719
28928
  const skillsRoot = resolveTargetPath(paths.skills);
28720
28929
  return compileCommandsAsSkills(commandsRoot, "codex").map((skill) => {
28721
- const destination = path39.join(skillsRoot, skill.name, "SKILL.md");
28930
+ const destination = path40.join(skillsRoot, skill.name, "SKILL.md");
28722
28931
  if (options.dryRun) {
28723
28932
  logger.info(
28724
28933
  `[dry-run] commands: compile ${skill.relativeSource} -> ${destination}`
@@ -28744,16 +28953,16 @@ function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, l
28744
28953
  });
28745
28954
  }
28746
28955
  function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
28747
- const sourceAgentsRoot = path39.join(sourceRoot, config.source.agents);
28748
- if (!fs40.existsSync(sourceAgentsRoot)) {
28956
+ const sourceAgentsRoot = path40.join(sourceRoot, config.source.agents);
28957
+ if (!fs41.existsSync(sourceAgentsRoot)) {
28749
28958
  return [skippedMissingSource2("agents", sourceAgentsRoot)];
28750
28959
  }
28751
- const sourceAgents = ts(path39.join(sourceAgentsRoot, "*.md")).sort();
28960
+ const sourceAgents = ts(path40.join(sourceAgentsRoot, "*.md")).sort();
28752
28961
  const agentsRoot = resolveTargetPath(paths.agents);
28753
28962
  return sourceAgents.map((agentFile) => {
28754
- const destination = path39.join(
28963
+ const destination = path40.join(
28755
28964
  agentsRoot,
28756
- `${path39.basename(agentFile, ".md")}.toml`
28965
+ `${path40.basename(agentFile, ".md")}.toml`
28757
28966
  );
28758
28967
  const compiled = compileAgent(
28759
28968
  agentFile,
@@ -28831,7 +29040,7 @@ function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, lo
28831
29040
  destination,
28832
29041
  hostHooks,
28833
29042
  stringifyJson3,
28834
- !fs40.existsSync(destination),
29043
+ !fs41.existsSync(destination),
28835
29044
  logger
28836
29045
  );
28837
29046
  return {
@@ -28844,7 +29053,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
28844
29053
  const source = resolveMcpSourceFile(sourceRoot, config);
28845
29054
  const sourceLabel = mcpSourceLabel(config);
28846
29055
  const destination = resolveTargetPath(paths.mcp_shared_file);
28847
- if (!fs40.existsSync(source)) {
29056
+ if (!fs41.existsSync(source)) {
28848
29057
  if (providerToml && !options.dryRun) {
28849
29058
  const changed2 = writeTomlManagedSection(
28850
29059
  destination,
@@ -28859,7 +29068,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
28859
29068
  }
28860
29069
  return skippedMissingSource2("mcp", source);
28861
29070
  }
28862
- const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
29071
+ const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
28863
29072
  const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
28864
29073
  const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
28865
29074
  if (options.dryRun) {
@@ -28884,18 +29093,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
28884
29093
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
28885
29094
  return { component, status: "conflict", path: destination };
28886
29095
  }
28887
- ensureDir(path39.dirname(destination));
29096
+ ensureDir(path40.dirname(destination));
28888
29097
  const clearedLink = clearSymlinkAtDestination(destination);
28889
29098
  if (clearedLink !== null) {
28890
29099
  logger.verbose(
28891
29100
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
28892
29101
  );
28893
29102
  }
28894
- fs40.writeFileSync(destination, content);
29103
+ fs41.writeFileSync(destination, content);
28895
29104
  return { component, status: "success", path: destination };
28896
29105
  }
28897
29106
  function writeTomlManagedSection(destination, managedContent, logger) {
28898
- const current = fs40.existsSync(destination) ? fs40.readFileSync(destination, "utf8") : "";
29107
+ const current = fs41.existsSync(destination) ? fs41.readFileSync(destination, "utf8") : "";
28899
29108
  const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
28900
29109
  if (isFirstWrite) {
28901
29110
  logger.warn(
@@ -28911,8 +29120,8 @@ ${managedMcpEnd}
28911
29120
  if (current === next.trimStart()) {
28912
29121
  return false;
28913
29122
  }
28914
- ensureDir(path39.dirname(destination));
28915
- fs40.writeFileSync(destination, next.trimStart());
29123
+ ensureDir(path40.dirname(destination));
29124
+ fs41.writeFileSync(destination, next.trimStart());
28916
29125
  return true;
28917
29126
  }
28918
29127
  function removeManagedTomlSection(content) {
@@ -28938,7 +29147,7 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
28938
29147
  if (manifest && scopePath) {
28939
29148
  backupFile(destination, manifest, scopePath);
28940
29149
  writeManifest(scopePath, manifest);
28941
- fs40.rmSync(destination, { recursive: true, force: true });
29150
+ fs41.rmSync(destination, { recursive: true, force: true });
28942
29151
  } else {
28943
29152
  const parked = parkConflictingPath(
28944
29153
  destination,
@@ -28953,12 +29162,12 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
28953
29162
  }
28954
29163
  return true;
28955
29164
  }
28956
- fs40.rmSync(destination, { recursive: true, force: true });
29165
+ fs41.rmSync(destination, { recursive: true, force: true });
28957
29166
  return true;
28958
29167
  }
28959
29168
  function isCompiledCurrent(destination, expectedContent, _expectedHash) {
28960
29169
  try {
28961
- return fs40.readFileSync(destination, "utf8") === expectedContent;
29170
+ return fs41.readFileSync(destination, "utf8") === expectedContent;
28962
29171
  } catch {
28963
29172
  return false;
28964
29173
  }
@@ -28974,10 +29183,10 @@ function shouldSkipComponent2(options, component) {
28974
29183
  return Boolean(options.component && options.component !== component);
28975
29184
  }
28976
29185
  function readJsonObject4(filePath) {
28977
- if (!fs40.existsSync(filePath)) {
29186
+ if (!fs41.existsSync(filePath)) {
28978
29187
  return {};
28979
29188
  }
28980
- const parsed = JSON.parse(fs40.readFileSync(filePath, "utf8"));
29189
+ const parsed = JSON.parse(fs41.readFileSync(filePath, "utf8"));
28981
29190
  return isRecord5(parsed) ? parsed : {};
28982
29191
  }
28983
29192
  function stringifyJson3(value) {
@@ -28993,16 +29202,16 @@ function hashString(value) {
28993
29202
 
28994
29203
  // src/adapters/copilot.ts
28995
29204
  import crypto7 from "crypto";
28996
- import fs41 from "fs";
28997
- import path41 from "path";
29205
+ import fs42 from "fs";
29206
+ import path42 from "path";
28998
29207
 
28999
29208
  // src/compiler/commands.ts
29000
29209
  var import_yaml11 = __toESM(require_dist(), 1);
29001
- import path40 from "path";
29210
+ import path41 from "path";
29002
29211
  function compileCommandPrompt(sourceFile) {
29003
29212
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
29004
- const relativeSource = `commands/${path40.basename(sourceFile)}`;
29005
- const fields = promptFrontmatter(data, path40.basename(sourceFile, ".md"));
29213
+ const relativeSource = `commands/${path41.basename(sourceFile)}`;
29214
+ const fields = promptFrontmatter(data, path41.basename(sourceFile, ".md"));
29006
29215
  const marker = formatProvenanceMarker(
29007
29216
  "markdown",
29008
29217
  relativeSource,
@@ -29143,7 +29352,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29143
29352
  if (!shouldSkipComponent3(options, "hooks")) {
29144
29353
  outcomes.push(
29145
29354
  syncHookScriptsBridge({
29146
- source: path41.resolve(sourceRoot, config.source.hooks),
29355
+ source: path42.resolve(sourceRoot, config.source.hooks),
29147
29356
  destination: resolveTargetPath(paths.hook_scripts),
29148
29357
  config,
29149
29358
  sourceRoot,
@@ -29224,13 +29433,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29224
29433
  }
29225
29434
  function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
29226
29435
  if (!mappings.modelTiers.custom_provider) return;
29227
- const agentsDir = path41.join(sourceRoot, config.source.agents);
29228
- if (!fs41.existsSync(agentsDir)) return;
29229
- for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
29436
+ const agentsDir = path42.join(sourceRoot, config.source.agents);
29437
+ if (!fs42.existsSync(agentsDir)) return;
29438
+ for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
29230
29439
  const { data } = parseMarkdownFrontmatter(agentFile);
29231
29440
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
29232
29441
  if (hasProvider) {
29233
- const basename = path41.basename(agentFile);
29442
+ const basename = path42.basename(agentFile);
29234
29443
  addLoss(lossReport, "copilot", "agents", {
29235
29444
  source: `agents/${basename}`,
29236
29445
  fields: [
@@ -29256,22 +29465,22 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
29256
29465
  return [{ component: "instructions", status: "skipped", path: message }];
29257
29466
  }
29258
29467
  const source = instructionsSourcePath(sourceRoot, config);
29259
- if (!fs41.existsSync(source)) {
29468
+ if (!fs42.existsSync(source)) {
29260
29469
  return [skippedMissingSource3("instructions", source)];
29261
29470
  }
29262
- const rawContent = fs41.readFileSync(source, "utf8");
29471
+ const rawContent = fs42.readFileSync(source, "utf8");
29263
29472
  const contentHash = hashString2(rawContent);
29264
29473
  const marker = formatProvenanceMarker(
29265
29474
  "markdown",
29266
- path41.basename(instructionsSourceLabel(sourceRoot, config)),
29475
+ path42.basename(instructionsSourceLabel(sourceRoot, config)),
29267
29476
  contentHash,
29268
29477
  "copilot"
29269
29478
  );
29270
29479
  const composedContent = `${marker}
29271
29480
  ${rawContent}`;
29272
29481
  const projectRoot = options.projectRoot ?? process.cwd();
29273
- const agentsMdDest = path41.resolve(projectRoot, "AGENTS.md");
29274
- const mirrorDest = path41.resolve(
29482
+ const agentsMdDest = path42.resolve(projectRoot, "AGENTS.md");
29483
+ const mirrorDest = path42.resolve(
29275
29484
  projectRoot,
29276
29485
  ".github",
29277
29486
  "copilot-instructions.md"
@@ -29325,14 +29534,14 @@ function writeInstructionsFile(component, destination, content, contentHash, con
29325
29534
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
29326
29535
  return { component, status: "conflict", path: destination };
29327
29536
  }
29328
- ensureDir(path41.dirname(destination));
29537
+ ensureDir(path42.dirname(destination));
29329
29538
  const clearedLink = clearSymlinkAtDestination(destination);
29330
29539
  if (clearedLink !== null) {
29331
29540
  logger.verbose(
29332
29541
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
29333
29542
  );
29334
29543
  }
29335
- fs41.writeFileSync(destination, content);
29544
+ fs42.writeFileSync(destination, content);
29336
29545
  return { component, status: "success", path: destination };
29337
29546
  }
29338
29547
  function hashString2(value) {
@@ -29342,7 +29551,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29342
29551
  return syncSkillsSlot({
29343
29552
  config,
29344
29553
  sourceRoot,
29345
- source: path41.resolve(sourceRoot, config.source.skills),
29554
+ source: path42.resolve(sourceRoot, config.source.skills),
29346
29555
  destination: resolveTargetPath(paths.skills),
29347
29556
  dryRun: options.dryRun,
29348
29557
  logger,
@@ -29357,16 +29566,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29357
29566
  });
29358
29567
  }
29359
29568
  function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29360
- const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
29361
- if (!fs41.existsSync(sourceAgentsRoot)) {
29569
+ const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
29570
+ if (!fs42.existsSync(sourceAgentsRoot)) {
29362
29571
  return [skippedMissingSource3("agents", sourceAgentsRoot)];
29363
29572
  }
29364
- const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
29573
+ const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
29365
29574
  const agentsRoot = resolveTargetPath(paths.agents);
29366
29575
  return sourceAgents.map((agentFile) => {
29367
- const destination = path41.join(
29576
+ const destination = path42.join(
29368
29577
  agentsRoot,
29369
- `${path41.basename(agentFile, ".md")}.agent.md`
29578
+ `${path42.basename(agentFile, ".md")}.agent.md`
29370
29579
  );
29371
29580
  const compiled = compileAgent(
29372
29581
  agentFile,
@@ -29394,16 +29603,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
29394
29603
  });
29395
29604
  }
29396
29605
  function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
29397
- const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
29398
- if (!fs41.existsSync(sourceCommandsRoot)) {
29606
+ const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
29607
+ if (!fs42.existsSync(sourceCommandsRoot)) {
29399
29608
  return [skippedMissingSource3("commands", sourceCommandsRoot)];
29400
29609
  }
29401
- const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
29610
+ const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
29402
29611
  const promptsRoot = resolveTargetPath(paths.prompts);
29403
29612
  return sourceCommands.map((commandFile) => {
29404
- const destination = path41.join(
29613
+ const destination = path42.join(
29405
29614
  promptsRoot,
29406
- `${path41.basename(commandFile, ".md")}.prompt.md`
29615
+ `${path42.basename(commandFile, ".md")}.prompt.md`
29407
29616
  );
29408
29617
  const compiled = compileCommandPrompt(commandFile);
29409
29618
  if (options.dryRun) {
@@ -29427,7 +29636,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
29427
29636
  });
29428
29637
  }
29429
29638
  function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
29430
- const destination = path41.join(
29639
+ const destination = path42.join(
29431
29640
  resolveTargetPath(paths.hooks),
29432
29641
  "tangyr-managed.json"
29433
29642
  );
@@ -29490,10 +29699,10 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
29490
29699
  const source = resolveMcpSourceFile(sourceRoot, config);
29491
29700
  const sourceLabel = mcpSourceLabel(config);
29492
29701
  const destination = resolveTargetPath(paths.mcp_shared_file);
29493
- if (!fs41.existsSync(source)) {
29702
+ if (!fs42.existsSync(source)) {
29494
29703
  return skippedMissingSource3("mcp", source);
29495
29704
  }
29496
- const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
29705
+ const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
29497
29706
  const compiled = compileMcp(
29498
29707
  sourceMcpJson,
29499
29708
  "copilot",
@@ -29516,13 +29725,13 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
29516
29725
  );
29517
29726
  }
29518
29727
  function syncRules2(config, sourceRoot, rulesSlot, options, logger, manifest, scopePath) {
29519
- const sourceRulesDir = path41.resolve(sourceRoot, config.source.rules);
29520
- if (!fs41.existsSync(sourceRulesDir)) {
29728
+ const sourceRulesDir = path42.resolve(sourceRoot, config.source.rules);
29729
+ if (!fs42.existsSync(sourceRulesDir)) {
29521
29730
  return [skippedMissingSource3("rules", sourceRulesDir)];
29522
29731
  }
29523
29732
  const destinationRoot = resolveTargetPath(rulesSlot);
29524
29733
  return compileCopilotRules(sourceRulesDir).map((file) => {
29525
- const destination = path41.join(destinationRoot, file.name);
29734
+ const destination = path42.join(destinationRoot, file.name);
29526
29735
  if (options.dryRun) {
29527
29736
  logger.info(`[dry-run] rules: compile -> ${destination}`);
29528
29737
  return {
@@ -29556,19 +29765,19 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
29556
29765
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
29557
29766
  return { component, status: "conflict", path: destination };
29558
29767
  }
29559
- ensureDir(path41.dirname(destination));
29768
+ ensureDir(path42.dirname(destination));
29560
29769
  const clearedLink = clearSymlinkAtDestination(destination);
29561
29770
  if (clearedLink !== null) {
29562
29771
  logger.verbose(
29563
29772
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
29564
29773
  );
29565
29774
  }
29566
- fs41.writeFileSync(destination, content);
29775
+ fs42.writeFileSync(destination, content);
29567
29776
  return { component, status: "success", path: destination };
29568
29777
  }
29569
29778
  function isCompiledCurrent2(destination, expectedContent, _expectedHash) {
29570
29779
  try {
29571
- return fs41.readFileSync(destination, "utf8") === expectedContent;
29780
+ return fs42.readFileSync(destination, "utf8") === expectedContent;
29572
29781
  } catch {
29573
29782
  return false;
29574
29783
  }
@@ -29588,7 +29797,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
29588
29797
  if (manifest && scopePath) {
29589
29798
  backupFile(destination, manifest, scopePath);
29590
29799
  writeManifest(scopePath, manifest);
29591
- fs41.rmSync(destination, { recursive: true, force: true });
29800
+ fs42.rmSync(destination, { recursive: true, force: true });
29592
29801
  } else {
29593
29802
  const parked = parkConflictingPath(
29594
29803
  destination,
@@ -29603,7 +29812,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
29603
29812
  }
29604
29813
  return true;
29605
29814
  }
29606
- fs41.rmSync(destination, { recursive: true, force: true });
29815
+ fs42.rmSync(destination, { recursive: true, force: true });
29607
29816
  return true;
29608
29817
  }
29609
29818
  function shouldSkipComponent3(options, component) {
@@ -29612,12 +29821,12 @@ function shouldSkipComponent3(options, component) {
29612
29821
  function cleanupLegacyAgents(paths, options, logger) {
29613
29822
  const currentAgentsRoot = resolveTargetPath(paths.agents);
29614
29823
  const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
29615
- if (path41.resolve(currentAgentsRoot) === path41.resolve(legacyAgentsRoot)) {
29824
+ if (path42.resolve(currentAgentsRoot) === path42.resolve(legacyAgentsRoot)) {
29616
29825
  return [];
29617
29826
  }
29618
29827
  const outcomes = [];
29619
29828
  for (const filePath of ts(
29620
- path41.join(legacyAgentsRoot, "*.agent.md")
29829
+ path42.join(legacyAgentsRoot, "*.agent.md")
29621
29830
  ).sort()) {
29622
29831
  if (!isCopilotManagedCompiledFile(filePath)) {
29623
29832
  continue;
@@ -29627,14 +29836,14 @@ function cleanupLegacyAgents(paths, options, logger) {
29627
29836
  outcomes.push({ component: "agents", status: "dry-run", path: filePath });
29628
29837
  continue;
29629
29838
  }
29630
- fs41.rmSync(filePath, { force: true });
29839
+ fs42.rmSync(filePath, { force: true });
29631
29840
  outcomes.push({ component: "agents", status: "success", path: filePath });
29632
29841
  }
29633
29842
  return outcomes;
29634
29843
  }
29635
29844
  function isCopilotManagedCompiledFile(filePath) {
29636
29845
  try {
29637
- return extractProvenanceMarker(fs41.readFileSync(filePath, "utf8"))?.target === "copilot";
29846
+ return extractProvenanceMarker(fs42.readFileSync(filePath, "utf8"))?.target === "copilot";
29638
29847
  } catch {
29639
29848
  return false;
29640
29849
  }
@@ -29649,8 +29858,8 @@ function skippedMissingSource3(component, source) {
29649
29858
 
29650
29859
  // src/adapters/cursor.ts
29651
29860
  import crypto8 from "crypto";
29652
- import fs42 from "fs";
29653
- import path42 from "path";
29861
+ import fs43 from "fs";
29862
+ import path43 from "path";
29654
29863
  function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29655
29864
  const scope = options.scope ?? "global";
29656
29865
  const profile = resolveTargetPaths({
@@ -29762,7 +29971,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
29762
29971
  if (!shouldSkipComponent4(options, "hooks")) {
29763
29972
  outcomes.push(
29764
29973
  syncHookScriptsBridge({
29765
- source: path42.resolve(sourceRoot, config.source.hooks),
29974
+ source: path43.resolve(sourceRoot, config.source.hooks),
29766
29975
  destination: resolveTargetPath(paths.hook_scripts),
29767
29976
  config,
29768
29977
  sourceRoot,
@@ -29827,7 +30036,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
29827
30036
  const composed = composeCursorInstructions(config, sourceRoot, lossReport);
29828
30037
  const marker = formatProvenanceMarker(
29829
30038
  "markdown",
29830
- path42.basename(instructionsSourceLabel(sourceRoot, config)),
30039
+ path43.basename(instructionsSourceLabel(sourceRoot, config)),
29831
30040
  hashString3(composed),
29832
30041
  "cursor"
29833
30042
  );
@@ -29853,7 +30062,7 @@ ${composed}
29853
30062
  }
29854
30063
  function composeCursorInstructions(config, sourceRoot, lossReport) {
29855
30064
  const source = instructionsSourcePath(sourceRoot, config);
29856
- const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
30065
+ const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
29857
30066
  const personaContent = extractPrimaryPersonaContent(
29858
30067
  config,
29859
30068
  sourceRoot,
@@ -29866,11 +30075,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
29866
30075
  ${personaContent}`.trim() : baseContent;
29867
30076
  }
29868
30077
  function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29869
- const agentsDir = path42.join(sourceRoot, config.source.agents);
29870
- if (!fs42.existsSync(agentsDir)) {
30078
+ const agentsDir = path43.join(sourceRoot, config.source.agents);
30079
+ if (!fs43.existsSync(agentsDir)) {
29871
30080
  return null;
29872
30081
  }
29873
- const agentFiles = ts(path42.join(agentsDir, "*.md")).sort();
30082
+ const agentFiles = ts(path43.join(agentsDir, "*.md")).sort();
29874
30083
  if (agentFiles.length === 0) {
29875
30084
  return null;
29876
30085
  }
@@ -29893,7 +30102,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29893
30102
  return null;
29894
30103
  }
29895
30104
  addLoss(lossReport, "cursor", "instructions", {
29896
- source: `agents/${path42.basename(primaryFile)}`,
30105
+ source: `agents/${path43.basename(primaryFile)}`,
29897
30106
  fields: [
29898
30107
  {
29899
30108
  field: "persona",
@@ -29903,23 +30112,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
29903
30112
  "persona",
29904
30113
  "instructions-shim"
29905
30114
  ),
29906
- detail: `Primary persona from ${path42.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
30115
+ detail: `Primary persona from ${path43.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
29907
30116
  }
29908
30117
  ]
29909
30118
  });
29910
30119
  return body.trim();
29911
30120
  }
29912
30121
  function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29913
- const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
29914
- if (!fs42.existsSync(sourceAgentsRoot)) {
30122
+ const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
30123
+ if (!fs43.existsSync(sourceAgentsRoot)) {
29915
30124
  return [skippedMissingSource4("agents", sourceAgentsRoot)];
29916
30125
  }
29917
- const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
30126
+ const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
29918
30127
  const agentsRoot = resolveTargetPath(paths.agents);
29919
30128
  return sourceAgents.map((agentFile) => {
29920
- const destination = path42.join(
30129
+ const destination = path43.join(
29921
30130
  agentsRoot,
29922
- `${path42.basename(agentFile, ".md")}.md`
30131
+ `${path43.basename(agentFile, ".md")}.md`
29923
30132
  );
29924
30133
  let compiled;
29925
30134
  try {
@@ -29960,14 +30169,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
29960
30169
  });
29961
30170
  }
29962
30171
  function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
29963
- const sourceRulesDir = path42.join(sourceRoot, config.source.rules);
29964
- if (!fs42.existsSync(sourceRulesDir)) {
30172
+ const sourceRulesDir = path43.join(sourceRoot, config.source.rules);
30173
+ if (!fs43.existsSync(sourceRulesDir)) {
29965
30174
  return [skippedMissingSource4("rules", sourceRulesDir)];
29966
30175
  }
29967
30176
  const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
29968
30177
  const rulesDir = resolveTargetPath(paths.rules);
29969
30178
  return compiled.dotRulesFiles.map(({ name, content }) => {
29970
- const destination = path42.join(rulesDir, name);
30179
+ const destination = path43.join(rulesDir, name);
29971
30180
  if (options.dryRun) {
29972
30181
  logger.info(`[dry-run] rules: write ${destination}`);
29973
30182
  return {
@@ -29991,15 +30200,15 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
29991
30200
  });
29992
30201
  }
29993
30202
  function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
29994
- const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
29995
- if (!fs42.existsSync(sourceCommandsRoot)) {
30203
+ const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
30204
+ if (!fs43.existsSync(sourceCommandsRoot)) {
29996
30205
  return [skippedMissingSource4("commands", sourceCommandsRoot)];
29997
30206
  }
29998
- const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
30207
+ const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
29999
30208
  const skillsRoot = resolveTargetPath(paths.skills);
30000
30209
  return sourceCommands.map((commandFile) => {
30001
- const baseName = path42.basename(commandFile, ".md");
30002
- const destination = path42.join(skillsRoot, baseName, "SKILL.md");
30210
+ const baseName = path43.basename(commandFile, ".md");
30211
+ const destination = path43.join(skillsRoot, baseName, "SKILL.md");
30003
30212
  const { content } = compileCommandAsSkill(commandFile, "cursor");
30004
30213
  if (options.dryRun) {
30005
30214
  logger.info(
@@ -30029,7 +30238,7 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, _
30029
30238
  return syncSkillsSlot({
30030
30239
  config,
30031
30240
  sourceRoot,
30032
- source: path42.resolve(sourceRoot, config.source.skills),
30241
+ source: path43.resolve(sourceRoot, config.source.skills),
30033
30242
  destination,
30034
30243
  dryRun: options.dryRun,
30035
30244
  logger,
@@ -30077,18 +30286,18 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
30077
30286
  }
30078
30287
  const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
30079
30288
  `;
30080
- ensureDir(path42.dirname(destination));
30081
- fs42.writeFileSync(destination, hooksFileContent);
30289
+ ensureDir(path43.dirname(destination));
30290
+ fs43.writeFileSync(destination, hooksFileContent);
30082
30291
  return { component: "hooks", status: "success", path: destination };
30083
30292
  }
30084
30293
  function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
30085
30294
  const source = resolveMcpSourceFile(sourceRoot, config);
30086
30295
  const sourceLabel = mcpSourceLabel(config);
30087
30296
  const destination = resolveTargetPath(paths.mcp_file);
30088
- if (!fs42.existsSync(source)) {
30297
+ if (!fs43.existsSync(source)) {
30089
30298
  return skippedMissingSource4("mcp", source);
30090
30299
  }
30091
- const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
30300
+ const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
30092
30301
  const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
30093
30302
  if (options.dryRun) {
30094
30303
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -30141,13 +30350,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
30141
30350
  );
30142
30351
  }
30143
30352
  function syncProviderPin(config, sourceRoot, lossReport) {
30144
- const agentsDir = path42.join(sourceRoot, config.source.agents);
30145
- if (!fs42.existsSync(agentsDir)) return;
30146
- for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
30353
+ const agentsDir = path43.join(sourceRoot, config.source.agents);
30354
+ if (!fs43.existsSync(agentsDir)) return;
30355
+ for (const agentFile of ts(path43.join(agentsDir, "*.md")).sort()) {
30147
30356
  const { data } = parseMarkdownFrontmatter(agentFile);
30148
30357
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30149
30358
  if (hasCustomProvider) {
30150
- const relativeSource = `agents/${path42.basename(agentFile)}`;
30359
+ const relativeSource = `agents/${path43.basename(agentFile)}`;
30151
30360
  addLoss(lossReport, "cursor", "agents", {
30152
30361
  source: relativeSource,
30153
30362
  fields: [
@@ -30159,7 +30368,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
30159
30368
  "provider",
30160
30369
  "provider-not-representable"
30161
30370
  ),
30162
- detail: `${path42.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
30371
+ detail: `${path43.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
30163
30372
  }
30164
30373
  ]
30165
30374
  });
@@ -30177,14 +30386,14 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
30177
30386
  if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
30178
30387
  return { component, status: "conflict", path: destination };
30179
30388
  }
30180
- ensureDir(path42.dirname(destination));
30389
+ ensureDir(path43.dirname(destination));
30181
30390
  const clearedLink = clearSymlinkAtDestination(destination);
30182
30391
  if (clearedLink !== null) {
30183
30392
  logger.verbose(
30184
30393
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
30185
30394
  );
30186
30395
  }
30187
- fs42.writeFileSync(destination, content);
30396
+ fs43.writeFileSync(destination, content);
30188
30397
  return { component, status: "success", path: destination };
30189
30398
  }
30190
30399
  function handleConflict4(destination, config, options, logger, manifest, scopePath) {
@@ -30202,7 +30411,7 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
30202
30411
  if (manifest && scopePath) {
30203
30412
  backupFile(destination, manifest, scopePath);
30204
30413
  writeManifest(scopePath, manifest);
30205
- fs42.rmSync(destination, { recursive: true, force: true });
30414
+ fs43.rmSync(destination, { recursive: true, force: true });
30206
30415
  } else {
30207
30416
  const parked = parkConflictingPath(
30208
30417
  destination,
@@ -30217,12 +30426,12 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
30217
30426
  }
30218
30427
  return true;
30219
30428
  }
30220
- fs42.rmSync(destination, { recursive: true, force: true });
30429
+ fs43.rmSync(destination, { recursive: true, force: true });
30221
30430
  return true;
30222
30431
  }
30223
30432
  function isCompiledCurrent3(destination, expectedContent, _expectedHash) {
30224
30433
  try {
30225
- return fs42.readFileSync(destination, "utf8") === expectedContent;
30434
+ return fs43.readFileSync(destination, "utf8") === expectedContent;
30226
30435
  } catch {
30227
30436
  return false;
30228
30437
  }
@@ -30243,8 +30452,8 @@ function hashString3(value) {
30243
30452
 
30244
30453
  // src/adapters/cline.ts
30245
30454
  import crypto9 from "crypto";
30246
- import fs43 from "fs";
30247
- import path43 from "path";
30455
+ import fs44 from "fs";
30456
+ import path44 from "path";
30248
30457
  function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30249
30458
  const scope = options.scope ?? "global";
30250
30459
  const profile = resolveTargetPaths({
@@ -30357,7 +30566,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
30357
30566
  function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
30358
30567
  if (scope === "global" || paths.instructions === null) {
30359
30568
  addLoss(lossReport, "cline", "instructions", {
30360
- source: path43.basename(instructionsSourceLabel(sourceRoot, config)),
30569
+ source: path44.basename(instructionsSourceLabel(sourceRoot, config)),
30361
30570
  fields: [
30362
30571
  {
30363
30572
  field: "instructions",
@@ -30379,10 +30588,10 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
30379
30588
  }
30380
30589
  const source = instructionsSourcePath(sourceRoot, config);
30381
30590
  const destination = resolveTargetPath(paths.instructions);
30382
- const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
30591
+ const baseContent = fs44.existsSync(source) ? fs44.readFileSync(source, "utf8").trim() : "";
30383
30592
  const marker = formatProvenanceMarker(
30384
30593
  "markdown",
30385
- path43.basename(instructionsSourceLabel(sourceRoot, config)),
30594
+ path44.basename(instructionsSourceLabel(sourceRoot, config)),
30386
30595
  hashString4(baseContent),
30387
30596
  "cline"
30388
30597
  );
@@ -30407,11 +30616,11 @@ ${baseContent}
30407
30616
  );
30408
30617
  }
30409
30618
  function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
30410
- const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
30411
- if (!fs43.existsSync(sourceAgentsRoot)) {
30619
+ const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
30620
+ if (!fs44.existsSync(sourceAgentsRoot)) {
30412
30621
  return [skippedMissingSource5("agents", sourceAgentsRoot)];
30413
30622
  }
30414
- const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
30623
+ const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
30415
30624
  return sourceAgents.map((agentFile) => {
30416
30625
  compileAgent(agentFile, "cline", mappings, extensions, lossReport);
30417
30626
  if (options.dryRun) {
@@ -30427,14 +30636,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
30427
30636
  });
30428
30637
  }
30429
30638
  function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
30430
- const sourceRulesDir = path43.join(sourceRoot, config.source.rules);
30431
- if (!fs43.existsSync(sourceRulesDir)) {
30639
+ const sourceRulesDir = path44.join(sourceRoot, config.source.rules);
30640
+ if (!fs44.existsSync(sourceRulesDir)) {
30432
30641
  return [skippedMissingSource5("rules", sourceRulesDir)];
30433
30642
  }
30434
30643
  const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
30435
30644
  const rulesDir = resolveTargetPath(paths.rules);
30436
30645
  return compiled.dotRulesFiles.map(({ name, content }) => {
30437
- const destination = path43.join(rulesDir, name);
30646
+ const destination = path44.join(rulesDir, name);
30438
30647
  if (options.dryRun) {
30439
30648
  logger.info(`[dry-run] rules: write ${destination}`);
30440
30649
  return {
@@ -30458,17 +30667,17 @@ function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, lo
30458
30667
  });
30459
30668
  }
30460
30669
  function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30461
- const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
30462
- if (!fs43.existsSync(sourceCommandsRoot)) {
30670
+ const sourceCommandsRoot = path44.join(sourceRoot, config.source.commands);
30671
+ if (!fs44.existsSync(sourceCommandsRoot)) {
30463
30672
  return [skippedMissingSource5("commands", sourceCommandsRoot)];
30464
30673
  }
30465
- const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
30674
+ const sourceCommands = ts(path44.join(sourceCommandsRoot, "*.md")).sort();
30466
30675
  const workflowsRoot = resolveTargetPath(paths.workflows);
30467
30676
  return sourceCommands.map((commandFile) => {
30468
- const baseName = path43.basename(commandFile);
30469
- const destination = path43.join(workflowsRoot, baseName);
30470
- const commandContent = fs43.readFileSync(commandFile, "utf8");
30471
- const relativeSource = `commands/${path43.basename(commandFile)}`;
30677
+ const baseName = path44.basename(commandFile);
30678
+ const destination = path44.join(workflowsRoot, baseName);
30679
+ const commandContent = fs44.readFileSync(commandFile, "utf8");
30680
+ const relativeSource = `commands/${path44.basename(commandFile)}`;
30472
30681
  const marker = formatProvenanceMarker(
30473
30682
  "markdown",
30474
30683
  relativeSource,
@@ -30506,7 +30715,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
30506
30715
  return syncSkillsSlot({
30507
30716
  config,
30508
30717
  sourceRoot,
30509
- source: path43.resolve(sourceRoot, config.source.skills),
30718
+ source: path44.resolve(sourceRoot, config.source.skills),
30510
30719
  destination: resolveTargetPath(paths.skills),
30511
30720
  dryRun: options.dryRun,
30512
30721
  logger,
@@ -30539,10 +30748,10 @@ function syncMcp5(config, sourceRoot, paths, options, lossReport, logger, manife
30539
30748
  const source = resolveMcpSourceFile(sourceRoot, config);
30540
30749
  const sourceLabel = mcpSourceLabel(config);
30541
30750
  const destination = resolveTargetPath(paths.mcp_file);
30542
- if (!fs43.existsSync(source)) {
30751
+ if (!fs44.existsSync(source)) {
30543
30752
  return skippedMissingSource5("mcp", source);
30544
30753
  }
30545
- const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
30754
+ const sourceMcpJson = JSON.parse(fs44.readFileSync(source, "utf8"));
30546
30755
  const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
30547
30756
  if (options.dryRun) {
30548
30757
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -30585,11 +30794,11 @@ function syncSettings2(lossReport) {
30585
30794
  };
30586
30795
  }
30587
30796
  function syncProviderAndModel(config, sourceRoot, lossReport) {
30588
- const agentsDir = path43.join(sourceRoot, config.source.agents);
30589
- if (!fs43.existsSync(agentsDir)) return;
30590
- for (const agentFile of ts(path43.join(agentsDir, "*.md")).sort()) {
30797
+ const agentsDir = path44.join(sourceRoot, config.source.agents);
30798
+ if (!fs44.existsSync(agentsDir)) return;
30799
+ for (const agentFile of ts(path44.join(agentsDir, "*.md")).sort()) {
30591
30800
  const { data } = parseMarkdownFrontmatter(agentFile);
30592
- const relativeSource = `agents/${path43.basename(agentFile)}`;
30801
+ const relativeSource = `agents/${path44.basename(agentFile)}`;
30593
30802
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30594
30803
  if (hasCustomProvider) {
30595
30804
  addLoss(lossReport, "cline", "agents", {
@@ -30603,7 +30812,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
30603
30812
  "provider",
30604
30813
  "provider-not-representable"
30605
30814
  ),
30606
- detail: `${path43.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
30815
+ detail: `${path44.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
30607
30816
  }
30608
30817
  ]
30609
30818
  });
@@ -30621,7 +30830,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
30621
30830
  "model",
30622
30831
  "model-not-representable"
30623
30832
  ),
30624
- detail: `${path43.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
30833
+ detail: `${path44.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
30625
30834
  }
30626
30835
  ]
30627
30836
  });
@@ -30639,14 +30848,14 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
30639
30848
  if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
30640
30849
  return { component, status: "conflict", path: destination };
30641
30850
  }
30642
- ensureDir(path43.dirname(destination));
30851
+ ensureDir(path44.dirname(destination));
30643
30852
  const clearedLink = clearSymlinkAtDestination(destination);
30644
30853
  if (clearedLink !== null) {
30645
30854
  logger.verbose(
30646
30855
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
30647
30856
  );
30648
30857
  }
30649
- fs43.writeFileSync(destination, content);
30858
+ fs44.writeFileSync(destination, content);
30650
30859
  return { component, status: "success", path: destination };
30651
30860
  }
30652
30861
  function handleConflict5(destination, config, options, logger, manifest, scopePath) {
@@ -30664,7 +30873,7 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
30664
30873
  if (manifest && scopePath) {
30665
30874
  backupFile(destination, manifest, scopePath);
30666
30875
  writeManifest(scopePath, manifest);
30667
- fs43.rmSync(destination, { recursive: true, force: true });
30876
+ fs44.rmSync(destination, { recursive: true, force: true });
30668
30877
  } else {
30669
30878
  const parked = parkConflictingPath(
30670
30879
  destination,
@@ -30679,12 +30888,12 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
30679
30888
  }
30680
30889
  return true;
30681
30890
  }
30682
- fs43.rmSync(destination, { recursive: true, force: true });
30891
+ fs44.rmSync(destination, { recursive: true, force: true });
30683
30892
  return true;
30684
30893
  }
30685
30894
  function isCompiledCurrent4(destination, expectedContent, _expectedHash) {
30686
30895
  try {
30687
- return fs43.readFileSync(destination, "utf8") === expectedContent;
30896
+ return fs44.readFileSync(destination, "utf8") === expectedContent;
30688
30897
  } catch {
30689
30898
  return false;
30690
30899
  }
@@ -30705,9 +30914,9 @@ function hashString4(value) {
30705
30914
 
30706
30915
  // src/adapters/opencode.ts
30707
30916
  import crypto10 from "crypto";
30708
- import fs44 from "fs";
30917
+ import fs45 from "fs";
30709
30918
  import os6 from "os";
30710
- import path44 from "path";
30919
+ import path45 from "path";
30711
30920
  var import_yaml12 = __toESM(require_dist(), 1);
30712
30921
  function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30713
30922
  const scope = options.scope ?? "global";
@@ -30725,7 +30934,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30725
30934
  config_doc: profile.config_doc
30726
30935
  };
30727
30936
  const rules = compileRules(
30728
- path44.join(sourceRoot, config.source.rules),
30937
+ path45.join(sourceRoot, config.source.rules),
30729
30938
  "opencode",
30730
30939
  mappings,
30731
30940
  lossReport
@@ -30733,7 +30942,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30733
30942
  const outcomes = [];
30734
30943
  if (!shouldSkipComponent6(options, "instructions")) {
30735
30944
  outcomes.push(
30736
- syncInstructions4(
30945
+ ...syncInstructions4(
30737
30946
  config,
30738
30947
  sourceRoot,
30739
30948
  paths,
@@ -30829,14 +31038,14 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
30829
31038
  function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
30830
31039
  const source = instructionsSourcePath(sourceRoot, config);
30831
31040
  const destination = resolveTargetPath(paths.instructions);
30832
- const baseContent = fs44.existsSync(source) ? fs44.readFileSync(source, "utf8").trim() : "";
31041
+ const baseContent = fs45.existsSync(source) ? fs45.readFileSync(source, "utf8").trim() : "";
30833
31042
  const composed = agentsAppendix ? `${baseContent}
30834
31043
 
30835
31044
  --- tangyr managed rules ---
30836
31045
  ${agentsAppendix}`.trim() : baseContent;
30837
31046
  const marker = formatProvenanceMarker(
30838
31047
  "markdown",
30839
- path44.basename(instructionsSourceLabel(sourceRoot, config)),
31048
+ path45.basename(instructionsSourceLabel(sourceRoot, config)),
30840
31049
  hashString5(composed),
30841
31050
  "opencode"
30842
31051
  );
@@ -30847,9 +31056,11 @@ ${composed}
30847
31056
  logger.info(
30848
31057
  `[dry-run] instructions: generate ${source} + rules appendix -> ${destination}`
30849
31058
  );
30850
- return { component: "instructions", status: "dry-run", path: destination };
31059
+ return [
31060
+ { component: "instructions", status: "dry-run", path: destination }
31061
+ ];
30851
31062
  }
30852
- return writeCompiledArtifact5(
31063
+ const written = writeCompiledArtifact5(
30853
31064
  "instructions",
30854
31065
  destination,
30855
31066
  content,
@@ -30861,18 +31072,60 @@ ${composed}
30861
31072
  manifest,
30862
31073
  scopePath
30863
31074
  );
31075
+ const declared = declareInstructions(paths);
31076
+ return declared === null ? [written] : [
31077
+ written,
31078
+ { component: "instructions", status: "success", path: declared }
31079
+ ];
31080
+ }
31081
+ function declaredInstructionsPath(paths) {
31082
+ const configDir = path45.dirname(resolveTargetPath(paths.config_doc));
31083
+ const instructions = resolveTargetPath(paths.instructions);
31084
+ const relative = path45.relative(configDir, instructions);
31085
+ if (relative === "AGENTS.md" || relative.startsWith("..")) {
31086
+ return null;
31087
+ }
31088
+ return relative.split(path45.sep).join("/");
31089
+ }
31090
+ function withDeclaredInstructions(existing, reference) {
31091
+ const listed = Array.isArray(existing) ? existing.filter((entry) => typeof entry === "string") : [];
31092
+ return listed.includes(reference) ? listed : [...listed, reference];
31093
+ }
31094
+ function declareInstructions(paths) {
31095
+ const reference = declaredInstructionsPath(paths);
31096
+ if (reference === null) {
31097
+ return null;
31098
+ }
31099
+ const destination = resolveTargetPath(paths.config_doc);
31100
+ let existing = {};
31101
+ if (fs45.existsSync(destination)) {
31102
+ try {
31103
+ existing = JSON.parse(fs45.readFileSync(destination, "utf8"));
31104
+ } catch {
31105
+ existing = {};
31106
+ }
31107
+ }
31108
+ const config = {
31109
+ $schema: "https://opencode.ai/config.json",
31110
+ ...existing,
31111
+ instructions: withDeclaredInstructions(existing.instructions, reference)
31112
+ };
31113
+ ensureDir(path45.dirname(destination));
31114
+ fs45.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31115
+ `);
31116
+ return destination;
30864
31117
  }
30865
31118
  function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30866
- const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
30867
- if (!fs44.existsSync(sourceAgentsRoot)) {
31119
+ const sourceAgentsRoot = path45.join(sourceRoot, config.source.agents);
31120
+ if (!fs45.existsSync(sourceAgentsRoot)) {
30868
31121
  return [skippedMissingSource6("agents", sourceAgentsRoot)];
30869
31122
  }
30870
- const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
31123
+ const sourceAgents = ts(path45.join(sourceAgentsRoot, "*.md")).sort();
30871
31124
  const agentsRoot = resolveTargetPath(paths.agents);
30872
31125
  return sourceAgents.map((agentFile) => {
30873
- const destination = path44.join(
31126
+ const destination = path45.join(
30874
31127
  agentsRoot,
30875
- `${path44.basename(agentFile, ".md")}.md`
31128
+ `${path45.basename(agentFile, ".md")}.md`
30876
31129
  );
30877
31130
  let compiled;
30878
31131
  try {
@@ -30936,11 +31189,11 @@ function applyProviderModelBinding(compiled, mappings) {
30936
31189
  return `${before}${(0, import_yaml12.stringify)(fields).trim()}${after}`;
30937
31190
  }
30938
31191
  function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30939
- const sourceCommandsRoot = path44.join(sourceRoot, config.source.commands);
30940
- if (!fs44.existsSync(sourceCommandsRoot)) {
31192
+ const sourceCommandsRoot = path45.join(sourceRoot, config.source.commands);
31193
+ if (!fs45.existsSync(sourceCommandsRoot)) {
30941
31194
  return [skippedMissingSource6("commands", sourceCommandsRoot)];
30942
31195
  }
30943
- const sourceCommands = ts(path44.join(sourceCommandsRoot, "*.md")).sort();
31196
+ const sourceCommands = ts(path45.join(sourceCommandsRoot, "*.md")).sort();
30944
31197
  const commandsRoot = resolveTargetPath(paths.commands);
30945
31198
  return sourceCommands.map((commandFile) => {
30946
31199
  const { data, body } = parseCommandFile(commandFile);
@@ -30954,7 +31207,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
30954
31207
  if (typeof data.model === "string") {
30955
31208
  frontmatter.model = data.model;
30956
31209
  }
30957
- const relativeSource = `commands/${path44.basename(commandFile)}`;
31210
+ const relativeSource = `commands/${path45.basename(commandFile)}`;
30958
31211
  const marker = formatProvenanceMarker(
30959
31212
  "markdown",
30960
31213
  relativeSource,
@@ -30970,9 +31223,9 @@ ${body.trimEnd()}
30970
31223
  ` : `${marker}
30971
31224
  ${body.trimEnd()}
30972
31225
  `;
30973
- const destination = path44.join(
31226
+ const destination = path45.join(
30974
31227
  commandsRoot,
30975
- `${path44.basename(commandFile, ".md")}.md`
31228
+ `${path45.basename(commandFile, ".md")}.md`
30976
31229
  );
30977
31230
  if (options.dryRun) {
30978
31231
  logger.info(
@@ -31002,7 +31255,7 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
31002
31255
  return syncSkillsSlot({
31003
31256
  config,
31004
31257
  sourceRoot,
31005
- source: path44.resolve(sourceRoot, config.source.skills),
31258
+ source: path45.resolve(sourceRoot, config.source.skills),
31006
31259
  destination,
31007
31260
  dryRun: options.dryRun,
31008
31261
  logger,
@@ -31020,13 +31273,13 @@ function syncMcp6(config, sourceRoot, paths, mappings, options, lossReport, logg
31020
31273
  const source = resolveMcpSourceFile(sourceRoot, config);
31021
31274
  const sourceLabel = mcpSourceLabel(config);
31022
31275
  const destination = resolveTargetPath(paths.config_doc);
31023
- if (!fs44.existsSync(source)) {
31276
+ if (!fs45.existsSync(source)) {
31024
31277
  if (!options.dryRun) {
31025
31278
  syncConfigDoc(paths, {}, lossReport, {}, mappings);
31026
31279
  }
31027
31280
  return skippedMissingSource6("mcp", source);
31028
31281
  }
31029
- const sourceMcpJson = JSON.parse(fs44.readFileSync(source, "utf8"));
31282
+ const sourceMcpJson = JSON.parse(fs45.readFileSync(source, "utf8"));
31030
31283
  const mcpJson = compileMcp(
31031
31284
  sourceMcpJson,
31032
31285
  "opencode",
@@ -31092,9 +31345,9 @@ function syncProviderBlock(mappings) {
31092
31345
  function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
31093
31346
  const destination = resolveTargetPath(paths.config_doc);
31094
31347
  let existing = {};
31095
- if (fs44.existsSync(destination)) {
31348
+ if (fs45.existsSync(destination)) {
31096
31349
  try {
31097
- existing = JSON.parse(fs44.readFileSync(destination, "utf8"));
31350
+ existing = JSON.parse(fs45.readFileSync(destination, "utf8"));
31098
31351
  } catch {
31099
31352
  existing = {};
31100
31353
  }
@@ -31107,6 +31360,13 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
31107
31360
  ...mcpEntries
31108
31361
  }
31109
31362
  };
31363
+ const instructionsRef = declaredInstructionsPath(paths);
31364
+ if (instructionsRef !== null) {
31365
+ config.instructions = withDeclaredInstructions(
31366
+ existing.instructions,
31367
+ instructionsRef
31368
+ );
31369
+ }
31110
31370
  if (Object.keys(permissionMap).length > 0) {
31111
31371
  config.permission = permissionMap;
31112
31372
  }
@@ -31119,8 +31379,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
31119
31379
  };
31120
31380
  }
31121
31381
  }
31122
- ensureDir(path44.dirname(destination));
31123
- fs44.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31382
+ ensureDir(path45.dirname(destination));
31383
+ fs45.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31124
31384
  `);
31125
31385
  }
31126
31386
  function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
@@ -31134,14 +31394,14 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
31134
31394
  if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
31135
31395
  return { component, status: "conflict", path: destination };
31136
31396
  }
31137
- ensureDir(path44.dirname(destination));
31397
+ ensureDir(path45.dirname(destination));
31138
31398
  const clearedLink = clearSymlinkAtDestination(destination);
31139
31399
  if (clearedLink !== null) {
31140
31400
  logger.verbose(
31141
31401
  ` ${destination}: replaced a symlink to ${clearedLink} with generated content`
31142
31402
  );
31143
31403
  }
31144
- fs44.writeFileSync(destination, content);
31404
+ fs45.writeFileSync(destination, content);
31145
31405
  return { component, status: "success", path: destination };
31146
31406
  }
31147
31407
  function handleConflict6(destination, config, options, logger, manifest, scopePath) {
@@ -31159,7 +31419,7 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
31159
31419
  if (manifest && scopePath) {
31160
31420
  backupFile(destination, manifest, scopePath);
31161
31421
  writeManifest(scopePath, manifest);
31162
- fs44.rmSync(destination, { recursive: true, force: true });
31422
+ fs45.rmSync(destination, { recursive: true, force: true });
31163
31423
  } else {
31164
31424
  const parked = parkConflictingPath(
31165
31425
  destination,
@@ -31174,12 +31434,12 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
31174
31434
  }
31175
31435
  return true;
31176
31436
  }
31177
- fs44.rmSync(destination, { recursive: true, force: true });
31437
+ fs45.rmSync(destination, { recursive: true, force: true });
31178
31438
  return true;
31179
31439
  }
31180
31440
  function isCompiledCurrent5(destination, expectedContent, _expectedHash) {
31181
31441
  try {
31182
- return fs44.readFileSync(destination, "utf8") === expectedContent;
31442
+ return fs45.readFileSync(destination, "utf8") === expectedContent;
31183
31443
  } catch {
31184
31444
  return false;
31185
31445
  }
@@ -31198,7 +31458,7 @@ function hashString5(value) {
31198
31458
  return `sha256:${crypto10.createHash("sha256").update(value).digest("hex")}`;
31199
31459
  }
31200
31460
  function parseCommandFile(commandFile) {
31201
- const content = fs44.readFileSync(commandFile, "utf8");
31461
+ const content = fs45.readFileSync(commandFile, "utf8");
31202
31462
  if (!content.startsWith("---\n")) {
31203
31463
  return { data: {}, body: content };
31204
31464
  }
@@ -31218,7 +31478,7 @@ function parseCommandFile(commandFile) {
31218
31478
  // src/commands/install.ts
31219
31479
  function isBackupablePath(targetPath) {
31220
31480
  try {
31221
- const lstat = fs45.lstatSync(targetPath);
31481
+ const lstat = fs46.lstatSync(targetPath);
31222
31482
  return lstat.isSymbolicLink() || lstat.isFile() || lstat.isDirectory();
31223
31483
  } catch {
31224
31484
  return false;
@@ -31255,7 +31515,7 @@ async function runInstallCommand(options, logger) {
31255
31515
  );
31256
31516
  }
31257
31517
  const kitName = resolvedKitName ?? config.kit;
31258
- const kitPath = kitPathOverride ?? (options.kitPath ? path45.resolve(options.kitPath) : config.kitPath);
31518
+ const kitPath = kitPathOverride ?? (options.kitPath ? path46.resolve(options.kitPath) : config.kitPath);
31259
31519
  if (!kitName && !kitPath) {
31260
31520
  logger.error(
31261
31521
  "No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
@@ -31360,8 +31620,8 @@ async function runInstallCommand(options, logger) {
31360
31620
  config: options.config,
31361
31621
  scope
31362
31622
  });
31363
- const skillsSource = path45.resolve(kitInfo.path, config.source.skills);
31364
- const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path45.basename(f.path) === "skills";
31623
+ const skillsSource = path46.resolve(kitInfo.path, config.source.skills);
31624
+ const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path46.basename(f.path) === "skills";
31365
31625
  const foreignSkillsSlots = new Set(
31366
31626
  assessResult.findings.filter(
31367
31627
  (f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
@@ -31399,7 +31659,7 @@ async function runInstallCommand(options, logger) {
31399
31659
  let instructionsLabel;
31400
31660
  try {
31401
31661
  const resolved = resolveInstructionsSource(kitInfo.path, config);
31402
- instructionsLabel = resolved ? path45.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
31662
+ instructionsLabel = resolved ? path46.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
31403
31663
  } catch (err) {
31404
31664
  logger.error(
31405
31665
  `[dry-run] ${err instanceof Error ? err.message : String(err)}`
@@ -31427,7 +31687,7 @@ async function runInstallCommand(options, logger) {
31427
31687
  }
31428
31688
  }
31429
31689
  logger.info(
31430
- `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path45.join(scopePath, "manifest.json")}`
31690
+ `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path46.join(scopePath, "manifest.json")}`
31431
31691
  );
31432
31692
  return;
31433
31693
  }
@@ -31486,7 +31746,7 @@ ACCEPTED CONFLICTS (posture: ${posture}; ${replaceable.length} target(s)):`
31486
31746
  logger.info(` - ${finding.path}`);
31487
31747
  logger.info(` source: ${sources}`);
31488
31748
  logger.info(
31489
- ` action: backup-and-replace${fs45.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
31749
+ ` action: backup-and-replace${fs46.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
31490
31750
  );
31491
31751
  logger.info(` backup: ${backupLocation}`);
31492
31752
  continue;
@@ -31594,11 +31854,29 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
31594
31854
  installLossReport
31595
31855
  );
31596
31856
  }
31857
+ const instructionsByTarget = instructionsByActiveTarget(
31858
+ tools,
31859
+ scope,
31860
+ projectRoot,
31861
+ mappings
31862
+ );
31863
+ const rulesCoverage = measureRulesCoverage(
31864
+ tools,
31865
+ kitInfo.components.rules?.declared ?? [],
31866
+ scope,
31867
+ projectRoot,
31868
+ mappings,
31869
+ installLossReport,
31870
+ instructionsByTarget
31871
+ );
31597
31872
  reportContestedInstructions(
31598
- instructionsByActiveTarget(tools, scope, projectRoot, mappings),
31873
+ instructionsByTarget,
31599
31874
  (kitInfo.components.rules?.declared.length ?? 0) > 0,
31600
- logger
31875
+ logger,
31876
+ missingRulesByTarget(rulesCoverage)
31601
31877
  );
31878
+ reportRulesCoverage(rulesCoverage, logger);
31879
+ recordRulesCoverageLoss(rulesCoverage, installLossReport);
31602
31880
  for (const [relativePath, sourcePath] of collectAllFiles(kitInfo, config)) {
31603
31881
  addFileToManifest(manifest, {
31604
31882
  relativePath,
@@ -31610,20 +31888,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
31610
31888
  writeManifest(scopePath, manifest);
31611
31889
  logger.info(`
31612
31890
  Installation complete: ${installedCount} files installed.`);
31613
- logger.info(`Manifest written to ${path45.join(scopePath, "manifest.json")}`);
31891
+ logger.info(`Manifest written to ${path46.join(scopePath, "manifest.json")}`);
31614
31892
  logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
31615
31893
  logger.info(`Scope: ${scope}`);
31616
31894
  logger.info(`Tools: ${tools.join(", ")}`);
31617
31895
  reportHookRejections(
31618
31896
  installLossReport,
31619
31897
  tools,
31620
- path45.resolve(kitInfo.path, "hooks"),
31898
+ path46.resolve(kitInfo.path, "hooks"),
31621
31899
  kitInfo.components.hooks.declared
31622
31900
  );
31623
31901
  const hooksConflict = reportHooksSourceConflict(
31624
31902
  installLossReport,
31625
31903
  tools,
31626
- path45.resolve(kitInfo.path, "hooks"),
31904
+ path46.resolve(kitInfo.path, "hooks"),
31627
31905
  kitInfo.components.hooks.declared
31628
31906
  );
31629
31907
  if (hooksConflict) {
@@ -31929,7 +32207,8 @@ function installClaudeCodeAdapterSlots(args) {
31929
32207
  profile,
31930
32208
  outcome,
31931
32209
  scope,
31932
- projectRoot
32210
+ projectRoot,
32211
+ mappings
31933
32212
  );
31934
32213
  if (!key) {
31935
32214
  continue;
@@ -31954,8 +32233,13 @@ function installClaudeCodeAdapterSlots(args) {
31954
32233
  }
31955
32234
  return count;
31956
32235
  }
31957
- function claudeCodeOutcomeToManifestKey(profile, outcome, scope, projectRoot) {
31958
- 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
+ );
31959
32243
  if (shared) {
31960
32244
  return shared;
31961
32245
  }
@@ -31982,7 +32266,7 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
31982
32266
  return 0;
31983
32267
  }
31984
32268
  try {
31985
- const stat = fs45.lstatSync(destination);
32269
+ const stat = fs46.lstatSync(destination);
31986
32270
  if (stat.isFile() && !stat.isSymbolicLink()) {
31987
32271
  logger.warn(
31988
32272
  `${destination}: a regular file occupies the skills slot \u2014 skipping skills. Move or remove it, then re-run install.`
@@ -32010,17 +32294,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
32010
32294
  manifest,
32011
32295
  scopePath
32012
32296
  );
32013
- const skillsSource = path45.resolve(kitInfo.path, config.source.skills);
32297
+ const skillsSource = path46.resolve(kitInfo.path, config.source.skills);
32014
32298
  let count = 0;
32015
32299
  for (const outcome of outcomes) {
32016
32300
  if (outcome.status !== "success" && outcome.status !== "skipped-current") {
32017
32301
  continue;
32018
32302
  }
32019
- const skillName = path45.basename(outcome.path);
32303
+ const skillName = path46.basename(outcome.path);
32020
32304
  addArtifactToManifest(manifest, {
32021
32305
  relativePath: `claude-code/skills/${skillName}`,
32022
32306
  path: outcome.path,
32023
- hash: describeArtifactState(outcome.path) ?? `dir:${path45.join(skillsSource, skillName)}`,
32307
+ hash: describeArtifactState(outcome.path) ?? `dir:${path46.join(skillsSource, skillName)}`,
32024
32308
  origin: "tangyr-managed"
32025
32309
  });
32026
32310
  count++;
@@ -32034,10 +32318,10 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
32034
32318
  logger.verbose(` skipped (operator choice): ${placement.destination}`);
32035
32319
  continue;
32036
32320
  }
32037
- const destDir = path45.dirname(placement.destination);
32038
- fs45.mkdirSync(destDir, { recursive: true });
32321
+ const destDir = path46.dirname(placement.destination);
32322
+ fs46.mkdirSync(destDir, { recursive: true });
32039
32323
  if (placement.type === "symlink") {
32040
- if (fs45.existsSync(placement.destination) || isSymlink2(placement.destination)) {
32324
+ if (fs46.existsSync(placement.destination) || isSymlink2(placement.destination)) {
32041
32325
  removeManagedPath(placement.destination);
32042
32326
  }
32043
32327
  createRelativeSymlink(
@@ -32054,7 +32338,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
32054
32338
  ` symlink: ${placement.source} \u2192 ${placement.destination}`
32055
32339
  );
32056
32340
  } else {
32057
- fs45.copyFileSync(placement.source, placement.destination);
32341
+ fs46.copyFileSync(placement.source, placement.destination);
32058
32342
  logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
32059
32343
  }
32060
32344
  addArtifactToManifest(manifest, {
@@ -32304,7 +32588,12 @@ function countInstalledArtifacts(outcomes) {
32304
32588
  ).length;
32305
32589
  }
32306
32590
  function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", projectRoot) {
32307
- const shared = sharedArtifactKey(outcome.path, scope, projectRoot);
32591
+ const shared = sharedKeyForDestination(
32592
+ outcome.path,
32593
+ scope,
32594
+ projectRoot,
32595
+ mappings.platformPaths
32596
+ );
32308
32597
  if (shared) {
32309
32598
  return shared;
32310
32599
  }
@@ -32346,11 +32635,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32346
32635
  if (outcome.path === mcpFile2) {
32347
32636
  return "cline/mcp.json";
32348
32637
  }
32349
- if (outcome.path.startsWith(`${workflowsRoot}${path45.sep}`)) {
32350
- return `cline/workflows/${path45.basename(outcome.path)}`;
32638
+ if (outcome.path.startsWith(`${workflowsRoot}${path46.sep}`)) {
32639
+ return `cline/workflows/${path46.basename(outcome.path)}`;
32351
32640
  }
32352
- if (outcome.path.startsWith(`${rulesRoot2}${path45.sep}`)) {
32353
- return `cline/rules/${path45.basename(outcome.path)}`;
32641
+ if (outcome.path.startsWith(`${rulesRoot2}${path46.sep}`)) {
32642
+ return `cline/rules/${path46.basename(outcome.path)}`;
32354
32643
  }
32355
32644
  return null;
32356
32645
  }
@@ -32386,14 +32675,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32386
32675
  if (outcome.path === permissionsFile) {
32387
32676
  return "cursor/permissions.json";
32388
32677
  }
32389
- if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
32390
- return `cursor/agents/${path45.basename(outcome.path)}`;
32678
+ if (outcome.path.startsWith(`${agentsRoot2}${path46.sep}`)) {
32679
+ return `cursor/agents/${path46.basename(outcome.path)}`;
32391
32680
  }
32392
- if (outcome.path.startsWith(`${rulesRoot2}${path45.sep}`)) {
32393
- return `cursor/rules/${path45.basename(outcome.path)}`;
32681
+ if (outcome.path.startsWith(`${rulesRoot2}${path46.sep}`)) {
32682
+ return `cursor/rules/${path46.basename(outcome.path)}`;
32394
32683
  }
32395
- if (outcome.path.startsWith(`${skillsRoot2}${path45.sep}`)) {
32396
- const rel = path45.relative(skillsRoot2, outcome.path);
32684
+ if (outcome.path.startsWith(`${skillsRoot2}${path46.sep}`)) {
32685
+ const rel = path46.relative(skillsRoot2, outcome.path);
32397
32686
  return `cursor/skills/${rel}`;
32398
32687
  }
32399
32688
  return null;
@@ -32419,14 +32708,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32419
32708
  if (outcome.path === skillsSharedRoot) {
32420
32709
  return "opencode/skills_shared";
32421
32710
  }
32422
- if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
32423
- return `opencode/agents/${path45.basename(outcome.path)}`;
32711
+ if (outcome.path.startsWith(`${agentsRoot2}${path46.sep}`)) {
32712
+ return `opencode/agents/${path46.basename(outcome.path)}`;
32424
32713
  }
32425
- if (outcome.path.startsWith(`${commandsRoot}${path45.sep}`)) {
32426
- return `opencode/commands/${path45.basename(outcome.path)}`;
32714
+ if (outcome.path.startsWith(`${commandsRoot}${path46.sep}`)) {
32715
+ return `opencode/commands/${path46.basename(outcome.path)}`;
32427
32716
  }
32428
32717
  if (outcome.path === configDocFile) {
32429
- return `opencode/${path45.basename(outcome.path)}`;
32718
+ return `opencode/${path46.basename(outcome.path)}`;
32430
32719
  }
32431
32720
  return null;
32432
32721
  }
@@ -32443,29 +32732,29 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32443
32732
  const hooksRoot = resolveTargetPath(copilot.hooks);
32444
32733
  const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
32445
32734
  const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
32446
- if (copilot.rules !== null && outcome.path.startsWith(`${resolveTargetPath(copilot.rules)}${path45.sep}`)) {
32447
- return `copilot/rules/${path45.relative(resolveTargetPath(copilot.rules), 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)}`;
32448
32737
  }
32449
- if (outcome.path.startsWith(`${skillsRoot2}${path45.sep}`)) {
32450
- return `copilot/skills/${path45.relative(skillsRoot2, outcome.path)}`;
32738
+ if (outcome.path.startsWith(`${skillsRoot2}${path46.sep}`)) {
32739
+ return `copilot/skills/${path46.relative(skillsRoot2, outcome.path)}`;
32451
32740
  }
32452
32741
  if (outcome.path === skillsRoot2) {
32453
32742
  return "copilot/skills";
32454
32743
  }
32455
32744
  if (instructionsMirror !== null && outcome.path === instructionsMirror) {
32456
- return `copilot/${path45.basename(outcome.path)}`;
32745
+ return `copilot/${path46.basename(outcome.path)}`;
32457
32746
  }
32458
- if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
32459
- return `copilot/agents/${path45.basename(outcome.path)}`;
32747
+ if (outcome.path.startsWith(`${agentsRoot2}${path46.sep}`)) {
32748
+ return `copilot/agents/${path46.basename(outcome.path)}`;
32460
32749
  }
32461
- if (outcome.path.startsWith(`${promptsRoot}${path45.sep}`)) {
32462
- return `copilot/prompts/${path45.basename(outcome.path)}`;
32750
+ if (outcome.path.startsWith(`${promptsRoot}${path46.sep}`)) {
32751
+ return `copilot/prompts/${path46.basename(outcome.path)}`;
32463
32752
  }
32464
- if (outcome.path.startsWith(`${hooksRoot}${path45.sep}`)) {
32465
- return `copilot/hooks/${path45.basename(outcome.path)}`;
32753
+ if (outcome.path.startsWith(`${hooksRoot}${path46.sep}`)) {
32754
+ return `copilot/hooks/${path46.basename(outcome.path)}`;
32466
32755
  }
32467
32756
  if (outcome.path === mcpFile2) {
32468
- return `copilot/${path45.basename(outcome.path)}`;
32757
+ return `copilot/${path46.basename(outcome.path)}`;
32469
32758
  }
32470
32759
  return null;
32471
32760
  }
@@ -32482,17 +32771,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
32482
32771
  if (outcome.path === skillsRoot) {
32483
32772
  return "codex/skills";
32484
32773
  }
32485
- if (outcome.path.startsWith(`${agentsRoot}${path45.sep}`)) {
32486
- return `codex/agents/${path45.basename(outcome.path)}`;
32774
+ if (outcome.path.startsWith(`${agentsRoot}${path46.sep}`)) {
32775
+ return `codex/agents/${path46.basename(outcome.path)}`;
32487
32776
  }
32488
- if (outcome.path.startsWith(`${rulesRoot}${path45.sep}`)) {
32489
- return `codex/rules/${path45.basename(outcome.path)}`;
32777
+ if (outcome.path.startsWith(`${rulesRoot}${path46.sep}`)) {
32778
+ return `codex/rules/${path46.basename(outcome.path)}`;
32490
32779
  }
32491
32780
  if (outcome.path === hooksFile) {
32492
- return `codex/${path45.basename(outcome.path)}`;
32781
+ return `codex/${path46.basename(outcome.path)}`;
32493
32782
  }
32494
32783
  if (outcome.path === mcpFile) {
32495
- return `codex/${path45.basename(outcome.path)}`;
32784
+ return `codex/${path46.basename(outcome.path)}`;
32496
32785
  }
32497
32786
  return null;
32498
32787
  }
@@ -32561,8 +32850,8 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
32561
32850
  rules: resolvedPaths.rules
32562
32851
  };
32563
32852
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
32564
- const componentDir = path45.join(kitInfo.path, component);
32565
- 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()) {
32566
32855
  placements.push({
32567
32856
  source: componentDir,
32568
32857
  destination: targetPath,
@@ -32592,8 +32881,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
32592
32881
  rules: profile.rules
32593
32882
  };
32594
32883
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
32595
- const componentDir = path45.join(kitInfo.path, component);
32596
- 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()) {
32597
32886
  placements.push({
32598
32887
  source: componentDir,
32599
32888
  destination: targetPath,
@@ -32609,7 +32898,7 @@ function collectAllFiles(kitInfo, config) {
32609
32898
  const files = /* @__PURE__ */ new Map();
32610
32899
  const entrypoint = resolveInstructionsSource(kitInfo.path, config);
32611
32900
  if (entrypoint) {
32612
- files.set(path45.basename(entrypoint.file), entrypoint.file);
32901
+ files.set(path46.basename(entrypoint.file), entrypoint.file);
32613
32902
  }
32614
32903
  for (const [component, reconciliation] of Object.entries(
32615
32904
  kitInfo.components
@@ -32618,22 +32907,22 @@ function collectAllFiles(kitInfo, config) {
32618
32907
  const missingSet = new Set(reconciliation.missing);
32619
32908
  for (const entry of reconciliation.declared) {
32620
32909
  if (missingSet.has(entry)) continue;
32621
- const relPath = isSkills ? path45.join(component, entry) : path45.join(component, `${entry}.md`);
32622
- 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));
32623
32912
  }
32624
32913
  }
32625
32914
  return files;
32626
32915
  }
32627
32916
  function readLinkTarget(p) {
32628
32917
  try {
32629
- return fs45.readlinkSync(p);
32918
+ return fs46.readlinkSync(p);
32630
32919
  } catch {
32631
32920
  return null;
32632
32921
  }
32633
32922
  }
32634
32923
  function isSymlink2(p) {
32635
32924
  try {
32636
- return fs45.lstatSync(p).isSymbolicLink();
32925
+ return fs46.lstatSync(p).isSymbolicLink();
32637
32926
  } catch {
32638
32927
  return false;
32639
32928
  }
@@ -32652,10 +32941,10 @@ function skillsSubPathKey(tool, outcomePath, mappings, scope, projectRoot) {
32652
32941
  continue;
32653
32942
  }
32654
32943
  const root = resolveTargetPath(slot);
32655
- if (!outcomePath.startsWith(`${root}${path45.sep}`)) {
32944
+ if (!outcomePath.startsWith(`${root}${path46.sep}`)) {
32656
32945
  continue;
32657
32946
  }
32658
- const inside = path45.relative(root, outcomePath).split(path45.sep).join("/");
32947
+ const inside = path46.relative(root, outcomePath).split(path46.sep).join("/");
32659
32948
  return `${tool}/skills/${inside}`;
32660
32949
  }
32661
32950
  return null;
@@ -32700,14 +32989,14 @@ async function runKitUpdateCommand(options, logger) {
32700
32989
  }
32701
32990
 
32702
32991
  // src/commands/list.ts
32703
- import path46 from "path";
32992
+ import path47 from "path";
32704
32993
  function runListCommand(options, logger) {
32705
32994
  let searchPaths = [];
32706
- let directKitPath = options.kitPath ? path46.resolve(options.kitPath) : void 0;
32995
+ let directKitPath = options.kitPath ? path47.resolve(options.kitPath) : void 0;
32707
32996
  try {
32708
32997
  const { config, configDir } = resolveConfig(options.config);
32709
32998
  searchPaths = config.kitSearchPaths ?? [
32710
- path46.join(configDir, "operating-kits")
32999
+ path47.join(configDir, "operating-kits")
32711
33000
  ];
32712
33001
  directKitPath = directKitPath ?? config.kitPath;
32713
33002
  } catch (err) {
@@ -32782,7 +33071,7 @@ function withDirectKit(kits, directKitPath) {
32782
33071
  return kits;
32783
33072
  }
32784
33073
  const directKit = loadKit(directKitPath);
32785
- if (kits.some((kit) => path46.resolve(kit.path) === directKit.path)) {
33074
+ if (kits.some((kit) => path47.resolve(kit.path) === directKit.path)) {
32786
33075
  return kits;
32787
33076
  }
32788
33077
  return [...kits, directKit];
@@ -32790,8 +33079,8 @@ function withDirectKit(kits, directKitPath) {
32790
33079
 
32791
33080
  // src/commands/probe.ts
32792
33081
  import { spawnSync as spawnSync2 } from "child_process";
32793
- import fs46 from "fs";
32794
- import path47 from "path";
33082
+ import fs47 from "fs";
33083
+ import path48 from "path";
32795
33084
  function runProbeCommand(options, logger) {
32796
33085
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
32797
33086
  options,
@@ -32819,7 +33108,7 @@ function runProbeCommand(options, logger) {
32819
33108
  toProbeRow(
32820
33109
  target,
32821
33110
  key,
32822
- scope === "project" ? path47.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
33111
+ scope === "project" ? path48.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
32823
33112
  )
32824
33113
  );
32825
33114
  }
@@ -32841,7 +33130,7 @@ function toProbeRow(target, key, rawPath) {
32841
33130
  const resolved = resolveTargetPath(rawPath);
32842
33131
  let accessible = false;
32843
33132
  try {
32844
- fs46.accessSync(resolved);
33133
+ fs47.accessSync(resolved);
32845
33134
  accessible = true;
32846
33135
  } catch {
32847
33136
  accessible = false;
@@ -32850,7 +33139,7 @@ function toProbeRow(target, key, rawPath) {
32850
33139
  target,
32851
33140
  key,
32852
33141
  path: resolved,
32853
- exists: fs46.existsSync(resolved),
33142
+ exists: fs47.existsSync(resolved),
32854
33143
  accessible
32855
33144
  };
32856
33145
  }
@@ -32868,7 +33157,7 @@ function codexRuntimeProbeRows() {
32868
33157
  ["binary_snap", "/snap/bin/codex"],
32869
33158
  ["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
32870
33159
  ]) {
32871
- if (fs46.existsSync(candidatePath)) {
33160
+ if (fs47.existsSync(candidatePath)) {
32872
33161
  rows.push(toProbeRow("codex", key, candidatePath));
32873
33162
  }
32874
33163
  }
@@ -32884,8 +33173,8 @@ function commandProbeRows(target, key, command, args) {
32884
33173
 
32885
33174
  // src/commands/status.ts
32886
33175
  import crypto11 from "crypto";
32887
- import fs47 from "fs";
32888
- import path48 from "path";
33176
+ import fs48 from "fs";
33177
+ import path49 from "path";
32889
33178
  function runStatusCommand(options, logger) {
32890
33179
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
32891
33180
  options,
@@ -32991,11 +33280,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
32991
33280
  }
32992
33281
  }
32993
33282
  function sourceMarkdownFiles(sourceRoot, componentPath) {
32994
- const root = path48.join(sourceRoot, componentPath);
32995
- if (!fs47.existsSync(root)) {
33283
+ const root = path49.join(sourceRoot, componentPath);
33284
+ if (!fs48.existsSync(root)) {
32996
33285
  return [];
32997
33286
  }
32998
- return ts(path48.join(root, "*.md")).sort();
33287
+ return ts(path49.join(root, "*.md")).sort();
32999
33288
  }
33000
33289
  function notRepresentableRow(component, detail) {
33001
33290
  return {
@@ -33006,11 +33295,11 @@ function notRepresentableRow(component, detail) {
33006
33295
  };
33007
33296
  }
33008
33297
  function readTargetJson(filePath) {
33009
- if (!fs47.existsSync(filePath)) {
33298
+ if (!fs48.existsSync(filePath)) {
33010
33299
  return { kind: "missing" };
33011
33300
  }
33012
33301
  try {
33013
- const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
33302
+ const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
33014
33303
  return { kind: "object", value: isRecord(parsed) ? parsed : {} };
33015
33304
  } catch (err) {
33016
33305
  return {
@@ -33099,7 +33388,7 @@ function classifyInstructions(filePath, target, expectedHash, config, sourceRoot
33099
33388
  }
33100
33389
  function compiledMcpDocument(config, sourceRoot, target) {
33101
33390
  const source = resolveMcpSourceFile(sourceRoot, config);
33102
- if (!fs47.existsSync(source)) {
33391
+ if (!fs48.existsSync(source)) {
33103
33392
  return {};
33104
33393
  }
33105
33394
  const compiled = compileMcp(
@@ -33112,7 +33401,7 @@ function compiledMcpDocument(config, sourceRoot, target) {
33112
33401
  return isRecord(parsed) ? parsed : {};
33113
33402
  }
33114
33403
  function classifyMcpDocument(config, sourceRoot, target, filePath) {
33115
- if (!fs47.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
33404
+ if (!fs48.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
33116
33405
  return notConfiguredRow("mcp", filePath);
33117
33406
  }
33118
33407
  return classifyJsonDocument(
@@ -33142,12 +33431,12 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
33142
33431
  const rows = [];
33143
33432
  const instructionsSource = instructionsSourcePath(sourceRoot, config);
33144
33433
  const rules = compileRules(
33145
- path48.join(sourceRoot, config.source.rules),
33434
+ path49.join(sourceRoot, config.source.rules),
33146
33435
  "opencode",
33147
33436
  mappings,
33148
33437
  createLossReport()
33149
33438
  );
33150
- const baseInstructions = fs47.existsSync(instructionsSource) ? fs47.readFileSync(instructionsSource, "utf8").trim() : "";
33439
+ const baseInstructions = fs48.existsSync(instructionsSource) ? fs48.readFileSync(instructionsSource, "utf8").trim() : "";
33151
33440
  const composedInstructions = rules.agentsAppendix ? `${baseInstructions}
33152
33441
 
33153
33442
  --- tangyr managed rules ---
@@ -33169,10 +33458,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
33169
33458
  )) {
33170
33459
  rows.push(
33171
33460
  classifyCompiledFile(
33172
- `agents/${path48.basename(agentFile, ".md")}`,
33173
- path48.join(
33461
+ `agents/${path49.basename(agentFile, ".md")}`,
33462
+ path49.join(
33174
33463
  resolveTargetPath(paths.agents),
33175
- `${path48.basename(agentFile, ".md")}.md`
33464
+ `${path49.basename(agentFile, ".md")}.md`
33176
33465
  ),
33177
33466
  "opencode",
33178
33467
  computeSourceHash(agentFile),
@@ -33187,10 +33476,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
33187
33476
  )) {
33188
33477
  rows.push(
33189
33478
  classifyCompiledFile(
33190
- `commands/${path48.basename(commandFile, ".md")}`,
33191
- path48.join(
33479
+ `commands/${path49.basename(commandFile, ".md")}`,
33480
+ path49.join(
33192
33481
  resolveTargetPath(paths.commands),
33193
- `${path48.basename(commandFile, ".md")}.md`
33482
+ `${path49.basename(commandFile, ".md")}.md`
33194
33483
  ),
33195
33484
  "opencode",
33196
33485
  computeSourceHash(commandFile),
@@ -33272,10 +33561,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33272
33561
  )) {
33273
33562
  rows.push(
33274
33563
  classifyCompiledFile(
33275
- `agents/${path48.basename(agentFile, ".md")}`,
33276
- path48.join(
33564
+ `agents/${path49.basename(agentFile, ".md")}`,
33565
+ path49.join(
33277
33566
  resolveTargetPath(paths.agents),
33278
- `${path48.basename(agentFile, ".md")}.md`
33567
+ `${path49.basename(agentFile, ".md")}.md`
33279
33568
  ),
33280
33569
  "cursor",
33281
33570
  computeSourceHash(agentFile),
@@ -33292,7 +33581,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33292
33581
  rows.push(
33293
33582
  classifyCompiledFile(
33294
33583
  `rules/${ruleFile.name}`,
33295
- path48.join(resolveTargetPath(paths.rules), ruleFile.name),
33584
+ path49.join(resolveTargetPath(paths.rules), ruleFile.name),
33296
33585
  "cursor",
33297
33586
  void 0,
33298
33587
  config,
@@ -33306,11 +33595,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33306
33595
  sourceRoot,
33307
33596
  config.source.commands
33308
33597
  )) {
33309
- const baseName = path48.basename(commandFile, ".md");
33598
+ const baseName = path49.basename(commandFile, ".md");
33310
33599
  rows.push(
33311
33600
  classifyCompiledFile(
33312
33601
  `commands/${baseName}`,
33313
- path48.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
33602
+ path49.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
33314
33603
  "cursor",
33315
33604
  computeSourceHash(commandFile),
33316
33605
  config,
@@ -33393,7 +33682,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33393
33682
  rows.push(
33394
33683
  classifyCompiledFile(
33395
33684
  `rules/${ruleFile.name}`,
33396
- path48.join(resolveTargetPath(paths.rules), ruleFile.name),
33685
+ path49.join(resolveTargetPath(paths.rules), ruleFile.name),
33397
33686
  "cline",
33398
33687
  void 0,
33399
33688
  config,
@@ -33409,10 +33698,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33409
33698
  )) {
33410
33699
  rows.push(
33411
33700
  classifyCompiledFile(
33412
- `commands/${path48.basename(commandFile, ".md")}`,
33413
- path48.join(
33701
+ `commands/${path49.basename(commandFile, ".md")}`,
33702
+ path49.join(
33414
33703
  resolveTargetPath(paths.workflows),
33415
- path48.basename(commandFile)
33704
+ path49.basename(commandFile)
33416
33705
  ),
33417
33706
  "cline",
33418
33707
  computeSourceHash(commandFile),
@@ -33453,14 +33742,14 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
33453
33742
  return rows;
33454
33743
  }
33455
33744
  function compileRulesFiles(config, sourceRoot, target, mappings) {
33456
- const rulesSource = path48.join(sourceRoot, config.source.rules);
33457
- if (!fs47.existsSync(rulesSource)) {
33745
+ const rulesSource = path49.join(sourceRoot, config.source.rules);
33746
+ if (!fs48.existsSync(rulesSource)) {
33458
33747
  return [];
33459
33748
  }
33460
33749
  return compileRules(rulesSource, target, mappings, createLossReport()).dotRulesFiles;
33461
33750
  }
33462
33751
  function classifyDirectoryPresence(component, dirPath) {
33463
- const present = fs47.existsSync(dirPath) && fs47.statSync(dirPath).isDirectory();
33752
+ const present = fs48.existsSync(dirPath) && fs48.statSync(dirPath).isDirectory();
33464
33753
  return {
33465
33754
  component,
33466
33755
  className: present ? "current" : "missing",
@@ -33479,7 +33768,7 @@ function slotsForScope2(scopeMap, scope, projectRoot) {
33479
33768
  const root = projectRoot ?? process.cwd();
33480
33769
  const resolved = {};
33481
33770
  for (const [slot, value] of Object.entries(projectSlots)) {
33482
- resolved[slot] = typeof value === "string" ? path48.resolve(root, value) : value;
33771
+ resolved[slot] = typeof value === "string" ? path49.resolve(root, value) : value;
33483
33772
  }
33484
33773
  return resolved;
33485
33774
  }
@@ -33499,21 +33788,21 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
33499
33788
  rules: paths.rules
33500
33789
  };
33501
33790
  const rules = compileRules(
33502
- path48.join(sourceRoot, config.source.rules),
33791
+ path49.join(sourceRoot, config.source.rules),
33503
33792
  "codex",
33504
33793
  mappings,
33505
33794
  createLossReport()
33506
33795
  );
33507
- const instructionsSource = fs47.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
33796
+ const instructionsSource = fs48.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
33508
33797
  const composedInstructions = `${instructionsSource}
33509
33798
 
33510
33799
  --- tangyr managed rules ---
33511
33800
  ${rules.agentsAppendix}`.trim();
33512
33801
  const agentFiles = ts(
33513
- path48.join(sourceRoot, config.source.agents, "*.md")
33802
+ path49.join(sourceRoot, config.source.agents, "*.md")
33514
33803
  ).sort();
33515
33804
  const hooksPresent = hooksSourceExists(sourceRoot, config);
33516
- const mcpSource = path48.join(sourceRoot, config.source.mcp);
33805
+ const mcpSource = path49.join(sourceRoot, config.source.mcp);
33517
33806
  const ruleRows = rules.dotRulesFiles.length === 0 ? [
33518
33807
  {
33519
33808
  component: "rules",
@@ -33524,7 +33813,7 @@ ${rules.agentsAppendix}`.trim();
33524
33813
  ] : rules.dotRulesFiles.map(
33525
33814
  (ruleFile) => classifyCompiledFile(
33526
33815
  `rules/${ruleFile.name}`,
33527
- path48.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
33816
+ path49.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
33528
33817
  "codex",
33529
33818
  void 0,
33530
33819
  config,
@@ -33542,10 +33831,10 @@ ${rules.agentsAppendix}`.trim();
33542
33831
  ),
33543
33832
  ...agentFiles.map(
33544
33833
  (agentFile) => classifyCompiledFile(
33545
- `agents/${path48.basename(agentFile, ".md")}`,
33546
- path48.join(
33834
+ `agents/${path49.basename(agentFile, ".md")}`,
33835
+ path49.join(
33547
33836
  resolveTargetPath(codexPaths.agents),
33548
- `${path48.basename(agentFile, ".md")}.toml`
33837
+ `${path49.basename(agentFile, ".md")}.toml`
33549
33838
  ),
33550
33839
  "codex",
33551
33840
  computeSourceHash(agentFile),
@@ -33573,7 +33862,7 @@ ${rules.agentsAppendix}`.trim();
33573
33862
  "hooks",
33574
33863
  resolveTargetPath(codexPaths.hooksSharedFile)
33575
33864
  ),
33576
- fs47.existsSync(mcpSource) ? classifyCompiledFile(
33865
+ fs48.existsSync(mcpSource) ? classifyCompiledFile(
33577
33866
  "mcp",
33578
33867
  resolveTargetPath(codexPaths.mcpSharedFile),
33579
33868
  "codex",
@@ -33639,20 +33928,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33639
33928
  mcpSharedFile: paths.mcp_shared_file
33640
33929
  };
33641
33930
  const agentFiles = ts(
33642
- path48.join(sourceRoot, config.source.agents, "*.md")
33931
+ path49.join(sourceRoot, config.source.agents, "*.md")
33643
33932
  ).sort();
33644
33933
  const commandFiles = ts(
33645
- path48.join(sourceRoot, config.source.commands, "*.md")
33934
+ path49.join(sourceRoot, config.source.commands, "*.md")
33646
33935
  ).sort();
33647
33936
  const hooksPresent = hooksSourceExists(sourceRoot, config);
33648
- const mcpSource = path48.join(sourceRoot, config.source.mcp);
33937
+ const mcpSource = path49.join(sourceRoot, config.source.mcp);
33649
33938
  return [
33650
33939
  ...agentFiles.map(
33651
33940
  (agentFile) => classifyCompiledFile(
33652
- `agents/${path48.basename(agentFile, ".md")}`,
33653
- path48.join(
33941
+ `agents/${path49.basename(agentFile, ".md")}`,
33942
+ path49.join(
33654
33943
  resolveTargetPath(copilotPaths.agents),
33655
- `${path48.basename(agentFile, ".md")}.agent.md`
33944
+ `${path49.basename(agentFile, ".md")}.agent.md`
33656
33945
  ),
33657
33946
  "copilot",
33658
33947
  computeSourceHash(agentFile),
@@ -33669,10 +33958,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33669
33958
  ),
33670
33959
  ...commandFiles.map(
33671
33960
  (commandFile) => classifyCompiledFile(
33672
- `commands/${path48.basename(commandFile, ".md")}`,
33673
- path48.join(
33961
+ `commands/${path49.basename(commandFile, ".md")}`,
33962
+ path49.join(
33674
33963
  resolveTargetPath(copilotPaths.prompts),
33675
- `${path48.basename(commandFile, ".md")}.prompt.md`
33964
+ `${path49.basename(commandFile, ".md")}.prompt.md`
33676
33965
  ),
33677
33966
  "copilot",
33678
33967
  computeSourceHash(commandFile),
@@ -33691,19 +33980,19 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
33691
33980
  sourceRoot
33692
33981
  ),
33693
33982
  hooksPresent ? classifyCompiledHooksByProvenance(
33694
- path48.join(
33983
+ path49.join(
33695
33984
  resolveTargetPath(copilotPaths.hooks),
33696
33985
  "tangyr-managed.json"
33697
33986
  ),
33698
33987
  "copilot"
33699
33988
  ) : notConfiguredRow(
33700
33989
  "hooks",
33701
- path48.join(
33990
+ path49.join(
33702
33991
  resolveTargetPath(copilotPaths.hooks),
33703
33992
  "tangyr-managed.json"
33704
33993
  )
33705
33994
  ),
33706
- fs47.existsSync(mcpSource) ? classifyCompiledFile(
33995
+ fs48.existsSync(mcpSource) ? classifyCompiledFile(
33707
33996
  "mcp",
33708
33997
  resolveTargetPath(copilotPaths.mcpSharedFile),
33709
33998
  "copilot",
@@ -33723,7 +34012,7 @@ function notConfiguredRow(component, filePath) {
33723
34012
  }
33724
34013
  function classifyDirectArtifact(artifact, config, sourceRoot) {
33725
34014
  const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
33726
- 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;
33727
34016
  if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
33728
34017
  const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
33729
34018
  if (perSkill) {
@@ -33819,11 +34108,11 @@ function classifyClaudeCodeRows(sourceRoot, config, configDir, scope, projectRoo
33819
34108
  function classifyPerSkillSlot(slotPath, sourceRoot) {
33820
34109
  let entries;
33821
34110
  try {
33822
- const stat = fs47.lstatSync(slotPath);
34111
+ const stat = fs48.lstatSync(slotPath);
33823
34112
  if (!stat.isDirectory() || stat.isSymbolicLink()) {
33824
34113
  return null;
33825
34114
  }
33826
- entries = fs47.readdirSync(slotPath, { withFileTypes: true });
34115
+ entries = fs48.readdirSync(slotPath, { withFileTypes: true });
33827
34116
  } catch {
33828
34117
  return null;
33829
34118
  }
@@ -33835,7 +34124,7 @@ function classifyPerSkillSlot(slotPath, sourceRoot) {
33835
34124
  return null;
33836
34125
  }
33837
34126
  const ours = links.filter(
33838
- (entry) => isOurSymlink(path48.join(slotPath, entry.name), sourceRoot)
34127
+ (entry) => isOurSymlink(path49.join(slotPath, entry.name), sourceRoot)
33839
34128
  );
33840
34129
  if (ours.length === 0) {
33841
34130
  return null;
@@ -33847,9 +34136,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
33847
34136
  classifyHooks(settingsPath),
33848
34137
  classifySettings(
33849
34138
  settingsPath,
33850
- path48.resolve(sourceRoot, config.source.settings)
34139
+ path49.resolve(sourceRoot, config.source.settings)
33851
34140
  ),
33852
- classifyMcp(claudeJsonPath, path48.resolve(sourceRoot, config.source.mcp))
34141
+ classifyMcp(claudeJsonPath, path49.resolve(sourceRoot, config.source.mcp))
33853
34142
  ];
33854
34143
  }
33855
34144
  function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
@@ -33946,14 +34235,14 @@ function classifyMcp(filePath, sourcePath) {
33946
34235
  }
33947
34236
  function isSymlinkCurrent(linkPath, sourcePath) {
33948
34237
  try {
33949
- return fs47.realpathSync(linkPath) === fs47.realpathSync(sourcePath);
34238
+ return fs48.realpathSync(linkPath) === fs48.realpathSync(sourcePath);
33950
34239
  } catch {
33951
34240
  return false;
33952
34241
  }
33953
34242
  }
33954
34243
  function isCompiledCurrent6(filePath, sourcePath) {
33955
34244
  try {
33956
- const marker = extractProvenanceMarker(fs47.readFileSync(filePath, "utf8"));
34245
+ const marker = extractProvenanceMarker(fs48.readFileSync(filePath, "utf8"));
33957
34246
  return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
33958
34247
  } catch {
33959
34248
  return false;
@@ -33983,7 +34272,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
33983
34272
  }
33984
34273
  function readCompiledContent(filePath) {
33985
34274
  try {
33986
- return fs47.readFileSync(filePath, "utf8");
34275
+ return fs48.readFileSync(filePath, "utf8");
33987
34276
  } catch {
33988
34277
  return null;
33989
34278
  }
@@ -34014,8 +34303,8 @@ function hashString6(value) {
34014
34303
  }
34015
34304
 
34016
34305
  // src/commands/sync.ts
34017
- import fs48 from "fs";
34018
- import path49 from "path";
34306
+ import fs49 from "fs";
34307
+ import path50 from "path";
34019
34308
 
34020
34309
  // node_modules/chalk/source/vendor/ansi-styles/index.js
34021
34310
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -34685,29 +34974,42 @@ async function runSyncCommand(options, logger) {
34685
34974
  reportHookRejections(
34686
34975
  lossReport,
34687
34976
  targets,
34688
- path49.resolve(kitInfo.path, "hooks"),
34977
+ path50.resolve(kitInfo.path, "hooks"),
34689
34978
  kitInfo.components.hooks.declared
34690
34979
  );
34691
34980
  const hooksConflict = reportHooksSourceConflict(
34692
34981
  lossReport,
34693
34982
  targets,
34694
- path49.resolve(kitInfo.path, "hooks"),
34983
+ path50.resolve(kitInfo.path, "hooks"),
34695
34984
  kitInfo.components.hooks.declared
34696
34985
  );
34697
34986
  if (hooksConflict) {
34698
34987
  logger.warn(hooksConflict);
34699
34988
  }
34700
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
+ );
34701
35005
  reportContestedInstructions(
34702
- instructionsByActiveTarget(
34703
- targets,
34704
- syncOptions.scope,
34705
- syncOptions.projectRoot,
34706
- allMappings
34707
- ),
35006
+ instructionsByTarget,
34708
35007
  kitInfo.components.rules.declared.length > 0,
34709
- logger
35008
+ logger,
35009
+ missingRulesByTarget(rulesCoverage)
34710
35010
  );
35011
+ reportRulesCoverage(rulesCoverage, logger);
35012
+ recordRulesCoverageLoss(rulesCoverage, lossReport);
34711
35013
  }
34712
35014
  }
34713
35015
  writeLossReport(options.lossReport, lossReport);
@@ -34894,8 +35196,8 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
34894
35196
  }
34895
35197
  }
34896
35198
  function resolveKitFilePath(kitPath, relativePath) {
34897
- const fullPath = path49.join(kitPath, relativePath);
34898
- return fs48.existsSync(fullPath) ? fullPath : null;
35199
+ const fullPath = path50.join(kitPath, relativePath);
35200
+ return fs49.existsSync(fullPath) ? fullPath : null;
34899
35201
  }
34900
35202
  function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
34901
35203
  if (removedSourcePaths.length === 0 || !mappings) {
@@ -34958,9 +35260,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34958
35260
  }
34959
35261
  if (relativePath.startsWith("agents/")) {
34960
35262
  removeManagedCompiledArtifact2(
34961
- path49.join(
35263
+ path50.join(
34962
35264
  resolveTargetPath(paths.agents ?? ""),
34963
- `${path49.parse(relativePath).name}.agent.md`
35265
+ `${path50.parse(relativePath).name}.agent.md`
34964
35266
  ),
34965
35267
  "copilot",
34966
35268
  relativePath,
@@ -34970,9 +35272,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34970
35272
  }
34971
35273
  if (relativePath.startsWith("commands/")) {
34972
35274
  removeManagedCompiledArtifact2(
34973
- path49.join(
35275
+ path50.join(
34974
35276
  resolveTargetPath(paths.prompts ?? ""),
34975
- `${path49.parse(relativePath).name}.prompt.md`
35277
+ `${path50.parse(relativePath).name}.prompt.md`
34976
35278
  ),
34977
35279
  "copilot",
34978
35280
  relativePath,
@@ -34982,7 +35284,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
34982
35284
  }
34983
35285
  if (relativePath.endsWith("hooks.json")) {
34984
35286
  removeManagedCompiledArtifact2(
34985
- path49.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
35287
+ path50.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
34986
35288
  "copilot",
34987
35289
  relativePath,
34988
35290
  logger
@@ -35012,9 +35314,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
35012
35314
  }
35013
35315
  if (relativePath.startsWith("agents/")) {
35014
35316
  removeManagedCompiledArtifact2(
35015
- path49.join(
35317
+ path50.join(
35016
35318
  resolveTargetPath(paths.agents ?? ""),
35017
- `${path49.parse(relativePath).name}.toml`
35319
+ `${path50.parse(relativePath).name}.toml`
35018
35320
  ),
35019
35321
  "codex",
35020
35322
  relativePath,
@@ -35024,9 +35326,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
35024
35326
  }
35025
35327
  if (relativePath.startsWith("rules/")) {
35026
35328
  removeManagedCompiledArtifact2(
35027
- path49.join(
35329
+ path50.join(
35028
35330
  resolveTargetPath(paths.rules ?? ""),
35029
- `${path49.parse(relativePath).name}.rules`
35331
+ `${path50.parse(relativePath).name}.rules`
35030
35332
  ),
35031
35333
  "codex",
35032
35334
  relativePath,
@@ -35065,9 +35367,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
35065
35367
  }
35066
35368
  if (relativePath.startsWith("agents/")) {
35067
35369
  removeManagedCompiledArtifact2(
35068
- path49.join(
35370
+ path50.join(
35069
35371
  resolveTargetPath(paths.agents ?? ""),
35070
- `${path49.parse(relativePath).name}.md`
35372
+ `${path50.parse(relativePath).name}.md`
35071
35373
  ),
35072
35374
  "opencode",
35073
35375
  relativePath,
@@ -35077,9 +35379,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
35077
35379
  }
35078
35380
  if (relativePath.startsWith("commands/")) {
35079
35381
  removeManagedCompiledArtifact2(
35080
- path49.join(
35382
+ path50.join(
35081
35383
  resolveTargetPath(paths.commands ?? ""),
35082
- `${path49.parse(relativePath).name}.md`
35384
+ `${path50.parse(relativePath).name}.md`
35083
35385
  ),
35084
35386
  "opencode",
35085
35387
  relativePath,
@@ -35111,9 +35413,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35111
35413
  }
35112
35414
  if (relativePath.startsWith("agents/")) {
35113
35415
  removeManagedCompiledArtifact2(
35114
- path49.join(
35416
+ path50.join(
35115
35417
  resolveTargetPath(paths.agents ?? ""),
35116
- `${path49.parse(relativePath).name}.md`
35418
+ `${path50.parse(relativePath).name}.md`
35117
35419
  ),
35118
35420
  "cursor",
35119
35421
  relativePath,
@@ -35123,9 +35425,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35123
35425
  }
35124
35426
  if (relativePath.startsWith("rules/")) {
35125
35427
  removeManagedCompiledArtifact2(
35126
- path49.join(
35428
+ path50.join(
35127
35429
  resolveTargetPath(paths.rules ?? ""),
35128
- `${path49.parse(relativePath).name}.mdc`
35430
+ `${path50.parse(relativePath).name}.mdc`
35129
35431
  ),
35130
35432
  "cursor",
35131
35433
  relativePath,
@@ -35135,9 +35437,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35135
35437
  }
35136
35438
  if (relativePath.startsWith("commands/")) {
35137
35439
  removeManagedCompiledArtifact2(
35138
- path49.join(
35440
+ path50.join(
35139
35441
  resolveTargetPath(paths.skills ?? ""),
35140
- path49.parse(relativePath).name,
35442
+ path50.parse(relativePath).name,
35141
35443
  "SKILL.md"
35142
35444
  ),
35143
35445
  "cursor",
@@ -35181,9 +35483,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35181
35483
  }
35182
35484
  if (relativePath.startsWith("rules/")) {
35183
35485
  removeManagedCompiledArtifact2(
35184
- path49.join(
35486
+ path50.join(
35185
35487
  resolveTargetPath(paths.rules ?? ""),
35186
- `${path49.parse(relativePath).name}.md`
35488
+ `${path50.parse(relativePath).name}.md`
35187
35489
  ),
35188
35490
  "cline",
35189
35491
  relativePath,
@@ -35193,9 +35495,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35193
35495
  }
35194
35496
  if (relativePath.startsWith("commands/")) {
35195
35497
  removeManagedCompiledArtifact2(
35196
- path49.join(
35498
+ path50.join(
35197
35499
  resolveTargetPath(paths.workflows ?? ""),
35198
- path49.basename(relativePath)
35500
+ path50.basename(relativePath)
35199
35501
  ),
35200
35502
  "cline",
35201
35503
  relativePath,
@@ -35213,17 +35515,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35213
35515
  }
35214
35516
  }
35215
35517
  function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
35216
- if (!fs48.existsSync(artifactPath)) {
35518
+ if (!fs49.existsSync(artifactPath)) {
35217
35519
  return;
35218
35520
  }
35219
- if (!fs48.statSync(artifactPath).isFile()) {
35521
+ if (!fs49.statSync(artifactPath).isFile()) {
35220
35522
  return;
35221
35523
  }
35222
- const marker = extractProvenanceMarker(fs48.readFileSync(artifactPath, "utf8"));
35524
+ const marker = extractProvenanceMarker(fs49.readFileSync(artifactPath, "utf8"));
35223
35525
  if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
35224
35526
  return;
35225
35527
  }
35226
- fs48.rmSync(artifactPath, { force: true });
35528
+ fs49.rmSync(artifactPath, { force: true });
35227
35529
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
35228
35530
  }
35229
35531
  function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
@@ -35254,10 +35556,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
35254
35556
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
35255
35557
  }
35256
35558
  function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
35257
- if (!fs48.existsSync(artifactPath)) {
35559
+ if (!fs49.existsSync(artifactPath)) {
35258
35560
  return;
35259
35561
  }
35260
- const content = fs48.readFileSync(artifactPath, "utf8");
35562
+ const content = fs49.readFileSync(artifactPath, "utf8");
35261
35563
  const startMarker = "# tangyr: managed mcp start";
35262
35564
  const endMarker = "# tangyr: managed mcp end";
35263
35565
  const startIndex = content.indexOf(startMarker);
@@ -35274,19 +35576,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
35274
35576
  const after = content.slice(endIndex + endMarker.length).trimStart();
35275
35577
  const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
35276
35578
  if (cleaned.length === 0) {
35277
- fs48.rmSync(artifactPath, { force: true });
35579
+ fs49.rmSync(artifactPath, { force: true });
35278
35580
  } else {
35279
- fs48.writeFileSync(artifactPath, `${cleaned}
35581
+ fs49.writeFileSync(artifactPath, `${cleaned}
35280
35582
  `);
35281
35583
  }
35282
35584
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
35283
35585
  }
35284
35586
  function readJsonObject5(filePath) {
35285
- if (!fs48.existsSync(filePath)) {
35587
+ if (!fs49.existsSync(filePath)) {
35286
35588
  return null;
35287
35589
  }
35288
35590
  try {
35289
- const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
35591
+ const parsed = JSON.parse(fs49.readFileSync(filePath, "utf8"));
35290
35592
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
35291
35593
  } catch {
35292
35594
  return null;
@@ -35300,10 +35602,10 @@ function readJsonMetadata(value) {
35300
35602
  }
35301
35603
  function writeJsonOrRemove2(filePath, parsed) {
35302
35604
  if (isEmptyJsonValue2(parsed)) {
35303
- fs48.rmSync(filePath, { force: true });
35605
+ fs49.rmSync(filePath, { force: true });
35304
35606
  return;
35305
35607
  }
35306
- fs48.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
35608
+ fs49.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
35307
35609
  `);
35308
35610
  }
35309
35611
  function isEmptyJsonValue2(value) {
@@ -35363,8 +35665,8 @@ function removeManagedHookEntries(value, expectedSource) {
35363
35665
  }
35364
35666
 
35365
35667
  // src/commands/validate.ts
35366
- import fs49 from "fs";
35367
- import path50 from "path";
35668
+ import fs50 from "fs";
35669
+ import path51 from "path";
35368
35670
  var SUPPORTED_KIT_FORMATS2 = [1];
35369
35671
  var SUPPORTED_DISCIPLINE_VERSIONS = [
35370
35672
  "0.14.0",
@@ -35479,12 +35781,12 @@ function checkArchetype(kit) {
35479
35781
  }
35480
35782
  function checkHookScriptsExist(kit) {
35481
35783
  const violations = [];
35482
- const hooksDir = path50.join(kit.path, "hooks");
35784
+ const hooksDir = path51.join(kit.path, "hooks");
35483
35785
  const missingSet = new Set(kit.components.hooks.missing);
35484
35786
  for (const name of kit.components.hooks.declared) {
35485
35787
  if (missingSet.has(name)) continue;
35486
- const declarationPath = path50.join(hooksDir, `${name}.md`);
35487
- if (!fs49.existsSync(declarationPath)) continue;
35788
+ const declarationPath = path51.join(hooksDir, `${name}.md`);
35789
+ if (!fs50.existsSync(declarationPath)) continue;
35488
35790
  let data;
35489
35791
  try {
35490
35792
  ({ data } = parseMarkdownFrontmatter(declarationPath));
@@ -35494,8 +35796,8 @@ function checkHookScriptsExist(kit) {
35494
35796
  if (typeof data.command === "string" && data.command.trim().length > 0) {
35495
35797
  continue;
35496
35798
  }
35497
- const scriptPath = path50.join(hooksDir, "scripts", `${name}.ts`);
35498
- if (!fs49.existsSync(scriptPath)) {
35799
+ const scriptPath = path51.join(hooksDir, "scripts", `${name}.ts`);
35800
+ if (!fs50.existsSync(scriptPath)) {
35499
35801
  violations.push({
35500
35802
  code: "hook-script-missing",
35501
35803
  location: `hooks/scripts/${name}.ts`,
@@ -35508,10 +35810,10 @@ function checkHookScriptsExist(kit) {
35508
35810
  function checkOptionalSourceDocuments(kit) {
35509
35811
  const violations = [];
35510
35812
  for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
35511
- const filePath = path50.join(kit.path, name);
35512
- if (!fs49.existsSync(filePath)) continue;
35813
+ const filePath = path51.join(kit.path, name);
35814
+ if (!fs50.existsSync(filePath)) continue;
35513
35815
  try {
35514
- const parsed = JSON.parse(fs49.readFileSync(filePath, "utf8"));
35816
+ const parsed = JSON.parse(fs50.readFileSync(filePath, "utf8"));
35515
35817
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
35516
35818
  violations.push({
35517
35819
  code: "optional-source-malformed",
@@ -35533,10 +35835,10 @@ function checkSkillSubfolderNames(kit) {
35533
35835
  const notices = [];
35534
35836
  const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
35535
35837
  for (const name of kit.components.skills.declared) {
35536
- const skillDir = path50.join(kit.path, "skills", name);
35838
+ const skillDir = path51.join(kit.path, "skills", name);
35537
35839
  let entries;
35538
35840
  try {
35539
- entries = fs49.readdirSync(skillDir, { withFileTypes: true });
35841
+ entries = fs50.readdirSync(skillDir, { withFileTypes: true });
35540
35842
  } catch {
35541
35843
  continue;
35542
35844
  }
@@ -35554,7 +35856,7 @@ function checkSkillSubfolderNames(kit) {
35554
35856
  return notices;
35555
35857
  }
35556
35858
  function checkHooksSourceForm(kit) {
35557
- const hooksDir = path50.join(kit.path, "hooks");
35859
+ const hooksDir = path51.join(kit.path, "hooks");
35558
35860
  const message = describeHooksSourceConflict(
35559
35861
  hooksDir,
35560
35862
  kit.components.hooks.declared
@@ -35566,12 +35868,12 @@ function checkHooksSourceForm(kit) {
35566
35868
  } : null;
35567
35869
  }
35568
35870
  function checkHookDeclarations(kit) {
35569
- const hooksDir = path50.join(kit.path, "hooks");
35871
+ const hooksDir = path51.join(kit.path, "hooks");
35570
35872
  return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
35571
35873
  (r) => ({
35572
35874
  code: "hook-declaration-invalid",
35573
- location: `hooks/${path50.basename(r.file)}`,
35574
- 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.`
35875
+ location: `hooks/${path51.basename(r.file)}`,
35876
+ 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.`
35575
35877
  })
35576
35878
  );
35577
35879
  }
@@ -35591,11 +35893,11 @@ function checkKitFormatSupported(kit) {
35591
35893
  function checkEntrypointExists(kit) {
35592
35894
  const declared = kit.entrypoint;
35593
35895
  const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
35594
- const entrypointPath = path50.join(kit.path, entrypoint);
35595
- if (fs49.existsSync(entrypointPath)) {
35896
+ const entrypointPath = path51.join(kit.path, entrypoint);
35897
+ if (fs50.existsSync(entrypointPath)) {
35596
35898
  return null;
35597
35899
  }
35598
- const legacyPresent = declared === void 0 && fs49.existsSync(path50.join(kit.path, LEGACY_ENTRYPOINT));
35900
+ const legacyPresent = declared === void 0 && fs50.existsSync(path51.join(kit.path, LEGACY_ENTRYPOINT));
35599
35901
  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.`;
35600
35902
  return {
35601
35903
  code: "entrypoint-missing",
@@ -35654,9 +35956,9 @@ function checkComponentFrontmatter(kit) {
35654
35956
  const missingSet = new Set(kit.components[cat].missing);
35655
35957
  for (const name of kit.components[cat].declared) {
35656
35958
  if (missingSet.has(name)) continue;
35657
- const filePath = cat === "skills" ? path50.join(kit.path, cat, name, "SKILL.md") : path50.join(kit.path, cat, `${name}.md`);
35658
- if (!fs49.existsSync(filePath)) continue;
35659
- const relPath = path50.relative(kit.path, filePath);
35959
+ const filePath = cat === "skills" ? path51.join(kit.path, cat, name, "SKILL.md") : path51.join(kit.path, cat, `${name}.md`);
35960
+ if (!fs50.existsSync(filePath)) continue;
35961
+ const relPath = path51.relative(kit.path, filePath);
35660
35962
  try {
35661
35963
  const { data } = parseMarkdownFrontmatter(filePath);
35662
35964
  for (const field of requiredFields) {
@@ -35681,10 +35983,10 @@ function checkComponentFrontmatter(kit) {
35681
35983
  }
35682
35984
  function checkReservedRootNames(kit) {
35683
35985
  const violations = [];
35684
- if (!fs49.existsSync(kit.path) || !fs49.statSync(kit.path).isDirectory()) {
35986
+ if (!fs50.existsSync(kit.path) || !fs50.statSync(kit.path).isDirectory()) {
35685
35987
  return violations;
35686
35988
  }
35687
- const entries = fs49.readdirSync(kit.path, { withFileTypes: true });
35989
+ const entries = fs50.readdirSync(kit.path, { withFileTypes: true });
35688
35990
  for (const entry of entries) {
35689
35991
  if (RESERVED_ROOT_NAMES.includes(entry.name)) {
35690
35992
  violations.push({
@@ -35701,8 +36003,8 @@ function checkHumanOnlyCommandInvocation(kit) {
35701
36003
  const missingSet = new Set(kit.components.commands.missing);
35702
36004
  for (const name of kit.components.commands.declared) {
35703
36005
  if (missingSet.has(name)) continue;
35704
- const filePath = path50.join(kit.path, "commands", `${name}.md`);
35705
- if (!fs49.existsSync(filePath)) continue;
36006
+ const filePath = path51.join(kit.path, "commands", `${name}.md`);
36007
+ if (!fs50.existsSync(filePath)) continue;
35706
36008
  let data;
35707
36009
  try {
35708
36010
  ({ data } = parseMarkdownFrontmatter(filePath));
@@ -35715,7 +36017,7 @@ function checkHumanOnlyCommandInvocation(kit) {
35715
36017
  if (!barred) {
35716
36018
  violations.push({
35717
36019
  code: "command-human-only-model-invocable",
35718
- location: path50.relative(kit.path, filePath),
36020
+ location: path51.relative(kit.path, filePath),
35719
36021
  message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
35720
36022
  });
35721
36023
  }
@@ -35724,8 +36026,8 @@ function checkHumanOnlyCommandInvocation(kit) {
35724
36026
  }
35725
36027
 
35726
36028
  // src/commands/verify.ts
35727
- import fs50 from "fs";
35728
- import path51 from "path";
36029
+ import fs51 from "fs";
36030
+ import path52 from "path";
35729
36031
  function runVerifyCommand(options, logger) {
35730
36032
  if (options.target && !isKnownTarget(options.target)) {
35731
36033
  throwUnrecognizedTarget(options.target);
@@ -35906,8 +36208,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
35906
36208
  if (!slotPath) {
35907
36209
  continue;
35908
36210
  }
35909
- const fullPath = subPath ? path51.join(slotPath, subPath) : slotPath;
35910
- if (!fs50.existsSync(fullPath)) {
36211
+ const fullPath = subPath ? path52.join(slotPath, subPath) : slotPath;
36212
+ if (!fs51.existsSync(fullPath)) {
35911
36213
  failures.push(
35912
36214
  `claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
35913
36215
  );