@alessandroraffa/tangyr 0.14.1 → 0.15.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.
Files changed (2) hide show
  1. package/dist/index.js +888 -586
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1372,8 +1372,8 @@ var require_command = __commonJS({
1372
1372
  "use strict";
1373
1373
  var EventEmitter = __require("events").EventEmitter;
1374
1374
  var childProcess = __require("child_process");
1375
- var path45 = __require("path");
1376
- var fs44 = __require("fs");
1375
+ var path46 = __require("path");
1376
+ var fs45 = __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 (fs44.existsSync(executableFile)) return;
2370
+ if (fs45.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 = path45.resolve(baseDir, baseName);
2389
- if (fs44.existsSync(localBin)) return localBin;
2390
- if (sourceExt.includes(path45.extname(baseName))) return void 0;
2388
+ const localBin = path46.resolve(baseDir, baseName);
2389
+ if (fs45.existsSync(localBin)) return localBin;
2390
+ if (sourceExt.includes(path46.extname(baseName))) return void 0;
2391
2391
  const foundExt = sourceExt.find(
2392
- (ext) => fs44.existsSync(`${localBin}${ext}`)
2392
+ (ext) => fs45.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 = fs44.realpathSync(this._scriptPath);
2404
+ resolvedScriptPath = fs45.realpathSync(this._scriptPath);
2405
2405
  } catch {
2406
2406
  resolvedScriptPath = this._scriptPath;
2407
2407
  }
2408
- executableDir = path45.resolve(
2409
- path45.dirname(resolvedScriptPath),
2408
+ executableDir = path46.resolve(
2409
+ path46.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 = path45.basename(
2416
+ const legacyName = path46.basename(
2417
2417
  this._scriptPath,
2418
- path45.extname(this._scriptPath)
2418
+ path46.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(path45.extname(executableFile));
2429
+ launchWithNode = sourceExt.includes(path46.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 = path45.basename(filename, path45.extname(filename));
3344
+ this._name = path46.basename(filename, path46.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(path46) {
3359
- if (path46 === void 0) return this._executableDir;
3360
- this._executableDir = path46;
3358
+ executableDir(path47) {
3359
+ if (path47 === void 0) return this._executableDir;
3360
+ this._executableDir = path47;
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, path45) {
3717
- const ctrl = callVisitor(key, node, visitor, path45);
3716
+ function visit_(key, node, visitor, path46) {
3717
+ const ctrl = callVisitor(key, node, visitor, path46);
3718
3718
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3719
- replaceNode(key, path45, ctrl);
3720
- return visit_(key, ctrl, visitor, path45);
3719
+ replaceNode(key, path46, ctrl);
3720
+ return visit_(key, ctrl, visitor, path46);
3721
3721
  }
3722
3722
  if (typeof ctrl !== "symbol") {
3723
3723
  if (identity.isCollection(node)) {
3724
- path45 = Object.freeze(path45.concat(node));
3724
+ path46 = Object.freeze(path46.concat(node));
3725
3725
  for (let i = 0; i < node.items.length; ++i) {
3726
- const ci2 = visit_(i, node.items[i], visitor, path45);
3726
+ const ci2 = visit_(i, node.items[i], visitor, path46);
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
- path45 = Object.freeze(path45.concat(node));
3738
- const ck = visit_("key", node.key, visitor, path45);
3737
+ path46 = Object.freeze(path46.concat(node));
3738
+ const ck = visit_("key", node.key, visitor, path46);
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, path45);
3743
+ const cv = visit_("value", node.value, visitor, path46);
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, path45) {
3765
- const ctrl = await callVisitor(key, node, visitor, path45);
3764
+ async function visitAsync_(key, node, visitor, path46) {
3765
+ const ctrl = await callVisitor(key, node, visitor, path46);
3766
3766
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3767
- replaceNode(key, path45, ctrl);
3768
- return visitAsync_(key, ctrl, visitor, path45);
3767
+ replaceNode(key, path46, ctrl);
3768
+ return visitAsync_(key, ctrl, visitor, path46);
3769
3769
  }
3770
3770
  if (typeof ctrl !== "symbol") {
3771
3771
  if (identity.isCollection(node)) {
3772
- path45 = Object.freeze(path45.concat(node));
3772
+ path46 = Object.freeze(path46.concat(node));
3773
3773
  for (let i = 0; i < node.items.length; ++i) {
3774
- const ci2 = await visitAsync_(i, node.items[i], visitor, path45);
3774
+ const ci2 = await visitAsync_(i, node.items[i], visitor, path46);
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
- path45 = Object.freeze(path45.concat(node));
3786
- const ck = await visitAsync_("key", node.key, visitor, path45);
3785
+ path46 = Object.freeze(path46.concat(node));
3786
+ const ck = await visitAsync_("key", node.key, visitor, path46);
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, path45);
3791
+ const cv = await visitAsync_("value", node.value, visitor, path46);
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, path45) {
3818
+ function callVisitor(key, node, visitor, path46) {
3819
3819
  if (typeof visitor === "function")
3820
- return visitor(key, node, path45);
3820
+ return visitor(key, node, path46);
3821
3821
  if (identity.isMap(node))
3822
- return visitor.Map?.(key, node, path45);
3822
+ return visitor.Map?.(key, node, path46);
3823
3823
  if (identity.isSeq(node))
3824
- return visitor.Seq?.(key, node, path45);
3824
+ return visitor.Seq?.(key, node, path46);
3825
3825
  if (identity.isPair(node))
3826
- return visitor.Pair?.(key, node, path45);
3826
+ return visitor.Pair?.(key, node, path46);
3827
3827
  if (identity.isScalar(node))
3828
- return visitor.Scalar?.(key, node, path45);
3828
+ return visitor.Scalar?.(key, node, path46);
3829
3829
  if (identity.isAlias(node))
3830
- return visitor.Alias?.(key, node, path45);
3830
+ return visitor.Alias?.(key, node, path46);
3831
3831
  return void 0;
3832
3832
  }
3833
- function replaceNode(key, path45, node) {
3834
- const parent = path45[path45.length - 1];
3833
+ function replaceNode(key, path46, node) {
3834
+ const parent = path46[path46.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, path45, value) {
4442
+ function collectionFromPath(schema, path46, value) {
4443
4443
  let v2 = value;
4444
- for (let i = path45.length - 1; i >= 0; --i) {
4445
- const k2 = path45[i];
4444
+ for (let i = path46.length - 1; i >= 0; --i) {
4445
+ const k2 = path46[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 = (path45) => path45 == null || typeof path45 === "object" && !!path45[Symbol.iterator]().next().done;
4464
+ var isEmptyPath = (path46) => path46 == null || typeof path46 === "object" && !!path46[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(path45, value) {
4495
- if (isEmptyPath(path45))
4494
+ addIn(path46, value) {
4495
+ if (isEmptyPath(path46))
4496
4496
  this.add(value);
4497
4497
  else {
4498
- const [key, ...rest] = path45;
4498
+ const [key, ...rest] = path46;
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(path45) {
4513
- const [key, ...rest] = path45;
4512
+ deleteIn(path46) {
4513
+ const [key, ...rest] = path46;
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(path45, keepScalar) {
4528
- const [key, ...rest] = path45;
4527
+ getIn(path46, keepScalar) {
4528
+ const [key, ...rest] = path46;
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(path45) {
4547
- const [key, ...rest] = path45;
4546
+ hasIn(path46) {
4547
+ const [key, ...rest] = path46;
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(path45, value) {
4558
- const [key, ...rest] = path45;
4557
+ setIn(path46, value) {
4558
+ const [key, ...rest] = path46;
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(path45, value) {
7070
+ addIn(path46, value) {
7071
7071
  if (assertCollection(this.contents))
7072
- this.contents.addIn(path45, value);
7072
+ this.contents.addIn(path46, 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(path45) {
7148
- if (Collection.isEmptyPath(path45)) {
7147
+ deleteIn(path46) {
7148
+ if (Collection.isEmptyPath(path46)) {
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(path45) : false;
7154
+ return assertCollection(this.contents) ? this.contents.deleteIn(path46) : 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(path45, keepScalar) {
7170
- if (Collection.isEmptyPath(path45))
7169
+ getIn(path46, keepScalar) {
7170
+ if (Collection.isEmptyPath(path46))
7171
7171
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
7172
- return identity.isCollection(this.contents) ? this.contents.getIn(path45, keepScalar) : void 0;
7172
+ return identity.isCollection(this.contents) ? this.contents.getIn(path46, 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(path45) {
7184
- if (Collection.isEmptyPath(path45))
7183
+ hasIn(path46) {
7184
+ if (Collection.isEmptyPath(path46))
7185
7185
  return this.contents !== void 0;
7186
- return identity.isCollection(this.contents) ? this.contents.hasIn(path45) : false;
7186
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path46) : 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(path45, value) {
7204
- if (Collection.isEmptyPath(path45)) {
7203
+ setIn(path46, value) {
7204
+ if (Collection.isEmptyPath(path46)) {
7205
7205
  this.contents = value;
7206
7206
  } else if (this.contents == null) {
7207
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path45), value);
7207
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path46), value);
7208
7208
  } else if (assertCollection(this.contents)) {
7209
- this.contents.setIn(path45, value);
7209
+ this.contents.setIn(path46, 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, path45) => {
9166
+ visit.itemAtPath = (cst, path46) => {
9167
9167
  let item = cst;
9168
- for (const [field, index] of path45) {
9168
+ for (const [field, index] of path46) {
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, path45) => {
9178
- const parent = visit.itemAtPath(cst, path45.slice(0, -1));
9179
- const field = path45[path45.length - 1][0];
9177
+ visit.parentCollection = (cst, path46) => {
9178
+ const parent = visit.itemAtPath(cst, path46.slice(0, -1));
9179
+ const field = path46[path46.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(path45, item, visitor) {
9186
- let ctrl = visitor(item, path45);
9185
+ function _visit(path46, item, visitor) {
9186
+ let ctrl = visitor(item, path46);
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(path45.concat([[field, i]])), token.items[i], visitor);
9193
+ const ci2 = _visit(Object.freeze(path46.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, path45);
9204
+ ctrl = ctrl(item, path46);
9205
9205
  }
9206
9206
  }
9207
- return typeof ctrl === "function" ? ctrl(item, path45) : ctrl;
9207
+ return typeof ctrl === "function" ? ctrl(item, path46) : 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 fs44 = this.flowScalar(this.type);
10492
+ const fs45 = this.flowScalar(this.type);
10493
10493
  if (atNextItem || it2.value) {
10494
- map.items.push({ start, key: fs44, sep: [] });
10494
+ map.items.push({ start, key: fs45, sep: [] });
10495
10495
  this.onKeyLine = true;
10496
10496
  } else if (it2.sep) {
10497
- this.stack.push(fs44);
10497
+ this.stack.push(fs45);
10498
10498
  } else {
10499
- Object.assign(it2, { key: fs44, sep: [] });
10499
+ Object.assign(it2, { key: fs45, 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 fs44 = this.flowScalar(this.type);
10627
+ const fs45 = this.flowScalar(this.type);
10628
10628
  if (!it2 || it2.value)
10629
- fc.items.push({ start: [], key: fs44, sep: [] });
10629
+ fc.items.push({ start: [], key: fs45, sep: [] });
10630
10630
  else if (it2.sep)
10631
- this.stack.push(fs44);
10631
+ this.stack.push(fs45);
10632
10632
  else
10633
- Object.assign(it2, { key: fs44, sep: [] });
10633
+ Object.assign(it2, { key: fs45, sep: [] });
10634
10634
  return;
10635
10635
  }
10636
10636
  case "flow-map-end":
@@ -15090,6 +15090,13 @@ function normalizeSource(declared) {
15090
15090
  "Configuration declares source.type: remote but no source.url. Set source.url to the https endpoint of your kit origin."
15091
15091
  );
15092
15092
  }
15093
+ if (source.channel !== void 0) {
15094
+ if (!/^[a-z0-9][a-z0-9-]{0,31}$/u.test(source.channel)) {
15095
+ throw new Error(
15096
+ `Configuration declares source.channel "${source.channel}", which must be lowercase alphanumeric with hyphens, 1-32 characters.`
15097
+ );
15098
+ }
15099
+ }
15093
15100
  return source;
15094
15101
  }
15095
15102
  function findConfigPath(explicitPath) {
@@ -17577,6 +17584,24 @@ import path15 from "path";
17577
17584
 
17578
17585
  // src/core/kit-reference.ts
17579
17586
  var BARE_URL = /^https?:\/\//u;
17587
+ function parseKitSelector(raw) {
17588
+ if (BARE_URL.test(raw)) {
17589
+ throw new Error(
17590
+ "A bare URL is not a kit reference. Configure source.url in tangyr.config.yaml and reference the kit as --kit <name> or --kit <name>@<version>."
17591
+ );
17592
+ }
17593
+ if (raw.length === 0) {
17594
+ throw new Error(
17595
+ "No kit was named. Pass --kit <name> to resolve the configured channel, or --kit <name>@<version> for an exact version."
17596
+ );
17597
+ }
17598
+ const separator = raw.lastIndexOf("@");
17599
+ if (separator === -1) {
17600
+ assertPathSafeComponent("name", raw);
17601
+ return { name: raw };
17602
+ }
17603
+ return parseKitReference(raw);
17604
+ }
17580
17605
  function parseKitReference(raw) {
17581
17606
  if (BARE_URL.test(raw)) {
17582
17607
  throw new Error(
@@ -23113,20 +23138,98 @@ function toConflictPolicy2(value) {
23113
23138
  }
23114
23139
 
23115
23140
  // src/commands/install.ts
23116
- import fs36 from "fs";
23117
- import path36 from "path";
23118
-
23119
- // src/core/materialize.ts
23120
- import fs29 from "fs";
23121
- import path27 from "path";
23141
+ import fs37 from "fs";
23142
+ import path37 from "path";
23122
23143
 
23123
- // src/core/integrity.ts
23124
- import crypto3 from "crypto";
23144
+ // src/core/channel-state.ts
23145
+ import fs28 from "fs";
23146
+ import path26 from "path";
23147
+ var CHANNEL_STATE_FILENAME = ".tangyr-channels.json";
23148
+ function stateFilePath(cacheRoot) {
23149
+ return path26.join(cacheRoot, CHANNEL_STATE_FILENAME);
23150
+ }
23151
+ function channelKey(kit, channel) {
23152
+ return `${kit}/${channel}`;
23153
+ }
23154
+ function readState(cacheRoot) {
23155
+ const filePath = stateFilePath(cacheRoot);
23156
+ let raw;
23157
+ try {
23158
+ raw = fs28.readFileSync(filePath, "utf8");
23159
+ } catch (err) {
23160
+ if (err.code === "ENOENT") {
23161
+ return { state: {} };
23162
+ }
23163
+ return {
23164
+ state: {},
23165
+ warning: `Could not read ${filePath} (${err.message}); the channel downgrade guard starts from nothing for this run.`
23166
+ };
23167
+ }
23168
+ let parsed;
23169
+ try {
23170
+ parsed = JSON.parse(raw);
23171
+ } catch {
23172
+ return {
23173
+ state: {},
23174
+ warning: `${filePath} is not valid JSON; the channel downgrade guard starts from nothing for this run.`
23175
+ };
23176
+ }
23177
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
23178
+ return {
23179
+ state: {},
23180
+ warning: `${filePath} does not contain an object; the channel downgrade guard starts from nothing for this run.`
23181
+ };
23182
+ }
23183
+ return { state: parsed };
23184
+ }
23185
+ function readChannelSequence(cacheRoot, originUrl, kit, channel) {
23186
+ const { state, warning } = readState(cacheRoot);
23187
+ const record = state[originUrl]?.[channelKey(kit, channel)];
23188
+ const usable = record !== void 0 && Number.isSafeInteger(record.sequence) && typeof record.version === "string" && record.version.length > 0;
23189
+ const result = usable ? { sequence: record.sequence, version: record.version } : { sequence: void 0, version: void 0 };
23190
+ return warning === void 0 ? result : { ...result, warning };
23191
+ }
23192
+ function writeChannelSequence(params) {
23193
+ const { cacheRoot, originUrl, kit, channel, sequence, version, now } = params;
23194
+ const { state } = readState(cacheRoot);
23195
+ const key = channelKey(kit, channel);
23196
+ const existing = state[originUrl]?.[key]?.sequence;
23197
+ if (existing !== void 0 && existing > sequence) {
23198
+ return;
23199
+ }
23200
+ state[originUrl] = {
23201
+ ...state[originUrl],
23202
+ [key]: { sequence, version, seenAt: now.toISOString() }
23203
+ };
23204
+ const filePath = stateFilePath(cacheRoot);
23205
+ fs28.mkdirSync(path26.dirname(filePath), { recursive: true, mode: 448 });
23206
+ const tempPath = `${filePath}.${process.pid}.tmp`;
23207
+ fs28.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
23208
+ `, {
23209
+ mode: 384
23210
+ });
23211
+ fs28.renameSync(tempPath, filePath);
23212
+ }
23213
+ function assertChannelNotRolledBack(params) {
23214
+ const { originUrl, kit, channel, seen, seenVersion, incoming } = params;
23215
+ if (seen !== void 0 && incoming < seen) {
23216
+ throw new IntegrityError(
23217
+ `Channel pointer for ${kit}/${channel} from ${originUrl} carries sequence ${incoming}, behind the highest already accepted (${seen}${seenVersion === void 0 ? "" : `, naming ${kit}@${seenVersion}`}). That is a replay of a superseded pointer, which would pin this machine to ${kit}@${params.incomingVersion} and hide every version published since \u2014 refusing.`
23218
+ );
23219
+ }
23220
+ }
23125
23221
 
23126
23222
  // src/core/bundle.ts
23127
23223
  var DENY_LIST_TYPE = "tangyr.deny-list.v2";
23224
+ var CHANNEL_POINTER_TYPE = "tangyr.channel-pointer.v1";
23225
+ var DEFAULT_CHANNEL = "stable";
23226
+
23227
+ // src/core/materialize.ts
23228
+ import fs30 from "fs";
23229
+ import path28 from "path";
23128
23230
 
23129
23231
  // src/core/integrity.ts
23232
+ import crypto3 from "crypto";
23130
23233
  function canonicalize(value) {
23131
23234
  if (Array.isArray(value)) {
23132
23235
  return value.map(canonicalize);
@@ -23273,11 +23376,16 @@ function verifyDenyList(denyList, keys, now) {
23273
23376
  keys,
23274
23377
  now
23275
23378
  );
23276
- assertFreshnessWindow(list.issuedAt, list.expiresAt, now);
23379
+ assertFreshnessWindow(
23380
+ list.issuedAt,
23381
+ list.expiresAt,
23382
+ now,
23383
+ "An expired revocation deny-list is not evidence that nothing is revoked \u2014 the publisher must re-sign and republish it."
23384
+ );
23277
23385
  return list;
23278
23386
  }
23279
23387
  var DENY_LIST_MALFORMED = "Revocation deny-list response is malformed, unsigned, or corrupted \u2014 treated as an integrity failure, never as an absent deny-list (REQ-INT-009).";
23280
- function assertFreshnessWindow(issuedAt, expiresAt, now) {
23388
+ function assertFreshnessWindow(issuedAt, expiresAt, now, expiryConsequence) {
23281
23389
  const utcDesignatorPattern = /Z|[+-]\d{2}:\d{2}$/;
23282
23390
  if (!utcDesignatorPattern.test(issuedAt) || !utcDesignatorPattern.test(expiresAt)) {
23283
23391
  throw new IntegrityError(
@@ -23298,7 +23406,7 @@ function assertFreshnessWindow(issuedAt, expiresAt, now) {
23298
23406
  }
23299
23407
  if (now.getTime() > expires.getTime()) {
23300
23408
  throw new IntegrityError(
23301
- `Signed document expired at ${expiresAt} (now ${now.toISOString()}). An expired revocation deny-list is not evidence that nothing is revoked \u2014 the publisher must re-sign and republish it.`
23409
+ `Signed document expired at ${expiresAt} (now ${now.toISOString()}). ${expiryConsequence}`
23302
23410
  );
23303
23411
  }
23304
23412
  if (now.getTime() < issued.getTime()) {
@@ -23307,19 +23415,68 @@ function assertFreshnessWindow(issuedAt, expiresAt, now) {
23307
23415
  );
23308
23416
  }
23309
23417
  }
23418
+ var CHANNEL_POINTER_MALFORMED = "Channel pointer from the origin is malformed.";
23419
+ function verifyChannelPointer(pointer, expectedKit, expectedChannel, keys, now) {
23420
+ if (pointer === null || typeof pointer !== "object") {
23421
+ throw new IntegrityError(CHANNEL_POINTER_MALFORMED);
23422
+ }
23423
+ const actualKeys = Object.keys(pointer).sort();
23424
+ const expectedKeys = [
23425
+ "channel",
23426
+ "expiresAt",
23427
+ "issuedAt",
23428
+ "keyId",
23429
+ "kit",
23430
+ "sequence",
23431
+ "signature",
23432
+ "type",
23433
+ "version"
23434
+ ];
23435
+ if (actualKeys.length !== expectedKeys.length || actualKeys.some((key, index) => key !== expectedKeys[index])) {
23436
+ throw new IntegrityError(
23437
+ `${CHANNEL_POINTER_MALFORMED} Expected exactly [${expectedKeys.join(", ")}], got [${actualKeys.join(", ")}].`
23438
+ );
23439
+ }
23440
+ const candidate = pointer;
23441
+ const shapeOk = candidate.type === CHANNEL_POINTER_TYPE && typeof candidate.keyId === "string" && typeof candidate.kit === "string" && candidate.kit.length > 0 && typeof candidate.channel === "string" && candidate.channel.length > 0 && typeof candidate.version === "string" && candidate.version.length > 0 && typeof candidate.signature === "string" && candidate.signature.length > 0 && Number.isSafeInteger(candidate.sequence) && candidate.sequence >= 0 && typeof candidate.issuedAt === "string" && typeof candidate.expiresAt === "string";
23442
+ if (!shapeOk) {
23443
+ throw new IntegrityError(CHANNEL_POINTER_MALFORMED);
23444
+ }
23445
+ const { signature, ...signed } = candidate;
23446
+ verifySignedPayload(
23447
+ canonicalJsonBytes(signed),
23448
+ signature,
23449
+ candidate.keyId,
23450
+ keys,
23451
+ now
23452
+ );
23453
+ if (candidate.kit !== expectedKit || candidate.channel !== expectedChannel) {
23454
+ throw new IntegrityError(
23455
+ `Channel pointer is signed for ${candidate.kit}/${candidate.channel} but was served as ${expectedKit}/${expectedChannel}. A pointer the publisher signed for one channel is being presented as another's \u2014 refusing.`
23456
+ );
23457
+ }
23458
+ assertPathSafeComponent("version", candidate.version);
23459
+ assertFreshnessWindow(
23460
+ candidate.issuedAt,
23461
+ candidate.expiresAt,
23462
+ now,
23463
+ "An expired channel pointer is not evidence that it still names the newest version \u2014 the publisher must re-sign and republish it."
23464
+ );
23465
+ return candidate;
23466
+ }
23310
23467
 
23311
23468
  // src/core/revocation-state.ts
23312
- import fs28 from "fs";
23313
- import path26 from "path";
23469
+ import fs29 from "fs";
23470
+ import path27 from "path";
23314
23471
  var REVOCATION_STATE_FILENAME = ".tangyr-revocation.json";
23315
- function stateFilePath(cacheRoot) {
23316
- return path26.join(cacheRoot, REVOCATION_STATE_FILENAME);
23472
+ function stateFilePath2(cacheRoot) {
23473
+ return path27.join(cacheRoot, REVOCATION_STATE_FILENAME);
23317
23474
  }
23318
- function readState(cacheRoot) {
23319
- const filePath = stateFilePath(cacheRoot);
23475
+ function readState2(cacheRoot) {
23476
+ const filePath = stateFilePath2(cacheRoot);
23320
23477
  let raw;
23321
23478
  try {
23322
- raw = fs28.readFileSync(filePath, "utf8");
23479
+ raw = fs29.readFileSync(filePath, "utf8");
23323
23480
  } catch (err) {
23324
23481
  if (err.code === "ENOENT") {
23325
23482
  return { state: {} };
@@ -23347,26 +23504,26 @@ function readState(cacheRoot) {
23347
23504
  return { state: parsed };
23348
23505
  }
23349
23506
  function readRevocationSequence(cacheRoot, originUrl) {
23350
- const { state, warning } = readState(cacheRoot);
23507
+ const { state, warning } = readState2(cacheRoot);
23351
23508
  const record = state[originUrl];
23352
23509
  const sequence = record !== void 0 && Number.isSafeInteger(record.sequence) ? record.sequence : void 0;
23353
23510
  return warning === void 0 ? { sequence } : { sequence, warning };
23354
23511
  }
23355
23512
  function writeRevocationSequence(cacheRoot, originUrl, sequence, now) {
23356
- const { state } = readState(cacheRoot);
23513
+ const { state } = readState2(cacheRoot);
23357
23514
  const existing = state[originUrl]?.sequence;
23358
23515
  if (existing !== void 0 && existing >= sequence) {
23359
23516
  return;
23360
23517
  }
23361
23518
  state[originUrl] = { sequence, seenAt: now.toISOString() };
23362
- const filePath = stateFilePath(cacheRoot);
23363
- fs28.mkdirSync(path26.dirname(filePath), { recursive: true, mode: 448 });
23519
+ const filePath = stateFilePath2(cacheRoot);
23520
+ fs29.mkdirSync(path27.dirname(filePath), { recursive: true, mode: 448 });
23364
23521
  const tempPath = `${filePath}.${process.pid}.tmp`;
23365
- fs28.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
23522
+ fs29.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
23366
23523
  `, {
23367
23524
  mode: 384
23368
23525
  });
23369
- fs28.renameSync(tempPath, filePath);
23526
+ fs29.renameSync(tempPath, filePath);
23370
23527
  }
23371
23528
  function assertSequenceNotReplayed(params) {
23372
23529
  const { originUrl, seen, incoming } = params;
@@ -23538,8 +23695,8 @@ async function assertReferenceNotRevoked(params) {
23538
23695
  const key = `${reference.name}@${reference.version}`;
23539
23696
  if (denyList.entries.includes(key)) {
23540
23697
  const entryDir = cacheEntryPath(cacheRoot, reference);
23541
- if (fs29.existsSync(entryDir)) {
23542
- fs29.rmSync(entryDir, { recursive: true, force: true });
23698
+ if (fs30.existsSync(entryDir)) {
23699
+ fs30.rmSync(entryDir, { recursive: true, force: true });
23543
23700
  }
23544
23701
  throw new IntegrityError(
23545
23702
  `"${key}" is present on the signed revocation deny-list \u2014 refusing to materialize or install; any existing cache entry has been invalidated (REQ-INT-009).`
@@ -23586,7 +23743,7 @@ function assertFileWithinCeiling(entryPath, byteLength) {
23586
23743
  }
23587
23744
  var WINDOWS_DRIVE_ABSOLUTE = /^[a-zA-Z]:[\\/]/u;
23588
23745
  function sanitizeBundleFilePath(entryPath, stagingDir) {
23589
- if (path27.isAbsolute(entryPath) || WINDOWS_DRIVE_ABSOLUTE.test(entryPath)) {
23746
+ if (path28.isAbsolute(entryPath) || WINDOWS_DRIVE_ABSOLUTE.test(entryPath)) {
23590
23747
  throw new IntegrityError(
23591
23748
  `Bundle file path "${entryPath}" is absolute \u2014 every file inside a bundle must use a relative path (REQ-INT-004).`
23592
23749
  );
@@ -23602,13 +23759,13 @@ function sanitizeBundleFilePath(entryPath, stagingDir) {
23602
23759
  `Bundle file path "${entryPath}" contains a ".." segment \u2014 directory traversal is rejected (REQ-INT-004).`
23603
23760
  );
23604
23761
  }
23605
- const resolved = path27.resolve(stagingDir, entryPath);
23762
+ const resolved = path28.resolve(stagingDir, entryPath);
23606
23763
  if (resolved === stagingDir) {
23607
23764
  throw new IntegrityError(
23608
23765
  `Bundle file path "${entryPath}" resolves to the staging directory itself \u2014 every entry must be a file inside it (REQ-INT-004).`
23609
23766
  );
23610
23767
  }
23611
- if (!resolved.startsWith(stagingDir + path27.sep)) {
23768
+ if (!resolved.startsWith(stagingDir + path28.sep)) {
23612
23769
  throw new IntegrityError(
23613
23770
  `Bundle file path "${entryPath}" escapes the staging directory \u2014 refusing to write (REQ-INT-004).`
23614
23771
  );
@@ -23660,10 +23817,10 @@ function verifyBundleFileHashes(bundle) {
23660
23817
  function writeStagedFiles(stagingDir, decoded) {
23661
23818
  for (const [rawPath, bytes] of decoded) {
23662
23819
  const target = sanitizeBundleFilePath(rawPath, stagingDir);
23663
- fs29.mkdirSync(path27.dirname(target), { recursive: true, mode: 448 });
23820
+ fs30.mkdirSync(path28.dirname(target), { recursive: true, mode: 448 });
23664
23821
  let existingStat;
23665
23822
  try {
23666
- existingStat = fs29.lstatSync(target);
23823
+ existingStat = fs30.lstatSync(target);
23667
23824
  } catch (error) {
23668
23825
  if (error.code !== "ENOENT") {
23669
23826
  throw error;
@@ -23674,7 +23831,7 @@ function writeStagedFiles(stagingDir, decoded) {
23674
23831
  `Refusing to write "${rawPath}" \u2014 a symbolic link already exists at the target path.`
23675
23832
  );
23676
23833
  }
23677
- fs29.writeFileSync(target, bytes, { mode: 384, flag: "wx" });
23834
+ fs30.writeFileSync(target, bytes, { mode: 384, flag: "wx" });
23678
23835
  }
23679
23836
  }
23680
23837
  function verifyWarmCacheEntry(entryDir, reference, keys, now) {
@@ -23740,18 +23897,103 @@ async function materializeRemoteKit(params) {
23740
23897
  writeStagedFiles(stagingDir, decoded);
23741
23898
  writeBundleDocument(stagingDir, bundle);
23742
23899
  writeCompletionMarker(stagingDir, reference);
23743
- if (replace && fs29.existsSync(entryDir)) {
23744
- fs29.rmSync(entryDir, { recursive: true, force: true });
23900
+ if (replace && fs30.existsSync(entryDir)) {
23901
+ fs30.rmSync(entryDir, { recursive: true, force: true });
23745
23902
  }
23746
23903
  publishCacheEntry(stagingDir, entryDir);
23747
23904
  return entryDir;
23748
23905
  } catch (error) {
23749
23906
  if (stagingDir !== void 0) {
23750
- fs29.rmSync(stagingDir, { recursive: true, force: true });
23907
+ fs30.rmSync(stagingDir, { recursive: true, force: true });
23751
23908
  }
23752
23909
  throw error;
23753
23910
  }
23754
23911
  }
23912
+ var CHANNEL_OBJECT_PATH_PREFIX = "/v1/channels";
23913
+ var MAX_CHANNEL_POINTER_BYTES = 64 * 1024;
23914
+ async function resolveChannelVersion(params) {
23915
+ const {
23916
+ originUrl,
23917
+ kit,
23918
+ channel,
23919
+ cacheRoot,
23920
+ transport,
23921
+ keys,
23922
+ now,
23923
+ logger,
23924
+ sleep: sleep2
23925
+ } = params;
23926
+ const credentials = resolveCredentialNonInteractive();
23927
+ const objectPath = `${CHANNEL_OBJECT_PATH_PREFIX}/${kit}/${channel}.json`;
23928
+ const pointer = await withBoundedRetry(
23929
+ async () => {
23930
+ const controller = new AbortController();
23931
+ const response = await transport.fetchObjectStream(
23932
+ originUrl,
23933
+ objectPath,
23934
+ credentials,
23935
+ controller.signal
23936
+ );
23937
+ if (response.status === 401 || response.status === 403) {
23938
+ throw new AuthenticationError(
23939
+ `The origin rejected the credential (HTTP ${response.status}) resolving ${kit}/${channel}. Set TANGYR_ACCESS_CLIENT_ID and TANGYR_ACCESS_CLIENT_SECRET, or run 'tangyr auth login'.`
23940
+ );
23941
+ }
23942
+ if (response.status === 404) {
23943
+ throw new IntegrityError(
23944
+ `The origin has no ${channel} channel for "${kit}" (HTTP 404 at ${originUrl}${objectPath}). Either the publisher has not published that channel, or the kit name is wrong. Reference an explicit version as --kit ${kit}@<version> if you know one.`
23945
+ );
23946
+ }
23947
+ if (response.status !== 200) {
23948
+ throw new Error(
23949
+ `Unexpected HTTP ${response.status} resolving ${kit}/${channel} from ${originUrl}${objectPath}.`
23950
+ );
23951
+ }
23952
+ const buffer = await readBoundedStream(
23953
+ response.body,
23954
+ MAX_CHANNEL_POINTER_BYTES,
23955
+ () => controller.abort()
23956
+ );
23957
+ let parsed;
23958
+ try {
23959
+ parsed = JSON.parse(buffer.toString("utf8"));
23960
+ } catch {
23961
+ throw new IntegrityError(
23962
+ `Channel pointer for ${kit}/${channel} is not valid JSON \u2014 rejecting.`
23963
+ );
23964
+ }
23965
+ return verifyChannelPointer(parsed, kit, channel, keys, now);
23966
+ },
23967
+ sleep2,
23968
+ logger
23969
+ );
23970
+ const seen = readChannelSequence(cacheRoot, originUrl, kit, channel);
23971
+ if (seen.warning) {
23972
+ logger.warn(seen.warning);
23973
+ }
23974
+ assertChannelNotRolledBack({
23975
+ originUrl,
23976
+ kit,
23977
+ channel,
23978
+ seen: seen.sequence,
23979
+ seenVersion: seen.version,
23980
+ incoming: pointer.sequence,
23981
+ incomingVersion: pointer.version
23982
+ });
23983
+ writeChannelSequence({
23984
+ cacheRoot,
23985
+ originUrl,
23986
+ kit,
23987
+ channel,
23988
+ sequence: pointer.sequence,
23989
+ version: pointer.version,
23990
+ now
23991
+ });
23992
+ logger.verbose(
23993
+ `Resolved ${kit}/${channel} to ${kit}@${pointer.version} (pointer sequence ${pointer.sequence}).`
23994
+ );
23995
+ return pointer.version;
23996
+ }
23755
23997
 
23756
23998
  // src/core/kit-source.ts
23757
23999
  function resolveCacheOnly(entryDir, reference, keys, now) {
@@ -23790,13 +24032,25 @@ async function resolveKitSource(params) {
23790
24032
  if (config.source.type !== "remote") {
23791
24033
  return { kitName: kitOption };
23792
24034
  }
23793
- const reference = parseKitReference(kitOption ?? "");
24035
+ const selector = parseKitSelector(kitOption ?? "");
23794
24036
  if (!config.source.url) {
23795
24037
  throw new Error(
23796
24038
  "Configuration declares source.type: remote but no source.url. Set source.url to the https endpoint of your kit origin."
23797
24039
  );
23798
24040
  }
23799
24041
  const cacheRoot = resolveCacheRoot(env2);
24042
+ const reference = selector.version === void 0 ? await resolveThroughChannel({
24043
+ name: selector.name,
24044
+ channel: config.source.channel ?? DEFAULT_CHANNEL,
24045
+ originUrl: config.source.url,
24046
+ cacheRoot,
24047
+ offline: offline === true,
24048
+ transport,
24049
+ keys,
24050
+ now,
24051
+ logger,
24052
+ sleep: sleep2
24053
+ }) : { name: selector.name, version: selector.version };
23800
24054
  const entryDir = cacheEntryPath(cacheRoot, reference);
23801
24055
  if (offline) {
23802
24056
  return resolveCacheOnly(entryDir, reference, keys, now);
@@ -23934,6 +24188,54 @@ async function resolveKitSource(params) {
23934
24188
  writeLastAuthorizedAt(cacheRoot, config.source.url, now);
23935
24189
  return { kitPathOverride, kitName: reference.name };
23936
24190
  }
24191
+ async function resolveThroughChannel(params) {
24192
+ const { name, channel, originUrl, cacheRoot, offline, logger } = params;
24193
+ const lastSeenVersion = () => {
24194
+ const seen = readChannelSequence(cacheRoot, originUrl, name, channel);
24195
+ if (seen.warning) {
24196
+ logger.warn(seen.warning);
24197
+ }
24198
+ return seen.version;
24199
+ };
24200
+ if (offline) {
24201
+ const version = lastSeenVersion();
24202
+ if (version === void 0) {
24203
+ throw new OfflineCacheMissError(
24204
+ `--offline cannot resolve ${name}/${channel}: this machine has never resolved that channel, and a channel pointer is never cached. Run once with network access, or name a version as --kit ${name}@<version>.`
24205
+ );
24206
+ }
24207
+ logger.warn(
24208
+ `--offline: using ${name}@${version}, the last version this machine saw on ${channel}. A newer one may exist.`
24209
+ );
24210
+ return { name, version };
24211
+ }
24212
+ try {
24213
+ const version = await resolveChannelVersion({
24214
+ originUrl,
24215
+ kit: name,
24216
+ channel,
24217
+ cacheRoot,
24218
+ transport: params.transport,
24219
+ keys: params.keys,
24220
+ now: params.now,
24221
+ logger,
24222
+ sleep: params.sleep
24223
+ });
24224
+ return { name, version };
24225
+ } catch (error) {
24226
+ if (!(error instanceof RemoteUnavailableError)) {
24227
+ throw error;
24228
+ }
24229
+ const version = lastSeenVersion();
24230
+ if (version === void 0) {
24231
+ throw error;
24232
+ }
24233
+ logger.warn(
24234
+ `Could not reach the origin to resolve ${name}/${channel}; falling back to ${name}@${version}, the last version this machine saw. A newer one may exist.`
24235
+ );
24236
+ return { name, version };
24237
+ }
24238
+ }
23937
24239
 
23938
24240
  // src/core/keys.ts
23939
24241
  var PINNED_PUBLISHER_KEYS = [
@@ -23955,13 +24257,13 @@ function sleep(ms2) {
23955
24257
  // src/adapters/codex.ts
23956
24258
  var TOML3 = __toESM(require_toml(), 1);
23957
24259
  import crypto5 from "crypto";
23958
- import fs31 from "fs";
23959
- import path30 from "path";
24260
+ import fs32 from "fs";
24261
+ import path31 from "path";
23960
24262
 
23961
24263
  // src/compiler/agents.ts
23962
24264
  var TOML = __toESM(require_toml(), 1);
23963
24265
  var import_yaml7 = __toESM(require_dist(), 1);
23964
- import path28 from "path";
24266
+ import path29 from "path";
23965
24267
 
23966
24268
  // src/compiler/loss-report.ts
23967
24269
  function createLossReport() {
@@ -24025,7 +24327,7 @@ var copilotToolAliasesByClass = {
24025
24327
  };
24026
24328
  function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
24027
24329
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
24028
- const relativeSource = `agents/${path28.basename(sourceFile)}`;
24330
+ const relativeSource = `agents/${path29.basename(sourceFile)}`;
24029
24331
  if (target === "opencode") {
24030
24332
  return compileOpenCodeAgent(
24031
24333
  sourceFile,
@@ -24066,7 +24368,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
24066
24368
  mappings,
24067
24369
  lossReport
24068
24370
  );
24069
- const overlayKey = `agents/${path28.basename(sourceFile, ".md")}.${target}.yaml`;
24371
+ const overlayKey = `agents/${path29.basename(sourceFile, ".md")}.${target}.yaml`;
24070
24372
  const targetFields = {
24071
24373
  ...translated.fields,
24072
24374
  ...extensions[overlayKey] ?? {}
@@ -24100,7 +24402,7 @@ ${TOML.stringify({
24100
24402
  function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
24101
24403
  if (typeof data.description !== "string" || data.description.trim() === "") {
24102
24404
  throw new Error(
24103
- `${path28.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
24405
+ `${path29.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
24104
24406
  );
24105
24407
  }
24106
24408
  const frontmatter = {
@@ -24154,7 +24456,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
24154
24456
  "permission",
24155
24457
  "permission-coarsening"
24156
24458
  ),
24157
- detail: `${path28.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
24459
+ detail: `${path29.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
24158
24460
  }
24159
24461
  ]
24160
24462
  });
@@ -24179,7 +24481,7 @@ ${(0, import_yaml7.stringify)(frontmatter).trim()}
24179
24481
  function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
24180
24482
  if (typeof data.description !== "string" || data.description.trim() === "") {
24181
24483
  throw new Error(
24182
- `${path28.basename(sourceFile)}: Cursor agent requires a non-empty description field`
24484
+ `${path29.basename(sourceFile)}: Cursor agent requires a non-empty description field`
24183
24485
  );
24184
24486
  }
24185
24487
  const frontmatter = {
@@ -24216,7 +24518,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
24216
24518
  "permission",
24217
24519
  "permission-coarsening"
24218
24520
  ),
24219
- detail: `${path28.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
24521
+ detail: `${path29.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
24220
24522
  }
24221
24523
  ]
24222
24524
  });
@@ -24235,7 +24537,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
24235
24537
  "provider",
24236
24538
  "provider-not-representable"
24237
24539
  ),
24238
- detail: `${path28.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
24540
+ detail: `${path29.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
24239
24541
  }
24240
24542
  ]
24241
24543
  });
@@ -24267,7 +24569,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
24267
24569
  "persona",
24268
24570
  "persona-not-representable"
24269
24571
  ),
24270
- detail: `${path28.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
24572
+ detail: `${path29.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
24271
24573
  }
24272
24574
  ]
24273
24575
  });
@@ -24315,7 +24617,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
24315
24617
  field,
24316
24618
  "model-not-representable"
24317
24619
  ),
24318
- detail: `${path28.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
24620
+ detail: `${path29.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
24319
24621
  });
24320
24622
  return;
24321
24623
  }
@@ -24333,9 +24635,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
24333
24635
  lossReport,
24334
24636
  target,
24335
24637
  "agents",
24336
- `agents/${path28.basename(sourceFile)}`,
24638
+ `agents/${path29.basename(sourceFile)}`,
24337
24639
  "info",
24338
- `${path28.basename(sourceFile)}: ${field} is delivered through another managed surface.`
24640
+ `${path29.basename(sourceFile)}: ${field} is delivered through another managed surface.`
24339
24641
  );
24340
24642
  return;
24341
24643
  }
@@ -24344,7 +24646,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
24344
24646
  field,
24345
24647
  action: entryType,
24346
24648
  severity: resolveLossSeverity("agent-field", field, entryType),
24347
- detail: `${path28.basename(sourceFile)}: ${field} has no emitted field for this target.`
24649
+ detail: `${path29.basename(sourceFile)}: ${field} has no emitted field for this target.`
24348
24650
  });
24349
24651
  }
24350
24652
  function mapToolsToCapabilities(value, mappings) {
@@ -24941,9 +25243,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
24941
25243
  }
24942
25244
 
24943
25245
  // src/compiler/rules.ts
24944
- import path29 from "path";
25246
+ import path30 from "path";
24945
25247
  var import_yaml8 = __toESM(require_dist(), 1);
24946
- import fs30 from "fs";
25248
+ import fs31 from "fs";
24947
25249
  function compileRules(sourceRulesDir, target, _mappings, lossReport) {
24948
25250
  if (target === "copilot") {
24949
25251
  addLoss(lossReport, "copilot", "rules", {
@@ -24980,13 +25282,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
24980
25282
  }
24981
25283
  const appendixParts = [];
24982
25284
  const dotRulesFiles = [];
24983
- for (const ruleFile of ts(path29.join(sourceRulesDir, "*.md")).sort()) {
25285
+ for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
24984
25286
  const parsed = parseRule(ruleFile);
24985
- const name = path29.basename(ruleFile, ".md");
25287
+ const name = path30.basename(ruleFile, ".md");
24986
25288
  if (parsed.mode === "exec-policy") {
24987
25289
  dotRulesFiles.push({
24988
25290
  name: `${name}.rules`,
24989
- content: `${formatProvenanceMarker("toml", `rules/${path29.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
25291
+ content: `${formatProvenanceMarker("toml", `rules/${path30.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
24990
25292
  ${parsed.body}`
24991
25293
  });
24992
25294
  continue;
@@ -24995,7 +25297,7 @@ ${parsed.body}`
24995
25297
 
24996
25298
  ${parsed.body.trim()}`);
24997
25299
  addLoss(lossReport, "codex", "rules", {
24998
- source: `rules/${path29.basename(ruleFile)}`,
25300
+ source: `rules/${path30.basename(ruleFile)}`,
24999
25301
  fields: [
25000
25302
  {
25001
25303
  field: "mode",
@@ -25005,7 +25307,7 @@ ${parsed.body.trim()}`);
25005
25307
  "mode",
25006
25308
  "rule-as-instruction"
25007
25309
  ),
25008
- detail: `${path29.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
25310
+ detail: `${path30.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
25009
25311
  }
25010
25312
  ]
25011
25313
  });
@@ -25013,7 +25315,7 @@ ${parsed.body.trim()}`);
25013
25315
  return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
25014
25316
  }
25015
25317
  function parseRule(ruleFile) {
25016
- const content = fs30.readFileSync(ruleFile, "utf8");
25318
+ const content = fs31.readFileSync(ruleFile, "utf8");
25017
25319
  if (!content.startsWith("---\n")) {
25018
25320
  return { mode: "guidance", body: content };
25019
25321
  }
@@ -25037,14 +25339,14 @@ function isRuleMode(value) {
25037
25339
  }
25038
25340
  function compileOpenCodeRules(sourceRulesDir, lossReport) {
25039
25341
  const appendixParts = [];
25040
- for (const ruleFile of ts(path29.join(sourceRulesDir, "*.md")).sort()) {
25342
+ for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
25041
25343
  const parsed = parseRule(ruleFile);
25042
- const name = path29.basename(ruleFile, ".md");
25344
+ const name = path30.basename(ruleFile, ".md");
25043
25345
  appendixParts.push(`## ${name}
25044
25346
 
25045
25347
  ${parsed.body.trim()}`);
25046
25348
  addLoss(lossReport, "opencode", "rules", {
25047
- source: `rules/${path29.basename(ruleFile)}`,
25349
+ source: `rules/${path30.basename(ruleFile)}`,
25048
25350
  fields: [
25049
25351
  {
25050
25352
  field: "rule",
@@ -25054,7 +25356,7 @@ ${parsed.body.trim()}`);
25054
25356
  "rule",
25055
25357
  "rule-path-scoping"
25056
25358
  ),
25057
- detail: `${path29.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
25359
+ detail: `${path30.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
25058
25360
  }
25059
25361
  ]
25060
25362
  });
@@ -25063,9 +25365,9 @@ ${parsed.body.trim()}`);
25063
25365
  }
25064
25366
  function compileCursorRules(sourceRulesDir, _lossReport) {
25065
25367
  const dotRulesFiles = [];
25066
- for (const ruleFile of ts(path29.join(sourceRulesDir, "*.md")).sort()) {
25067
- const content = fs30.readFileSync(ruleFile, "utf8");
25068
- const name = path29.basename(ruleFile, ".md");
25368
+ for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
25369
+ const content = fs31.readFileSync(ruleFile, "utf8");
25370
+ const name = path30.basename(ruleFile, ".md");
25069
25371
  let frontmatterData = {};
25070
25372
  let body = content;
25071
25373
  if (content.startsWith("---\n")) {
@@ -25094,7 +25396,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
25094
25396
  }
25095
25397
  const marker = formatProvenanceMarker(
25096
25398
  "markdown",
25097
- `rules/${path29.basename(ruleFile)}`,
25399
+ `rules/${path30.basename(ruleFile)}`,
25098
25400
  computeSourceHash(ruleFile),
25099
25401
  "cursor"
25100
25402
  );
@@ -25110,9 +25412,9 @@ ${body}`;
25110
25412
  }
25111
25413
  function compileClineRules(sourceRulesDir, lossReport) {
25112
25414
  const dotRulesFiles = [];
25113
- for (const ruleFile of ts(path29.join(sourceRulesDir, "*.md")).sort()) {
25114
- const content = fs30.readFileSync(ruleFile, "utf8");
25115
- const name = path29.basename(ruleFile, ".md");
25415
+ for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
25416
+ const content = fs31.readFileSync(ruleFile, "utf8");
25417
+ const name = path30.basename(ruleFile, ".md");
25116
25418
  let frontmatterData = {};
25117
25419
  let body = content;
25118
25420
  if (content.startsWith("---\n")) {
@@ -25129,13 +25431,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
25129
25431
  }
25130
25432
  const marker = formatProvenanceMarker(
25131
25433
  "markdown",
25132
- `rules/${path29.basename(ruleFile)}`,
25434
+ `rules/${path30.basename(ruleFile)}`,
25133
25435
  computeSourceHash(ruleFile),
25134
25436
  "cline"
25135
25437
  );
25136
25438
  if (frontmatterData.mode === "exec-policy") {
25137
25439
  addLoss(lossReport, "cline", "rules", {
25138
- source: `rules/${path29.basename(ruleFile)}`,
25440
+ source: `rules/${path30.basename(ruleFile)}`,
25139
25441
  fields: [
25140
25442
  {
25141
25443
  field: "mode",
@@ -25145,7 +25447,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
25145
25447
  "mode",
25146
25448
  "rule-mode-downgrade"
25147
25449
  ),
25148
- detail: `${path29.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
25450
+ detail: `${path30.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
25149
25451
  }
25150
25452
  ]
25151
25453
  });
@@ -25190,7 +25492,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
25190
25492
  rules: profile.rules
25191
25493
  };
25192
25494
  const rules = compileRules(
25193
- path30.join(sourceRoot, config.source.rules),
25495
+ path31.join(sourceRoot, config.source.rules),
25194
25496
  "codex",
25195
25497
  mappings,
25196
25498
  lossReport
@@ -25335,9 +25637,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
25335
25637
  function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
25336
25638
  const cp = mappings.modelTiers.custom_provider;
25337
25639
  if (!cp) return "";
25338
- const agentsDir = path30.join(sourceRoot, config.source.agents);
25339
- if (!fs31.existsSync(agentsDir)) return "";
25340
- const agentFiles = ts(path30.join(agentsDir, "*.md")).sort();
25640
+ const agentsDir = path31.join(sourceRoot, config.source.agents);
25641
+ if (!fs32.existsSync(agentsDir)) return "";
25642
+ const agentFiles = ts(path31.join(agentsDir, "*.md")).sort();
25341
25643
  const hasProviderAgent = agentFiles.some((agentFile) => {
25342
25644
  const { data } = parseMarkdownFrontmatter(agentFile);
25343
25645
  return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
@@ -25402,7 +25704,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
25402
25704
  }
25403
25705
  ];
25404
25706
  for (const ruleFile of rules.dotRulesFiles) {
25405
- const destination = path30.join(rulesRoot, ruleFile.name);
25707
+ const destination = path31.join(rulesRoot, ruleFile.name);
25406
25708
  if (options.dryRun) {
25407
25709
  logger.info(`[dry-run] rules: write ${destination}`);
25408
25710
  outcomes.push({
@@ -25430,15 +25732,15 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
25430
25732
  return outcomes;
25431
25733
  }
25432
25734
  function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
25433
- const source = path30.join(sourceRoot, config.source.instructions);
25735
+ const source = path31.join(sourceRoot, config.source.instructions);
25434
25736
  const destination = resolveTargetPath(paths.instructions);
25435
- const composed = `${fs31.readFileSync(source, "utf8").trim()}
25737
+ const composed = `${fs32.readFileSync(source, "utf8").trim()}
25436
25738
 
25437
25739
  --- tangyr managed rules ---
25438
25740
  ${agentsAppendix}`.trim();
25439
25741
  const marker = formatProvenanceMarker(
25440
25742
  "markdown",
25441
- path30.basename(config.source.instructions),
25743
+ path31.basename(config.source.instructions),
25442
25744
  hashString(composed),
25443
25745
  "codex"
25444
25746
  );
@@ -25465,9 +25767,9 @@ ${composed}
25465
25767
  );
25466
25768
  }
25467
25769
  function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
25468
- const source = path30.resolve(sourceRoot, config.source.skills);
25770
+ const source = path31.resolve(sourceRoot, config.source.skills);
25469
25771
  const destination = resolveTargetPath(paths.skills);
25470
- if (!fs31.existsSync(source)) {
25772
+ if (!fs32.existsSync(source)) {
25471
25773
  return skippedMissingSource("skills", source);
25472
25774
  }
25473
25775
  if (options.dryRun) {
@@ -25483,29 +25785,29 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
25483
25785
  };
25484
25786
  }
25485
25787
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
25486
- fs31.unlinkSync(destination);
25788
+ fs32.unlinkSync(destination);
25487
25789
  logger.verbose(`Skills: created skills path ${destination}`);
25488
25790
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
25489
25791
  return { component: "skills", status: "conflict", path: destination };
25490
25792
  } else if (artifactClass === "managed-symlink") {
25491
- fs31.unlinkSync(destination);
25793
+ fs32.unlinkSync(destination);
25492
25794
  }
25493
- ensureDir(path30.dirname(destination));
25795
+ ensureDir(path31.dirname(destination));
25494
25796
  createRelativeSymlink(source, destination, "dir");
25495
25797
  logger.verbose(`Skills: created skills path ${destination}`);
25496
25798
  return { component: "skills", status: "success", path: destination };
25497
25799
  }
25498
25800
  function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
25499
- const sourceAgentsRoot = path30.join(sourceRoot, config.source.agents);
25500
- if (!fs31.existsSync(sourceAgentsRoot)) {
25801
+ const sourceAgentsRoot = path31.join(sourceRoot, config.source.agents);
25802
+ if (!fs32.existsSync(sourceAgentsRoot)) {
25501
25803
  return [skippedMissingSource("agents", sourceAgentsRoot)];
25502
25804
  }
25503
- const sourceAgents = ts(path30.join(sourceAgentsRoot, "*.md")).sort();
25805
+ const sourceAgents = ts(path31.join(sourceAgentsRoot, "*.md")).sort();
25504
25806
  const agentsRoot = resolveTargetPath(paths.agents);
25505
25807
  return sourceAgents.map((agentFile) => {
25506
- const destination = path30.join(
25808
+ const destination = path31.join(
25507
25809
  agentsRoot,
25508
- `${path30.basename(agentFile, ".md")}.toml`
25810
+ `${path31.basename(agentFile, ".md")}.toml`
25509
25811
  );
25510
25812
  const compiled = compileAgent(
25511
25813
  agentFile,
@@ -25541,10 +25843,10 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
25541
25843
  }
25542
25844
  const source = resolveHooksSourceFile(sourceRoot, config);
25543
25845
  const sourceLabel = hooksSourceLabel(config);
25544
- if (!fs31.existsSync(source)) {
25846
+ if (!fs32.existsSync(source)) {
25545
25847
  return skippedMissingSource("hooks", source);
25546
25848
  }
25547
- const sourceHooksJson = JSON.parse(fs31.readFileSync(source, "utf8"));
25849
+ const sourceHooksJson = JSON.parse(fs32.readFileSync(source, "utf8"));
25548
25850
  const compiled = compileHooks(
25549
25851
  sourceHooksJson,
25550
25852
  "codex",
@@ -25566,7 +25868,7 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
25566
25868
  destination,
25567
25869
  hostHooks,
25568
25870
  stringifyJson2,
25569
- !fs31.existsSync(destination),
25871
+ !fs32.existsSync(destination),
25570
25872
  logger
25571
25873
  );
25572
25874
  return {
@@ -25579,7 +25881,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
25579
25881
  const source = resolveMcpSourceFile(sourceRoot, config);
25580
25882
  const sourceLabel = mcpSourceLabel(config);
25581
25883
  const destination = resolveTargetPath(paths.mcp_shared_file);
25582
- if (!fs31.existsSync(source)) {
25884
+ if (!fs32.existsSync(source)) {
25583
25885
  if (providerToml && !options.dryRun) {
25584
25886
  const changed2 = writeTomlManagedSection(
25585
25887
  destination,
@@ -25594,7 +25896,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
25594
25896
  }
25595
25897
  return skippedMissingSource("mcp", source);
25596
25898
  }
25597
- const sourceMcpJson = JSON.parse(fs31.readFileSync(source, "utf8"));
25899
+ const sourceMcpJson = JSON.parse(fs32.readFileSync(source, "utf8"));
25598
25900
  const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
25599
25901
  const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
25600
25902
  if (options.dryRun) {
@@ -25616,12 +25918,12 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
25616
25918
  if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
25617
25919
  return { component, status: "conflict", path: destination };
25618
25920
  }
25619
- ensureDir(path30.dirname(destination));
25620
- fs31.writeFileSync(destination, content);
25921
+ ensureDir(path31.dirname(destination));
25922
+ fs32.writeFileSync(destination, content);
25621
25923
  return { component, status: "success", path: destination };
25622
25924
  }
25623
25925
  function writeTomlManagedSection(destination, managedContent, logger) {
25624
- const current = fs31.existsSync(destination) ? fs31.readFileSync(destination, "utf8") : "";
25926
+ const current = fs32.existsSync(destination) ? fs32.readFileSync(destination, "utf8") : "";
25625
25927
  const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
25626
25928
  if (isFirstWrite) {
25627
25929
  logger.warn(
@@ -25637,8 +25939,8 @@ ${managedMcpEnd}
25637
25939
  if (current === next.trimStart()) {
25638
25940
  return false;
25639
25941
  }
25640
- ensureDir(path30.dirname(destination));
25641
- fs31.writeFileSync(destination, next.trimStart());
25942
+ ensureDir(path31.dirname(destination));
25943
+ fs32.writeFileSync(destination, next.trimStart());
25642
25944
  return true;
25643
25945
  }
25644
25946
  function removeManagedTomlSection(content) {
@@ -25665,16 +25967,16 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
25665
25967
  backupFile(destination, manifest);
25666
25968
  writeManifest(scopePath, manifest);
25667
25969
  } else {
25668
- fs31.renameSync(destination, `${destination}.bak.${Date.now()}`);
25970
+ fs32.renameSync(destination, `${destination}.bak.${Date.now()}`);
25669
25971
  }
25670
25972
  return true;
25671
25973
  }
25672
- fs31.rmSync(destination, { recursive: true, force: true });
25974
+ fs32.rmSync(destination, { recursive: true, force: true });
25673
25975
  return true;
25674
25976
  }
25675
25977
  function isCompiledCurrent(destination, expectedContent, expectedHash) {
25676
25978
  try {
25677
- const current = fs31.readFileSync(destination, "utf8");
25979
+ const current = fs32.readFileSync(destination, "utf8");
25678
25980
  const marker = extractProvenanceMarker(current);
25679
25981
  return expectedHash ? marker?.hash === expectedHash && marker.target === "codex" && current === expectedContent : current === expectedContent;
25680
25982
  } catch {
@@ -25693,16 +25995,16 @@ function shouldSkipComponent(options, component) {
25693
25995
  }
25694
25996
  function isSymlinkTo(linkPath, source) {
25695
25997
  try {
25696
- return fs31.realpathSync(linkPath) === fs31.realpathSync(source);
25998
+ return fs32.realpathSync(linkPath) === fs32.realpathSync(source);
25697
25999
  } catch {
25698
26000
  return false;
25699
26001
  }
25700
26002
  }
25701
26003
  function readJsonObject3(filePath) {
25702
- if (!fs31.existsSync(filePath)) {
26004
+ if (!fs32.existsSync(filePath)) {
25703
26005
  return {};
25704
26006
  }
25705
- const parsed = JSON.parse(fs31.readFileSync(filePath, "utf8"));
26007
+ const parsed = JSON.parse(fs32.readFileSync(filePath, "utf8"));
25706
26008
  return isRecord4(parsed) ? parsed : {};
25707
26009
  }
25708
26010
  function stringifyJson2(value) {
@@ -25718,16 +26020,16 @@ function hashString(value) {
25718
26020
 
25719
26021
  // src/adapters/copilot.ts
25720
26022
  import crypto6 from "crypto";
25721
- import fs32 from "fs";
25722
- import path32 from "path";
26023
+ import fs33 from "fs";
26024
+ import path33 from "path";
25723
26025
 
25724
26026
  // src/compiler/commands.ts
25725
26027
  var import_yaml9 = __toESM(require_dist(), 1);
25726
- import path31 from "path";
26028
+ import path32 from "path";
25727
26029
  function compileCommandPrompt(sourceFile) {
25728
26030
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
25729
- const relativeSource = `commands/${path31.basename(sourceFile)}`;
25730
- const fields = promptFrontmatter(data, path31.basename(sourceFile, ".md"));
26031
+ const relativeSource = `commands/${path32.basename(sourceFile)}`;
26032
+ const fields = promptFrontmatter(data, path32.basename(sourceFile, ".md"));
25731
26033
  const marker = formatProvenanceMarker(
25732
26034
  "markdown",
25733
26035
  relativeSource,
@@ -25902,13 +26204,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
25902
26204
  }
25903
26205
  function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
25904
26206
  if (!mappings.modelTiers.custom_provider) return;
25905
- const agentsDir = path32.join(sourceRoot, config.source.agents);
25906
- if (!fs32.existsSync(agentsDir)) return;
25907
- for (const agentFile of ts(path32.join(agentsDir, "*.md")).sort()) {
26207
+ const agentsDir = path33.join(sourceRoot, config.source.agents);
26208
+ if (!fs33.existsSync(agentsDir)) return;
26209
+ for (const agentFile of ts(path33.join(agentsDir, "*.md")).sort()) {
25908
26210
  const { data } = parseMarkdownFrontmatter(agentFile);
25909
26211
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
25910
26212
  if (hasProvider) {
25911
- const basename = path32.basename(agentFile);
26213
+ const basename = path33.basename(agentFile);
25912
26214
  addLoss(lossReport, "copilot", "agents", {
25913
26215
  source: `agents/${basename}`,
25914
26216
  fields: [
@@ -25933,23 +26235,23 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
25933
26235
  logger.verbose(message);
25934
26236
  return [{ component: "instructions", status: "skipped", path: message }];
25935
26237
  }
25936
- const source = path32.resolve(sourceRoot, config.source.instructions);
25937
- if (!fs32.existsSync(source)) {
26238
+ const source = path33.resolve(sourceRoot, config.source.instructions);
26239
+ if (!fs33.existsSync(source)) {
25938
26240
  return [skippedMissingSource2("instructions", source)];
25939
26241
  }
25940
- const rawContent = fs32.readFileSync(source, "utf8");
26242
+ const rawContent = fs33.readFileSync(source, "utf8");
25941
26243
  const contentHash = hashString2(rawContent);
25942
26244
  const marker = formatProvenanceMarker(
25943
26245
  "markdown",
25944
- path32.basename(config.source.instructions),
26246
+ path33.basename(config.source.instructions),
25945
26247
  contentHash,
25946
26248
  "copilot"
25947
26249
  );
25948
26250
  const composedContent = `${marker}
25949
26251
  ${rawContent}`;
25950
26252
  const projectRoot = options.projectRoot ?? process.cwd();
25951
- const agentsMdDest = path32.resolve(projectRoot, "AGENTS.md");
25952
- const mirrorDest = path32.resolve(
26253
+ const agentsMdDest = path33.resolve(projectRoot, "AGENTS.md");
26254
+ const mirrorDest = path33.resolve(
25953
26255
  projectRoot,
25954
26256
  ".github",
25955
26257
  "copilot-instructions.md"
@@ -26003,17 +26305,17 @@ function writeInstructionsFile(component, destination, content, contentHash, con
26003
26305
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
26004
26306
  return { component, status: "conflict", path: destination };
26005
26307
  }
26006
- ensureDir(path32.dirname(destination));
26007
- fs32.writeFileSync(destination, content);
26308
+ ensureDir(path33.dirname(destination));
26309
+ fs33.writeFileSync(destination, content);
26008
26310
  return { component, status: "success", path: destination };
26009
26311
  }
26010
26312
  function hashString2(value) {
26011
26313
  return `sha256:${crypto6.createHash("sha256").update(value).digest("hex")}`;
26012
26314
  }
26013
26315
  function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
26014
- const source = path32.resolve(sourceRoot, config.source.skills);
26316
+ const source = path33.resolve(sourceRoot, config.source.skills);
26015
26317
  const destination = resolveTargetPath(paths.skills);
26016
- if (!fs32.existsSync(source)) {
26318
+ if (!fs33.existsSync(source)) {
26017
26319
  return skippedMissingSource2("skills", source);
26018
26320
  }
26019
26321
  if (options.dryRun) {
@@ -26029,27 +26331,27 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
26029
26331
  };
26030
26332
  }
26031
26333
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
26032
- fs32.unlinkSync(destination);
26334
+ fs33.unlinkSync(destination);
26033
26335
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
26034
26336
  return { component: "skills", status: "conflict", path: destination };
26035
26337
  } else if (artifactClass === "managed-symlink") {
26036
- fs32.unlinkSync(destination);
26338
+ fs33.unlinkSync(destination);
26037
26339
  }
26038
- ensureDir(path32.dirname(destination));
26340
+ ensureDir(path33.dirname(destination));
26039
26341
  createRelativeSymlink(source, destination, "dir");
26040
26342
  return { component: "skills", status: "success", path: destination };
26041
26343
  }
26042
26344
  function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
26043
- const sourceAgentsRoot = path32.join(sourceRoot, config.source.agents);
26044
- if (!fs32.existsSync(sourceAgentsRoot)) {
26345
+ const sourceAgentsRoot = path33.join(sourceRoot, config.source.agents);
26346
+ if (!fs33.existsSync(sourceAgentsRoot)) {
26045
26347
  return [skippedMissingSource2("agents", sourceAgentsRoot)];
26046
26348
  }
26047
- const sourceAgents = ts(path32.join(sourceAgentsRoot, "*.md")).sort();
26349
+ const sourceAgents = ts(path33.join(sourceAgentsRoot, "*.md")).sort();
26048
26350
  const agentsRoot = resolveTargetPath(paths.agents);
26049
26351
  return sourceAgents.map((agentFile) => {
26050
- const destination = path32.join(
26352
+ const destination = path33.join(
26051
26353
  agentsRoot,
26052
- `${path32.basename(agentFile, ".md")}.agent.md`
26354
+ `${path33.basename(agentFile, ".md")}.agent.md`
26053
26355
  );
26054
26356
  const compiled = compileAgent(
26055
26357
  agentFile,
@@ -26077,16 +26379,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
26077
26379
  });
26078
26380
  }
26079
26381
  function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
26080
- const sourceCommandsRoot = path32.join(sourceRoot, config.source.commands);
26081
- if (!fs32.existsSync(sourceCommandsRoot)) {
26382
+ const sourceCommandsRoot = path33.join(sourceRoot, config.source.commands);
26383
+ if (!fs33.existsSync(sourceCommandsRoot)) {
26082
26384
  return [skippedMissingSource2("commands", sourceCommandsRoot)];
26083
26385
  }
26084
- const sourceCommands = ts(path32.join(sourceCommandsRoot, "*.md")).sort();
26386
+ const sourceCommands = ts(path33.join(sourceCommandsRoot, "*.md")).sort();
26085
26387
  const promptsRoot = resolveTargetPath(paths.prompts);
26086
26388
  return sourceCommands.map((commandFile) => {
26087
- const destination = path32.join(
26389
+ const destination = path33.join(
26088
26390
  promptsRoot,
26089
- `${path32.basename(commandFile, ".md")}.prompt.md`
26391
+ `${path33.basename(commandFile, ".md")}.prompt.md`
26090
26392
  );
26091
26393
  const compiled = compileCommandPrompt(commandFile);
26092
26394
  if (options.dryRun) {
@@ -26112,14 +26414,14 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
26112
26414
  function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, logger) {
26113
26415
  const source = resolveHooksSourceFile(sourceRoot, config);
26114
26416
  const sourceLabel = hooksSourceLabel(config);
26115
- const destination = path32.join(
26417
+ const destination = path33.join(
26116
26418
  resolveTargetPath(paths.hooks),
26117
26419
  "tangyr-managed.json"
26118
26420
  );
26119
- if (!fs32.existsSync(source)) {
26421
+ if (!fs33.existsSync(source)) {
26120
26422
  return skippedMissingSource2("hooks", source);
26121
26423
  }
26122
- const sourceHooksJson = JSON.parse(fs32.readFileSync(source, "utf8"));
26424
+ const sourceHooksJson = JSON.parse(fs33.readFileSync(source, "utf8"));
26123
26425
  const compiled = compileHooks(
26124
26426
  sourceHooksJson,
26125
26427
  "copilot",
@@ -26156,10 +26458,10 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger) {
26156
26458
  const source = resolveMcpSourceFile(sourceRoot, config);
26157
26459
  const sourceLabel = mcpSourceLabel(config);
26158
26460
  const destination = resolveTargetPath(paths.mcp_shared_file);
26159
- if (!fs32.existsSync(source)) {
26461
+ if (!fs33.existsSync(source)) {
26160
26462
  return skippedMissingSource2("mcp", source);
26161
26463
  }
26162
- const sourceMcpJson = JSON.parse(fs32.readFileSync(source, "utf8"));
26464
+ const sourceMcpJson = JSON.parse(fs33.readFileSync(source, "utf8"));
26163
26465
  const compiled = compileMcp(
26164
26466
  sourceMcpJson,
26165
26467
  "copilot",
@@ -26189,13 +26491,13 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
26189
26491
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
26190
26492
  return { component, status: "conflict", path: destination };
26191
26493
  }
26192
- ensureDir(path32.dirname(destination));
26193
- fs32.writeFileSync(destination, content);
26494
+ ensureDir(path33.dirname(destination));
26495
+ fs33.writeFileSync(destination, content);
26194
26496
  return { component, status: "success", path: destination };
26195
26497
  }
26196
26498
  function isCompiledCurrent2(destination, expectedContent, expectedHash) {
26197
26499
  try {
26198
- const current = fs32.readFileSync(destination, "utf8");
26500
+ const current = fs33.readFileSync(destination, "utf8");
26199
26501
  const marker = extractProvenanceMarker(current);
26200
26502
  return expectedHash ? marker?.hash === expectedHash && marker.target === "copilot" && current === expectedContent : current === expectedContent;
26201
26503
  } catch {
@@ -26218,11 +26520,11 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
26218
26520
  backupFile(destination, manifest);
26219
26521
  writeManifest(scopePath, manifest);
26220
26522
  } else {
26221
- fs32.renameSync(destination, `${destination}.bak.${Date.now()}`);
26523
+ fs33.renameSync(destination, `${destination}.bak.${Date.now()}`);
26222
26524
  }
26223
26525
  return true;
26224
26526
  }
26225
- fs32.rmSync(destination, { recursive: true, force: true });
26527
+ fs33.rmSync(destination, { recursive: true, force: true });
26226
26528
  return true;
26227
26529
  }
26228
26530
  function shouldSkipComponent2(options, component) {
@@ -26231,12 +26533,12 @@ function shouldSkipComponent2(options, component) {
26231
26533
  function cleanupLegacyAgents(paths, options, logger) {
26232
26534
  const currentAgentsRoot = resolveTargetPath(paths.agents);
26233
26535
  const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
26234
- if (path32.resolve(currentAgentsRoot) === path32.resolve(legacyAgentsRoot)) {
26536
+ if (path33.resolve(currentAgentsRoot) === path33.resolve(legacyAgentsRoot)) {
26235
26537
  return [];
26236
26538
  }
26237
26539
  const outcomes = [];
26238
26540
  for (const filePath of ts(
26239
- path32.join(legacyAgentsRoot, "*.agent.md")
26541
+ path33.join(legacyAgentsRoot, "*.agent.md")
26240
26542
  ).sort()) {
26241
26543
  if (!isCopilotManagedCompiledFile(filePath)) {
26242
26544
  continue;
@@ -26246,14 +26548,14 @@ function cleanupLegacyAgents(paths, options, logger) {
26246
26548
  outcomes.push({ component: "agents", status: "dry-run", path: filePath });
26247
26549
  continue;
26248
26550
  }
26249
- fs32.rmSync(filePath, { force: true });
26551
+ fs33.rmSync(filePath, { force: true });
26250
26552
  outcomes.push({ component: "agents", status: "success", path: filePath });
26251
26553
  }
26252
26554
  return outcomes;
26253
26555
  }
26254
26556
  function isCopilotManagedCompiledFile(filePath) {
26255
26557
  try {
26256
- return extractProvenanceMarker(fs32.readFileSync(filePath, "utf8"))?.target === "copilot";
26558
+ return extractProvenanceMarker(fs33.readFileSync(filePath, "utf8"))?.target === "copilot";
26257
26559
  } catch {
26258
26560
  return false;
26259
26561
  }
@@ -26267,7 +26569,7 @@ function skippedMissingSource2(component, source) {
26267
26569
  }
26268
26570
  function isSymlinkTo2(linkPath, source) {
26269
26571
  try {
26270
- return fs32.realpathSync(linkPath) === fs32.realpathSync(source);
26572
+ return fs33.realpathSync(linkPath) === fs33.realpathSync(source);
26271
26573
  } catch {
26272
26574
  return false;
26273
26575
  }
@@ -26275,8 +26577,8 @@ function isSymlinkTo2(linkPath, source) {
26275
26577
 
26276
26578
  // src/adapters/cursor.ts
26277
26579
  import crypto7 from "crypto";
26278
- import fs33 from "fs";
26279
- import path33 from "path";
26580
+ import fs34 from "fs";
26581
+ import path34 from "path";
26280
26582
  function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
26281
26583
  const scope = options.scope ?? "global";
26282
26584
  const profile = resolveTargetPaths({
@@ -26427,9 +26729,9 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
26427
26729
  return { target: "cursor", outcomes };
26428
26730
  }
26429
26731
  function syncInstructions2(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
26430
- const source = path33.join(sourceRoot, config.source.instructions);
26732
+ const source = path34.join(sourceRoot, config.source.instructions);
26431
26733
  const destination = resolveTargetPath(paths.instructions);
26432
- const baseContent = fs33.existsSync(source) ? fs33.readFileSync(source, "utf8").trim() : "";
26734
+ const baseContent = fs34.existsSync(source) ? fs34.readFileSync(source, "utf8").trim() : "";
26433
26735
  const personaContent = extractPrimaryPersonaContent(
26434
26736
  config,
26435
26737
  sourceRoot,
@@ -26442,7 +26744,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
26442
26744
  ${personaContent}`.trim() : baseContent;
26443
26745
  const marker = formatProvenanceMarker(
26444
26746
  "markdown",
26445
- path33.basename(config.source.instructions),
26747
+ path34.basename(config.source.instructions),
26446
26748
  hashString3(composed),
26447
26749
  "cursor"
26448
26750
  );
@@ -26467,11 +26769,11 @@ ${composed}
26467
26769
  );
26468
26770
  }
26469
26771
  function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
26470
- const agentsDir = path33.join(sourceRoot, config.source.agents);
26471
- if (!fs33.existsSync(agentsDir)) {
26772
+ const agentsDir = path34.join(sourceRoot, config.source.agents);
26773
+ if (!fs34.existsSync(agentsDir)) {
26472
26774
  return null;
26473
26775
  }
26474
- const agentFiles = ts(path33.join(agentsDir, "*.md")).sort();
26776
+ const agentFiles = ts(path34.join(agentsDir, "*.md")).sort();
26475
26777
  if (agentFiles.length === 0) {
26476
26778
  return null;
26477
26779
  }
@@ -26494,7 +26796,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
26494
26796
  return null;
26495
26797
  }
26496
26798
  addLoss(lossReport, "cursor", "instructions", {
26497
- source: `agents/${path33.basename(primaryFile)}`,
26799
+ source: `agents/${path34.basename(primaryFile)}`,
26498
26800
  fields: [
26499
26801
  {
26500
26802
  field: "persona",
@@ -26504,23 +26806,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
26504
26806
  "persona",
26505
26807
  "instructions-shim"
26506
26808
  ),
26507
- detail: `Primary persona from ${path33.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
26809
+ detail: `Primary persona from ${path34.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
26508
26810
  }
26509
26811
  ]
26510
26812
  });
26511
26813
  return body.trim();
26512
26814
  }
26513
26815
  function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
26514
- const sourceAgentsRoot = path33.join(sourceRoot, config.source.agents);
26515
- if (!fs33.existsSync(sourceAgentsRoot)) {
26816
+ const sourceAgentsRoot = path34.join(sourceRoot, config.source.agents);
26817
+ if (!fs34.existsSync(sourceAgentsRoot)) {
26516
26818
  return [skippedMissingSource3("agents", sourceAgentsRoot)];
26517
26819
  }
26518
- const sourceAgents = ts(path33.join(sourceAgentsRoot, "*.md")).sort();
26820
+ const sourceAgents = ts(path34.join(sourceAgentsRoot, "*.md")).sort();
26519
26821
  const agentsRoot = resolveTargetPath(paths.agents);
26520
26822
  return sourceAgents.map((agentFile) => {
26521
- const destination = path33.join(
26823
+ const destination = path34.join(
26522
26824
  agentsRoot,
26523
- `${path33.basename(agentFile, ".md")}.md`
26825
+ `${path34.basename(agentFile, ".md")}.md`
26524
26826
  );
26525
26827
  let compiled;
26526
26828
  try {
@@ -26561,14 +26863,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
26561
26863
  });
26562
26864
  }
26563
26865
  function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
26564
- const sourceRulesDir = path33.join(sourceRoot, config.source.rules);
26565
- if (!fs33.existsSync(sourceRulesDir)) {
26866
+ const sourceRulesDir = path34.join(sourceRoot, config.source.rules);
26867
+ if (!fs34.existsSync(sourceRulesDir)) {
26566
26868
  return [skippedMissingSource3("rules", sourceRulesDir)];
26567
26869
  }
26568
26870
  const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
26569
26871
  const rulesDir = resolveTargetPath(paths.rules);
26570
26872
  return compiled.dotRulesFiles.map(({ name, content }) => {
26571
- const destination = path33.join(rulesDir, name);
26873
+ const destination = path34.join(rulesDir, name);
26572
26874
  if (options.dryRun) {
26573
26875
  logger.info(`[dry-run] rules: write ${destination}`);
26574
26876
  return {
@@ -26592,17 +26894,17 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
26592
26894
  });
26593
26895
  }
26594
26896
  function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
26595
- const sourceCommandsRoot = path33.join(sourceRoot, config.source.commands);
26596
- if (!fs33.existsSync(sourceCommandsRoot)) {
26897
+ const sourceCommandsRoot = path34.join(sourceRoot, config.source.commands);
26898
+ if (!fs34.existsSync(sourceCommandsRoot)) {
26597
26899
  return [skippedMissingSource3("commands", sourceCommandsRoot)];
26598
26900
  }
26599
- const sourceCommands = ts(path33.join(sourceCommandsRoot, "*.md")).sort();
26901
+ const sourceCommands = ts(path34.join(sourceCommandsRoot, "*.md")).sort();
26600
26902
  const skillsRoot = resolveTargetPath(paths.skills);
26601
26903
  return sourceCommands.map((commandFile) => {
26602
- const baseName = path33.basename(commandFile, ".md");
26603
- const destination = path33.join(skillsRoot, baseName, "SKILL.md");
26604
- const commandContent = fs33.readFileSync(commandFile, "utf8");
26605
- const relativeSource = `commands/${path33.basename(commandFile)}`;
26904
+ const baseName = path34.basename(commandFile, ".md");
26905
+ const destination = path34.join(skillsRoot, baseName, "SKILL.md");
26906
+ const commandContent = fs34.readFileSync(commandFile, "utf8");
26907
+ const relativeSource = `commands/${path34.basename(commandFile)}`;
26606
26908
  const marker = formatProvenanceMarker(
26607
26909
  "markdown",
26608
26910
  relativeSource,
@@ -26641,8 +26943,8 @@ ${commandContent.trim()}
26641
26943
  });
26642
26944
  }
26643
26945
  function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
26644
- const source = path33.resolve(sourceRoot, config.source.skills);
26645
- if (!fs33.existsSync(source)) {
26946
+ const source = path34.resolve(sourceRoot, config.source.skills);
26947
+ if (!fs34.existsSync(source)) {
26646
26948
  return skippedMissingSource3(component, source);
26647
26949
  }
26648
26950
  if (options.dryRun) {
@@ -26656,18 +26958,18 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
26656
26958
  return { component, status: "skipped-current", path: destination };
26657
26959
  }
26658
26960
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
26659
- fs33.unlinkSync(destination);
26961
+ fs34.unlinkSync(destination);
26660
26962
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
26661
26963
  return { component, status: "conflict", path: destination };
26662
26964
  } else if (artifactClass === "managed-symlink") {
26663
- fs33.unlinkSync(destination);
26965
+ fs34.unlinkSync(destination);
26664
26966
  }
26665
- ensureDir(path33.dirname(destination));
26967
+ ensureDir(path34.dirname(destination));
26666
26968
  createRelativeSymlink(source, destination, "dir");
26667
26969
  logger.verbose(`Skills: created shared skills symlink ${destination}`);
26668
26970
  return { component, status: "success", path: destination };
26669
26971
  }
26670
- if (fs33.existsSync(destination)) {
26972
+ if (fs34.existsSync(destination)) {
26671
26973
  return { component, status: "skipped-current", path: destination };
26672
26974
  }
26673
26975
  ensureDir(destination);
@@ -26678,7 +26980,7 @@ function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, lo
26678
26980
  const source = resolveHooksSourceFile(sourceRoot, config);
26679
26981
  const sourceLabel = hooksSourceLabel(config);
26680
26982
  const destination = resolveTargetPath(paths.hooks_file);
26681
- const sourceHooksJson = fs33.existsSync(source) ? JSON.parse(fs33.readFileSync(source, "utf8")) : { hooks: {} };
26983
+ const sourceHooksJson = fs34.existsSync(source) ? JSON.parse(fs34.readFileSync(source, "utf8")) : { hooks: {} };
26682
26984
  const compiled = compileHooks(
26683
26985
  sourceHooksJson,
26684
26986
  "cursor",
@@ -26692,18 +26994,18 @@ function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, lo
26692
26994
  }
26693
26995
  const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
26694
26996
  `;
26695
- ensureDir(path33.dirname(destination));
26696
- fs33.writeFileSync(destination, hooksFileContent);
26997
+ ensureDir(path34.dirname(destination));
26998
+ fs34.writeFileSync(destination, hooksFileContent);
26697
26999
  return { component: "hooks", status: "success", path: destination };
26698
27000
  }
26699
27001
  function syncMcp3(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
26700
27002
  const source = resolveMcpSourceFile(sourceRoot, config);
26701
27003
  const sourceLabel = mcpSourceLabel(config);
26702
27004
  const destination = resolveTargetPath(paths.mcp_file);
26703
- if (!fs33.existsSync(source)) {
27005
+ if (!fs34.existsSync(source)) {
26704
27006
  return skippedMissingSource3("mcp", source);
26705
27007
  }
26706
- const sourceMcpJson = JSON.parse(fs33.readFileSync(source, "utf8"));
27008
+ const sourceMcpJson = JSON.parse(fs34.readFileSync(source, "utf8"));
26707
27009
  const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
26708
27010
  if (options.dryRun) {
26709
27011
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -26754,13 +27056,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
26754
27056
  );
26755
27057
  }
26756
27058
  function syncProviderPin(config, sourceRoot, lossReport) {
26757
- const agentsDir = path33.join(sourceRoot, config.source.agents);
26758
- if (!fs33.existsSync(agentsDir)) return;
26759
- for (const agentFile of ts(path33.join(agentsDir, "*.md")).sort()) {
27059
+ const agentsDir = path34.join(sourceRoot, config.source.agents);
27060
+ if (!fs34.existsSync(agentsDir)) return;
27061
+ for (const agentFile of ts(path34.join(agentsDir, "*.md")).sort()) {
26760
27062
  const { data } = parseMarkdownFrontmatter(agentFile);
26761
27063
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
26762
27064
  if (hasCustomProvider) {
26763
- const relativeSource = `agents/${path33.basename(agentFile)}`;
27065
+ const relativeSource = `agents/${path34.basename(agentFile)}`;
26764
27066
  addLoss(lossReport, "cursor", "agents", {
26765
27067
  source: relativeSource,
26766
27068
  fields: [
@@ -26772,7 +27074,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
26772
27074
  "provider",
26773
27075
  "provider-not-representable"
26774
27076
  ),
26775
- detail: `${path33.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
27077
+ detail: `${path34.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
26776
27078
  }
26777
27079
  ]
26778
27080
  });
@@ -26787,8 +27089,8 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
26787
27089
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
26788
27090
  return { component, status: "conflict", path: destination };
26789
27091
  }
26790
- ensureDir(path33.dirname(destination));
26791
- fs33.writeFileSync(destination, content);
27092
+ ensureDir(path34.dirname(destination));
27093
+ fs34.writeFileSync(destination, content);
26792
27094
  return { component, status: "success", path: destination };
26793
27095
  }
26794
27096
  function handleConflict3(destination, config, options, logger, manifest, scopePath) {
@@ -26807,16 +27109,16 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
26807
27109
  backupFile(destination, manifest);
26808
27110
  writeManifest(scopePath, manifest);
26809
27111
  } else {
26810
- fs33.renameSync(destination, `${destination}.bak.${Date.now()}`);
27112
+ fs34.renameSync(destination, `${destination}.bak.${Date.now()}`);
26811
27113
  }
26812
27114
  return true;
26813
27115
  }
26814
- fs33.rmSync(destination, { recursive: true, force: true });
27116
+ fs34.rmSync(destination, { recursive: true, force: true });
26815
27117
  return true;
26816
27118
  }
26817
27119
  function isCompiledCurrent3(destination, expectedContent, expectedHash) {
26818
27120
  try {
26819
- const current = fs33.readFileSync(destination, "utf8");
27121
+ const current = fs34.readFileSync(destination, "utf8");
26820
27122
  const marker = extractProvenanceMarker(current);
26821
27123
  return expectedHash ? marker?.hash === expectedHash && marker.target === "cursor" && current === expectedContent : current === expectedContent;
26822
27124
  } catch {
@@ -26835,7 +27137,7 @@ function shouldSkipComponent3(options, component) {
26835
27137
  }
26836
27138
  function isSymlinkTo3(linkPath, source) {
26837
27139
  try {
26838
- return fs33.realpathSync(linkPath) === fs33.realpathSync(source);
27140
+ return fs34.realpathSync(linkPath) === fs34.realpathSync(source);
26839
27141
  } catch {
26840
27142
  return false;
26841
27143
  }
@@ -26846,8 +27148,8 @@ function hashString3(value) {
26846
27148
 
26847
27149
  // src/adapters/cline.ts
26848
27150
  import crypto8 from "crypto";
26849
- import fs34 from "fs";
26850
- import path34 from "path";
27151
+ import fs35 from "fs";
27152
+ import path35 from "path";
26851
27153
  function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
26852
27154
  const scope = options.scope ?? "global";
26853
27155
  const profile = resolveTargetPaths({
@@ -26960,7 +27262,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
26960
27262
  function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
26961
27263
  if (scope === "global" || paths.instructions === null) {
26962
27264
  addLoss(lossReport, "cline", "instructions", {
26963
- source: path34.basename(config.source.instructions),
27265
+ source: path35.basename(config.source.instructions),
26964
27266
  fields: [
26965
27267
  {
26966
27268
  field: "instructions",
@@ -26980,12 +27282,12 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
26980
27282
  path: "cline/global/instructions: no committable global path"
26981
27283
  };
26982
27284
  }
26983
- const source = path34.join(sourceRoot, config.source.instructions);
27285
+ const source = path35.join(sourceRoot, config.source.instructions);
26984
27286
  const destination = resolveTargetPath(paths.instructions);
26985
- const baseContent = fs34.existsSync(source) ? fs34.readFileSync(source, "utf8").trim() : "";
27287
+ const baseContent = fs35.existsSync(source) ? fs35.readFileSync(source, "utf8").trim() : "";
26986
27288
  const marker = formatProvenanceMarker(
26987
27289
  "markdown",
26988
- path34.basename(config.source.instructions),
27290
+ path35.basename(config.source.instructions),
26989
27291
  hashString4(baseContent),
26990
27292
  "cline"
26991
27293
  );
@@ -27010,11 +27312,11 @@ ${baseContent}
27010
27312
  );
27011
27313
  }
27012
27314
  function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
27013
- const sourceAgentsRoot = path34.join(sourceRoot, config.source.agents);
27014
- if (!fs34.existsSync(sourceAgentsRoot)) {
27315
+ const sourceAgentsRoot = path35.join(sourceRoot, config.source.agents);
27316
+ if (!fs35.existsSync(sourceAgentsRoot)) {
27015
27317
  return [skippedMissingSource4("agents", sourceAgentsRoot)];
27016
27318
  }
27017
- const sourceAgents = ts(path34.join(sourceAgentsRoot, "*.md")).sort();
27319
+ const sourceAgents = ts(path35.join(sourceAgentsRoot, "*.md")).sort();
27018
27320
  return sourceAgents.map((agentFile) => {
27019
27321
  compileAgent(agentFile, "cline", mappings, extensions, lossReport);
27020
27322
  if (options.dryRun) {
@@ -27030,14 +27332,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
27030
27332
  });
27031
27333
  }
27032
27334
  function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
27033
- const sourceRulesDir = path34.join(sourceRoot, config.source.rules);
27034
- if (!fs34.existsSync(sourceRulesDir)) {
27335
+ const sourceRulesDir = path35.join(sourceRoot, config.source.rules);
27336
+ if (!fs35.existsSync(sourceRulesDir)) {
27035
27337
  return [skippedMissingSource4("rules", sourceRulesDir)];
27036
27338
  }
27037
27339
  const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
27038
27340
  const rulesDir = resolveTargetPath(paths.rules);
27039
27341
  return compiled.dotRulesFiles.map(({ name, content }) => {
27040
- const destination = path34.join(rulesDir, name);
27342
+ const destination = path35.join(rulesDir, name);
27041
27343
  if (options.dryRun) {
27042
27344
  logger.info(`[dry-run] rules: write ${destination}`);
27043
27345
  return {
@@ -27061,17 +27363,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
27061
27363
  });
27062
27364
  }
27063
27365
  function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
27064
- const sourceCommandsRoot = path34.join(sourceRoot, config.source.commands);
27065
- if (!fs34.existsSync(sourceCommandsRoot)) {
27366
+ const sourceCommandsRoot = path35.join(sourceRoot, config.source.commands);
27367
+ if (!fs35.existsSync(sourceCommandsRoot)) {
27066
27368
  return [skippedMissingSource4("commands", sourceCommandsRoot)];
27067
27369
  }
27068
- const sourceCommands = ts(path34.join(sourceCommandsRoot, "*.md")).sort();
27370
+ const sourceCommands = ts(path35.join(sourceCommandsRoot, "*.md")).sort();
27069
27371
  const workflowsRoot = resolveTargetPath(paths.workflows);
27070
27372
  return sourceCommands.map((commandFile) => {
27071
- const baseName = path34.basename(commandFile);
27072
- const destination = path34.join(workflowsRoot, baseName);
27073
- const commandContent = fs34.readFileSync(commandFile, "utf8");
27074
- const relativeSource = `commands/${path34.basename(commandFile)}`;
27373
+ const baseName = path35.basename(commandFile);
27374
+ const destination = path35.join(workflowsRoot, baseName);
27375
+ const commandContent = fs35.readFileSync(commandFile, "utf8");
27376
+ const relativeSource = `commands/${path35.basename(commandFile)}`;
27075
27377
  const marker = formatProvenanceMarker(
27076
27378
  "markdown",
27077
27379
  relativeSource,
@@ -27106,9 +27408,9 @@ ${commandContent.trim()}
27106
27408
  });
27107
27409
  }
27108
27410
  function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
27109
- const source = path34.resolve(sourceRoot, config.source.skills);
27411
+ const source = path35.resolve(sourceRoot, config.source.skills);
27110
27412
  const destination = resolveTargetPath(paths.skills);
27111
- if (!fs34.existsSync(source)) {
27413
+ if (!fs35.existsSync(source)) {
27112
27414
  return skippedMissingSource4("skills", source);
27113
27415
  }
27114
27416
  if (options.dryRun) {
@@ -27128,9 +27430,9 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
27128
27430
  return { component: "skills", status: "conflict", path: destination };
27129
27431
  }
27130
27432
  } else if (artifactClass === "managed-symlink") {
27131
- fs34.unlinkSync(destination);
27433
+ fs35.unlinkSync(destination);
27132
27434
  }
27133
- ensureDir(path34.dirname(destination));
27435
+ ensureDir(path35.dirname(destination));
27134
27436
  createRelativeSymlink(source, destination, "dir");
27135
27437
  logger.verbose(`Skills: created Cline skills symlink ${destination}`);
27136
27438
  return { component: "skills", status: "success", path: destination };
@@ -27138,7 +27440,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
27138
27440
  function syncHooks4(config, sourceRoot, mappings, options, lossReport, logger) {
27139
27441
  const source = resolveHooksSourceFile(sourceRoot, config);
27140
27442
  const sourceLabel = hooksSourceLabel(config);
27141
- const sourceHooksJson = fs34.existsSync(source) ? JSON.parse(fs34.readFileSync(source, "utf8")) : { hooks: {} };
27443
+ const sourceHooksJson = fs35.existsSync(source) ? JSON.parse(fs35.readFileSync(source, "utf8")) : { hooks: {} };
27142
27444
  compileHooks(sourceHooksJson, "cline", mappings, lossReport, sourceLabel);
27143
27445
  if (options.dryRun) {
27144
27446
  logger.info(`[dry-run] hooks: record hook-as-plugin loss for ${source}`);
@@ -27153,10 +27455,10 @@ function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manife
27153
27455
  const source = resolveMcpSourceFile(sourceRoot, config);
27154
27456
  const sourceLabel = mcpSourceLabel(config);
27155
27457
  const destination = resolveTargetPath(paths.mcp_file);
27156
- if (!fs34.existsSync(source)) {
27458
+ if (!fs35.existsSync(source)) {
27157
27459
  return skippedMissingSource4("mcp", source);
27158
27460
  }
27159
- const sourceMcpJson = JSON.parse(fs34.readFileSync(source, "utf8"));
27461
+ const sourceMcpJson = JSON.parse(fs35.readFileSync(source, "utf8"));
27160
27462
  const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
27161
27463
  if (options.dryRun) {
27162
27464
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -27199,11 +27501,11 @@ function syncSettings(lossReport) {
27199
27501
  };
27200
27502
  }
27201
27503
  function syncProviderAndModel(config, sourceRoot, lossReport) {
27202
- const agentsDir = path34.join(sourceRoot, config.source.agents);
27203
- if (!fs34.existsSync(agentsDir)) return;
27204
- for (const agentFile of ts(path34.join(agentsDir, "*.md")).sort()) {
27504
+ const agentsDir = path35.join(sourceRoot, config.source.agents);
27505
+ if (!fs35.existsSync(agentsDir)) return;
27506
+ for (const agentFile of ts(path35.join(agentsDir, "*.md")).sort()) {
27205
27507
  const { data } = parseMarkdownFrontmatter(agentFile);
27206
- const relativeSource = `agents/${path34.basename(agentFile)}`;
27508
+ const relativeSource = `agents/${path35.basename(agentFile)}`;
27207
27509
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
27208
27510
  if (hasCustomProvider) {
27209
27511
  addLoss(lossReport, "cline", "agents", {
@@ -27217,7 +27519,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
27217
27519
  "provider",
27218
27520
  "provider-not-representable"
27219
27521
  ),
27220
- detail: `${path34.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
27522
+ detail: `${path35.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
27221
27523
  }
27222
27524
  ]
27223
27525
  });
@@ -27235,7 +27537,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
27235
27537
  "model",
27236
27538
  "model-not-representable"
27237
27539
  ),
27238
- detail: `${path34.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
27540
+ detail: `${path35.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
27239
27541
  }
27240
27542
  ]
27241
27543
  });
@@ -27250,8 +27552,8 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
27250
27552
  if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
27251
27553
  return { component, status: "conflict", path: destination };
27252
27554
  }
27253
- ensureDir(path34.dirname(destination));
27254
- fs34.writeFileSync(destination, content);
27555
+ ensureDir(path35.dirname(destination));
27556
+ fs35.writeFileSync(destination, content);
27255
27557
  return { component, status: "success", path: destination };
27256
27558
  }
27257
27559
  function handleConflict4(destination, config, options, logger, manifest, scopePath) {
@@ -27270,16 +27572,16 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
27270
27572
  backupFile(destination, manifest);
27271
27573
  writeManifest(scopePath, manifest);
27272
27574
  } else {
27273
- fs34.renameSync(destination, `${destination}.bak.${Date.now()}`);
27575
+ fs35.renameSync(destination, `${destination}.bak.${Date.now()}`);
27274
27576
  }
27275
27577
  return true;
27276
27578
  }
27277
- fs34.rmSync(destination, { recursive: true, force: true });
27579
+ fs35.rmSync(destination, { recursive: true, force: true });
27278
27580
  return true;
27279
27581
  }
27280
27582
  function isCompiledCurrent4(destination, expectedContent, expectedHash) {
27281
27583
  try {
27282
- const current = fs34.readFileSync(destination, "utf8");
27584
+ const current = fs35.readFileSync(destination, "utf8");
27283
27585
  const marker = extractProvenanceMarker(current);
27284
27586
  return expectedHash ? marker?.hash === expectedHash && marker.target === "cline" && current === expectedContent : current === expectedContent;
27285
27587
  } catch {
@@ -27298,7 +27600,7 @@ function shouldSkipComponent4(options, component) {
27298
27600
  }
27299
27601
  function isSymlinkTo4(linkPath, source) {
27300
27602
  try {
27301
- return fs34.realpathSync(linkPath) === fs34.realpathSync(source);
27603
+ return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
27302
27604
  } catch {
27303
27605
  return false;
27304
27606
  }
@@ -27309,9 +27611,9 @@ function hashString4(value) {
27309
27611
 
27310
27612
  // src/adapters/opencode.ts
27311
27613
  import crypto9 from "crypto";
27312
- import fs35 from "fs";
27614
+ import fs36 from "fs";
27313
27615
  import os6 from "os";
27314
- import path35 from "path";
27616
+ import path36 from "path";
27315
27617
  var import_yaml10 = __toESM(require_dist(), 1);
27316
27618
  function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
27317
27619
  const scope = options.scope ?? "global";
@@ -27329,7 +27631,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
27329
27631
  config_doc: profile.config_doc
27330
27632
  };
27331
27633
  const rules = compileRules(
27332
- path35.join(sourceRoot, config.source.rules),
27634
+ path36.join(sourceRoot, config.source.rules),
27333
27635
  "opencode",
27334
27636
  mappings,
27335
27637
  lossReport
@@ -27431,16 +27733,16 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
27431
27733
  return { target: "opencode", outcomes };
27432
27734
  }
27433
27735
  function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
27434
- const source = path35.join(sourceRoot, config.source.instructions);
27736
+ const source = path36.join(sourceRoot, config.source.instructions);
27435
27737
  const destination = resolveTargetPath(paths.instructions);
27436
- const baseContent = fs35.existsSync(source) ? fs35.readFileSync(source, "utf8").trim() : "";
27738
+ const baseContent = fs36.existsSync(source) ? fs36.readFileSync(source, "utf8").trim() : "";
27437
27739
  const composed = agentsAppendix ? `${baseContent}
27438
27740
 
27439
27741
  --- tangyr managed rules ---
27440
27742
  ${agentsAppendix}`.trim() : baseContent;
27441
27743
  const marker = formatProvenanceMarker(
27442
27744
  "markdown",
27443
- path35.basename(config.source.instructions),
27745
+ path36.basename(config.source.instructions),
27444
27746
  hashString5(composed),
27445
27747
  "opencode"
27446
27748
  );
@@ -27467,16 +27769,16 @@ ${composed}
27467
27769
  );
27468
27770
  }
27469
27771
  function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
27470
- const sourceAgentsRoot = path35.join(sourceRoot, config.source.agents);
27471
- if (!fs35.existsSync(sourceAgentsRoot)) {
27772
+ const sourceAgentsRoot = path36.join(sourceRoot, config.source.agents);
27773
+ if (!fs36.existsSync(sourceAgentsRoot)) {
27472
27774
  return [skippedMissingSource5("agents", sourceAgentsRoot)];
27473
27775
  }
27474
- const sourceAgents = ts(path35.join(sourceAgentsRoot, "*.md")).sort();
27776
+ const sourceAgents = ts(path36.join(sourceAgentsRoot, "*.md")).sort();
27475
27777
  const agentsRoot = resolveTargetPath(paths.agents);
27476
27778
  return sourceAgents.map((agentFile) => {
27477
- const destination = path35.join(
27779
+ const destination = path36.join(
27478
27780
  agentsRoot,
27479
- `${path35.basename(agentFile, ".md")}.md`
27781
+ `${path36.basename(agentFile, ".md")}.md`
27480
27782
  );
27481
27783
  let compiled;
27482
27784
  try {
@@ -27540,11 +27842,11 @@ function applyProviderModelBinding(compiled, mappings) {
27540
27842
  return `${before}${(0, import_yaml10.stringify)(fields).trim()}${after}`;
27541
27843
  }
27542
27844
  function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
27543
- const sourceCommandsRoot = path35.join(sourceRoot, config.source.commands);
27544
- if (!fs35.existsSync(sourceCommandsRoot)) {
27845
+ const sourceCommandsRoot = path36.join(sourceRoot, config.source.commands);
27846
+ if (!fs36.existsSync(sourceCommandsRoot)) {
27545
27847
  return [skippedMissingSource5("commands", sourceCommandsRoot)];
27546
27848
  }
27547
- const sourceCommands = ts(path35.join(sourceCommandsRoot, "*.md")).sort();
27849
+ const sourceCommands = ts(path36.join(sourceCommandsRoot, "*.md")).sort();
27548
27850
  const commandsRoot = resolveTargetPath(paths.commands);
27549
27851
  return sourceCommands.map((commandFile) => {
27550
27852
  const { data, body } = parseCommandFile(commandFile);
@@ -27558,7 +27860,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
27558
27860
  if (typeof data.model === "string") {
27559
27861
  frontmatter.model = data.model;
27560
27862
  }
27561
- const relativeSource = `commands/${path35.basename(commandFile)}`;
27863
+ const relativeSource = `commands/${path36.basename(commandFile)}`;
27562
27864
  const marker = formatProvenanceMarker(
27563
27865
  "markdown",
27564
27866
  relativeSource,
@@ -27574,9 +27876,9 @@ ${body.trimEnd()}
27574
27876
  ` : `${marker}
27575
27877
  ${body.trimEnd()}
27576
27878
  `;
27577
- const destination = path35.join(
27879
+ const destination = path36.join(
27578
27880
  commandsRoot,
27579
- `${path35.basename(commandFile, ".md")}.md`
27881
+ `${path36.basename(commandFile, ".md")}.md`
27580
27882
  );
27581
27883
  if (options.dryRun) {
27582
27884
  logger.info(
@@ -27603,8 +27905,8 @@ ${body.trimEnd()}
27603
27905
  });
27604
27906
  }
27605
27907
  function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
27606
- const source = path35.resolve(sourceRoot, config.source.skills);
27607
- if (!fs35.existsSync(source)) {
27908
+ const source = path36.resolve(sourceRoot, config.source.skills);
27909
+ if (!fs36.existsSync(source)) {
27608
27910
  return skippedMissingSource5(component, source);
27609
27911
  }
27610
27912
  if (options.dryRun) {
@@ -27616,13 +27918,13 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
27616
27918
  return { component, status: "skipped-current", path: destination };
27617
27919
  }
27618
27920
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
27619
- fs35.unlinkSync(destination);
27921
+ fs36.unlinkSync(destination);
27620
27922
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
27621
27923
  return { component, status: "conflict", path: destination };
27622
27924
  } else if (artifactClass === "managed-symlink") {
27623
- fs35.unlinkSync(destination);
27925
+ fs36.unlinkSync(destination);
27624
27926
  }
27625
- ensureDir(path35.dirname(destination));
27927
+ ensureDir(path36.dirname(destination));
27626
27928
  createRelativeSymlink(source, destination, "dir");
27627
27929
  logger.verbose(`Skills: created skills path ${destination}`);
27628
27930
  return { component, status: "success", path: destination };
@@ -27631,13 +27933,13 @@ function syncMcp5(config, sourceRoot, paths, mappings, options, lossReport, logg
27631
27933
  const source = resolveMcpSourceFile(sourceRoot, config);
27632
27934
  const sourceLabel = mcpSourceLabel(config);
27633
27935
  const destination = resolveTargetPath(paths.config_doc);
27634
- if (!fs35.existsSync(source)) {
27936
+ if (!fs36.existsSync(source)) {
27635
27937
  if (!options.dryRun) {
27636
27938
  syncConfigDoc(paths, {}, lossReport, {}, mappings);
27637
27939
  }
27638
27940
  return skippedMissingSource5("mcp", source);
27639
27941
  }
27640
- const sourceMcpJson = JSON.parse(fs35.readFileSync(source, "utf8"));
27942
+ const sourceMcpJson = JSON.parse(fs36.readFileSync(source, "utf8"));
27641
27943
  const mcpJson = compileMcp(
27642
27944
  sourceMcpJson,
27643
27945
  "opencode",
@@ -27668,7 +27970,7 @@ function syncPermissions2(config, _sourceRoot, paths, options, lossReport, logge
27668
27970
  function syncHooks5(config, sourceRoot, mappings, options, lossReport) {
27669
27971
  const source = resolveHooksSourceFile(sourceRoot, config);
27670
27972
  const sourceLabel = hooksSourceLabel(config);
27671
- const sourceHooksJson = fs35.existsSync(source) ? JSON.parse(fs35.readFileSync(source, "utf8")) : { hooks: {} };
27973
+ const sourceHooksJson = fs36.existsSync(source) ? JSON.parse(fs36.readFileSync(source, "utf8")) : { hooks: {} };
27672
27974
  compileHooks(sourceHooksJson, "opencode", mappings, lossReport, sourceLabel);
27673
27975
  const message = "hooks: Skip \u2014 OpenCode exposes hooks only as plugin code (hook-as-plugin loss recorded)";
27674
27976
  return { component: "hooks", status: "skipped", path: message };
@@ -27702,9 +28004,9 @@ function syncProviderBlock(mappings) {
27702
28004
  function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
27703
28005
  const destination = resolveTargetPath(paths.config_doc);
27704
28006
  let existing = {};
27705
- if (fs35.existsSync(destination)) {
28007
+ if (fs36.existsSync(destination)) {
27706
28008
  try {
27707
- existing = JSON.parse(fs35.readFileSync(destination, "utf8"));
28009
+ existing = JSON.parse(fs36.readFileSync(destination, "utf8"));
27708
28010
  } catch {
27709
28011
  existing = {};
27710
28012
  }
@@ -27729,8 +28031,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
27729
28031
  };
27730
28032
  }
27731
28033
  }
27732
- ensureDir(path35.dirname(destination));
27733
- fs35.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
28034
+ ensureDir(path36.dirname(destination));
28035
+ fs36.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
27734
28036
  `);
27735
28037
  }
27736
28038
  function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
@@ -27741,8 +28043,8 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
27741
28043
  if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
27742
28044
  return { component, status: "conflict", path: destination };
27743
28045
  }
27744
- ensureDir(path35.dirname(destination));
27745
- fs35.writeFileSync(destination, content);
28046
+ ensureDir(path36.dirname(destination));
28047
+ fs36.writeFileSync(destination, content);
27746
28048
  return { component, status: "success", path: destination };
27747
28049
  }
27748
28050
  function handleConflict5(destination, config, options, logger, manifest, scopePath) {
@@ -27761,16 +28063,16 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
27761
28063
  backupFile(destination, manifest);
27762
28064
  writeManifest(scopePath, manifest);
27763
28065
  } else {
27764
- fs35.renameSync(destination, `${destination}.bak.${Date.now()}`);
28066
+ fs36.renameSync(destination, `${destination}.bak.${Date.now()}`);
27765
28067
  }
27766
28068
  return true;
27767
28069
  }
27768
- fs35.rmSync(destination, { recursive: true, force: true });
28070
+ fs36.rmSync(destination, { recursive: true, force: true });
27769
28071
  return true;
27770
28072
  }
27771
28073
  function isCompiledCurrent5(destination, expectedContent, expectedHash) {
27772
28074
  try {
27773
- const current = fs35.readFileSync(destination, "utf8");
28075
+ const current = fs36.readFileSync(destination, "utf8");
27774
28076
  const marker = extractProvenanceMarker(current);
27775
28077
  return expectedHash ? marker?.hash === expectedHash && marker.target === "opencode" && current === expectedContent : current === expectedContent;
27776
28078
  } catch {
@@ -27789,7 +28091,7 @@ function shouldSkipComponent5(options, component) {
27789
28091
  }
27790
28092
  function isSymlinkTo5(linkPath, source) {
27791
28093
  try {
27792
- return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
28094
+ return fs36.realpathSync(linkPath) === fs36.realpathSync(source);
27793
28095
  } catch {
27794
28096
  return false;
27795
28097
  }
@@ -27798,7 +28100,7 @@ function hashString5(value) {
27798
28100
  return `sha256:${crypto9.createHash("sha256").update(value).digest("hex")}`;
27799
28101
  }
27800
28102
  function parseCommandFile(commandFile) {
27801
- const content = fs35.readFileSync(commandFile, "utf8");
28103
+ const content = fs36.readFileSync(commandFile, "utf8");
27802
28104
  if (!content.startsWith("---\n")) {
27803
28105
  return { data: {}, body: content };
27804
28106
  }
@@ -27818,10 +28120,10 @@ function parseCommandFile(commandFile) {
27818
28120
  // src/commands/install.ts
27819
28121
  function isBackupableFile(targetPath) {
27820
28122
  try {
27821
- const lstat = fs36.lstatSync(targetPath);
28123
+ const lstat = fs37.lstatSync(targetPath);
27822
28124
  if (lstat.isDirectory()) return false;
27823
28125
  if (lstat.isSymbolicLink()) {
27824
- const stat = fs36.statSync(targetPath);
28126
+ const stat = fs37.statSync(targetPath);
27825
28127
  return stat.isFile();
27826
28128
  }
27827
28129
  return lstat.isFile();
@@ -27831,10 +28133,10 @@ function isBackupableFile(targetPath) {
27831
28133
  }
27832
28134
  function backupConflictingTarget(targetPath, scopePath) {
27833
28135
  const ts2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/gu, "").replace("T", "T").replace(/\.\d+Z$/u, "Z");
27834
- const relativeToRoot = path36.relative("/", targetPath).replace(/^\.\.\/+/gu, "");
27835
- const backupPath = path36.join(scopePath, "backups", ts2, relativeToRoot);
27836
- fs36.mkdirSync(path36.dirname(backupPath), { recursive: true });
27837
- fs36.copyFileSync(targetPath, backupPath);
28136
+ const relativeToRoot = path37.relative("/", targetPath).replace(/^\.\.\/+/gu, "");
28137
+ const backupPath = path37.join(scopePath, "backups", ts2, relativeToRoot);
28138
+ fs37.mkdirSync(path37.dirname(backupPath), { recursive: true });
28139
+ fs37.copyFileSync(targetPath, backupPath);
27838
28140
  return backupPath;
27839
28141
  }
27840
28142
  async function runInstallCommand(options, logger) {
@@ -27863,7 +28165,7 @@ async function runInstallCommand(options, logger) {
27863
28165
  );
27864
28166
  }
27865
28167
  const kitName = resolvedKitName ?? config.kit;
27866
- const kitPath = kitPathOverride ?? (options.kitPath ? path36.resolve(options.kitPath) : config.kitPath);
28168
+ const kitPath = kitPathOverride ?? (options.kitPath ? path37.resolve(options.kitPath) : config.kitPath);
27867
28169
  if (!kitName && !kitPath) {
27868
28170
  logger.error(
27869
28171
  "No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
@@ -28004,7 +28306,7 @@ ACCEPTED CONFLICTS (backup-and-replace applied to ${conflictingFindings.length}
28004
28306
  logger.info(` source: ${finding.tool}`);
28005
28307
  logger.info(` action: backup-and-replace`);
28006
28308
  logger.info(` backup: ${backupLocation}`);
28007
- } else if (fs36.existsSync(finding.path)) {
28309
+ } else if (fs37.existsSync(finding.path)) {
28008
28310
  logger.info(` - ${finding.path}`);
28009
28311
  logger.info(` source: ${finding.tool}`);
28010
28312
  logger.info(
@@ -28115,7 +28417,7 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
28115
28417
  writeManifest(scopePath, manifest);
28116
28418
  logger.info(`
28117
28419
  Installation complete: ${installedCount} files installed.`);
28118
- logger.info(`Manifest written to ${path36.join(scopePath, "manifest.json")}`);
28420
+ logger.info(`Manifest written to ${path37.join(scopePath, "manifest.json")}`);
28119
28421
  logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
28120
28422
  logger.info(`Scope: ${scope}`);
28121
28423
  logger.info(`Tools: ${tools.join(", ")}`);
@@ -28257,13 +28559,13 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
28257
28559
  logger.verbose(` skipped (operator choice): ${placement.destination}`);
28258
28560
  continue;
28259
28561
  }
28260
- const destDir = path36.dirname(placement.destination);
28261
- fs36.mkdirSync(destDir, { recursive: true });
28562
+ const destDir = path37.dirname(placement.destination);
28563
+ fs37.mkdirSync(destDir, { recursive: true });
28262
28564
  if (placement.type === "symlink") {
28263
- if (fs36.existsSync(placement.destination) || isSymlink2(placement.destination)) {
28565
+ if (fs37.existsSync(placement.destination) || isSymlink2(placement.destination)) {
28264
28566
  removeManagedPath(placement.destination);
28265
28567
  }
28266
- fs36.symlinkSync(
28568
+ fs37.symlinkSync(
28267
28569
  placement.source,
28268
28570
  placement.destination,
28269
28571
  placement.isDir ? "dir" : "file"
@@ -28272,12 +28574,12 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
28272
28574
  ` symlink: ${placement.source} \u2192 ${placement.destination}`
28273
28575
  );
28274
28576
  } else {
28275
- fs36.copyFileSync(placement.source, placement.destination);
28577
+ fs37.copyFileSync(placement.source, placement.destination);
28276
28578
  logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
28277
28579
  }
28278
28580
  addArtifactToManifest(manifest, {
28279
28581
  relativePath: placement.manifestKey,
28280
- hash: fs36.statSync(placement.source).isDirectory() ? `dir:${placement.source}` : computeSourceHash(placement.source),
28582
+ hash: fs37.statSync(placement.source).isDirectory() ? `dir:${placement.source}` : computeSourceHash(placement.source),
28281
28583
  origin: "tangyr-managed"
28282
28584
  });
28283
28585
  count++;
@@ -28524,11 +28826,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28524
28826
  if (outcome.path === mcpFile2) {
28525
28827
  return "cline/mcp.json";
28526
28828
  }
28527
- if (outcome.path.startsWith(`${workflowsRoot}${path36.sep}`)) {
28528
- return `cline/workflows/${path36.basename(outcome.path)}`;
28829
+ if (outcome.path.startsWith(`${workflowsRoot}${path37.sep}`)) {
28830
+ return `cline/workflows/${path37.basename(outcome.path)}`;
28529
28831
  }
28530
- if (outcome.path.startsWith(`${rulesRoot2}${path36.sep}`)) {
28531
- return `cline/rules/${path36.basename(outcome.path)}`;
28832
+ if (outcome.path.startsWith(`${rulesRoot2}${path37.sep}`)) {
28833
+ return `cline/rules/${path37.basename(outcome.path)}`;
28532
28834
  }
28533
28835
  return null;
28534
28836
  }
@@ -28564,14 +28866,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28564
28866
  if (outcome.path === permissionsFile) {
28565
28867
  return "cursor/permissions.json";
28566
28868
  }
28567
- if (outcome.path.startsWith(`${agentsRoot2}${path36.sep}`)) {
28568
- return `cursor/agents/${path36.basename(outcome.path)}`;
28869
+ if (outcome.path.startsWith(`${agentsRoot2}${path37.sep}`)) {
28870
+ return `cursor/agents/${path37.basename(outcome.path)}`;
28569
28871
  }
28570
- if (outcome.path.startsWith(`${rulesRoot2}${path36.sep}`)) {
28571
- return `cursor/rules/${path36.basename(outcome.path)}`;
28872
+ if (outcome.path.startsWith(`${rulesRoot2}${path37.sep}`)) {
28873
+ return `cursor/rules/${path37.basename(outcome.path)}`;
28572
28874
  }
28573
- if (outcome.path.startsWith(`${skillsRoot2}${path36.sep}`)) {
28574
- const rel = path36.relative(skillsRoot2, outcome.path);
28875
+ if (outcome.path.startsWith(`${skillsRoot2}${path37.sep}`)) {
28876
+ const rel = path37.relative(skillsRoot2, outcome.path);
28575
28877
  return `cursor/skills/${rel}`;
28576
28878
  }
28577
28879
  return null;
@@ -28597,14 +28899,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28597
28899
  if (outcome.path === skillsSharedRoot) {
28598
28900
  return "opencode/skills_shared";
28599
28901
  }
28600
- if (outcome.path.startsWith(`${agentsRoot2}${path36.sep}`)) {
28601
- return `opencode/agents/${path36.basename(outcome.path)}`;
28902
+ if (outcome.path.startsWith(`${agentsRoot2}${path37.sep}`)) {
28903
+ return `opencode/agents/${path37.basename(outcome.path)}`;
28602
28904
  }
28603
- if (outcome.path.startsWith(`${commandsRoot}${path36.sep}`)) {
28604
- return `opencode/commands/${path36.basename(outcome.path)}`;
28905
+ if (outcome.path.startsWith(`${commandsRoot}${path37.sep}`)) {
28906
+ return `opencode/commands/${path37.basename(outcome.path)}`;
28605
28907
  }
28606
28908
  if (outcome.path === configDocFile) {
28607
- return `opencode/${path36.basename(outcome.path)}`;
28909
+ return `opencode/${path37.basename(outcome.path)}`;
28608
28910
  }
28609
28911
  return null;
28610
28912
  }
@@ -28618,17 +28920,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28618
28920
  if (outcome.path === skillsRoot2) {
28619
28921
  return "copilot/skills";
28620
28922
  }
28621
- if (outcome.path.startsWith(`${agentsRoot2}${path36.sep}`)) {
28622
- return `copilot/agents/${path36.basename(outcome.path)}`;
28923
+ if (outcome.path.startsWith(`${agentsRoot2}${path37.sep}`)) {
28924
+ return `copilot/agents/${path37.basename(outcome.path)}`;
28623
28925
  }
28624
- if (outcome.path.startsWith(`${promptsRoot}${path36.sep}`)) {
28625
- return `copilot/prompts/${path36.basename(outcome.path)}`;
28926
+ if (outcome.path.startsWith(`${promptsRoot}${path37.sep}`)) {
28927
+ return `copilot/prompts/${path37.basename(outcome.path)}`;
28626
28928
  }
28627
- if (outcome.path.startsWith(`${hooksRoot}${path36.sep}`)) {
28628
- return `copilot/hooks/${path36.basename(outcome.path)}`;
28929
+ if (outcome.path.startsWith(`${hooksRoot}${path37.sep}`)) {
28930
+ return `copilot/hooks/${path37.basename(outcome.path)}`;
28629
28931
  }
28630
28932
  if (outcome.path === mcpFile2) {
28631
- return `copilot/${path36.basename(outcome.path)}`;
28933
+ return `copilot/${path37.basename(outcome.path)}`;
28632
28934
  }
28633
28935
  return null;
28634
28936
  }
@@ -28644,17 +28946,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28644
28946
  if (outcome.path === skillsRoot) {
28645
28947
  return "codex/skills";
28646
28948
  }
28647
- if (outcome.path.startsWith(`${agentsRoot}${path36.sep}`)) {
28648
- return `codex/agents/${path36.basename(outcome.path)}`;
28949
+ if (outcome.path.startsWith(`${agentsRoot}${path37.sep}`)) {
28950
+ return `codex/agents/${path37.basename(outcome.path)}`;
28649
28951
  }
28650
- if (outcome.path.startsWith(`${rulesRoot}${path36.sep}`)) {
28651
- return `codex/rules/${path36.basename(outcome.path)}`;
28952
+ if (outcome.path.startsWith(`${rulesRoot}${path37.sep}`)) {
28953
+ return `codex/rules/${path37.basename(outcome.path)}`;
28652
28954
  }
28653
28955
  if (outcome.path === hooksFile) {
28654
- return `codex/${path36.basename(outcome.path)}`;
28956
+ return `codex/${path37.basename(outcome.path)}`;
28655
28957
  }
28656
28958
  if (outcome.path === mcpFile) {
28657
- return `codex/${path36.basename(outcome.path)}`;
28959
+ return `codex/${path37.basename(outcome.path)}`;
28658
28960
  }
28659
28961
  return null;
28660
28962
  }
@@ -28689,8 +28991,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
28689
28991
  };
28690
28992
  }
28691
28993
  const placements = [];
28692
- const claudeMd = path36.join(kitInfo.path, "CLAUDE.md");
28693
- if (fs36.existsSync(claudeMd)) {
28994
+ const claudeMd = path37.join(kitInfo.path, "CLAUDE.md");
28995
+ if (fs37.existsSync(claudeMd)) {
28694
28996
  placements.push({
28695
28997
  source: claudeMd,
28696
28998
  destination: resolvedPaths.instructions,
@@ -28706,8 +29008,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
28706
29008
  rules: resolvedPaths.rules
28707
29009
  };
28708
29010
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
28709
- const componentDir = path36.join(kitInfo.path, component);
28710
- if (fs36.existsSync(componentDir) && fs36.statSync(componentDir).isDirectory()) {
29011
+ const componentDir = path37.join(kitInfo.path, component);
29012
+ if (fs37.existsSync(componentDir) && fs37.statSync(componentDir).isDirectory()) {
28711
29013
  placements.push({
28712
29014
  source: componentDir,
28713
29015
  destination: targetPath,
@@ -28721,8 +29023,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
28721
29023
  }
28722
29024
  function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
28723
29025
  const placements = [];
28724
- const claudeMd = path36.join(kitInfo.path, "CLAUDE.md");
28725
- if (fs36.existsSync(claudeMd)) {
29026
+ const claudeMd = path37.join(kitInfo.path, "CLAUDE.md");
29027
+ if (fs37.existsSync(claudeMd)) {
28726
29028
  placements.push({
28727
29029
  source: claudeMd,
28728
29030
  destination: profile.instructions,
@@ -28738,8 +29040,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
28738
29040
  rules: profile.rules
28739
29041
  };
28740
29042
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
28741
- const componentDir = path36.join(kitInfo.path, component);
28742
- if (fs36.existsSync(componentDir) && fs36.statSync(componentDir).isDirectory()) {
29043
+ const componentDir = path37.join(kitInfo.path, component);
29044
+ if (fs37.existsSync(componentDir) && fs37.statSync(componentDir).isDirectory()) {
28743
29045
  placements.push({
28744
29046
  source: componentDir,
28745
29047
  destination: targetPath,
@@ -28753,8 +29055,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
28753
29055
  }
28754
29056
  function collectAllFiles(kitInfo) {
28755
29057
  const files = /* @__PURE__ */ new Map();
28756
- const claudeMd = path36.join(kitInfo.path, "CLAUDE.md");
28757
- if (fs36.existsSync(claudeMd)) {
29058
+ const claudeMd = path37.join(kitInfo.path, "CLAUDE.md");
29059
+ if (fs37.existsSync(claudeMd)) {
28758
29060
  files.set("CLAUDE.md", claudeMd);
28759
29061
  }
28760
29062
  for (const [component, reconciliation] of Object.entries(
@@ -28764,15 +29066,15 @@ function collectAllFiles(kitInfo) {
28764
29066
  const missingSet = new Set(reconciliation.missing);
28765
29067
  for (const entry of reconciliation.declared) {
28766
29068
  if (missingSet.has(entry)) continue;
28767
- const relPath = isSkills ? path36.join(component, entry) : path36.join(component, `${entry}.md`);
28768
- files.set(relPath, path36.join(kitInfo.path, relPath));
29069
+ const relPath = isSkills ? path37.join(component, entry) : path37.join(component, `${entry}.md`);
29070
+ files.set(relPath, path37.join(kitInfo.path, relPath));
28769
29071
  }
28770
29072
  }
28771
29073
  return files;
28772
29074
  }
28773
29075
  function isSymlink2(p) {
28774
29076
  try {
28775
- return fs36.lstatSync(p).isSymbolicLink();
29077
+ return fs37.lstatSync(p).isSymbolicLink();
28776
29078
  } catch {
28777
29079
  return false;
28778
29080
  }
@@ -28817,14 +29119,14 @@ async function runKitUpdateCommand(options, logger) {
28817
29119
  }
28818
29120
 
28819
29121
  // src/commands/list.ts
28820
- import path37 from "path";
29122
+ import path38 from "path";
28821
29123
  function runListCommand(options, logger) {
28822
29124
  let searchPaths = [];
28823
- let directKitPath = options.kitPath ? path37.resolve(options.kitPath) : void 0;
29125
+ let directKitPath = options.kitPath ? path38.resolve(options.kitPath) : void 0;
28824
29126
  try {
28825
29127
  const { config, configDir } = resolveConfig(options.config);
28826
29128
  searchPaths = config.kitSearchPaths ?? [
28827
- path37.join(configDir, "operating-kits")
29129
+ path38.join(configDir, "operating-kits")
28828
29130
  ];
28829
29131
  directKitPath = directKitPath ?? config.kitPath;
28830
29132
  } catch (err) {
@@ -28899,7 +29201,7 @@ function withDirectKit(kits, directKitPath) {
28899
29201
  return kits;
28900
29202
  }
28901
29203
  const directKit = loadKit(directKitPath);
28902
- if (kits.some((kit) => path37.resolve(kit.path) === directKit.path)) {
29204
+ if (kits.some((kit) => path38.resolve(kit.path) === directKit.path)) {
28903
29205
  return kits;
28904
29206
  }
28905
29207
  return [...kits, directKit];
@@ -28907,12 +29209,12 @@ function withDirectKit(kits, directKitPath) {
28907
29209
 
28908
29210
  // src/commands/probe.ts
28909
29211
  import { spawnSync as spawnSync2 } from "child_process";
28910
- import fs37 from "fs";
28911
- import path38 from "path";
29212
+ import fs38 from "fs";
29213
+ import path39 from "path";
28912
29214
  function runProbeCommand(options, logger) {
28913
29215
  const { config, configDir, sourceRoot } = resolveRuntime(options, import.meta.url);
28914
29216
  const platformPaths = readYamlObject(
28915
- path38.join(
29217
+ path39.join(
28916
29218
  resolveConfiguredPath(config.mappings, configDir, sourceRoot, "mappings"),
28917
29219
  "platform-paths.yaml"
28918
29220
  )
@@ -28946,12 +29248,12 @@ function toProbeRow(target, key, rawPath) {
28946
29248
  const resolved = resolveTargetPath(rawPath);
28947
29249
  let accessible = false;
28948
29250
  try {
28949
- fs37.accessSync(resolved);
29251
+ fs38.accessSync(resolved);
28950
29252
  accessible = true;
28951
29253
  } catch {
28952
29254
  accessible = false;
28953
29255
  }
28954
- return { target, key, path: resolved, exists: fs37.existsSync(resolved), accessible };
29256
+ return { target, key, path: resolved, exists: fs38.existsSync(resolved), accessible };
28955
29257
  }
28956
29258
  function codexRuntimeProbeRows() {
28957
29259
  const rows = commandProbeRows("codex", "binary", process.platform === "win32" ? "where.exe" : "which", ["codex"]);
@@ -28962,7 +29264,7 @@ function codexRuntimeProbeRows() {
28962
29264
  ["binary_snap", "/snap/bin/codex"],
28963
29265
  ["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
28964
29266
  ]) {
28965
- if (fs37.existsSync(candidatePath)) {
29267
+ if (fs38.existsSync(candidatePath)) {
28966
29268
  rows.push(toProbeRow("codex", key, candidatePath));
28967
29269
  }
28968
29270
  }
@@ -28978,8 +29280,8 @@ function commandProbeRows(target, key, command, args) {
28978
29280
 
28979
29281
  // src/commands/status.ts
28980
29282
  import crypto10 from "crypto";
28981
- import fs38 from "fs";
28982
- import path39 from "path";
29283
+ import fs39 from "fs";
29284
+ import path40 from "path";
28983
29285
  function runStatusCommand(options, logger) {
28984
29286
  const { config, configDir, sourceRoot } = resolveRuntime(
28985
29287
  options,
@@ -29058,21 +29360,21 @@ function classifyCodexFiles(config, sourceRoot, configDir) {
29058
29360
  rules: paths.rules
29059
29361
  };
29060
29362
  const rules = compileRules(
29061
- path39.join(sourceRoot, config.source.rules),
29363
+ path40.join(sourceRoot, config.source.rules),
29062
29364
  "codex",
29063
29365
  mappings,
29064
29366
  createLossReport()
29065
29367
  );
29066
- const instructionsSource = fs38.readFileSync(path39.join(sourceRoot, config.source.instructions), "utf8").trim();
29368
+ const instructionsSource = fs39.readFileSync(path40.join(sourceRoot, config.source.instructions), "utf8").trim();
29067
29369
  const composedInstructions = `${instructionsSource}
29068
29370
 
29069
29371
  --- tangyr managed rules ---
29070
29372
  ${rules.agentsAppendix}`.trim();
29071
29373
  const agentFiles = ts(
29072
- path39.join(sourceRoot, config.source.agents, "*.md")
29374
+ path40.join(sourceRoot, config.source.agents, "*.md")
29073
29375
  ).sort();
29074
- const hooksSource = path39.join(sourceRoot, config.source.hooks, "hooks.json");
29075
- const mcpSource = path39.join(sourceRoot, config.source.mcp);
29376
+ const hooksSource = path40.join(sourceRoot, config.source.hooks, "hooks.json");
29377
+ const mcpSource = path40.join(sourceRoot, config.source.mcp);
29076
29378
  const ruleRows = rules.dotRulesFiles.length === 0 ? [
29077
29379
  {
29078
29380
  component: "rules",
@@ -29083,7 +29385,7 @@ ${rules.agentsAppendix}`.trim();
29083
29385
  ] : rules.dotRulesFiles.map(
29084
29386
  (ruleFile) => classifyCompiledFile(
29085
29387
  `rules/${ruleFile.name}`,
29086
- path39.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
29388
+ path40.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
29087
29389
  "codex",
29088
29390
  void 0,
29089
29391
  config,
@@ -29101,10 +29403,10 @@ ${rules.agentsAppendix}`.trim();
29101
29403
  ),
29102
29404
  ...agentFiles.map(
29103
29405
  (agentFile) => classifyCompiledFile(
29104
- `agents/${path39.basename(agentFile, ".md")}`,
29105
- path39.join(
29406
+ `agents/${path40.basename(agentFile, ".md")}`,
29407
+ path40.join(
29106
29408
  resolveTargetPath(codexPaths.agents),
29107
- `${path39.basename(agentFile, ".md")}.toml`
29409
+ `${path40.basename(agentFile, ".md")}.toml`
29108
29410
  ),
29109
29411
  "codex",
29110
29412
  computeSourceHash(agentFile),
@@ -29128,11 +29430,11 @@ ${rules.agentsAppendix}`.trim();
29128
29430
  config,
29129
29431
  sourceRoot
29130
29432
  ),
29131
- fs38.existsSync(hooksSource) ? classifyCodexHooksFile(resolveTargetPath(codexPaths.hooksSharedFile)) : notConfiguredRow(
29433
+ fs39.existsSync(hooksSource) ? classifyCodexHooksFile(resolveTargetPath(codexPaths.hooksSharedFile)) : notConfiguredRow(
29132
29434
  "hooks",
29133
29435
  resolveTargetPath(codexPaths.hooksSharedFile)
29134
29436
  ),
29135
- fs38.existsSync(mcpSource) ? classifyCompiledFile(
29437
+ fs39.existsSync(mcpSource) ? classifyCompiledFile(
29136
29438
  "mcp",
29137
29439
  resolveTargetPath(codexPaths.mcpSharedFile),
29138
29440
  "codex",
@@ -29152,7 +29454,7 @@ function classifyCodexHooksFile(filePath) {
29152
29454
  conformant: true
29153
29455
  };
29154
29456
  }
29155
- if (!fs38.existsSync(filePath)) {
29457
+ if (!fs39.existsSync(filePath)) {
29156
29458
  return {
29157
29459
  component: "hooks",
29158
29460
  className: "missing",
@@ -29184,20 +29486,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
29184
29486
  mcpSharedFile: paths.mcp_shared_file
29185
29487
  };
29186
29488
  const agentFiles = ts(
29187
- path39.join(sourceRoot, config.source.agents, "*.md")
29489
+ path40.join(sourceRoot, config.source.agents, "*.md")
29188
29490
  ).sort();
29189
29491
  const commandFiles = ts(
29190
- path39.join(sourceRoot, config.source.commands, "*.md")
29492
+ path40.join(sourceRoot, config.source.commands, "*.md")
29191
29493
  ).sort();
29192
- const hooksSource = path39.join(sourceRoot, config.source.hooks, "hooks.json");
29193
- const mcpSource = path39.join(sourceRoot, config.source.mcp);
29494
+ const hooksSource = path40.join(sourceRoot, config.source.hooks, "hooks.json");
29495
+ const mcpSource = path40.join(sourceRoot, config.source.mcp);
29194
29496
  return [
29195
29497
  ...agentFiles.map(
29196
29498
  (agentFile) => classifyCompiledFile(
29197
- `agents/${path39.basename(agentFile, ".md")}`,
29198
- path39.join(
29499
+ `agents/${path40.basename(agentFile, ".md")}`,
29500
+ path40.join(
29199
29501
  resolveTargetPath(copilotPaths.agents),
29200
- `${path39.basename(agentFile, ".md")}.agent.md`
29502
+ `${path40.basename(agentFile, ".md")}.agent.md`
29201
29503
  ),
29202
29504
  "copilot",
29203
29505
  computeSourceHash(agentFile),
@@ -29214,10 +29516,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
29214
29516
  ),
29215
29517
  ...commandFiles.map(
29216
29518
  (commandFile) => classifyCompiledFile(
29217
- `commands/${path39.basename(commandFile, ".md")}`,
29218
- path39.join(
29519
+ `commands/${path40.basename(commandFile, ".md")}`,
29520
+ path40.join(
29219
29521
  resolveTargetPath(copilotPaths.prompts),
29220
- `${path39.basename(commandFile, ".md")}.prompt.md`
29522
+ `${path40.basename(commandFile, ".md")}.prompt.md`
29221
29523
  ),
29222
29524
  "copilot",
29223
29525
  computeSourceHash(commandFile),
@@ -29235,9 +29537,9 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
29235
29537
  config,
29236
29538
  sourceRoot
29237
29539
  ),
29238
- fs38.existsSync(hooksSource) ? classifyCompiledFile(
29540
+ fs39.existsSync(hooksSource) ? classifyCompiledFile(
29239
29541
  "hooks",
29240
- path39.join(
29542
+ path40.join(
29241
29543
  resolveTargetPath(copilotPaths.hooks),
29242
29544
  "tangyr-managed.json"
29243
29545
  ),
@@ -29247,12 +29549,12 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
29247
29549
  sourceRoot
29248
29550
  ) : notConfiguredRow(
29249
29551
  "hooks",
29250
- path39.join(
29552
+ path40.join(
29251
29553
  resolveTargetPath(copilotPaths.hooks),
29252
29554
  "tangyr-managed.json"
29253
29555
  )
29254
29556
  ),
29255
- fs38.existsSync(mcpSource) ? classifyCompiledFile(
29557
+ fs39.existsSync(mcpSource) ? classifyCompiledFile(
29256
29558
  "mcp",
29257
29559
  resolveTargetPath(copilotPaths.mcpSharedFile),
29258
29560
  "copilot",
@@ -29272,7 +29574,7 @@ function notConfiguredRow(component, filePath) {
29272
29574
  }
29273
29575
  function classifyDirectArtifact(artifact, config, sourceRoot) {
29274
29576
  const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
29275
- const sourcePath = artifact.sourceKey ? path39.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
29577
+ const sourcePath = artifact.sourceKey ? path40.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
29276
29578
  if (artifactClass === "managed-symlink" && sourcePath && !isSymlinkCurrent(artifact.path, sourcePath)) {
29277
29579
  return {
29278
29580
  component: artifact.component,
@@ -29361,9 +29663,9 @@ function classifyClaudeSharedFiles(config, sourceRoot) {
29361
29663
  classifyHooks(settingsPath),
29362
29664
  classifySettings(
29363
29665
  settingsPath,
29364
- path39.resolve(sourceRoot, config.source.settings)
29666
+ path40.resolve(sourceRoot, config.source.settings)
29365
29667
  ),
29366
- classifyMcp(claudeJsonPath, path39.resolve(sourceRoot, config.source.mcp))
29668
+ classifyMcp(claudeJsonPath, path40.resolve(sourceRoot, config.source.mcp))
29367
29669
  ];
29368
29670
  }
29369
29671
  function classifyHooks(filePath) {
@@ -29427,14 +29729,14 @@ function classifyMcp(filePath, sourcePath) {
29427
29729
  }
29428
29730
  function isSymlinkCurrent(linkPath, sourcePath) {
29429
29731
  try {
29430
- return fs38.realpathSync(linkPath) === fs38.realpathSync(sourcePath);
29732
+ return fs39.realpathSync(linkPath) === fs39.realpathSync(sourcePath);
29431
29733
  } catch {
29432
29734
  return false;
29433
29735
  }
29434
29736
  }
29435
29737
  function isCompiledCurrent6(filePath, sourcePath) {
29436
29738
  try {
29437
- const marker = extractProvenanceMarker(fs38.readFileSync(filePath, "utf8"));
29739
+ const marker = extractProvenanceMarker(fs39.readFileSync(filePath, "utf8"));
29438
29740
  return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
29439
29741
  } catch {
29440
29742
  return false;
@@ -29464,7 +29766,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
29464
29766
  }
29465
29767
  function readCompiledContent(filePath) {
29466
29768
  try {
29467
- return fs38.readFileSync(filePath, "utf8");
29769
+ return fs39.readFileSync(filePath, "utf8");
29468
29770
  } catch {
29469
29771
  return null;
29470
29772
  }
@@ -29495,8 +29797,8 @@ function hashString6(value) {
29495
29797
  }
29496
29798
 
29497
29799
  // src/commands/sync.ts
29498
- import fs41 from "fs";
29499
- import path42 from "path";
29800
+ import fs42 from "fs";
29801
+ import path43 from "path";
29500
29802
 
29501
29803
  // node_modules/chalk/source/vendor/ansi-styles/index.js
29502
29804
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -29994,8 +30296,8 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
29994
30296
  var source_default = chalk;
29995
30297
 
29996
30298
  // src/adapters/claude-code.ts
29997
- import fs40 from "fs";
29998
- import path41 from "path";
30299
+ import fs41 from "fs";
30300
+ import path42 from "path";
29999
30301
 
30000
30302
  // src/core/shim.ts
30001
30303
  import crypto11 from "crypto";
@@ -30012,12 +30314,12 @@ ${SHIM_BODY}`;
30012
30314
 
30013
30315
  // src/compiler/hook-components.ts
30014
30316
  var import_yaml11 = __toESM(require_dist(), 1);
30015
- import fs39 from "fs";
30016
- import path40 from "path";
30317
+ import fs40 from "fs";
30318
+ import path41 from "path";
30017
30319
  function parseHookDeclaration(filePath) {
30018
30320
  let raw;
30019
30321
  try {
30020
- raw = fs39.readFileSync(filePath, "utf8");
30322
+ raw = fs40.readFileSync(filePath, "utf8");
30021
30323
  } catch {
30022
30324
  return null;
30023
30325
  }
@@ -30100,9 +30402,9 @@ function synthesizeHooksJson(declarations) {
30100
30402
  return { hooks };
30101
30403
  }
30102
30404
  function loadSourceHooks(hooksDir, hookNames) {
30103
- const hooksJsonPath = path40.join(hooksDir, "hooks.json");
30104
- if (fs39.existsSync(hooksJsonPath)) {
30105
- const raw = fs39.readFileSync(hooksJsonPath, "utf8");
30405
+ const hooksJsonPath = path41.join(hooksDir, "hooks.json");
30406
+ if (fs40.existsSync(hooksJsonPath)) {
30407
+ const raw = fs40.readFileSync(hooksJsonPath, "utf8");
30106
30408
  return JSON.parse(raw);
30107
30409
  }
30108
30410
  const declarations = loadHookDeclarations(hooksDir, hookNames);
@@ -30113,14 +30415,14 @@ function loadHookDeclarations(hooksDir, hookNames) {
30113
30415
  if (hookNames && hookNames.length > 0) {
30114
30416
  names = hookNames;
30115
30417
  } else {
30116
- if (!fs39.existsSync(hooksDir) || !fs39.statSync(hooksDir).isDirectory()) {
30418
+ if (!fs40.existsSync(hooksDir) || !fs40.statSync(hooksDir).isDirectory()) {
30117
30419
  return [];
30118
30420
  }
30119
- names = fs39.readdirSync(hooksDir).filter((f) => f.endsWith(".md") && !f.startsWith(".")).map((f) => f.slice(0, -3)).sort();
30421
+ names = fs40.readdirSync(hooksDir).filter((f) => f.endsWith(".md") && !f.startsWith(".")).map((f) => f.slice(0, -3)).sort();
30120
30422
  }
30121
30423
  const declarations = [];
30122
30424
  for (const name of names) {
30123
- const filePath = path40.join(hooksDir, `${name}.md`);
30425
+ const filePath = path41.join(hooksDir, `${name}.md`);
30124
30426
  const decl = parseHookDeclaration(filePath);
30125
30427
  if (decl) {
30126
30428
  declarations.push(decl);
@@ -30244,7 +30546,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
30244
30546
  }
30245
30547
  if (!shouldSkipComponent6(options, "instructions") && manifest && scopePath) {
30246
30548
  const shimPath = profile.instructions_shim;
30247
- const agentsMdPath = path41.resolve(sourceRoot, config.source.instructions);
30549
+ const agentsMdPath = path42.resolve(sourceRoot, config.source.instructions);
30248
30550
  if (!options.dryRun) {
30249
30551
  applyClaudeCodeShimUpgrade(
30250
30552
  shimPath,
@@ -30298,13 +30600,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
30298
30600
  }
30299
30601
  function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
30300
30602
  if (!mappings.modelTiers.custom_provider) return;
30301
- const agentsDir = path41.join(sourceRoot, config.source.agents);
30302
- if (!fs40.existsSync(agentsDir)) return;
30303
- for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
30603
+ const agentsDir = path42.join(sourceRoot, config.source.agents);
30604
+ if (!fs41.existsSync(agentsDir)) return;
30605
+ for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
30304
30606
  const { data } = parseMarkdownFrontmatter(agentFile);
30305
30607
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30306
30608
  if (hasProvider) {
30307
- const basename = path41.basename(agentFile);
30609
+ const basename = path42.basename(agentFile);
30308
30610
  addLoss(lossReport, "claude-code", "agents", {
30309
30611
  source: `agents/${basename}`,
30310
30612
  fields: [
@@ -30329,19 +30631,19 @@ function shouldSkipComponent6(options, component) {
30329
30631
  function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath, logger) {
30330
30632
  const expectedBodyHash = shimBodyHash();
30331
30633
  const shimContent = buildAgentsMdShim(shimPath, agentsMdPath, "claude-code");
30332
- if (!fs40.existsSync(shimPath)) {
30634
+ if (!fs41.existsSync(shimPath)) {
30333
30635
  manifest.artifacts.push({
30334
- relativePath: path41.relative(scopePath, shimPath),
30636
+ relativePath: path42.relative(scopePath, shimPath),
30335
30637
  hash: expectedBodyHash,
30336
30638
  origin: "tangyr-managed"
30337
30639
  });
30338
30640
  writeManifest(scopePath, manifest);
30339
- fs40.mkdirSync(path41.dirname(shimPath), { recursive: true });
30340
- fs40.writeFileSync(shimPath, shimContent);
30641
+ fs41.mkdirSync(path42.dirname(shimPath), { recursive: true });
30642
+ fs41.writeFileSync(shimPath, shimContent);
30341
30643
  logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
30342
30644
  return;
30343
30645
  }
30344
- const existing = fs40.readFileSync(shimPath, "utf8");
30646
+ const existing = fs41.readFileSync(shimPath, "utf8");
30345
30647
  const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
30346
30648
  const marker = extractProvenanceMarker(firstNonEmptyLine);
30347
30649
  if (marker !== null && marker.hash === expectedBodyHash) {
@@ -30352,21 +30654,21 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
30352
30654
  }
30353
30655
  backupFile(shimPath, manifest);
30354
30656
  writeManifest(scopePath, manifest);
30355
- fs40.writeFileSync(shimPath, shimContent);
30657
+ fs41.writeFileSync(shimPath, shimContent);
30356
30658
  manifest.artifacts.push({
30357
- relativePath: path41.relative(scopePath, shimPath),
30659
+ relativePath: path42.relative(scopePath, shimPath),
30358
30660
  hash: expectedBodyHash,
30359
30661
  origin: "tangyr-managed"
30360
30662
  });
30361
30663
  logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
30362
30664
  }
30363
30665
  function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
30364
- const source = path41.resolve(
30666
+ const source = path42.resolve(
30365
30667
  sourceRoot,
30366
30668
  config.source[directComponent.sourceKey]
30367
30669
  );
30368
30670
  const destination = directComponent.destination;
30369
- if (!fs40.existsSync(source)) {
30671
+ if (!fs41.existsSync(source)) {
30370
30672
  return skippedMissingSource6(directComponent.component, source);
30371
30673
  }
30372
30674
  if (options.dryRun) {
@@ -30388,7 +30690,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
30388
30690
  };
30389
30691
  }
30390
30692
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
30391
- fs40.unlinkSync(destination);
30693
+ fs41.unlinkSync(destination);
30392
30694
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
30393
30695
  return {
30394
30696
  component: directComponent.component,
@@ -30396,9 +30698,9 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
30396
30698
  path: destination
30397
30699
  };
30398
30700
  } else if (artifactClass === "managed-symlink") {
30399
- fs40.unlinkSync(destination);
30701
+ fs41.unlinkSync(destination);
30400
30702
  }
30401
- ensureDir(path41.dirname(destination));
30703
+ ensureDir(path42.dirname(destination));
30402
30704
  createRelativeSymlink(source, destination, directComponent.type, {
30403
30705
  logger,
30404
30706
  provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
@@ -30415,8 +30717,8 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
30415
30717
  };
30416
30718
  }
30417
30719
  function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination, manifest, scopePath) {
30418
- const source = path41.resolve(sourceRoot, config.source.skills);
30419
- if (!fs40.existsSync(source)) {
30720
+ const source = path42.resolve(sourceRoot, config.source.skills);
30721
+ if (!fs41.existsSync(source)) {
30420
30722
  return [skippedMissingSource6("skills", source)];
30421
30723
  }
30422
30724
  const declaredNames = resolveKitSkillNames(sourceRoot);
@@ -30426,7 +30728,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
30426
30728
  if (isLegacyWholesaleSymlink) {
30427
30729
  for (const name of foreignSkillNames(source, declaredNames)) {
30428
30730
  logger.info(
30429
- `[dry-run] skills: migrate foreign skill ${path41.join(source, name)} -> ${path41.join(destination, name)}`
30731
+ `[dry-run] skills: migrate foreign skill ${path42.join(source, name)} -> ${path42.join(destination, name)}`
30430
30732
  );
30431
30733
  }
30432
30734
  logger.info(
@@ -30434,9 +30736,9 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
30434
30736
  );
30435
30737
  }
30436
30738
  for (const name of declaredNames ?? listSkillDirNames(source)) {
30437
- const skillDestination = path41.join(destination, name);
30739
+ const skillDestination = path42.join(destination, name);
30438
30740
  logger.info(
30439
- `[dry-run] skills: symlink ${path41.join(source, name)} -> ${skillDestination}`
30741
+ `[dry-run] skills: symlink ${path42.join(source, name)} -> ${skillDestination}`
30440
30742
  );
30441
30743
  outcomes2.push({
30442
30744
  component: "skills",
@@ -30469,9 +30771,9 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
30469
30771
  return outcomes;
30470
30772
  }
30471
30773
  function syncSingleSkill(config, sourceRoot, options, logger, source, destination, name, manifest, scopePath) {
30472
- const skillSource = path41.join(source, name);
30473
- const skillDestination = path41.join(destination, name);
30474
- if (!fs40.existsSync(skillSource)) {
30774
+ const skillSource = path42.join(source, name);
30775
+ const skillDestination = path42.join(destination, name);
30776
+ if (!fs41.existsSync(skillSource)) {
30475
30777
  return skippedMissingSource6("skills", skillSource);
30476
30778
  }
30477
30779
  const artifactClass = classifyArtifact(skillDestination, config, sourceRoot);
@@ -30483,7 +30785,7 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
30483
30785
  };
30484
30786
  }
30485
30787
  if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
30486
- fs40.unlinkSync(skillDestination);
30788
+ fs41.unlinkSync(skillDestination);
30487
30789
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(
30488
30790
  skillDestination,
30489
30791
  config,
@@ -30494,25 +30796,25 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
30494
30796
  )) {
30495
30797
  return { component: "skills", status: "conflict", path: skillDestination };
30496
30798
  } else if (artifactClass === "managed-symlink") {
30497
- fs40.unlinkSync(skillDestination);
30799
+ fs41.unlinkSync(skillDestination);
30498
30800
  }
30499
30801
  createRelativeSymlink(skillSource, skillDestination, "dir");
30500
30802
  return { component: "skills", status: "success", path: skillDestination };
30501
30803
  }
30502
30804
  function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
30503
30805
  const foreignNames = foreignSkillNames(source, declaredNames);
30504
- fs40.unlinkSync(destination);
30806
+ fs41.unlinkSync(destination);
30505
30807
  ensureDir(destination);
30506
30808
  for (const name of foreignNames) {
30507
- const from = path41.join(source, name);
30508
- const to = path41.join(destination, name);
30509
- if (fs40.existsSync(to)) {
30809
+ const from = path42.join(source, name);
30810
+ const to = path42.join(destination, name);
30811
+ if (fs41.existsSync(to)) {
30510
30812
  logger.warn(
30511
30813
  `skills migration: ${to} already exists \u2014 skipping move of ${from} to avoid overwrite`
30512
30814
  );
30513
30815
  continue;
30514
30816
  }
30515
- fs40.renameSync(from, to);
30817
+ fs41.renameSync(from, to);
30516
30818
  logger.info(`skills migration: moved ${from} -> ${to}`);
30517
30819
  }
30518
30820
  }
@@ -30524,21 +30826,21 @@ function foreignSkillNames(source, declaredNames) {
30524
30826
  return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
30525
30827
  }
30526
30828
  function listSkillDirNames(dir) {
30527
- if (!fs40.existsSync(dir)) {
30829
+ if (!fs41.existsSync(dir)) {
30528
30830
  return [];
30529
30831
  }
30530
- return fs40.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
30832
+ return fs41.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
30531
30833
  }
30532
30834
  function isSymlinkPath(filePath) {
30533
30835
  try {
30534
- return fs40.lstatSync(filePath).isSymbolicLink();
30836
+ return fs41.lstatSync(filePath).isSymbolicLink();
30535
30837
  } catch {
30536
30838
  return false;
30537
30839
  }
30538
30840
  }
30539
30841
  function syncHookScriptsBridge(config, sourceRoot, options, logger, destination, manifest, scopePath) {
30540
- const source = path41.resolve(sourceRoot, config.source.hooks);
30541
- if (!fs40.existsSync(source)) {
30842
+ const source = path42.resolve(sourceRoot, config.source.hooks);
30843
+ if (!fs41.existsSync(source)) {
30542
30844
  return skippedMissingSource6("hooks", source);
30543
30845
  }
30544
30846
  if (options.dryRun) {
@@ -30550,13 +30852,13 @@ function syncHookScriptsBridge(config, sourceRoot, options, logger, destination,
30550
30852
  return { component: "hooks", status: "skipped-current", path: destination };
30551
30853
  }
30552
30854
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
30553
- fs40.unlinkSync(destination);
30855
+ fs41.unlinkSync(destination);
30554
30856
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
30555
30857
  return { component: "hooks", status: "conflict", path: destination };
30556
30858
  } else if (artifactClass === "managed-symlink") {
30557
- fs40.unlinkSync(destination);
30859
+ fs41.unlinkSync(destination);
30558
30860
  }
30559
- ensureDir(path41.dirname(destination));
30861
+ ensureDir(path42.dirname(destination));
30560
30862
  createRelativeSymlink(source, destination, "dir");
30561
30863
  return { component: "hooks", status: "success", path: destination };
30562
30864
  }
@@ -30579,7 +30881,7 @@ function syncHooks6(config, sourceRoot, options, logger, destination) {
30579
30881
  destination,
30580
30882
  settings,
30581
30883
  stringifyJson3,
30582
- !fs40.existsSync(destination),
30884
+ !fs41.existsSync(destination),
30583
30885
  logger
30584
30886
  );
30585
30887
  return {
@@ -30589,8 +30891,8 @@ function syncHooks6(config, sourceRoot, options, logger, destination) {
30589
30891
  };
30590
30892
  }
30591
30893
  function syncMcp6(config, sourceRoot, options, logger, destination) {
30592
- const source = path41.resolve(sourceRoot, config.source.mcp);
30593
- if (!fs40.existsSync(source)) {
30894
+ const source = path42.resolve(sourceRoot, config.source.mcp);
30895
+ if (!fs41.existsSync(source)) {
30594
30896
  return skippedMissingSource6("mcp", source);
30595
30897
  }
30596
30898
  if (options.dryRun) {
@@ -30615,7 +30917,7 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
30615
30917
  destination,
30616
30918
  hostConfig,
30617
30919
  stringifyJson3,
30618
- !fs40.existsSync(destination),
30920
+ !fs41.existsSync(destination),
30619
30921
  logger
30620
30922
  );
30621
30923
  return {
@@ -30625,8 +30927,8 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
30625
30927
  };
30626
30928
  }
30627
30929
  function syncSettings2(config, sourceRoot, options, logger, destination) {
30628
- const source = path41.resolve(sourceRoot, config.source.settings);
30629
- if (!fs40.existsSync(source)) {
30930
+ const source = path42.resolve(sourceRoot, config.source.settings);
30931
+ if (!fs41.existsSync(source)) {
30630
30932
  return skippedMissingSource6("settings", source);
30631
30933
  }
30632
30934
  if (options.dryRun) {
@@ -30644,7 +30946,7 @@ function syncSettings2(config, sourceRoot, options, logger, destination) {
30644
30946
  destination,
30645
30947
  settings,
30646
30948
  stringifyJson3,
30647
- !fs40.existsSync(destination),
30949
+ !fs41.existsSync(destination),
30648
30950
  logger
30649
30951
  );
30650
30952
  return {
@@ -30669,11 +30971,11 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
30669
30971
  backupFile(destination, manifest);
30670
30972
  writeManifest(scopePath, manifest);
30671
30973
  } else {
30672
- fs40.renameSync(destination, `${destination}.bak.${Date.now()}`);
30974
+ fs41.renameSync(destination, `${destination}.bak.${Date.now()}`);
30673
30975
  }
30674
30976
  return true;
30675
30977
  }
30676
- fs40.rmSync(destination, { recursive: true, force: true });
30978
+ fs41.rmSync(destination, { recursive: true, force: true });
30677
30979
  return true;
30678
30980
  }
30679
30981
  function skippedMissingSource6(component, source) {
@@ -30685,16 +30987,16 @@ function skippedMissingSource6(component, source) {
30685
30987
  }
30686
30988
  function isSymlinkTo6(linkPath, source) {
30687
30989
  try {
30688
- return fs40.realpathSync(linkPath) === fs40.realpathSync(source);
30990
+ return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
30689
30991
  } catch {
30690
30992
  return false;
30691
30993
  }
30692
30994
  }
30693
30995
  function readJsonObject4(filePath) {
30694
- if (!fs40.existsSync(filePath)) {
30996
+ if (!fs41.existsSync(filePath)) {
30695
30997
  return {};
30696
30998
  }
30697
- const parsed = JSON.parse(fs40.readFileSync(filePath, "utf8"));
30999
+ const parsed = JSON.parse(fs41.readFileSync(filePath, "utf8"));
30698
31000
  return isRecord5(parsed) ? parsed : {};
30699
31001
  }
30700
31002
  function markManaged(value) {
@@ -30960,7 +31262,7 @@ function writeLossReport(filePath, report) {
30960
31262
  if (!filePath) {
30961
31263
  return;
30962
31264
  }
30963
- fs41.writeFileSync(filePath, `${JSON.stringify(report, null, 2)}
31265
+ fs42.writeFileSync(filePath, `${JSON.stringify(report, null, 2)}
30964
31266
  `);
30965
31267
  }
30966
31268
  function prepareKitManifest(scope, projectRoot, kitInfo) {
@@ -31001,8 +31303,8 @@ function updateManifest(kitInfo, kitSync) {
31001
31303
  writeManifest(kitSync.scopePath, kitSync.manifest);
31002
31304
  }
31003
31305
  function resolveKitFilePath(kitPath, relativePath) {
31004
- const fullPath = path42.join(kitPath, relativePath);
31005
- return fs41.existsSync(fullPath) ? fullPath : null;
31306
+ const fullPath = path43.join(kitPath, relativePath);
31307
+ return fs42.existsSync(fullPath) ? fullPath : null;
31006
31308
  }
31007
31309
  function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
31008
31310
  if (removedSourcePaths.length === 0 || !mappings) {
@@ -31063,9 +31365,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
31063
31365
  }
31064
31366
  if (relativePath.startsWith("agents/")) {
31065
31367
  removeManagedCompiledArtifact2(
31066
- path42.join(
31368
+ path43.join(
31067
31369
  resolveTargetPath(paths.agents ?? ""),
31068
- `${path42.parse(relativePath).name}.agent.md`
31370
+ `${path43.parse(relativePath).name}.agent.md`
31069
31371
  ),
31070
31372
  "copilot",
31071
31373
  relativePath,
@@ -31075,9 +31377,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
31075
31377
  }
31076
31378
  if (relativePath.startsWith("commands/")) {
31077
31379
  removeManagedCompiledArtifact2(
31078
- path42.join(
31380
+ path43.join(
31079
31381
  resolveTargetPath(paths.prompts ?? ""),
31080
- `${path42.parse(relativePath).name}.prompt.md`
31382
+ `${path43.parse(relativePath).name}.prompt.md`
31081
31383
  ),
31082
31384
  "copilot",
31083
31385
  relativePath,
@@ -31087,7 +31389,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
31087
31389
  }
31088
31390
  if (relativePath.endsWith("hooks.json")) {
31089
31391
  removeManagedCompiledArtifact2(
31090
- path42.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
31392
+ path43.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
31091
31393
  "copilot",
31092
31394
  relativePath,
31093
31395
  logger
@@ -31117,9 +31419,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
31117
31419
  }
31118
31420
  if (relativePath.startsWith("agents/")) {
31119
31421
  removeManagedCompiledArtifact2(
31120
- path42.join(
31422
+ path43.join(
31121
31423
  resolveTargetPath(paths.agents ?? ""),
31122
- `${path42.parse(relativePath).name}.toml`
31424
+ `${path43.parse(relativePath).name}.toml`
31123
31425
  ),
31124
31426
  "codex",
31125
31427
  relativePath,
@@ -31129,9 +31431,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
31129
31431
  }
31130
31432
  if (relativePath.startsWith("rules/")) {
31131
31433
  removeManagedCompiledArtifact2(
31132
- path42.join(
31434
+ path43.join(
31133
31435
  resolveTargetPath(paths.rules ?? ""),
31134
- `${path42.parse(relativePath).name}.rules`
31436
+ `${path43.parse(relativePath).name}.rules`
31135
31437
  ),
31136
31438
  "codex",
31137
31439
  relativePath,
@@ -31170,9 +31472,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
31170
31472
  }
31171
31473
  if (relativePath.startsWith("agents/")) {
31172
31474
  removeManagedCompiledArtifact2(
31173
- path42.join(
31475
+ path43.join(
31174
31476
  resolveTargetPath(paths.agents ?? ""),
31175
- `${path42.parse(relativePath).name}.md`
31477
+ `${path43.parse(relativePath).name}.md`
31176
31478
  ),
31177
31479
  "opencode",
31178
31480
  relativePath,
@@ -31182,9 +31484,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
31182
31484
  }
31183
31485
  if (relativePath.startsWith("commands/")) {
31184
31486
  removeManagedCompiledArtifact2(
31185
- path42.join(
31487
+ path43.join(
31186
31488
  resolveTargetPath(paths.commands ?? ""),
31187
- `${path42.parse(relativePath).name}.md`
31489
+ `${path43.parse(relativePath).name}.md`
31188
31490
  ),
31189
31491
  "opencode",
31190
31492
  relativePath,
@@ -31216,9 +31518,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
31216
31518
  }
31217
31519
  if (relativePath.startsWith("agents/")) {
31218
31520
  removeManagedCompiledArtifact2(
31219
- path42.join(
31521
+ path43.join(
31220
31522
  resolveTargetPath(paths.agents ?? ""),
31221
- `${path42.parse(relativePath).name}.md`
31523
+ `${path43.parse(relativePath).name}.md`
31222
31524
  ),
31223
31525
  "cursor",
31224
31526
  relativePath,
@@ -31228,9 +31530,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
31228
31530
  }
31229
31531
  if (relativePath.startsWith("rules/")) {
31230
31532
  removeManagedCompiledArtifact2(
31231
- path42.join(
31533
+ path43.join(
31232
31534
  resolveTargetPath(paths.rules ?? ""),
31233
- `${path42.parse(relativePath).name}.mdc`
31535
+ `${path43.parse(relativePath).name}.mdc`
31234
31536
  ),
31235
31537
  "cursor",
31236
31538
  relativePath,
@@ -31240,9 +31542,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
31240
31542
  }
31241
31543
  if (relativePath.startsWith("commands/")) {
31242
31544
  removeManagedCompiledArtifact2(
31243
- path42.join(
31545
+ path43.join(
31244
31546
  resolveTargetPath(paths.skills ?? ""),
31245
- path42.parse(relativePath).name,
31547
+ path43.parse(relativePath).name,
31246
31548
  "SKILL.md"
31247
31549
  ),
31248
31550
  "cursor",
@@ -31286,9 +31588,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
31286
31588
  }
31287
31589
  if (relativePath.startsWith("rules/")) {
31288
31590
  removeManagedCompiledArtifact2(
31289
- path42.join(
31591
+ path43.join(
31290
31592
  resolveTargetPath(paths.rules ?? ""),
31291
- `${path42.parse(relativePath).name}.md`
31593
+ `${path43.parse(relativePath).name}.md`
31292
31594
  ),
31293
31595
  "cline",
31294
31596
  relativePath,
@@ -31298,9 +31600,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
31298
31600
  }
31299
31601
  if (relativePath.startsWith("commands/")) {
31300
31602
  removeManagedCompiledArtifact2(
31301
- path42.join(
31603
+ path43.join(
31302
31604
  resolveTargetPath(paths.workflows ?? ""),
31303
- path42.basename(relativePath)
31605
+ path43.basename(relativePath)
31304
31606
  ),
31305
31607
  "cline",
31306
31608
  relativePath,
@@ -31318,17 +31620,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
31318
31620
  }
31319
31621
  }
31320
31622
  function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
31321
- if (!fs41.existsSync(artifactPath)) {
31623
+ if (!fs42.existsSync(artifactPath)) {
31322
31624
  return;
31323
31625
  }
31324
- if (!fs41.statSync(artifactPath).isFile()) {
31626
+ if (!fs42.statSync(artifactPath).isFile()) {
31325
31627
  return;
31326
31628
  }
31327
- const marker = extractProvenanceMarker(fs41.readFileSync(artifactPath, "utf8"));
31629
+ const marker = extractProvenanceMarker(fs42.readFileSync(artifactPath, "utf8"));
31328
31630
  if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
31329
31631
  return;
31330
31632
  }
31331
- fs41.rmSync(artifactPath, { force: true });
31633
+ fs42.rmSync(artifactPath, { force: true });
31332
31634
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
31333
31635
  }
31334
31636
  function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
@@ -31359,10 +31661,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
31359
31661
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
31360
31662
  }
31361
31663
  function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
31362
- if (!fs41.existsSync(artifactPath)) {
31664
+ if (!fs42.existsSync(artifactPath)) {
31363
31665
  return;
31364
31666
  }
31365
- const content = fs41.readFileSync(artifactPath, "utf8");
31667
+ const content = fs42.readFileSync(artifactPath, "utf8");
31366
31668
  const startMarker = "# tangyr: managed mcp start";
31367
31669
  const endMarker = "# tangyr: managed mcp end";
31368
31670
  const startIndex = content.indexOf(startMarker);
@@ -31379,19 +31681,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
31379
31681
  const after = content.slice(endIndex + endMarker.length).trimStart();
31380
31682
  const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
31381
31683
  if (cleaned.length === 0) {
31382
- fs41.rmSync(artifactPath, { force: true });
31684
+ fs42.rmSync(artifactPath, { force: true });
31383
31685
  } else {
31384
- fs41.writeFileSync(artifactPath, `${cleaned}
31686
+ fs42.writeFileSync(artifactPath, `${cleaned}
31385
31687
  `);
31386
31688
  }
31387
31689
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
31388
31690
  }
31389
31691
  function readJsonObject5(filePath) {
31390
- if (!fs41.existsSync(filePath)) {
31692
+ if (!fs42.existsSync(filePath)) {
31391
31693
  return null;
31392
31694
  }
31393
31695
  try {
31394
- const parsed = JSON.parse(fs41.readFileSync(filePath, "utf8"));
31696
+ const parsed = JSON.parse(fs42.readFileSync(filePath, "utf8"));
31395
31697
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
31396
31698
  } catch {
31397
31699
  return null;
@@ -31405,10 +31707,10 @@ function readJsonMetadata(value) {
31405
31707
  }
31406
31708
  function writeJsonOrRemove2(filePath, parsed) {
31407
31709
  if (isEmptyJsonValue2(parsed)) {
31408
- fs41.rmSync(filePath, { force: true });
31710
+ fs42.rmSync(filePath, { force: true });
31409
31711
  return;
31410
31712
  }
31411
- fs41.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
31713
+ fs42.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
31412
31714
  `);
31413
31715
  }
31414
31716
  function isEmptyJsonValue2(value) {
@@ -31468,8 +31770,8 @@ function removeManagedHookEntries(value, expectedSource) {
31468
31770
  }
31469
31771
 
31470
31772
  // src/commands/validate.ts
31471
- import fs42 from "fs";
31472
- import path43 from "path";
31773
+ import fs43 from "fs";
31774
+ import path44 from "path";
31473
31775
  var SUPPORTED_KIT_FORMATS2 = [1];
31474
31776
  var SUPPORTED_DISCIPLINE_VERSIONS = [
31475
31777
  "0.14.0",
@@ -31553,8 +31855,8 @@ function checkKitFormatSupported(kit) {
31553
31855
  }
31554
31856
  function checkEntrypointExists(kit) {
31555
31857
  const entrypoint = "CLAUDE.md";
31556
- const entrypointPath = path43.join(kit.path, entrypoint);
31557
- if (!fs42.existsSync(entrypointPath)) {
31858
+ const entrypointPath = path44.join(kit.path, entrypoint);
31859
+ if (!fs43.existsSync(entrypointPath)) {
31558
31860
  return {
31559
31861
  code: "entrypoint-missing",
31560
31862
  location: entrypoint,
@@ -31611,9 +31913,9 @@ function checkComponentFrontmatter(kit) {
31611
31913
  const missingSet = new Set(kit.components[cat].missing);
31612
31914
  for (const name of kit.components[cat].declared) {
31613
31915
  if (missingSet.has(name)) continue;
31614
- const filePath = cat === "skills" ? path43.join(kit.path, cat, name, "SKILL.md") : path43.join(kit.path, cat, `${name}.md`);
31615
- if (!fs42.existsSync(filePath)) continue;
31616
- const relPath = path43.relative(kit.path, filePath);
31916
+ const filePath = cat === "skills" ? path44.join(kit.path, cat, name, "SKILL.md") : path44.join(kit.path, cat, `${name}.md`);
31917
+ if (!fs43.existsSync(filePath)) continue;
31918
+ const relPath = path44.relative(kit.path, filePath);
31617
31919
  try {
31618
31920
  const { data } = parseMarkdownFrontmatter(filePath);
31619
31921
  for (const field of requiredFields) {
@@ -31638,10 +31940,10 @@ function checkComponentFrontmatter(kit) {
31638
31940
  }
31639
31941
  function checkReservedRootNames(kit) {
31640
31942
  const violations = [];
31641
- if (!fs42.existsSync(kit.path) || !fs42.statSync(kit.path).isDirectory()) {
31943
+ if (!fs43.existsSync(kit.path) || !fs43.statSync(kit.path).isDirectory()) {
31642
31944
  return violations;
31643
31945
  }
31644
- const entries = fs42.readdirSync(kit.path, { withFileTypes: true });
31946
+ const entries = fs43.readdirSync(kit.path, { withFileTypes: true });
31645
31947
  for (const entry of entries) {
31646
31948
  if (RESERVED_ROOT_NAMES.includes(entry.name)) {
31647
31949
  violations.push({
@@ -31658,8 +31960,8 @@ function checkHumanOnlyCommandInvocation(kit) {
31658
31960
  const missingSet = new Set(kit.components.commands.missing);
31659
31961
  for (const name of kit.components.commands.declared) {
31660
31962
  if (missingSet.has(name)) continue;
31661
- const filePath = path43.join(kit.path, "commands", `${name}.md`);
31662
- if (!fs42.existsSync(filePath)) continue;
31963
+ const filePath = path44.join(kit.path, "commands", `${name}.md`);
31964
+ if (!fs43.existsSync(filePath)) continue;
31663
31965
  let data;
31664
31966
  try {
31665
31967
  ({ data } = parseMarkdownFrontmatter(filePath));
@@ -31672,7 +31974,7 @@ function checkHumanOnlyCommandInvocation(kit) {
31672
31974
  if (!barred) {
31673
31975
  violations.push({
31674
31976
  code: "command-human-only-model-invocable",
31675
- location: path43.relative(kit.path, filePath),
31977
+ location: path44.relative(kit.path, filePath),
31676
31978
  message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
31677
31979
  });
31678
31980
  }
@@ -31681,8 +31983,8 @@ function checkHumanOnlyCommandInvocation(kit) {
31681
31983
  }
31682
31984
 
31683
31985
  // src/commands/verify.ts
31684
- import fs43 from "fs";
31685
- import path44 from "path";
31986
+ import fs44 from "fs";
31987
+ import path45 from "path";
31686
31988
  function runVerifyCommand(options, logger) {
31687
31989
  const { config, configDir, sourceRoot, kitInfo } = resolveRuntime(
31688
31990
  options,
@@ -31773,8 +32075,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
31773
32075
  if (!slotPath) {
31774
32076
  continue;
31775
32077
  }
31776
- const fullPath = subPath ? path44.join(slotPath, subPath) : slotPath;
31777
- if (!fs43.existsSync(fullPath)) {
32078
+ const fullPath = subPath ? path45.join(slotPath, subPath) : slotPath;
32079
+ if (!fs44.existsSync(fullPath)) {
31778
32080
  failures.push(
31779
32081
  `claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
31780
32082
  );