@alessandroraffa/tangyr 0.20.1 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1372,8 +1372,8 @@ var require_command = __commonJS({
1372
1372
  "use strict";
1373
1373
  var EventEmitter = __require("events").EventEmitter;
1374
1374
  var childProcess = __require("child_process");
1375
- var path45 = __require("path");
1376
- var fs45 = __require("fs");
1375
+ var path47 = __require("path");
1376
+ var fs46 = __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 (fs45.existsSync(executableFile)) return;
2370
+ if (fs46.existsSync(executableFile)) return;
2371
2371
  const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
2372
2372
  const executableMissing = `'${executableFile}' does not exist
2373
2373
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
@@ -2385,11 +2385,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
2385
2385
  let launchWithNode = false;
2386
2386
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
2387
2387
  function findFile(baseDir, baseName) {
2388
- const localBin = path45.resolve(baseDir, baseName);
2389
- if (fs45.existsSync(localBin)) return localBin;
2390
- if (sourceExt.includes(path45.extname(baseName))) return void 0;
2388
+ const localBin = path47.resolve(baseDir, baseName);
2389
+ if (fs46.existsSync(localBin)) return localBin;
2390
+ if (sourceExt.includes(path47.extname(baseName))) return void 0;
2391
2391
  const foundExt = sourceExt.find(
2392
- (ext) => fs45.existsSync(`${localBin}${ext}`)
2392
+ (ext) => fs46.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 = fs45.realpathSync(this._scriptPath);
2404
+ resolvedScriptPath = fs46.realpathSync(this._scriptPath);
2405
2405
  } catch {
2406
2406
  resolvedScriptPath = this._scriptPath;
2407
2407
  }
2408
- executableDir = path45.resolve(
2409
- path45.dirname(resolvedScriptPath),
2408
+ executableDir = path47.resolve(
2409
+ path47.dirname(resolvedScriptPath),
2410
2410
  executableDir
2411
2411
  );
2412
2412
  }
2413
2413
  if (executableDir) {
2414
2414
  let localFile = findFile(executableDir, executableFile);
2415
2415
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
2416
- const legacyName = path45.basename(
2416
+ const legacyName = path47.basename(
2417
2417
  this._scriptPath,
2418
- path45.extname(this._scriptPath)
2418
+ path47.extname(this._scriptPath)
2419
2419
  );
2420
2420
  if (legacyName !== this._name) {
2421
2421
  localFile = findFile(
@@ -2426,7 +2426,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2426
2426
  }
2427
2427
  executableFile = localFile || executableFile;
2428
2428
  }
2429
- launchWithNode = sourceExt.includes(path45.extname(executableFile));
2429
+ launchWithNode = sourceExt.includes(path47.extname(executableFile));
2430
2430
  let proc;
2431
2431
  if (process5.platform !== "win32") {
2432
2432
  if (launchWithNode) {
@@ -3341,7 +3341,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3341
3341
  * @return {Command}
3342
3342
  */
3343
3343
  nameFromFilename(filename) {
3344
- this._name = path45.basename(filename, path45.extname(filename));
3344
+ this._name = path47.basename(filename, path47.extname(filename));
3345
3345
  return this;
3346
3346
  }
3347
3347
  /**
@@ -3355,9 +3355,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
3355
3355
  * @param {string} [path]
3356
3356
  * @return {(string|null|Command)}
3357
3357
  */
3358
- executableDir(path46) {
3359
- if (path46 === void 0) return this._executableDir;
3360
- this._executableDir = path46;
3358
+ executableDir(path48) {
3359
+ if (path48 === void 0) return this._executableDir;
3360
+ this._executableDir = path48;
3361
3361
  return this;
3362
3362
  }
3363
3363
  /**
@@ -3713,17 +3713,17 @@ var require_visit = __commonJS({
3713
3713
  visit.BREAK = BREAK;
3714
3714
  visit.SKIP = SKIP;
3715
3715
  visit.REMOVE = REMOVE;
3716
- function visit_(key, node, visitor, path45) {
3717
- const ctrl = callVisitor(key, node, visitor, path45);
3716
+ function visit_(key, node, visitor, path47) {
3717
+ const ctrl = callVisitor(key, node, visitor, path47);
3718
3718
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3719
- replaceNode(key, path45, ctrl);
3720
- return visit_(key, ctrl, visitor, path45);
3719
+ replaceNode(key, path47, ctrl);
3720
+ return visit_(key, ctrl, visitor, path47);
3721
3721
  }
3722
3722
  if (typeof ctrl !== "symbol") {
3723
3723
  if (identity.isCollection(node)) {
3724
- path45 = Object.freeze(path45.concat(node));
3724
+ path47 = Object.freeze(path47.concat(node));
3725
3725
  for (let i = 0; i < node.items.length; ++i) {
3726
- const ci2 = visit_(i, node.items[i], visitor, path45);
3726
+ const ci2 = visit_(i, node.items[i], visitor, path47);
3727
3727
  if (typeof ci2 === "number")
3728
3728
  i = ci2 - 1;
3729
3729
  else if (ci2 === BREAK)
@@ -3734,13 +3734,13 @@ var require_visit = __commonJS({
3734
3734
  }
3735
3735
  }
3736
3736
  } else if (identity.isPair(node)) {
3737
- path45 = Object.freeze(path45.concat(node));
3738
- const ck = visit_("key", node.key, visitor, path45);
3737
+ path47 = Object.freeze(path47.concat(node));
3738
+ const ck = visit_("key", node.key, visitor, path47);
3739
3739
  if (ck === BREAK)
3740
3740
  return BREAK;
3741
3741
  else if (ck === REMOVE)
3742
3742
  node.key = null;
3743
- const cv = visit_("value", node.value, visitor, path45);
3743
+ const cv = visit_("value", node.value, visitor, path47);
3744
3744
  if (cv === BREAK)
3745
3745
  return BREAK;
3746
3746
  else if (cv === REMOVE)
@@ -3761,17 +3761,17 @@ var require_visit = __commonJS({
3761
3761
  visitAsync.BREAK = BREAK;
3762
3762
  visitAsync.SKIP = SKIP;
3763
3763
  visitAsync.REMOVE = REMOVE;
3764
- async function visitAsync_(key, node, visitor, path45) {
3765
- const ctrl = await callVisitor(key, node, visitor, path45);
3764
+ async function visitAsync_(key, node, visitor, path47) {
3765
+ const ctrl = await callVisitor(key, node, visitor, path47);
3766
3766
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3767
- replaceNode(key, path45, ctrl);
3768
- return visitAsync_(key, ctrl, visitor, path45);
3767
+ replaceNode(key, path47, ctrl);
3768
+ return visitAsync_(key, ctrl, visitor, path47);
3769
3769
  }
3770
3770
  if (typeof ctrl !== "symbol") {
3771
3771
  if (identity.isCollection(node)) {
3772
- path45 = Object.freeze(path45.concat(node));
3772
+ path47 = Object.freeze(path47.concat(node));
3773
3773
  for (let i = 0; i < node.items.length; ++i) {
3774
- const ci2 = await visitAsync_(i, node.items[i], visitor, path45);
3774
+ const ci2 = await visitAsync_(i, node.items[i], visitor, path47);
3775
3775
  if (typeof ci2 === "number")
3776
3776
  i = ci2 - 1;
3777
3777
  else if (ci2 === BREAK)
@@ -3782,13 +3782,13 @@ var require_visit = __commonJS({
3782
3782
  }
3783
3783
  }
3784
3784
  } else if (identity.isPair(node)) {
3785
- path45 = Object.freeze(path45.concat(node));
3786
- const ck = await visitAsync_("key", node.key, visitor, path45);
3785
+ path47 = Object.freeze(path47.concat(node));
3786
+ const ck = await visitAsync_("key", node.key, visitor, path47);
3787
3787
  if (ck === BREAK)
3788
3788
  return BREAK;
3789
3789
  else if (ck === REMOVE)
3790
3790
  node.key = null;
3791
- const cv = await visitAsync_("value", node.value, visitor, path45);
3791
+ const cv = await visitAsync_("value", node.value, visitor, path47);
3792
3792
  if (cv === BREAK)
3793
3793
  return BREAK;
3794
3794
  else if (cv === REMOVE)
@@ -3815,23 +3815,23 @@ var require_visit = __commonJS({
3815
3815
  }
3816
3816
  return visitor;
3817
3817
  }
3818
- function callVisitor(key, node, visitor, path45) {
3818
+ function callVisitor(key, node, visitor, path47) {
3819
3819
  if (typeof visitor === "function")
3820
- return visitor(key, node, path45);
3820
+ return visitor(key, node, path47);
3821
3821
  if (identity.isMap(node))
3822
- return visitor.Map?.(key, node, path45);
3822
+ return visitor.Map?.(key, node, path47);
3823
3823
  if (identity.isSeq(node))
3824
- return visitor.Seq?.(key, node, path45);
3824
+ return visitor.Seq?.(key, node, path47);
3825
3825
  if (identity.isPair(node))
3826
- return visitor.Pair?.(key, node, path45);
3826
+ return visitor.Pair?.(key, node, path47);
3827
3827
  if (identity.isScalar(node))
3828
- return visitor.Scalar?.(key, node, path45);
3828
+ return visitor.Scalar?.(key, node, path47);
3829
3829
  if (identity.isAlias(node))
3830
- return visitor.Alias?.(key, node, path45);
3830
+ return visitor.Alias?.(key, node, path47);
3831
3831
  return void 0;
3832
3832
  }
3833
- function replaceNode(key, path45, node) {
3834
- const parent = path45[path45.length - 1];
3833
+ function replaceNode(key, path47, node) {
3834
+ const parent = path47[path47.length - 1];
3835
3835
  if (identity.isCollection(parent)) {
3836
3836
  parent.items[key] = node;
3837
3837
  } else if (identity.isPair(parent)) {
@@ -4439,10 +4439,10 @@ var require_Collection = __commonJS({
4439
4439
  var createNode = require_createNode();
4440
4440
  var identity = require_identity();
4441
4441
  var Node = require_Node();
4442
- function collectionFromPath(schema, path45, value) {
4442
+ function collectionFromPath(schema, path47, value) {
4443
4443
  let v2 = value;
4444
- for (let i = path45.length - 1; i >= 0; --i) {
4445
- const k2 = path45[i];
4444
+ for (let i = path47.length - 1; i >= 0; --i) {
4445
+ const k2 = path47[i];
4446
4446
  if (typeof k2 === "number" && Number.isInteger(k2) && k2 >= 0) {
4447
4447
  const a = [];
4448
4448
  a[k2] = v2;
@@ -4461,7 +4461,7 @@ var require_Collection = __commonJS({
4461
4461
  sourceObjects: /* @__PURE__ */ new Map()
4462
4462
  });
4463
4463
  }
4464
- var isEmptyPath = (path45) => path45 == null || typeof path45 === "object" && !!path45[Symbol.iterator]().next().done;
4464
+ var isEmptyPath = (path47) => path47 == null || typeof path47 === "object" && !!path47[Symbol.iterator]().next().done;
4465
4465
  var Collection = class extends Node.NodeBase {
4466
4466
  constructor(type, schema) {
4467
4467
  super(type);
@@ -4491,11 +4491,11 @@ var require_Collection = __commonJS({
4491
4491
  * be a Pair instance or a `{ key, value }` object, which may not have a key
4492
4492
  * that already exists in the map.
4493
4493
  */
4494
- addIn(path45, value) {
4495
- if (isEmptyPath(path45))
4494
+ addIn(path47, value) {
4495
+ if (isEmptyPath(path47))
4496
4496
  this.add(value);
4497
4497
  else {
4498
- const [key, ...rest] = path45;
4498
+ const [key, ...rest] = path47;
4499
4499
  const node = this.get(key, true);
4500
4500
  if (identity.isCollection(node))
4501
4501
  node.addIn(rest, value);
@@ -4509,8 +4509,8 @@ var require_Collection = __commonJS({
4509
4509
  * Removes a value from the collection.
4510
4510
  * @returns `true` if the item was found and removed.
4511
4511
  */
4512
- deleteIn(path45) {
4513
- const [key, ...rest] = path45;
4512
+ deleteIn(path47) {
4513
+ const [key, ...rest] = path47;
4514
4514
  if (rest.length === 0)
4515
4515
  return this.delete(key);
4516
4516
  const node = this.get(key, true);
@@ -4524,8 +4524,8 @@ var require_Collection = __commonJS({
4524
4524
  * scalar values from their surrounding node; to disable set `keepScalar` to
4525
4525
  * `true` (collections are always returned intact).
4526
4526
  */
4527
- getIn(path45, keepScalar) {
4528
- const [key, ...rest] = path45;
4527
+ getIn(path47, keepScalar) {
4528
+ const [key, ...rest] = path47;
4529
4529
  const node = this.get(key, true);
4530
4530
  if (rest.length === 0)
4531
4531
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -4543,8 +4543,8 @@ var require_Collection = __commonJS({
4543
4543
  /**
4544
4544
  * Checks if the collection includes a value with the key `key`.
4545
4545
  */
4546
- hasIn(path45) {
4547
- const [key, ...rest] = path45;
4546
+ hasIn(path47) {
4547
+ const [key, ...rest] = path47;
4548
4548
  if (rest.length === 0)
4549
4549
  return this.has(key);
4550
4550
  const node = this.get(key, true);
@@ -4554,8 +4554,8 @@ var require_Collection = __commonJS({
4554
4554
  * Sets a value in this collection. For `!!set`, `value` needs to be a
4555
4555
  * boolean to add/remove the item from the set.
4556
4556
  */
4557
- setIn(path45, value) {
4558
- const [key, ...rest] = path45;
4557
+ setIn(path47, value) {
4558
+ const [key, ...rest] = path47;
4559
4559
  if (rest.length === 0) {
4560
4560
  this.set(key, value);
4561
4561
  } else {
@@ -7067,9 +7067,9 @@ var require_Document = __commonJS({
7067
7067
  this.contents.add(value);
7068
7068
  }
7069
7069
  /** Adds a value to the document. */
7070
- addIn(path45, value) {
7070
+ addIn(path47, value) {
7071
7071
  if (assertCollection(this.contents))
7072
- this.contents.addIn(path45, value);
7072
+ this.contents.addIn(path47, value);
7073
7073
  }
7074
7074
  /**
7075
7075
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -7144,14 +7144,14 @@ var require_Document = __commonJS({
7144
7144
  * Removes a value from the document.
7145
7145
  * @returns `true` if the item was found and removed.
7146
7146
  */
7147
- deleteIn(path45) {
7148
- if (Collection.isEmptyPath(path45)) {
7147
+ deleteIn(path47) {
7148
+ if (Collection.isEmptyPath(path47)) {
7149
7149
  if (this.contents == null)
7150
7150
  return false;
7151
7151
  this.contents = null;
7152
7152
  return true;
7153
7153
  }
7154
- return assertCollection(this.contents) ? this.contents.deleteIn(path45) : false;
7154
+ return assertCollection(this.contents) ? this.contents.deleteIn(path47) : false;
7155
7155
  }
7156
7156
  /**
7157
7157
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -7166,10 +7166,10 @@ var require_Document = __commonJS({
7166
7166
  * scalar values from their surrounding node; to disable set `keepScalar` to
7167
7167
  * `true` (collections are always returned intact).
7168
7168
  */
7169
- getIn(path45, keepScalar) {
7170
- if (Collection.isEmptyPath(path45))
7169
+ getIn(path47, keepScalar) {
7170
+ if (Collection.isEmptyPath(path47))
7171
7171
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
7172
- return identity.isCollection(this.contents) ? this.contents.getIn(path45, keepScalar) : void 0;
7172
+ return identity.isCollection(this.contents) ? this.contents.getIn(path47, keepScalar) : void 0;
7173
7173
  }
7174
7174
  /**
7175
7175
  * Checks if the document includes a value with the key `key`.
@@ -7180,10 +7180,10 @@ var require_Document = __commonJS({
7180
7180
  /**
7181
7181
  * Checks if the document includes a value at `path`.
7182
7182
  */
7183
- hasIn(path45) {
7184
- if (Collection.isEmptyPath(path45))
7183
+ hasIn(path47) {
7184
+ if (Collection.isEmptyPath(path47))
7185
7185
  return this.contents !== void 0;
7186
- return identity.isCollection(this.contents) ? this.contents.hasIn(path45) : false;
7186
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path47) : false;
7187
7187
  }
7188
7188
  /**
7189
7189
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -7200,13 +7200,13 @@ var require_Document = __commonJS({
7200
7200
  * Sets a value in this document. For `!!set`, `value` needs to be a
7201
7201
  * boolean to add/remove the item from the set.
7202
7202
  */
7203
- setIn(path45, value) {
7204
- if (Collection.isEmptyPath(path45)) {
7203
+ setIn(path47, value) {
7204
+ if (Collection.isEmptyPath(path47)) {
7205
7205
  this.contents = value;
7206
7206
  } else if (this.contents == null) {
7207
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path45), value);
7207
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path47), value);
7208
7208
  } else if (assertCollection(this.contents)) {
7209
- this.contents.setIn(path45, value);
7209
+ this.contents.setIn(path47, value);
7210
7210
  }
7211
7211
  }
7212
7212
  /**
@@ -9163,9 +9163,9 @@ var require_cst_visit = __commonJS({
9163
9163
  visit.BREAK = BREAK;
9164
9164
  visit.SKIP = SKIP;
9165
9165
  visit.REMOVE = REMOVE;
9166
- visit.itemAtPath = (cst, path45) => {
9166
+ visit.itemAtPath = (cst, path47) => {
9167
9167
  let item = cst;
9168
- for (const [field, index] of path45) {
9168
+ for (const [field, index] of path47) {
9169
9169
  const tok = item?.[field];
9170
9170
  if (tok && "items" in tok) {
9171
9171
  item = tok.items[index];
@@ -9174,23 +9174,23 @@ var require_cst_visit = __commonJS({
9174
9174
  }
9175
9175
  return item;
9176
9176
  };
9177
- visit.parentCollection = (cst, path45) => {
9178
- const parent = visit.itemAtPath(cst, path45.slice(0, -1));
9179
- const field = path45[path45.length - 1][0];
9177
+ visit.parentCollection = (cst, path47) => {
9178
+ const parent = visit.itemAtPath(cst, path47.slice(0, -1));
9179
+ const field = path47[path47.length - 1][0];
9180
9180
  const coll = parent?.[field];
9181
9181
  if (coll && "items" in coll)
9182
9182
  return coll;
9183
9183
  throw new Error("Parent collection not found");
9184
9184
  };
9185
- function _visit(path45, item, visitor) {
9186
- let ctrl = visitor(item, path45);
9185
+ function _visit(path47, item, visitor) {
9186
+ let ctrl = visitor(item, path47);
9187
9187
  if (typeof ctrl === "symbol")
9188
9188
  return ctrl;
9189
9189
  for (const field of ["key", "value"]) {
9190
9190
  const token = item[field];
9191
9191
  if (token && "items" in token) {
9192
9192
  for (let i = 0; i < token.items.length; ++i) {
9193
- const ci2 = _visit(Object.freeze(path45.concat([[field, i]])), token.items[i], visitor);
9193
+ const ci2 = _visit(Object.freeze(path47.concat([[field, i]])), token.items[i], visitor);
9194
9194
  if (typeof ci2 === "number")
9195
9195
  i = ci2 - 1;
9196
9196
  else if (ci2 === BREAK)
@@ -9201,10 +9201,10 @@ var require_cst_visit = __commonJS({
9201
9201
  }
9202
9202
  }
9203
9203
  if (typeof ctrl === "function" && field === "key")
9204
- ctrl = ctrl(item, path45);
9204
+ ctrl = ctrl(item, path47);
9205
9205
  }
9206
9206
  }
9207
- return typeof ctrl === "function" ? ctrl(item, path45) : ctrl;
9207
+ return typeof ctrl === "function" ? ctrl(item, path47) : 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 fs45 = this.flowScalar(this.type);
10492
+ const fs46 = this.flowScalar(this.type);
10493
10493
  if (atNextItem || it2.value) {
10494
- map.items.push({ start, key: fs45, sep: [] });
10494
+ map.items.push({ start, key: fs46, sep: [] });
10495
10495
  this.onKeyLine = true;
10496
10496
  } else if (it2.sep) {
10497
- this.stack.push(fs45);
10497
+ this.stack.push(fs46);
10498
10498
  } else {
10499
- Object.assign(it2, { key: fs45, sep: [] });
10499
+ Object.assign(it2, { key: fs46, 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 fs45 = this.flowScalar(this.type);
10627
+ const fs46 = this.flowScalar(this.type);
10628
10628
  if (!it2 || it2.value)
10629
- fc.items.push({ start: [], key: fs45, sep: [] });
10629
+ fc.items.push({ start: [], key: fs46, sep: [] });
10630
10630
  else if (it2.sep)
10631
- this.stack.push(fs45);
10631
+ this.stack.push(fs46);
10632
10632
  else
10633
- Object.assign(it2, { key: fs45, sep: [] });
10633
+ Object.assign(it2, { key: fs46, sep: [] });
10634
10634
  return;
10635
10635
  }
10636
10636
  case "flow-map-end":
@@ -15724,7 +15724,8 @@ function resolveClaudeCodeProfile(scope, projectRoot, mappings) {
15724
15724
  hooks_shared_file: r(slotMap, "hooks_shared_file"),
15725
15725
  settings_shared_file: r(slotMap, "settings_shared_file"),
15726
15726
  mcp_shared_file: r(slotMap, "mcp_shared_file"),
15727
- hooks: r(slotMap, "hooks")
15727
+ hooks: r(slotMap, "hooks"),
15728
+ hook_scripts: r(slotMap, "hook_scripts")
15728
15729
  };
15729
15730
  }
15730
15731
  function resolveCopilotProfile(scope, projectRoot, mappings) {
@@ -15741,6 +15742,7 @@ function resolveCopilotProfile(scope, projectRoot, mappings) {
15741
15742
  skills: r(slotMap, "skills"),
15742
15743
  prompts: r(slotMap, "prompts"),
15743
15744
  hooks: r(slotMap, "hooks"),
15745
+ hook_scripts: r(slotMap, "hook_scripts"),
15744
15746
  mcp_shared_file: r(slotMap, "mcp_shared_file"),
15745
15747
  instructions
15746
15748
  };
@@ -15759,6 +15761,7 @@ function resolveCodexProfile(scope, projectRoot, mappings) {
15759
15761
  rules: r(slotMap, "rules"),
15760
15762
  skills: r(slotMap, "skills"),
15761
15763
  hooks_shared_file: r(slotMap, "hooks_shared_file"),
15764
+ hook_scripts: r(slotMap, "hook_scripts"),
15762
15765
  mcp_shared_file: r(slotMap, "mcp_shared_file")
15763
15766
  };
15764
15767
  }
@@ -15794,6 +15797,7 @@ function resolveCursorProfile(scope, projectRoot, mappings) {
15794
15797
  skills: r(slotMap, "skills"),
15795
15798
  skills_shared: r(slotMap, "skills_shared"),
15796
15799
  hooks_file: r(slotMap, "hooks_file"),
15800
+ hook_scripts: r(slotMap, "hook_scripts"),
15797
15801
  mcp_file: r(slotMap, "mcp_file"),
15798
15802
  permissions_file: r(slotMap, "permissions_file")
15799
15803
  };
@@ -15863,7 +15867,8 @@ function resolveClaudeCodeProfileForRoot(root, mappings) {
15863
15867
  hooks_shared_file: r(slotMap, "hooks_shared_file"),
15864
15868
  settings_shared_file: r(slotMap, "settings_shared_file"),
15865
15869
  mcp_shared_file: r(slotMap, "mcp_shared_file"),
15866
- hooks: r(slotMap, "hooks")
15870
+ hooks: r(slotMap, "hooks"),
15871
+ hook_scripts: r(slotMap, "hook_scripts")
15867
15872
  };
15868
15873
  const defaultRoot = defaultProfile.agents !== void 0 ? path8.dirname(defaultProfile.agents) : path8.resolve(expandHome(DEFAULT_CLAUDE_ROOT_RAW));
15869
15874
  if (root === defaultRoot) {
@@ -21130,9 +21135,6 @@ var lossSeverityByEntryType = {
21130
21135
  // which. Error severity, because the CLI cannot tell an author which half
21131
21136
  // of their kit it is ignoring without them deciding first.
21132
21137
  "hook-source-ambiguous": "error",
21133
- // A warning, not an error: the hooks that do reach the target are correct,
21134
- // and the remedy is a choice about scope rather than a defect in the kit.
21135
- "hook-script-path-unresolved": "warning",
21136
21138
  "hook-as-plugin": "error",
21137
21139
  "instructions-shim": "info",
21138
21140
  "permission-coarsening": "error",
@@ -21250,7 +21252,9 @@ function parseHookDeclaration(filePath) {
21250
21252
  }
21251
21253
  var GLOBAL_HOOK_SCRIPTS_DIR = "~/.agents/hooks/scripts";
21252
21254
  function synthesizedHookCommand(name, scriptsDir = GLOBAL_HOOK_SCRIPTS_DIR) {
21253
- return `npx tsx ${scriptsDir}/${name}.ts`;
21255
+ const script = `${scriptsDir}/${name}.ts`;
21256
+ const needsQuoting = (/\s/u.test(script) || script.includes("$")) && !script.startsWith("~");
21257
+ return `npx tsx ${needsQuoting ? `"${script}"` : script}`;
21254
21258
  }
21255
21259
  function resolveHookCommand(declaration, scriptsDir) {
21256
21260
  return declaration.command ?? synthesizedHookCommand(declaration.name, scriptsDir);
@@ -21486,32 +21490,6 @@ function reportHooksSourceConflict(report, targets, hooksDir, hookNames) {
21486
21490
  }
21487
21491
  return message;
21488
21492
  }
21489
- function reportProjectScopeScriptPath(report, targets, hooksDir, hookNames) {
21490
- const affected = targets.filter((t) => t !== "claude-code");
21491
- if (affected.length === 0) {
21492
- return [];
21493
- }
21494
- const synthesized = loadHookDeclarations(hooksDir, hookNames).filter(
21495
- (d) => d.command === void 0
21496
- );
21497
- if (synthesized.length === 0) {
21498
- return [];
21499
- }
21500
- for (const target of affected) {
21501
- addLoss(report, target, "hooks", {
21502
- source: `${path20.basename(hooksDir)}/`,
21503
- fields: [
21504
- {
21505
- field: "command",
21506
- action: "hook-script-path-unresolved",
21507
- severity: "warning",
21508
- detail: `The ${synthesized.length} hook${synthesized.length === 1 ? "" : "s"} that take the synthesized command name '${GLOBAL_HOOK_SCRIPTS_DIR}/<name>.ts', which a project-scope install does not write. Only the claude-code adapter delivers hook scripts into a project, and only its own commands are resolved against the project. To fix, choose one: install this kit at global scope, where the path is correct; install claude-code alongside ${target} so the scripts reach the project, and give each hook an explicit 'command' pointing at them; or give each hook a 'command' of its own. Until then these hooks do not run under ${target}.`
21509
- }
21510
- ]
21511
- });
21512
- }
21513
- return affected;
21514
- }
21515
21493
 
21516
21494
  // src/core/remove.ts
21517
21495
  import fs23 from "fs";
@@ -24311,8 +24289,8 @@ function toConflictPolicy2(value) {
24311
24289
  }
24312
24290
 
24313
24291
  // src/commands/install.ts
24314
- import fs38 from "fs";
24315
- import path37 from "path";
24292
+ import fs39 from "fs";
24293
+ import path39 from "path";
24316
24294
 
24317
24295
  // src/core/channel-state.ts
24318
24296
  import fs30 from "fs";
@@ -25221,8 +25199,8 @@ function sleep(ms2) {
25221
25199
  // src/adapters/codex.ts
25222
25200
  var TOML3 = __toESM(require_toml(), 1);
25223
25201
  import crypto5 from "crypto";
25224
- import fs33 from "fs";
25225
- import path31 from "path";
25202
+ import fs34 from "fs";
25203
+ import path33 from "path";
25226
25204
 
25227
25205
  // src/compiler/agents.ts
25228
25206
  var TOML = __toESM(require_toml(), 1);
@@ -25668,6 +25646,16 @@ function compileCursorHooks(sourceHooksJson, mappings, lossReport, sourceLabel)
25668
25646
  }
25669
25647
  hooks[mapping.target_event] = { command: extracted.command };
25670
25648
  translated += 1;
25649
+ if (extracted.remaining.length > 0) {
25650
+ addHookLoss(
25651
+ lossReport,
25652
+ "cursor",
25653
+ sourceEvent,
25654
+ sourceLabel,
25655
+ "error",
25656
+ `${sourceEvent}: the source registers ${extracted.remaining.length + 1} hooks on this event and Cursor's entry holds one command. Only '${extracted.command}' was written; ${extracted.remaining.map((c) => `'${c}'`).join(", ")} ${extracted.remaining.length === 1 ? "does" : "do"} not run under Cursor. To fix: give this event a single entry point that dispatches to the others, or accept the loss knowingly.`
25657
+ );
25658
+ }
25671
25659
  if (extracted.matcher) {
25672
25660
  addInformational(
25673
25661
  lossReport,
@@ -25835,20 +25823,30 @@ function compileCopilotHooks(sourceHooksJson, mappings, lossReport, sourceLabel)
25835
25823
  }
25836
25824
  function extractHookCommand(payload) {
25837
25825
  const entries = Array.isArray(payload) ? payload : [payload];
25826
+ const found = [];
25838
25827
  for (const entry of entries) {
25839
25828
  if (!isRecord(entry)) continue;
25840
25829
  const matcher = typeof entry.matcher === "string" && entry.matcher ? { matcher: entry.matcher } : {};
25841
25830
  if (typeof entry.command === "string" && entry.command) {
25842
- return { command: entry.command, ...matcher };
25831
+ found.push({ command: entry.command, ...matcher });
25832
+ continue;
25843
25833
  }
25844
25834
  const inner = Array.isArray(entry.hooks) ? entry.hooks : [];
25845
25835
  for (const hook of inner) {
25846
25836
  if (isRecord(hook) && typeof hook.command === "string" && hook.command) {
25847
- return { command: hook.command, ...matcher };
25837
+ found.push({ command: hook.command, ...matcher });
25848
25838
  }
25849
25839
  }
25850
25840
  }
25851
- return { command: "" };
25841
+ if (found.length === 0) {
25842
+ return { command: "", remaining: [] };
25843
+ }
25844
+ const [first, ...rest] = found;
25845
+ return {
25846
+ command: first.command,
25847
+ ...first.matcher !== void 0 ? { matcher: first.matcher } : {},
25848
+ remaining: rest.map((r) => r.command)
25849
+ };
25852
25850
  }
25853
25851
  function normalizeHookEventRule(value, target, sourceEvent) {
25854
25852
  if (typeof value === "string") {
@@ -25929,6 +25927,78 @@ function addHookLoss(lossReport, target, eventName, sourceLabel, severity, reaso
25929
25927
  });
25930
25928
  }
25931
25929
 
25930
+ // src/core/hook-scripts.ts
25931
+ import path30 from "path";
25932
+ function hookScriptsDir(bridge, target) {
25933
+ const globalBridge = resolveTargetPath("~/.agents/hooks");
25934
+ if (path30.resolve(bridge) === path30.resolve(globalBridge)) {
25935
+ return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
25936
+ }
25937
+ const relative = path30.relative(process.cwd(), bridge);
25938
+ const insideProject = !relative.startsWith("..") && !path30.isAbsolute(relative) && relative !== "";
25939
+ const variable = PROJECT_DIR_VARIABLE[target];
25940
+ if (insideProject && variable) {
25941
+ const posix = path30.posix.join(
25942
+ relative.split(path30.sep).join("/"),
25943
+ "scripts"
25944
+ );
25945
+ return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
25946
+ }
25947
+ return { prefix: path30.join(bridge, "scripts"), machineLocal: true };
25948
+ }
25949
+ var PROJECT_DIR_VARIABLE = {
25950
+ "claude-code": "$CLAUDE_PROJECT_DIR"
25951
+ };
25952
+ function machineLocalScriptPathNotice(target, prefix) {
25953
+ return `The hook commands compiled for ${target} name '${prefix}', an absolute path. ${target} publishes no project-directory variable a command could use instead \u2014 measured, not assumed \u2014 and a bare relative path would resolve against whatever directory the harness runs the hook from. The compiled file is therefore correct on this machine and not on another: re-run 'tangyr sync' after cloning, and prefer keeping it out of version control.`;
25954
+ }
25955
+
25956
+ // src/adapters/hook-scripts-bridge.ts
25957
+ import fs32 from "fs";
25958
+ import path31 from "path";
25959
+ function syncHookScriptsBridge(args) {
25960
+ const { source, destination, config, sourceRoot, options, logger } = args;
25961
+ if (!fs32.existsSync(source)) {
25962
+ return {
25963
+ component: "hooks",
25964
+ status: "skipped",
25965
+ path: `${source}: source not configured`
25966
+ };
25967
+ }
25968
+ if (options.dryRun) {
25969
+ logger.info(`[dry-run] hooks: symlink ${source} -> ${destination}`);
25970
+ return { component: "hooks", status: "dry-run", path: destination };
25971
+ }
25972
+ const artifactClass = classifyArtifact(destination, config, sourceRoot);
25973
+ if (artifactClass === "managed-symlink" && isSymlinkTo(destination, source)) {
25974
+ return { component: "hooks", status: "skipped-current", path: destination };
25975
+ }
25976
+ if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
25977
+ fs32.unlinkSync(destination);
25978
+ } else if (artifactClass === "unmanaged-conflict" && !args.onConflict()) {
25979
+ return { component: "hooks", status: "conflict", path: destination };
25980
+ } else if (artifactClass === "managed-symlink") {
25981
+ fs32.unlinkSync(destination);
25982
+ }
25983
+ ensureDir(path31.dirname(destination));
25984
+ createRelativeSymlink(source, destination, "dir");
25985
+ if (args.manifest && args.scopePath) {
25986
+ addArtifactToManifest(args.manifest, {
25987
+ relativePath: path31.relative(args.scopePath, destination),
25988
+ hash: `dir:${source}`,
25989
+ origin: "tangyr-managed"
25990
+ });
25991
+ }
25992
+ return { component: "hooks", status: "success", path: destination };
25993
+ }
25994
+ function isSymlinkTo(linkPath, source) {
25995
+ try {
25996
+ return fs32.realpathSync(linkPath) === fs32.realpathSync(source);
25997
+ } catch {
25998
+ return false;
25999
+ }
26000
+ }
26001
+
25932
26002
  // src/compiler/mcp.ts
25933
26003
  var TOML2 = __toESM(require_toml(), 1);
25934
26004
  import crypto4 from "crypto";
@@ -26208,9 +26278,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
26208
26278
  }
26209
26279
 
26210
26280
  // src/compiler/rules.ts
26211
- import path30 from "path";
26281
+ import path32 from "path";
26212
26282
  var import_yaml9 = __toESM(require_dist(), 1);
26213
- import fs32 from "fs";
26283
+ import fs33 from "fs";
26214
26284
  function compileRules(sourceRulesDir, target, _mappings, lossReport) {
26215
26285
  if (target === "copilot") {
26216
26286
  addLoss(lossReport, "copilot", "rules", {
@@ -26247,13 +26317,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
26247
26317
  }
26248
26318
  const appendixParts = [];
26249
26319
  const dotRulesFiles = [];
26250
- for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
26320
+ for (const ruleFile of ts(path32.join(sourceRulesDir, "*.md")).sort()) {
26251
26321
  const parsed = parseRule(ruleFile);
26252
- const name = path30.basename(ruleFile, ".md");
26322
+ const name = path32.basename(ruleFile, ".md");
26253
26323
  if (parsed.mode === "exec-policy") {
26254
26324
  dotRulesFiles.push({
26255
26325
  name: `${name}.rules`,
26256
- content: `${formatProvenanceMarker("toml", `rules/${path30.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
26326
+ content: `${formatProvenanceMarker("toml", `rules/${path32.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
26257
26327
  ${parsed.body}`
26258
26328
  });
26259
26329
  continue;
@@ -26262,7 +26332,7 @@ ${parsed.body}`
26262
26332
 
26263
26333
  ${parsed.body.trim()}`);
26264
26334
  addLoss(lossReport, "codex", "rules", {
26265
- source: `rules/${path30.basename(ruleFile)}`,
26335
+ source: `rules/${path32.basename(ruleFile)}`,
26266
26336
  fields: [
26267
26337
  {
26268
26338
  field: "mode",
@@ -26272,7 +26342,7 @@ ${parsed.body.trim()}`);
26272
26342
  "mode",
26273
26343
  "rule-as-instruction"
26274
26344
  ),
26275
- detail: `${path30.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
26345
+ detail: `${path32.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
26276
26346
  }
26277
26347
  ]
26278
26348
  });
@@ -26280,7 +26350,7 @@ ${parsed.body.trim()}`);
26280
26350
  return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
26281
26351
  }
26282
26352
  function parseRule(ruleFile) {
26283
- const content = fs32.readFileSync(ruleFile, "utf8");
26353
+ const content = fs33.readFileSync(ruleFile, "utf8");
26284
26354
  if (!content.startsWith("---\n")) {
26285
26355
  return { mode: "guidance", body: content };
26286
26356
  }
@@ -26304,14 +26374,14 @@ function isRuleMode(value) {
26304
26374
  }
26305
26375
  function compileOpenCodeRules(sourceRulesDir, lossReport) {
26306
26376
  const appendixParts = [];
26307
- for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
26377
+ for (const ruleFile of ts(path32.join(sourceRulesDir, "*.md")).sort()) {
26308
26378
  const parsed = parseRule(ruleFile);
26309
- const name = path30.basename(ruleFile, ".md");
26379
+ const name = path32.basename(ruleFile, ".md");
26310
26380
  appendixParts.push(`## ${name}
26311
26381
 
26312
26382
  ${parsed.body.trim()}`);
26313
26383
  addLoss(lossReport, "opencode", "rules", {
26314
- source: `rules/${path30.basename(ruleFile)}`,
26384
+ source: `rules/${path32.basename(ruleFile)}`,
26315
26385
  fields: [
26316
26386
  {
26317
26387
  field: "rule",
@@ -26321,7 +26391,7 @@ ${parsed.body.trim()}`);
26321
26391
  "rule",
26322
26392
  "rule-path-scoping"
26323
26393
  ),
26324
- detail: `${path30.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
26394
+ detail: `${path32.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
26325
26395
  }
26326
26396
  ]
26327
26397
  });
@@ -26330,9 +26400,9 @@ ${parsed.body.trim()}`);
26330
26400
  }
26331
26401
  function compileCursorRules(sourceRulesDir, _lossReport) {
26332
26402
  const dotRulesFiles = [];
26333
- for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
26334
- const content = fs32.readFileSync(ruleFile, "utf8");
26335
- const name = path30.basename(ruleFile, ".md");
26403
+ for (const ruleFile of ts(path32.join(sourceRulesDir, "*.md")).sort()) {
26404
+ const content = fs33.readFileSync(ruleFile, "utf8");
26405
+ const name = path32.basename(ruleFile, ".md");
26336
26406
  let frontmatterData = {};
26337
26407
  let body = content;
26338
26408
  if (content.startsWith("---\n")) {
@@ -26361,7 +26431,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
26361
26431
  }
26362
26432
  const marker = formatProvenanceMarker(
26363
26433
  "markdown",
26364
- `rules/${path30.basename(ruleFile)}`,
26434
+ `rules/${path32.basename(ruleFile)}`,
26365
26435
  computeSourceHash(ruleFile),
26366
26436
  "cursor"
26367
26437
  );
@@ -26377,9 +26447,9 @@ ${body}`;
26377
26447
  }
26378
26448
  function compileClineRules(sourceRulesDir, lossReport) {
26379
26449
  const dotRulesFiles = [];
26380
- for (const ruleFile of ts(path30.join(sourceRulesDir, "*.md")).sort()) {
26381
- const content = fs32.readFileSync(ruleFile, "utf8");
26382
- const name = path30.basename(ruleFile, ".md");
26450
+ for (const ruleFile of ts(path32.join(sourceRulesDir, "*.md")).sort()) {
26451
+ const content = fs33.readFileSync(ruleFile, "utf8");
26452
+ const name = path32.basename(ruleFile, ".md");
26383
26453
  let frontmatterData = {};
26384
26454
  let body = content;
26385
26455
  if (content.startsWith("---\n")) {
@@ -26396,13 +26466,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
26396
26466
  }
26397
26467
  const marker = formatProvenanceMarker(
26398
26468
  "markdown",
26399
- `rules/${path30.basename(ruleFile)}`,
26469
+ `rules/${path32.basename(ruleFile)}`,
26400
26470
  computeSourceHash(ruleFile),
26401
26471
  "cline"
26402
26472
  );
26403
26473
  if (frontmatterData.mode === "exec-policy") {
26404
26474
  addLoss(lossReport, "cline", "rules", {
26405
- source: `rules/${path30.basename(ruleFile)}`,
26475
+ source: `rules/${path32.basename(ruleFile)}`,
26406
26476
  fields: [
26407
26477
  {
26408
26478
  field: "mode",
@@ -26412,7 +26482,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
26412
26482
  "mode",
26413
26483
  "rule-mode-downgrade"
26414
26484
  ),
26415
- detail: `${path30.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
26485
+ detail: `${path32.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
26416
26486
  }
26417
26487
  ]
26418
26488
  });
@@ -26453,11 +26523,12 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
26453
26523
  agents: profile.agents,
26454
26524
  skills: profile.skills,
26455
26525
  hooks_shared_file: profile.hooks_shared_file,
26526
+ hook_scripts: profile.hook_scripts,
26456
26527
  mcp_shared_file: profile.mcp_shared_file,
26457
26528
  rules: profile.rules
26458
26529
  };
26459
26530
  const rules = compileRules(
26460
- path31.join(sourceRoot, config.source.rules),
26531
+ path33.join(sourceRoot, config.source.rules),
26461
26532
  "codex",
26462
26533
  mappings,
26463
26534
  lossReport
@@ -26521,6 +26592,26 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
26521
26592
  );
26522
26593
  }
26523
26594
  if (!shouldSkipComponent(options, "hooks")) {
26595
+ outcomes.push(
26596
+ syncHookScriptsBridge({
26597
+ source: path33.resolve(sourceRoot, config.source.hooks),
26598
+ destination: resolveTargetPath(paths.hook_scripts),
26599
+ config,
26600
+ sourceRoot,
26601
+ options,
26602
+ logger,
26603
+ onConflict: () => handleConflict(
26604
+ resolveTargetPath(paths.hook_scripts),
26605
+ config,
26606
+ options,
26607
+ logger,
26608
+ manifest,
26609
+ scopePath
26610
+ ),
26611
+ manifest,
26612
+ scopePath
26613
+ })
26614
+ );
26524
26615
  outcomes.push(
26525
26616
  syncHooks(
26526
26617
  config,
@@ -26602,9 +26693,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
26602
26693
  function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
26603
26694
  const cp = mappings.modelTiers.custom_provider;
26604
26695
  if (!cp) return "";
26605
- const agentsDir = path31.join(sourceRoot, config.source.agents);
26606
- if (!fs33.existsSync(agentsDir)) return "";
26607
- const agentFiles = ts(path31.join(agentsDir, "*.md")).sort();
26696
+ const agentsDir = path33.join(sourceRoot, config.source.agents);
26697
+ if (!fs34.existsSync(agentsDir)) return "";
26698
+ const agentFiles = ts(path33.join(agentsDir, "*.md")).sort();
26608
26699
  const hasProviderAgent = agentFiles.some((agentFile) => {
26609
26700
  const { data } = parseMarkdownFrontmatter(agentFile);
26610
26701
  return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
@@ -26669,7 +26760,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
26669
26760
  }
26670
26761
  ];
26671
26762
  for (const ruleFile of rules.dotRulesFiles) {
26672
- const destination = path31.join(rulesRoot, ruleFile.name);
26763
+ const destination = path33.join(rulesRoot, ruleFile.name);
26673
26764
  if (options.dryRun) {
26674
26765
  logger.info(`[dry-run] rules: write ${destination}`);
26675
26766
  outcomes.push({
@@ -26697,15 +26788,15 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
26697
26788
  return outcomes;
26698
26789
  }
26699
26790
  function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
26700
- const source = path31.join(sourceRoot, config.source.instructions);
26791
+ const source = path33.join(sourceRoot, config.source.instructions);
26701
26792
  const destination = resolveTargetPath(paths.instructions);
26702
- const composed = `${fs33.readFileSync(source, "utf8").trim()}
26793
+ const composed = `${fs34.readFileSync(source, "utf8").trim()}
26703
26794
 
26704
26795
  --- tangyr managed rules ---
26705
26796
  ${agentsAppendix}`.trim();
26706
26797
  const marker = formatProvenanceMarker(
26707
26798
  "markdown",
26708
- path31.basename(config.source.instructions),
26799
+ path33.basename(config.source.instructions),
26709
26800
  hashString(composed),
26710
26801
  "codex"
26711
26802
  );
@@ -26732,9 +26823,9 @@ ${composed}
26732
26823
  );
26733
26824
  }
26734
26825
  function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
26735
- const source = path31.resolve(sourceRoot, config.source.skills);
26826
+ const source = path33.resolve(sourceRoot, config.source.skills);
26736
26827
  const destination = resolveTargetPath(paths.skills);
26737
- if (!fs33.existsSync(source)) {
26828
+ if (!fs34.existsSync(source)) {
26738
26829
  return skippedMissingSource("skills", source);
26739
26830
  }
26740
26831
  if (options.dryRun) {
@@ -26742,7 +26833,7 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
26742
26833
  return { component: "skills", status: "dry-run", path: destination };
26743
26834
  }
26744
26835
  const artifactClass = classifyArtifact(destination, config, sourceRoot);
26745
- if (artifactClass === "managed-symlink" && isSymlinkTo(destination, source)) {
26836
+ if (artifactClass === "managed-symlink" && isSymlinkTo2(destination, source)) {
26746
26837
  return {
26747
26838
  component: "skills",
26748
26839
  status: "skipped-current",
@@ -26750,29 +26841,29 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
26750
26841
  };
26751
26842
  }
26752
26843
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
26753
- fs33.unlinkSync(destination);
26844
+ fs34.unlinkSync(destination);
26754
26845
  logger.verbose(`Skills: created skills path ${destination}`);
26755
26846
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
26756
26847
  return { component: "skills", status: "conflict", path: destination };
26757
26848
  } else if (artifactClass === "managed-symlink") {
26758
- fs33.unlinkSync(destination);
26849
+ fs34.unlinkSync(destination);
26759
26850
  }
26760
- ensureDir(path31.dirname(destination));
26851
+ ensureDir(path33.dirname(destination));
26761
26852
  createRelativeSymlink(source, destination, "dir");
26762
26853
  logger.verbose(`Skills: created skills path ${destination}`);
26763
26854
  return { component: "skills", status: "success", path: destination };
26764
26855
  }
26765
26856
  function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
26766
- const sourceAgentsRoot = path31.join(sourceRoot, config.source.agents);
26767
- if (!fs33.existsSync(sourceAgentsRoot)) {
26857
+ const sourceAgentsRoot = path33.join(sourceRoot, config.source.agents);
26858
+ if (!fs34.existsSync(sourceAgentsRoot)) {
26768
26859
  return [skippedMissingSource("agents", sourceAgentsRoot)];
26769
26860
  }
26770
- const sourceAgents = ts(path31.join(sourceAgentsRoot, "*.md")).sort();
26861
+ const sourceAgents = ts(path33.join(sourceAgentsRoot, "*.md")).sort();
26771
26862
  const agentsRoot = resolveTargetPath(paths.agents);
26772
26863
  return sourceAgents.map((agentFile) => {
26773
- const destination = path31.join(
26864
+ const destination = path33.join(
26774
26865
  agentsRoot,
26775
- `${path31.basename(agentFile, ".md")}.toml`
26866
+ `${path33.basename(agentFile, ".md")}.toml`
26776
26867
  );
26777
26868
  const compiled = compileAgent(
26778
26869
  agentFile,
@@ -26806,7 +26897,21 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
26806
26897
  logger.warn(message);
26807
26898
  return { component: "hooks", status: "skipped", path: message };
26808
26899
  }
26809
- const hooksSource = loadKitHooksSource(sourceRoot, config);
26900
+ const scripts = hookScriptsDir(
26901
+ resolveTargetPath(paths.hook_scripts),
26902
+ "codex"
26903
+ );
26904
+ const hooksSource = loadKitHooksSource(sourceRoot, config, scripts.prefix);
26905
+ if (scripts.machineLocal) {
26906
+ addInformational(
26907
+ lossReport,
26908
+ "codex",
26909
+ "hooks",
26910
+ hooksSourceLabel(sourceRoot, config),
26911
+ "warning",
26912
+ machineLocalScriptPathNotice("codex", scripts.prefix)
26913
+ );
26914
+ }
26810
26915
  if (!hooksSource) {
26811
26916
  return skippedMissingSource(
26812
26917
  "hooks",
@@ -26835,7 +26940,7 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
26835
26940
  destination,
26836
26941
  hostHooks,
26837
26942
  stringifyJson2,
26838
- !fs33.existsSync(destination),
26943
+ !fs34.existsSync(destination),
26839
26944
  logger
26840
26945
  );
26841
26946
  return {
@@ -26848,7 +26953,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
26848
26953
  const source = resolveMcpSourceFile(sourceRoot, config);
26849
26954
  const sourceLabel = mcpSourceLabel(config);
26850
26955
  const destination = resolveTargetPath(paths.mcp_shared_file);
26851
- if (!fs33.existsSync(source)) {
26956
+ if (!fs34.existsSync(source)) {
26852
26957
  if (providerToml && !options.dryRun) {
26853
26958
  const changed2 = writeTomlManagedSection(
26854
26959
  destination,
@@ -26863,7 +26968,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
26863
26968
  }
26864
26969
  return skippedMissingSource("mcp", source);
26865
26970
  }
26866
- const sourceMcpJson = JSON.parse(fs33.readFileSync(source, "utf8"));
26971
+ const sourceMcpJson = JSON.parse(fs34.readFileSync(source, "utf8"));
26867
26972
  const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
26868
26973
  const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
26869
26974
  if (options.dryRun) {
@@ -26885,12 +26990,12 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
26885
26990
  if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
26886
26991
  return { component, status: "conflict", path: destination };
26887
26992
  }
26888
- ensureDir(path31.dirname(destination));
26889
- fs33.writeFileSync(destination, content);
26993
+ ensureDir(path33.dirname(destination));
26994
+ fs34.writeFileSync(destination, content);
26890
26995
  return { component, status: "success", path: destination };
26891
26996
  }
26892
26997
  function writeTomlManagedSection(destination, managedContent, logger) {
26893
- const current = fs33.existsSync(destination) ? fs33.readFileSync(destination, "utf8") : "";
26998
+ const current = fs34.existsSync(destination) ? fs34.readFileSync(destination, "utf8") : "";
26894
26999
  const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
26895
27000
  if (isFirstWrite) {
26896
27001
  logger.warn(
@@ -26906,8 +27011,8 @@ ${managedMcpEnd}
26906
27011
  if (current === next.trimStart()) {
26907
27012
  return false;
26908
27013
  }
26909
- ensureDir(path31.dirname(destination));
26910
- fs33.writeFileSync(destination, next.trimStart());
27014
+ ensureDir(path33.dirname(destination));
27015
+ fs34.writeFileSync(destination, next.trimStart());
26911
27016
  return true;
26912
27017
  }
26913
27018
  function removeManagedTomlSection(content) {
@@ -26934,16 +27039,16 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
26934
27039
  backupFile(destination, manifest);
26935
27040
  writeManifest(scopePath, manifest);
26936
27041
  } else {
26937
- fs33.renameSync(destination, `${destination}.bak.${Date.now()}`);
27042
+ fs34.renameSync(destination, `${destination}.bak.${Date.now()}`);
26938
27043
  }
26939
27044
  return true;
26940
27045
  }
26941
- fs33.rmSync(destination, { recursive: true, force: true });
27046
+ fs34.rmSync(destination, { recursive: true, force: true });
26942
27047
  return true;
26943
27048
  }
26944
27049
  function isCompiledCurrent(destination, expectedContent, expectedHash) {
26945
27050
  try {
26946
- const current = fs33.readFileSync(destination, "utf8");
27051
+ const current = fs34.readFileSync(destination, "utf8");
26947
27052
  const marker = extractProvenanceMarker(current);
26948
27053
  return expectedHash ? marker?.hash === expectedHash && marker.target === "codex" && current === expectedContent : current === expectedContent;
26949
27054
  } catch {
@@ -26960,18 +27065,18 @@ function skippedMissingSource(component, source) {
26960
27065
  function shouldSkipComponent(options, component) {
26961
27066
  return Boolean(options.component && options.component !== component);
26962
27067
  }
26963
- function isSymlinkTo(linkPath, source) {
27068
+ function isSymlinkTo2(linkPath, source) {
26964
27069
  try {
26965
- return fs33.realpathSync(linkPath) === fs33.realpathSync(source);
27070
+ return fs34.realpathSync(linkPath) === fs34.realpathSync(source);
26966
27071
  } catch {
26967
27072
  return false;
26968
27073
  }
26969
27074
  }
26970
27075
  function readJsonObject3(filePath) {
26971
- if (!fs33.existsSync(filePath)) {
27076
+ if (!fs34.existsSync(filePath)) {
26972
27077
  return {};
26973
27078
  }
26974
- const parsed = JSON.parse(fs33.readFileSync(filePath, "utf8"));
27079
+ const parsed = JSON.parse(fs34.readFileSync(filePath, "utf8"));
26975
27080
  return isRecord4(parsed) ? parsed : {};
26976
27081
  }
26977
27082
  function stringifyJson2(value) {
@@ -26987,16 +27092,16 @@ function hashString(value) {
26987
27092
 
26988
27093
  // src/adapters/copilot.ts
26989
27094
  import crypto6 from "crypto";
26990
- import fs34 from "fs";
26991
- import path33 from "path";
27095
+ import fs35 from "fs";
27096
+ import path35 from "path";
26992
27097
 
26993
27098
  // src/compiler/commands.ts
26994
27099
  var import_yaml10 = __toESM(require_dist(), 1);
26995
- import path32 from "path";
27100
+ import path34 from "path";
26996
27101
  function compileCommandPrompt(sourceFile) {
26997
27102
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
26998
- const relativeSource = `commands/${path32.basename(sourceFile)}`;
26999
- const fields = promptFrontmatter(data, path32.basename(sourceFile, ".md"));
27103
+ const relativeSource = `commands/${path34.basename(sourceFile)}`;
27104
+ const fields = promptFrontmatter(data, path34.basename(sourceFile, ".md"));
27000
27105
  const marker = formatProvenanceMarker(
27001
27106
  "markdown",
27002
27107
  relativeSource,
@@ -27048,6 +27153,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
27048
27153
  skills: profile.skills,
27049
27154
  prompts: profile.prompts,
27050
27155
  hooks: profile.hooks,
27156
+ hook_scripts: profile.hook_scripts,
27051
27157
  mcp_shared_file: profile.mcp_shared_file
27052
27158
  };
27053
27159
  const outcomes = [];
@@ -27108,6 +27214,26 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
27108
27214
  );
27109
27215
  }
27110
27216
  if (!shouldSkipComponent2(options, "hooks")) {
27217
+ outcomes.push(
27218
+ syncHookScriptsBridge({
27219
+ source: path35.resolve(sourceRoot, config.source.hooks),
27220
+ destination: resolveTargetPath(paths.hook_scripts),
27221
+ config,
27222
+ sourceRoot,
27223
+ options,
27224
+ logger,
27225
+ onConflict: () => handleConflict2(
27226
+ resolveTargetPath(paths.hook_scripts),
27227
+ config,
27228
+ options,
27229
+ logger,
27230
+ manifest,
27231
+ scopePath
27232
+ ),
27233
+ manifest,
27234
+ scopePath
27235
+ })
27236
+ );
27111
27237
  outcomes.push(
27112
27238
  syncHooks2(
27113
27239
  config,
@@ -27171,13 +27297,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
27171
27297
  }
27172
27298
  function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
27173
27299
  if (!mappings.modelTiers.custom_provider) return;
27174
- const agentsDir = path33.join(sourceRoot, config.source.agents);
27175
- if (!fs34.existsSync(agentsDir)) return;
27176
- for (const agentFile of ts(path33.join(agentsDir, "*.md")).sort()) {
27300
+ const agentsDir = path35.join(sourceRoot, config.source.agents);
27301
+ if (!fs35.existsSync(agentsDir)) return;
27302
+ for (const agentFile of ts(path35.join(agentsDir, "*.md")).sort()) {
27177
27303
  const { data } = parseMarkdownFrontmatter(agentFile);
27178
27304
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
27179
27305
  if (hasProvider) {
27180
- const basename = path33.basename(agentFile);
27306
+ const basename = path35.basename(agentFile);
27181
27307
  addLoss(lossReport, "copilot", "agents", {
27182
27308
  source: `agents/${basename}`,
27183
27309
  fields: [
@@ -27202,23 +27328,23 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
27202
27328
  logger.verbose(message);
27203
27329
  return [{ component: "instructions", status: "skipped", path: message }];
27204
27330
  }
27205
- const source = path33.resolve(sourceRoot, config.source.instructions);
27206
- if (!fs34.existsSync(source)) {
27331
+ const source = path35.resolve(sourceRoot, config.source.instructions);
27332
+ if (!fs35.existsSync(source)) {
27207
27333
  return [skippedMissingSource2("instructions", source)];
27208
27334
  }
27209
- const rawContent = fs34.readFileSync(source, "utf8");
27335
+ const rawContent = fs35.readFileSync(source, "utf8");
27210
27336
  const contentHash = hashString2(rawContent);
27211
27337
  const marker = formatProvenanceMarker(
27212
27338
  "markdown",
27213
- path33.basename(config.source.instructions),
27339
+ path35.basename(config.source.instructions),
27214
27340
  contentHash,
27215
27341
  "copilot"
27216
27342
  );
27217
27343
  const composedContent = `${marker}
27218
27344
  ${rawContent}`;
27219
27345
  const projectRoot = options.projectRoot ?? process.cwd();
27220
- const agentsMdDest = path33.resolve(projectRoot, "AGENTS.md");
27221
- const mirrorDest = path33.resolve(
27346
+ const agentsMdDest = path35.resolve(projectRoot, "AGENTS.md");
27347
+ const mirrorDest = path35.resolve(
27222
27348
  projectRoot,
27223
27349
  ".github",
27224
27350
  "copilot-instructions.md"
@@ -27272,17 +27398,17 @@ function writeInstructionsFile(component, destination, content, contentHash, con
27272
27398
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
27273
27399
  return { component, status: "conflict", path: destination };
27274
27400
  }
27275
- ensureDir(path33.dirname(destination));
27276
- fs34.writeFileSync(destination, content);
27401
+ ensureDir(path35.dirname(destination));
27402
+ fs35.writeFileSync(destination, content);
27277
27403
  return { component, status: "success", path: destination };
27278
27404
  }
27279
27405
  function hashString2(value) {
27280
27406
  return `sha256:${crypto6.createHash("sha256").update(value).digest("hex")}`;
27281
27407
  }
27282
27408
  function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
27283
- const source = path33.resolve(sourceRoot, config.source.skills);
27409
+ const source = path35.resolve(sourceRoot, config.source.skills);
27284
27410
  const destination = resolveTargetPath(paths.skills);
27285
- if (!fs34.existsSync(source)) {
27411
+ if (!fs35.existsSync(source)) {
27286
27412
  return skippedMissingSource2("skills", source);
27287
27413
  }
27288
27414
  if (options.dryRun) {
@@ -27290,7 +27416,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
27290
27416
  return { component: "skills", status: "dry-run", path: destination };
27291
27417
  }
27292
27418
  const artifactClass = classifyArtifact(destination, config, sourceRoot);
27293
- if (artifactClass === "managed-symlink" && isSymlinkTo2(destination, source)) {
27419
+ if (artifactClass === "managed-symlink" && isSymlinkTo3(destination, source)) {
27294
27420
  return {
27295
27421
  component: "skills",
27296
27422
  status: "skipped-current",
@@ -27298,27 +27424,27 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
27298
27424
  };
27299
27425
  }
27300
27426
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
27301
- fs34.unlinkSync(destination);
27427
+ fs35.unlinkSync(destination);
27302
27428
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
27303
27429
  return { component: "skills", status: "conflict", path: destination };
27304
27430
  } else if (artifactClass === "managed-symlink") {
27305
- fs34.unlinkSync(destination);
27431
+ fs35.unlinkSync(destination);
27306
27432
  }
27307
- ensureDir(path33.dirname(destination));
27433
+ ensureDir(path35.dirname(destination));
27308
27434
  createRelativeSymlink(source, destination, "dir");
27309
27435
  return { component: "skills", status: "success", path: destination };
27310
27436
  }
27311
27437
  function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
27312
- const sourceAgentsRoot = path33.join(sourceRoot, config.source.agents);
27313
- if (!fs34.existsSync(sourceAgentsRoot)) {
27438
+ const sourceAgentsRoot = path35.join(sourceRoot, config.source.agents);
27439
+ if (!fs35.existsSync(sourceAgentsRoot)) {
27314
27440
  return [skippedMissingSource2("agents", sourceAgentsRoot)];
27315
27441
  }
27316
- const sourceAgents = ts(path33.join(sourceAgentsRoot, "*.md")).sort();
27442
+ const sourceAgents = ts(path35.join(sourceAgentsRoot, "*.md")).sort();
27317
27443
  const agentsRoot = resolveTargetPath(paths.agents);
27318
27444
  return sourceAgents.map((agentFile) => {
27319
- const destination = path33.join(
27445
+ const destination = path35.join(
27320
27446
  agentsRoot,
27321
- `${path33.basename(agentFile, ".md")}.agent.md`
27447
+ `${path35.basename(agentFile, ".md")}.agent.md`
27322
27448
  );
27323
27449
  const compiled = compileAgent(
27324
27450
  agentFile,
@@ -27346,16 +27472,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
27346
27472
  });
27347
27473
  }
27348
27474
  function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
27349
- const sourceCommandsRoot = path33.join(sourceRoot, config.source.commands);
27350
- if (!fs34.existsSync(sourceCommandsRoot)) {
27475
+ const sourceCommandsRoot = path35.join(sourceRoot, config.source.commands);
27476
+ if (!fs35.existsSync(sourceCommandsRoot)) {
27351
27477
  return [skippedMissingSource2("commands", sourceCommandsRoot)];
27352
27478
  }
27353
- const sourceCommands = ts(path33.join(sourceCommandsRoot, "*.md")).sort();
27479
+ const sourceCommands = ts(path35.join(sourceCommandsRoot, "*.md")).sort();
27354
27480
  const promptsRoot = resolveTargetPath(paths.prompts);
27355
27481
  return sourceCommands.map((commandFile) => {
27356
- const destination = path33.join(
27482
+ const destination = path35.join(
27357
27483
  promptsRoot,
27358
- `${path33.basename(commandFile, ".md")}.prompt.md`
27484
+ `${path35.basename(commandFile, ".md")}.prompt.md`
27359
27485
  );
27360
27486
  const compiled = compileCommandPrompt(commandFile);
27361
27487
  if (options.dryRun) {
@@ -27379,11 +27505,25 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
27379
27505
  });
27380
27506
  }
27381
27507
  function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, logger) {
27382
- const destination = path33.join(
27508
+ const destination = path35.join(
27383
27509
  resolveTargetPath(paths.hooks),
27384
27510
  "tangyr-managed.json"
27385
27511
  );
27386
- const hooksSource = loadKitHooksSource(sourceRoot, config);
27512
+ const scripts = hookScriptsDir(
27513
+ resolveTargetPath(paths.hook_scripts),
27514
+ "copilot"
27515
+ );
27516
+ const hooksSource = loadKitHooksSource(sourceRoot, config, scripts.prefix);
27517
+ if (scripts.machineLocal) {
27518
+ addInformational(
27519
+ lossReport,
27520
+ "copilot",
27521
+ "hooks",
27522
+ hooksSourceLabel(sourceRoot, config),
27523
+ "warning",
27524
+ machineLocalScriptPathNotice("copilot", scripts.prefix)
27525
+ );
27526
+ }
27387
27527
  if (!hooksSource) {
27388
27528
  return skippedMissingSource2(
27389
27529
  "hooks",
@@ -27427,10 +27567,10 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger) {
27427
27567
  const source = resolveMcpSourceFile(sourceRoot, config);
27428
27568
  const sourceLabel = mcpSourceLabel(config);
27429
27569
  const destination = resolveTargetPath(paths.mcp_shared_file);
27430
- if (!fs34.existsSync(source)) {
27570
+ if (!fs35.existsSync(source)) {
27431
27571
  return skippedMissingSource2("mcp", source);
27432
27572
  }
27433
- const sourceMcpJson = JSON.parse(fs34.readFileSync(source, "utf8"));
27573
+ const sourceMcpJson = JSON.parse(fs35.readFileSync(source, "utf8"));
27434
27574
  const compiled = compileMcp(
27435
27575
  sourceMcpJson,
27436
27576
  "copilot",
@@ -27460,13 +27600,13 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
27460
27600
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
27461
27601
  return { component, status: "conflict", path: destination };
27462
27602
  }
27463
- ensureDir(path33.dirname(destination));
27464
- fs34.writeFileSync(destination, content);
27603
+ ensureDir(path35.dirname(destination));
27604
+ fs35.writeFileSync(destination, content);
27465
27605
  return { component, status: "success", path: destination };
27466
27606
  }
27467
27607
  function isCompiledCurrent2(destination, expectedContent, expectedHash) {
27468
27608
  try {
27469
- const current = fs34.readFileSync(destination, "utf8");
27609
+ const current = fs35.readFileSync(destination, "utf8");
27470
27610
  const marker = extractProvenanceMarker(current);
27471
27611
  return expectedHash ? marker?.hash === expectedHash && marker.target === "copilot" && current === expectedContent : current === expectedContent;
27472
27612
  } catch {
@@ -27489,11 +27629,11 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
27489
27629
  backupFile(destination, manifest);
27490
27630
  writeManifest(scopePath, manifest);
27491
27631
  } else {
27492
- fs34.renameSync(destination, `${destination}.bak.${Date.now()}`);
27632
+ fs35.renameSync(destination, `${destination}.bak.${Date.now()}`);
27493
27633
  }
27494
27634
  return true;
27495
27635
  }
27496
- fs34.rmSync(destination, { recursive: true, force: true });
27636
+ fs35.rmSync(destination, { recursive: true, force: true });
27497
27637
  return true;
27498
27638
  }
27499
27639
  function shouldSkipComponent2(options, component) {
@@ -27502,12 +27642,12 @@ function shouldSkipComponent2(options, component) {
27502
27642
  function cleanupLegacyAgents(paths, options, logger) {
27503
27643
  const currentAgentsRoot = resolveTargetPath(paths.agents);
27504
27644
  const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
27505
- if (path33.resolve(currentAgentsRoot) === path33.resolve(legacyAgentsRoot)) {
27645
+ if (path35.resolve(currentAgentsRoot) === path35.resolve(legacyAgentsRoot)) {
27506
27646
  return [];
27507
27647
  }
27508
27648
  const outcomes = [];
27509
27649
  for (const filePath of ts(
27510
- path33.join(legacyAgentsRoot, "*.agent.md")
27650
+ path35.join(legacyAgentsRoot, "*.agent.md")
27511
27651
  ).sort()) {
27512
27652
  if (!isCopilotManagedCompiledFile(filePath)) {
27513
27653
  continue;
@@ -27517,14 +27657,14 @@ function cleanupLegacyAgents(paths, options, logger) {
27517
27657
  outcomes.push({ component: "agents", status: "dry-run", path: filePath });
27518
27658
  continue;
27519
27659
  }
27520
- fs34.rmSync(filePath, { force: true });
27660
+ fs35.rmSync(filePath, { force: true });
27521
27661
  outcomes.push({ component: "agents", status: "success", path: filePath });
27522
27662
  }
27523
27663
  return outcomes;
27524
27664
  }
27525
27665
  function isCopilotManagedCompiledFile(filePath) {
27526
27666
  try {
27527
- return extractProvenanceMarker(fs34.readFileSync(filePath, "utf8"))?.target === "copilot";
27667
+ return extractProvenanceMarker(fs35.readFileSync(filePath, "utf8"))?.target === "copilot";
27528
27668
  } catch {
27529
27669
  return false;
27530
27670
  }
@@ -27536,9 +27676,9 @@ function skippedMissingSource2(component, source) {
27536
27676
  path: `${source}: source not configured`
27537
27677
  };
27538
27678
  }
27539
- function isSymlinkTo2(linkPath, source) {
27679
+ function isSymlinkTo3(linkPath, source) {
27540
27680
  try {
27541
- return fs34.realpathSync(linkPath) === fs34.realpathSync(source);
27681
+ return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
27542
27682
  } catch {
27543
27683
  return false;
27544
27684
  }
@@ -27546,8 +27686,8 @@ function isSymlinkTo2(linkPath, source) {
27546
27686
 
27547
27687
  // src/adapters/cursor.ts
27548
27688
  import crypto7 from "crypto";
27549
- import fs35 from "fs";
27550
- import path34 from "path";
27689
+ import fs36 from "fs";
27690
+ import path36 from "path";
27551
27691
  function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
27552
27692
  const scope = options.scope ?? "global";
27553
27693
  const profile = resolveTargetPaths({
@@ -27562,6 +27702,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
27562
27702
  skills: profile.skills,
27563
27703
  skills_shared: profile.skills_shared,
27564
27704
  hooks_file: profile.hooks_file,
27705
+ hook_scripts: profile.hook_scripts,
27565
27706
  mcp_file: profile.mcp_file,
27566
27707
  permissions_file: profile.permissions_file
27567
27708
  };
@@ -27656,6 +27797,26 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
27656
27797
  );
27657
27798
  }
27658
27799
  if (!shouldSkipComponent3(options, "hooks")) {
27800
+ outcomes.push(
27801
+ syncHookScriptsBridge({
27802
+ source: path36.resolve(sourceRoot, config.source.hooks),
27803
+ destination: resolveTargetPath(paths.hook_scripts),
27804
+ config,
27805
+ sourceRoot,
27806
+ options,
27807
+ logger,
27808
+ onConflict: () => handleConflict3(
27809
+ resolveTargetPath(paths.hook_scripts),
27810
+ config,
27811
+ options,
27812
+ logger,
27813
+ manifest,
27814
+ scopePath
27815
+ ),
27816
+ manifest,
27817
+ scopePath
27818
+ })
27819
+ );
27659
27820
  outcomes.push(
27660
27821
  syncHooks3(
27661
27822
  config,
@@ -27698,9 +27859,9 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
27698
27859
  return { target: "cursor", outcomes };
27699
27860
  }
27700
27861
  function syncInstructions2(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
27701
- const source = path34.join(sourceRoot, config.source.instructions);
27862
+ const source = path36.join(sourceRoot, config.source.instructions);
27702
27863
  const destination = resolveTargetPath(paths.instructions);
27703
- const baseContent = fs35.existsSync(source) ? fs35.readFileSync(source, "utf8").trim() : "";
27864
+ const baseContent = fs36.existsSync(source) ? fs36.readFileSync(source, "utf8").trim() : "";
27704
27865
  const personaContent = extractPrimaryPersonaContent(
27705
27866
  config,
27706
27867
  sourceRoot,
@@ -27713,7 +27874,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
27713
27874
  ${personaContent}`.trim() : baseContent;
27714
27875
  const marker = formatProvenanceMarker(
27715
27876
  "markdown",
27716
- path34.basename(config.source.instructions),
27877
+ path36.basename(config.source.instructions),
27717
27878
  hashString3(composed),
27718
27879
  "cursor"
27719
27880
  );
@@ -27738,11 +27899,11 @@ ${composed}
27738
27899
  );
27739
27900
  }
27740
27901
  function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
27741
- const agentsDir = path34.join(sourceRoot, config.source.agents);
27742
- if (!fs35.existsSync(agentsDir)) {
27902
+ const agentsDir = path36.join(sourceRoot, config.source.agents);
27903
+ if (!fs36.existsSync(agentsDir)) {
27743
27904
  return null;
27744
27905
  }
27745
- const agentFiles = ts(path34.join(agentsDir, "*.md")).sort();
27906
+ const agentFiles = ts(path36.join(agentsDir, "*.md")).sort();
27746
27907
  if (agentFiles.length === 0) {
27747
27908
  return null;
27748
27909
  }
@@ -27765,7 +27926,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
27765
27926
  return null;
27766
27927
  }
27767
27928
  addLoss(lossReport, "cursor", "instructions", {
27768
- source: `agents/${path34.basename(primaryFile)}`,
27929
+ source: `agents/${path36.basename(primaryFile)}`,
27769
27930
  fields: [
27770
27931
  {
27771
27932
  field: "persona",
@@ -27775,23 +27936,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
27775
27936
  "persona",
27776
27937
  "instructions-shim"
27777
27938
  ),
27778
- detail: `Primary persona from ${path34.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
27939
+ detail: `Primary persona from ${path36.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
27779
27940
  }
27780
27941
  ]
27781
27942
  });
27782
27943
  return body.trim();
27783
27944
  }
27784
27945
  function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
27785
- const sourceAgentsRoot = path34.join(sourceRoot, config.source.agents);
27786
- if (!fs35.existsSync(sourceAgentsRoot)) {
27946
+ const sourceAgentsRoot = path36.join(sourceRoot, config.source.agents);
27947
+ if (!fs36.existsSync(sourceAgentsRoot)) {
27787
27948
  return [skippedMissingSource3("agents", sourceAgentsRoot)];
27788
27949
  }
27789
- const sourceAgents = ts(path34.join(sourceAgentsRoot, "*.md")).sort();
27950
+ const sourceAgents = ts(path36.join(sourceAgentsRoot, "*.md")).sort();
27790
27951
  const agentsRoot = resolveTargetPath(paths.agents);
27791
27952
  return sourceAgents.map((agentFile) => {
27792
- const destination = path34.join(
27953
+ const destination = path36.join(
27793
27954
  agentsRoot,
27794
- `${path34.basename(agentFile, ".md")}.md`
27955
+ `${path36.basename(agentFile, ".md")}.md`
27795
27956
  );
27796
27957
  let compiled;
27797
27958
  try {
@@ -27832,14 +27993,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
27832
27993
  });
27833
27994
  }
27834
27995
  function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
27835
- const sourceRulesDir = path34.join(sourceRoot, config.source.rules);
27836
- if (!fs35.existsSync(sourceRulesDir)) {
27996
+ const sourceRulesDir = path36.join(sourceRoot, config.source.rules);
27997
+ if (!fs36.existsSync(sourceRulesDir)) {
27837
27998
  return [skippedMissingSource3("rules", sourceRulesDir)];
27838
27999
  }
27839
28000
  const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
27840
28001
  const rulesDir = resolveTargetPath(paths.rules);
27841
28002
  return compiled.dotRulesFiles.map(({ name, content }) => {
27842
- const destination = path34.join(rulesDir, name);
28003
+ const destination = path36.join(rulesDir, name);
27843
28004
  if (options.dryRun) {
27844
28005
  logger.info(`[dry-run] rules: write ${destination}`);
27845
28006
  return {
@@ -27863,17 +28024,17 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
27863
28024
  });
27864
28025
  }
27865
28026
  function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
27866
- const sourceCommandsRoot = path34.join(sourceRoot, config.source.commands);
27867
- if (!fs35.existsSync(sourceCommandsRoot)) {
28027
+ const sourceCommandsRoot = path36.join(sourceRoot, config.source.commands);
28028
+ if (!fs36.existsSync(sourceCommandsRoot)) {
27868
28029
  return [skippedMissingSource3("commands", sourceCommandsRoot)];
27869
28030
  }
27870
- const sourceCommands = ts(path34.join(sourceCommandsRoot, "*.md")).sort();
28031
+ const sourceCommands = ts(path36.join(sourceCommandsRoot, "*.md")).sort();
27871
28032
  const skillsRoot = resolveTargetPath(paths.skills);
27872
28033
  return sourceCommands.map((commandFile) => {
27873
- const baseName = path34.basename(commandFile, ".md");
27874
- const destination = path34.join(skillsRoot, baseName, "SKILL.md");
27875
- const commandContent = fs35.readFileSync(commandFile, "utf8");
27876
- const relativeSource = `commands/${path34.basename(commandFile)}`;
28034
+ const baseName = path36.basename(commandFile, ".md");
28035
+ const destination = path36.join(skillsRoot, baseName, "SKILL.md");
28036
+ const commandContent = fs36.readFileSync(commandFile, "utf8");
28037
+ const relativeSource = `commands/${path36.basename(commandFile)}`;
27877
28038
  const marker = formatProvenanceMarker(
27878
28039
  "markdown",
27879
28040
  relativeSource,
@@ -27912,8 +28073,8 @@ ${commandContent.trim()}
27912
28073
  });
27913
28074
  }
27914
28075
  function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
27915
- const source = path34.resolve(sourceRoot, config.source.skills);
27916
- if (!fs35.existsSync(source)) {
28076
+ const source = path36.resolve(sourceRoot, config.source.skills);
28077
+ if (!fs36.existsSync(source)) {
27917
28078
  return skippedMissingSource3(component, source);
27918
28079
  }
27919
28080
  if (options.dryRun) {
@@ -27923,22 +28084,22 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
27923
28084
  }
27924
28085
  if (asSymlink) {
27925
28086
  const artifactClass = classifyArtifact(destination, config, sourceRoot);
27926
- if (artifactClass === "managed-symlink" && isSymlinkTo3(destination, source)) {
28087
+ if (artifactClass === "managed-symlink" && isSymlinkTo4(destination, source)) {
27927
28088
  return { component, status: "skipped-current", path: destination };
27928
28089
  }
27929
28090
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
27930
- fs35.unlinkSync(destination);
28091
+ fs36.unlinkSync(destination);
27931
28092
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
27932
28093
  return { component, status: "conflict", path: destination };
27933
28094
  } else if (artifactClass === "managed-symlink") {
27934
- fs35.unlinkSync(destination);
28095
+ fs36.unlinkSync(destination);
27935
28096
  }
27936
- ensureDir(path34.dirname(destination));
28097
+ ensureDir(path36.dirname(destination));
27937
28098
  createRelativeSymlink(source, destination, "dir");
27938
28099
  logger.verbose(`Skills: created shared skills symlink ${destination}`);
27939
28100
  return { component, status: "success", path: destination };
27940
28101
  }
27941
- if (fs35.existsSync(destination)) {
28102
+ if (fs36.existsSync(destination)) {
27942
28103
  return { component, status: "skipped-current", path: destination };
27943
28104
  }
27944
28105
  ensureDir(destination);
@@ -27946,7 +28107,21 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
27946
28107
  return { component, status: "success", path: destination };
27947
28108
  }
27948
28109
  function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
27949
- const hooksSource = loadKitHooksSource(sourceRoot, config);
28110
+ const scripts = hookScriptsDir(
28111
+ resolveTargetPath(paths.hook_scripts),
28112
+ "cursor"
28113
+ );
28114
+ const hooksSource = loadKitHooksSource(sourceRoot, config, scripts.prefix);
28115
+ if (scripts.machineLocal) {
28116
+ addInformational(
28117
+ lossReport,
28118
+ "cursor",
28119
+ "hooks",
28120
+ hooksSourceLabel(sourceRoot, config),
28121
+ "warning",
28122
+ machineLocalScriptPathNotice("cursor", scripts.prefix)
28123
+ );
28124
+ }
27950
28125
  const source = hooksSource?.path ?? resolveHooksSourceDir(sourceRoot, config);
27951
28126
  const sourceLabel = hooksSource?.label ?? hooksSourceLabel(sourceRoot, config);
27952
28127
  const destination = resolveTargetPath(paths.hooks_file);
@@ -27964,18 +28139,18 @@ function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, lo
27964
28139
  }
27965
28140
  const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
27966
28141
  `;
27967
- ensureDir(path34.dirname(destination));
27968
- fs35.writeFileSync(destination, hooksFileContent);
28142
+ ensureDir(path36.dirname(destination));
28143
+ fs36.writeFileSync(destination, hooksFileContent);
27969
28144
  return { component: "hooks", status: "success", path: destination };
27970
28145
  }
27971
28146
  function syncMcp3(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
27972
28147
  const source = resolveMcpSourceFile(sourceRoot, config);
27973
28148
  const sourceLabel = mcpSourceLabel(config);
27974
28149
  const destination = resolveTargetPath(paths.mcp_file);
27975
- if (!fs35.existsSync(source)) {
28150
+ if (!fs36.existsSync(source)) {
27976
28151
  return skippedMissingSource3("mcp", source);
27977
28152
  }
27978
- const sourceMcpJson = JSON.parse(fs35.readFileSync(source, "utf8"));
28153
+ const sourceMcpJson = JSON.parse(fs36.readFileSync(source, "utf8"));
27979
28154
  const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
27980
28155
  if (options.dryRun) {
27981
28156
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -28026,13 +28201,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
28026
28201
  );
28027
28202
  }
28028
28203
  function syncProviderPin(config, sourceRoot, lossReport) {
28029
- const agentsDir = path34.join(sourceRoot, config.source.agents);
28030
- if (!fs35.existsSync(agentsDir)) return;
28031
- for (const agentFile of ts(path34.join(agentsDir, "*.md")).sort()) {
28204
+ const agentsDir = path36.join(sourceRoot, config.source.agents);
28205
+ if (!fs36.existsSync(agentsDir)) return;
28206
+ for (const agentFile of ts(path36.join(agentsDir, "*.md")).sort()) {
28032
28207
  const { data } = parseMarkdownFrontmatter(agentFile);
28033
28208
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
28034
28209
  if (hasCustomProvider) {
28035
- const relativeSource = `agents/${path34.basename(agentFile)}`;
28210
+ const relativeSource = `agents/${path36.basename(agentFile)}`;
28036
28211
  addLoss(lossReport, "cursor", "agents", {
28037
28212
  source: relativeSource,
28038
28213
  fields: [
@@ -28044,7 +28219,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
28044
28219
  "provider",
28045
28220
  "provider-not-representable"
28046
28221
  ),
28047
- detail: `${path34.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
28222
+ detail: `${path36.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
28048
28223
  }
28049
28224
  ]
28050
28225
  });
@@ -28059,8 +28234,8 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
28059
28234
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
28060
28235
  return { component, status: "conflict", path: destination };
28061
28236
  }
28062
- ensureDir(path34.dirname(destination));
28063
- fs35.writeFileSync(destination, content);
28237
+ ensureDir(path36.dirname(destination));
28238
+ fs36.writeFileSync(destination, content);
28064
28239
  return { component, status: "success", path: destination };
28065
28240
  }
28066
28241
  function handleConflict3(destination, config, options, logger, manifest, scopePath) {
@@ -28079,16 +28254,16 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
28079
28254
  backupFile(destination, manifest);
28080
28255
  writeManifest(scopePath, manifest);
28081
28256
  } else {
28082
- fs35.renameSync(destination, `${destination}.bak.${Date.now()}`);
28257
+ fs36.renameSync(destination, `${destination}.bak.${Date.now()}`);
28083
28258
  }
28084
28259
  return true;
28085
28260
  }
28086
- fs35.rmSync(destination, { recursive: true, force: true });
28261
+ fs36.rmSync(destination, { recursive: true, force: true });
28087
28262
  return true;
28088
28263
  }
28089
28264
  function isCompiledCurrent3(destination, expectedContent, expectedHash) {
28090
28265
  try {
28091
- const current = fs35.readFileSync(destination, "utf8");
28266
+ const current = fs36.readFileSync(destination, "utf8");
28092
28267
  const marker = extractProvenanceMarker(current);
28093
28268
  return expectedHash ? marker?.hash === expectedHash && marker.target === "cursor" && current === expectedContent : current === expectedContent;
28094
28269
  } catch {
@@ -28105,9 +28280,9 @@ function skippedMissingSource3(component, source) {
28105
28280
  function shouldSkipComponent3(options, component) {
28106
28281
  return Boolean(options.component && options.component !== component);
28107
28282
  }
28108
- function isSymlinkTo3(linkPath, source) {
28283
+ function isSymlinkTo4(linkPath, source) {
28109
28284
  try {
28110
- return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
28285
+ return fs36.realpathSync(linkPath) === fs36.realpathSync(source);
28111
28286
  } catch {
28112
28287
  return false;
28113
28288
  }
@@ -28118,8 +28293,8 @@ function hashString3(value) {
28118
28293
 
28119
28294
  // src/adapters/cline.ts
28120
28295
  import crypto8 from "crypto";
28121
- import fs36 from "fs";
28122
- import path35 from "path";
28296
+ import fs37 from "fs";
28297
+ import path37 from "path";
28123
28298
  function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
28124
28299
  const scope = options.scope ?? "global";
28125
28300
  const profile = resolveTargetPaths({
@@ -28232,7 +28407,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
28232
28407
  function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
28233
28408
  if (scope === "global" || paths.instructions === null) {
28234
28409
  addLoss(lossReport, "cline", "instructions", {
28235
- source: path35.basename(config.source.instructions),
28410
+ source: path37.basename(config.source.instructions),
28236
28411
  fields: [
28237
28412
  {
28238
28413
  field: "instructions",
@@ -28252,12 +28427,12 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
28252
28427
  path: "cline/global/instructions: no committable global path"
28253
28428
  };
28254
28429
  }
28255
- const source = path35.join(sourceRoot, config.source.instructions);
28430
+ const source = path37.join(sourceRoot, config.source.instructions);
28256
28431
  const destination = resolveTargetPath(paths.instructions);
28257
- const baseContent = fs36.existsSync(source) ? fs36.readFileSync(source, "utf8").trim() : "";
28432
+ const baseContent = fs37.existsSync(source) ? fs37.readFileSync(source, "utf8").trim() : "";
28258
28433
  const marker = formatProvenanceMarker(
28259
28434
  "markdown",
28260
- path35.basename(config.source.instructions),
28435
+ path37.basename(config.source.instructions),
28261
28436
  hashString4(baseContent),
28262
28437
  "cline"
28263
28438
  );
@@ -28282,11 +28457,11 @@ ${baseContent}
28282
28457
  );
28283
28458
  }
28284
28459
  function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
28285
- const sourceAgentsRoot = path35.join(sourceRoot, config.source.agents);
28286
- if (!fs36.existsSync(sourceAgentsRoot)) {
28460
+ const sourceAgentsRoot = path37.join(sourceRoot, config.source.agents);
28461
+ if (!fs37.existsSync(sourceAgentsRoot)) {
28287
28462
  return [skippedMissingSource4("agents", sourceAgentsRoot)];
28288
28463
  }
28289
- const sourceAgents = ts(path35.join(sourceAgentsRoot, "*.md")).sort();
28464
+ const sourceAgents = ts(path37.join(sourceAgentsRoot, "*.md")).sort();
28290
28465
  return sourceAgents.map((agentFile) => {
28291
28466
  compileAgent(agentFile, "cline", mappings, extensions, lossReport);
28292
28467
  if (options.dryRun) {
@@ -28302,14 +28477,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
28302
28477
  });
28303
28478
  }
28304
28479
  function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
28305
- const sourceRulesDir = path35.join(sourceRoot, config.source.rules);
28306
- if (!fs36.existsSync(sourceRulesDir)) {
28480
+ const sourceRulesDir = path37.join(sourceRoot, config.source.rules);
28481
+ if (!fs37.existsSync(sourceRulesDir)) {
28307
28482
  return [skippedMissingSource4("rules", sourceRulesDir)];
28308
28483
  }
28309
28484
  const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
28310
28485
  const rulesDir = resolveTargetPath(paths.rules);
28311
28486
  return compiled.dotRulesFiles.map(({ name, content }) => {
28312
- const destination = path35.join(rulesDir, name);
28487
+ const destination = path37.join(rulesDir, name);
28313
28488
  if (options.dryRun) {
28314
28489
  logger.info(`[dry-run] rules: write ${destination}`);
28315
28490
  return {
@@ -28333,17 +28508,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
28333
28508
  });
28334
28509
  }
28335
28510
  function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
28336
- const sourceCommandsRoot = path35.join(sourceRoot, config.source.commands);
28337
- if (!fs36.existsSync(sourceCommandsRoot)) {
28511
+ const sourceCommandsRoot = path37.join(sourceRoot, config.source.commands);
28512
+ if (!fs37.existsSync(sourceCommandsRoot)) {
28338
28513
  return [skippedMissingSource4("commands", sourceCommandsRoot)];
28339
28514
  }
28340
- const sourceCommands = ts(path35.join(sourceCommandsRoot, "*.md")).sort();
28515
+ const sourceCommands = ts(path37.join(sourceCommandsRoot, "*.md")).sort();
28341
28516
  const workflowsRoot = resolveTargetPath(paths.workflows);
28342
28517
  return sourceCommands.map((commandFile) => {
28343
- const baseName = path35.basename(commandFile);
28344
- const destination = path35.join(workflowsRoot, baseName);
28345
- const commandContent = fs36.readFileSync(commandFile, "utf8");
28346
- const relativeSource = `commands/${path35.basename(commandFile)}`;
28518
+ const baseName = path37.basename(commandFile);
28519
+ const destination = path37.join(workflowsRoot, baseName);
28520
+ const commandContent = fs37.readFileSync(commandFile, "utf8");
28521
+ const relativeSource = `commands/${path37.basename(commandFile)}`;
28347
28522
  const marker = formatProvenanceMarker(
28348
28523
  "markdown",
28349
28524
  relativeSource,
@@ -28378,9 +28553,9 @@ ${commandContent.trim()}
28378
28553
  });
28379
28554
  }
28380
28555
  function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
28381
- const source = path35.resolve(sourceRoot, config.source.skills);
28556
+ const source = path37.resolve(sourceRoot, config.source.skills);
28382
28557
  const destination = resolveTargetPath(paths.skills);
28383
- if (!fs36.existsSync(source)) {
28558
+ if (!fs37.existsSync(source)) {
28384
28559
  return skippedMissingSource4("skills", source);
28385
28560
  }
28386
28561
  if (options.dryRun) {
@@ -28388,7 +28563,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
28388
28563
  return { component: "skills", status: "dry-run", path: destination };
28389
28564
  }
28390
28565
  const artifactClass = classifyArtifact(destination, config, sourceRoot);
28391
- if (artifactClass === "managed-symlink" && isSymlinkTo4(destination, source)) {
28566
+ if (artifactClass === "managed-symlink" && isSymlinkTo5(destination, source)) {
28392
28567
  return {
28393
28568
  component: "skills",
28394
28569
  status: "skipped-current",
@@ -28400,9 +28575,9 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
28400
28575
  return { component: "skills", status: "conflict", path: destination };
28401
28576
  }
28402
28577
  } else if (artifactClass === "managed-symlink") {
28403
- fs36.unlinkSync(destination);
28578
+ fs37.unlinkSync(destination);
28404
28579
  }
28405
- ensureDir(path35.dirname(destination));
28580
+ ensureDir(path37.dirname(destination));
28406
28581
  createRelativeSymlink(source, destination, "dir");
28407
28582
  logger.verbose(`Skills: created Cline skills symlink ${destination}`);
28408
28583
  return { component: "skills", status: "success", path: destination };
@@ -28426,10 +28601,10 @@ function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manife
28426
28601
  const source = resolveMcpSourceFile(sourceRoot, config);
28427
28602
  const sourceLabel = mcpSourceLabel(config);
28428
28603
  const destination = resolveTargetPath(paths.mcp_file);
28429
- if (!fs36.existsSync(source)) {
28604
+ if (!fs37.existsSync(source)) {
28430
28605
  return skippedMissingSource4("mcp", source);
28431
28606
  }
28432
- const sourceMcpJson = JSON.parse(fs36.readFileSync(source, "utf8"));
28607
+ const sourceMcpJson = JSON.parse(fs37.readFileSync(source, "utf8"));
28433
28608
  const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
28434
28609
  if (options.dryRun) {
28435
28610
  logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
@@ -28472,11 +28647,11 @@ function syncSettings(lossReport) {
28472
28647
  };
28473
28648
  }
28474
28649
  function syncProviderAndModel(config, sourceRoot, lossReport) {
28475
- const agentsDir = path35.join(sourceRoot, config.source.agents);
28476
- if (!fs36.existsSync(agentsDir)) return;
28477
- for (const agentFile of ts(path35.join(agentsDir, "*.md")).sort()) {
28650
+ const agentsDir = path37.join(sourceRoot, config.source.agents);
28651
+ if (!fs37.existsSync(agentsDir)) return;
28652
+ for (const agentFile of ts(path37.join(agentsDir, "*.md")).sort()) {
28478
28653
  const { data } = parseMarkdownFrontmatter(agentFile);
28479
- const relativeSource = `agents/${path35.basename(agentFile)}`;
28654
+ const relativeSource = `agents/${path37.basename(agentFile)}`;
28480
28655
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
28481
28656
  if (hasCustomProvider) {
28482
28657
  addLoss(lossReport, "cline", "agents", {
@@ -28490,7 +28665,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
28490
28665
  "provider",
28491
28666
  "provider-not-representable"
28492
28667
  ),
28493
- detail: `${path35.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
28668
+ detail: `${path37.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
28494
28669
  }
28495
28670
  ]
28496
28671
  });
@@ -28508,7 +28683,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
28508
28683
  "model",
28509
28684
  "model-not-representable"
28510
28685
  ),
28511
- detail: `${path35.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
28686
+ detail: `${path37.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
28512
28687
  }
28513
28688
  ]
28514
28689
  });
@@ -28523,8 +28698,8 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
28523
28698
  if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
28524
28699
  return { component, status: "conflict", path: destination };
28525
28700
  }
28526
- ensureDir(path35.dirname(destination));
28527
- fs36.writeFileSync(destination, content);
28701
+ ensureDir(path37.dirname(destination));
28702
+ fs37.writeFileSync(destination, content);
28528
28703
  return { component, status: "success", path: destination };
28529
28704
  }
28530
28705
  function handleConflict4(destination, config, options, logger, manifest, scopePath) {
@@ -28543,16 +28718,16 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
28543
28718
  backupFile(destination, manifest);
28544
28719
  writeManifest(scopePath, manifest);
28545
28720
  } else {
28546
- fs36.renameSync(destination, `${destination}.bak.${Date.now()}`);
28721
+ fs37.renameSync(destination, `${destination}.bak.${Date.now()}`);
28547
28722
  }
28548
28723
  return true;
28549
28724
  }
28550
- fs36.rmSync(destination, { recursive: true, force: true });
28725
+ fs37.rmSync(destination, { recursive: true, force: true });
28551
28726
  return true;
28552
28727
  }
28553
28728
  function isCompiledCurrent4(destination, expectedContent, expectedHash) {
28554
28729
  try {
28555
- const current = fs36.readFileSync(destination, "utf8");
28730
+ const current = fs37.readFileSync(destination, "utf8");
28556
28731
  const marker = extractProvenanceMarker(current);
28557
28732
  return expectedHash ? marker?.hash === expectedHash && marker.target === "cline" && current === expectedContent : current === expectedContent;
28558
28733
  } catch {
@@ -28569,9 +28744,9 @@ function skippedMissingSource4(component, source) {
28569
28744
  function shouldSkipComponent4(options, component) {
28570
28745
  return Boolean(options.component && options.component !== component);
28571
28746
  }
28572
- function isSymlinkTo4(linkPath, source) {
28747
+ function isSymlinkTo5(linkPath, source) {
28573
28748
  try {
28574
- return fs36.realpathSync(linkPath) === fs36.realpathSync(source);
28749
+ return fs37.realpathSync(linkPath) === fs37.realpathSync(source);
28575
28750
  } catch {
28576
28751
  return false;
28577
28752
  }
@@ -28582,9 +28757,9 @@ function hashString4(value) {
28582
28757
 
28583
28758
  // src/adapters/opencode.ts
28584
28759
  import crypto9 from "crypto";
28585
- import fs37 from "fs";
28760
+ import fs38 from "fs";
28586
28761
  import os6 from "os";
28587
- import path36 from "path";
28762
+ import path38 from "path";
28588
28763
  var import_yaml11 = __toESM(require_dist(), 1);
28589
28764
  function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
28590
28765
  const scope = options.scope ?? "global";
@@ -28602,7 +28777,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
28602
28777
  config_doc: profile.config_doc
28603
28778
  };
28604
28779
  const rules = compileRules(
28605
- path36.join(sourceRoot, config.source.rules),
28780
+ path38.join(sourceRoot, config.source.rules),
28606
28781
  "opencode",
28607
28782
  mappings,
28608
28783
  lossReport
@@ -28704,16 +28879,16 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
28704
28879
  return { target: "opencode", outcomes };
28705
28880
  }
28706
28881
  function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
28707
- const source = path36.join(sourceRoot, config.source.instructions);
28882
+ const source = path38.join(sourceRoot, config.source.instructions);
28708
28883
  const destination = resolveTargetPath(paths.instructions);
28709
- const baseContent = fs37.existsSync(source) ? fs37.readFileSync(source, "utf8").trim() : "";
28884
+ const baseContent = fs38.existsSync(source) ? fs38.readFileSync(source, "utf8").trim() : "";
28710
28885
  const composed = agentsAppendix ? `${baseContent}
28711
28886
 
28712
28887
  --- tangyr managed rules ---
28713
28888
  ${agentsAppendix}`.trim() : baseContent;
28714
28889
  const marker = formatProvenanceMarker(
28715
28890
  "markdown",
28716
- path36.basename(config.source.instructions),
28891
+ path38.basename(config.source.instructions),
28717
28892
  hashString5(composed),
28718
28893
  "opencode"
28719
28894
  );
@@ -28740,16 +28915,16 @@ ${composed}
28740
28915
  );
28741
28916
  }
28742
28917
  function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
28743
- const sourceAgentsRoot = path36.join(sourceRoot, config.source.agents);
28744
- if (!fs37.existsSync(sourceAgentsRoot)) {
28918
+ const sourceAgentsRoot = path38.join(sourceRoot, config.source.agents);
28919
+ if (!fs38.existsSync(sourceAgentsRoot)) {
28745
28920
  return [skippedMissingSource5("agents", sourceAgentsRoot)];
28746
28921
  }
28747
- const sourceAgents = ts(path36.join(sourceAgentsRoot, "*.md")).sort();
28922
+ const sourceAgents = ts(path38.join(sourceAgentsRoot, "*.md")).sort();
28748
28923
  const agentsRoot = resolveTargetPath(paths.agents);
28749
28924
  return sourceAgents.map((agentFile) => {
28750
- const destination = path36.join(
28925
+ const destination = path38.join(
28751
28926
  agentsRoot,
28752
- `${path36.basename(agentFile, ".md")}.md`
28927
+ `${path38.basename(agentFile, ".md")}.md`
28753
28928
  );
28754
28929
  let compiled;
28755
28930
  try {
@@ -28813,11 +28988,11 @@ function applyProviderModelBinding(compiled, mappings) {
28813
28988
  return `${before}${(0, import_yaml11.stringify)(fields).trim()}${after}`;
28814
28989
  }
28815
28990
  function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
28816
- const sourceCommandsRoot = path36.join(sourceRoot, config.source.commands);
28817
- if (!fs37.existsSync(sourceCommandsRoot)) {
28991
+ const sourceCommandsRoot = path38.join(sourceRoot, config.source.commands);
28992
+ if (!fs38.existsSync(sourceCommandsRoot)) {
28818
28993
  return [skippedMissingSource5("commands", sourceCommandsRoot)];
28819
28994
  }
28820
- const sourceCommands = ts(path36.join(sourceCommandsRoot, "*.md")).sort();
28995
+ const sourceCommands = ts(path38.join(sourceCommandsRoot, "*.md")).sort();
28821
28996
  const commandsRoot = resolveTargetPath(paths.commands);
28822
28997
  return sourceCommands.map((commandFile) => {
28823
28998
  const { data, body } = parseCommandFile(commandFile);
@@ -28831,7 +29006,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
28831
29006
  if (typeof data.model === "string") {
28832
29007
  frontmatter.model = data.model;
28833
29008
  }
28834
- const relativeSource = `commands/${path36.basename(commandFile)}`;
29009
+ const relativeSource = `commands/${path38.basename(commandFile)}`;
28835
29010
  const marker = formatProvenanceMarker(
28836
29011
  "markdown",
28837
29012
  relativeSource,
@@ -28847,9 +29022,9 @@ ${body.trimEnd()}
28847
29022
  ` : `${marker}
28848
29023
  ${body.trimEnd()}
28849
29024
  `;
28850
- const destination = path36.join(
29025
+ const destination = path38.join(
28851
29026
  commandsRoot,
28852
- `${path36.basename(commandFile, ".md")}.md`
29027
+ `${path38.basename(commandFile, ".md")}.md`
28853
29028
  );
28854
29029
  if (options.dryRun) {
28855
29030
  logger.info(
@@ -28876,8 +29051,8 @@ ${body.trimEnd()}
28876
29051
  });
28877
29052
  }
28878
29053
  function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
28879
- const source = path36.resolve(sourceRoot, config.source.skills);
28880
- if (!fs37.existsSync(source)) {
29054
+ const source = path38.resolve(sourceRoot, config.source.skills);
29055
+ if (!fs38.existsSync(source)) {
28881
29056
  return skippedMissingSource5(component, source);
28882
29057
  }
28883
29058
  if (options.dryRun) {
@@ -28885,17 +29060,17 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
28885
29060
  return { component, status: "dry-run", path: destination };
28886
29061
  }
28887
29062
  const artifactClass = classifyArtifact(destination, config, sourceRoot);
28888
- if (artifactClass === "managed-symlink" && isSymlinkTo5(destination, source)) {
29063
+ if (artifactClass === "managed-symlink" && isSymlinkTo6(destination, source)) {
28889
29064
  return { component, status: "skipped-current", path: destination };
28890
29065
  }
28891
29066
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
28892
- fs37.unlinkSync(destination);
29067
+ fs38.unlinkSync(destination);
28893
29068
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
28894
29069
  return { component, status: "conflict", path: destination };
28895
29070
  } else if (artifactClass === "managed-symlink") {
28896
- fs37.unlinkSync(destination);
29071
+ fs38.unlinkSync(destination);
28897
29072
  }
28898
- ensureDir(path36.dirname(destination));
29073
+ ensureDir(path38.dirname(destination));
28899
29074
  createRelativeSymlink(source, destination, "dir");
28900
29075
  logger.verbose(`Skills: created skills path ${destination}`);
28901
29076
  return { component, status: "success", path: destination };
@@ -28904,13 +29079,13 @@ function syncMcp5(config, sourceRoot, paths, mappings, options, lossReport, logg
28904
29079
  const source = resolveMcpSourceFile(sourceRoot, config);
28905
29080
  const sourceLabel = mcpSourceLabel(config);
28906
29081
  const destination = resolveTargetPath(paths.config_doc);
28907
- if (!fs37.existsSync(source)) {
29082
+ if (!fs38.existsSync(source)) {
28908
29083
  if (!options.dryRun) {
28909
29084
  syncConfigDoc(paths, {}, lossReport, {}, mappings);
28910
29085
  }
28911
29086
  return skippedMissingSource5("mcp", source);
28912
29087
  }
28913
- const sourceMcpJson = JSON.parse(fs37.readFileSync(source, "utf8"));
29088
+ const sourceMcpJson = JSON.parse(fs38.readFileSync(source, "utf8"));
28914
29089
  const mcpJson = compileMcp(
28915
29090
  sourceMcpJson,
28916
29091
  "opencode",
@@ -28976,9 +29151,9 @@ function syncProviderBlock(mappings) {
28976
29151
  function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
28977
29152
  const destination = resolveTargetPath(paths.config_doc);
28978
29153
  let existing = {};
28979
- if (fs37.existsSync(destination)) {
29154
+ if (fs38.existsSync(destination)) {
28980
29155
  try {
28981
- existing = JSON.parse(fs37.readFileSync(destination, "utf8"));
29156
+ existing = JSON.parse(fs38.readFileSync(destination, "utf8"));
28982
29157
  } catch {
28983
29158
  existing = {};
28984
29159
  }
@@ -29003,8 +29178,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
29003
29178
  };
29004
29179
  }
29005
29180
  }
29006
- ensureDir(path36.dirname(destination));
29007
- fs37.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
29181
+ ensureDir(path38.dirname(destination));
29182
+ fs38.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
29008
29183
  `);
29009
29184
  }
29010
29185
  function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
@@ -29015,8 +29190,8 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
29015
29190
  if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
29016
29191
  return { component, status: "conflict", path: destination };
29017
29192
  }
29018
- ensureDir(path36.dirname(destination));
29019
- fs37.writeFileSync(destination, content);
29193
+ ensureDir(path38.dirname(destination));
29194
+ fs38.writeFileSync(destination, content);
29020
29195
  return { component, status: "success", path: destination };
29021
29196
  }
29022
29197
  function handleConflict5(destination, config, options, logger, manifest, scopePath) {
@@ -29035,16 +29210,16 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
29035
29210
  backupFile(destination, manifest);
29036
29211
  writeManifest(scopePath, manifest);
29037
29212
  } else {
29038
- fs37.renameSync(destination, `${destination}.bak.${Date.now()}`);
29213
+ fs38.renameSync(destination, `${destination}.bak.${Date.now()}`);
29039
29214
  }
29040
29215
  return true;
29041
29216
  }
29042
- fs37.rmSync(destination, { recursive: true, force: true });
29217
+ fs38.rmSync(destination, { recursive: true, force: true });
29043
29218
  return true;
29044
29219
  }
29045
29220
  function isCompiledCurrent5(destination, expectedContent, expectedHash) {
29046
29221
  try {
29047
- const current = fs37.readFileSync(destination, "utf8");
29222
+ const current = fs38.readFileSync(destination, "utf8");
29048
29223
  const marker = extractProvenanceMarker(current);
29049
29224
  return expectedHash ? marker?.hash === expectedHash && marker.target === "opencode" && current === expectedContent : current === expectedContent;
29050
29225
  } catch {
@@ -29061,9 +29236,9 @@ function skippedMissingSource5(component, source) {
29061
29236
  function shouldSkipComponent5(options, component) {
29062
29237
  return Boolean(options.component && options.component !== component);
29063
29238
  }
29064
- function isSymlinkTo5(linkPath, source) {
29239
+ function isSymlinkTo6(linkPath, source) {
29065
29240
  try {
29066
- return fs37.realpathSync(linkPath) === fs37.realpathSync(source);
29241
+ return fs38.realpathSync(linkPath) === fs38.realpathSync(source);
29067
29242
  } catch {
29068
29243
  return false;
29069
29244
  }
@@ -29072,7 +29247,7 @@ function hashString5(value) {
29072
29247
  return `sha256:${crypto9.createHash("sha256").update(value).digest("hex")}`;
29073
29248
  }
29074
29249
  function parseCommandFile(commandFile) {
29075
- const content = fs37.readFileSync(commandFile, "utf8");
29250
+ const content = fs38.readFileSync(commandFile, "utf8");
29076
29251
  if (!content.startsWith("---\n")) {
29077
29252
  return { data: {}, body: content };
29078
29253
  }
@@ -29092,10 +29267,10 @@ function parseCommandFile(commandFile) {
29092
29267
  // src/commands/install.ts
29093
29268
  function isBackupableFile(targetPath) {
29094
29269
  try {
29095
- const lstat = fs38.lstatSync(targetPath);
29270
+ const lstat = fs39.lstatSync(targetPath);
29096
29271
  if (lstat.isDirectory()) return false;
29097
29272
  if (lstat.isSymbolicLink()) {
29098
- const stat = fs38.statSync(targetPath);
29273
+ const stat = fs39.statSync(targetPath);
29099
29274
  return stat.isFile();
29100
29275
  }
29101
29276
  return lstat.isFile();
@@ -29105,10 +29280,10 @@ function isBackupableFile(targetPath) {
29105
29280
  }
29106
29281
  function backupConflictingTarget(targetPath, scopePath) {
29107
29282
  const ts2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/gu, "").replace("T", "T").replace(/\.\d+Z$/u, "Z");
29108
- const relativeToRoot = path37.relative("/", targetPath).replace(/^\.\.\/+/gu, "");
29109
- const backupPath = path37.join(scopePath, "backups", ts2, relativeToRoot);
29110
- fs38.mkdirSync(path37.dirname(backupPath), { recursive: true });
29111
- fs38.copyFileSync(targetPath, backupPath);
29283
+ const relativeToRoot = path39.relative("/", targetPath).replace(/^\.\.\/+/gu, "");
29284
+ const backupPath = path39.join(scopePath, "backups", ts2, relativeToRoot);
29285
+ fs39.mkdirSync(path39.dirname(backupPath), { recursive: true });
29286
+ fs39.copyFileSync(targetPath, backupPath);
29112
29287
  return backupPath;
29113
29288
  }
29114
29289
  async function runInstallCommand(options, logger) {
@@ -29137,7 +29312,7 @@ async function runInstallCommand(options, logger) {
29137
29312
  );
29138
29313
  }
29139
29314
  const kitName = resolvedKitName ?? config.kit;
29140
- const kitPath = kitPathOverride ?? (options.kitPath ? path37.resolve(options.kitPath) : config.kitPath);
29315
+ const kitPath = kitPathOverride ?? (options.kitPath ? path39.resolve(options.kitPath) : config.kitPath);
29141
29316
  if (!kitName && !kitPath) {
29142
29317
  logger.error(
29143
29318
  "No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
@@ -29282,7 +29457,7 @@ ACCEPTED CONFLICTS (backup-and-replace applied to ${conflictingFindings.length}
29282
29457
  logger.info(` source: ${finding.tool}`);
29283
29458
  logger.info(` action: backup-and-replace`);
29284
29459
  logger.info(` backup: ${backupLocation}`);
29285
- } else if (fs38.existsSync(finding.path)) {
29460
+ } else if (fs39.existsSync(finding.path)) {
29286
29461
  logger.info(` - ${finding.path}`);
29287
29462
  logger.info(` source: ${finding.tool}`);
29288
29463
  logger.info(
@@ -29393,33 +29568,25 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
29393
29568
  writeManifest(scopePath, manifest);
29394
29569
  logger.info(`
29395
29570
  Installation complete: ${installedCount} files installed.`);
29396
- logger.info(`Manifest written to ${path37.join(scopePath, "manifest.json")}`);
29571
+ logger.info(`Manifest written to ${path39.join(scopePath, "manifest.json")}`);
29397
29572
  logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
29398
29573
  logger.info(`Scope: ${scope}`);
29399
29574
  logger.info(`Tools: ${tools.join(", ")}`);
29400
29575
  reportHookRejections(
29401
29576
  installLossReport,
29402
29577
  tools,
29403
- path37.resolve(kitInfo.path, "hooks"),
29578
+ path39.resolve(kitInfo.path, "hooks"),
29404
29579
  kitInfo.components.hooks.declared
29405
29580
  );
29406
29581
  const hooksConflict = reportHooksSourceConflict(
29407
29582
  installLossReport,
29408
29583
  tools,
29409
- path37.resolve(kitInfo.path, "hooks"),
29584
+ path39.resolve(kitInfo.path, "hooks"),
29410
29585
  kitInfo.components.hooks.declared
29411
29586
  );
29412
29587
  if (hooksConflict) {
29413
29588
  logger.warn(hooksConflict);
29414
29589
  }
29415
- if (scope === "project") {
29416
- reportProjectScopeScriptPath(
29417
- installLossReport,
29418
- tools,
29419
- path37.resolve(kitInfo.path, "hooks"),
29420
- kitInfo.components.hooks.declared
29421
- );
29422
- }
29423
29590
  writeLossReport(options.lossReport, installLossReport);
29424
29591
  exitOnErrorSeverityLoss(installLossReport, logger, {
29425
29592
  ignoreErrors: options.ignoreErrors ?? false
@@ -29559,13 +29726,13 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
29559
29726
  logger.verbose(` skipped (operator choice): ${placement.destination}`);
29560
29727
  continue;
29561
29728
  }
29562
- const destDir = path37.dirname(placement.destination);
29563
- fs38.mkdirSync(destDir, { recursive: true });
29729
+ const destDir = path39.dirname(placement.destination);
29730
+ fs39.mkdirSync(destDir, { recursive: true });
29564
29731
  if (placement.type === "symlink") {
29565
- if (fs38.existsSync(placement.destination) || isSymlink2(placement.destination)) {
29732
+ if (fs39.existsSync(placement.destination) || isSymlink2(placement.destination)) {
29566
29733
  removeManagedPath(placement.destination);
29567
29734
  }
29568
- fs38.symlinkSync(
29735
+ fs39.symlinkSync(
29569
29736
  placement.source,
29570
29737
  placement.destination,
29571
29738
  placement.isDir ? "dir" : "file"
@@ -29574,12 +29741,12 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
29574
29741
  ` symlink: ${placement.source} \u2192 ${placement.destination}`
29575
29742
  );
29576
29743
  } else {
29577
- fs38.copyFileSync(placement.source, placement.destination);
29744
+ fs39.copyFileSync(placement.source, placement.destination);
29578
29745
  logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
29579
29746
  }
29580
29747
  addArtifactToManifest(manifest, {
29581
29748
  relativePath: placement.manifestKey,
29582
- hash: fs38.statSync(placement.source).isDirectory() ? `dir:${placement.source}` : computeSourceHash(placement.source),
29749
+ hash: fs39.statSync(placement.source).isDirectory() ? `dir:${placement.source}` : computeSourceHash(placement.source),
29583
29750
  origin: "tangyr-managed"
29584
29751
  });
29585
29752
  count++;
@@ -29826,11 +29993,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
29826
29993
  if (outcome.path === mcpFile2) {
29827
29994
  return "cline/mcp.json";
29828
29995
  }
29829
- if (outcome.path.startsWith(`${workflowsRoot}${path37.sep}`)) {
29830
- return `cline/workflows/${path37.basename(outcome.path)}`;
29996
+ if (outcome.path.startsWith(`${workflowsRoot}${path39.sep}`)) {
29997
+ return `cline/workflows/${path39.basename(outcome.path)}`;
29831
29998
  }
29832
- if (outcome.path.startsWith(`${rulesRoot2}${path37.sep}`)) {
29833
- return `cline/rules/${path37.basename(outcome.path)}`;
29999
+ if (outcome.path.startsWith(`${rulesRoot2}${path39.sep}`)) {
30000
+ return `cline/rules/${path39.basename(outcome.path)}`;
29834
30001
  }
29835
30002
  return null;
29836
30003
  }
@@ -29866,14 +30033,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
29866
30033
  if (outcome.path === permissionsFile) {
29867
30034
  return "cursor/permissions.json";
29868
30035
  }
29869
- if (outcome.path.startsWith(`${agentsRoot2}${path37.sep}`)) {
29870
- return `cursor/agents/${path37.basename(outcome.path)}`;
30036
+ if (outcome.path.startsWith(`${agentsRoot2}${path39.sep}`)) {
30037
+ return `cursor/agents/${path39.basename(outcome.path)}`;
29871
30038
  }
29872
- if (outcome.path.startsWith(`${rulesRoot2}${path37.sep}`)) {
29873
- return `cursor/rules/${path37.basename(outcome.path)}`;
30039
+ if (outcome.path.startsWith(`${rulesRoot2}${path39.sep}`)) {
30040
+ return `cursor/rules/${path39.basename(outcome.path)}`;
29874
30041
  }
29875
- if (outcome.path.startsWith(`${skillsRoot2}${path37.sep}`)) {
29876
- const rel = path37.relative(skillsRoot2, outcome.path);
30042
+ if (outcome.path.startsWith(`${skillsRoot2}${path39.sep}`)) {
30043
+ const rel = path39.relative(skillsRoot2, outcome.path);
29877
30044
  return `cursor/skills/${rel}`;
29878
30045
  }
29879
30046
  return null;
@@ -29899,14 +30066,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
29899
30066
  if (outcome.path === skillsSharedRoot) {
29900
30067
  return "opencode/skills_shared";
29901
30068
  }
29902
- if (outcome.path.startsWith(`${agentsRoot2}${path37.sep}`)) {
29903
- return `opencode/agents/${path37.basename(outcome.path)}`;
30069
+ if (outcome.path.startsWith(`${agentsRoot2}${path39.sep}`)) {
30070
+ return `opencode/agents/${path39.basename(outcome.path)}`;
29904
30071
  }
29905
- if (outcome.path.startsWith(`${commandsRoot}${path37.sep}`)) {
29906
- return `opencode/commands/${path37.basename(outcome.path)}`;
30072
+ if (outcome.path.startsWith(`${commandsRoot}${path39.sep}`)) {
30073
+ return `opencode/commands/${path39.basename(outcome.path)}`;
29907
30074
  }
29908
30075
  if (outcome.path === configDocFile) {
29909
- return `opencode/${path37.basename(outcome.path)}`;
30076
+ return `opencode/${path39.basename(outcome.path)}`;
29910
30077
  }
29911
30078
  return null;
29912
30079
  }
@@ -29920,17 +30087,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
29920
30087
  if (outcome.path === skillsRoot2) {
29921
30088
  return "copilot/skills";
29922
30089
  }
29923
- if (outcome.path.startsWith(`${agentsRoot2}${path37.sep}`)) {
29924
- return `copilot/agents/${path37.basename(outcome.path)}`;
30090
+ if (outcome.path.startsWith(`${agentsRoot2}${path39.sep}`)) {
30091
+ return `copilot/agents/${path39.basename(outcome.path)}`;
29925
30092
  }
29926
- if (outcome.path.startsWith(`${promptsRoot}${path37.sep}`)) {
29927
- return `copilot/prompts/${path37.basename(outcome.path)}`;
30093
+ if (outcome.path.startsWith(`${promptsRoot}${path39.sep}`)) {
30094
+ return `copilot/prompts/${path39.basename(outcome.path)}`;
29928
30095
  }
29929
- if (outcome.path.startsWith(`${hooksRoot}${path37.sep}`)) {
29930
- return `copilot/hooks/${path37.basename(outcome.path)}`;
30096
+ if (outcome.path.startsWith(`${hooksRoot}${path39.sep}`)) {
30097
+ return `copilot/hooks/${path39.basename(outcome.path)}`;
29931
30098
  }
29932
30099
  if (outcome.path === mcpFile2) {
29933
- return `copilot/${path37.basename(outcome.path)}`;
30100
+ return `copilot/${path39.basename(outcome.path)}`;
29934
30101
  }
29935
30102
  return null;
29936
30103
  }
@@ -29946,17 +30113,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
29946
30113
  if (outcome.path === skillsRoot) {
29947
30114
  return "codex/skills";
29948
30115
  }
29949
- if (outcome.path.startsWith(`${agentsRoot}${path37.sep}`)) {
29950
- return `codex/agents/${path37.basename(outcome.path)}`;
30116
+ if (outcome.path.startsWith(`${agentsRoot}${path39.sep}`)) {
30117
+ return `codex/agents/${path39.basename(outcome.path)}`;
29951
30118
  }
29952
- if (outcome.path.startsWith(`${rulesRoot}${path37.sep}`)) {
29953
- return `codex/rules/${path37.basename(outcome.path)}`;
30119
+ if (outcome.path.startsWith(`${rulesRoot}${path39.sep}`)) {
30120
+ return `codex/rules/${path39.basename(outcome.path)}`;
29954
30121
  }
29955
30122
  if (outcome.path === hooksFile) {
29956
- return `codex/${path37.basename(outcome.path)}`;
30123
+ return `codex/${path39.basename(outcome.path)}`;
29957
30124
  }
29958
30125
  if (outcome.path === mcpFile) {
29959
- return `codex/${path37.basename(outcome.path)}`;
30126
+ return `codex/${path39.basename(outcome.path)}`;
29960
30127
  }
29961
30128
  return null;
29962
30129
  }
@@ -30008,8 +30175,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
30008
30175
  rules: resolvedPaths.rules
30009
30176
  };
30010
30177
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
30011
- const componentDir = path37.join(kitInfo.path, component);
30012
- if (fs38.existsSync(componentDir) && fs38.statSync(componentDir).isDirectory()) {
30178
+ const componentDir = path39.join(kitInfo.path, component);
30179
+ if (fs39.existsSync(componentDir) && fs39.statSync(componentDir).isDirectory()) {
30013
30180
  placements.push({
30014
30181
  source: componentDir,
30015
30182
  destination: targetPath,
@@ -30040,8 +30207,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
30040
30207
  rules: profile.rules
30041
30208
  };
30042
30209
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
30043
- const componentDir = path37.join(kitInfo.path, component);
30044
- if (fs38.existsSync(componentDir) && fs38.statSync(componentDir).isDirectory()) {
30210
+ const componentDir = path39.join(kitInfo.path, component);
30211
+ if (fs39.existsSync(componentDir) && fs39.statSync(componentDir).isDirectory()) {
30045
30212
  placements.push({
30046
30213
  source: componentDir,
30047
30214
  destination: targetPath,
@@ -30066,15 +30233,15 @@ function collectAllFiles(kitInfo) {
30066
30233
  const missingSet = new Set(reconciliation.missing);
30067
30234
  for (const entry of reconciliation.declared) {
30068
30235
  if (missingSet.has(entry)) continue;
30069
- const relPath = isSkills ? path37.join(component, entry) : path37.join(component, `${entry}.md`);
30070
- files.set(relPath, path37.join(kitInfo.path, relPath));
30236
+ const relPath = isSkills ? path39.join(component, entry) : path39.join(component, `${entry}.md`);
30237
+ files.set(relPath, path39.join(kitInfo.path, relPath));
30071
30238
  }
30072
30239
  }
30073
30240
  return files;
30074
30241
  }
30075
30242
  function isSymlink2(p) {
30076
30243
  try {
30077
- return fs38.lstatSync(p).isSymbolicLink();
30244
+ return fs39.lstatSync(p).isSymbolicLink();
30078
30245
  } catch {
30079
30246
  return false;
30080
30247
  }
@@ -30119,14 +30286,14 @@ async function runKitUpdateCommand(options, logger) {
30119
30286
  }
30120
30287
 
30121
30288
  // src/commands/list.ts
30122
- import path38 from "path";
30289
+ import path40 from "path";
30123
30290
  function runListCommand(options, logger) {
30124
30291
  let searchPaths = [];
30125
- let directKitPath = options.kitPath ? path38.resolve(options.kitPath) : void 0;
30292
+ let directKitPath = options.kitPath ? path40.resolve(options.kitPath) : void 0;
30126
30293
  try {
30127
30294
  const { config, configDir } = resolveConfig(options.config);
30128
30295
  searchPaths = config.kitSearchPaths ?? [
30129
- path38.join(configDir, "operating-kits")
30296
+ path40.join(configDir, "operating-kits")
30130
30297
  ];
30131
30298
  directKitPath = directKitPath ?? config.kitPath;
30132
30299
  } catch (err) {
@@ -30201,7 +30368,7 @@ function withDirectKit(kits, directKitPath) {
30201
30368
  return kits;
30202
30369
  }
30203
30370
  const directKit = loadKit(directKitPath);
30204
- if (kits.some((kit) => path38.resolve(kit.path) === directKit.path)) {
30371
+ if (kits.some((kit) => path40.resolve(kit.path) === directKit.path)) {
30205
30372
  return kits;
30206
30373
  }
30207
30374
  return [...kits, directKit];
@@ -30209,15 +30376,15 @@ function withDirectKit(kits, directKitPath) {
30209
30376
 
30210
30377
  // src/commands/probe.ts
30211
30378
  import { spawnSync as spawnSync2 } from "child_process";
30212
- import fs39 from "fs";
30213
- import path39 from "path";
30379
+ import fs40 from "fs";
30380
+ import path41 from "path";
30214
30381
  function runProbeCommand(options, logger) {
30215
30382
  const { config, configDir, sourceRoot } = resolveRuntime(
30216
30383
  options,
30217
30384
  import.meta.url
30218
30385
  );
30219
30386
  const platformPaths = readYamlObject(
30220
- path39.join(
30387
+ path41.join(
30221
30388
  resolveConfiguredPath(config.mappings, configDir, sourceRoot, "mappings"),
30222
30389
  "platform-paths.yaml"
30223
30390
  )
@@ -30253,7 +30420,7 @@ function toProbeRow(target, key, rawPath) {
30253
30420
  const resolved = resolveTargetPath(rawPath);
30254
30421
  let accessible = false;
30255
30422
  try {
30256
- fs39.accessSync(resolved);
30423
+ fs40.accessSync(resolved);
30257
30424
  accessible = true;
30258
30425
  } catch {
30259
30426
  accessible = false;
@@ -30262,7 +30429,7 @@ function toProbeRow(target, key, rawPath) {
30262
30429
  target,
30263
30430
  key,
30264
30431
  path: resolved,
30265
- exists: fs39.existsSync(resolved),
30432
+ exists: fs40.existsSync(resolved),
30266
30433
  accessible
30267
30434
  };
30268
30435
  }
@@ -30280,7 +30447,7 @@ function codexRuntimeProbeRows() {
30280
30447
  ["binary_snap", "/snap/bin/codex"],
30281
30448
  ["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
30282
30449
  ]) {
30283
- if (fs39.existsSync(candidatePath)) {
30450
+ if (fs40.existsSync(candidatePath)) {
30284
30451
  rows.push(toProbeRow("codex", key, candidatePath));
30285
30452
  }
30286
30453
  }
@@ -30296,8 +30463,8 @@ function commandProbeRows(target, key, command, args) {
30296
30463
 
30297
30464
  // src/commands/status.ts
30298
30465
  import crypto10 from "crypto";
30299
- import fs40 from "fs";
30300
- import path40 from "path";
30466
+ import fs41 from "fs";
30467
+ import path42 from "path";
30301
30468
  function runStatusCommand(options, logger) {
30302
30469
  const { config, configDir, sourceRoot } = resolveRuntime(
30303
30470
  options,
@@ -30376,21 +30543,21 @@ function classifyCodexFiles(config, sourceRoot, configDir) {
30376
30543
  rules: paths.rules
30377
30544
  };
30378
30545
  const rules = compileRules(
30379
- path40.join(sourceRoot, config.source.rules),
30546
+ path42.join(sourceRoot, config.source.rules),
30380
30547
  "codex",
30381
30548
  mappings,
30382
30549
  createLossReport()
30383
30550
  );
30384
- const instructionsSource = fs40.readFileSync(path40.join(sourceRoot, config.source.instructions), "utf8").trim();
30551
+ const instructionsSource = fs41.readFileSync(path42.join(sourceRoot, config.source.instructions), "utf8").trim();
30385
30552
  const composedInstructions = `${instructionsSource}
30386
30553
 
30387
30554
  --- tangyr managed rules ---
30388
30555
  ${rules.agentsAppendix}`.trim();
30389
30556
  const agentFiles = ts(
30390
- path40.join(sourceRoot, config.source.agents, "*.md")
30557
+ path42.join(sourceRoot, config.source.agents, "*.md")
30391
30558
  ).sort();
30392
- const hooksSource = path40.join(sourceRoot, config.source.hooks, "hooks.json");
30393
- const mcpSource = path40.join(sourceRoot, config.source.mcp);
30559
+ const hooksSource = path42.join(sourceRoot, config.source.hooks, "hooks.json");
30560
+ const mcpSource = path42.join(sourceRoot, config.source.mcp);
30394
30561
  const ruleRows = rules.dotRulesFiles.length === 0 ? [
30395
30562
  {
30396
30563
  component: "rules",
@@ -30401,7 +30568,7 @@ ${rules.agentsAppendix}`.trim();
30401
30568
  ] : rules.dotRulesFiles.map(
30402
30569
  (ruleFile) => classifyCompiledFile(
30403
30570
  `rules/${ruleFile.name}`,
30404
- path40.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
30571
+ path42.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
30405
30572
  "codex",
30406
30573
  void 0,
30407
30574
  config,
@@ -30419,10 +30586,10 @@ ${rules.agentsAppendix}`.trim();
30419
30586
  ),
30420
30587
  ...agentFiles.map(
30421
30588
  (agentFile) => classifyCompiledFile(
30422
- `agents/${path40.basename(agentFile, ".md")}`,
30423
- path40.join(
30589
+ `agents/${path42.basename(agentFile, ".md")}`,
30590
+ path42.join(
30424
30591
  resolveTargetPath(codexPaths.agents),
30425
- `${path40.basename(agentFile, ".md")}.toml`
30592
+ `${path42.basename(agentFile, ".md")}.toml`
30426
30593
  ),
30427
30594
  "codex",
30428
30595
  computeSourceHash(agentFile),
@@ -30446,11 +30613,11 @@ ${rules.agentsAppendix}`.trim();
30446
30613
  config,
30447
30614
  sourceRoot
30448
30615
  ),
30449
- fs40.existsSync(hooksSource) ? classifyCodexHooksFile(resolveTargetPath(codexPaths.hooksSharedFile)) : notConfiguredRow(
30616
+ fs41.existsSync(hooksSource) ? classifyCodexHooksFile(resolveTargetPath(codexPaths.hooksSharedFile)) : notConfiguredRow(
30450
30617
  "hooks",
30451
30618
  resolveTargetPath(codexPaths.hooksSharedFile)
30452
30619
  ),
30453
- fs40.existsSync(mcpSource) ? classifyCompiledFile(
30620
+ fs41.existsSync(mcpSource) ? classifyCompiledFile(
30454
30621
  "mcp",
30455
30622
  resolveTargetPath(codexPaths.mcpSharedFile),
30456
30623
  "codex",
@@ -30470,7 +30637,7 @@ function classifyCodexHooksFile(filePath) {
30470
30637
  conformant: true
30471
30638
  };
30472
30639
  }
30473
- if (!fs40.existsSync(filePath)) {
30640
+ if (!fs41.existsSync(filePath)) {
30474
30641
  return {
30475
30642
  component: "hooks",
30476
30643
  className: "missing",
@@ -30502,20 +30669,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
30502
30669
  mcpSharedFile: paths.mcp_shared_file
30503
30670
  };
30504
30671
  const agentFiles = ts(
30505
- path40.join(sourceRoot, config.source.agents, "*.md")
30672
+ path42.join(sourceRoot, config.source.agents, "*.md")
30506
30673
  ).sort();
30507
30674
  const commandFiles = ts(
30508
- path40.join(sourceRoot, config.source.commands, "*.md")
30675
+ path42.join(sourceRoot, config.source.commands, "*.md")
30509
30676
  ).sort();
30510
- const hooksSource = path40.join(sourceRoot, config.source.hooks, "hooks.json");
30511
- const mcpSource = path40.join(sourceRoot, config.source.mcp);
30677
+ const hooksSource = path42.join(sourceRoot, config.source.hooks, "hooks.json");
30678
+ const mcpSource = path42.join(sourceRoot, config.source.mcp);
30512
30679
  return [
30513
30680
  ...agentFiles.map(
30514
30681
  (agentFile) => classifyCompiledFile(
30515
- `agents/${path40.basename(agentFile, ".md")}`,
30516
- path40.join(
30682
+ `agents/${path42.basename(agentFile, ".md")}`,
30683
+ path42.join(
30517
30684
  resolveTargetPath(copilotPaths.agents),
30518
- `${path40.basename(agentFile, ".md")}.agent.md`
30685
+ `${path42.basename(agentFile, ".md")}.agent.md`
30519
30686
  ),
30520
30687
  "copilot",
30521
30688
  computeSourceHash(agentFile),
@@ -30532,10 +30699,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
30532
30699
  ),
30533
30700
  ...commandFiles.map(
30534
30701
  (commandFile) => classifyCompiledFile(
30535
- `commands/${path40.basename(commandFile, ".md")}`,
30536
- path40.join(
30702
+ `commands/${path42.basename(commandFile, ".md")}`,
30703
+ path42.join(
30537
30704
  resolveTargetPath(copilotPaths.prompts),
30538
- `${path40.basename(commandFile, ".md")}.prompt.md`
30705
+ `${path42.basename(commandFile, ".md")}.prompt.md`
30539
30706
  ),
30540
30707
  "copilot",
30541
30708
  computeSourceHash(commandFile),
@@ -30553,9 +30720,9 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
30553
30720
  config,
30554
30721
  sourceRoot
30555
30722
  ),
30556
- fs40.existsSync(hooksSource) ? classifyCompiledFile(
30723
+ fs41.existsSync(hooksSource) ? classifyCompiledFile(
30557
30724
  "hooks",
30558
- path40.join(
30725
+ path42.join(
30559
30726
  resolveTargetPath(copilotPaths.hooks),
30560
30727
  "tangyr-managed.json"
30561
30728
  ),
@@ -30565,12 +30732,12 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
30565
30732
  sourceRoot
30566
30733
  ) : notConfiguredRow(
30567
30734
  "hooks",
30568
- path40.join(
30735
+ path42.join(
30569
30736
  resolveTargetPath(copilotPaths.hooks),
30570
30737
  "tangyr-managed.json"
30571
30738
  )
30572
30739
  ),
30573
- fs40.existsSync(mcpSource) ? classifyCompiledFile(
30740
+ fs41.existsSync(mcpSource) ? classifyCompiledFile(
30574
30741
  "mcp",
30575
30742
  resolveTargetPath(copilotPaths.mcpSharedFile),
30576
30743
  "copilot",
@@ -30590,7 +30757,7 @@ function notConfiguredRow(component, filePath) {
30590
30757
  }
30591
30758
  function classifyDirectArtifact(artifact, config, sourceRoot) {
30592
30759
  const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
30593
- const sourcePath = artifact.sourceKey ? path40.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
30760
+ const sourcePath = artifact.sourceKey ? path42.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
30594
30761
  if (artifactClass === "managed-symlink" && sourcePath && !isSymlinkCurrent(artifact.path, sourcePath)) {
30595
30762
  return {
30596
30763
  component: artifact.component,
@@ -30679,9 +30846,9 @@ function classifyClaudeSharedFiles(config, sourceRoot) {
30679
30846
  classifyHooks(settingsPath),
30680
30847
  classifySettings(
30681
30848
  settingsPath,
30682
- path40.resolve(sourceRoot, config.source.settings)
30849
+ path42.resolve(sourceRoot, config.source.settings)
30683
30850
  ),
30684
- classifyMcp(claudeJsonPath, path40.resolve(sourceRoot, config.source.mcp))
30851
+ classifyMcp(claudeJsonPath, path42.resolve(sourceRoot, config.source.mcp))
30685
30852
  ];
30686
30853
  }
30687
30854
  function classifyHooks(filePath) {
@@ -30745,14 +30912,14 @@ function classifyMcp(filePath, sourcePath) {
30745
30912
  }
30746
30913
  function isSymlinkCurrent(linkPath, sourcePath) {
30747
30914
  try {
30748
- return fs40.realpathSync(linkPath) === fs40.realpathSync(sourcePath);
30915
+ return fs41.realpathSync(linkPath) === fs41.realpathSync(sourcePath);
30749
30916
  } catch {
30750
30917
  return false;
30751
30918
  }
30752
30919
  }
30753
30920
  function isCompiledCurrent6(filePath, sourcePath) {
30754
30921
  try {
30755
- const marker = extractProvenanceMarker(fs40.readFileSync(filePath, "utf8"));
30922
+ const marker = extractProvenanceMarker(fs41.readFileSync(filePath, "utf8"));
30756
30923
  return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
30757
30924
  } catch {
30758
30925
  return false;
@@ -30782,7 +30949,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
30782
30949
  }
30783
30950
  function readCompiledContent(filePath) {
30784
30951
  try {
30785
- return fs40.readFileSync(filePath, "utf8");
30952
+ return fs41.readFileSync(filePath, "utf8");
30786
30953
  } catch {
30787
30954
  return null;
30788
30955
  }
@@ -30813,8 +30980,8 @@ function hashString6(value) {
30813
30980
  }
30814
30981
 
30815
30982
  // src/commands/sync.ts
30816
- import fs42 from "fs";
30817
- import path42 from "path";
30983
+ import fs43 from "fs";
30984
+ import path44 from "path";
30818
30985
 
30819
30986
  // node_modules/chalk/source/vendor/ansi-styles/index.js
30820
30987
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -31312,8 +31479,8 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
31312
31479
  var source_default = chalk;
31313
31480
 
31314
31481
  // src/adapters/claude-code.ts
31315
- import fs41 from "fs";
31316
- import path41 from "path";
31482
+ import fs42 from "fs";
31483
+ import path43 from "path";
31317
31484
 
31318
31485
  // src/core/shim.ts
31319
31486
  import crypto11 from "crypto";
@@ -31387,7 +31554,8 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
31387
31554
  hooks_shared_file: resolveTargetPath("~/.claude/settings.json"),
31388
31555
  settings_shared_file: resolveTargetPath("~/.claude/settings.json"),
31389
31556
  mcp_shared_file: resolveTargetPath("~/.claude.json"),
31390
- hooks: resolveTargetPath("~/.agents/hooks")
31557
+ hooks: resolveTargetPath("~/.agents/hooks"),
31558
+ hook_scripts: resolveTargetPath("~/.agents/hooks")
31391
31559
  };
31392
31560
  }
31393
31561
  const directComponents = buildDirectComponents(profile);
@@ -31423,7 +31591,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
31423
31591
  }
31424
31592
  if (!shouldSkipComponent6(options, "instructions") && manifest && scopePath) {
31425
31593
  const shimPath = profile.instructions_shim;
31426
- const agentsMdPath = path41.resolve(sourceRoot, config.source.instructions);
31594
+ const agentsMdPath = path43.resolve(sourceRoot, config.source.instructions);
31427
31595
  if (!options.dryRun) {
31428
31596
  applyClaudeCodeShimUpgrade(
31429
31597
  shimPath,
@@ -31440,15 +31608,24 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
31440
31608
  }
31441
31609
  if (!shouldSkipComponent6(options, "hooks")) {
31442
31610
  outcomes.push(
31443
- syncHookScriptsBridge(
31611
+ syncHookScriptsBridge({
31612
+ source: path43.resolve(sourceRoot, config.source.hooks),
31613
+ destination: profile.hook_scripts,
31444
31614
  config,
31445
31615
  sourceRoot,
31446
31616
  options,
31447
31617
  logger,
31448
- profile.hooks,
31618
+ onConflict: () => handleConflict6(
31619
+ profile.hook_scripts,
31620
+ config,
31621
+ options,
31622
+ logger,
31623
+ manifest,
31624
+ scopePath
31625
+ ),
31449
31626
  manifest,
31450
31627
  scopePath
31451
- )
31628
+ })
31452
31629
  );
31453
31630
  outcomes.push(
31454
31631
  syncHooks6(
@@ -31457,7 +31634,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
31457
31634
  options,
31458
31635
  logger,
31459
31636
  profile.hooks_shared_file,
31460
- profile.hooks
31637
+ profile.hook_scripts
31461
31638
  )
31462
31639
  );
31463
31640
  }
@@ -31484,13 +31661,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
31484
31661
  }
31485
31662
  function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
31486
31663
  if (!mappings.modelTiers.custom_provider) return;
31487
- const agentsDir = path41.join(sourceRoot, config.source.agents);
31488
- if (!fs41.existsSync(agentsDir)) return;
31489
- for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
31664
+ const agentsDir = path43.join(sourceRoot, config.source.agents);
31665
+ if (!fs42.existsSync(agentsDir)) return;
31666
+ for (const agentFile of ts(path43.join(agentsDir, "*.md")).sort()) {
31490
31667
  const { data } = parseMarkdownFrontmatter(agentFile);
31491
31668
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
31492
31669
  if (hasProvider) {
31493
- const basename = path41.basename(agentFile);
31670
+ const basename = path43.basename(agentFile);
31494
31671
  addLoss(lossReport, "claude-code", "agents", {
31495
31672
  source: `agents/${basename}`,
31496
31673
  fields: [
@@ -31515,19 +31692,19 @@ function shouldSkipComponent6(options, component) {
31515
31692
  function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath, logger) {
31516
31693
  const expectedBodyHash = shimBodyHash();
31517
31694
  const shimContent = buildAgentsMdShim(shimPath, agentsMdPath, "claude-code");
31518
- if (!fs41.existsSync(shimPath)) {
31695
+ if (!fs42.existsSync(shimPath)) {
31519
31696
  manifest.artifacts.push({
31520
- relativePath: path41.relative(scopePath, shimPath),
31697
+ relativePath: path43.relative(scopePath, shimPath),
31521
31698
  hash: expectedBodyHash,
31522
31699
  origin: "tangyr-managed"
31523
31700
  });
31524
31701
  writeManifest(scopePath, manifest);
31525
- fs41.mkdirSync(path41.dirname(shimPath), { recursive: true });
31526
- fs41.writeFileSync(shimPath, shimContent);
31702
+ fs42.mkdirSync(path43.dirname(shimPath), { recursive: true });
31703
+ fs42.writeFileSync(shimPath, shimContent);
31527
31704
  logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
31528
31705
  return;
31529
31706
  }
31530
- const existing = fs41.readFileSync(shimPath, "utf8");
31707
+ const existing = fs42.readFileSync(shimPath, "utf8");
31531
31708
  const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
31532
31709
  const marker = extractProvenanceMarker(firstNonEmptyLine);
31533
31710
  if (marker !== null && marker.hash === expectedBodyHash) {
@@ -31538,21 +31715,21 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
31538
31715
  }
31539
31716
  backupFile(shimPath, manifest);
31540
31717
  writeManifest(scopePath, manifest);
31541
- fs41.writeFileSync(shimPath, shimContent);
31718
+ fs42.writeFileSync(shimPath, shimContent);
31542
31719
  manifest.artifacts.push({
31543
- relativePath: path41.relative(scopePath, shimPath),
31720
+ relativePath: path43.relative(scopePath, shimPath),
31544
31721
  hash: expectedBodyHash,
31545
31722
  origin: "tangyr-managed"
31546
31723
  });
31547
31724
  logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
31548
31725
  }
31549
31726
  function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
31550
- const source = path41.resolve(
31727
+ const source = path43.resolve(
31551
31728
  sourceRoot,
31552
31729
  config.source[directComponent.sourceKey]
31553
31730
  );
31554
31731
  const destination = directComponent.destination;
31555
- if (!fs41.existsSync(source)) {
31732
+ if (!fs42.existsSync(source)) {
31556
31733
  return skippedMissingSource6(directComponent.component, source);
31557
31734
  }
31558
31735
  if (options.dryRun) {
@@ -31566,7 +31743,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
31566
31743
  };
31567
31744
  }
31568
31745
  const artifactClass = classifyArtifact(destination, config, sourceRoot);
31569
- if (artifactClass === "managed-symlink" && isSymlinkTo6(destination, source)) {
31746
+ if (artifactClass === "managed-symlink" && isSymlinkTo7(destination, source)) {
31570
31747
  return {
31571
31748
  component: directComponent.component,
31572
31749
  status: "skipped-current",
@@ -31574,7 +31751,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
31574
31751
  };
31575
31752
  }
31576
31753
  if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
31577
- fs41.unlinkSync(destination);
31754
+ fs42.unlinkSync(destination);
31578
31755
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
31579
31756
  return {
31580
31757
  component: directComponent.component,
@@ -31582,9 +31759,9 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
31582
31759
  path: destination
31583
31760
  };
31584
31761
  } else if (artifactClass === "managed-symlink") {
31585
- fs41.unlinkSync(destination);
31762
+ fs42.unlinkSync(destination);
31586
31763
  }
31587
- ensureDir(path41.dirname(destination));
31764
+ ensureDir(path43.dirname(destination));
31588
31765
  createRelativeSymlink(source, destination, directComponent.type, {
31589
31766
  logger,
31590
31767
  provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
@@ -31601,8 +31778,8 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
31601
31778
  };
31602
31779
  }
31603
31780
  function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination, manifest, scopePath) {
31604
- const source = path41.resolve(sourceRoot, config.source.skills);
31605
- if (!fs41.existsSync(source)) {
31781
+ const source = path43.resolve(sourceRoot, config.source.skills);
31782
+ if (!fs42.existsSync(source)) {
31606
31783
  return [skippedMissingSource6("skills", source)];
31607
31784
  }
31608
31785
  const declaredNames = resolveKitSkillNames(sourceRoot);
@@ -31612,7 +31789,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
31612
31789
  if (isLegacyWholesaleSymlink) {
31613
31790
  for (const name of foreignSkillNames(source, declaredNames)) {
31614
31791
  logger.info(
31615
- `[dry-run] skills: migrate foreign skill ${path41.join(source, name)} -> ${path41.join(destination, name)}`
31792
+ `[dry-run] skills: migrate foreign skill ${path43.join(source, name)} -> ${path43.join(destination, name)}`
31616
31793
  );
31617
31794
  }
31618
31795
  logger.info(
@@ -31620,9 +31797,9 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
31620
31797
  );
31621
31798
  }
31622
31799
  for (const name of declaredNames ?? listSkillDirNames(source)) {
31623
- const skillDestination = path41.join(destination, name);
31800
+ const skillDestination = path43.join(destination, name);
31624
31801
  logger.info(
31625
- `[dry-run] skills: symlink ${path41.join(source, name)} -> ${skillDestination}`
31802
+ `[dry-run] skills: symlink ${path43.join(source, name)} -> ${skillDestination}`
31626
31803
  );
31627
31804
  outcomes2.push({
31628
31805
  component: "skills",
@@ -31655,13 +31832,13 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
31655
31832
  return outcomes;
31656
31833
  }
31657
31834
  function syncSingleSkill(config, sourceRoot, options, logger, source, destination, name, manifest, scopePath) {
31658
- const skillSource = path41.join(source, name);
31659
- const skillDestination = path41.join(destination, name);
31660
- if (!fs41.existsSync(skillSource)) {
31835
+ const skillSource = path43.join(source, name);
31836
+ const skillDestination = path43.join(destination, name);
31837
+ if (!fs42.existsSync(skillSource)) {
31661
31838
  return skippedMissingSource6("skills", skillSource);
31662
31839
  }
31663
31840
  const artifactClass = classifyArtifact(skillDestination, config, sourceRoot);
31664
- if (artifactClass === "managed-symlink" && isSymlinkTo6(skillDestination, skillSource)) {
31841
+ if (artifactClass === "managed-symlink" && isSymlinkTo7(skillDestination, skillSource)) {
31665
31842
  return {
31666
31843
  component: "skills",
31667
31844
  status: "skipped-current",
@@ -31669,7 +31846,7 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
31669
31846
  };
31670
31847
  }
31671
31848
  if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
31672
- fs41.unlinkSync(skillDestination);
31849
+ fs42.unlinkSync(skillDestination);
31673
31850
  } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(
31674
31851
  skillDestination,
31675
31852
  config,
@@ -31680,25 +31857,25 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
31680
31857
  )) {
31681
31858
  return { component: "skills", status: "conflict", path: skillDestination };
31682
31859
  } else if (artifactClass === "managed-symlink") {
31683
- fs41.unlinkSync(skillDestination);
31860
+ fs42.unlinkSync(skillDestination);
31684
31861
  }
31685
31862
  createRelativeSymlink(skillSource, skillDestination, "dir");
31686
31863
  return { component: "skills", status: "success", path: skillDestination };
31687
31864
  }
31688
31865
  function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
31689
31866
  const foreignNames = foreignSkillNames(source, declaredNames);
31690
- fs41.unlinkSync(destination);
31867
+ fs42.unlinkSync(destination);
31691
31868
  ensureDir(destination);
31692
31869
  for (const name of foreignNames) {
31693
- const from = path41.join(source, name);
31694
- const to = path41.join(destination, name);
31695
- if (fs41.existsSync(to)) {
31870
+ const from = path43.join(source, name);
31871
+ const to = path43.join(destination, name);
31872
+ if (fs42.existsSync(to)) {
31696
31873
  logger.warn(
31697
31874
  `skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
31698
31875
  );
31699
31876
  continue;
31700
31877
  }
31701
- fs41.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
31878
+ fs42.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
31702
31879
  logger.warn(
31703
31880
  `skills migration: '${name}' is present under the kit's skills/ but is not declared in its manifest. Copied ${from} -> ${to} so the harness can read it. The original is left in the kit deliberately: this command does not modify a kit. Remove ${from} yourself if it does not belong there, or declare it in tangyr-kit.yaml if it does.`
31704
31881
  );
@@ -31712,50 +31889,18 @@ function foreignSkillNames(source, declaredNames) {
31712
31889
  return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
31713
31890
  }
31714
31891
  function listSkillDirNames(dir) {
31715
- if (!fs41.existsSync(dir)) {
31892
+ if (!fs42.existsSync(dir)) {
31716
31893
  return [];
31717
31894
  }
31718
- return fs41.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
31895
+ return fs42.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
31719
31896
  }
31720
31897
  function isSymlinkPath(filePath) {
31721
31898
  try {
31722
- return fs41.lstatSync(filePath).isSymbolicLink();
31899
+ return fs42.lstatSync(filePath).isSymbolicLink();
31723
31900
  } catch {
31724
31901
  return false;
31725
31902
  }
31726
31903
  }
31727
- function syncHookScriptsBridge(config, sourceRoot, options, logger, destination, manifest, scopePath) {
31728
- const source = path41.resolve(sourceRoot, config.source.hooks);
31729
- if (!fs41.existsSync(source)) {
31730
- return skippedMissingSource6("hooks", source);
31731
- }
31732
- if (options.dryRun) {
31733
- logger.info(`[dry-run] hooks: symlink ${source} -> ${destination}`);
31734
- return { component: "hooks", status: "dry-run", path: destination };
31735
- }
31736
- const artifactClass = classifyArtifact(destination, config, sourceRoot);
31737
- if (artifactClass === "managed-symlink" && isSymlinkTo6(destination, source)) {
31738
- return { component: "hooks", status: "skipped-current", path: destination };
31739
- }
31740
- if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
31741
- fs41.unlinkSync(destination);
31742
- } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
31743
- return { component: "hooks", status: "conflict", path: destination };
31744
- } else if (artifactClass === "managed-symlink") {
31745
- fs41.unlinkSync(destination);
31746
- }
31747
- ensureDir(path41.dirname(destination));
31748
- createRelativeSymlink(source, destination, "dir");
31749
- return { component: "hooks", status: "success", path: destination };
31750
- }
31751
- function hookScriptsDir(scriptsBridge) {
31752
- const globalBridge = resolveTargetPath("~/.agents/hooks");
31753
- if (path41.resolve(scriptsBridge) === path41.resolve(globalBridge)) {
31754
- return GLOBAL_HOOK_SCRIPTS_DIR;
31755
- }
31756
- const relative = path41.relative(process.cwd(), scriptsBridge);
31757
- return relative.startsWith("..") || path41.isAbsolute(relative) ? path41.join(scriptsBridge, "scripts") : `"$CLAUDE_PROJECT_DIR"/${path41.posix.join(relative.split(path41.sep).join("/"), "scripts")}`;
31758
- }
31759
31904
  function syncHooks6(config, sourceRoot, options, logger, destination, scriptsBridge) {
31760
31905
  const hooksDir = resolveHooksSourceDir(sourceRoot, config);
31761
31906
  if (!hooksSourceExists(sourceRoot, config)) {
@@ -31769,14 +31914,14 @@ function syncHooks6(config, sourceRoot, options, logger, destination, scriptsBri
31769
31914
  const sourceHooks = loadSourceHooks(
31770
31915
  hooksDir,
31771
31916
  resolveKitHookNames(sourceRoot),
31772
- hookScriptsDir(scriptsBridge)
31917
+ hookScriptsDir(scriptsBridge, "claude-code").prefix
31773
31918
  );
31774
31919
  settings.hooks = markManaged(sourceHooks.hooks ?? {});
31775
31920
  const changed = writeSharedFile(
31776
31921
  destination,
31777
31922
  settings,
31778
31923
  stringifyJson3,
31779
- !fs41.existsSync(destination),
31924
+ !fs42.existsSync(destination),
31780
31925
  logger
31781
31926
  );
31782
31927
  return {
@@ -31786,8 +31931,8 @@ function syncHooks6(config, sourceRoot, options, logger, destination, scriptsBri
31786
31931
  };
31787
31932
  }
31788
31933
  function syncMcp6(config, sourceRoot, options, logger, destination) {
31789
- const source = path41.resolve(sourceRoot, config.source.mcp);
31790
- if (!fs41.existsSync(source)) {
31934
+ const source = path43.resolve(sourceRoot, config.source.mcp);
31935
+ if (!fs42.existsSync(source)) {
31791
31936
  return skippedMissingSource6("mcp", source);
31792
31937
  }
31793
31938
  if (options.dryRun) {
@@ -31812,7 +31957,7 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
31812
31957
  destination,
31813
31958
  hostConfig,
31814
31959
  stringifyJson3,
31815
- !fs41.existsSync(destination),
31960
+ !fs42.existsSync(destination),
31816
31961
  logger
31817
31962
  );
31818
31963
  return {
@@ -31822,8 +31967,8 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
31822
31967
  };
31823
31968
  }
31824
31969
  function syncSettings2(config, sourceRoot, options, logger, destination) {
31825
- const source = path41.resolve(sourceRoot, config.source.settings);
31826
- if (!fs41.existsSync(source)) {
31970
+ const source = path43.resolve(sourceRoot, config.source.settings);
31971
+ if (!fs42.existsSync(source)) {
31827
31972
  return skippedMissingSource6("settings", source);
31828
31973
  }
31829
31974
  if (options.dryRun) {
@@ -31841,7 +31986,7 @@ function syncSettings2(config, sourceRoot, options, logger, destination) {
31841
31986
  destination,
31842
31987
  settings,
31843
31988
  stringifyJson3,
31844
- !fs41.existsSync(destination),
31989
+ !fs42.existsSync(destination),
31845
31990
  logger
31846
31991
  );
31847
31992
  return {
@@ -31866,11 +32011,11 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
31866
32011
  backupFile(destination, manifest);
31867
32012
  writeManifest(scopePath, manifest);
31868
32013
  } else {
31869
- fs41.renameSync(destination, `${destination}.bak.${Date.now()}`);
32014
+ fs42.renameSync(destination, `${destination}.bak.${Date.now()}`);
31870
32015
  }
31871
32016
  return true;
31872
32017
  }
31873
- fs41.rmSync(destination, { recursive: true, force: true });
32018
+ fs42.rmSync(destination, { recursive: true, force: true });
31874
32019
  return true;
31875
32020
  }
31876
32021
  function skippedMissingSource6(component, source) {
@@ -31880,18 +32025,18 @@ function skippedMissingSource6(component, source) {
31880
32025
  path: `${source}: source not configured`
31881
32026
  };
31882
32027
  }
31883
- function isSymlinkTo6(linkPath, source) {
32028
+ function isSymlinkTo7(linkPath, source) {
31884
32029
  try {
31885
- return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
32030
+ return fs42.realpathSync(linkPath) === fs42.realpathSync(source);
31886
32031
  } catch {
31887
32032
  return false;
31888
32033
  }
31889
32034
  }
31890
32035
  function readJsonObject4(filePath) {
31891
- if (!fs41.existsSync(filePath)) {
32036
+ if (!fs42.existsSync(filePath)) {
31892
32037
  return {};
31893
32038
  }
31894
- const parsed = JSON.parse(fs41.readFileSync(filePath, "utf8"));
32039
+ const parsed = JSON.parse(fs42.readFileSync(filePath, "utf8"));
31895
32040
  return isRecord5(parsed) ? parsed : {};
31896
32041
  }
31897
32042
  function markManaged(value) {
@@ -32091,26 +32236,18 @@ async function runSyncCommand(options, logger) {
32091
32236
  reportHookRejections(
32092
32237
  lossReport,
32093
32238
  targets,
32094
- path42.resolve(kitInfo.path, "hooks"),
32239
+ path44.resolve(kitInfo.path, "hooks"),
32095
32240
  kitInfo.components.hooks.declared
32096
32241
  );
32097
32242
  const hooksConflict = reportHooksSourceConflict(
32098
32243
  lossReport,
32099
32244
  targets,
32100
- path42.resolve(kitInfo.path, "hooks"),
32245
+ path44.resolve(kitInfo.path, "hooks"),
32101
32246
  kitInfo.components.hooks.declared
32102
32247
  );
32103
32248
  if (hooksConflict) {
32104
32249
  logger.warn(hooksConflict);
32105
32250
  }
32106
- if (syncOptions.scope === "project") {
32107
- reportProjectScopeScriptPath(
32108
- lossReport,
32109
- targets,
32110
- path42.resolve(kitInfo.path, "hooks"),
32111
- kitInfo.components.hooks.declared
32112
- );
32113
- }
32114
32251
  }
32115
32252
  writeLossReport(options.lossReport, lossReport);
32116
32253
  printOutcomeTable(results);
@@ -32216,8 +32353,8 @@ function updateManifest(kitInfo, kitSync) {
32216
32353
  writeManifest(kitSync.scopePath, kitSync.manifest);
32217
32354
  }
32218
32355
  function resolveKitFilePath(kitPath, relativePath) {
32219
- const fullPath = path42.join(kitPath, relativePath);
32220
- return fs42.existsSync(fullPath) ? fullPath : null;
32356
+ const fullPath = path44.join(kitPath, relativePath);
32357
+ return fs43.existsSync(fullPath) ? fullPath : null;
32221
32358
  }
32222
32359
  function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
32223
32360
  if (removedSourcePaths.length === 0 || !mappings) {
@@ -32280,9 +32417,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
32280
32417
  }
32281
32418
  if (relativePath.startsWith("agents/")) {
32282
32419
  removeManagedCompiledArtifact2(
32283
- path42.join(
32420
+ path44.join(
32284
32421
  resolveTargetPath(paths.agents ?? ""),
32285
- `${path42.parse(relativePath).name}.agent.md`
32422
+ `${path44.parse(relativePath).name}.agent.md`
32286
32423
  ),
32287
32424
  "copilot",
32288
32425
  relativePath,
@@ -32292,9 +32429,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
32292
32429
  }
32293
32430
  if (relativePath.startsWith("commands/")) {
32294
32431
  removeManagedCompiledArtifact2(
32295
- path42.join(
32432
+ path44.join(
32296
32433
  resolveTargetPath(paths.prompts ?? ""),
32297
- `${path42.parse(relativePath).name}.prompt.md`
32434
+ `${path44.parse(relativePath).name}.prompt.md`
32298
32435
  ),
32299
32436
  "copilot",
32300
32437
  relativePath,
@@ -32304,7 +32441,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
32304
32441
  }
32305
32442
  if (relativePath.endsWith("hooks.json")) {
32306
32443
  removeManagedCompiledArtifact2(
32307
- path42.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
32444
+ path44.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
32308
32445
  "copilot",
32309
32446
  relativePath,
32310
32447
  logger
@@ -32334,9 +32471,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
32334
32471
  }
32335
32472
  if (relativePath.startsWith("agents/")) {
32336
32473
  removeManagedCompiledArtifact2(
32337
- path42.join(
32474
+ path44.join(
32338
32475
  resolveTargetPath(paths.agents ?? ""),
32339
- `${path42.parse(relativePath).name}.toml`
32476
+ `${path44.parse(relativePath).name}.toml`
32340
32477
  ),
32341
32478
  "codex",
32342
32479
  relativePath,
@@ -32346,9 +32483,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
32346
32483
  }
32347
32484
  if (relativePath.startsWith("rules/")) {
32348
32485
  removeManagedCompiledArtifact2(
32349
- path42.join(
32486
+ path44.join(
32350
32487
  resolveTargetPath(paths.rules ?? ""),
32351
- `${path42.parse(relativePath).name}.rules`
32488
+ `${path44.parse(relativePath).name}.rules`
32352
32489
  ),
32353
32490
  "codex",
32354
32491
  relativePath,
@@ -32387,9 +32524,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
32387
32524
  }
32388
32525
  if (relativePath.startsWith("agents/")) {
32389
32526
  removeManagedCompiledArtifact2(
32390
- path42.join(
32527
+ path44.join(
32391
32528
  resolveTargetPath(paths.agents ?? ""),
32392
- `${path42.parse(relativePath).name}.md`
32529
+ `${path44.parse(relativePath).name}.md`
32393
32530
  ),
32394
32531
  "opencode",
32395
32532
  relativePath,
@@ -32399,9 +32536,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
32399
32536
  }
32400
32537
  if (relativePath.startsWith("commands/")) {
32401
32538
  removeManagedCompiledArtifact2(
32402
- path42.join(
32539
+ path44.join(
32403
32540
  resolveTargetPath(paths.commands ?? ""),
32404
- `${path42.parse(relativePath).name}.md`
32541
+ `${path44.parse(relativePath).name}.md`
32405
32542
  ),
32406
32543
  "opencode",
32407
32544
  relativePath,
@@ -32433,9 +32570,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
32433
32570
  }
32434
32571
  if (relativePath.startsWith("agents/")) {
32435
32572
  removeManagedCompiledArtifact2(
32436
- path42.join(
32573
+ path44.join(
32437
32574
  resolveTargetPath(paths.agents ?? ""),
32438
- `${path42.parse(relativePath).name}.md`
32575
+ `${path44.parse(relativePath).name}.md`
32439
32576
  ),
32440
32577
  "cursor",
32441
32578
  relativePath,
@@ -32445,9 +32582,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
32445
32582
  }
32446
32583
  if (relativePath.startsWith("rules/")) {
32447
32584
  removeManagedCompiledArtifact2(
32448
- path42.join(
32585
+ path44.join(
32449
32586
  resolveTargetPath(paths.rules ?? ""),
32450
- `${path42.parse(relativePath).name}.mdc`
32587
+ `${path44.parse(relativePath).name}.mdc`
32451
32588
  ),
32452
32589
  "cursor",
32453
32590
  relativePath,
@@ -32457,9 +32594,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
32457
32594
  }
32458
32595
  if (relativePath.startsWith("commands/")) {
32459
32596
  removeManagedCompiledArtifact2(
32460
- path42.join(
32597
+ path44.join(
32461
32598
  resolveTargetPath(paths.skills ?? ""),
32462
- path42.parse(relativePath).name,
32599
+ path44.parse(relativePath).name,
32463
32600
  "SKILL.md"
32464
32601
  ),
32465
32602
  "cursor",
@@ -32503,9 +32640,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
32503
32640
  }
32504
32641
  if (relativePath.startsWith("rules/")) {
32505
32642
  removeManagedCompiledArtifact2(
32506
- path42.join(
32643
+ path44.join(
32507
32644
  resolveTargetPath(paths.rules ?? ""),
32508
- `${path42.parse(relativePath).name}.md`
32645
+ `${path44.parse(relativePath).name}.md`
32509
32646
  ),
32510
32647
  "cline",
32511
32648
  relativePath,
@@ -32515,9 +32652,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
32515
32652
  }
32516
32653
  if (relativePath.startsWith("commands/")) {
32517
32654
  removeManagedCompiledArtifact2(
32518
- path42.join(
32655
+ path44.join(
32519
32656
  resolveTargetPath(paths.workflows ?? ""),
32520
- path42.basename(relativePath)
32657
+ path44.basename(relativePath)
32521
32658
  ),
32522
32659
  "cline",
32523
32660
  relativePath,
@@ -32535,17 +32672,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
32535
32672
  }
32536
32673
  }
32537
32674
  function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
32538
- if (!fs42.existsSync(artifactPath)) {
32675
+ if (!fs43.existsSync(artifactPath)) {
32539
32676
  return;
32540
32677
  }
32541
- if (!fs42.statSync(artifactPath).isFile()) {
32678
+ if (!fs43.statSync(artifactPath).isFile()) {
32542
32679
  return;
32543
32680
  }
32544
- const marker = extractProvenanceMarker(fs42.readFileSync(artifactPath, "utf8"));
32681
+ const marker = extractProvenanceMarker(fs43.readFileSync(artifactPath, "utf8"));
32545
32682
  if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
32546
32683
  return;
32547
32684
  }
32548
- fs42.rmSync(artifactPath, { force: true });
32685
+ fs43.rmSync(artifactPath, { force: true });
32549
32686
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
32550
32687
  }
32551
32688
  function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
@@ -32576,10 +32713,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
32576
32713
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
32577
32714
  }
32578
32715
  function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
32579
- if (!fs42.existsSync(artifactPath)) {
32716
+ if (!fs43.existsSync(artifactPath)) {
32580
32717
  return;
32581
32718
  }
32582
- const content = fs42.readFileSync(artifactPath, "utf8");
32719
+ const content = fs43.readFileSync(artifactPath, "utf8");
32583
32720
  const startMarker = "# tangyr: managed mcp start";
32584
32721
  const endMarker = "# tangyr: managed mcp end";
32585
32722
  const startIndex = content.indexOf(startMarker);
@@ -32596,19 +32733,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
32596
32733
  const after = content.slice(endIndex + endMarker.length).trimStart();
32597
32734
  const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
32598
32735
  if (cleaned.length === 0) {
32599
- fs42.rmSync(artifactPath, { force: true });
32736
+ fs43.rmSync(artifactPath, { force: true });
32600
32737
  } else {
32601
- fs42.writeFileSync(artifactPath, `${cleaned}
32738
+ fs43.writeFileSync(artifactPath, `${cleaned}
32602
32739
  `);
32603
32740
  }
32604
32741
  logger.verbose(` removed stale target artifact: ${artifactPath}`);
32605
32742
  }
32606
32743
  function readJsonObject5(filePath) {
32607
- if (!fs42.existsSync(filePath)) {
32744
+ if (!fs43.existsSync(filePath)) {
32608
32745
  return null;
32609
32746
  }
32610
32747
  try {
32611
- const parsed = JSON.parse(fs42.readFileSync(filePath, "utf8"));
32748
+ const parsed = JSON.parse(fs43.readFileSync(filePath, "utf8"));
32612
32749
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
32613
32750
  } catch {
32614
32751
  return null;
@@ -32622,10 +32759,10 @@ function readJsonMetadata(value) {
32622
32759
  }
32623
32760
  function writeJsonOrRemove2(filePath, parsed) {
32624
32761
  if (isEmptyJsonValue2(parsed)) {
32625
- fs42.rmSync(filePath, { force: true });
32762
+ fs43.rmSync(filePath, { force: true });
32626
32763
  return;
32627
32764
  }
32628
- fs42.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
32765
+ fs43.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
32629
32766
  `);
32630
32767
  }
32631
32768
  function isEmptyJsonValue2(value) {
@@ -32685,8 +32822,8 @@ function removeManagedHookEntries(value, expectedSource) {
32685
32822
  }
32686
32823
 
32687
32824
  // src/commands/validate.ts
32688
- import fs43 from "fs";
32689
- import path43 from "path";
32825
+ import fs44 from "fs";
32826
+ import path45 from "path";
32690
32827
  var SUPPORTED_KIT_FORMATS2 = [1];
32691
32828
  var SUPPORTED_DISCIPLINE_VERSIONS = [
32692
32829
  "0.14.0",
@@ -32780,10 +32917,10 @@ function checkSkillSubfolderNames(kit) {
32780
32917
  const notices = [];
32781
32918
  const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
32782
32919
  for (const name of kit.components.skills.declared) {
32783
- const skillDir = path43.join(kit.path, "skills", name);
32920
+ const skillDir = path45.join(kit.path, "skills", name);
32784
32921
  let entries;
32785
32922
  try {
32786
- entries = fs43.readdirSync(skillDir, { withFileTypes: true });
32923
+ entries = fs44.readdirSync(skillDir, { withFileTypes: true });
32787
32924
  } catch {
32788
32925
  continue;
32789
32926
  }
@@ -32801,7 +32938,7 @@ function checkSkillSubfolderNames(kit) {
32801
32938
  return notices;
32802
32939
  }
32803
32940
  function checkHooksSourceForm(kit) {
32804
- const hooksDir = path43.join(kit.path, "hooks");
32941
+ const hooksDir = path45.join(kit.path, "hooks");
32805
32942
  const message = describeHooksSourceConflict(
32806
32943
  hooksDir,
32807
32944
  kit.components.hooks.declared
@@ -32813,12 +32950,12 @@ function checkHooksSourceForm(kit) {
32813
32950
  } : null;
32814
32951
  }
32815
32952
  function checkHookDeclarations(kit) {
32816
- const hooksDir = path43.join(kit.path, "hooks");
32953
+ const hooksDir = path45.join(kit.path, "hooks");
32817
32954
  return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
32818
32955
  (r) => ({
32819
32956
  code: "hook-declaration-invalid",
32820
- location: `hooks/${path43.basename(r.file)}`,
32821
- message: `hooks: '${path43.basename(r.file, ".md")}' was rejected at '${r.field}' \u2014 ${r.reason}. Until this is fixed the hook is not installed on any target; install and sync report it as an error-severity loss and exit 3. To fix: correct the field named above in this file.`
32957
+ location: `hooks/${path45.basename(r.file)}`,
32958
+ message: `hooks: '${path45.basename(r.file, ".md")}' was rejected at '${r.field}' \u2014 ${r.reason}. Until this is fixed the hook is not installed on any target; install and sync report it as an error-severity loss and exit 3. To fix: correct the field named above in this file.`
32822
32959
  })
32823
32960
  );
32824
32961
  }
@@ -32838,11 +32975,11 @@ function checkKitFormatSupported(kit) {
32838
32975
  function checkEntrypointExists(kit) {
32839
32976
  const declared = kit.entrypoint;
32840
32977
  const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
32841
- const entrypointPath = path43.join(kit.path, entrypoint);
32842
- if (fs43.existsSync(entrypointPath)) {
32978
+ const entrypointPath = path45.join(kit.path, entrypoint);
32979
+ if (fs44.existsSync(entrypointPath)) {
32843
32980
  return null;
32844
32981
  }
32845
- const legacyPresent = declared === void 0 && fs43.existsSync(path43.join(kit.path, LEGACY_ENTRYPOINT));
32982
+ const legacyPresent = declared === void 0 && fs44.existsSync(path45.join(kit.path, LEGACY_ENTRYPOINT));
32846
32983
  const remedy = legacyPresent ? `This kit has '${LEGACY_ENTRYPOINT}' but not '${DEFAULT_ENTRYPOINT}'. Until now validate looked for '${LEGACY_ENTRYPOINT}' unconditionally; it now reads the manifest's 'entrypoint', defaulting to '${DEFAULT_ENTRYPOINT}' \u2014 the contract's canonical orientation document, of which '${LEGACY_ENTRYPOINT}' is a target translation. To fix: either add "entrypoint: ${LEGACY_ENTRYPOINT}" to tangyr-kit.yaml to keep the current filename, or rename '${LEGACY_ENTRYPOINT}' to '${DEFAULT_ENTRYPOINT}'.` : declared === void 0 ? `No 'entrypoint' is declared in tangyr-kit.yaml, so '${DEFAULT_ENTRYPOINT}' is expected at the kit root. To fix: create it, or declare the file you use with "entrypoint: <filename>".` : `tangyr-kit.yaml declares "entrypoint: ${declared}", and no such file exists at the kit root. To fix: create it, or correct the declaration.`;
32847
32984
  return {
32848
32985
  code: "entrypoint-missing",
@@ -32898,9 +33035,9 @@ function checkComponentFrontmatter(kit) {
32898
33035
  const missingSet = new Set(kit.components[cat].missing);
32899
33036
  for (const name of kit.components[cat].declared) {
32900
33037
  if (missingSet.has(name)) continue;
32901
- const filePath = cat === "skills" ? path43.join(kit.path, cat, name, "SKILL.md") : path43.join(kit.path, cat, `${name}.md`);
32902
- if (!fs43.existsSync(filePath)) continue;
32903
- const relPath = path43.relative(kit.path, filePath);
33038
+ const filePath = cat === "skills" ? path45.join(kit.path, cat, name, "SKILL.md") : path45.join(kit.path, cat, `${name}.md`);
33039
+ if (!fs44.existsSync(filePath)) continue;
33040
+ const relPath = path45.relative(kit.path, filePath);
32904
33041
  try {
32905
33042
  const { data } = parseMarkdownFrontmatter(filePath);
32906
33043
  for (const field of requiredFields) {
@@ -32925,10 +33062,10 @@ function checkComponentFrontmatter(kit) {
32925
33062
  }
32926
33063
  function checkReservedRootNames(kit) {
32927
33064
  const violations = [];
32928
- if (!fs43.existsSync(kit.path) || !fs43.statSync(kit.path).isDirectory()) {
33065
+ if (!fs44.existsSync(kit.path) || !fs44.statSync(kit.path).isDirectory()) {
32929
33066
  return violations;
32930
33067
  }
32931
- const entries = fs43.readdirSync(kit.path, { withFileTypes: true });
33068
+ const entries = fs44.readdirSync(kit.path, { withFileTypes: true });
32932
33069
  for (const entry of entries) {
32933
33070
  if (RESERVED_ROOT_NAMES.includes(entry.name)) {
32934
33071
  violations.push({
@@ -32945,8 +33082,8 @@ function checkHumanOnlyCommandInvocation(kit) {
32945
33082
  const missingSet = new Set(kit.components.commands.missing);
32946
33083
  for (const name of kit.components.commands.declared) {
32947
33084
  if (missingSet.has(name)) continue;
32948
- const filePath = path43.join(kit.path, "commands", `${name}.md`);
32949
- if (!fs43.existsSync(filePath)) continue;
33085
+ const filePath = path45.join(kit.path, "commands", `${name}.md`);
33086
+ if (!fs44.existsSync(filePath)) continue;
32950
33087
  let data;
32951
33088
  try {
32952
33089
  ({ data } = parseMarkdownFrontmatter(filePath));
@@ -32959,7 +33096,7 @@ function checkHumanOnlyCommandInvocation(kit) {
32959
33096
  if (!barred) {
32960
33097
  violations.push({
32961
33098
  code: "command-human-only-model-invocable",
32962
- location: path43.relative(kit.path, filePath),
33099
+ location: path45.relative(kit.path, filePath),
32963
33100
  message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
32964
33101
  });
32965
33102
  }
@@ -32968,8 +33105,8 @@ function checkHumanOnlyCommandInvocation(kit) {
32968
33105
  }
32969
33106
 
32970
33107
  // src/commands/verify.ts
32971
- import fs44 from "fs";
32972
- import path44 from "path";
33108
+ import fs45 from "fs";
33109
+ import path46 from "path";
32973
33110
  function runVerifyCommand(options, logger) {
32974
33111
  const { config, configDir, sourceRoot, kitInfo } = resolveRuntime(
32975
33112
  options,
@@ -33060,8 +33197,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
33060
33197
  if (!slotPath) {
33061
33198
  continue;
33062
33199
  }
33063
- const fullPath = subPath ? path44.join(slotPath, subPath) : slotPath;
33064
- if (!fs44.existsSync(fullPath)) {
33200
+ const fullPath = subPath ? path46.join(slotPath, subPath) : slotPath;
33201
+ if (!fs45.existsSync(fullPath)) {
33065
33202
  failures.push(
33066
33203
  `claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
33067
33204
  );