@alessandroraffa/tangyr 0.14.0 → 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 +1012 -577
  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 path44 = __require("path");
1376
- var fs43 = __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 (fs43.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 = path44.resolve(baseDir, baseName);
2389
- if (fs43.existsSync(localBin)) return localBin;
2390
- if (sourceExt.includes(path44.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) => fs43.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 = fs43.realpathSync(this._scriptPath);
2404
+ resolvedScriptPath = fs45.realpathSync(this._scriptPath);
2405
2405
  } catch {
2406
2406
  resolvedScriptPath = this._scriptPath;
2407
2407
  }
2408
- executableDir = path44.resolve(
2409
- path44.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 = path44.basename(
2416
+ const legacyName = path46.basename(
2417
2417
  this._scriptPath,
2418
- path44.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(path44.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 = path44.basename(filename, path44.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(path45) {
3359
- if (path45 === void 0) return this._executableDir;
3360
- this._executableDir = path45;
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, path44) {
3717
- const ctrl = callVisitor(key, node, visitor, path44);
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, path44, ctrl);
3720
- return visit_(key, ctrl, visitor, path44);
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
- path44 = Object.freeze(path44.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, path44);
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
- path44 = Object.freeze(path44.concat(node));
3738
- const ck = visit_("key", node.key, visitor, path44);
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, path44);
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, path44) {
3765
- const ctrl = await callVisitor(key, node, visitor, path44);
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, path44, ctrl);
3768
- return visitAsync_(key, ctrl, visitor, path44);
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
- path44 = Object.freeze(path44.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, path44);
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
- path44 = Object.freeze(path44.concat(node));
3786
- const ck = await visitAsync_("key", node.key, visitor, path44);
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, path44);
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, path44) {
3818
+ function callVisitor(key, node, visitor, path46) {
3819
3819
  if (typeof visitor === "function")
3820
- return visitor(key, node, path44);
3820
+ return visitor(key, node, path46);
3821
3821
  if (identity.isMap(node))
3822
- return visitor.Map?.(key, node, path44);
3822
+ return visitor.Map?.(key, node, path46);
3823
3823
  if (identity.isSeq(node))
3824
- return visitor.Seq?.(key, node, path44);
3824
+ return visitor.Seq?.(key, node, path46);
3825
3825
  if (identity.isPair(node))
3826
- return visitor.Pair?.(key, node, path44);
3826
+ return visitor.Pair?.(key, node, path46);
3827
3827
  if (identity.isScalar(node))
3828
- return visitor.Scalar?.(key, node, path44);
3828
+ return visitor.Scalar?.(key, node, path46);
3829
3829
  if (identity.isAlias(node))
3830
- return visitor.Alias?.(key, node, path44);
3830
+ return visitor.Alias?.(key, node, path46);
3831
3831
  return void 0;
3832
3832
  }
3833
- function replaceNode(key, path44, node) {
3834
- const parent = path44[path44.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, path44, value) {
4442
+ function collectionFromPath(schema, path46, value) {
4443
4443
  let v2 = value;
4444
- for (let i = path44.length - 1; i >= 0; --i) {
4445
- const k2 = path44[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 = (path44) => path44 == null || typeof path44 === "object" && !!path44[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(path44, value) {
4495
- if (isEmptyPath(path44))
4494
+ addIn(path46, value) {
4495
+ if (isEmptyPath(path46))
4496
4496
  this.add(value);
4497
4497
  else {
4498
- const [key, ...rest] = path44;
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(path44) {
4513
- const [key, ...rest] = path44;
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(path44, keepScalar) {
4528
- const [key, ...rest] = path44;
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(path44) {
4547
- const [key, ...rest] = path44;
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(path44, value) {
4558
- const [key, ...rest] = path44;
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(path44, value) {
7070
+ addIn(path46, value) {
7071
7071
  if (assertCollection(this.contents))
7072
- this.contents.addIn(path44, 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(path44) {
7148
- if (Collection.isEmptyPath(path44)) {
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(path44) : 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(path44, keepScalar) {
7170
- if (Collection.isEmptyPath(path44))
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(path44, 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(path44) {
7184
- if (Collection.isEmptyPath(path44))
7183
+ hasIn(path46) {
7184
+ if (Collection.isEmptyPath(path46))
7185
7185
  return this.contents !== void 0;
7186
- return identity.isCollection(this.contents) ? this.contents.hasIn(path44) : 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(path44, value) {
7204
- if (Collection.isEmptyPath(path44)) {
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(path44), value);
7207
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path46), value);
7208
7208
  } else if (assertCollection(this.contents)) {
7209
- this.contents.setIn(path44, 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, path44) => {
9166
+ visit.itemAtPath = (cst, path46) => {
9167
9167
  let item = cst;
9168
- for (const [field, index] of path44) {
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, path44) => {
9178
- const parent = visit.itemAtPath(cst, path44.slice(0, -1));
9179
- const field = path44[path44.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(path44, item, visitor) {
9186
- let ctrl = visitor(item, path44);
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(path44.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, path44);
9204
+ ctrl = ctrl(item, path46);
9205
9205
  }
9206
9206
  }
9207
- return typeof ctrl === "function" ? ctrl(item, path44) : 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 fs43 = this.flowScalar(this.type);
10492
+ const fs45 = this.flowScalar(this.type);
10493
10493
  if (atNextItem || it2.value) {
10494
- map.items.push({ start, key: fs43, sep: [] });
10494
+ map.items.push({ start, key: fs45, sep: [] });
10495
10495
  this.onKeyLine = true;
10496
10496
  } else if (it2.sep) {
10497
- this.stack.push(fs43);
10497
+ this.stack.push(fs45);
10498
10498
  } else {
10499
- Object.assign(it2, { key: fs43, 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 fs43 = this.flowScalar(this.type);
10627
+ const fs45 = this.flowScalar(this.type);
10628
10628
  if (!it2 || it2.value)
10629
- fc.items.push({ start: [], key: fs43, sep: [] });
10629
+ fc.items.push({ start: [], key: fs45, sep: [] });
10630
10630
  else if (it2.sep)
10631
- this.stack.push(fs43);
10631
+ this.stack.push(fs45);
10632
10632
  else
10633
- Object.assign(it2, { key: fs43, 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,12 +23138,95 @@ function toConflictPolicy2(value) {
23113
23138
  }
23114
23139
 
23115
23140
  // src/commands/install.ts
23116
- import fs35 from "fs";
23117
- import path35 from "path";
23141
+ import fs37 from "fs";
23142
+ import path37 from "path";
23118
23143
 
23119
- // src/core/materialize.ts
23144
+ // src/core/channel-state.ts
23120
23145
  import fs28 from "fs";
23121
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
+ }
23221
+
23222
+ // src/core/bundle.ts
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";
23122
23230
 
23123
23231
  // src/core/integrity.ts
23124
23232
  import crypto3 from "crypto";
@@ -23237,21 +23345,193 @@ function verifyBundle(bundle, keys, expectedIdentity, now) {
23237
23345
  verifyIdentity(bundle.manifest, expectedIdentity);
23238
23346
  }
23239
23347
  function verifyDenyList(denyList, keys, now) {
23240
- const isWellFormed = denyList !== null && typeof denyList === "object" && typeof denyList.keyId === "string" && typeof denyList.signature === "string" && denyList.signature.length > 0 && Array.isArray(denyList.entries) && denyList.entries.every(
23241
- (entry) => typeof entry === "string"
23242
- );
23243
- if (!isWellFormed) {
23348
+ if (denyList === null || typeof denyList !== "object") {
23349
+ throw new IntegrityError(DENY_LIST_MALFORMED);
23350
+ }
23351
+ const actualKeys = Object.keys(denyList).sort();
23352
+ const expectedKeys = [
23353
+ "entries",
23354
+ "expiresAt",
23355
+ "issuedAt",
23356
+ "keyId",
23357
+ "sequence",
23358
+ "signature",
23359
+ "type"
23360
+ ];
23361
+ if (actualKeys.length !== expectedKeys.length || actualKeys.some((key, index) => key !== expectedKeys[index])) {
23244
23362
  throw new IntegrityError(
23245
- "Revocation deny-list response is malformed, unsigned, or corrupted \u2014 treated as an integrity failure, never as an absent deny-list (REQ-INT-009)."
23363
+ `${DENY_LIST_MALFORMED} Expected exactly [${expectedKeys.join(", ")}], got [${actualKeys.join(", ")}].`
23246
23364
  );
23247
23365
  }
23248
23366
  const list = denyList;
23249
- const canonicalBytes = canonicalJsonBytes({
23250
- keyId: list.keyId,
23251
- entries: list.entries
23367
+ const shapeOk = list.type === DENY_LIST_TYPE && typeof list.keyId === "string" && typeof list.signature === "string" && list.signature.length > 0 && Number.isSafeInteger(list.sequence) && list.sequence >= 0 && typeof list.issuedAt === "string" && typeof list.expiresAt === "string" && Array.isArray(list.entries) && list.entries.every((entry) => typeof entry === "string");
23368
+ if (!shapeOk) {
23369
+ throw new IntegrityError(DENY_LIST_MALFORMED);
23370
+ }
23371
+ const { signature, ...signed } = list;
23372
+ verifySignedPayload(
23373
+ canonicalJsonBytes(signed),
23374
+ signature,
23375
+ list.keyId,
23376
+ keys,
23377
+ now
23378
+ );
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
+ );
23385
+ return list;
23386
+ }
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).";
23388
+ function assertFreshnessWindow(issuedAt, expiresAt, now, expiryConsequence) {
23389
+ const utcDesignatorPattern = /Z|[+-]\d{2}:\d{2}$/;
23390
+ if (!utcDesignatorPattern.test(issuedAt) || !utcDesignatorPattern.test(expiresAt)) {
23391
+ throw new IntegrityError(
23392
+ `Signed document has a timezone-ambiguous validity window (issuedAt "${issuedAt}", expiresAt "${expiresAt}") \u2014 an explicit UTC designator ("Z") or numeric offset is required.`
23393
+ );
23394
+ }
23395
+ const issued = new Date(issuedAt);
23396
+ const expires = new Date(expiresAt);
23397
+ if (Number.isNaN(issued.getTime()) || Number.isNaN(expires.getTime())) {
23398
+ throw new IntegrityError(
23399
+ `Signed document has an unparseable validity window (issuedAt "${issuedAt}", expiresAt "${expiresAt}").`
23400
+ );
23401
+ }
23402
+ if (expires.getTime() < issued.getTime()) {
23403
+ throw new IntegrityError(
23404
+ `Signed document expires (${expiresAt}) before it was issued (${issuedAt}) \u2014 refusing.`
23405
+ );
23406
+ }
23407
+ if (now.getTime() > expires.getTime()) {
23408
+ throw new IntegrityError(
23409
+ `Signed document expired at ${expiresAt} (now ${now.toISOString()}). ${expiryConsequence}`
23410
+ );
23411
+ }
23412
+ if (now.getTime() < issued.getTime()) {
23413
+ throw new IntegrityError(
23414
+ `Signed document is not yet valid: issued at ${issuedAt}, now ${now.toISOString()}. Check the local clock.`
23415
+ );
23416
+ }
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
+ }
23467
+
23468
+ // src/core/revocation-state.ts
23469
+ import fs29 from "fs";
23470
+ import path27 from "path";
23471
+ var REVOCATION_STATE_FILENAME = ".tangyr-revocation.json";
23472
+ function stateFilePath2(cacheRoot) {
23473
+ return path27.join(cacheRoot, REVOCATION_STATE_FILENAME);
23474
+ }
23475
+ function readState2(cacheRoot) {
23476
+ const filePath = stateFilePath2(cacheRoot);
23477
+ let raw;
23478
+ try {
23479
+ raw = fs29.readFileSync(filePath, "utf8");
23480
+ } catch (err) {
23481
+ if (err.code === "ENOENT") {
23482
+ return { state: {} };
23483
+ }
23484
+ return {
23485
+ state: {},
23486
+ warning: `Could not read ${filePath} (${err.message}); the deny-list replay guard starts from nothing for this run.`
23487
+ };
23488
+ }
23489
+ let parsed;
23490
+ try {
23491
+ parsed = JSON.parse(raw);
23492
+ } catch {
23493
+ return {
23494
+ state: {},
23495
+ warning: `${filePath} is not valid JSON; the deny-list replay guard starts from nothing for this run.`
23496
+ };
23497
+ }
23498
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
23499
+ return {
23500
+ state: {},
23501
+ warning: `${filePath} does not contain an object; the deny-list replay guard starts from nothing for this run.`
23502
+ };
23503
+ }
23504
+ return { state: parsed };
23505
+ }
23506
+ function readRevocationSequence(cacheRoot, originUrl) {
23507
+ const { state, warning } = readState2(cacheRoot);
23508
+ const record = state[originUrl];
23509
+ const sequence = record !== void 0 && Number.isSafeInteger(record.sequence) ? record.sequence : void 0;
23510
+ return warning === void 0 ? { sequence } : { sequence, warning };
23511
+ }
23512
+ function writeRevocationSequence(cacheRoot, originUrl, sequence, now) {
23513
+ const { state } = readState2(cacheRoot);
23514
+ const existing = state[originUrl]?.sequence;
23515
+ if (existing !== void 0 && existing >= sequence) {
23516
+ return;
23517
+ }
23518
+ state[originUrl] = { sequence, seenAt: now.toISOString() };
23519
+ const filePath = stateFilePath2(cacheRoot);
23520
+ fs29.mkdirSync(path27.dirname(filePath), { recursive: true, mode: 448 });
23521
+ const tempPath = `${filePath}.${process.pid}.tmp`;
23522
+ fs29.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
23523
+ `, {
23524
+ mode: 384
23252
23525
  });
23253
- verifySignedPayload(canonicalBytes, list.signature, list.keyId, keys, now);
23254
- return list.entries;
23526
+ fs29.renameSync(tempPath, filePath);
23527
+ }
23528
+ function assertSequenceNotReplayed(params) {
23529
+ const { originUrl, seen, incoming } = params;
23530
+ if (seen !== void 0 && incoming < seen) {
23531
+ throw new IntegrityError(
23532
+ `Revocation deny-list from ${originUrl} carries sequence ${incoming}, behind the highest already accepted (${seen}). That is a replay of a superseded deny-list, which would silently un-revoke a kit \u2014 refusing (REQ-INT-009).`
23533
+ );
23534
+ }
23255
23535
  }
23256
23536
 
23257
23537
  // src/core/materialize.ts
@@ -23365,7 +23645,7 @@ async function assertReferenceNotRevoked(params) {
23365
23645
  sleep: sleep2
23366
23646
  } = params;
23367
23647
  const credentials = resolveCredentialNonInteractive();
23368
- const deniedEntries = await withBoundedRetry(
23648
+ const denyList = await withBoundedRetry(
23369
23649
  async () => {
23370
23650
  const controller = new AbortController();
23371
23651
  const response = await transport.fetchObjectStream(
@@ -23402,11 +23682,21 @@ async function assertReferenceNotRevoked(params) {
23402
23682
  sleep2,
23403
23683
  logger
23404
23684
  );
23685
+ const seen = readRevocationSequence(cacheRoot, originUrl);
23686
+ if (seen.warning) {
23687
+ logger.warn(seen.warning);
23688
+ }
23689
+ assertSequenceNotReplayed({
23690
+ originUrl,
23691
+ seen: seen.sequence,
23692
+ incoming: denyList.sequence
23693
+ });
23694
+ writeRevocationSequence(cacheRoot, originUrl, denyList.sequence, now);
23405
23695
  const key = `${reference.name}@${reference.version}`;
23406
- if (deniedEntries.includes(key)) {
23696
+ if (denyList.entries.includes(key)) {
23407
23697
  const entryDir = cacheEntryPath(cacheRoot, reference);
23408
- if (fs28.existsSync(entryDir)) {
23409
- fs28.rmSync(entryDir, { recursive: true, force: true });
23698
+ if (fs30.existsSync(entryDir)) {
23699
+ fs30.rmSync(entryDir, { recursive: true, force: true });
23410
23700
  }
23411
23701
  throw new IntegrityError(
23412
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).`
@@ -23453,7 +23743,7 @@ function assertFileWithinCeiling(entryPath, byteLength) {
23453
23743
  }
23454
23744
  var WINDOWS_DRIVE_ABSOLUTE = /^[a-zA-Z]:[\\/]/u;
23455
23745
  function sanitizeBundleFilePath(entryPath, stagingDir) {
23456
- if (path26.isAbsolute(entryPath) || WINDOWS_DRIVE_ABSOLUTE.test(entryPath)) {
23746
+ if (path28.isAbsolute(entryPath) || WINDOWS_DRIVE_ABSOLUTE.test(entryPath)) {
23457
23747
  throw new IntegrityError(
23458
23748
  `Bundle file path "${entryPath}" is absolute \u2014 every file inside a bundle must use a relative path (REQ-INT-004).`
23459
23749
  );
@@ -23469,13 +23759,13 @@ function sanitizeBundleFilePath(entryPath, stagingDir) {
23469
23759
  `Bundle file path "${entryPath}" contains a ".." segment \u2014 directory traversal is rejected (REQ-INT-004).`
23470
23760
  );
23471
23761
  }
23472
- const resolved = path26.resolve(stagingDir, entryPath);
23762
+ const resolved = path28.resolve(stagingDir, entryPath);
23473
23763
  if (resolved === stagingDir) {
23474
23764
  throw new IntegrityError(
23475
23765
  `Bundle file path "${entryPath}" resolves to the staging directory itself \u2014 every entry must be a file inside it (REQ-INT-004).`
23476
23766
  );
23477
23767
  }
23478
- if (!resolved.startsWith(stagingDir + path26.sep)) {
23768
+ if (!resolved.startsWith(stagingDir + path28.sep)) {
23479
23769
  throw new IntegrityError(
23480
23770
  `Bundle file path "${entryPath}" escapes the staging directory \u2014 refusing to write (REQ-INT-004).`
23481
23771
  );
@@ -23527,10 +23817,10 @@ function verifyBundleFileHashes(bundle) {
23527
23817
  function writeStagedFiles(stagingDir, decoded) {
23528
23818
  for (const [rawPath, bytes] of decoded) {
23529
23819
  const target = sanitizeBundleFilePath(rawPath, stagingDir);
23530
- fs28.mkdirSync(path26.dirname(target), { recursive: true, mode: 448 });
23820
+ fs30.mkdirSync(path28.dirname(target), { recursive: true, mode: 448 });
23531
23821
  let existingStat;
23532
23822
  try {
23533
- existingStat = fs28.lstatSync(target);
23823
+ existingStat = fs30.lstatSync(target);
23534
23824
  } catch (error) {
23535
23825
  if (error.code !== "ENOENT") {
23536
23826
  throw error;
@@ -23541,7 +23831,7 @@ function writeStagedFiles(stagingDir, decoded) {
23541
23831
  `Refusing to write "${rawPath}" \u2014 a symbolic link already exists at the target path.`
23542
23832
  );
23543
23833
  }
23544
- fs28.writeFileSync(target, bytes, { mode: 384, flag: "wx" });
23834
+ fs30.writeFileSync(target, bytes, { mode: 384, flag: "wx" });
23545
23835
  }
23546
23836
  }
23547
23837
  function verifyWarmCacheEntry(entryDir, reference, keys, now) {
@@ -23607,18 +23897,103 @@ async function materializeRemoteKit(params) {
23607
23897
  writeStagedFiles(stagingDir, decoded);
23608
23898
  writeBundleDocument(stagingDir, bundle);
23609
23899
  writeCompletionMarker(stagingDir, reference);
23610
- if (replace && fs28.existsSync(entryDir)) {
23611
- fs28.rmSync(entryDir, { recursive: true, force: true });
23900
+ if (replace && fs30.existsSync(entryDir)) {
23901
+ fs30.rmSync(entryDir, { recursive: true, force: true });
23612
23902
  }
23613
23903
  publishCacheEntry(stagingDir, entryDir);
23614
23904
  return entryDir;
23615
23905
  } catch (error) {
23616
23906
  if (stagingDir !== void 0) {
23617
- fs28.rmSync(stagingDir, { recursive: true, force: true });
23907
+ fs30.rmSync(stagingDir, { recursive: true, force: true });
23618
23908
  }
23619
23909
  throw error;
23620
23910
  }
23621
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
+ }
23622
23997
 
23623
23998
  // src/core/kit-source.ts
23624
23999
  function resolveCacheOnly(entryDir, reference, keys, now) {
@@ -23657,13 +24032,25 @@ async function resolveKitSource(params) {
23657
24032
  if (config.source.type !== "remote") {
23658
24033
  return { kitName: kitOption };
23659
24034
  }
23660
- const reference = parseKitReference(kitOption ?? "");
24035
+ const selector = parseKitSelector(kitOption ?? "");
23661
24036
  if (!config.source.url) {
23662
24037
  throw new Error(
23663
24038
  "Configuration declares source.type: remote but no source.url. Set source.url to the https endpoint of your kit origin."
23664
24039
  );
23665
24040
  }
23666
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 };
23667
24054
  const entryDir = cacheEntryPath(cacheRoot, reference);
23668
24055
  if (offline) {
23669
24056
  return resolveCacheOnly(entryDir, reference, keys, now);
@@ -23801,6 +24188,54 @@ async function resolveKitSource(params) {
23801
24188
  writeLastAuthorizedAt(cacheRoot, config.source.url, now);
23802
24189
  return { kitPathOverride, kitName: reference.name };
23803
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
+ }
23804
24239
 
23805
24240
  // src/core/keys.ts
23806
24241
  var PINNED_PUBLISHER_KEYS = [
@@ -23822,13 +24257,13 @@ function sleep(ms2) {
23822
24257
  // src/adapters/codex.ts
23823
24258
  var TOML3 = __toESM(require_toml(), 1);
23824
24259
  import crypto5 from "crypto";
23825
- import fs30 from "fs";
23826
- import path29 from "path";
24260
+ import fs32 from "fs";
24261
+ import path31 from "path";
23827
24262
 
23828
24263
  // src/compiler/agents.ts
23829
24264
  var TOML = __toESM(require_toml(), 1);
23830
24265
  var import_yaml7 = __toESM(require_dist(), 1);
23831
- import path27 from "path";
24266
+ import path29 from "path";
23832
24267
 
23833
24268
  // src/compiler/loss-report.ts
23834
24269
  function createLossReport() {
@@ -23892,7 +24327,7 @@ var copilotToolAliasesByClass = {
23892
24327
  };
23893
24328
  function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
23894
24329
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
23895
- const relativeSource = `agents/${path27.basename(sourceFile)}`;
24330
+ const relativeSource = `agents/${path29.basename(sourceFile)}`;
23896
24331
  if (target === "opencode") {
23897
24332
  return compileOpenCodeAgent(
23898
24333
  sourceFile,
@@ -23933,7 +24368,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
23933
24368
  mappings,
23934
24369
  lossReport
23935
24370
  );
23936
- const overlayKey = `agents/${path27.basename(sourceFile, ".md")}.${target}.yaml`;
24371
+ const overlayKey = `agents/${path29.basename(sourceFile, ".md")}.${target}.yaml`;
23937
24372
  const targetFields = {
23938
24373
  ...translated.fields,
23939
24374
  ...extensions[overlayKey] ?? {}
@@ -23967,7 +24402,7 @@ ${TOML.stringify({
23967
24402
  function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
23968
24403
  if (typeof data.description !== "string" || data.description.trim() === "") {
23969
24404
  throw new Error(
23970
- `${path27.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
24405
+ `${path29.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
23971
24406
  );
23972
24407
  }
23973
24408
  const frontmatter = {
@@ -24021,7 +24456,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
24021
24456
  "permission",
24022
24457
  "permission-coarsening"
24023
24458
  ),
24024
- detail: `${path27.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`
24025
24460
  }
24026
24461
  ]
24027
24462
  });
@@ -24046,7 +24481,7 @@ ${(0, import_yaml7.stringify)(frontmatter).trim()}
24046
24481
  function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
24047
24482
  if (typeof data.description !== "string" || data.description.trim() === "") {
24048
24483
  throw new Error(
24049
- `${path27.basename(sourceFile)}: Cursor agent requires a non-empty description field`
24484
+ `${path29.basename(sourceFile)}: Cursor agent requires a non-empty description field`
24050
24485
  );
24051
24486
  }
24052
24487
  const frontmatter = {
@@ -24083,7 +24518,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
24083
24518
  "permission",
24084
24519
  "permission-coarsening"
24085
24520
  ),
24086
- detail: `${path27.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)`
24087
24522
  }
24088
24523
  ]
24089
24524
  });
@@ -24102,7 +24537,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
24102
24537
  "provider",
24103
24538
  "provider-not-representable"
24104
24539
  ),
24105
- detail: `${path27.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`
24106
24541
  }
24107
24542
  ]
24108
24543
  });
@@ -24134,7 +24569,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
24134
24569
  "persona",
24135
24570
  "persona-not-representable"
24136
24571
  ),
24137
- detail: `${path27.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.`
24138
24573
  }
24139
24574
  ]
24140
24575
  });
@@ -24182,7 +24617,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
24182
24617
  field,
24183
24618
  "model-not-representable"
24184
24619
  ),
24185
- detail: `${path27.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.`
24186
24621
  });
24187
24622
  return;
24188
24623
  }
@@ -24200,9 +24635,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
24200
24635
  lossReport,
24201
24636
  target,
24202
24637
  "agents",
24203
- `agents/${path27.basename(sourceFile)}`,
24638
+ `agents/${path29.basename(sourceFile)}`,
24204
24639
  "info",
24205
- `${path27.basename(sourceFile)}: ${field} is delivered through another managed surface.`
24640
+ `${path29.basename(sourceFile)}: ${field} is delivered through another managed surface.`
24206
24641
  );
24207
24642
  return;
24208
24643
  }
@@ -24211,7 +24646,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
24211
24646
  field,
24212
24647
  action: entryType,
24213
24648
  severity: resolveLossSeverity("agent-field", field, entryType),
24214
- detail: `${path27.basename(sourceFile)}: ${field} has no emitted field for this target.`
24649
+ detail: `${path29.basename(sourceFile)}: ${field} has no emitted field for this target.`
24215
24650
  });
24216
24651
  }
24217
24652
  function mapToolsToCapabilities(value, mappings) {
@@ -24808,9 +25243,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
24808
25243
  }
24809
25244
 
24810
25245
  // src/compiler/rules.ts
24811
- import path28 from "path";
25246
+ import path30 from "path";
24812
25247
  var import_yaml8 = __toESM(require_dist(), 1);
24813
- import fs29 from "fs";
25248
+ import fs31 from "fs";
24814
25249
  function compileRules(sourceRulesDir, target, _mappings, lossReport) {
24815
25250
  if (target === "copilot") {
24816
25251
  addLoss(lossReport, "copilot", "rules", {
@@ -24847,13 +25282,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
24847
25282
  }
24848
25283
  const appendixParts = [];
24849
25284
  const dotRulesFiles = [];
24850
- for (const ruleFile of ts(path28.join(sourceRulesDir, "*.md")).sort()) {
25285
+ for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
24851
25286
  const parsed = parseRule(ruleFile);
24852
- const name = path28.basename(ruleFile, ".md");
25287
+ const name = path30.basename(ruleFile, ".md");
24853
25288
  if (parsed.mode === "exec-policy") {
24854
25289
  dotRulesFiles.push({
24855
25290
  name: `${name}.rules`,
24856
- content: `${formatProvenanceMarker("toml", `rules/${path28.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
25291
+ content: `${formatProvenanceMarker("toml", `rules/${path30.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
24857
25292
  ${parsed.body}`
24858
25293
  });
24859
25294
  continue;
@@ -24862,7 +25297,7 @@ ${parsed.body}`
24862
25297
 
24863
25298
  ${parsed.body.trim()}`);
24864
25299
  addLoss(lossReport, "codex", "rules", {
24865
- source: `rules/${path28.basename(ruleFile)}`,
25300
+ source: `rules/${path30.basename(ruleFile)}`,
24866
25301
  fields: [
24867
25302
  {
24868
25303
  field: "mode",
@@ -24872,7 +25307,7 @@ ${parsed.body.trim()}`);
24872
25307
  "mode",
24873
25308
  "rule-as-instruction"
24874
25309
  ),
24875
- detail: `${path28.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.`
24876
25311
  }
24877
25312
  ]
24878
25313
  });
@@ -24880,7 +25315,7 @@ ${parsed.body.trim()}`);
24880
25315
  return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
24881
25316
  }
24882
25317
  function parseRule(ruleFile) {
24883
- const content = fs29.readFileSync(ruleFile, "utf8");
25318
+ const content = fs31.readFileSync(ruleFile, "utf8");
24884
25319
  if (!content.startsWith("---\n")) {
24885
25320
  return { mode: "guidance", body: content };
24886
25321
  }
@@ -24904,14 +25339,14 @@ function isRuleMode(value) {
24904
25339
  }
24905
25340
  function compileOpenCodeRules(sourceRulesDir, lossReport) {
24906
25341
  const appendixParts = [];
24907
- for (const ruleFile of ts(path28.join(sourceRulesDir, "*.md")).sort()) {
25342
+ for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
24908
25343
  const parsed = parseRule(ruleFile);
24909
- const name = path28.basename(ruleFile, ".md");
25344
+ const name = path30.basename(ruleFile, ".md");
24910
25345
  appendixParts.push(`## ${name}
24911
25346
 
24912
25347
  ${parsed.body.trim()}`);
24913
25348
  addLoss(lossReport, "opencode", "rules", {
24914
- source: `rules/${path28.basename(ruleFile)}`,
25349
+ source: `rules/${path30.basename(ruleFile)}`,
24915
25350
  fields: [
24916
25351
  {
24917
25352
  field: "rule",
@@ -24921,7 +25356,7 @@ ${parsed.body.trim()}`);
24921
25356
  "rule",
24922
25357
  "rule-path-scoping"
24923
25358
  ),
24924
- detail: `${path28.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`
24925
25360
  }
24926
25361
  ]
24927
25362
  });
@@ -24930,9 +25365,9 @@ ${parsed.body.trim()}`);
24930
25365
  }
24931
25366
  function compileCursorRules(sourceRulesDir, _lossReport) {
24932
25367
  const dotRulesFiles = [];
24933
- for (const ruleFile of ts(path28.join(sourceRulesDir, "*.md")).sort()) {
24934
- const content = fs29.readFileSync(ruleFile, "utf8");
24935
- const name = path28.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");
24936
25371
  let frontmatterData = {};
24937
25372
  let body = content;
24938
25373
  if (content.startsWith("---\n")) {
@@ -24961,7 +25396,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
24961
25396
  }
24962
25397
  const marker = formatProvenanceMarker(
24963
25398
  "markdown",
24964
- `rules/${path28.basename(ruleFile)}`,
25399
+ `rules/${path30.basename(ruleFile)}`,
24965
25400
  computeSourceHash(ruleFile),
24966
25401
  "cursor"
24967
25402
  );
@@ -24977,9 +25412,9 @@ ${body}`;
24977
25412
  }
24978
25413
  function compileClineRules(sourceRulesDir, lossReport) {
24979
25414
  const dotRulesFiles = [];
24980
- for (const ruleFile of ts(path28.join(sourceRulesDir, "*.md")).sort()) {
24981
- const content = fs29.readFileSync(ruleFile, "utf8");
24982
- const name = path28.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");
24983
25418
  let frontmatterData = {};
24984
25419
  let body = content;
24985
25420
  if (content.startsWith("---\n")) {
@@ -24996,13 +25431,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
24996
25431
  }
24997
25432
  const marker = formatProvenanceMarker(
24998
25433
  "markdown",
24999
- `rules/${path28.basename(ruleFile)}`,
25434
+ `rules/${path30.basename(ruleFile)}`,
25000
25435
  computeSourceHash(ruleFile),
25001
25436
  "cline"
25002
25437
  );
25003
25438
  if (frontmatterData.mode === "exec-policy") {
25004
25439
  addLoss(lossReport, "cline", "rules", {
25005
- source: `rules/${path28.basename(ruleFile)}`,
25440
+ source: `rules/${path30.basename(ruleFile)}`,
25006
25441
  fields: [
25007
25442
  {
25008
25443
  field: "mode",
@@ -25012,7 +25447,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
25012
25447
  "mode",
25013
25448
  "rule-mode-downgrade"
25014
25449
  ),
25015
- detail: `${path28.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.`
25016
25451
  }
25017
25452
  ]
25018
25453
  });
@@ -25057,7 +25492,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
25057
25492
  rules: profile.rules
25058
25493
  };
25059
25494
  const rules = compileRules(
25060
- path29.join(sourceRoot, config.source.rules),
25495
+ path31.join(sourceRoot, config.source.rules),
25061
25496
  "codex",
25062
25497
  mappings,
25063
25498
  lossReport
@@ -25202,9 +25637,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
25202
25637
  function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
25203
25638
  const cp = mappings.modelTiers.custom_provider;
25204
25639
  if (!cp) return "";
25205
- const agentsDir = path29.join(sourceRoot, config.source.agents);
25206
- if (!fs30.existsSync(agentsDir)) return "";
25207
- const agentFiles = ts(path29.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();
25208
25643
  const hasProviderAgent = agentFiles.some((agentFile) => {
25209
25644
  const { data } = parseMarkdownFrontmatter(agentFile);
25210
25645
  return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
@@ -25269,7 +25704,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
25269
25704
  }
25270
25705
  ];
25271
25706
  for (const ruleFile of rules.dotRulesFiles) {
25272
- const destination = path29.join(rulesRoot, ruleFile.name);
25707
+ const destination = path31.join(rulesRoot, ruleFile.name);
25273
25708
  if (options.dryRun) {
25274
25709
  logger.info(`[dry-run] rules: write ${destination}`);
25275
25710
  outcomes.push({
@@ -25297,15 +25732,15 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
25297
25732
  return outcomes;
25298
25733
  }
25299
25734
  function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
25300
- const source = path29.join(sourceRoot, config.source.instructions);
25735
+ const source = path31.join(sourceRoot, config.source.instructions);
25301
25736
  const destination = resolveTargetPath(paths.instructions);
25302
- const composed = `${fs30.readFileSync(source, "utf8").trim()}
25737
+ const composed = `${fs32.readFileSync(source, "utf8").trim()}
25303
25738
 
25304
25739
  --- tangyr managed rules ---
25305
25740
  ${agentsAppendix}`.trim();
25306
25741
  const marker = formatProvenanceMarker(
25307
25742
  "markdown",
25308
- path29.basename(config.source.instructions),
25743
+ path31.basename(config.source.instructions),
25309
25744
  hashString(composed),
25310
25745
  "codex"
25311
25746
  );
@@ -25332,9 +25767,9 @@ ${composed}
25332
25767
  );
25333
25768
  }
25334
25769
  function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
25335
- const source = path29.resolve(sourceRoot, config.source.skills);
25770
+ const source = path31.resolve(sourceRoot, config.source.skills);
25336
25771
  const destination = resolveTargetPath(paths.skills);
25337
- if (!fs30.existsSync(source)) {
25772
+ if (!fs32.existsSync(source)) {
25338
25773
  return skippedMissingSource("skills", source);
25339
25774
  }
25340
25775
  if (options.dryRun) {
@@ -25350,29 +25785,29 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
25350
25785
  };
25351
25786
  }
25352
25787
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
25353
- fs30.unlinkSync(destination);
25788
+ fs32.unlinkSync(destination);
25354
25789
  logger.verbose(`Skills: created skills path ${destination}`);
25355
25790
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
25356
25791
  return { component: "skills", status: "conflict", path: destination };
25357
25792
  } else if (artifactClass === "managed-symlink") {
25358
- fs30.unlinkSync(destination);
25793
+ fs32.unlinkSync(destination);
25359
25794
  }
25360
- ensureDir(path29.dirname(destination));
25795
+ ensureDir(path31.dirname(destination));
25361
25796
  createRelativeSymlink(source, destination, "dir");
25362
25797
  logger.verbose(`Skills: created skills path ${destination}`);
25363
25798
  return { component: "skills", status: "success", path: destination };
25364
25799
  }
25365
25800
  function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
25366
- const sourceAgentsRoot = path29.join(sourceRoot, config.source.agents);
25367
- if (!fs30.existsSync(sourceAgentsRoot)) {
25801
+ const sourceAgentsRoot = path31.join(sourceRoot, config.source.agents);
25802
+ if (!fs32.existsSync(sourceAgentsRoot)) {
25368
25803
  return [skippedMissingSource("agents", sourceAgentsRoot)];
25369
25804
  }
25370
- const sourceAgents = ts(path29.join(sourceAgentsRoot, "*.md")).sort();
25805
+ const sourceAgents = ts(path31.join(sourceAgentsRoot, "*.md")).sort();
25371
25806
  const agentsRoot = resolveTargetPath(paths.agents);
25372
25807
  return sourceAgents.map((agentFile) => {
25373
- const destination = path29.join(
25808
+ const destination = path31.join(
25374
25809
  agentsRoot,
25375
- `${path29.basename(agentFile, ".md")}.toml`
25810
+ `${path31.basename(agentFile, ".md")}.toml`
25376
25811
  );
25377
25812
  const compiled = compileAgent(
25378
25813
  agentFile,
@@ -25408,10 +25843,10 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
25408
25843
  }
25409
25844
  const source = resolveHooksSourceFile(sourceRoot, config);
25410
25845
  const sourceLabel = hooksSourceLabel(config);
25411
- if (!fs30.existsSync(source)) {
25846
+ if (!fs32.existsSync(source)) {
25412
25847
  return skippedMissingSource("hooks", source);
25413
25848
  }
25414
- const sourceHooksJson = JSON.parse(fs30.readFileSync(source, "utf8"));
25849
+ const sourceHooksJson = JSON.parse(fs32.readFileSync(source, "utf8"));
25415
25850
  const compiled = compileHooks(
25416
25851
  sourceHooksJson,
25417
25852
  "codex",
@@ -25433,7 +25868,7 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
25433
25868
  destination,
25434
25869
  hostHooks,
25435
25870
  stringifyJson2,
25436
- !fs30.existsSync(destination),
25871
+ !fs32.existsSync(destination),
25437
25872
  logger
25438
25873
  );
25439
25874
  return {
@@ -25446,7 +25881,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
25446
25881
  const source = resolveMcpSourceFile(sourceRoot, config);
25447
25882
  const sourceLabel = mcpSourceLabel(config);
25448
25883
  const destination = resolveTargetPath(paths.mcp_shared_file);
25449
- if (!fs30.existsSync(source)) {
25884
+ if (!fs32.existsSync(source)) {
25450
25885
  if (providerToml && !options.dryRun) {
25451
25886
  const changed2 = writeTomlManagedSection(
25452
25887
  destination,
@@ -25461,7 +25896,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
25461
25896
  }
25462
25897
  return skippedMissingSource("mcp", source);
25463
25898
  }
25464
- const sourceMcpJson = JSON.parse(fs30.readFileSync(source, "utf8"));
25899
+ const sourceMcpJson = JSON.parse(fs32.readFileSync(source, "utf8"));
25465
25900
  const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
25466
25901
  const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
25467
25902
  if (options.dryRun) {
@@ -25483,12 +25918,12 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
25483
25918
  if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
25484
25919
  return { component, status: "conflict", path: destination };
25485
25920
  }
25486
- ensureDir(path29.dirname(destination));
25487
- fs30.writeFileSync(destination, content);
25921
+ ensureDir(path31.dirname(destination));
25922
+ fs32.writeFileSync(destination, content);
25488
25923
  return { component, status: "success", path: destination };
25489
25924
  }
25490
25925
  function writeTomlManagedSection(destination, managedContent, logger) {
25491
- const current = fs30.existsSync(destination) ? fs30.readFileSync(destination, "utf8") : "";
25926
+ const current = fs32.existsSync(destination) ? fs32.readFileSync(destination, "utf8") : "";
25492
25927
  const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
25493
25928
  if (isFirstWrite) {
25494
25929
  logger.warn(
@@ -25504,8 +25939,8 @@ ${managedMcpEnd}
25504
25939
  if (current === next.trimStart()) {
25505
25940
  return false;
25506
25941
  }
25507
- ensureDir(path29.dirname(destination));
25508
- fs30.writeFileSync(destination, next.trimStart());
25942
+ ensureDir(path31.dirname(destination));
25943
+ fs32.writeFileSync(destination, next.trimStart());
25509
25944
  return true;
25510
25945
  }
25511
25946
  function removeManagedTomlSection(content) {
@@ -25532,16 +25967,16 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
25532
25967
  backupFile(destination, manifest);
25533
25968
  writeManifest(scopePath, manifest);
25534
25969
  } else {
25535
- fs30.renameSync(destination, `${destination}.bak.${Date.now()}`);
25970
+ fs32.renameSync(destination, `${destination}.bak.${Date.now()}`);
25536
25971
  }
25537
25972
  return true;
25538
25973
  }
25539
- fs30.rmSync(destination, { recursive: true, force: true });
25974
+ fs32.rmSync(destination, { recursive: true, force: true });
25540
25975
  return true;
25541
25976
  }
25542
25977
  function isCompiledCurrent(destination, expectedContent, expectedHash) {
25543
25978
  try {
25544
- const current = fs30.readFileSync(destination, "utf8");
25979
+ const current = fs32.readFileSync(destination, "utf8");
25545
25980
  const marker = extractProvenanceMarker(current);
25546
25981
  return expectedHash ? marker?.hash === expectedHash && marker.target === "codex" && current === expectedContent : current === expectedContent;
25547
25982
  } catch {
@@ -25560,16 +25995,16 @@ function shouldSkipComponent(options, component) {
25560
25995
  }
25561
25996
  function isSymlinkTo(linkPath, source) {
25562
25997
  try {
25563
- return fs30.realpathSync(linkPath) === fs30.realpathSync(source);
25998
+ return fs32.realpathSync(linkPath) === fs32.realpathSync(source);
25564
25999
  } catch {
25565
26000
  return false;
25566
26001
  }
25567
26002
  }
25568
26003
  function readJsonObject3(filePath) {
25569
- if (!fs30.existsSync(filePath)) {
26004
+ if (!fs32.existsSync(filePath)) {
25570
26005
  return {};
25571
26006
  }
25572
- const parsed = JSON.parse(fs30.readFileSync(filePath, "utf8"));
26007
+ const parsed = JSON.parse(fs32.readFileSync(filePath, "utf8"));
25573
26008
  return isRecord4(parsed) ? parsed : {};
25574
26009
  }
25575
26010
  function stringifyJson2(value) {
@@ -25585,16 +26020,16 @@ function hashString(value) {
25585
26020
 
25586
26021
  // src/adapters/copilot.ts
25587
26022
  import crypto6 from "crypto";
25588
- import fs31 from "fs";
25589
- import path31 from "path";
26023
+ import fs33 from "fs";
26024
+ import path33 from "path";
25590
26025
 
25591
26026
  // src/compiler/commands.ts
25592
26027
  var import_yaml9 = __toESM(require_dist(), 1);
25593
- import path30 from "path";
26028
+ import path32 from "path";
25594
26029
  function compileCommandPrompt(sourceFile) {
25595
26030
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
25596
- const relativeSource = `commands/${path30.basename(sourceFile)}`;
25597
- const fields = promptFrontmatter(data, path30.basename(sourceFile, ".md"));
26031
+ const relativeSource = `commands/${path32.basename(sourceFile)}`;
26032
+ const fields = promptFrontmatter(data, path32.basename(sourceFile, ".md"));
25598
26033
  const marker = formatProvenanceMarker(
25599
26034
  "markdown",
25600
26035
  relativeSource,
@@ -25769,13 +26204,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
25769
26204
  }
25770
26205
  function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
25771
26206
  if (!mappings.modelTiers.custom_provider) return;
25772
- const agentsDir = path31.join(sourceRoot, config.source.agents);
25773
- if (!fs31.existsSync(agentsDir)) return;
25774
- for (const agentFile of ts(path31.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()) {
25775
26210
  const { data } = parseMarkdownFrontmatter(agentFile);
25776
26211
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
25777
26212
  if (hasProvider) {
25778
- const basename = path31.basename(agentFile);
26213
+ const basename = path33.basename(agentFile);
25779
26214
  addLoss(lossReport, "copilot", "agents", {
25780
26215
  source: `agents/${basename}`,
25781
26216
  fields: [
@@ -25800,23 +26235,23 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
25800
26235
  logger.verbose(message);
25801
26236
  return [{ component: "instructions", status: "skipped", path: message }];
25802
26237
  }
25803
- const source = path31.resolve(sourceRoot, config.source.instructions);
25804
- if (!fs31.existsSync(source)) {
26238
+ const source = path33.resolve(sourceRoot, config.source.instructions);
26239
+ if (!fs33.existsSync(source)) {
25805
26240
  return [skippedMissingSource2("instructions", source)];
25806
26241
  }
25807
- const rawContent = fs31.readFileSync(source, "utf8");
26242
+ const rawContent = fs33.readFileSync(source, "utf8");
25808
26243
  const contentHash = hashString2(rawContent);
25809
26244
  const marker = formatProvenanceMarker(
25810
26245
  "markdown",
25811
- path31.basename(config.source.instructions),
26246
+ path33.basename(config.source.instructions),
25812
26247
  contentHash,
25813
26248
  "copilot"
25814
26249
  );
25815
26250
  const composedContent = `${marker}
25816
26251
  ${rawContent}`;
25817
26252
  const projectRoot = options.projectRoot ?? process.cwd();
25818
- const agentsMdDest = path31.resolve(projectRoot, "AGENTS.md");
25819
- const mirrorDest = path31.resolve(
26253
+ const agentsMdDest = path33.resolve(projectRoot, "AGENTS.md");
26254
+ const mirrorDest = path33.resolve(
25820
26255
  projectRoot,
25821
26256
  ".github",
25822
26257
  "copilot-instructions.md"
@@ -25870,17 +26305,17 @@ function writeInstructionsFile(component, destination, content, contentHash, con
25870
26305
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
25871
26306
  return { component, status: "conflict", path: destination };
25872
26307
  }
25873
- ensureDir(path31.dirname(destination));
25874
- fs31.writeFileSync(destination, content);
26308
+ ensureDir(path33.dirname(destination));
26309
+ fs33.writeFileSync(destination, content);
25875
26310
  return { component, status: "success", path: destination };
25876
26311
  }
25877
26312
  function hashString2(value) {
25878
26313
  return `sha256:${crypto6.createHash("sha256").update(value).digest("hex")}`;
25879
26314
  }
25880
26315
  function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
25881
- const source = path31.resolve(sourceRoot, config.source.skills);
26316
+ const source = path33.resolve(sourceRoot, config.source.skills);
25882
26317
  const destination = resolveTargetPath(paths.skills);
25883
- if (!fs31.existsSync(source)) {
26318
+ if (!fs33.existsSync(source)) {
25884
26319
  return skippedMissingSource2("skills", source);
25885
26320
  }
25886
26321
  if (options.dryRun) {
@@ -25896,27 +26331,27 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
25896
26331
  };
25897
26332
  }
25898
26333
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
25899
- fs31.unlinkSync(destination);
26334
+ fs33.unlinkSync(destination);
25900
26335
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
25901
26336
  return { component: "skills", status: "conflict", path: destination };
25902
26337
  } else if (artifactClass === "managed-symlink") {
25903
- fs31.unlinkSync(destination);
26338
+ fs33.unlinkSync(destination);
25904
26339
  }
25905
- ensureDir(path31.dirname(destination));
26340
+ ensureDir(path33.dirname(destination));
25906
26341
  createRelativeSymlink(source, destination, "dir");
25907
26342
  return { component: "skills", status: "success", path: destination };
25908
26343
  }
25909
26344
  function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
25910
- const sourceAgentsRoot = path31.join(sourceRoot, config.source.agents);
25911
- if (!fs31.existsSync(sourceAgentsRoot)) {
26345
+ const sourceAgentsRoot = path33.join(sourceRoot, config.source.agents);
26346
+ if (!fs33.existsSync(sourceAgentsRoot)) {
25912
26347
  return [skippedMissingSource2("agents", sourceAgentsRoot)];
25913
26348
  }
25914
- const sourceAgents = ts(path31.join(sourceAgentsRoot, "*.md")).sort();
26349
+ const sourceAgents = ts(path33.join(sourceAgentsRoot, "*.md")).sort();
25915
26350
  const agentsRoot = resolveTargetPath(paths.agents);
25916
26351
  return sourceAgents.map((agentFile) => {
25917
- const destination = path31.join(
26352
+ const destination = path33.join(
25918
26353
  agentsRoot,
25919
- `${path31.basename(agentFile, ".md")}.agent.md`
26354
+ `${path33.basename(agentFile, ".md")}.agent.md`
25920
26355
  );
25921
26356
  const compiled = compileAgent(
25922
26357
  agentFile,
@@ -25944,16 +26379,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
25944
26379
  });
25945
26380
  }
25946
26381
  function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
25947
- const sourceCommandsRoot = path31.join(sourceRoot, config.source.commands);
25948
- if (!fs31.existsSync(sourceCommandsRoot)) {
26382
+ const sourceCommandsRoot = path33.join(sourceRoot, config.source.commands);
26383
+ if (!fs33.existsSync(sourceCommandsRoot)) {
25949
26384
  return [skippedMissingSource2("commands", sourceCommandsRoot)];
25950
26385
  }
25951
- const sourceCommands = ts(path31.join(sourceCommandsRoot, "*.md")).sort();
26386
+ const sourceCommands = ts(path33.join(sourceCommandsRoot, "*.md")).sort();
25952
26387
  const promptsRoot = resolveTargetPath(paths.prompts);
25953
26388
  return sourceCommands.map((commandFile) => {
25954
- const destination = path31.join(
26389
+ const destination = path33.join(
25955
26390
  promptsRoot,
25956
- `${path31.basename(commandFile, ".md")}.prompt.md`
26391
+ `${path33.basename(commandFile, ".md")}.prompt.md`
25957
26392
  );
25958
26393
  const compiled = compileCommandPrompt(commandFile);
25959
26394
  if (options.dryRun) {
@@ -25979,14 +26414,14 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
25979
26414
  function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, logger) {
25980
26415
  const source = resolveHooksSourceFile(sourceRoot, config);
25981
26416
  const sourceLabel = hooksSourceLabel(config);
25982
- const destination = path31.join(
26417
+ const destination = path33.join(
25983
26418
  resolveTargetPath(paths.hooks),
25984
26419
  "tangyr-managed.json"
25985
26420
  );
25986
- if (!fs31.existsSync(source)) {
26421
+ if (!fs33.existsSync(source)) {
25987
26422
  return skippedMissingSource2("hooks", source);
25988
26423
  }
25989
- const sourceHooksJson = JSON.parse(fs31.readFileSync(source, "utf8"));
26424
+ const sourceHooksJson = JSON.parse(fs33.readFileSync(source, "utf8"));
25990
26425
  const compiled = compileHooks(
25991
26426
  sourceHooksJson,
25992
26427
  "copilot",
@@ -26023,10 +26458,10 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger) {
26023
26458
  const source = resolveMcpSourceFile(sourceRoot, config);
26024
26459
  const sourceLabel = mcpSourceLabel(config);
26025
26460
  const destination = resolveTargetPath(paths.mcp_shared_file);
26026
- if (!fs31.existsSync(source)) {
26461
+ if (!fs33.existsSync(source)) {
26027
26462
  return skippedMissingSource2("mcp", source);
26028
26463
  }
26029
- const sourceMcpJson = JSON.parse(fs31.readFileSync(source, "utf8"));
26464
+ const sourceMcpJson = JSON.parse(fs33.readFileSync(source, "utf8"));
26030
26465
  const compiled = compileMcp(
26031
26466
  sourceMcpJson,
26032
26467
  "copilot",
@@ -26056,13 +26491,13 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
26056
26491
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
26057
26492
  return { component, status: "conflict", path: destination };
26058
26493
  }
26059
- ensureDir(path31.dirname(destination));
26060
- fs31.writeFileSync(destination, content);
26494
+ ensureDir(path33.dirname(destination));
26495
+ fs33.writeFileSync(destination, content);
26061
26496
  return { component, status: "success", path: destination };
26062
26497
  }
26063
26498
  function isCompiledCurrent2(destination, expectedContent, expectedHash) {
26064
26499
  try {
26065
- const current = fs31.readFileSync(destination, "utf8");
26500
+ const current = fs33.readFileSync(destination, "utf8");
26066
26501
  const marker = extractProvenanceMarker(current);
26067
26502
  return expectedHash ? marker?.hash === expectedHash && marker.target === "copilot" && current === expectedContent : current === expectedContent;
26068
26503
  } catch {
@@ -26085,11 +26520,11 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
26085
26520
  backupFile(destination, manifest);
26086
26521
  writeManifest(scopePath, manifest);
26087
26522
  } else {
26088
- fs31.renameSync(destination, `${destination}.bak.${Date.now()}`);
26523
+ fs33.renameSync(destination, `${destination}.bak.${Date.now()}`);
26089
26524
  }
26090
26525
  return true;
26091
26526
  }
26092
- fs31.rmSync(destination, { recursive: true, force: true });
26527
+ fs33.rmSync(destination, { recursive: true, force: true });
26093
26528
  return true;
26094
26529
  }
26095
26530
  function shouldSkipComponent2(options, component) {
@@ -26098,12 +26533,12 @@ function shouldSkipComponent2(options, component) {
26098
26533
  function cleanupLegacyAgents(paths, options, logger) {
26099
26534
  const currentAgentsRoot = resolveTargetPath(paths.agents);
26100
26535
  const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
26101
- if (path31.resolve(currentAgentsRoot) === path31.resolve(legacyAgentsRoot)) {
26536
+ if (path33.resolve(currentAgentsRoot) === path33.resolve(legacyAgentsRoot)) {
26102
26537
  return [];
26103
26538
  }
26104
26539
  const outcomes = [];
26105
26540
  for (const filePath of ts(
26106
- path31.join(legacyAgentsRoot, "*.agent.md")
26541
+ path33.join(legacyAgentsRoot, "*.agent.md")
26107
26542
  ).sort()) {
26108
26543
  if (!isCopilotManagedCompiledFile(filePath)) {
26109
26544
  continue;
@@ -26113,14 +26548,14 @@ function cleanupLegacyAgents(paths, options, logger) {
26113
26548
  outcomes.push({ component: "agents", status: "dry-run", path: filePath });
26114
26549
  continue;
26115
26550
  }
26116
- fs31.rmSync(filePath, { force: true });
26551
+ fs33.rmSync(filePath, { force: true });
26117
26552
  outcomes.push({ component: "agents", status: "success", path: filePath });
26118
26553
  }
26119
26554
  return outcomes;
26120
26555
  }
26121
26556
  function isCopilotManagedCompiledFile(filePath) {
26122
26557
  try {
26123
- return extractProvenanceMarker(fs31.readFileSync(filePath, "utf8"))?.target === "copilot";
26558
+ return extractProvenanceMarker(fs33.readFileSync(filePath, "utf8"))?.target === "copilot";
26124
26559
  } catch {
26125
26560
  return false;
26126
26561
  }
@@ -26134,7 +26569,7 @@ function skippedMissingSource2(component, source) {
26134
26569
  }
26135
26570
  function isSymlinkTo2(linkPath, source) {
26136
26571
  try {
26137
- return fs31.realpathSync(linkPath) === fs31.realpathSync(source);
26572
+ return fs33.realpathSync(linkPath) === fs33.realpathSync(source);
26138
26573
  } catch {
26139
26574
  return false;
26140
26575
  }
@@ -26142,8 +26577,8 @@ function isSymlinkTo2(linkPath, source) {
26142
26577
 
26143
26578
  // src/adapters/cursor.ts
26144
26579
  import crypto7 from "crypto";
26145
- import fs32 from "fs";
26146
- import path32 from "path";
26580
+ import fs34 from "fs";
26581
+ import path34 from "path";
26147
26582
  function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
26148
26583
  const scope = options.scope ?? "global";
26149
26584
  const profile = resolveTargetPaths({
@@ -26294,9 +26729,9 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
26294
26729
  return { target: "cursor", outcomes };
26295
26730
  }
26296
26731
  function syncInstructions2(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
26297
- const source = path32.join(sourceRoot, config.source.instructions);
26732
+ const source = path34.join(sourceRoot, config.source.instructions);
26298
26733
  const destination = resolveTargetPath(paths.instructions);
26299
- const baseContent = fs32.existsSync(source) ? fs32.readFileSync(source, "utf8").trim() : "";
26734
+ const baseContent = fs34.existsSync(source) ? fs34.readFileSync(source, "utf8").trim() : "";
26300
26735
  const personaContent = extractPrimaryPersonaContent(
26301
26736
  config,
26302
26737
  sourceRoot,
@@ -26309,7 +26744,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
26309
26744
  ${personaContent}`.trim() : baseContent;
26310
26745
  const marker = formatProvenanceMarker(
26311
26746
  "markdown",
26312
- path32.basename(config.source.instructions),
26747
+ path34.basename(config.source.instructions),
26313
26748
  hashString3(composed),
26314
26749
  "cursor"
26315
26750
  );
@@ -26334,11 +26769,11 @@ ${composed}
26334
26769
  );
26335
26770
  }
26336
26771
  function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
26337
- const agentsDir = path32.join(sourceRoot, config.source.agents);
26338
- if (!fs32.existsSync(agentsDir)) {
26772
+ const agentsDir = path34.join(sourceRoot, config.source.agents);
26773
+ if (!fs34.existsSync(agentsDir)) {
26339
26774
  return null;
26340
26775
  }
26341
- const agentFiles = ts(path32.join(agentsDir, "*.md")).sort();
26776
+ const agentFiles = ts(path34.join(agentsDir, "*.md")).sort();
26342
26777
  if (agentFiles.length === 0) {
26343
26778
  return null;
26344
26779
  }
@@ -26361,7 +26796,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
26361
26796
  return null;
26362
26797
  }
26363
26798
  addLoss(lossReport, "cursor", "instructions", {
26364
- source: `agents/${path32.basename(primaryFile)}`,
26799
+ source: `agents/${path34.basename(primaryFile)}`,
26365
26800
  fields: [
26366
26801
  {
26367
26802
  field: "persona",
@@ -26371,23 +26806,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
26371
26806
  "persona",
26372
26807
  "instructions-shim"
26373
26808
  ),
26374
- detail: `Primary persona from ${path32.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)`
26375
26810
  }
26376
26811
  ]
26377
26812
  });
26378
26813
  return body.trim();
26379
26814
  }
26380
26815
  function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
26381
- const sourceAgentsRoot = path32.join(sourceRoot, config.source.agents);
26382
- if (!fs32.existsSync(sourceAgentsRoot)) {
26816
+ const sourceAgentsRoot = path34.join(sourceRoot, config.source.agents);
26817
+ if (!fs34.existsSync(sourceAgentsRoot)) {
26383
26818
  return [skippedMissingSource3("agents", sourceAgentsRoot)];
26384
26819
  }
26385
- const sourceAgents = ts(path32.join(sourceAgentsRoot, "*.md")).sort();
26820
+ const sourceAgents = ts(path34.join(sourceAgentsRoot, "*.md")).sort();
26386
26821
  const agentsRoot = resolveTargetPath(paths.agents);
26387
26822
  return sourceAgents.map((agentFile) => {
26388
- const destination = path32.join(
26823
+ const destination = path34.join(
26389
26824
  agentsRoot,
26390
- `${path32.basename(agentFile, ".md")}.md`
26825
+ `${path34.basename(agentFile, ".md")}.md`
26391
26826
  );
26392
26827
  let compiled;
26393
26828
  try {
@@ -26428,14 +26863,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
26428
26863
  });
26429
26864
  }
26430
26865
  function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
26431
- const sourceRulesDir = path32.join(sourceRoot, config.source.rules);
26432
- if (!fs32.existsSync(sourceRulesDir)) {
26866
+ const sourceRulesDir = path34.join(sourceRoot, config.source.rules);
26867
+ if (!fs34.existsSync(sourceRulesDir)) {
26433
26868
  return [skippedMissingSource3("rules", sourceRulesDir)];
26434
26869
  }
26435
26870
  const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
26436
26871
  const rulesDir = resolveTargetPath(paths.rules);
26437
26872
  return compiled.dotRulesFiles.map(({ name, content }) => {
26438
- const destination = path32.join(rulesDir, name);
26873
+ const destination = path34.join(rulesDir, name);
26439
26874
  if (options.dryRun) {
26440
26875
  logger.info(`[dry-run] rules: write ${destination}`);
26441
26876
  return {
@@ -26459,17 +26894,17 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
26459
26894
  });
26460
26895
  }
26461
26896
  function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
26462
- const sourceCommandsRoot = path32.join(sourceRoot, config.source.commands);
26463
- if (!fs32.existsSync(sourceCommandsRoot)) {
26897
+ const sourceCommandsRoot = path34.join(sourceRoot, config.source.commands);
26898
+ if (!fs34.existsSync(sourceCommandsRoot)) {
26464
26899
  return [skippedMissingSource3("commands", sourceCommandsRoot)];
26465
26900
  }
26466
- const sourceCommands = ts(path32.join(sourceCommandsRoot, "*.md")).sort();
26901
+ const sourceCommands = ts(path34.join(sourceCommandsRoot, "*.md")).sort();
26467
26902
  const skillsRoot = resolveTargetPath(paths.skills);
26468
26903
  return sourceCommands.map((commandFile) => {
26469
- const baseName = path32.basename(commandFile, ".md");
26470
- const destination = path32.join(skillsRoot, baseName, "SKILL.md");
26471
- const commandContent = fs32.readFileSync(commandFile, "utf8");
26472
- const relativeSource = `commands/${path32.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)}`;
26473
26908
  const marker = formatProvenanceMarker(
26474
26909
  "markdown",
26475
26910
  relativeSource,
@@ -26508,8 +26943,8 @@ ${commandContent.trim()}
26508
26943
  });
26509
26944
  }
26510
26945
  function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
26511
- const source = path32.resolve(sourceRoot, config.source.skills);
26512
- if (!fs32.existsSync(source)) {
26946
+ const source = path34.resolve(sourceRoot, config.source.skills);
26947
+ if (!fs34.existsSync(source)) {
26513
26948
  return skippedMissingSource3(component, source);
26514
26949
  }
26515
26950
  if (options.dryRun) {
@@ -26523,18 +26958,18 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
26523
26958
  return { component, status: "skipped-current", path: destination };
26524
26959
  }
26525
26960
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
26526
- fs32.unlinkSync(destination);
26961
+ fs34.unlinkSync(destination);
26527
26962
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
26528
26963
  return { component, status: "conflict", path: destination };
26529
26964
  } else if (artifactClass === "managed-symlink") {
26530
- fs32.unlinkSync(destination);
26965
+ fs34.unlinkSync(destination);
26531
26966
  }
26532
- ensureDir(path32.dirname(destination));
26967
+ ensureDir(path34.dirname(destination));
26533
26968
  createRelativeSymlink(source, destination, "dir");
26534
26969
  logger.verbose(`Skills: created shared skills symlink ${destination}`);
26535
26970
  return { component, status: "success", path: destination };
26536
26971
  }
26537
- if (fs32.existsSync(destination)) {
26972
+ if (fs34.existsSync(destination)) {
26538
26973
  return { component, status: "skipped-current", path: destination };
26539
26974
  }
26540
26975
  ensureDir(destination);
@@ -26545,7 +26980,7 @@ function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, lo
26545
26980
  const source = resolveHooksSourceFile(sourceRoot, config);
26546
26981
  const sourceLabel = hooksSourceLabel(config);
26547
26982
  const destination = resolveTargetPath(paths.hooks_file);
26548
- const sourceHooksJson = fs32.existsSync(source) ? JSON.parse(fs32.readFileSync(source, "utf8")) : { hooks: {} };
26983
+ const sourceHooksJson = fs34.existsSync(source) ? JSON.parse(fs34.readFileSync(source, "utf8")) : { hooks: {} };
26549
26984
  const compiled = compileHooks(
26550
26985
  sourceHooksJson,
26551
26986
  "cursor",
@@ -26559,18 +26994,18 @@ function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, lo
26559
26994
  }
26560
26995
  const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
26561
26996
  `;
26562
- ensureDir(path32.dirname(destination));
26563
- fs32.writeFileSync(destination, hooksFileContent);
26997
+ ensureDir(path34.dirname(destination));
26998
+ fs34.writeFileSync(destination, hooksFileContent);
26564
26999
  return { component: "hooks", status: "success", path: destination };
26565
27000
  }
26566
27001
  function syncMcp3(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
26567
27002
  const source = resolveMcpSourceFile(sourceRoot, config);
26568
27003
  const sourceLabel = mcpSourceLabel(config);
26569
27004
  const destination = resolveTargetPath(paths.mcp_file);
26570
- if (!fs32.existsSync(source)) {
27005
+ if (!fs34.existsSync(source)) {
26571
27006
  return skippedMissingSource3("mcp", source);
26572
27007
  }
26573
- const sourceMcpJson = JSON.parse(fs32.readFileSync(source, "utf8"));
27008
+ const sourceMcpJson = JSON.parse(fs34.readFileSync(source, "utf8"));
26574
27009
  const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
26575
27010
  if (options.dryRun) {
26576
27011
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -26621,13 +27056,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
26621
27056
  );
26622
27057
  }
26623
27058
  function syncProviderPin(config, sourceRoot, lossReport) {
26624
- const agentsDir = path32.join(sourceRoot, config.source.agents);
26625
- if (!fs32.existsSync(agentsDir)) return;
26626
- for (const agentFile of ts(path32.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()) {
26627
27062
  const { data } = parseMarkdownFrontmatter(agentFile);
26628
27063
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
26629
27064
  if (hasCustomProvider) {
26630
- const relativeSource = `agents/${path32.basename(agentFile)}`;
27065
+ const relativeSource = `agents/${path34.basename(agentFile)}`;
26631
27066
  addLoss(lossReport, "cursor", "agents", {
26632
27067
  source: relativeSource,
26633
27068
  fields: [
@@ -26639,7 +27074,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
26639
27074
  "provider",
26640
27075
  "provider-not-representable"
26641
27076
  ),
26642
- detail: `${path32.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`
26643
27078
  }
26644
27079
  ]
26645
27080
  });
@@ -26654,8 +27089,8 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
26654
27089
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
26655
27090
  return { component, status: "conflict", path: destination };
26656
27091
  }
26657
- ensureDir(path32.dirname(destination));
26658
- fs32.writeFileSync(destination, content);
27092
+ ensureDir(path34.dirname(destination));
27093
+ fs34.writeFileSync(destination, content);
26659
27094
  return { component, status: "success", path: destination };
26660
27095
  }
26661
27096
  function handleConflict3(destination, config, options, logger, manifest, scopePath) {
@@ -26674,16 +27109,16 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
26674
27109
  backupFile(destination, manifest);
26675
27110
  writeManifest(scopePath, manifest);
26676
27111
  } else {
26677
- fs32.renameSync(destination, `${destination}.bak.${Date.now()}`);
27112
+ fs34.renameSync(destination, `${destination}.bak.${Date.now()}`);
26678
27113
  }
26679
27114
  return true;
26680
27115
  }
26681
- fs32.rmSync(destination, { recursive: true, force: true });
27116
+ fs34.rmSync(destination, { recursive: true, force: true });
26682
27117
  return true;
26683
27118
  }
26684
27119
  function isCompiledCurrent3(destination, expectedContent, expectedHash) {
26685
27120
  try {
26686
- const current = fs32.readFileSync(destination, "utf8");
27121
+ const current = fs34.readFileSync(destination, "utf8");
26687
27122
  const marker = extractProvenanceMarker(current);
26688
27123
  return expectedHash ? marker?.hash === expectedHash && marker.target === "cursor" && current === expectedContent : current === expectedContent;
26689
27124
  } catch {
@@ -26702,7 +27137,7 @@ function shouldSkipComponent3(options, component) {
26702
27137
  }
26703
27138
  function isSymlinkTo3(linkPath, source) {
26704
27139
  try {
26705
- return fs32.realpathSync(linkPath) === fs32.realpathSync(source);
27140
+ return fs34.realpathSync(linkPath) === fs34.realpathSync(source);
26706
27141
  } catch {
26707
27142
  return false;
26708
27143
  }
@@ -26713,8 +27148,8 @@ function hashString3(value) {
26713
27148
 
26714
27149
  // src/adapters/cline.ts
26715
27150
  import crypto8 from "crypto";
26716
- import fs33 from "fs";
26717
- import path33 from "path";
27151
+ import fs35 from "fs";
27152
+ import path35 from "path";
26718
27153
  function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
26719
27154
  const scope = options.scope ?? "global";
26720
27155
  const profile = resolveTargetPaths({
@@ -26827,7 +27262,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
26827
27262
  function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
26828
27263
  if (scope === "global" || paths.instructions === null) {
26829
27264
  addLoss(lossReport, "cline", "instructions", {
26830
- source: path33.basename(config.source.instructions),
27265
+ source: path35.basename(config.source.instructions),
26831
27266
  fields: [
26832
27267
  {
26833
27268
  field: "instructions",
@@ -26847,12 +27282,12 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
26847
27282
  path: "cline/global/instructions: no committable global path"
26848
27283
  };
26849
27284
  }
26850
- const source = path33.join(sourceRoot, config.source.instructions);
27285
+ const source = path35.join(sourceRoot, config.source.instructions);
26851
27286
  const destination = resolveTargetPath(paths.instructions);
26852
- const baseContent = fs33.existsSync(source) ? fs33.readFileSync(source, "utf8").trim() : "";
27287
+ const baseContent = fs35.existsSync(source) ? fs35.readFileSync(source, "utf8").trim() : "";
26853
27288
  const marker = formatProvenanceMarker(
26854
27289
  "markdown",
26855
- path33.basename(config.source.instructions),
27290
+ path35.basename(config.source.instructions),
26856
27291
  hashString4(baseContent),
26857
27292
  "cline"
26858
27293
  );
@@ -26877,11 +27312,11 @@ ${baseContent}
26877
27312
  );
26878
27313
  }
26879
27314
  function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
26880
- const sourceAgentsRoot = path33.join(sourceRoot, config.source.agents);
26881
- if (!fs33.existsSync(sourceAgentsRoot)) {
27315
+ const sourceAgentsRoot = path35.join(sourceRoot, config.source.agents);
27316
+ if (!fs35.existsSync(sourceAgentsRoot)) {
26882
27317
  return [skippedMissingSource4("agents", sourceAgentsRoot)];
26883
27318
  }
26884
- const sourceAgents = ts(path33.join(sourceAgentsRoot, "*.md")).sort();
27319
+ const sourceAgents = ts(path35.join(sourceAgentsRoot, "*.md")).sort();
26885
27320
  return sourceAgents.map((agentFile) => {
26886
27321
  compileAgent(agentFile, "cline", mappings, extensions, lossReport);
26887
27322
  if (options.dryRun) {
@@ -26897,14 +27332,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
26897
27332
  });
26898
27333
  }
26899
27334
  function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
26900
- const sourceRulesDir = path33.join(sourceRoot, config.source.rules);
26901
- if (!fs33.existsSync(sourceRulesDir)) {
27335
+ const sourceRulesDir = path35.join(sourceRoot, config.source.rules);
27336
+ if (!fs35.existsSync(sourceRulesDir)) {
26902
27337
  return [skippedMissingSource4("rules", sourceRulesDir)];
26903
27338
  }
26904
27339
  const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
26905
27340
  const rulesDir = resolveTargetPath(paths.rules);
26906
27341
  return compiled.dotRulesFiles.map(({ name, content }) => {
26907
- const destination = path33.join(rulesDir, name);
27342
+ const destination = path35.join(rulesDir, name);
26908
27343
  if (options.dryRun) {
26909
27344
  logger.info(`[dry-run] rules: write ${destination}`);
26910
27345
  return {
@@ -26928,17 +27363,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
26928
27363
  });
26929
27364
  }
26930
27365
  function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
26931
- const sourceCommandsRoot = path33.join(sourceRoot, config.source.commands);
26932
- if (!fs33.existsSync(sourceCommandsRoot)) {
27366
+ const sourceCommandsRoot = path35.join(sourceRoot, config.source.commands);
27367
+ if (!fs35.existsSync(sourceCommandsRoot)) {
26933
27368
  return [skippedMissingSource4("commands", sourceCommandsRoot)];
26934
27369
  }
26935
- const sourceCommands = ts(path33.join(sourceCommandsRoot, "*.md")).sort();
27370
+ const sourceCommands = ts(path35.join(sourceCommandsRoot, "*.md")).sort();
26936
27371
  const workflowsRoot = resolveTargetPath(paths.workflows);
26937
27372
  return sourceCommands.map((commandFile) => {
26938
- const baseName = path33.basename(commandFile);
26939
- const destination = path33.join(workflowsRoot, baseName);
26940
- const commandContent = fs33.readFileSync(commandFile, "utf8");
26941
- const relativeSource = `commands/${path33.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)}`;
26942
27377
  const marker = formatProvenanceMarker(
26943
27378
  "markdown",
26944
27379
  relativeSource,
@@ -26973,9 +27408,9 @@ ${commandContent.trim()}
26973
27408
  });
26974
27409
  }
26975
27410
  function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
26976
- const source = path33.resolve(sourceRoot, config.source.skills);
27411
+ const source = path35.resolve(sourceRoot, config.source.skills);
26977
27412
  const destination = resolveTargetPath(paths.skills);
26978
- if (!fs33.existsSync(source)) {
27413
+ if (!fs35.existsSync(source)) {
26979
27414
  return skippedMissingSource4("skills", source);
26980
27415
  }
26981
27416
  if (options.dryRun) {
@@ -26995,9 +27430,9 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
26995
27430
  return { component: "skills", status: "conflict", path: destination };
26996
27431
  }
26997
27432
  } else if (artifactClass === "managed-symlink") {
26998
- fs33.unlinkSync(destination);
27433
+ fs35.unlinkSync(destination);
26999
27434
  }
27000
- ensureDir(path33.dirname(destination));
27435
+ ensureDir(path35.dirname(destination));
27001
27436
  createRelativeSymlink(source, destination, "dir");
27002
27437
  logger.verbose(`Skills: created Cline skills symlink ${destination}`);
27003
27438
  return { component: "skills", status: "success", path: destination };
@@ -27005,7 +27440,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
27005
27440
  function syncHooks4(config, sourceRoot, mappings, options, lossReport, logger) {
27006
27441
  const source = resolveHooksSourceFile(sourceRoot, config);
27007
27442
  const sourceLabel = hooksSourceLabel(config);
27008
- const sourceHooksJson = fs33.existsSync(source) ? JSON.parse(fs33.readFileSync(source, "utf8")) : { hooks: {} };
27443
+ const sourceHooksJson = fs35.existsSync(source) ? JSON.parse(fs35.readFileSync(source, "utf8")) : { hooks: {} };
27009
27444
  compileHooks(sourceHooksJson, "cline", mappings, lossReport, sourceLabel);
27010
27445
  if (options.dryRun) {
27011
27446
  logger.info(`[dry-run] hooks: record hook-as-plugin loss for ${source}`);
@@ -27020,10 +27455,10 @@ function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manife
27020
27455
  const source = resolveMcpSourceFile(sourceRoot, config);
27021
27456
  const sourceLabel = mcpSourceLabel(config);
27022
27457
  const destination = resolveTargetPath(paths.mcp_file);
27023
- if (!fs33.existsSync(source)) {
27458
+ if (!fs35.existsSync(source)) {
27024
27459
  return skippedMissingSource4("mcp", source);
27025
27460
  }
27026
- const sourceMcpJson = JSON.parse(fs33.readFileSync(source, "utf8"));
27461
+ const sourceMcpJson = JSON.parse(fs35.readFileSync(source, "utf8"));
27027
27462
  const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
27028
27463
  if (options.dryRun) {
27029
27464
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -27066,11 +27501,11 @@ function syncSettings(lossReport) {
27066
27501
  };
27067
27502
  }
27068
27503
  function syncProviderAndModel(config, sourceRoot, lossReport) {
27069
- const agentsDir = path33.join(sourceRoot, config.source.agents);
27070
- if (!fs33.existsSync(agentsDir)) return;
27071
- for (const agentFile of ts(path33.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()) {
27072
27507
  const { data } = parseMarkdownFrontmatter(agentFile);
27073
- const relativeSource = `agents/${path33.basename(agentFile)}`;
27508
+ const relativeSource = `agents/${path35.basename(agentFile)}`;
27074
27509
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
27075
27510
  if (hasCustomProvider) {
27076
27511
  addLoss(lossReport, "cline", "agents", {
@@ -27084,7 +27519,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
27084
27519
  "provider",
27085
27520
  "provider-not-representable"
27086
27521
  ),
27087
- detail: `${path33.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.`
27088
27523
  }
27089
27524
  ]
27090
27525
  });
@@ -27102,7 +27537,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
27102
27537
  "model",
27103
27538
  "model-not-representable"
27104
27539
  ),
27105
- detail: `${path33.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.`
27106
27541
  }
27107
27542
  ]
27108
27543
  });
@@ -27117,8 +27552,8 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
27117
27552
  if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
27118
27553
  return { component, status: "conflict", path: destination };
27119
27554
  }
27120
- ensureDir(path33.dirname(destination));
27121
- fs33.writeFileSync(destination, content);
27555
+ ensureDir(path35.dirname(destination));
27556
+ fs35.writeFileSync(destination, content);
27122
27557
  return { component, status: "success", path: destination };
27123
27558
  }
27124
27559
  function handleConflict4(destination, config, options, logger, manifest, scopePath) {
@@ -27137,16 +27572,16 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
27137
27572
  backupFile(destination, manifest);
27138
27573
  writeManifest(scopePath, manifest);
27139
27574
  } else {
27140
- fs33.renameSync(destination, `${destination}.bak.${Date.now()}`);
27575
+ fs35.renameSync(destination, `${destination}.bak.${Date.now()}`);
27141
27576
  }
27142
27577
  return true;
27143
27578
  }
27144
- fs33.rmSync(destination, { recursive: true, force: true });
27579
+ fs35.rmSync(destination, { recursive: true, force: true });
27145
27580
  return true;
27146
27581
  }
27147
27582
  function isCompiledCurrent4(destination, expectedContent, expectedHash) {
27148
27583
  try {
27149
- const current = fs33.readFileSync(destination, "utf8");
27584
+ const current = fs35.readFileSync(destination, "utf8");
27150
27585
  const marker = extractProvenanceMarker(current);
27151
27586
  return expectedHash ? marker?.hash === expectedHash && marker.target === "cline" && current === expectedContent : current === expectedContent;
27152
27587
  } catch {
@@ -27165,7 +27600,7 @@ function shouldSkipComponent4(options, component) {
27165
27600
  }
27166
27601
  function isSymlinkTo4(linkPath, source) {
27167
27602
  try {
27168
- return fs33.realpathSync(linkPath) === fs33.realpathSync(source);
27603
+ return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
27169
27604
  } catch {
27170
27605
  return false;
27171
27606
  }
@@ -27176,9 +27611,9 @@ function hashString4(value) {
27176
27611
 
27177
27612
  // src/adapters/opencode.ts
27178
27613
  import crypto9 from "crypto";
27179
- import fs34 from "fs";
27614
+ import fs36 from "fs";
27180
27615
  import os6 from "os";
27181
- import path34 from "path";
27616
+ import path36 from "path";
27182
27617
  var import_yaml10 = __toESM(require_dist(), 1);
27183
27618
  function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
27184
27619
  const scope = options.scope ?? "global";
@@ -27196,7 +27631,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
27196
27631
  config_doc: profile.config_doc
27197
27632
  };
27198
27633
  const rules = compileRules(
27199
- path34.join(sourceRoot, config.source.rules),
27634
+ path36.join(sourceRoot, config.source.rules),
27200
27635
  "opencode",
27201
27636
  mappings,
27202
27637
  lossReport
@@ -27298,16 +27733,16 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
27298
27733
  return { target: "opencode", outcomes };
27299
27734
  }
27300
27735
  function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
27301
- const source = path34.join(sourceRoot, config.source.instructions);
27736
+ const source = path36.join(sourceRoot, config.source.instructions);
27302
27737
  const destination = resolveTargetPath(paths.instructions);
27303
- const baseContent = fs34.existsSync(source) ? fs34.readFileSync(source, "utf8").trim() : "";
27738
+ const baseContent = fs36.existsSync(source) ? fs36.readFileSync(source, "utf8").trim() : "";
27304
27739
  const composed = agentsAppendix ? `${baseContent}
27305
27740
 
27306
27741
  --- tangyr managed rules ---
27307
27742
  ${agentsAppendix}`.trim() : baseContent;
27308
27743
  const marker = formatProvenanceMarker(
27309
27744
  "markdown",
27310
- path34.basename(config.source.instructions),
27745
+ path36.basename(config.source.instructions),
27311
27746
  hashString5(composed),
27312
27747
  "opencode"
27313
27748
  );
@@ -27334,16 +27769,16 @@ ${composed}
27334
27769
  );
27335
27770
  }
27336
27771
  function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
27337
- const sourceAgentsRoot = path34.join(sourceRoot, config.source.agents);
27338
- if (!fs34.existsSync(sourceAgentsRoot)) {
27772
+ const sourceAgentsRoot = path36.join(sourceRoot, config.source.agents);
27773
+ if (!fs36.existsSync(sourceAgentsRoot)) {
27339
27774
  return [skippedMissingSource5("agents", sourceAgentsRoot)];
27340
27775
  }
27341
- const sourceAgents = ts(path34.join(sourceAgentsRoot, "*.md")).sort();
27776
+ const sourceAgents = ts(path36.join(sourceAgentsRoot, "*.md")).sort();
27342
27777
  const agentsRoot = resolveTargetPath(paths.agents);
27343
27778
  return sourceAgents.map((agentFile) => {
27344
- const destination = path34.join(
27779
+ const destination = path36.join(
27345
27780
  agentsRoot,
27346
- `${path34.basename(agentFile, ".md")}.md`
27781
+ `${path36.basename(agentFile, ".md")}.md`
27347
27782
  );
27348
27783
  let compiled;
27349
27784
  try {
@@ -27407,11 +27842,11 @@ function applyProviderModelBinding(compiled, mappings) {
27407
27842
  return `${before}${(0, import_yaml10.stringify)(fields).trim()}${after}`;
27408
27843
  }
27409
27844
  function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
27410
- const sourceCommandsRoot = path34.join(sourceRoot, config.source.commands);
27411
- if (!fs34.existsSync(sourceCommandsRoot)) {
27845
+ const sourceCommandsRoot = path36.join(sourceRoot, config.source.commands);
27846
+ if (!fs36.existsSync(sourceCommandsRoot)) {
27412
27847
  return [skippedMissingSource5("commands", sourceCommandsRoot)];
27413
27848
  }
27414
- const sourceCommands = ts(path34.join(sourceCommandsRoot, "*.md")).sort();
27849
+ const sourceCommands = ts(path36.join(sourceCommandsRoot, "*.md")).sort();
27415
27850
  const commandsRoot = resolveTargetPath(paths.commands);
27416
27851
  return sourceCommands.map((commandFile) => {
27417
27852
  const { data, body } = parseCommandFile(commandFile);
@@ -27425,7 +27860,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
27425
27860
  if (typeof data.model === "string") {
27426
27861
  frontmatter.model = data.model;
27427
27862
  }
27428
- const relativeSource = `commands/${path34.basename(commandFile)}`;
27863
+ const relativeSource = `commands/${path36.basename(commandFile)}`;
27429
27864
  const marker = formatProvenanceMarker(
27430
27865
  "markdown",
27431
27866
  relativeSource,
@@ -27441,9 +27876,9 @@ ${body.trimEnd()}
27441
27876
  ` : `${marker}
27442
27877
  ${body.trimEnd()}
27443
27878
  `;
27444
- const destination = path34.join(
27879
+ const destination = path36.join(
27445
27880
  commandsRoot,
27446
- `${path34.basename(commandFile, ".md")}.md`
27881
+ `${path36.basename(commandFile, ".md")}.md`
27447
27882
  );
27448
27883
  if (options.dryRun) {
27449
27884
  logger.info(
@@ -27470,8 +27905,8 @@ ${body.trimEnd()}
27470
27905
  });
27471
27906
  }
27472
27907
  function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
27473
- const source = path34.resolve(sourceRoot, config.source.skills);
27474
- if (!fs34.existsSync(source)) {
27908
+ const source = path36.resolve(sourceRoot, config.source.skills);
27909
+ if (!fs36.existsSync(source)) {
27475
27910
  return skippedMissingSource5(component, source);
27476
27911
  }
27477
27912
  if (options.dryRun) {
@@ -27483,13 +27918,13 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
27483
27918
  return { component, status: "skipped-current", path: destination };
27484
27919
  }
27485
27920
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
27486
- fs34.unlinkSync(destination);
27921
+ fs36.unlinkSync(destination);
27487
27922
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
27488
27923
  return { component, status: "conflict", path: destination };
27489
27924
  } else if (artifactClass === "managed-symlink") {
27490
- fs34.unlinkSync(destination);
27925
+ fs36.unlinkSync(destination);
27491
27926
  }
27492
- ensureDir(path34.dirname(destination));
27927
+ ensureDir(path36.dirname(destination));
27493
27928
  createRelativeSymlink(source, destination, "dir");
27494
27929
  logger.verbose(`Skills: created skills path ${destination}`);
27495
27930
  return { component, status: "success", path: destination };
@@ -27498,13 +27933,13 @@ function syncMcp5(config, sourceRoot, paths, mappings, options, lossReport, logg
27498
27933
  const source = resolveMcpSourceFile(sourceRoot, config);
27499
27934
  const sourceLabel = mcpSourceLabel(config);
27500
27935
  const destination = resolveTargetPath(paths.config_doc);
27501
- if (!fs34.existsSync(source)) {
27936
+ if (!fs36.existsSync(source)) {
27502
27937
  if (!options.dryRun) {
27503
27938
  syncConfigDoc(paths, {}, lossReport, {}, mappings);
27504
27939
  }
27505
27940
  return skippedMissingSource5("mcp", source);
27506
27941
  }
27507
- const sourceMcpJson = JSON.parse(fs34.readFileSync(source, "utf8"));
27942
+ const sourceMcpJson = JSON.parse(fs36.readFileSync(source, "utf8"));
27508
27943
  const mcpJson = compileMcp(
27509
27944
  sourceMcpJson,
27510
27945
  "opencode",
@@ -27535,7 +27970,7 @@ function syncPermissions2(config, _sourceRoot, paths, options, lossReport, logge
27535
27970
  function syncHooks5(config, sourceRoot, mappings, options, lossReport) {
27536
27971
  const source = resolveHooksSourceFile(sourceRoot, config);
27537
27972
  const sourceLabel = hooksSourceLabel(config);
27538
- const sourceHooksJson = fs34.existsSync(source) ? JSON.parse(fs34.readFileSync(source, "utf8")) : { hooks: {} };
27973
+ const sourceHooksJson = fs36.existsSync(source) ? JSON.parse(fs36.readFileSync(source, "utf8")) : { hooks: {} };
27539
27974
  compileHooks(sourceHooksJson, "opencode", mappings, lossReport, sourceLabel);
27540
27975
  const message = "hooks: Skip \u2014 OpenCode exposes hooks only as plugin code (hook-as-plugin loss recorded)";
27541
27976
  return { component: "hooks", status: "skipped", path: message };
@@ -27569,9 +28004,9 @@ function syncProviderBlock(mappings) {
27569
28004
  function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
27570
28005
  const destination = resolveTargetPath(paths.config_doc);
27571
28006
  let existing = {};
27572
- if (fs34.existsSync(destination)) {
28007
+ if (fs36.existsSync(destination)) {
27573
28008
  try {
27574
- existing = JSON.parse(fs34.readFileSync(destination, "utf8"));
28009
+ existing = JSON.parse(fs36.readFileSync(destination, "utf8"));
27575
28010
  } catch {
27576
28011
  existing = {};
27577
28012
  }
@@ -27596,8 +28031,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
27596
28031
  };
27597
28032
  }
27598
28033
  }
27599
- ensureDir(path34.dirname(destination));
27600
- fs34.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
28034
+ ensureDir(path36.dirname(destination));
28035
+ fs36.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
27601
28036
  `);
27602
28037
  }
27603
28038
  function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
@@ -27608,8 +28043,8 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
27608
28043
  if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
27609
28044
  return { component, status: "conflict", path: destination };
27610
28045
  }
27611
- ensureDir(path34.dirname(destination));
27612
- fs34.writeFileSync(destination, content);
28046
+ ensureDir(path36.dirname(destination));
28047
+ fs36.writeFileSync(destination, content);
27613
28048
  return { component, status: "success", path: destination };
27614
28049
  }
27615
28050
  function handleConflict5(destination, config, options, logger, manifest, scopePath) {
@@ -27628,16 +28063,16 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
27628
28063
  backupFile(destination, manifest);
27629
28064
  writeManifest(scopePath, manifest);
27630
28065
  } else {
27631
- fs34.renameSync(destination, `${destination}.bak.${Date.now()}`);
28066
+ fs36.renameSync(destination, `${destination}.bak.${Date.now()}`);
27632
28067
  }
27633
28068
  return true;
27634
28069
  }
27635
- fs34.rmSync(destination, { recursive: true, force: true });
28070
+ fs36.rmSync(destination, { recursive: true, force: true });
27636
28071
  return true;
27637
28072
  }
27638
28073
  function isCompiledCurrent5(destination, expectedContent, expectedHash) {
27639
28074
  try {
27640
- const current = fs34.readFileSync(destination, "utf8");
28075
+ const current = fs36.readFileSync(destination, "utf8");
27641
28076
  const marker = extractProvenanceMarker(current);
27642
28077
  return expectedHash ? marker?.hash === expectedHash && marker.target === "opencode" && current === expectedContent : current === expectedContent;
27643
28078
  } catch {
@@ -27656,7 +28091,7 @@ function shouldSkipComponent5(options, component) {
27656
28091
  }
27657
28092
  function isSymlinkTo5(linkPath, source) {
27658
28093
  try {
27659
- return fs34.realpathSync(linkPath) === fs34.realpathSync(source);
28094
+ return fs36.realpathSync(linkPath) === fs36.realpathSync(source);
27660
28095
  } catch {
27661
28096
  return false;
27662
28097
  }
@@ -27665,7 +28100,7 @@ function hashString5(value) {
27665
28100
  return `sha256:${crypto9.createHash("sha256").update(value).digest("hex")}`;
27666
28101
  }
27667
28102
  function parseCommandFile(commandFile) {
27668
- const content = fs34.readFileSync(commandFile, "utf8");
28103
+ const content = fs36.readFileSync(commandFile, "utf8");
27669
28104
  if (!content.startsWith("---\n")) {
27670
28105
  return { data: {}, body: content };
27671
28106
  }
@@ -27685,10 +28120,10 @@ function parseCommandFile(commandFile) {
27685
28120
  // src/commands/install.ts
27686
28121
  function isBackupableFile(targetPath) {
27687
28122
  try {
27688
- const lstat = fs35.lstatSync(targetPath);
28123
+ const lstat = fs37.lstatSync(targetPath);
27689
28124
  if (lstat.isDirectory()) return false;
27690
28125
  if (lstat.isSymbolicLink()) {
27691
- const stat = fs35.statSync(targetPath);
28126
+ const stat = fs37.statSync(targetPath);
27692
28127
  return stat.isFile();
27693
28128
  }
27694
28129
  return lstat.isFile();
@@ -27698,10 +28133,10 @@ function isBackupableFile(targetPath) {
27698
28133
  }
27699
28134
  function backupConflictingTarget(targetPath, scopePath) {
27700
28135
  const ts2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/gu, "").replace("T", "T").replace(/\.\d+Z$/u, "Z");
27701
- const relativeToRoot = path35.relative("/", targetPath).replace(/^\.\.\/+/gu, "");
27702
- const backupPath = path35.join(scopePath, "backups", ts2, relativeToRoot);
27703
- fs35.mkdirSync(path35.dirname(backupPath), { recursive: true });
27704
- fs35.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);
27705
28140
  return backupPath;
27706
28141
  }
27707
28142
  async function runInstallCommand(options, logger) {
@@ -27730,7 +28165,7 @@ async function runInstallCommand(options, logger) {
27730
28165
  );
27731
28166
  }
27732
28167
  const kitName = resolvedKitName ?? config.kit;
27733
- const kitPath = kitPathOverride ?? (options.kitPath ? path35.resolve(options.kitPath) : config.kitPath);
28168
+ const kitPath = kitPathOverride ?? (options.kitPath ? path37.resolve(options.kitPath) : config.kitPath);
27734
28169
  if (!kitName && !kitPath) {
27735
28170
  logger.error(
27736
28171
  "No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
@@ -27871,7 +28306,7 @@ ACCEPTED CONFLICTS (backup-and-replace applied to ${conflictingFindings.length}
27871
28306
  logger.info(` source: ${finding.tool}`);
27872
28307
  logger.info(` action: backup-and-replace`);
27873
28308
  logger.info(` backup: ${backupLocation}`);
27874
- } else if (fs35.existsSync(finding.path)) {
28309
+ } else if (fs37.existsSync(finding.path)) {
27875
28310
  logger.info(` - ${finding.path}`);
27876
28311
  logger.info(` source: ${finding.tool}`);
27877
28312
  logger.info(
@@ -27982,7 +28417,7 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
27982
28417
  writeManifest(scopePath, manifest);
27983
28418
  logger.info(`
27984
28419
  Installation complete: ${installedCount} files installed.`);
27985
- logger.info(`Manifest written to ${path35.join(scopePath, "manifest.json")}`);
28420
+ logger.info(`Manifest written to ${path37.join(scopePath, "manifest.json")}`);
27986
28421
  logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
27987
28422
  logger.info(`Scope: ${scope}`);
27988
28423
  logger.info(`Tools: ${tools.join(", ")}`);
@@ -28124,13 +28559,13 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
28124
28559
  logger.verbose(` skipped (operator choice): ${placement.destination}`);
28125
28560
  continue;
28126
28561
  }
28127
- const destDir = path35.dirname(placement.destination);
28128
- fs35.mkdirSync(destDir, { recursive: true });
28562
+ const destDir = path37.dirname(placement.destination);
28563
+ fs37.mkdirSync(destDir, { recursive: true });
28129
28564
  if (placement.type === "symlink") {
28130
- if (fs35.existsSync(placement.destination) || isSymlink2(placement.destination)) {
28565
+ if (fs37.existsSync(placement.destination) || isSymlink2(placement.destination)) {
28131
28566
  removeManagedPath(placement.destination);
28132
28567
  }
28133
- fs35.symlinkSync(
28568
+ fs37.symlinkSync(
28134
28569
  placement.source,
28135
28570
  placement.destination,
28136
28571
  placement.isDir ? "dir" : "file"
@@ -28139,12 +28574,12 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
28139
28574
  ` symlink: ${placement.source} \u2192 ${placement.destination}`
28140
28575
  );
28141
28576
  } else {
28142
- fs35.copyFileSync(placement.source, placement.destination);
28577
+ fs37.copyFileSync(placement.source, placement.destination);
28143
28578
  logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
28144
28579
  }
28145
28580
  addArtifactToManifest(manifest, {
28146
28581
  relativePath: placement.manifestKey,
28147
- hash: fs35.statSync(placement.source).isDirectory() ? `dir:${placement.source}` : computeSourceHash(placement.source),
28582
+ hash: fs37.statSync(placement.source).isDirectory() ? `dir:${placement.source}` : computeSourceHash(placement.source),
28148
28583
  origin: "tangyr-managed"
28149
28584
  });
28150
28585
  count++;
@@ -28391,11 +28826,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28391
28826
  if (outcome.path === mcpFile2) {
28392
28827
  return "cline/mcp.json";
28393
28828
  }
28394
- if (outcome.path.startsWith(`${workflowsRoot}${path35.sep}`)) {
28395
- return `cline/workflows/${path35.basename(outcome.path)}`;
28829
+ if (outcome.path.startsWith(`${workflowsRoot}${path37.sep}`)) {
28830
+ return `cline/workflows/${path37.basename(outcome.path)}`;
28396
28831
  }
28397
- if (outcome.path.startsWith(`${rulesRoot2}${path35.sep}`)) {
28398
- return `cline/rules/${path35.basename(outcome.path)}`;
28832
+ if (outcome.path.startsWith(`${rulesRoot2}${path37.sep}`)) {
28833
+ return `cline/rules/${path37.basename(outcome.path)}`;
28399
28834
  }
28400
28835
  return null;
28401
28836
  }
@@ -28431,14 +28866,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28431
28866
  if (outcome.path === permissionsFile) {
28432
28867
  return "cursor/permissions.json";
28433
28868
  }
28434
- if (outcome.path.startsWith(`${agentsRoot2}${path35.sep}`)) {
28435
- return `cursor/agents/${path35.basename(outcome.path)}`;
28869
+ if (outcome.path.startsWith(`${agentsRoot2}${path37.sep}`)) {
28870
+ return `cursor/agents/${path37.basename(outcome.path)}`;
28436
28871
  }
28437
- if (outcome.path.startsWith(`${rulesRoot2}${path35.sep}`)) {
28438
- return `cursor/rules/${path35.basename(outcome.path)}`;
28872
+ if (outcome.path.startsWith(`${rulesRoot2}${path37.sep}`)) {
28873
+ return `cursor/rules/${path37.basename(outcome.path)}`;
28439
28874
  }
28440
- if (outcome.path.startsWith(`${skillsRoot2}${path35.sep}`)) {
28441
- const rel = path35.relative(skillsRoot2, outcome.path);
28875
+ if (outcome.path.startsWith(`${skillsRoot2}${path37.sep}`)) {
28876
+ const rel = path37.relative(skillsRoot2, outcome.path);
28442
28877
  return `cursor/skills/${rel}`;
28443
28878
  }
28444
28879
  return null;
@@ -28464,14 +28899,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28464
28899
  if (outcome.path === skillsSharedRoot) {
28465
28900
  return "opencode/skills_shared";
28466
28901
  }
28467
- if (outcome.path.startsWith(`${agentsRoot2}${path35.sep}`)) {
28468
- return `opencode/agents/${path35.basename(outcome.path)}`;
28902
+ if (outcome.path.startsWith(`${agentsRoot2}${path37.sep}`)) {
28903
+ return `opencode/agents/${path37.basename(outcome.path)}`;
28469
28904
  }
28470
- if (outcome.path.startsWith(`${commandsRoot}${path35.sep}`)) {
28471
- return `opencode/commands/${path35.basename(outcome.path)}`;
28905
+ if (outcome.path.startsWith(`${commandsRoot}${path37.sep}`)) {
28906
+ return `opencode/commands/${path37.basename(outcome.path)}`;
28472
28907
  }
28473
28908
  if (outcome.path === configDocFile) {
28474
- return `opencode/${path35.basename(outcome.path)}`;
28909
+ return `opencode/${path37.basename(outcome.path)}`;
28475
28910
  }
28476
28911
  return null;
28477
28912
  }
@@ -28485,17 +28920,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28485
28920
  if (outcome.path === skillsRoot2) {
28486
28921
  return "copilot/skills";
28487
28922
  }
28488
- if (outcome.path.startsWith(`${agentsRoot2}${path35.sep}`)) {
28489
- return `copilot/agents/${path35.basename(outcome.path)}`;
28923
+ if (outcome.path.startsWith(`${agentsRoot2}${path37.sep}`)) {
28924
+ return `copilot/agents/${path37.basename(outcome.path)}`;
28490
28925
  }
28491
- if (outcome.path.startsWith(`${promptsRoot}${path35.sep}`)) {
28492
- return `copilot/prompts/${path35.basename(outcome.path)}`;
28926
+ if (outcome.path.startsWith(`${promptsRoot}${path37.sep}`)) {
28927
+ return `copilot/prompts/${path37.basename(outcome.path)}`;
28493
28928
  }
28494
- if (outcome.path.startsWith(`${hooksRoot}${path35.sep}`)) {
28495
- return `copilot/hooks/${path35.basename(outcome.path)}`;
28929
+ if (outcome.path.startsWith(`${hooksRoot}${path37.sep}`)) {
28930
+ return `copilot/hooks/${path37.basename(outcome.path)}`;
28496
28931
  }
28497
28932
  if (outcome.path === mcpFile2) {
28498
- return `copilot/${path35.basename(outcome.path)}`;
28933
+ return `copilot/${path37.basename(outcome.path)}`;
28499
28934
  }
28500
28935
  return null;
28501
28936
  }
@@ -28511,17 +28946,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
28511
28946
  if (outcome.path === skillsRoot) {
28512
28947
  return "codex/skills";
28513
28948
  }
28514
- if (outcome.path.startsWith(`${agentsRoot}${path35.sep}`)) {
28515
- return `codex/agents/${path35.basename(outcome.path)}`;
28949
+ if (outcome.path.startsWith(`${agentsRoot}${path37.sep}`)) {
28950
+ return `codex/agents/${path37.basename(outcome.path)}`;
28516
28951
  }
28517
- if (outcome.path.startsWith(`${rulesRoot}${path35.sep}`)) {
28518
- return `codex/rules/${path35.basename(outcome.path)}`;
28952
+ if (outcome.path.startsWith(`${rulesRoot}${path37.sep}`)) {
28953
+ return `codex/rules/${path37.basename(outcome.path)}`;
28519
28954
  }
28520
28955
  if (outcome.path === hooksFile) {
28521
- return `codex/${path35.basename(outcome.path)}`;
28956
+ return `codex/${path37.basename(outcome.path)}`;
28522
28957
  }
28523
28958
  if (outcome.path === mcpFile) {
28524
- return `codex/${path35.basename(outcome.path)}`;
28959
+ return `codex/${path37.basename(outcome.path)}`;
28525
28960
  }
28526
28961
  return null;
28527
28962
  }
@@ -28556,8 +28991,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
28556
28991
  };
28557
28992
  }
28558
28993
  const placements = [];
28559
- const claudeMd = path35.join(kitInfo.path, "CLAUDE.md");
28560
- if (fs35.existsSync(claudeMd)) {
28994
+ const claudeMd = path37.join(kitInfo.path, "CLAUDE.md");
28995
+ if (fs37.existsSync(claudeMd)) {
28561
28996
  placements.push({
28562
28997
  source: claudeMd,
28563
28998
  destination: resolvedPaths.instructions,
@@ -28573,8 +29008,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
28573
29008
  rules: resolvedPaths.rules
28574
29009
  };
28575
29010
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
28576
- const componentDir = path35.join(kitInfo.path, component);
28577
- if (fs35.existsSync(componentDir) && fs35.statSync(componentDir).isDirectory()) {
29011
+ const componentDir = path37.join(kitInfo.path, component);
29012
+ if (fs37.existsSync(componentDir) && fs37.statSync(componentDir).isDirectory()) {
28578
29013
  placements.push({
28579
29014
  source: componentDir,
28580
29015
  destination: targetPath,
@@ -28588,8 +29023,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
28588
29023
  }
28589
29024
  function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
28590
29025
  const placements = [];
28591
- const claudeMd = path35.join(kitInfo.path, "CLAUDE.md");
28592
- if (fs35.existsSync(claudeMd)) {
29026
+ const claudeMd = path37.join(kitInfo.path, "CLAUDE.md");
29027
+ if (fs37.existsSync(claudeMd)) {
28593
29028
  placements.push({
28594
29029
  source: claudeMd,
28595
29030
  destination: profile.instructions,
@@ -28605,8 +29040,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
28605
29040
  rules: profile.rules
28606
29041
  };
28607
29042
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
28608
- const componentDir = path35.join(kitInfo.path, component);
28609
- if (fs35.existsSync(componentDir) && fs35.statSync(componentDir).isDirectory()) {
29043
+ const componentDir = path37.join(kitInfo.path, component);
29044
+ if (fs37.existsSync(componentDir) && fs37.statSync(componentDir).isDirectory()) {
28610
29045
  placements.push({
28611
29046
  source: componentDir,
28612
29047
  destination: targetPath,
@@ -28620,8 +29055,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
28620
29055
  }
28621
29056
  function collectAllFiles(kitInfo) {
28622
29057
  const files = /* @__PURE__ */ new Map();
28623
- const claudeMd = path35.join(kitInfo.path, "CLAUDE.md");
28624
- if (fs35.existsSync(claudeMd)) {
29058
+ const claudeMd = path37.join(kitInfo.path, "CLAUDE.md");
29059
+ if (fs37.existsSync(claudeMd)) {
28625
29060
  files.set("CLAUDE.md", claudeMd);
28626
29061
  }
28627
29062
  for (const [component, reconciliation] of Object.entries(
@@ -28631,15 +29066,15 @@ function collectAllFiles(kitInfo) {
28631
29066
  const missingSet = new Set(reconciliation.missing);
28632
29067
  for (const entry of reconciliation.declared) {
28633
29068
  if (missingSet.has(entry)) continue;
28634
- const relPath = isSkills ? path35.join(component, entry) : path35.join(component, `${entry}.md`);
28635
- files.set(relPath, path35.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));
28636
29071
  }
28637
29072
  }
28638
29073
  return files;
28639
29074
  }
28640
29075
  function isSymlink2(p) {
28641
29076
  try {
28642
- return fs35.lstatSync(p).isSymbolicLink();
29077
+ return fs37.lstatSync(p).isSymbolicLink();
28643
29078
  } catch {
28644
29079
  return false;
28645
29080
  }
@@ -28684,14 +29119,14 @@ async function runKitUpdateCommand(options, logger) {
28684
29119
  }
28685
29120
 
28686
29121
  // src/commands/list.ts
28687
- import path36 from "path";
29122
+ import path38 from "path";
28688
29123
  function runListCommand(options, logger) {
28689
29124
  let searchPaths = [];
28690
- let directKitPath = options.kitPath ? path36.resolve(options.kitPath) : void 0;
29125
+ let directKitPath = options.kitPath ? path38.resolve(options.kitPath) : void 0;
28691
29126
  try {
28692
29127
  const { config, configDir } = resolveConfig(options.config);
28693
29128
  searchPaths = config.kitSearchPaths ?? [
28694
- path36.join(configDir, "operating-kits")
29129
+ path38.join(configDir, "operating-kits")
28695
29130
  ];
28696
29131
  directKitPath = directKitPath ?? config.kitPath;
28697
29132
  } catch (err) {
@@ -28766,7 +29201,7 @@ function withDirectKit(kits, directKitPath) {
28766
29201
  return kits;
28767
29202
  }
28768
29203
  const directKit = loadKit(directKitPath);
28769
- if (kits.some((kit) => path36.resolve(kit.path) === directKit.path)) {
29204
+ if (kits.some((kit) => path38.resolve(kit.path) === directKit.path)) {
28770
29205
  return kits;
28771
29206
  }
28772
29207
  return [...kits, directKit];
@@ -28774,12 +29209,12 @@ function withDirectKit(kits, directKitPath) {
28774
29209
 
28775
29210
  // src/commands/probe.ts
28776
29211
  import { spawnSync as spawnSync2 } from "child_process";
28777
- import fs36 from "fs";
28778
- import path37 from "path";
29212
+ import fs38 from "fs";
29213
+ import path39 from "path";
28779
29214
  function runProbeCommand(options, logger) {
28780
29215
  const { config, configDir, sourceRoot } = resolveRuntime(options, import.meta.url);
28781
29216
  const platformPaths = readYamlObject(
28782
- path37.join(
29217
+ path39.join(
28783
29218
  resolveConfiguredPath(config.mappings, configDir, sourceRoot, "mappings"),
28784
29219
  "platform-paths.yaml"
28785
29220
  )
@@ -28813,12 +29248,12 @@ function toProbeRow(target, key, rawPath) {
28813
29248
  const resolved = resolveTargetPath(rawPath);
28814
29249
  let accessible = false;
28815
29250
  try {
28816
- fs36.accessSync(resolved);
29251
+ fs38.accessSync(resolved);
28817
29252
  accessible = true;
28818
29253
  } catch {
28819
29254
  accessible = false;
28820
29255
  }
28821
- return { target, key, path: resolved, exists: fs36.existsSync(resolved), accessible };
29256
+ return { target, key, path: resolved, exists: fs38.existsSync(resolved), accessible };
28822
29257
  }
28823
29258
  function codexRuntimeProbeRows() {
28824
29259
  const rows = commandProbeRows("codex", "binary", process.platform === "win32" ? "where.exe" : "which", ["codex"]);
@@ -28829,7 +29264,7 @@ function codexRuntimeProbeRows() {
28829
29264
  ["binary_snap", "/snap/bin/codex"],
28830
29265
  ["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
28831
29266
  ]) {
28832
- if (fs36.existsSync(candidatePath)) {
29267
+ if (fs38.existsSync(candidatePath)) {
28833
29268
  rows.push(toProbeRow("codex", key, candidatePath));
28834
29269
  }
28835
29270
  }
@@ -28845,8 +29280,8 @@ function commandProbeRows(target, key, command, args) {
28845
29280
 
28846
29281
  // src/commands/status.ts
28847
29282
  import crypto10 from "crypto";
28848
- import fs37 from "fs";
28849
- import path38 from "path";
29283
+ import fs39 from "fs";
29284
+ import path40 from "path";
28850
29285
  function runStatusCommand(options, logger) {
28851
29286
  const { config, configDir, sourceRoot } = resolveRuntime(
28852
29287
  options,
@@ -28925,21 +29360,21 @@ function classifyCodexFiles(config, sourceRoot, configDir) {
28925
29360
  rules: paths.rules
28926
29361
  };
28927
29362
  const rules = compileRules(
28928
- path38.join(sourceRoot, config.source.rules),
29363
+ path40.join(sourceRoot, config.source.rules),
28929
29364
  "codex",
28930
29365
  mappings,
28931
29366
  createLossReport()
28932
29367
  );
28933
- const instructionsSource = fs37.readFileSync(path38.join(sourceRoot, config.source.instructions), "utf8").trim();
29368
+ const instructionsSource = fs39.readFileSync(path40.join(sourceRoot, config.source.instructions), "utf8").trim();
28934
29369
  const composedInstructions = `${instructionsSource}
28935
29370
 
28936
29371
  --- tangyr managed rules ---
28937
29372
  ${rules.agentsAppendix}`.trim();
28938
29373
  const agentFiles = ts(
28939
- path38.join(sourceRoot, config.source.agents, "*.md")
29374
+ path40.join(sourceRoot, config.source.agents, "*.md")
28940
29375
  ).sort();
28941
- const hooksSource = path38.join(sourceRoot, config.source.hooks, "hooks.json");
28942
- const mcpSource = path38.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);
28943
29378
  const ruleRows = rules.dotRulesFiles.length === 0 ? [
28944
29379
  {
28945
29380
  component: "rules",
@@ -28950,7 +29385,7 @@ ${rules.agentsAppendix}`.trim();
28950
29385
  ] : rules.dotRulesFiles.map(
28951
29386
  (ruleFile) => classifyCompiledFile(
28952
29387
  `rules/${ruleFile.name}`,
28953
- path38.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
29388
+ path40.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
28954
29389
  "codex",
28955
29390
  void 0,
28956
29391
  config,
@@ -28968,10 +29403,10 @@ ${rules.agentsAppendix}`.trim();
28968
29403
  ),
28969
29404
  ...agentFiles.map(
28970
29405
  (agentFile) => classifyCompiledFile(
28971
- `agents/${path38.basename(agentFile, ".md")}`,
28972
- path38.join(
29406
+ `agents/${path40.basename(agentFile, ".md")}`,
29407
+ path40.join(
28973
29408
  resolveTargetPath(codexPaths.agents),
28974
- `${path38.basename(agentFile, ".md")}.toml`
29409
+ `${path40.basename(agentFile, ".md")}.toml`
28975
29410
  ),
28976
29411
  "codex",
28977
29412
  computeSourceHash(agentFile),
@@ -28995,11 +29430,11 @@ ${rules.agentsAppendix}`.trim();
28995
29430
  config,
28996
29431
  sourceRoot
28997
29432
  ),
28998
- fs37.existsSync(hooksSource) ? classifyCodexHooksFile(resolveTargetPath(codexPaths.hooksSharedFile)) : notConfiguredRow(
29433
+ fs39.existsSync(hooksSource) ? classifyCodexHooksFile(resolveTargetPath(codexPaths.hooksSharedFile)) : notConfiguredRow(
28999
29434
  "hooks",
29000
29435
  resolveTargetPath(codexPaths.hooksSharedFile)
29001
29436
  ),
29002
- fs37.existsSync(mcpSource) ? classifyCompiledFile(
29437
+ fs39.existsSync(mcpSource) ? classifyCompiledFile(
29003
29438
  "mcp",
29004
29439
  resolveTargetPath(codexPaths.mcpSharedFile),
29005
29440
  "codex",
@@ -29019,7 +29454,7 @@ function classifyCodexHooksFile(filePath) {
29019
29454
  conformant: true
29020
29455
  };
29021
29456
  }
29022
- if (!fs37.existsSync(filePath)) {
29457
+ if (!fs39.existsSync(filePath)) {
29023
29458
  return {
29024
29459
  component: "hooks",
29025
29460
  className: "missing",
@@ -29051,20 +29486,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
29051
29486
  mcpSharedFile: paths.mcp_shared_file
29052
29487
  };
29053
29488
  const agentFiles = ts(
29054
- path38.join(sourceRoot, config.source.agents, "*.md")
29489
+ path40.join(sourceRoot, config.source.agents, "*.md")
29055
29490
  ).sort();
29056
29491
  const commandFiles = ts(
29057
- path38.join(sourceRoot, config.source.commands, "*.md")
29492
+ path40.join(sourceRoot, config.source.commands, "*.md")
29058
29493
  ).sort();
29059
- const hooksSource = path38.join(sourceRoot, config.source.hooks, "hooks.json");
29060
- const mcpSource = path38.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);
29061
29496
  return [
29062
29497
  ...agentFiles.map(
29063
29498
  (agentFile) => classifyCompiledFile(
29064
- `agents/${path38.basename(agentFile, ".md")}`,
29065
- path38.join(
29499
+ `agents/${path40.basename(agentFile, ".md")}`,
29500
+ path40.join(
29066
29501
  resolveTargetPath(copilotPaths.agents),
29067
- `${path38.basename(agentFile, ".md")}.agent.md`
29502
+ `${path40.basename(agentFile, ".md")}.agent.md`
29068
29503
  ),
29069
29504
  "copilot",
29070
29505
  computeSourceHash(agentFile),
@@ -29081,10 +29516,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
29081
29516
  ),
29082
29517
  ...commandFiles.map(
29083
29518
  (commandFile) => classifyCompiledFile(
29084
- `commands/${path38.basename(commandFile, ".md")}`,
29085
- path38.join(
29519
+ `commands/${path40.basename(commandFile, ".md")}`,
29520
+ path40.join(
29086
29521
  resolveTargetPath(copilotPaths.prompts),
29087
- `${path38.basename(commandFile, ".md")}.prompt.md`
29522
+ `${path40.basename(commandFile, ".md")}.prompt.md`
29088
29523
  ),
29089
29524
  "copilot",
29090
29525
  computeSourceHash(commandFile),
@@ -29102,9 +29537,9 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
29102
29537
  config,
29103
29538
  sourceRoot
29104
29539
  ),
29105
- fs37.existsSync(hooksSource) ? classifyCompiledFile(
29540
+ fs39.existsSync(hooksSource) ? classifyCompiledFile(
29106
29541
  "hooks",
29107
- path38.join(
29542
+ path40.join(
29108
29543
  resolveTargetPath(copilotPaths.hooks),
29109
29544
  "tangyr-managed.json"
29110
29545
  ),
@@ -29114,12 +29549,12 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
29114
29549
  sourceRoot
29115
29550
  ) : notConfiguredRow(
29116
29551
  "hooks",
29117
- path38.join(
29552
+ path40.join(
29118
29553
  resolveTargetPath(copilotPaths.hooks),
29119
29554
  "tangyr-managed.json"
29120
29555
  )
29121
29556
  ),
29122
- fs37.existsSync(mcpSource) ? classifyCompiledFile(
29557
+ fs39.existsSync(mcpSource) ? classifyCompiledFile(
29123
29558
  "mcp",
29124
29559
  resolveTargetPath(copilotPaths.mcpSharedFile),
29125
29560
  "copilot",
@@ -29139,7 +29574,7 @@ function notConfiguredRow(component, filePath) {
29139
29574
  }
29140
29575
  function classifyDirectArtifact(artifact, config, sourceRoot) {
29141
29576
  const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
29142
- const sourcePath = artifact.sourceKey ? path38.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
29577
+ const sourcePath = artifact.sourceKey ? path40.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
29143
29578
  if (artifactClass === "managed-symlink" && sourcePath && !isSymlinkCurrent(artifact.path, sourcePath)) {
29144
29579
  return {
29145
29580
  component: artifact.component,
@@ -29228,9 +29663,9 @@ function classifyClaudeSharedFiles(config, sourceRoot) {
29228
29663
  classifyHooks(settingsPath),
29229
29664
  classifySettings(
29230
29665
  settingsPath,
29231
- path38.resolve(sourceRoot, config.source.settings)
29666
+ path40.resolve(sourceRoot, config.source.settings)
29232
29667
  ),
29233
- classifyMcp(claudeJsonPath, path38.resolve(sourceRoot, config.source.mcp))
29668
+ classifyMcp(claudeJsonPath, path40.resolve(sourceRoot, config.source.mcp))
29234
29669
  ];
29235
29670
  }
29236
29671
  function classifyHooks(filePath) {
@@ -29294,14 +29729,14 @@ function classifyMcp(filePath, sourcePath) {
29294
29729
  }
29295
29730
  function isSymlinkCurrent(linkPath, sourcePath) {
29296
29731
  try {
29297
- return fs37.realpathSync(linkPath) === fs37.realpathSync(sourcePath);
29732
+ return fs39.realpathSync(linkPath) === fs39.realpathSync(sourcePath);
29298
29733
  } catch {
29299
29734
  return false;
29300
29735
  }
29301
29736
  }
29302
29737
  function isCompiledCurrent6(filePath, sourcePath) {
29303
29738
  try {
29304
- const marker = extractProvenanceMarker(fs37.readFileSync(filePath, "utf8"));
29739
+ const marker = extractProvenanceMarker(fs39.readFileSync(filePath, "utf8"));
29305
29740
  return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
29306
29741
  } catch {
29307
29742
  return false;
@@ -29331,7 +29766,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
29331
29766
  }
29332
29767
  function readCompiledContent(filePath) {
29333
29768
  try {
29334
- return fs37.readFileSync(filePath, "utf8");
29769
+ return fs39.readFileSync(filePath, "utf8");
29335
29770
  } catch {
29336
29771
  return null;
29337
29772
  }
@@ -29362,8 +29797,8 @@ function hashString6(value) {
29362
29797
  }
29363
29798
 
29364
29799
  // src/commands/sync.ts
29365
- import fs40 from "fs";
29366
- import path41 from "path";
29800
+ import fs42 from "fs";
29801
+ import path43 from "path";
29367
29802
 
29368
29803
  // node_modules/chalk/source/vendor/ansi-styles/index.js
29369
29804
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -29861,8 +30296,8 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
29861
30296
  var source_default = chalk;
29862
30297
 
29863
30298
  // src/adapters/claude-code.ts
29864
- import fs39 from "fs";
29865
- import path40 from "path";
30299
+ import fs41 from "fs";
30300
+ import path42 from "path";
29866
30301
 
29867
30302
  // src/core/shim.ts
29868
30303
  import crypto11 from "crypto";
@@ -29879,12 +30314,12 @@ ${SHIM_BODY}`;
29879
30314
 
29880
30315
  // src/compiler/hook-components.ts
29881
30316
  var import_yaml11 = __toESM(require_dist(), 1);
29882
- import fs38 from "fs";
29883
- import path39 from "path";
30317
+ import fs40 from "fs";
30318
+ import path41 from "path";
29884
30319
  function parseHookDeclaration(filePath) {
29885
30320
  let raw;
29886
30321
  try {
29887
- raw = fs38.readFileSync(filePath, "utf8");
30322
+ raw = fs40.readFileSync(filePath, "utf8");
29888
30323
  } catch {
29889
30324
  return null;
29890
30325
  }
@@ -29967,9 +30402,9 @@ function synthesizeHooksJson(declarations) {
29967
30402
  return { hooks };
29968
30403
  }
29969
30404
  function loadSourceHooks(hooksDir, hookNames) {
29970
- const hooksJsonPath = path39.join(hooksDir, "hooks.json");
29971
- if (fs38.existsSync(hooksJsonPath)) {
29972
- const raw = fs38.readFileSync(hooksJsonPath, "utf8");
30405
+ const hooksJsonPath = path41.join(hooksDir, "hooks.json");
30406
+ if (fs40.existsSync(hooksJsonPath)) {
30407
+ const raw = fs40.readFileSync(hooksJsonPath, "utf8");
29973
30408
  return JSON.parse(raw);
29974
30409
  }
29975
30410
  const declarations = loadHookDeclarations(hooksDir, hookNames);
@@ -29980,14 +30415,14 @@ function loadHookDeclarations(hooksDir, hookNames) {
29980
30415
  if (hookNames && hookNames.length > 0) {
29981
30416
  names = hookNames;
29982
30417
  } else {
29983
- if (!fs38.existsSync(hooksDir) || !fs38.statSync(hooksDir).isDirectory()) {
30418
+ if (!fs40.existsSync(hooksDir) || !fs40.statSync(hooksDir).isDirectory()) {
29984
30419
  return [];
29985
30420
  }
29986
- names = fs38.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();
29987
30422
  }
29988
30423
  const declarations = [];
29989
30424
  for (const name of names) {
29990
- const filePath = path39.join(hooksDir, `${name}.md`);
30425
+ const filePath = path41.join(hooksDir, `${name}.md`);
29991
30426
  const decl = parseHookDeclaration(filePath);
29992
30427
  if (decl) {
29993
30428
  declarations.push(decl);
@@ -30111,7 +30546,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
30111
30546
  }
30112
30547
  if (!shouldSkipComponent6(options, "instructions") && manifest && scopePath) {
30113
30548
  const shimPath = profile.instructions_shim;
30114
- const agentsMdPath = path40.resolve(sourceRoot, config.source.instructions);
30549
+ const agentsMdPath = path42.resolve(sourceRoot, config.source.instructions);
30115
30550
  if (!options.dryRun) {
30116
30551
  applyClaudeCodeShimUpgrade(
30117
30552
  shimPath,
@@ -30165,13 +30600,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
30165
30600
  }
30166
30601
  function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
30167
30602
  if (!mappings.modelTiers.custom_provider) return;
30168
- const agentsDir = path40.join(sourceRoot, config.source.agents);
30169
- if (!fs39.existsSync(agentsDir)) return;
30170
- for (const agentFile of ts(path40.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()) {
30171
30606
  const { data } = parseMarkdownFrontmatter(agentFile);
30172
30607
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30173
30608
  if (hasProvider) {
30174
- const basename = path40.basename(agentFile);
30609
+ const basename = path42.basename(agentFile);
30175
30610
  addLoss(lossReport, "claude-code", "agents", {
30176
30611
  source: `agents/${basename}`,
30177
30612
  fields: [
@@ -30196,19 +30631,19 @@ function shouldSkipComponent6(options, component) {
30196
30631
  function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath, logger) {
30197
30632
  const expectedBodyHash = shimBodyHash();
30198
30633
  const shimContent = buildAgentsMdShim(shimPath, agentsMdPath, "claude-code");
30199
- if (!fs39.existsSync(shimPath)) {
30634
+ if (!fs41.existsSync(shimPath)) {
30200
30635
  manifest.artifacts.push({
30201
- relativePath: path40.relative(scopePath, shimPath),
30636
+ relativePath: path42.relative(scopePath, shimPath),
30202
30637
  hash: expectedBodyHash,
30203
30638
  origin: "tangyr-managed"
30204
30639
  });
30205
30640
  writeManifest(scopePath, manifest);
30206
- fs39.mkdirSync(path40.dirname(shimPath), { recursive: true });
30207
- fs39.writeFileSync(shimPath, shimContent);
30641
+ fs41.mkdirSync(path42.dirname(shimPath), { recursive: true });
30642
+ fs41.writeFileSync(shimPath, shimContent);
30208
30643
  logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
30209
30644
  return;
30210
30645
  }
30211
- const existing = fs39.readFileSync(shimPath, "utf8");
30646
+ const existing = fs41.readFileSync(shimPath, "utf8");
30212
30647
  const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
30213
30648
  const marker = extractProvenanceMarker(firstNonEmptyLine);
30214
30649
  if (marker !== null && marker.hash === expectedBodyHash) {
@@ -30219,21 +30654,21 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
30219
30654
  }
30220
30655
  backupFile(shimPath, manifest);
30221
30656
  writeManifest(scopePath, manifest);
30222
- fs39.writeFileSync(shimPath, shimContent);
30657
+ fs41.writeFileSync(shimPath, shimContent);
30223
30658
  manifest.artifacts.push({
30224
- relativePath: path40.relative(scopePath, shimPath),
30659
+ relativePath: path42.relative(scopePath, shimPath),
30225
30660
  hash: expectedBodyHash,
30226
30661
  origin: "tangyr-managed"
30227
30662
  });
30228
30663
  logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
30229
30664
  }
30230
30665
  function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
30231
- const source = path40.resolve(
30666
+ const source = path42.resolve(
30232
30667
  sourceRoot,
30233
30668
  config.source[directComponent.sourceKey]
30234
30669
  );
30235
30670
  const destination = directComponent.destination;
30236
- if (!fs39.existsSync(source)) {
30671
+ if (!fs41.existsSync(source)) {
30237
30672
  return skippedMissingSource6(directComponent.component, source);
30238
30673
  }
30239
30674
  if (options.dryRun) {
@@ -30255,7 +30690,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
30255
30690
  };
30256
30691
  }
30257
30692
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
30258
- fs39.unlinkSync(destination);
30693
+ fs41.unlinkSync(destination);
30259
30694
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
30260
30695
  return {
30261
30696
  component: directComponent.component,
@@ -30263,9 +30698,9 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
30263
30698
  path: destination
30264
30699
  };
30265
30700
  } else if (artifactClass === "managed-symlink") {
30266
- fs39.unlinkSync(destination);
30701
+ fs41.unlinkSync(destination);
30267
30702
  }
30268
- ensureDir(path40.dirname(destination));
30703
+ ensureDir(path42.dirname(destination));
30269
30704
  createRelativeSymlink(source, destination, directComponent.type, {
30270
30705
  logger,
30271
30706
  provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
@@ -30282,8 +30717,8 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
30282
30717
  };
30283
30718
  }
30284
30719
  function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination, manifest, scopePath) {
30285
- const source = path40.resolve(sourceRoot, config.source.skills);
30286
- if (!fs39.existsSync(source)) {
30720
+ const source = path42.resolve(sourceRoot, config.source.skills);
30721
+ if (!fs41.existsSync(source)) {
30287
30722
  return [skippedMissingSource6("skills", source)];
30288
30723
  }
30289
30724
  const declaredNames = resolveKitSkillNames(sourceRoot);
@@ -30293,7 +30728,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
30293
30728
  if (isLegacyWholesaleSymlink) {
30294
30729
  for (const name of foreignSkillNames(source, declaredNames)) {
30295
30730
  logger.info(
30296
- `[dry-run] skills: migrate foreign skill ${path40.join(source, name)} -> ${path40.join(destination, name)}`
30731
+ `[dry-run] skills: migrate foreign skill ${path42.join(source, name)} -> ${path42.join(destination, name)}`
30297
30732
  );
30298
30733
  }
30299
30734
  logger.info(
@@ -30301,9 +30736,9 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
30301
30736
  );
30302
30737
  }
30303
30738
  for (const name of declaredNames ?? listSkillDirNames(source)) {
30304
- const skillDestination = path40.join(destination, name);
30739
+ const skillDestination = path42.join(destination, name);
30305
30740
  logger.info(
30306
- `[dry-run] skills: symlink ${path40.join(source, name)} -> ${skillDestination}`
30741
+ `[dry-run] skills: symlink ${path42.join(source, name)} -> ${skillDestination}`
30307
30742
  );
30308
30743
  outcomes2.push({
30309
30744
  component: "skills",
@@ -30336,9 +30771,9 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
30336
30771
  return outcomes;
30337
30772
  }
30338
30773
  function syncSingleSkill(config, sourceRoot, options, logger, source, destination, name, manifest, scopePath) {
30339
- const skillSource = path40.join(source, name);
30340
- const skillDestination = path40.join(destination, name);
30341
- if (!fs39.existsSync(skillSource)) {
30774
+ const skillSource = path42.join(source, name);
30775
+ const skillDestination = path42.join(destination, name);
30776
+ if (!fs41.existsSync(skillSource)) {
30342
30777
  return skippedMissingSource6("skills", skillSource);
30343
30778
  }
30344
30779
  const artifactClass = classifyArtifact(skillDestination, config, sourceRoot);
@@ -30350,7 +30785,7 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
30350
30785
  };
30351
30786
  }
30352
30787
  if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
30353
- fs39.unlinkSync(skillDestination);
30788
+ fs41.unlinkSync(skillDestination);
30354
30789
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(
30355
30790
  skillDestination,
30356
30791
  config,
@@ -30361,25 +30796,25 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
30361
30796
  )) {
30362
30797
  return { component: "skills", status: "conflict", path: skillDestination };
30363
30798
  } else if (artifactClass === "managed-symlink") {
30364
- fs39.unlinkSync(skillDestination);
30799
+ fs41.unlinkSync(skillDestination);
30365
30800
  }
30366
30801
  createRelativeSymlink(skillSource, skillDestination, "dir");
30367
30802
  return { component: "skills", status: "success", path: skillDestination };
30368
30803
  }
30369
30804
  function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
30370
30805
  const foreignNames = foreignSkillNames(source, declaredNames);
30371
- fs39.unlinkSync(destination);
30806
+ fs41.unlinkSync(destination);
30372
30807
  ensureDir(destination);
30373
30808
  for (const name of foreignNames) {
30374
- const from = path40.join(source, name);
30375
- const to = path40.join(destination, name);
30376
- if (fs39.existsSync(to)) {
30809
+ const from = path42.join(source, name);
30810
+ const to = path42.join(destination, name);
30811
+ if (fs41.existsSync(to)) {
30377
30812
  logger.warn(
30378
30813
  `skills migration: ${to} already exists \u2014 skipping move of ${from} to avoid overwrite`
30379
30814
  );
30380
30815
  continue;
30381
30816
  }
30382
- fs39.renameSync(from, to);
30817
+ fs41.renameSync(from, to);
30383
30818
  logger.info(`skills migration: moved ${from} -> ${to}`);
30384
30819
  }
30385
30820
  }
@@ -30391,21 +30826,21 @@ function foreignSkillNames(source, declaredNames) {
30391
30826
  return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
30392
30827
  }
30393
30828
  function listSkillDirNames(dir) {
30394
- if (!fs39.existsSync(dir)) {
30829
+ if (!fs41.existsSync(dir)) {
30395
30830
  return [];
30396
30831
  }
30397
- return fs39.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);
30398
30833
  }
30399
30834
  function isSymlinkPath(filePath) {
30400
30835
  try {
30401
- return fs39.lstatSync(filePath).isSymbolicLink();
30836
+ return fs41.lstatSync(filePath).isSymbolicLink();
30402
30837
  } catch {
30403
30838
  return false;
30404
30839
  }
30405
30840
  }
30406
30841
  function syncHookScriptsBridge(config, sourceRoot, options, logger, destination, manifest, scopePath) {
30407
- const source = path40.resolve(sourceRoot, config.source.hooks);
30408
- if (!fs39.existsSync(source)) {
30842
+ const source = path42.resolve(sourceRoot, config.source.hooks);
30843
+ if (!fs41.existsSync(source)) {
30409
30844
  return skippedMissingSource6("hooks", source);
30410
30845
  }
30411
30846
  if (options.dryRun) {
@@ -30417,13 +30852,13 @@ function syncHookScriptsBridge(config, sourceRoot, options, logger, destination,
30417
30852
  return { component: "hooks", status: "skipped-current", path: destination };
30418
30853
  }
30419
30854
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
30420
- fs39.unlinkSync(destination);
30855
+ fs41.unlinkSync(destination);
30421
30856
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
30422
30857
  return { component: "hooks", status: "conflict", path: destination };
30423
30858
  } else if (artifactClass === "managed-symlink") {
30424
- fs39.unlinkSync(destination);
30859
+ fs41.unlinkSync(destination);
30425
30860
  }
30426
- ensureDir(path40.dirname(destination));
30861
+ ensureDir(path42.dirname(destination));
30427
30862
  createRelativeSymlink(source, destination, "dir");
30428
30863
  return { component: "hooks", status: "success", path: destination };
30429
30864
  }
@@ -30446,7 +30881,7 @@ function syncHooks6(config, sourceRoot, options, logger, destination) {
30446
30881
  destination,
30447
30882
  settings,
30448
30883
  stringifyJson3,
30449
- !fs39.existsSync(destination),
30884
+ !fs41.existsSync(destination),
30450
30885
  logger
30451
30886
  );
30452
30887
  return {
@@ -30456,8 +30891,8 @@ function syncHooks6(config, sourceRoot, options, logger, destination) {
30456
30891
  };
30457
30892
  }
30458
30893
  function syncMcp6(config, sourceRoot, options, logger, destination) {
30459
- const source = path40.resolve(sourceRoot, config.source.mcp);
30460
- if (!fs39.existsSync(source)) {
30894
+ const source = path42.resolve(sourceRoot, config.source.mcp);
30895
+ if (!fs41.existsSync(source)) {
30461
30896
  return skippedMissingSource6("mcp", source);
30462
30897
  }
30463
30898
  if (options.dryRun) {
@@ -30482,7 +30917,7 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
30482
30917
  destination,
30483
30918
  hostConfig,
30484
30919
  stringifyJson3,
30485
- !fs39.existsSync(destination),
30920
+ !fs41.existsSync(destination),
30486
30921
  logger
30487
30922
  );
30488
30923
  return {
@@ -30492,8 +30927,8 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
30492
30927
  };
30493
30928
  }
30494
30929
  function syncSettings2(config, sourceRoot, options, logger, destination) {
30495
- const source = path40.resolve(sourceRoot, config.source.settings);
30496
- if (!fs39.existsSync(source)) {
30930
+ const source = path42.resolve(sourceRoot, config.source.settings);
30931
+ if (!fs41.existsSync(source)) {
30497
30932
  return skippedMissingSource6("settings", source);
30498
30933
  }
30499
30934
  if (options.dryRun) {
@@ -30511,7 +30946,7 @@ function syncSettings2(config, sourceRoot, options, logger, destination) {
30511
30946
  destination,
30512
30947
  settings,
30513
30948
  stringifyJson3,
30514
- !fs39.existsSync(destination),
30949
+ !fs41.existsSync(destination),
30515
30950
  logger
30516
30951
  );
30517
30952
  return {
@@ -30536,11 +30971,11 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
30536
30971
  backupFile(destination, manifest);
30537
30972
  writeManifest(scopePath, manifest);
30538
30973
  } else {
30539
- fs39.renameSync(destination, `${destination}.bak.${Date.now()}`);
30974
+ fs41.renameSync(destination, `${destination}.bak.${Date.now()}`);
30540
30975
  }
30541
30976
  return true;
30542
30977
  }
30543
- fs39.rmSync(destination, { recursive: true, force: true });
30978
+ fs41.rmSync(destination, { recursive: true, force: true });
30544
30979
  return true;
30545
30980
  }
30546
30981
  function skippedMissingSource6(component, source) {
@@ -30552,16 +30987,16 @@ function skippedMissingSource6(component, source) {
30552
30987
  }
30553
30988
  function isSymlinkTo6(linkPath, source) {
30554
30989
  try {
30555
- return fs39.realpathSync(linkPath) === fs39.realpathSync(source);
30990
+ return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
30556
30991
  } catch {
30557
30992
  return false;
30558
30993
  }
30559
30994
  }
30560
30995
  function readJsonObject4(filePath) {
30561
- if (!fs39.existsSync(filePath)) {
30996
+ if (!fs41.existsSync(filePath)) {
30562
30997
  return {};
30563
30998
  }
30564
- const parsed = JSON.parse(fs39.readFileSync(filePath, "utf8"));
30999
+ const parsed = JSON.parse(fs41.readFileSync(filePath, "utf8"));
30565
31000
  return isRecord5(parsed) ? parsed : {};
30566
31001
  }
30567
31002
  function markManaged(value) {
@@ -30827,7 +31262,7 @@ function writeLossReport(filePath, report) {
30827
31262
  if (!filePath) {
30828
31263
  return;
30829
31264
  }
30830
- fs40.writeFileSync(filePath, `${JSON.stringify(report, null, 2)}
31265
+ fs42.writeFileSync(filePath, `${JSON.stringify(report, null, 2)}
30831
31266
  `);
30832
31267
  }
30833
31268
  function prepareKitManifest(scope, projectRoot, kitInfo) {
@@ -30868,8 +31303,8 @@ function updateManifest(kitInfo, kitSync) {
30868
31303
  writeManifest(kitSync.scopePath, kitSync.manifest);
30869
31304
  }
30870
31305
  function resolveKitFilePath(kitPath, relativePath) {
30871
- const fullPath = path41.join(kitPath, relativePath);
30872
- return fs40.existsSync(fullPath) ? fullPath : null;
31306
+ const fullPath = path43.join(kitPath, relativePath);
31307
+ return fs42.existsSync(fullPath) ? fullPath : null;
30873
31308
  }
30874
31309
  function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
30875
31310
  if (removedSourcePaths.length === 0 || !mappings) {
@@ -30930,9 +31365,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
30930
31365
  }
30931
31366
  if (relativePath.startsWith("agents/")) {
30932
31367
  removeManagedCompiledArtifact2(
30933
- path41.join(
31368
+ path43.join(
30934
31369
  resolveTargetPath(paths.agents ?? ""),
30935
- `${path41.parse(relativePath).name}.agent.md`
31370
+ `${path43.parse(relativePath).name}.agent.md`
30936
31371
  ),
30937
31372
  "copilot",
30938
31373
  relativePath,
@@ -30942,9 +31377,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
30942
31377
  }
30943
31378
  if (relativePath.startsWith("commands/")) {
30944
31379
  removeManagedCompiledArtifact2(
30945
- path41.join(
31380
+ path43.join(
30946
31381
  resolveTargetPath(paths.prompts ?? ""),
30947
- `${path41.parse(relativePath).name}.prompt.md`
31382
+ `${path43.parse(relativePath).name}.prompt.md`
30948
31383
  ),
30949
31384
  "copilot",
30950
31385
  relativePath,
@@ -30954,7 +31389,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
30954
31389
  }
30955
31390
  if (relativePath.endsWith("hooks.json")) {
30956
31391
  removeManagedCompiledArtifact2(
30957
- path41.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
31392
+ path43.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
30958
31393
  "copilot",
30959
31394
  relativePath,
30960
31395
  logger
@@ -30984,9 +31419,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
30984
31419
  }
30985
31420
  if (relativePath.startsWith("agents/")) {
30986
31421
  removeManagedCompiledArtifact2(
30987
- path41.join(
31422
+ path43.join(
30988
31423
  resolveTargetPath(paths.agents ?? ""),
30989
- `${path41.parse(relativePath).name}.toml`
31424
+ `${path43.parse(relativePath).name}.toml`
30990
31425
  ),
30991
31426
  "codex",
30992
31427
  relativePath,
@@ -30996,9 +31431,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
30996
31431
  }
30997
31432
  if (relativePath.startsWith("rules/")) {
30998
31433
  removeManagedCompiledArtifact2(
30999
- path41.join(
31434
+ path43.join(
31000
31435
  resolveTargetPath(paths.rules ?? ""),
31001
- `${path41.parse(relativePath).name}.rules`
31436
+ `${path43.parse(relativePath).name}.rules`
31002
31437
  ),
31003
31438
  "codex",
31004
31439
  relativePath,
@@ -31037,9 +31472,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
31037
31472
  }
31038
31473
  if (relativePath.startsWith("agents/")) {
31039
31474
  removeManagedCompiledArtifact2(
31040
- path41.join(
31475
+ path43.join(
31041
31476
  resolveTargetPath(paths.agents ?? ""),
31042
- `${path41.parse(relativePath).name}.md`
31477
+ `${path43.parse(relativePath).name}.md`
31043
31478
  ),
31044
31479
  "opencode",
31045
31480
  relativePath,
@@ -31049,9 +31484,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
31049
31484
  }
31050
31485
  if (relativePath.startsWith("commands/")) {
31051
31486
  removeManagedCompiledArtifact2(
31052
- path41.join(
31487
+ path43.join(
31053
31488
  resolveTargetPath(paths.commands ?? ""),
31054
- `${path41.parse(relativePath).name}.md`
31489
+ `${path43.parse(relativePath).name}.md`
31055
31490
  ),
31056
31491
  "opencode",
31057
31492
  relativePath,
@@ -31083,9 +31518,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
31083
31518
  }
31084
31519
  if (relativePath.startsWith("agents/")) {
31085
31520
  removeManagedCompiledArtifact2(
31086
- path41.join(
31521
+ path43.join(
31087
31522
  resolveTargetPath(paths.agents ?? ""),
31088
- `${path41.parse(relativePath).name}.md`
31523
+ `${path43.parse(relativePath).name}.md`
31089
31524
  ),
31090
31525
  "cursor",
31091
31526
  relativePath,
@@ -31095,9 +31530,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
31095
31530
  }
31096
31531
  if (relativePath.startsWith("rules/")) {
31097
31532
  removeManagedCompiledArtifact2(
31098
- path41.join(
31533
+ path43.join(
31099
31534
  resolveTargetPath(paths.rules ?? ""),
31100
- `${path41.parse(relativePath).name}.mdc`
31535
+ `${path43.parse(relativePath).name}.mdc`
31101
31536
  ),
31102
31537
  "cursor",
31103
31538
  relativePath,
@@ -31107,9 +31542,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
31107
31542
  }
31108
31543
  if (relativePath.startsWith("commands/")) {
31109
31544
  removeManagedCompiledArtifact2(
31110
- path41.join(
31545
+ path43.join(
31111
31546
  resolveTargetPath(paths.skills ?? ""),
31112
- path41.parse(relativePath).name,
31547
+ path43.parse(relativePath).name,
31113
31548
  "SKILL.md"
31114
31549
  ),
31115
31550
  "cursor",
@@ -31153,9 +31588,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
31153
31588
  }
31154
31589
  if (relativePath.startsWith("rules/")) {
31155
31590
  removeManagedCompiledArtifact2(
31156
- path41.join(
31591
+ path43.join(
31157
31592
  resolveTargetPath(paths.rules ?? ""),
31158
- `${path41.parse(relativePath).name}.md`
31593
+ `${path43.parse(relativePath).name}.md`
31159
31594
  ),
31160
31595
  "cline",
31161
31596
  relativePath,
@@ -31165,9 +31600,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
31165
31600
  }
31166
31601
  if (relativePath.startsWith("commands/")) {
31167
31602
  removeManagedCompiledArtifact2(
31168
- path41.join(
31603
+ path43.join(
31169
31604
  resolveTargetPath(paths.workflows ?? ""),
31170
- path41.basename(relativePath)
31605
+ path43.basename(relativePath)
31171
31606
  ),
31172
31607
  "cline",
31173
31608
  relativePath,
@@ -31185,17 +31620,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
31185
31620
  }
31186
31621
  }
31187
31622
  function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
31188
- if (!fs40.existsSync(artifactPath)) {
31623
+ if (!fs42.existsSync(artifactPath)) {
31189
31624
  return;
31190
31625
  }
31191
- if (!fs40.statSync(artifactPath).isFile()) {
31626
+ if (!fs42.statSync(artifactPath).isFile()) {
31192
31627
  return;
31193
31628
  }
31194
- const marker = extractProvenanceMarker(fs40.readFileSync(artifactPath, "utf8"));
31629
+ const marker = extractProvenanceMarker(fs42.readFileSync(artifactPath, "utf8"));
31195
31630
  if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
31196
31631
  return;
31197
31632
  }
31198
- fs40.rmSync(artifactPath, { force: true });
31633
+ fs42.rmSync(artifactPath, { force: true });
31199
31634
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
31200
31635
  }
31201
31636
  function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
@@ -31226,10 +31661,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
31226
31661
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
31227
31662
  }
31228
31663
  function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
31229
- if (!fs40.existsSync(artifactPath)) {
31664
+ if (!fs42.existsSync(artifactPath)) {
31230
31665
  return;
31231
31666
  }
31232
- const content = fs40.readFileSync(artifactPath, "utf8");
31667
+ const content = fs42.readFileSync(artifactPath, "utf8");
31233
31668
  const startMarker = "# tangyr: managed mcp start";
31234
31669
  const endMarker = "# tangyr: managed mcp end";
31235
31670
  const startIndex = content.indexOf(startMarker);
@@ -31246,19 +31681,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
31246
31681
  const after = content.slice(endIndex + endMarker.length).trimStart();
31247
31682
  const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
31248
31683
  if (cleaned.length === 0) {
31249
- fs40.rmSync(artifactPath, { force: true });
31684
+ fs42.rmSync(artifactPath, { force: true });
31250
31685
  } else {
31251
- fs40.writeFileSync(artifactPath, `${cleaned}
31686
+ fs42.writeFileSync(artifactPath, `${cleaned}
31252
31687
  `);
31253
31688
  }
31254
31689
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
31255
31690
  }
31256
31691
  function readJsonObject5(filePath) {
31257
- if (!fs40.existsSync(filePath)) {
31692
+ if (!fs42.existsSync(filePath)) {
31258
31693
  return null;
31259
31694
  }
31260
31695
  try {
31261
- const parsed = JSON.parse(fs40.readFileSync(filePath, "utf8"));
31696
+ const parsed = JSON.parse(fs42.readFileSync(filePath, "utf8"));
31262
31697
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
31263
31698
  } catch {
31264
31699
  return null;
@@ -31272,10 +31707,10 @@ function readJsonMetadata(value) {
31272
31707
  }
31273
31708
  function writeJsonOrRemove2(filePath, parsed) {
31274
31709
  if (isEmptyJsonValue2(parsed)) {
31275
- fs40.rmSync(filePath, { force: true });
31710
+ fs42.rmSync(filePath, { force: true });
31276
31711
  return;
31277
31712
  }
31278
- fs40.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
31713
+ fs42.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
31279
31714
  `);
31280
31715
  }
31281
31716
  function isEmptyJsonValue2(value) {
@@ -31335,8 +31770,8 @@ function removeManagedHookEntries(value, expectedSource) {
31335
31770
  }
31336
31771
 
31337
31772
  // src/commands/validate.ts
31338
- import fs41 from "fs";
31339
- import path42 from "path";
31773
+ import fs43 from "fs";
31774
+ import path44 from "path";
31340
31775
  var SUPPORTED_KIT_FORMATS2 = [1];
31341
31776
  var SUPPORTED_DISCIPLINE_VERSIONS = [
31342
31777
  "0.14.0",
@@ -31420,8 +31855,8 @@ function checkKitFormatSupported(kit) {
31420
31855
  }
31421
31856
  function checkEntrypointExists(kit) {
31422
31857
  const entrypoint = "CLAUDE.md";
31423
- const entrypointPath = path42.join(kit.path, entrypoint);
31424
- if (!fs41.existsSync(entrypointPath)) {
31858
+ const entrypointPath = path44.join(kit.path, entrypoint);
31859
+ if (!fs43.existsSync(entrypointPath)) {
31425
31860
  return {
31426
31861
  code: "entrypoint-missing",
31427
31862
  location: entrypoint,
@@ -31478,9 +31913,9 @@ function checkComponentFrontmatter(kit) {
31478
31913
  const missingSet = new Set(kit.components[cat].missing);
31479
31914
  for (const name of kit.components[cat].declared) {
31480
31915
  if (missingSet.has(name)) continue;
31481
- const filePath = cat === "skills" ? path42.join(kit.path, cat, name, "SKILL.md") : path42.join(kit.path, cat, `${name}.md`);
31482
- if (!fs41.existsSync(filePath)) continue;
31483
- const relPath = path42.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);
31484
31919
  try {
31485
31920
  const { data } = parseMarkdownFrontmatter(filePath);
31486
31921
  for (const field of requiredFields) {
@@ -31505,10 +31940,10 @@ function checkComponentFrontmatter(kit) {
31505
31940
  }
31506
31941
  function checkReservedRootNames(kit) {
31507
31942
  const violations = [];
31508
- if (!fs41.existsSync(kit.path) || !fs41.statSync(kit.path).isDirectory()) {
31943
+ if (!fs43.existsSync(kit.path) || !fs43.statSync(kit.path).isDirectory()) {
31509
31944
  return violations;
31510
31945
  }
31511
- const entries = fs41.readdirSync(kit.path, { withFileTypes: true });
31946
+ const entries = fs43.readdirSync(kit.path, { withFileTypes: true });
31512
31947
  for (const entry of entries) {
31513
31948
  if (RESERVED_ROOT_NAMES.includes(entry.name)) {
31514
31949
  violations.push({
@@ -31525,8 +31960,8 @@ function checkHumanOnlyCommandInvocation(kit) {
31525
31960
  const missingSet = new Set(kit.components.commands.missing);
31526
31961
  for (const name of kit.components.commands.declared) {
31527
31962
  if (missingSet.has(name)) continue;
31528
- const filePath = path42.join(kit.path, "commands", `${name}.md`);
31529
- if (!fs41.existsSync(filePath)) continue;
31963
+ const filePath = path44.join(kit.path, "commands", `${name}.md`);
31964
+ if (!fs43.existsSync(filePath)) continue;
31530
31965
  let data;
31531
31966
  try {
31532
31967
  ({ data } = parseMarkdownFrontmatter(filePath));
@@ -31539,7 +31974,7 @@ function checkHumanOnlyCommandInvocation(kit) {
31539
31974
  if (!barred) {
31540
31975
  violations.push({
31541
31976
  code: "command-human-only-model-invocable",
31542
- location: path42.relative(kit.path, filePath),
31977
+ location: path44.relative(kit.path, filePath),
31543
31978
  message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
31544
31979
  });
31545
31980
  }
@@ -31548,8 +31983,8 @@ function checkHumanOnlyCommandInvocation(kit) {
31548
31983
  }
31549
31984
 
31550
31985
  // src/commands/verify.ts
31551
- import fs42 from "fs";
31552
- import path43 from "path";
31986
+ import fs44 from "fs";
31987
+ import path45 from "path";
31553
31988
  function runVerifyCommand(options, logger) {
31554
31989
  const { config, configDir, sourceRoot, kitInfo } = resolveRuntime(
31555
31990
  options,
@@ -31640,8 +32075,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
31640
32075
  if (!slotPath) {
31641
32076
  continue;
31642
32077
  }
31643
- const fullPath = subPath ? path43.join(slotPath, subPath) : slotPath;
31644
- if (!fs42.existsSync(fullPath)) {
32078
+ const fullPath = subPath ? path45.join(slotPath, subPath) : slotPath;
32079
+ if (!fs44.existsSync(fullPath)) {
31645
32080
  failures.push(
31646
32081
  `claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
31647
32082
  );