@alessandroraffa/tangyr 6.0.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1372,7 +1372,7 @@ var require_command = __commonJS({
1372
1372
  "use strict";
1373
1373
  var EventEmitter = __require("events").EventEmitter;
1374
1374
  var childProcess = __require("child_process");
1375
- var path54 = __require("path");
1375
+ var path55 = __require("path");
1376
1376
  var fs53 = __require("fs");
1377
1377
  var process5 = __require("process");
1378
1378
  var { Argument: Argument2, humanReadableArgName } = require_argument();
@@ -2385,9 +2385,9 @@ 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 = path54.resolve(baseDir, baseName);
2388
+ const localBin = path55.resolve(baseDir, baseName);
2389
2389
  if (fs53.existsSync(localBin)) return localBin;
2390
- if (sourceExt.includes(path54.extname(baseName))) return void 0;
2390
+ if (sourceExt.includes(path55.extname(baseName))) return void 0;
2391
2391
  const foundExt = sourceExt.find(
2392
2392
  (ext) => fs53.existsSync(`${localBin}${ext}`)
2393
2393
  );
@@ -2405,17 +2405,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
2405
2405
  } catch {
2406
2406
  resolvedScriptPath = this._scriptPath;
2407
2407
  }
2408
- executableDir = path54.resolve(
2409
- path54.dirname(resolvedScriptPath),
2408
+ executableDir = path55.resolve(
2409
+ path55.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 = path54.basename(
2416
+ const legacyName = path55.basename(
2417
2417
  this._scriptPath,
2418
- path54.extname(this._scriptPath)
2418
+ path55.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(path54.extname(executableFile));
2429
+ launchWithNode = sourceExt.includes(path55.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 = path54.basename(filename, path54.extname(filename));
3344
+ this._name = path55.basename(filename, path55.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(path55) {
3359
- if (path55 === void 0) return this._executableDir;
3360
- this._executableDir = path55;
3358
+ executableDir(path56) {
3359
+ if (path56 === void 0) return this._executableDir;
3360
+ this._executableDir = path56;
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, path54) {
3717
- const ctrl = callVisitor(key, node, visitor, path54);
3716
+ function visit_(key, node, visitor, path55) {
3717
+ const ctrl = callVisitor(key, node, visitor, path55);
3718
3718
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3719
- replaceNode(key, path54, ctrl);
3720
- return visit_(key, ctrl, visitor, path54);
3719
+ replaceNode(key, path55, ctrl);
3720
+ return visit_(key, ctrl, visitor, path55);
3721
3721
  }
3722
3722
  if (typeof ctrl !== "symbol") {
3723
3723
  if (identity.isCollection(node)) {
3724
- path54 = Object.freeze(path54.concat(node));
3724
+ path55 = Object.freeze(path55.concat(node));
3725
3725
  for (let i = 0; i < node.items.length; ++i) {
3726
- const ci2 = visit_(i, node.items[i], visitor, path54);
3726
+ const ci2 = visit_(i, node.items[i], visitor, path55);
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
- path54 = Object.freeze(path54.concat(node));
3738
- const ck = visit_("key", node.key, visitor, path54);
3737
+ path55 = Object.freeze(path55.concat(node));
3738
+ const ck = visit_("key", node.key, visitor, path55);
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, path54);
3743
+ const cv = visit_("value", node.value, visitor, path55);
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, path54) {
3765
- const ctrl = await callVisitor(key, node, visitor, path54);
3764
+ async function visitAsync_(key, node, visitor, path55) {
3765
+ const ctrl = await callVisitor(key, node, visitor, path55);
3766
3766
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3767
- replaceNode(key, path54, ctrl);
3768
- return visitAsync_(key, ctrl, visitor, path54);
3767
+ replaceNode(key, path55, ctrl);
3768
+ return visitAsync_(key, ctrl, visitor, path55);
3769
3769
  }
3770
3770
  if (typeof ctrl !== "symbol") {
3771
3771
  if (identity.isCollection(node)) {
3772
- path54 = Object.freeze(path54.concat(node));
3772
+ path55 = Object.freeze(path55.concat(node));
3773
3773
  for (let i = 0; i < node.items.length; ++i) {
3774
- const ci2 = await visitAsync_(i, node.items[i], visitor, path54);
3774
+ const ci2 = await visitAsync_(i, node.items[i], visitor, path55);
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
- path54 = Object.freeze(path54.concat(node));
3786
- const ck = await visitAsync_("key", node.key, visitor, path54);
3785
+ path55 = Object.freeze(path55.concat(node));
3786
+ const ck = await visitAsync_("key", node.key, visitor, path55);
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, path54);
3791
+ const cv = await visitAsync_("value", node.value, visitor, path55);
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, path54) {
3818
+ function callVisitor(key, node, visitor, path55) {
3819
3819
  if (typeof visitor === "function")
3820
- return visitor(key, node, path54);
3820
+ return visitor(key, node, path55);
3821
3821
  if (identity.isMap(node))
3822
- return visitor.Map?.(key, node, path54);
3822
+ return visitor.Map?.(key, node, path55);
3823
3823
  if (identity.isSeq(node))
3824
- return visitor.Seq?.(key, node, path54);
3824
+ return visitor.Seq?.(key, node, path55);
3825
3825
  if (identity.isPair(node))
3826
- return visitor.Pair?.(key, node, path54);
3826
+ return visitor.Pair?.(key, node, path55);
3827
3827
  if (identity.isScalar(node))
3828
- return visitor.Scalar?.(key, node, path54);
3828
+ return visitor.Scalar?.(key, node, path55);
3829
3829
  if (identity.isAlias(node))
3830
- return visitor.Alias?.(key, node, path54);
3830
+ return visitor.Alias?.(key, node, path55);
3831
3831
  return void 0;
3832
3832
  }
3833
- function replaceNode(key, path54, node) {
3834
- const parent = path54[path54.length - 1];
3833
+ function replaceNode(key, path55, node) {
3834
+ const parent = path55[path55.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, path54, value) {
4442
+ function collectionFromPath(schema, path55, value) {
4443
4443
  let v2 = value;
4444
- for (let i = path54.length - 1; i >= 0; --i) {
4445
- const k2 = path54[i];
4444
+ for (let i = path55.length - 1; i >= 0; --i) {
4445
+ const k2 = path55[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 = (path54) => path54 == null || typeof path54 === "object" && !!path54[Symbol.iterator]().next().done;
4464
+ var isEmptyPath = (path55) => path55 == null || typeof path55 === "object" && !!path55[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(path54, value) {
4495
- if (isEmptyPath(path54))
4494
+ addIn(path55, value) {
4495
+ if (isEmptyPath(path55))
4496
4496
  this.add(value);
4497
4497
  else {
4498
- const [key, ...rest] = path54;
4498
+ const [key, ...rest] = path55;
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(path54) {
4513
- const [key, ...rest] = path54;
4512
+ deleteIn(path55) {
4513
+ const [key, ...rest] = path55;
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(path54, keepScalar) {
4528
- const [key, ...rest] = path54;
4527
+ getIn(path55, keepScalar) {
4528
+ const [key, ...rest] = path55;
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(path54) {
4547
- const [key, ...rest] = path54;
4546
+ hasIn(path55) {
4547
+ const [key, ...rest] = path55;
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(path54, value) {
4558
- const [key, ...rest] = path54;
4557
+ setIn(path55, value) {
4558
+ const [key, ...rest] = path55;
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(path54, value) {
7070
+ addIn(path55, value) {
7071
7071
  if (assertCollection(this.contents))
7072
- this.contents.addIn(path54, value);
7072
+ this.contents.addIn(path55, 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(path54) {
7148
- if (Collection.isEmptyPath(path54)) {
7147
+ deleteIn(path55) {
7148
+ if (Collection.isEmptyPath(path55)) {
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(path54) : false;
7154
+ return assertCollection(this.contents) ? this.contents.deleteIn(path55) : 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(path54, keepScalar) {
7170
- if (Collection.isEmptyPath(path54))
7169
+ getIn(path55, keepScalar) {
7170
+ if (Collection.isEmptyPath(path55))
7171
7171
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
7172
- return identity.isCollection(this.contents) ? this.contents.getIn(path54, keepScalar) : void 0;
7172
+ return identity.isCollection(this.contents) ? this.contents.getIn(path55, 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(path54) {
7184
- if (Collection.isEmptyPath(path54))
7183
+ hasIn(path55) {
7184
+ if (Collection.isEmptyPath(path55))
7185
7185
  return this.contents !== void 0;
7186
- return identity.isCollection(this.contents) ? this.contents.hasIn(path54) : false;
7186
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path55) : 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(path54, value) {
7204
- if (Collection.isEmptyPath(path54)) {
7203
+ setIn(path55, value) {
7204
+ if (Collection.isEmptyPath(path55)) {
7205
7205
  this.contents = value;
7206
7206
  } else if (this.contents == null) {
7207
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path54), value);
7207
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path55), value);
7208
7208
  } else if (assertCollection(this.contents)) {
7209
- this.contents.setIn(path54, value);
7209
+ this.contents.setIn(path55, 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, path54) => {
9166
+ visit.itemAtPath = (cst, path55) => {
9167
9167
  let item = cst;
9168
- for (const [field, index] of path54) {
9168
+ for (const [field, index] of path55) {
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, path54) => {
9178
- const parent = visit.itemAtPath(cst, path54.slice(0, -1));
9179
- const field = path54[path54.length - 1][0];
9177
+ visit.parentCollection = (cst, path55) => {
9178
+ const parent = visit.itemAtPath(cst, path55.slice(0, -1));
9179
+ const field = path55[path55.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(path54, item, visitor) {
9186
- let ctrl = visitor(item, path54);
9185
+ function _visit(path55, item, visitor) {
9186
+ let ctrl = visitor(item, path55);
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(path54.concat([[field, i]])), token.items[i], visitor);
9193
+ const ci2 = _visit(Object.freeze(path55.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, path54);
9204
+ ctrl = ctrl(item, path55);
9205
9205
  }
9206
9206
  }
9207
- return typeof ctrl === "function" ? ctrl(item, path54) : ctrl;
9207
+ return typeof ctrl === "function" ? ctrl(item, path55) : ctrl;
9208
9208
  }
9209
9209
  exports2.visit = visit;
9210
9210
  }
@@ -15930,7 +15930,8 @@ function readManifest(scopePath) {
15930
15930
  // and `uninstall` is a different process from `install`. The shared-surface
15931
15931
  // records went out to disk correctly and arrived as `undefined`, which put
15932
15932
  // removal back on the marker-based guess this exists to replace.
15933
- sharedSurfaces: Array.isArray(parsed.sharedSurfaces) ? parsed.sharedSurfaces : void 0
15933
+ sharedSurfaces: Array.isArray(parsed.sharedSurfaces) ? parsed.sharedSurfaces : void 0,
15934
+ kit: typeof parsed.kit === "object" && parsed.kit !== null && typeof parsed.kit.name === "string" ? parsed.kit : void 0
15934
15935
  };
15935
15936
  }
15936
15937
  function readStrictManifest(scopePath) {
@@ -16710,6 +16711,21 @@ function makeResolver(scope, projectRoot, tool) {
16710
16711
  return resolved;
16711
16712
  };
16712
16713
  }
16714
+ function slotsForScope(scopeMap, scope, projectRoot) {
16715
+ if (scope !== "project") {
16716
+ return scopeMap?.global;
16717
+ }
16718
+ const projectSlots = scopeMap?.project;
16719
+ if (!projectSlots) {
16720
+ return void 0;
16721
+ }
16722
+ const root = projectRoot ?? process.cwd();
16723
+ const resolved = {};
16724
+ for (const [slot, value] of Object.entries(projectSlots)) {
16725
+ resolved[slot] = typeof value === "string" ? path9.resolve(root, value) : value;
16726
+ }
16727
+ return resolved;
16728
+ }
16713
16729
 
16714
16730
  // src/mappings/loader.ts
16715
16731
  var import_yaml4 = __toESM(require_dist(), 1);
@@ -18382,7 +18398,7 @@ async function runCacheClearCommand(options, logger) {
18382
18398
 
18383
18399
  // src/commands/cleanup.ts
18384
18400
  import fs29 from "fs";
18385
- import path26 from "path";
18401
+ import path27 from "path";
18386
18402
 
18387
18403
  // node_modules/glob/dist/esm/index.min.js
18388
18404
  import { fileURLToPath as Wi } from "url";
@@ -21542,7 +21558,7 @@ function removeManagedEntries(filePath, parser, serializer, removeManaged, logge
21542
21558
 
21543
21559
  // src/commands/uninstall.ts
21544
21560
  import fs28 from "fs";
21545
- import path25 from "path";
21561
+ import path26 from "path";
21546
21562
 
21547
21563
  // src/core/managed-sources.ts
21548
21564
  var import_yaml5 = __toESM(require_dist(), 1);
@@ -21628,10 +21644,11 @@ function normalizeManagedSourcePath(rawPath) {
21628
21644
 
21629
21645
  // src/compiler/hook-components.ts
21630
21646
  import fs22 from "fs";
21631
- import path20 from "path";
21647
+ import path21 from "path";
21632
21648
 
21633
21649
  // src/compiler/loss-report.ts
21634
21650
  import fs21 from "fs";
21651
+ import path20 from "path";
21635
21652
  function createLossReport() {
21636
21653
  return {
21637
21654
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -21710,12 +21727,24 @@ function resolveLossSeverity(kind, name, action, explicitSeverity) {
21710
21727
  }
21711
21728
  return lossSeverityByEntryType[action];
21712
21729
  }
21713
- function writeLossReport(filePath, report) {
21714
- if (!filePath) {
21715
- return;
21730
+ var DEFAULT_LOSS_REPORT_FILE = "loss.json";
21731
+ function writeLossReport(filePath, report, scopePath) {
21732
+ const destinations = /* @__PURE__ */ new Set();
21733
+ if (filePath) {
21734
+ destinations.add(filePath);
21735
+ }
21736
+ if (scopePath) {
21737
+ destinations.add(path20.join(scopePath, DEFAULT_LOSS_REPORT_FILE));
21738
+ }
21739
+ const serialized = `${JSON.stringify(report, null, 2)}
21740
+ `;
21741
+ for (const destination of destinations) {
21742
+ try {
21743
+ fs21.mkdirSync(path20.dirname(destination), { recursive: true });
21744
+ fs21.writeFileSync(destination, serialized);
21745
+ } catch {
21746
+ }
21716
21747
  }
21717
- fs21.writeFileSync(filePath, `${JSON.stringify(report, null, 2)}
21718
- `);
21719
21748
  }
21720
21749
 
21721
21750
  // src/compiler/hook-components.ts
@@ -21850,7 +21879,7 @@ function synthesizeHooksJson(declarations, scriptsDir) {
21850
21879
  return { hooks };
21851
21880
  }
21852
21881
  function loadSourceHooks(hooksDir, hookNames, scriptsDir) {
21853
- const hooksJsonPath = path20.join(hooksDir, "hooks.json");
21882
+ const hooksJsonPath = path21.join(hooksDir, "hooks.json");
21854
21883
  if (fs22.existsSync(hooksJsonPath)) {
21855
21884
  const raw = fs22.readFileSync(hooksJsonPath, "utf8");
21856
21885
  return JSON.parse(raw);
@@ -21870,7 +21899,7 @@ function loadHookDeclarations(hooksDir, hookNames) {
21870
21899
  }
21871
21900
  const declarations = [];
21872
21901
  for (const name of names) {
21873
- const filePath = path20.join(hooksDir, `${name}.md`);
21902
+ const filePath = path21.join(hooksDir, `${name}.md`);
21874
21903
  const result = parseHookDeclaration(filePath);
21875
21904
  if (result.ok) {
21876
21905
  declarations.push(result.declaration);
@@ -21879,7 +21908,7 @@ function loadHookDeclarations(hooksDir, hookNames) {
21879
21908
  return declarations;
21880
21909
  }
21881
21910
  function collectHookRejections(hooksDir, hookNames) {
21882
- if (fs22.existsSync(path20.join(hooksDir, "hooks.json"))) {
21911
+ if (fs22.existsSync(path21.join(hooksDir, "hooks.json"))) {
21883
21912
  return [];
21884
21913
  }
21885
21914
  if (!fs22.existsSync(hooksDir) || !fs22.statSync(hooksDir).isDirectory()) {
@@ -21888,7 +21917,7 @@ function collectHookRejections(hooksDir, hookNames) {
21888
21917
  const names = hookNames && hookNames.length > 0 ? hookNames : fs22.readdirSync(hooksDir).filter((f) => f.endsWith(".md") && !f.startsWith(".")).map((f) => f.slice(0, -3)).sort();
21889
21918
  const rejections = [];
21890
21919
  for (const name of names) {
21891
- const filePath = path20.join(hooksDir, `${name}.md`);
21920
+ const filePath = path21.join(hooksDir, `${name}.md`);
21892
21921
  if (!fs22.existsSync(filePath)) {
21893
21922
  continue;
21894
21923
  }
@@ -21922,10 +21951,10 @@ function extractFrontmatter(content) {
21922
21951
  function reportHookRejections(report, targets, hooksDir, hookNames) {
21923
21952
  const rejections = collectHookRejections(hooksDir, hookNames);
21924
21953
  for (const rejection of rejections) {
21925
- const name = path20.basename(rejection.file, ".md");
21954
+ const name = path21.basename(rejection.file, ".md");
21926
21955
  for (const target of targets) {
21927
21956
  addLoss(report, target, "hooks", {
21928
- source: `hooks/${path20.basename(rejection.file)}`,
21957
+ source: `hooks/${path21.basename(rejection.file)}`,
21929
21958
  fields: [
21930
21959
  {
21931
21960
  field: rejection.field,
@@ -21946,7 +21975,7 @@ function declarationFileNames(hooksDir) {
21946
21975
  return fs22.readdirSync(hooksDir).filter((f) => f.endsWith(".md") && !f.startsWith(".")).sort();
21947
21976
  }
21948
21977
  function detectHooksSourceForm(hooksDir) {
21949
- const hasJson = fs22.existsSync(path20.join(hooksDir, "hooks.json"));
21978
+ const hasJson = fs22.existsSync(path21.join(hooksDir, "hooks.json"));
21950
21979
  const hasDeclarations = declarationFileNames(hooksDir).length > 0;
21951
21980
  if (hasJson && hasDeclarations) return { kind: "both" };
21952
21981
  if (hasJson) return { kind: "hooks-json" };
@@ -21980,7 +22009,7 @@ function describeHooksSourceConflict(hooksDir, hookNames) {
21980
22009
  if (detectHooksSourceForm(hooksDir).kind !== "both") {
21981
22010
  return null;
21982
22011
  }
21983
- const jsonPath = path20.join(hooksDir, "hooks.json");
22012
+ const jsonPath = path21.join(hooksDir, "hooks.json");
21984
22013
  const declared = declarationFileNames(hooksDir);
21985
22014
  let divergence = "";
21986
22015
  try {
@@ -22022,7 +22051,7 @@ function loadKitHooksSource(sourceRoot, config, scriptsDir) {
22022
22051
  const form = detectHooksSourceForm(hooksDir);
22023
22052
  return {
22024
22053
  hooks,
22025
- path: form.kind === "declarations" ? hooksDir : path20.join(hooksDir, "hooks.json"),
22054
+ path: form.kind === "declarations" ? hooksDir : path21.join(hooksDir, "hooks.json"),
22026
22055
  label: hooksSourceLabel(sourceRoot, config),
22027
22056
  // Hashed over the compiled input rather than over one file's bytes: the
22028
22057
  // declaration form has no single file to hash, and what provenance needs
@@ -22037,7 +22066,7 @@ function reportHooksSourceConflict(report, targets, hooksDir, hookNames) {
22037
22066
  }
22038
22067
  for (const target of targets) {
22039
22068
  addLoss(report, target, "hooks", {
22040
- source: `${path20.basename(hooksDir)}/`,
22069
+ source: `${path21.basename(hooksDir)}/`,
22041
22070
  fields: [
22042
22071
  {
22043
22072
  field: "hooks.json",
@@ -22053,18 +22082,18 @@ function reportHooksSourceConflict(report, targets, hooksDir, hookNames) {
22053
22082
 
22054
22083
  // src/adapters/hook-scripts-bridge.ts
22055
22084
  import fs25 from "fs";
22056
- import path23 from "path";
22085
+ import path24 from "path";
22057
22086
 
22058
22087
  // src/utils/fs.ts
22059
22088
  import fs23 from "fs";
22060
- import path21 from "path";
22089
+ import path22 from "path";
22061
22090
  function ensureDir(dirPath) {
22062
22091
  fs23.mkdirSync(dirPath, { recursive: true });
22063
22092
  }
22064
22093
  function createRelativeSymlink(source, destination, type, options) {
22065
- const absoluteSource = path21.resolve(source);
22066
- const relative = path21.relative(
22067
- realPathOrInput(path21.dirname(destination)),
22094
+ const absoluteSource = path22.resolve(source);
22095
+ const relative = path22.relative(
22096
+ realPathOrInput(path22.dirname(destination)),
22068
22097
  absoluteSource
22069
22098
  );
22070
22099
  if (process.platform === "win32" && type === "dir") {
@@ -22098,7 +22127,7 @@ function createRelativeSymlink(source, destination, type, options) {
22098
22127
  fs23.symlinkSync(relative, destination, type);
22099
22128
  }
22100
22129
  function createManagedCopy(source, destination, provenanceMarker, _logger) {
22101
- ensureDir(path21.dirname(destination));
22130
+ ensureDir(path22.dirname(destination));
22102
22131
  const content = fs23.readFileSync(source, "utf8");
22103
22132
  fs23.writeFileSync(destination, `${provenanceMarker}
22104
22133
  ${content}`);
@@ -22184,7 +22213,7 @@ function compareArtifactState(recorded, artifactPath) {
22184
22213
  }
22185
22214
 
22186
22215
  // src/core/shared-artifacts.ts
22187
- import path22 from "path";
22216
+ import path23 from "path";
22188
22217
  var SHARED_NAMESPACE = "shared";
22189
22218
  var SHARED_INSTRUCTIONS_KEY = `${SHARED_NAMESPACE}/AGENTS.md`;
22190
22219
  var SHARED_INSTRUCTIONS_FILE = "AGENTS.md";
@@ -22194,14 +22223,14 @@ function sharedArtifactKey(destination, scope, projectRoot) {
22194
22223
  return null;
22195
22224
  }
22196
22225
  const root = projectRoot ?? process.cwd();
22197
- const shared = path22.resolve(root, SHARED_INSTRUCTIONS_FILE);
22198
- return path22.resolve(destination) === shared ? SHARED_INSTRUCTIONS_KEY : null;
22226
+ const shared = path23.resolve(root, SHARED_INSTRUCTIONS_FILE);
22227
+ return path23.resolve(destination) === shared ? SHARED_INSTRUCTIONS_KEY : null;
22199
22228
  }
22200
22229
  function resolveSharedArtifactKey(key, scope, projectRoot) {
22201
22230
  if (key !== SHARED_INSTRUCTIONS_KEY || scope !== "project") {
22202
22231
  return null;
22203
22232
  }
22204
- return path22.join(projectRoot ?? process.cwd(), SHARED_INSTRUCTIONS_FILE);
22233
+ return path23.join(projectRoot ?? process.cwd(), SHARED_INSTRUCTIONS_FILE);
22205
22234
  }
22206
22235
  var SHARED_SKILLS_PREFIX = `${SHARED_NAMESPACE}/skills`;
22207
22236
  function sharedKeyForDestination(destination, scope, projectRoot, platformPaths) {
@@ -22209,7 +22238,7 @@ function sharedKeyForDestination(destination, scope, projectRoot, platformPaths)
22209
22238
  if (instructions) {
22210
22239
  return instructions;
22211
22240
  }
22212
- const resolved = path22.resolve(destination);
22241
+ const resolved = path23.resolve(destination);
22213
22242
  let profiles;
22214
22243
  try {
22215
22244
  profiles = resolveTargetPaths({
@@ -22220,12 +22249,12 @@ function sharedKeyForDestination(destination, scope, projectRoot, platformPaths)
22220
22249
  } catch {
22221
22250
  return null;
22222
22251
  }
22223
- if (resolved === path22.resolve(profiles.codex.hook_scripts)) {
22252
+ if (resolved === path23.resolve(profiles.codex.hook_scripts)) {
22224
22253
  return SHARED_HOOK_SCRIPTS_KEY;
22225
22254
  }
22226
- const skillsRoot = path22.resolve(profiles.opencode.skills_shared);
22227
- if (resolved.startsWith(`${skillsRoot}${path22.sep}`)) {
22228
- const inside = path22.relative(skillsRoot, resolved).split(path22.sep).join("/");
22255
+ const skillsRoot = path23.resolve(profiles.opencode.skills_shared);
22256
+ if (resolved.startsWith(`${skillsRoot}${path23.sep}`)) {
22257
+ const inside = path23.relative(skillsRoot, resolved).split(path23.sep).join("/");
22229
22258
  return `${SHARED_SKILLS_PREFIX}/${inside}`;
22230
22259
  }
22231
22260
  return null;
@@ -22235,7 +22264,7 @@ function resolveSharedSkillsKey(key, sharedSkillsRoot) {
22235
22264
  return null;
22236
22265
  }
22237
22266
  const inside = key.slice(SHARED_SKILLS_PREFIX.length + 1);
22238
- return path22.join(sharedSkillsRoot, ...inside.split("/"));
22267
+ return path23.join(sharedSkillsRoot, ...inside.split("/"));
22239
22268
  }
22240
22269
 
22241
22270
  // src/adapters/hook-scripts-bridge.ts
@@ -22263,7 +22292,7 @@ function syncHookScriptsBridge(args) {
22263
22292
  } else if (artifactClass === "managed-symlink") {
22264
22293
  fs25.unlinkSync(destination);
22265
22294
  }
22266
- ensureDir(path23.dirname(destination));
22295
+ ensureDir(path24.dirname(destination));
22267
22296
  createRelativeSymlink(source, destination, "dir");
22268
22297
  if (args.manifest) {
22269
22298
  const state = describeArtifactState(destination);
@@ -22294,7 +22323,7 @@ function isSymlinkTo(linkPath, source) {
22294
22323
 
22295
22324
  // src/core/shared-surface.ts
22296
22325
  import fs26 from "fs";
22297
- import path24 from "path";
22326
+ import path25 from "path";
22298
22327
  function isPlainObject2(value) {
22299
22328
  return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) !== null;
22300
22329
  }
@@ -22607,7 +22636,7 @@ async function runUninstallCommand(options, logger) {
22607
22636
  if (recorded) {
22608
22637
  const outcome = revertSharedSurface(recorded, logger);
22609
22638
  if (outcome === "reverted" || outcome === "removed") {
22610
- removedParentDirs.add(path25.dirname(recorded.path));
22639
+ removedParentDirs.add(path26.dirname(recorded.path));
22611
22640
  removedCount++;
22612
22641
  }
22613
22642
  if (outcome === "reverted") {
@@ -22623,7 +22652,7 @@ async function runUninstallCommand(options, logger) {
22623
22652
  uninstallProjectRoot
22624
22653
  );
22625
22654
  if (surfacePath && stripTangyrFromMergeSurface(surfacePath, logger)) {
22626
- removedParentDirs.add(path25.dirname(surfacePath));
22655
+ removedParentDirs.add(path26.dirname(surfacePath));
22627
22656
  removedCount++;
22628
22657
  if (fs28.existsSync(surfacePath)) {
22629
22658
  keptSurfaces.push(surfacePath);
@@ -22645,7 +22674,7 @@ async function runUninstallCommand(options, logger) {
22645
22674
  for (const actualPath of paths) {
22646
22675
  if (actualPath && (fs28.existsSync(actualPath) || isSymlink(actualPath))) {
22647
22676
  removeManagedPath(actualPath);
22648
- removedParentDirs.add(path25.dirname(actualPath));
22677
+ removedParentDirs.add(path26.dirname(actualPath));
22649
22678
  logger.verbose(` removed: ${actualPath}`);
22650
22679
  removedCount++;
22651
22680
  } else {
@@ -22667,7 +22696,7 @@ async function runUninstallCommand(options, logger) {
22667
22696
  continue;
22668
22697
  }
22669
22698
  removeManagedPath(actualPath);
22670
- removedParentDirs.add(path25.dirname(actualPath));
22699
+ removedParentDirs.add(path26.dirname(actualPath));
22671
22700
  logger.verbose(` removed: ${actualPath}`);
22672
22701
  removedCount++;
22673
22702
  } else {
@@ -22724,12 +22753,17 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
22724
22753
  " The manifest is removed below, so nothing will reference these copies afterwards. Move what you need out of the backups directory now."
22725
22754
  );
22726
22755
  }
22727
- const manifestPath = path25.join(scopePath, "manifest.json");
22756
+ const manifestPath = path26.join(scopePath, "manifest.json");
22728
22757
  if (fs28.existsSync(manifestPath)) {
22729
22758
  fs28.unlinkSync(manifestPath);
22730
22759
  logger.verbose(` removed manifest: ${manifestPath}`);
22731
22760
  }
22732
- pruneEmptyDirs(path25.join(scopePath, "backups"), logger);
22761
+ const lossReportPath = path26.join(scopePath, DEFAULT_LOSS_REPORT_FILE);
22762
+ if (fs28.existsSync(lossReportPath)) {
22763
+ fs28.unlinkSync(lossReportPath);
22764
+ logger.verbose(` removed loss report: ${lossReportPath}`);
22765
+ }
22766
+ pruneEmptyDirs(path26.join(scopePath, "backups"), logger);
22733
22767
  try {
22734
22768
  const remaining = fs28.readdirSync(scopePath);
22735
22769
  if (remaining.length === 0) {
@@ -22752,7 +22786,7 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
22752
22786
  } else {
22753
22787
  logger.verbose(" no manifest to update after partial residue cleanup");
22754
22788
  }
22755
- const pruneBoundary = path25.dirname(scopePath);
22789
+ const pruneBoundary = path26.dirname(scopePath);
22756
22790
  for (const dir of removedParentDirs) {
22757
22791
  pruneEmptyAncestors2(dir, pruneBoundary, logger);
22758
22792
  }
@@ -22803,32 +22837,32 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
22803
22837
  if (!slotPath) {
22804
22838
  return null;
22805
22839
  }
22806
- return subPath ? path25.join(slotPath, subPath) : slotPath;
22840
+ return subPath ? path26.join(slotPath, subPath) : slotPath;
22807
22841
  }
22808
22842
  if (tool === "copilot") {
22809
22843
  const copilotPaths = resolveCopilotPaths(runtime, scope, projectRoot);
22810
22844
  if (component.startsWith("skills/")) {
22811
- return path25.join(copilotPaths.skills, component.slice("skills/".length));
22845
+ return path26.join(copilotPaths.skills, component.slice("skills/".length));
22812
22846
  }
22813
22847
  if (component === "skills") {
22814
22848
  return copilotPaths.skills;
22815
22849
  }
22816
22850
  if (component.startsWith("agents/")) {
22817
- return path25.join(copilotPaths.agents, component.slice("agents/".length));
22851
+ return path26.join(copilotPaths.agents, component.slice("agents/".length));
22818
22852
  }
22819
22853
  if (component.startsWith("prompts/")) {
22820
- return path25.join(
22854
+ return path26.join(
22821
22855
  copilotPaths.prompts,
22822
22856
  component.slice("prompts/".length)
22823
22857
  );
22824
22858
  }
22825
22859
  if (component.startsWith("hooks/")) {
22826
- return path25.join(copilotPaths.hooks, component.slice("hooks/".length));
22860
+ return path26.join(copilotPaths.hooks, component.slice("hooks/".length));
22827
22861
  }
22828
- if (component === path25.basename(copilotPaths.mcpSharedFile)) {
22862
+ if (component === path26.basename(copilotPaths.mcpSharedFile)) {
22829
22863
  return copilotPaths.mcpSharedFile;
22830
22864
  }
22831
- if (copilotPaths.instructions !== null && component === path25.basename(copilotPaths.instructions)) {
22865
+ if (copilotPaths.instructions !== null && component === path26.basename(copilotPaths.instructions)) {
22832
22866
  return copilotPaths.instructions;
22833
22867
  }
22834
22868
  return null;
@@ -22842,15 +22876,15 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
22842
22876
  return codexPaths.skills;
22843
22877
  }
22844
22878
  if (component.startsWith("agents/")) {
22845
- return path25.join(codexPaths.agents, component.slice("agents/".length));
22879
+ return path26.join(codexPaths.agents, component.slice("agents/".length));
22846
22880
  }
22847
22881
  if (component.startsWith("rules/")) {
22848
- return path25.join(codexPaths.rules, component.slice("rules/".length));
22882
+ return path26.join(codexPaths.rules, component.slice("rules/".length));
22849
22883
  }
22850
- if (component === path25.basename(codexPaths.hooksSharedFile)) {
22884
+ if (component === path26.basename(codexPaths.hooksSharedFile)) {
22851
22885
  return codexPaths.hooksSharedFile;
22852
22886
  }
22853
- if (component === path25.basename(codexPaths.mcpSharedFile)) {
22887
+ if (component === path26.basename(codexPaths.mcpSharedFile)) {
22854
22888
  return codexPaths.mcpSharedFile;
22855
22889
  }
22856
22890
  return null;
@@ -22867,15 +22901,15 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
22867
22901
  return opencodePaths.skillsShared;
22868
22902
  }
22869
22903
  if (component.startsWith("agents/")) {
22870
- return path25.join(opencodePaths.agents, component.slice("agents/".length));
22904
+ return path26.join(opencodePaths.agents, component.slice("agents/".length));
22871
22905
  }
22872
22906
  if (component.startsWith("commands/")) {
22873
- return path25.join(
22907
+ return path26.join(
22874
22908
  opencodePaths.commands,
22875
22909
  component.slice("commands/".length)
22876
22910
  );
22877
22911
  }
22878
- if (component === path25.basename(opencodePaths.configDoc)) {
22912
+ if (component === path26.basename(opencodePaths.configDoc)) {
22879
22913
  return opencodePaths.configDoc;
22880
22914
  }
22881
22915
  return null;
@@ -22901,13 +22935,13 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
22901
22935
  return cursorPaths.permissionsFile;
22902
22936
  }
22903
22937
  if (component.startsWith("agents/")) {
22904
- return path25.join(cursorPaths.agents, component.slice("agents/".length));
22938
+ return path26.join(cursorPaths.agents, component.slice("agents/".length));
22905
22939
  }
22906
22940
  if (component.startsWith("rules/")) {
22907
- return path25.join(cursorPaths.rules, component.slice("rules/".length));
22941
+ return path26.join(cursorPaths.rules, component.slice("rules/".length));
22908
22942
  }
22909
22943
  if (component.startsWith("skills/")) {
22910
- return path25.join(cursorPaths.skills, component.slice("skills/".length));
22944
+ return path26.join(cursorPaths.skills, component.slice("skills/".length));
22911
22945
  }
22912
22946
  return null;
22913
22947
  }
@@ -22923,10 +22957,10 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
22923
22957
  return clinePaths.mcpFile;
22924
22958
  }
22925
22959
  if (component.startsWith("rules/")) {
22926
- return path25.join(clinePaths.rules, component.slice("rules/".length));
22960
+ return path26.join(clinePaths.rules, component.slice("rules/".length));
22927
22961
  }
22928
22962
  if (component.startsWith("workflows/")) {
22929
- return path25.join(
22963
+ return path26.join(
22930
22964
  clinePaths.workflows,
22931
22965
  component.slice("workflows/".length)
22932
22966
  );
@@ -22960,22 +22994,22 @@ function resolveClaudeCodePaths(runtime, scope, projectRoot) {
22960
22994
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
22961
22995
  if (scope === "global") {
22962
22996
  return {
22963
- instructions: path25.join(home, ".claude", "CLAUDE.md"),
22964
- agents: path25.join(home, ".claude", "agents"),
22965
- skills: path25.join(home, ".claude", "skills"),
22966
- commands: path25.join(home, ".claude", "commands"),
22967
- rules: path25.join(home, ".claude", "rules"),
22968
- output_styles: path25.join(home, ".claude", "output-styles")
22997
+ instructions: path26.join(home, ".claude", "CLAUDE.md"),
22998
+ agents: path26.join(home, ".claude", "agents"),
22999
+ skills: path26.join(home, ".claude", "skills"),
23000
+ commands: path26.join(home, ".claude", "commands"),
23001
+ rules: path26.join(home, ".claude", "rules"),
23002
+ output_styles: path26.join(home, ".claude", "output-styles")
22969
23003
  };
22970
23004
  }
22971
23005
  const root = projectRoot ?? process.cwd();
22972
23006
  return {
22973
- instructions: path25.join(root, "CLAUDE.md"),
22974
- agents: path25.join(root, ".claude", "agents"),
22975
- skills: path25.join(root, ".claude", "skills"),
22976
- commands: path25.join(root, ".claude", "commands"),
22977
- rules: path25.join(root, ".claude", "rules"),
22978
- output_styles: path25.join(root, ".claude", "output-styles")
23007
+ instructions: path26.join(root, "CLAUDE.md"),
23008
+ agents: path26.join(root, ".claude", "agents"),
23009
+ skills: path26.join(root, ".claude", "skills"),
23010
+ commands: path26.join(root, ".claude", "commands"),
23011
+ rules: path26.join(root, ".claude", "rules"),
23012
+ output_styles: path26.join(root, ".claude", "output-styles")
22979
23013
  };
22980
23014
  }
22981
23015
  function resolveClaudeRootsForUninstall(manifest, runtime) {
@@ -22994,12 +23028,12 @@ function resolveClaudeRootsForUninstall(manifest, runtime) {
22994
23028
  projectRoot: void 0,
22995
23029
  mappings: mappings.platformPaths
22996
23030
  })["claude-code"];
22997
- return [path25.dirname(profile.agents)];
23031
+ return [path26.dirname(profile.agents)];
22998
23032
  } catch {
22999
23033
  }
23000
23034
  }
23001
23035
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
23002
- return [path25.resolve(expandHome(`${home}/.claude`))];
23036
+ return [path26.resolve(expandHome(`${home}/.claude`))];
23003
23037
  }
23004
23038
  function resolveAllClaudeRoots(manifest, runtime, claudeConfigDirs) {
23005
23039
  const home = process.env.HOME ?? process.env.USERPROFILE;
@@ -23011,13 +23045,13 @@ function resolveAllClaudeRoots(manifest, runtime, claudeConfigDirs) {
23011
23045
  env: process.env.TANGYR_CLAUDE_CONFIG_DIRS,
23012
23046
  config: runtime.config.claudeCodeGlobalPaths
23013
23047
  })
23014
- ].map((root) => path25.resolve(root))
23048
+ ].map((root) => path26.resolve(root))
23015
23049
  );
23016
23050
  if (home && fs28.existsSync(home)) {
23017
23051
  try {
23018
23052
  for (const entry of fs28.readdirSync(home, { withFileTypes: true })) {
23019
23053
  if (entry.isDirectory() && entry.name.startsWith(".claude-")) {
23020
- roots.add(path25.resolve(home, entry.name));
23054
+ roots.add(path26.resolve(home, entry.name));
23021
23055
  }
23022
23056
  }
23023
23057
  } catch {
@@ -23036,13 +23070,13 @@ function resolveManifestKeyToMultiPaths(key, claudeRoots, runtime) {
23036
23070
  const rootsToResolve = isShared ? [claudeRoots[0]] : claudeRoots;
23037
23071
  if (!runtime) {
23038
23072
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
23039
- const defaultRoot = path25.resolve(expandHome(`${home}/.claude`));
23073
+ const defaultRoot = path26.resolve(expandHome(`${home}/.claude`));
23040
23074
  return rootsToResolve.flatMap((root) => {
23041
23075
  const hardcoded = resolveHardcodedClaudeSlot(root, defaultRoot, slotName);
23042
23076
  if (!hardcoded) {
23043
23077
  return [];
23044
23078
  }
23045
- return [subPath ? path25.join(hardcoded, subPath) : hardcoded];
23079
+ return [subPath ? path26.join(hardcoded, subPath) : hardcoded];
23046
23080
  });
23047
23081
  }
23048
23082
  try {
@@ -23060,17 +23094,17 @@ function resolveManifestKeyToMultiPaths(key, claudeRoots, runtime) {
23060
23094
  if (!slotPath) {
23061
23095
  return [];
23062
23096
  }
23063
- return [subPath ? path25.join(slotPath, subPath) : slotPath];
23097
+ return [subPath ? path26.join(slotPath, subPath) : slotPath];
23064
23098
  });
23065
23099
  } catch {
23066
23100
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
23067
- const defaultRoot = path25.resolve(expandHome(`${home}/.claude`));
23101
+ const defaultRoot = path26.resolve(expandHome(`${home}/.claude`));
23068
23102
  return rootsToResolve.flatMap((root) => {
23069
23103
  const hardcoded = resolveHardcodedClaudeSlot(root, defaultRoot, slotName);
23070
23104
  if (!hardcoded) {
23071
23105
  return [];
23072
23106
  }
23073
- return [subPath ? path25.join(hardcoded, subPath) : hardcoded];
23107
+ return [subPath ? path26.join(hardcoded, subPath) : hardcoded];
23074
23108
  });
23075
23109
  }
23076
23110
  }
@@ -23095,9 +23129,9 @@ function resolveHardcodedClaudeSlot(root, defaultRoot, slotName) {
23095
23129
  return null;
23096
23130
  }
23097
23131
  if (root === defaultRoot) {
23098
- return path25.join(root, relative);
23132
+ return path26.join(root, relative);
23099
23133
  }
23100
- return path25.join(root, relative);
23134
+ return path26.join(root, relative);
23101
23135
  }
23102
23136
  function resolveRuntimeIfAvailable(options, logger) {
23103
23137
  try {
@@ -23169,9 +23203,9 @@ function stripTangyrFromMergeSurface(filePath, logger) {
23169
23203
  return true;
23170
23204
  }
23171
23205
  function pruneEmptyAncestors2(startDir, stopAt, logger) {
23172
- const boundary = path25.resolve(stopAt);
23173
- let current = path25.resolve(startDir);
23174
- while (current !== boundary && current.startsWith(`${boundary}${path25.sep}`)) {
23206
+ const boundary = path26.resolve(stopAt);
23207
+ let current = path26.resolve(startDir);
23208
+ while (current !== boundary && current.startsWith(`${boundary}${path26.sep}`)) {
23175
23209
  try {
23176
23210
  if (fs28.readdirSync(current).length > 0) {
23177
23211
  return;
@@ -23181,7 +23215,7 @@ function pruneEmptyAncestors2(startDir, stopAt, logger) {
23181
23215
  } catch {
23182
23216
  return;
23183
23217
  }
23184
- current = path25.dirname(current);
23218
+ current = path26.dirname(current);
23185
23219
  }
23186
23220
  }
23187
23221
  function pruneEmptyDirs(dir, logger) {
@@ -23196,7 +23230,7 @@ function pruneEmptyDirs(dir, logger) {
23196
23230
  }
23197
23231
  for (const entry of fs28.readdirSync(dir, { withFileTypes: true })) {
23198
23232
  if (entry.isDirectory() && !entry.isSymbolicLink()) {
23199
- pruneEmptyDirs(path25.join(dir, entry.name), logger);
23233
+ pruneEmptyDirs(path26.join(dir, entry.name), logger);
23200
23234
  }
23201
23235
  }
23202
23236
  try {
@@ -23221,9 +23255,9 @@ function sharedSurfaceFor(manifest, file, selectedTools, scope, runtime, project
23221
23255
  if (!artifactPath) {
23222
23256
  return null;
23223
23257
  }
23224
- const resolved = path25.resolve(artifactPath);
23258
+ const resolved = path26.resolve(artifactPath);
23225
23259
  return records.find(
23226
- (record) => path25.resolve(record.path) === resolved && selectedTools.has(record.tool)
23260
+ (record) => path26.resolve(record.path) === resolved && selectedTools.has(record.tool)
23227
23261
  ) ?? null;
23228
23262
  }
23229
23263
  function revertSharedSurface(record, logger) {
@@ -23304,7 +23338,7 @@ function addManagedSymlinkChildren(artifacts, directory, runtime, component) {
23304
23338
  return;
23305
23339
  }
23306
23340
  for (const entry of entries) {
23307
- const artifactPath = path25.join(directory, entry.name);
23341
+ const artifactPath = path26.join(directory, entry.name);
23308
23342
  const artifactClass = classifyArtifact(
23309
23343
  artifactPath,
23310
23344
  runtime.config,
@@ -23343,8 +23377,8 @@ function collectStringValuesByKey(value, keyName, values) {
23343
23377
  }
23344
23378
  function addLegacyOperatingGuideCopies(artifacts, claudeRoot) {
23345
23379
  for (const artifactPath of [
23346
- ...ts(path25.join(claudeRoot, "CLAUDE.md.bak.*")),
23347
- ...ts(path25.join(claudeRoot, "AGENTS.md.bak.*"))
23380
+ ...ts(path26.join(claudeRoot, "CLAUDE.md.bak.*")),
23381
+ ...ts(path26.join(claudeRoot, "AGENTS.md.bak.*"))
23348
23382
  ].sort()) {
23349
23383
  artifacts.push({
23350
23384
  component: "claude-code legacy operating guide backup",
@@ -23398,7 +23432,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23398
23432
  for (const skill of runtime.kitInfo.components.skills.declared) {
23399
23433
  artifacts.push({
23400
23434
  component: "claude-code skill",
23401
- path: path25.join(profile.skills, skill),
23435
+ path: path26.join(profile.skills, skill),
23402
23436
  kind: "direct"
23403
23437
  });
23404
23438
  }
@@ -23417,7 +23451,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23417
23451
  if (isFullToolUninstall(manifest, selectedTools)) {
23418
23452
  addLegacyOperatingGuideCopies(
23419
23453
  artifacts,
23420
- path25.dirname(profile.instructions)
23454
+ path26.dirname(profile.instructions)
23421
23455
  );
23422
23456
  }
23423
23457
  }
@@ -23440,20 +23474,20 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23440
23474
  if (selectedTools.has("copilot")) {
23441
23475
  addCompiledGlobPlans(
23442
23476
  artifacts,
23443
- path25.join(copilotPaths.agents, "*.agent.md"),
23477
+ path26.join(copilotPaths.agents, "*.agent.md"),
23444
23478
  "copilot",
23445
23479
  "copilot agent residue"
23446
23480
  );
23447
23481
  addCompiledGlobPlans(
23448
23482
  artifacts,
23449
- path25.join(copilotPaths.prompts, "*.prompt.md"),
23483
+ path26.join(copilotPaths.prompts, "*.prompt.md"),
23450
23484
  "copilot",
23451
23485
  "copilot prompt residue"
23452
23486
  );
23453
23487
  for (const agentEntry of runtime.kitInfo.components.agents.declared) {
23454
23488
  artifacts.push({
23455
23489
  component: "copilot agent",
23456
- path: path25.join(copilotPaths.agents, `${agentEntry}.agent.md`),
23490
+ path: path26.join(copilotPaths.agents, `${agentEntry}.agent.md`),
23457
23491
  kind: "compiled",
23458
23492
  expectedTarget: "copilot",
23459
23493
  expectedSource: `agents/${agentEntry}.md`
@@ -23462,7 +23496,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23462
23496
  for (const commandEntry of runtime.kitInfo.components.commands.declared) {
23463
23497
  artifacts.push({
23464
23498
  component: "copilot prompt",
23465
- path: path25.join(copilotPaths.prompts, `${commandEntry}.prompt.md`),
23499
+ path: path26.join(copilotPaths.prompts, `${commandEntry}.prompt.md`),
23466
23500
  kind: "compiled",
23467
23501
  expectedTarget: "copilot",
23468
23502
  expectedSource: `commands/${commandEntry}.md`
@@ -23477,7 +23511,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23477
23511
  for (const skill of runtime.kitInfo.components.skills.declared) {
23478
23512
  artifacts.push({
23479
23513
  component: "copilot skill",
23480
- path: path25.join(copilotPaths.skills, skill),
23514
+ path: path26.join(copilotPaths.skills, skill),
23481
23515
  kind: "direct"
23482
23516
  });
23483
23517
  }
@@ -23491,13 +23525,13 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23491
23525
  artifacts.push(
23492
23526
  {
23493
23527
  component: "copilot hooks",
23494
- path: path25.join(copilotPaths.hooks, "tangyr-managed.json"),
23528
+ path: path26.join(copilotPaths.hooks, "tangyr-managed.json"),
23495
23529
  kind: "managed-json",
23496
23530
  expectedTarget: "copilot"
23497
23531
  },
23498
23532
  {
23499
23533
  component: "copilot legacy hooks",
23500
- path: path25.join(copilotPaths.hooks, "proteus-managed.json"),
23534
+ path: path26.join(copilotPaths.hooks, "proteus-managed.json"),
23501
23535
  kind: "managed-json",
23502
23536
  expectedTarget: "copilot"
23503
23537
  }
@@ -23506,7 +23540,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23506
23540
  if (hooksSourceExists(runtime.sourceRoot, runtime.config)) {
23507
23541
  artifacts.push({
23508
23542
  component: "copilot hooks",
23509
- path: path25.join(copilotPaths.hooks, "tangyr-managed.json"),
23543
+ path: path26.join(copilotPaths.hooks, "tangyr-managed.json"),
23510
23544
  kind: "compiled",
23511
23545
  expectedTarget: "copilot",
23512
23546
  expectedSource: hooksSource
@@ -23536,13 +23570,13 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23536
23570
  );
23537
23571
  addCompiledGlobPlans(
23538
23572
  artifacts,
23539
- path25.join(codexPaths.agents, "*.toml"),
23573
+ path26.join(codexPaths.agents, "*.toml"),
23540
23574
  "codex",
23541
23575
  "codex agent residue"
23542
23576
  );
23543
23577
  addCompiledGlobPlans(
23544
23578
  artifacts,
23545
- path25.join(codexPaths.rules, "*.rules"),
23579
+ path26.join(codexPaths.rules, "*.rules"),
23546
23580
  "codex",
23547
23581
  "codex rule residue"
23548
23582
  );
@@ -23556,7 +23590,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23556
23590
  for (const agentEntry of runtime.kitInfo.components.agents.declared) {
23557
23591
  artifacts.push({
23558
23592
  component: "codex agent",
23559
- path: path25.join(codexPaths.agents, `${agentEntry}.toml`),
23593
+ path: path26.join(codexPaths.agents, `${agentEntry}.toml`),
23560
23594
  kind: "compiled",
23561
23595
  expectedTarget: "codex",
23562
23596
  expectedSource: `agents/${agentEntry}.md`
@@ -23565,7 +23599,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23565
23599
  for (const ruleEntry of runtime.kitInfo.components.rules.declared) {
23566
23600
  artifacts.push({
23567
23601
  component: "codex rule",
23568
- path: path25.join(codexPaths.rules, `${ruleEntry}.rules`),
23602
+ path: path26.join(codexPaths.rules, `${ruleEntry}.rules`),
23569
23603
  kind: "compiled",
23570
23604
  expectedTarget: "codex",
23571
23605
  expectedSource: `rules/${ruleEntry}.md`
@@ -23617,13 +23651,13 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23617
23651
  );
23618
23652
  addCompiledGlobPlans(
23619
23653
  artifacts,
23620
- path25.join(opencodePaths.agents, "*.md"),
23654
+ path26.join(opencodePaths.agents, "*.md"),
23621
23655
  "opencode",
23622
23656
  "opencode agent residue"
23623
23657
  );
23624
23658
  addCompiledGlobPlans(
23625
23659
  artifacts,
23626
- path25.join(opencodePaths.commands, "*.md"),
23660
+ path26.join(opencodePaths.commands, "*.md"),
23627
23661
  "opencode",
23628
23662
  "opencode command residue"
23629
23663
  );
@@ -23642,7 +23676,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23642
23676
  for (const agentEntry of runtime.kitInfo.components.agents.declared) {
23643
23677
  artifacts.push({
23644
23678
  component: "opencode agent",
23645
- path: path25.join(opencodePaths.agents, `${agentEntry}.md`),
23679
+ path: path26.join(opencodePaths.agents, `${agentEntry}.md`),
23646
23680
  kind: "compiled",
23647
23681
  expectedTarget: "opencode",
23648
23682
  expectedSource: `agents/${agentEntry}.md`
@@ -23651,7 +23685,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23651
23685
  for (const commandEntry of runtime.kitInfo.components.commands.declared) {
23652
23686
  artifacts.push({
23653
23687
  component: "opencode command",
23654
- path: path25.join(opencodePaths.commands, `${commandEntry}.md`),
23688
+ path: path26.join(opencodePaths.commands, `${commandEntry}.md`),
23655
23689
  kind: "compiled",
23656
23690
  expectedTarget: "opencode",
23657
23691
  expectedSource: `commands/${commandEntry}.md`
@@ -23706,19 +23740,19 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23706
23740
  );
23707
23741
  addCompiledGlobPlans(
23708
23742
  artifacts,
23709
- path25.join(cursorPaths.agents, "*.md"),
23743
+ path26.join(cursorPaths.agents, "*.md"),
23710
23744
  "cursor",
23711
23745
  "cursor agent residue"
23712
23746
  );
23713
23747
  addCompiledGlobPlans(
23714
23748
  artifacts,
23715
- path25.join(cursorPaths.rules, "*.mdc"),
23749
+ path26.join(cursorPaths.rules, "*.mdc"),
23716
23750
  "cursor",
23717
23751
  "cursor rule residue"
23718
23752
  );
23719
23753
  addCompiledGlobPlans(
23720
23754
  artifacts,
23721
- path25.join(cursorPaths.skills, "*", "SKILL.md"),
23755
+ path26.join(cursorPaths.skills, "*", "SKILL.md"),
23722
23756
  "cursor",
23723
23757
  "cursor command residue"
23724
23758
  );
@@ -23732,7 +23766,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23732
23766
  for (const agentEntry of runtime.kitInfo.components.agents.declared) {
23733
23767
  artifacts.push({
23734
23768
  component: "cursor agent",
23735
- path: path25.join(cursorPaths.agents, `${agentEntry}.md`),
23769
+ path: path26.join(cursorPaths.agents, `${agentEntry}.md`),
23736
23770
  kind: "compiled",
23737
23771
  expectedTarget: "cursor",
23738
23772
  expectedSource: `agents/${agentEntry}.md`
@@ -23769,13 +23803,13 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23769
23803
  );
23770
23804
  addCompiledGlobPlans(
23771
23805
  artifacts,
23772
- path25.join(clinePaths.rules, "*.md"),
23806
+ path26.join(clinePaths.rules, "*.md"),
23773
23807
  "cline",
23774
23808
  "cline rule residue"
23775
23809
  );
23776
23810
  addCompiledGlobPlans(
23777
23811
  artifacts,
23778
- path25.join(clinePaths.workflows, "*.md"),
23812
+ path26.join(clinePaths.workflows, "*.md"),
23779
23813
  "cline",
23780
23814
  "cline workflow residue"
23781
23815
  );
@@ -23803,7 +23837,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23803
23837
  for (const ruleEntry of runtime.kitInfo.components.rules.declared) {
23804
23838
  artifacts.push({
23805
23839
  component: "cline rule",
23806
- path: path25.join(clinePaths.rules, `${ruleEntry}.md`),
23840
+ path: path26.join(clinePaths.rules, `${ruleEntry}.md`),
23807
23841
  kind: "compiled",
23808
23842
  expectedTarget: "cline",
23809
23843
  expectedSource: `rules/${ruleEntry}.md`
@@ -23812,7 +23846,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
23812
23846
  for (const commandEntry of runtime.kitInfo.components.commands.declared) {
23813
23847
  artifacts.push({
23814
23848
  component: "cline workflow",
23815
- path: path25.join(clinePaths.workflows, `${commandEntry}.md`),
23849
+ path: path26.join(clinePaths.workflows, `${commandEntry}.md`),
23816
23850
  kind: "compiled",
23817
23851
  expectedTarget: "cline",
23818
23852
  expectedSource: `commands/${commandEntry}.md`
@@ -24147,12 +24181,12 @@ function resolveCopilotPaths(runtime, scope = "global", projectRoot) {
24147
24181
  if (scope === "project") {
24148
24182
  const root = projectRoot ?? process.cwd();
24149
24183
  return {
24150
- instructions: path25.join(root, ".github", "copilot-instructions.md"),
24151
- agents: path25.join(root, ".github", "agents"),
24152
- prompts: path25.join(root, ".github", "prompts"),
24153
- skills: path25.join(root, ".github", "skills"),
24154
- hooks: path25.join(root, ".github", "hooks"),
24155
- mcpSharedFile: path25.join(root, ".vscode", "mcp.json")
24184
+ instructions: path26.join(root, ".github", "copilot-instructions.md"),
24185
+ agents: path26.join(root, ".github", "agents"),
24186
+ prompts: path26.join(root, ".github", "prompts"),
24187
+ skills: path26.join(root, ".github", "skills"),
24188
+ hooks: path26.join(root, ".github", "hooks"),
24189
+ mcpSharedFile: path26.join(root, ".vscode", "mcp.json")
24156
24190
  };
24157
24191
  }
24158
24192
  return {
@@ -24192,12 +24226,12 @@ function resolveCodexPaths(runtime, scope = "global", projectRoot) {
24192
24226
  if (scope === "project") {
24193
24227
  const root = projectRoot ?? process.cwd();
24194
24228
  return {
24195
- instructions: path25.join(root, "AGENTS.md"),
24196
- agents: path25.join(root, ".codex", "agents"),
24197
- rules: path25.join(root, ".codex", "rules"),
24198
- skills: path25.join(root, ".codex", "skills"),
24199
- hooksSharedFile: path25.join(root, ".codex", "hooks.json"),
24200
- mcpSharedFile: path25.join(root, ".codex", "config.toml")
24229
+ instructions: path26.join(root, "AGENTS.md"),
24230
+ agents: path26.join(root, ".codex", "agents"),
24231
+ rules: path26.join(root, ".codex", "rules"),
24232
+ skills: path26.join(root, ".codex", "skills"),
24233
+ hooksSharedFile: path26.join(root, ".codex", "hooks.json"),
24234
+ mcpSharedFile: path26.join(root, ".codex", "config.toml")
24201
24235
  };
24202
24236
  }
24203
24237
  return {
@@ -24226,7 +24260,7 @@ function resolveSharedHookScriptsPath(runtime, scope, projectRoot) {
24226
24260
  }
24227
24261
  }
24228
24262
  if (scope === "project") {
24229
- return path25.join(projectRoot ?? process.cwd(), ".agents", "hooks");
24263
+ return path26.join(projectRoot ?? process.cwd(), ".agents", "hooks");
24230
24264
  }
24231
24265
  return resolveTargetPath("~/.agents/hooks");
24232
24266
  }
@@ -24247,7 +24281,7 @@ function resolveSharedSkillsPath(runtime, scope, projectRoot) {
24247
24281
  }
24248
24282
  }
24249
24283
  if (scope === "project") {
24250
- return path25.join(projectRoot ?? process.cwd(), ".agents", "skills");
24284
+ return path26.join(projectRoot ?? process.cwd(), ".agents", "skills");
24251
24285
  }
24252
24286
  return resolveTargetPath("~/.agents/skills");
24253
24287
  }
@@ -24432,7 +24466,7 @@ function isKitPointer(artifact) {
24432
24466
  }
24433
24467
  try {
24434
24468
  const recordedPath = fs28.readFileSync(artifact.path, "utf8").trim();
24435
- return recordedPath.length > 0 && path25.resolve(recordedPath) === path25.resolve(artifact.expectedPath);
24469
+ return recordedPath.length > 0 && path26.resolve(recordedPath) === path26.resolve(artifact.expectedPath);
24436
24470
  } catch {
24437
24471
  return false;
24438
24472
  }
@@ -24597,7 +24631,7 @@ function restoreBackup(backup, logger) {
24597
24631
  logger.warn(` backup not found: ${backup.backupLocation}`);
24598
24632
  return;
24599
24633
  }
24600
- const destDir = path25.dirname(backup.originalPath);
24634
+ const destDir = path26.dirname(backup.originalPath);
24601
24635
  fs28.mkdirSync(destDir, { recursive: true });
24602
24636
  if (fs28.lstatSync(backup.backupLocation).isDirectory()) {
24603
24637
  fs28.cpSync(backup.backupLocation, backup.originalPath, {
@@ -24759,7 +24793,7 @@ function cleanupCopilot(config, sourceRoot, configDir, logger) {
24759
24793
  logger
24760
24794
  );
24761
24795
  removeManagedJsonFile(
24762
- path26.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
24796
+ path27.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
24763
24797
  "_tangyr",
24764
24798
  logger
24765
24799
  );
@@ -24921,7 +24955,7 @@ function removeManagedDirectPath(artifactPath, config, sourceRoot, component, lo
24921
24955
  }
24922
24956
  }
24923
24957
  function removeManagedCompiledFiles(dir, pattern, expectedTarget, logger) {
24924
- for (const filePath of ts(path26.join(dir, pattern)).sort()) {
24958
+ for (const filePath of ts(path27.join(dir, pattern)).sort()) {
24925
24959
  removeManagedCompiledFile(filePath, expectedTarget, logger);
24926
24960
  }
24927
24961
  }
@@ -25032,7 +25066,7 @@ function toVerbosity(value) {
25032
25066
  // src/commands/detect.ts
25033
25067
  import fs30 from "fs";
25034
25068
  import os5 from "os";
25035
- import path27 from "path";
25069
+ import path28 from "path";
25036
25070
  import { spawnSync } from "child_process";
25037
25071
  var copilotEditorCommands = [
25038
25072
  "code",
@@ -25164,7 +25198,7 @@ function detectEditorExtension(label, matchesExtension, logger, dependencies = {
25164
25198
  }
25165
25199
  }
25166
25200
  for (const relativeDirectory of copilotExtensionDirectories) {
25167
- const extensionDirectory = path27.join(homeDirectory, relativeDirectory);
25201
+ const extensionDirectory = path28.join(homeDirectory, relativeDirectory);
25168
25202
  if (!pathExists(extensionDirectory)) {
25169
25203
  continue;
25170
25204
  }
@@ -25187,7 +25221,7 @@ function cursorExecutablePaths(platform, homeDirectory) {
25187
25221
  }
25188
25222
  return [
25189
25223
  ...systemPaths,
25190
- path27.join(
25224
+ path28.join(
25191
25225
  homeDirectory,
25192
25226
  "Applications/Cursor.app/Contents/Resources/app/bin/cursor"
25193
25227
  )
@@ -25248,7 +25282,7 @@ function logDetectionError(attemptedCommand, error, logger) {
25248
25282
 
25249
25283
  // src/commands/doctor.ts
25250
25284
  import fs31 from "fs";
25251
- import path28 from "path";
25285
+ import path29 from "path";
25252
25286
  function runDoctorCommand(options, logger) {
25253
25287
  const { config, configDir, configPath, sourceRoot } = resolveRuntime(
25254
25288
  options,
@@ -25258,7 +25292,7 @@ function runDoctorCommand(options, logger) {
25258
25292
  if (!fs31.existsSync(configPath)) {
25259
25293
  findings.push(`${configPath}: missing`);
25260
25294
  }
25261
- const hooksJsonPath = path28.join(
25295
+ const hooksJsonPath = path29.join(
25262
25296
  sourceRoot,
25263
25297
  config.source.hooks,
25264
25298
  "hooks.json"
@@ -25334,18 +25368,18 @@ function checkClaudeCode(options, findings, config, sourceRoot, configDir, logge
25334
25368
  projectRoot
25335
25369
  )) {
25336
25370
  const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
25337
- const sourcePath = artifact.sourceKey ? path28.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
25371
+ const sourcePath = artifact.sourceKey ? path29.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
25338
25372
  if (artifactClass === "managed-stale") {
25339
25373
  findings.push(
25340
25374
  `${artifact.component}: managed stale artifact at ${artifact.path}`
25341
25375
  );
25342
25376
  if (options.fix && sourcePath && isOurStaleSymlink(
25343
25377
  artifact.path,
25344
- /* @__PURE__ */ new Set([path28.resolve(artifact.path)]),
25378
+ /* @__PURE__ */ new Set([path29.resolve(artifact.path)]),
25345
25379
  config
25346
25380
  )) {
25347
25381
  fs31.unlinkSync(artifact.path);
25348
- ensureDir(path28.dirname(artifact.path));
25382
+ ensureDir(path29.dirname(artifact.path));
25349
25383
  const symlinkType = fs31.statSync(sourcePath).isDirectory() ? "dir" : "file";
25350
25384
  createRelativeSymlink(sourcePath, artifact.path, symlinkType, {
25351
25385
  logger,
@@ -25359,13 +25393,13 @@ function checkClaudeCode(options, findings, config, sourceRoot, configDir, logge
25359
25393
  logger.info(`${artifact.component}: recreated managed symlink`);
25360
25394
  }
25361
25395
  }
25362
- if (options.fix && !fs31.existsSync(path28.dirname(artifact.path))) {
25363
- ensureDir(path28.dirname(artifact.path));
25396
+ if (options.fix && !fs31.existsSync(path29.dirname(artifact.path))) {
25397
+ ensureDir(path29.dirname(artifact.path));
25364
25398
  }
25365
25399
  checkParentWritablePath(artifact.path, artifact.component, findings);
25366
25400
  }
25367
25401
  }
25368
- function slotsForScope(config, sourceRoot, configDir, target, options) {
25402
+ function slotsForScope2(config, sourceRoot, configDir, target, options) {
25369
25403
  const scopeMap = loadMappings(sourceRoot, config, configDir).platformPaths.targets[target];
25370
25404
  const scope = options.scope ?? config.scope ?? "global";
25371
25405
  if (scope !== "project") {
@@ -25382,12 +25416,12 @@ function slotsForScope(config, sourceRoot, configDir, target, options) {
25382
25416
  });
25383
25417
  const resolved = {};
25384
25418
  for (const [slot, value] of Object.entries(projectSlots)) {
25385
- resolved[slot] = typeof value === "string" ? path28.resolve(root, value) : value;
25419
+ resolved[slot] = typeof value === "string" ? path29.resolve(root, value) : value;
25386
25420
  }
25387
25421
  return resolved;
25388
25422
  }
25389
25423
  function checkCopilot(config, sourceRoot, configDir, findings, options) {
25390
- const globalPaths = slotsForScope(
25424
+ const globalPaths = slotsForScope2(
25391
25425
  config,
25392
25426
  sourceRoot,
25393
25427
  configDir,
@@ -25402,7 +25436,7 @@ function checkCopilot(config, sourceRoot, configDir, findings, options) {
25402
25436
  continue;
25403
25437
  }
25404
25438
  const label = `copilot: ${rawPath}`;
25405
- if (key.endsWith("_shared_file") || path28.extname(rawPath).length > 0) {
25439
+ if (key.endsWith("_shared_file") || path29.extname(rawPath).length > 0) {
25406
25440
  checkParentWritablePath(resolveTargetPath(rawPath), label, findings);
25407
25441
  continue;
25408
25442
  }
@@ -25410,7 +25444,7 @@ function checkCopilot(config, sourceRoot, configDir, findings, options) {
25410
25444
  }
25411
25445
  }
25412
25446
  function checkCodex(config, sourceRoot, configDir, findings, logger, options) {
25413
- const globalPaths = slotsForScope(
25447
+ const globalPaths = slotsForScope2(
25414
25448
  config,
25415
25449
  sourceRoot,
25416
25450
  configDir,
@@ -25428,7 +25462,7 @@ function checkCodex(config, sourceRoot, configDir, findings, logger, options) {
25428
25462
  continue;
25429
25463
  }
25430
25464
  const label = `codex: ${rawPath}`;
25431
- if (key.endsWith("_shared_file") || path28.extname(rawPath).length > 0) {
25465
+ if (key.endsWith("_shared_file") || path29.extname(rawPath).length > 0) {
25432
25466
  checkParentWritablePath(resolveTargetPath(rawPath), label, findings);
25433
25467
  continue;
25434
25468
  }
@@ -25445,13 +25479,13 @@ function resolveHooksScriptPath(config, sourceRoot, configDir) {
25445
25479
  scope: "global",
25446
25480
  mappings: mappings.platformPaths
25447
25481
  });
25448
- return path28.join(profile["claude-code"].hooks, "scripts");
25482
+ return path29.join(profile["claude-code"].hooks, "scripts");
25449
25483
  } catch {
25450
25484
  return resolveTargetPath("~/.agents/hooks/scripts");
25451
25485
  }
25452
25486
  }
25453
25487
  function checkParentWritablePath(targetPath, label, findings) {
25454
- checkWritablePath(path28.dirname(targetPath), `${label} parent`, findings);
25488
+ checkWritablePath(path29.dirname(targetPath), `${label} parent`, findings);
25455
25489
  }
25456
25490
  function checkWritablePath(checkPath, label, findings) {
25457
25491
  if (!fs31.existsSync(checkPath)) {
@@ -25468,7 +25502,7 @@ function walkHookScripts(dir) {
25468
25502
  if (!fs31.existsSync(dir)) {
25469
25503
  return [];
25470
25504
  }
25471
- return fs31.readdirSync(dir).map((entry) => path28.join(dir, entry)).filter((entryPath) => fs31.statSync(entryPath).isFile());
25505
+ return fs31.readdirSync(dir).map((entry) => path29.join(dir, entry)).filter((entryPath) => fs31.statSync(entryPath).isFile());
25472
25506
  }
25473
25507
  function fixManagedHookScriptModes(scriptRoot, sourceRoot, logger) {
25474
25508
  if (!fs31.existsSync(scriptRoot)) {
@@ -25485,16 +25519,16 @@ function fixManagedHookScriptModes(scriptRoot, sourceRoot, logger) {
25485
25519
  }
25486
25520
  }
25487
25521
  function hasSymlinkAncestor(targetPath, stopAt) {
25488
- const relative = path28.relative(
25489
- path28.resolve(stopAt),
25490
- path28.resolve(targetPath)
25522
+ const relative = path29.relative(
25523
+ path29.resolve(stopAt),
25524
+ path29.resolve(targetPath)
25491
25525
  );
25492
- if (relative.startsWith("..") || path28.isAbsolute(relative)) {
25526
+ if (relative.startsWith("..") || path29.isAbsolute(relative)) {
25493
25527
  return false;
25494
25528
  }
25495
- return relative.split(path28.sep).some((_segment, index, segments) => {
25496
- const candidate = path28.join(
25497
- path28.resolve(stopAt),
25529
+ return relative.split(path29.sep).some((_segment, index, segments) => {
25530
+ const candidate = path29.join(
25531
+ path29.resolve(stopAt),
25498
25532
  ...segments.slice(0, index + 1)
25499
25533
  );
25500
25534
  try {
@@ -25505,8 +25539,8 @@ function hasSymlinkAncestor(targetPath, stopAt) {
25505
25539
  });
25506
25540
  }
25507
25541
  function isInside(childPath, parentPath) {
25508
- const relative = path28.relative(parentPath, childPath);
25509
- return relative.length === 0 || !relative.startsWith("..") && !path28.isAbsolute(relative);
25542
+ const relative = path29.relative(parentPath, childPath);
25543
+ return relative.length === 0 || !relative.startsWith("..") && !path29.isAbsolute(relative);
25510
25544
  }
25511
25545
  function realPathOrInput2(filePath) {
25512
25546
  try {
@@ -25518,12 +25552,12 @@ function realPathOrInput2(filePath) {
25518
25552
 
25519
25553
  // src/commands/init.ts
25520
25554
  import fs32 from "fs";
25521
- import path29 from "path";
25555
+ import path30 from "path";
25522
25556
  var import_yaml7 = __toESM(require_dist(), 1);
25523
25557
  async function runInitCommand(_options, logger) {
25524
25558
  const sourceRoot = await dist_default6({
25525
25559
  message: "Canonical Tangyr kit root",
25526
- default: path29.resolve("projects/tangyr/agent-coding")
25560
+ default: path30.resolve("projects/tangyr/agent-coding")
25527
25561
  });
25528
25562
  const componentCount = [
25529
25563
  "CLAUDE.md",
@@ -25533,7 +25567,7 @@ async function runInitCommand(_options, logger) {
25533
25567
  "rules",
25534
25568
  "hooks"
25535
25569
  ].filter(
25536
- (relativePath) => fs32.existsSync(path29.join(sourceRoot, relativePath))
25570
+ (relativePath) => fs32.existsSync(path30.join(sourceRoot, relativePath))
25537
25571
  ).length;
25538
25572
  const detectedTargets = detectTargets(logger);
25539
25573
  const enabledTargets = await dist_default4({
@@ -25553,7 +25587,7 @@ async function runInitCommand(_options, logger) {
25553
25587
  value
25554
25588
  }))
25555
25589
  });
25556
- const configPath = path29.join(sourceRoot, "tangyr.config.yaml");
25590
+ const configPath = path30.join(sourceRoot, "tangyr.config.yaml");
25557
25591
  if (fs32.existsSync(configPath)) {
25558
25592
  const overwrite = await dist_default5({
25559
25593
  message: `${configPath} exists. Overwrite?`,
@@ -25608,14 +25642,14 @@ function toConflictPolicy2(value) {
25608
25642
 
25609
25643
  // src/commands/install.ts
25610
25644
  import fs47 from "fs";
25611
- import path47 from "path";
25645
+ import path48 from "path";
25612
25646
 
25613
25647
  // src/core/channel-state.ts
25614
25648
  import fs33 from "fs";
25615
- import path30 from "path";
25649
+ import path31 from "path";
25616
25650
  var CHANNEL_STATE_FILENAME = ".tangyr-channels.json";
25617
25651
  function stateFilePath(cacheRoot) {
25618
- return path30.join(cacheRoot, CHANNEL_STATE_FILENAME);
25652
+ return path31.join(cacheRoot, CHANNEL_STATE_FILENAME);
25619
25653
  }
25620
25654
  function channelKey(kit, channel) {
25621
25655
  return `${kit}/${channel}`;
@@ -25671,7 +25705,7 @@ function writeChannelSequence(params) {
25671
25705
  [key]: { sequence, version, seenAt: now.toISOString() }
25672
25706
  };
25673
25707
  const filePath = stateFilePath(cacheRoot);
25674
- fs33.mkdirSync(path30.dirname(filePath), { recursive: true, mode: 448 });
25708
+ fs33.mkdirSync(path31.dirname(filePath), { recursive: true, mode: 448 });
25675
25709
  const tempPath = `${filePath}.${process.pid}.tmp`;
25676
25710
  fs33.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
25677
25711
  `, {
@@ -25694,7 +25728,7 @@ var DEFAULT_CHANNEL = "stable";
25694
25728
 
25695
25729
  // src/core/materialize.ts
25696
25730
  import fs34 from "fs";
25697
- import path31 from "path";
25731
+ import path32 from "path";
25698
25732
 
25699
25733
  // src/core/integrity.ts
25700
25734
  import crypto3 from "crypto";
@@ -26030,7 +26064,7 @@ function assertFileWithinCeiling(entryPath, byteLength) {
26030
26064
  }
26031
26065
  var WINDOWS_DRIVE_ABSOLUTE = /^[a-zA-Z]:[\\/]/u;
26032
26066
  function sanitizeBundleFilePath(entryPath, stagingDir) {
26033
- if (path31.isAbsolute(entryPath) || WINDOWS_DRIVE_ABSOLUTE.test(entryPath)) {
26067
+ if (path32.isAbsolute(entryPath) || WINDOWS_DRIVE_ABSOLUTE.test(entryPath)) {
26034
26068
  throw new IntegrityError(
26035
26069
  `Bundle file path "${entryPath}" is absolute \u2014 every file inside a bundle must use a relative path (REQ-INT-004).`
26036
26070
  );
@@ -26046,13 +26080,13 @@ function sanitizeBundleFilePath(entryPath, stagingDir) {
26046
26080
  `Bundle file path "${entryPath}" contains a ".." segment \u2014 directory traversal is rejected (REQ-INT-004).`
26047
26081
  );
26048
26082
  }
26049
- const resolved = path31.resolve(stagingDir, entryPath);
26083
+ const resolved = path32.resolve(stagingDir, entryPath);
26050
26084
  if (resolved === stagingDir) {
26051
26085
  throw new IntegrityError(
26052
26086
  `Bundle file path "${entryPath}" resolves to the staging directory itself \u2014 every entry must be a file inside it (REQ-INT-004).`
26053
26087
  );
26054
26088
  }
26055
- if (!resolved.startsWith(stagingDir + path31.sep)) {
26089
+ if (!resolved.startsWith(stagingDir + path32.sep)) {
26056
26090
  throw new IntegrityError(
26057
26091
  `Bundle file path "${entryPath}" escapes the staging directory \u2014 refusing to write (REQ-INT-004).`
26058
26092
  );
@@ -26104,7 +26138,7 @@ function verifyBundleFileHashes(bundle) {
26104
26138
  function writeStagedFiles(stagingDir, decoded) {
26105
26139
  for (const [rawPath, bytes] of decoded) {
26106
26140
  const target = sanitizeBundleFilePath(rawPath, stagingDir);
26107
- fs34.mkdirSync(path31.dirname(target), { recursive: true, mode: 448 });
26141
+ fs34.mkdirSync(path32.dirname(target), { recursive: true, mode: 448 });
26108
26142
  let existingStat;
26109
26143
  try {
26110
26144
  existingStat = fs34.lstatSync(target);
@@ -26516,7 +26550,7 @@ function sleep(ms2) {
26516
26550
 
26517
26551
  // src/core/contested-instructions.ts
26518
26552
  import fs35 from "fs";
26519
- import path32 from "path";
26553
+ import path33 from "path";
26520
26554
  var FOLDS_RULES_INTO_INSTRUCTIONS = {
26521
26555
  codex: "its own rules slot takes only exec-policy rules, so guidance rules are folded in",
26522
26556
  opencode: "it has no rules slot of its own, so every rule is folded in"
@@ -26535,7 +26569,7 @@ function markerTarget(destination) {
26535
26569
  function findContestedInstructions(instructionsByTarget) {
26536
26570
  const byPath = /* @__PURE__ */ new Map();
26537
26571
  for (const [target, destination] of instructionsByTarget) {
26538
- const resolved = path32.resolve(destination);
26572
+ const resolved = path33.resolve(destination);
26539
26573
  byPath.set(resolved, [...byPath.get(resolved) ?? [], target]);
26540
26574
  }
26541
26575
  const contested = [];
@@ -26597,14 +26631,14 @@ function instructionsByActiveTarget(tools, scope, projectRoot, mappings) {
26597
26631
  }
26598
26632
  }
26599
26633
  if (scope === "project" && projectRoot && tools.includes("copilot")) {
26600
- byTarget.set("copilot", path32.join(projectRoot, "AGENTS.md"));
26634
+ byTarget.set("copilot", path33.join(projectRoot, "AGENTS.md"));
26601
26635
  }
26602
26636
  return byTarget;
26603
26637
  }
26604
26638
 
26605
26639
  // src/core/kit-coverage.ts
26606
26640
  import fs36 from "fs";
26607
- import path33 from "path";
26641
+ import path34 from "path";
26608
26642
  var COVERED_CATEGORIES = [
26609
26643
  "agents",
26610
26644
  "commands",
@@ -26682,7 +26716,7 @@ function inSlot(slotPath, name) {
26682
26716
  return true;
26683
26717
  }
26684
26718
  return entries.some((entry) => {
26685
- const full = path33.join(slotPath, entry);
26719
+ const full = path34.join(slotPath, entry);
26686
26720
  try {
26687
26721
  if (!fs36.statSync(full).isFile()) {
26688
26722
  return false;
@@ -26763,7 +26797,7 @@ function explain(target, category, surfaces, hasSurface, contestedByPath, lossRe
26763
26797
  return `${target} has no ${category} surface in this scope`;
26764
26798
  }
26765
26799
  if (FOLDS_INTO_INSTRUCTIONS.has(category) && surfaces.instructions) {
26766
- const contested = contestedByPath.get(path33.resolve(surfaces.instructions));
26800
+ const contested = contestedByPath.get(path34.resolve(surfaces.instructions));
26767
26801
  if (contested && contested.survivor !== null && contested.survivor !== target) {
26768
26802
  return `folded into ${display(surfaces.instructions, projectRoot)}, which ${contested.survivor} wrote last`;
26769
26803
  }
@@ -26779,7 +26813,7 @@ function display(target, projectRoot) {
26779
26813
  if (!projectRoot) {
26780
26814
  return target;
26781
26815
  }
26782
- const relative = path33.relative(projectRoot, target);
26816
+ const relative = path34.relative(projectRoot, target);
26783
26817
  return relative.startsWith("..") ? target : relative;
26784
26818
  }
26785
26819
  function reportKitCoverage(coverage, logger) {
@@ -26857,7 +26891,7 @@ function declaredComponents(kit) {
26857
26891
 
26858
26892
  // src/adapters/claude-code.ts
26859
26893
  import fs39 from "fs";
26860
- import path37 from "path";
26894
+ import path38 from "path";
26861
26895
 
26862
26896
  // src/core/shim.ts
26863
26897
  import crypto4 from "crypto";
@@ -26880,7 +26914,7 @@ ${SHIM_BODY}`;
26880
26914
 
26881
26915
  // src/core/skills-slot.ts
26882
26916
  import fs37 from "fs";
26883
- import path34 from "path";
26917
+ import path35 from "path";
26884
26918
  function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
26885
26919
  if (!isSymlinkPath(destination)) {
26886
26920
  return false;
@@ -26921,7 +26955,7 @@ function syncSkillsSlot(sync) {
26921
26955
  if (isLegacyWholesaleSymlink) {
26922
26956
  for (const name of foreignSkillNames(source, declaredNames)) {
26923
26957
  logger.info(
26924
- `[dry-run] skills: migrate foreign skill ${path34.join(source, name)} -> ${path34.join(destination, name)}`
26958
+ `[dry-run] skills: migrate foreign skill ${path35.join(source, name)} -> ${path35.join(destination, name)}`
26925
26959
  );
26926
26960
  }
26927
26961
  logger.info(
@@ -26929,9 +26963,9 @@ function syncSkillsSlot(sync) {
26929
26963
  );
26930
26964
  }
26931
26965
  for (const name of declaredNames ?? listSkillDirNames(source)) {
26932
- const skillDestination = path34.join(destination, name);
26966
+ const skillDestination = path35.join(destination, name);
26933
26967
  logger.info(
26934
- `[dry-run] skills: symlink ${path34.join(source, name)} -> ${skillDestination}`
26968
+ `[dry-run] skills: symlink ${path35.join(source, name)} -> ${skillDestination}`
26935
26969
  );
26936
26970
  outcomes2.push({
26937
26971
  component: "skills",
@@ -26958,8 +26992,8 @@ function syncSkillsSlot(sync) {
26958
26992
  }
26959
26993
  function syncSingleSkill(sync, name) {
26960
26994
  const { config, sourceRoot, source, destination } = sync;
26961
- const skillSource = path34.join(source, name);
26962
- const skillDestination = path34.join(destination, name);
26995
+ const skillSource = path35.join(source, name);
26996
+ const skillDestination = path35.join(destination, name);
26963
26997
  if (!fs37.existsSync(skillSource)) {
26964
26998
  return {
26965
26999
  component: "skills",
@@ -26990,8 +27024,8 @@ function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logge
26990
27024
  fs37.unlinkSync(destination);
26991
27025
  ensureDir(destination);
26992
27026
  for (const name of foreignNames) {
26993
- const from = path34.join(source, name);
26994
- const to = path34.join(destination, name);
27027
+ const from = path35.join(source, name);
27028
+ const to = path35.join(destination, name);
26995
27029
  if (fs37.existsSync(to)) {
26996
27030
  logger.warn(
26997
27031
  `skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
@@ -27033,23 +27067,23 @@ function isSymlinkTo2(linkPath, source) {
27033
27067
  }
27034
27068
 
27035
27069
  // src/core/hook-scripts.ts
27036
- import path35 from "path";
27070
+ import path36 from "path";
27037
27071
  function hookScriptsDir(bridge, target, projectRoot) {
27038
27072
  const globalBridge = resolveTargetPath("~/.agents/hooks");
27039
- if (path35.resolve(bridge) === path35.resolve(globalBridge)) {
27073
+ if (path36.resolve(bridge) === path36.resolve(globalBridge)) {
27040
27074
  return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
27041
27075
  }
27042
- const relative = path35.relative(projectRoot ?? process.cwd(), bridge);
27043
- const insideProject = !relative.startsWith("..") && !path35.isAbsolute(relative) && relative !== "";
27076
+ const relative = path36.relative(projectRoot ?? process.cwd(), bridge);
27077
+ const insideProject = !relative.startsWith("..") && !path36.isAbsolute(relative) && relative !== "";
27044
27078
  const variable = PROJECT_DIR_VARIABLE[target];
27045
27079
  if (insideProject && variable) {
27046
- const posix = path35.posix.join(
27047
- relative.split(path35.sep).join("/"),
27080
+ const posix = path36.posix.join(
27081
+ relative.split(path36.sep).join("/"),
27048
27082
  "scripts"
27049
27083
  );
27050
27084
  return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
27051
27085
  }
27052
- return { prefix: path35.join(bridge, "scripts"), machineLocal: true };
27086
+ return { prefix: path36.join(bridge, "scripts"), machineLocal: true };
27053
27087
  }
27054
27088
  var PROJECT_DIR_VARIABLE = {
27055
27089
  "claude-code": "$CLAUDE_PROJECT_DIR"
@@ -27060,18 +27094,18 @@ function machineLocalScriptPathNotice(target, prefix) {
27060
27094
 
27061
27095
  // src/core/instructions-source.ts
27062
27096
  import fs38 from "fs";
27063
- import path36 from "path";
27097
+ import path37 from "path";
27064
27098
  var PORTABLE_INSTRUCTIONS_NAME = "AGENTS.md";
27065
27099
  var InstructionsSourceMissingError = class extends Error {
27066
27100
  constructor(kitRoot, expected, declaredBy) {
27067
27101
  super(
27068
- `${path36.join(kitRoot, expected)}: instructions source not found (declared by ${declaredBy}). To fix: create that file, or point '${declaredBy}' at the file this kit actually carries. With neither declaration, the kit's ${DEFAULT_ENTRYPOINT} or ${PORTABLE_INSTRUCTIONS_NAME} is used.`
27102
+ `${path37.join(kitRoot, expected)}: instructions source not found (declared by ${declaredBy}). To fix: create that file, or point '${declaredBy}' at the file this kit actually carries. With neither declaration, the kit's ${DEFAULT_ENTRYPOINT} or ${PORTABLE_INSTRUCTIONS_NAME} is used.`
27069
27103
  );
27070
27104
  this.name = "InstructionsSourceMissingError";
27071
27105
  }
27072
27106
  };
27073
27107
  function normalizeLabel(kitRoot, file) {
27074
- return path36.relative(kitRoot, file).split(path36.sep).join("/");
27108
+ return path37.relative(kitRoot, file).split(path37.sep).join("/");
27075
27109
  }
27076
27110
  function isExplicitOverride(configured) {
27077
27111
  const normalize = (value) => value.replace(/\\/gu, "/").replace(/^\.\//u, "");
@@ -27080,7 +27114,7 @@ function isExplicitOverride(configured) {
27080
27114
  function resolveInstructionsSource(kitRoot, config) {
27081
27115
  const configured = config.source.instructions;
27082
27116
  if (isExplicitOverride(configured)) {
27083
- const file = path36.resolve(kitRoot, configured);
27117
+ const file = path37.resolve(kitRoot, configured);
27084
27118
  if (!fs38.existsSync(file)) {
27085
27119
  throw new InstructionsSourceMissingError(
27086
27120
  kitRoot,
@@ -27096,7 +27130,7 @@ function resolveInstructionsSource(kitRoot, config) {
27096
27130
  }
27097
27131
  const declared = resolveKitEntrypointName(kitRoot);
27098
27132
  if (declared !== void 0) {
27099
- const file = path36.resolve(kitRoot, declared);
27133
+ const file = path37.resolve(kitRoot, declared);
27100
27134
  if (!fs38.existsSync(file)) {
27101
27135
  throw new InstructionsSourceMissingError(
27102
27136
  kitRoot,
@@ -27111,12 +27145,12 @@ function resolveInstructionsSource(kitRoot, config) {
27111
27145
  };
27112
27146
  }
27113
27147
  for (const name of [DEFAULT_ENTRYPOINT, PORTABLE_INSTRUCTIONS_NAME]) {
27114
- const file = path36.resolve(kitRoot, name);
27148
+ const file = path37.resolve(kitRoot, name);
27115
27149
  if (fs38.existsSync(file)) {
27116
27150
  return { file, label: name, origin: "convention" };
27117
27151
  }
27118
27152
  }
27119
- const legacy = path36.resolve(kitRoot, LEGACY_ENTRYPOINT);
27153
+ const legacy = path37.resolve(kitRoot, LEGACY_ENTRYPOINT);
27120
27154
  if (fs38.existsSync(legacy)) {
27121
27155
  return {
27122
27156
  file: legacy,
@@ -27129,7 +27163,7 @@ function resolveInstructionsSource(kitRoot, config) {
27129
27163
  }
27130
27164
  function instructionsSourcePath(kitRoot, config) {
27131
27165
  const resolved = resolveInstructionsSource(kitRoot, config);
27132
- return resolved ? resolved.file : path36.resolve(kitRoot, config.source.instructions);
27166
+ return resolved ? resolved.file : path37.resolve(kitRoot, config.source.instructions);
27133
27167
  }
27134
27168
  function instructionsSourceLabel(kitRoot, config) {
27135
27169
  const resolved = resolveInstructionsSource(kitRoot, config);
@@ -27250,7 +27284,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
27250
27284
  if (!shouldSkipComponent(options, "hooks")) {
27251
27285
  outcomes.push(
27252
27286
  syncHookScriptsBridge({
27253
- source: path37.resolve(sourceRoot, config.source.hooks),
27287
+ source: path38.resolve(sourceRoot, config.source.hooks),
27254
27288
  destination: profile.hook_scripts,
27255
27289
  config,
27256
27290
  sourceRoot,
@@ -27311,13 +27345,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
27311
27345
  }
27312
27346
  function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
27313
27347
  if (!mappings.modelTiers.custom_provider) return;
27314
- const agentsDir = path37.join(sourceRoot, config.source.agents);
27348
+ const agentsDir = path38.join(sourceRoot, config.source.agents);
27315
27349
  if (!fs39.existsSync(agentsDir)) return;
27316
- for (const agentFile of ts(path37.join(agentsDir, "*.md")).sort()) {
27350
+ for (const agentFile of ts(path38.join(agentsDir, "*.md")).sort()) {
27317
27351
  const { data } = parseMarkdownFrontmatter(agentFile);
27318
27352
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
27319
27353
  if (hasProvider) {
27320
- const basename = path37.basename(agentFile);
27354
+ const basename = path38.basename(agentFile);
27321
27355
  addLoss(lossReport, "claude-code", "agents", {
27322
27356
  source: `agents/${basename}`,
27323
27357
  fields: [
@@ -27367,7 +27401,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
27367
27401
  origin: "tangyr-managed"
27368
27402
  });
27369
27403
  writeManifest(scopePath, manifest);
27370
- fs39.mkdirSync(path37.dirname(shimPath), { recursive: true });
27404
+ fs39.mkdirSync(path38.dirname(shimPath), { recursive: true });
27371
27405
  fs39.writeFileSync(shimPath, shimContent);
27372
27406
  logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
27373
27407
  return;
@@ -27399,7 +27433,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
27399
27433
  logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
27400
27434
  }
27401
27435
  function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
27402
- const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path37.resolve(sourceRoot, config.source[directComponent.sourceKey]);
27436
+ const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path38.resolve(sourceRoot, config.source[directComponent.sourceKey]);
27403
27437
  const sourceLabel = directComponent.sourceKey === "instructions" ? instructionsSourceLabel(sourceRoot, config) : config.source[directComponent.sourceKey];
27404
27438
  const destination = directComponent.destination;
27405
27439
  if (!fs39.existsSync(source)) {
@@ -27436,7 +27470,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
27436
27470
  } else if (artifactClass === "managed-compiled") {
27437
27471
  fs39.unlinkSync(destination);
27438
27472
  }
27439
- ensureDir(path37.dirname(destination));
27473
+ ensureDir(path38.dirname(destination));
27440
27474
  createRelativeSymlink(source, destination, directComponent.type, {
27441
27475
  logger,
27442
27476
  provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
@@ -27456,7 +27490,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
27456
27490
  return syncSkillsSlot({
27457
27491
  config,
27458
27492
  sourceRoot,
27459
- source: path37.resolve(sourceRoot, config.source.skills),
27493
+ source: path38.resolve(sourceRoot, config.source.skills),
27460
27494
  destination,
27461
27495
  dryRun: options.dryRun,
27462
27496
  logger,
@@ -27504,7 +27538,7 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
27504
27538
  };
27505
27539
  }
27506
27540
  function syncMcp(config, sourceRoot, options, logger, destination, manifest) {
27507
- const source = path37.resolve(sourceRoot, config.source.mcp);
27541
+ const source = path38.resolve(sourceRoot, config.source.mcp);
27508
27542
  if (!fs39.existsSync(source)) {
27509
27543
  return skippedMissingSource("mcp", source);
27510
27544
  }
@@ -27540,7 +27574,7 @@ function syncMcp(config, sourceRoot, options, logger, destination, manifest) {
27540
27574
  };
27541
27575
  }
27542
27576
  function syncSettings(config, sourceRoot, options, logger, destination, manifest) {
27543
- const source = path37.resolve(sourceRoot, config.source.settings);
27577
+ const source = path38.resolve(sourceRoot, config.source.settings);
27544
27578
  if (!fs39.existsSync(source)) {
27545
27579
  return skippedMissingSource("settings", source);
27546
27580
  }
@@ -27646,12 +27680,12 @@ function isRecord3(value) {
27646
27680
  var TOML3 = __toESM(require_toml(), 1);
27647
27681
  import crypto6 from "crypto";
27648
27682
  import fs42 from "fs";
27649
- import path41 from "path";
27683
+ import path42 from "path";
27650
27684
 
27651
27685
  // src/compiler/agents.ts
27652
27686
  var TOML = __toESM(require_toml(), 1);
27653
27687
  var import_yaml8 = __toESM(require_dist(), 1);
27654
- import path38 from "path";
27688
+ import path39 from "path";
27655
27689
  var writeCapabilityClasses = /* @__PURE__ */ new Set(["filesystem-write", "shell-execution"]);
27656
27690
  var copilotToolAliasesByClass = {
27657
27691
  delegation: "agent",
@@ -27663,7 +27697,7 @@ var copilotToolAliasesByClass = {
27663
27697
  };
27664
27698
  function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
27665
27699
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
27666
- const relativeSource = `agents/${path38.basename(sourceFile)}`;
27700
+ const relativeSource = `agents/${path39.basename(sourceFile)}`;
27667
27701
  if (target === "opencode") {
27668
27702
  return compileOpenCodeAgent(
27669
27703
  sourceFile,
@@ -27704,7 +27738,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
27704
27738
  mappings,
27705
27739
  lossReport
27706
27740
  );
27707
- const overlayKey = `agents/${path38.basename(sourceFile, ".md")}.${target}.yaml`;
27741
+ const overlayKey = `agents/${path39.basename(sourceFile, ".md")}.${target}.yaml`;
27708
27742
  const targetFields = {
27709
27743
  ...translated.fields,
27710
27744
  ...extensions[overlayKey] ?? {}
@@ -27738,7 +27772,7 @@ ${TOML.stringify({
27738
27772
  function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
27739
27773
  if (typeof data.description !== "string" || data.description.trim() === "") {
27740
27774
  throw new Error(
27741
- `${path38.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
27775
+ `${path39.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
27742
27776
  );
27743
27777
  }
27744
27778
  const frontmatter = {
@@ -27792,7 +27826,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
27792
27826
  "permission",
27793
27827
  "permission-coarsening"
27794
27828
  ),
27795
- detail: `${path38.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
27829
+ detail: `${path39.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
27796
27830
  }
27797
27831
  ]
27798
27832
  });
@@ -27817,7 +27851,7 @@ ${(0, import_yaml8.stringify)(frontmatter).trim()}
27817
27851
  function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
27818
27852
  if (typeof data.description !== "string" || data.description.trim() === "") {
27819
27853
  throw new Error(
27820
- `${path38.basename(sourceFile)}: Cursor agent requires a non-empty description field`
27854
+ `${path39.basename(sourceFile)}: Cursor agent requires a non-empty description field`
27821
27855
  );
27822
27856
  }
27823
27857
  const frontmatter = {
@@ -27854,7 +27888,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
27854
27888
  "permission",
27855
27889
  "permission-coarsening"
27856
27890
  ),
27857
- detail: `${path38.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
27891
+ detail: `${path39.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
27858
27892
  }
27859
27893
  ]
27860
27894
  });
@@ -27873,7 +27907,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
27873
27907
  "provider",
27874
27908
  "provider-not-representable"
27875
27909
  ),
27876
- detail: `${path38.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
27910
+ detail: `${path39.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
27877
27911
  }
27878
27912
  ]
27879
27913
  });
@@ -27905,7 +27939,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
27905
27939
  "persona",
27906
27940
  "persona-not-representable"
27907
27941
  ),
27908
- detail: `${path38.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
27942
+ detail: `${path39.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
27909
27943
  }
27910
27944
  ]
27911
27945
  });
@@ -27932,7 +27966,14 @@ function translateAgentFields(sourceFile, sourceFields, target, mappings, lossRe
27932
27966
  );
27933
27967
  }
27934
27968
  if (target === "codex") {
27935
- Object.assign(translated, deriveCodexSandbox(sourceFields.tools, mappings));
27969
+ const sandbox = deriveCodexSandbox(sourceFields.tools, mappings);
27970
+ Object.assign(translated, sandbox);
27971
+ recordCodexToolCoarsening(
27972
+ sourceFile,
27973
+ sourceFields.tools,
27974
+ sandbox.sandbox_mode,
27975
+ losses
27976
+ );
27936
27977
  const model = typeof sourceFields.model === "string" ? sourceFields.model : void 0;
27937
27978
  const tier = model ? mappings.modelTiers.tiers[model] : void 0;
27938
27979
  if (tier) {
@@ -27953,7 +27994,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27953
27994
  field,
27954
27995
  "model-not-representable"
27955
27996
  ),
27956
- detail: `${path38.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
27997
+ detail: `${path39.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
27957
27998
  });
27958
27999
  return;
27959
28000
  }
@@ -27971,9 +28012,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27971
28012
  lossReport,
27972
28013
  target,
27973
28014
  "agents",
27974
- `agents/${path38.basename(sourceFile)}`,
28015
+ `agents/${path39.basename(sourceFile)}`,
27975
28016
  "info",
27976
- `${path38.basename(sourceFile)}: ${field} is delivered through another managed surface.`
28017
+ `${path39.basename(sourceFile)}: ${field} is delivered through another managed surface.`
27977
28018
  );
27978
28019
  return;
27979
28020
  }
@@ -27982,7 +28023,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
27982
28023
  field,
27983
28024
  action: entryType,
27984
28025
  severity: resolveLossSeverity("agent-field", field, entryType),
27985
- detail: `${path38.basename(sourceFile)}: ${field} has no emitted field for this target.`
28026
+ detail: `${path39.basename(sourceFile)}: ${field} has no emitted field for this target.`
27986
28027
  });
27987
28028
  }
27988
28029
  function mapToolsToCapabilities(value, mappings) {
@@ -27995,6 +28036,27 @@ function mapToolsToCapabilities(value, mappings) {
27995
28036
  )
27996
28037
  ).sort();
27997
28038
  }
28039
+ function recordCodexToolCoarsening(sourceFile, tools, sandboxMode, losses) {
28040
+ const declared = normalizeToolList(tools);
28041
+ if (declared.length === 0) {
28042
+ return;
28043
+ }
28044
+ losses.push({
28045
+ field: "tools",
28046
+ action: "permission-coarsening",
28047
+ // `warning`, against the type's `error` default, and deliberately. The
28048
+ // default is set by the sites where a permission rule cannot be enforced at
28049
+ // all — a safety boundary that does not survive. Here the boundary does
28050
+ // survive, in a coarser form: the agent still runs under a posture, and no
28051
+ // manual step or kit change can make Codex hold a per-agent tool list.
28052
+ //
28053
+ // An error every kit with agents would hit on every run is an error nobody
28054
+ // reads, and the exit code it forces teaches `--ignore-errors`, which is
28055
+ // how the losses that ARE actionable get missed.
28056
+ severity: "warning",
28057
+ detail: `${path39.basename(sourceFile)}: Codex has no per-agent tool allow set \u2014 ${declared.join(", ")} becomes sandbox_mode = "${String(sandboxMode)}", so agents with different tool sets that share a posture become indistinguishable.`
28058
+ });
28059
+ }
27998
28060
  function deriveCodexSandbox(value, mappings) {
27999
28061
  const classes = new Set(
28000
28062
  normalizeToolList(value).map(
@@ -28413,12 +28475,12 @@ function addHookLoss(lossReport, target, eventName, sourceLabel, severity, reaso
28413
28475
  // src/compiler/command-as-skill.ts
28414
28476
  var import_yaml9 = __toESM(require_dist(), 1);
28415
28477
  import fs40 from "fs";
28416
- import path39 from "path";
28478
+ import path40 from "path";
28417
28479
  var CARRIED_OVER = ["argument-hint", "agent", "launch"];
28418
28480
  function compileCommandAsSkill(commandFile, target) {
28419
- const name = path39.basename(commandFile, ".md");
28481
+ const name = path40.basename(commandFile, ".md");
28420
28482
  const { data, body } = parseMarkdownFrontmatter(commandFile);
28421
- const relativeSource = `commands/${path39.basename(commandFile)}`;
28483
+ const relativeSource = `commands/${path40.basename(commandFile)}`;
28422
28484
  const description = typeof data.description === "string" && data.description.trim().length > 0 ? data.description.trim() : `The ${name} command.`;
28423
28485
  const frontmatter = { name, description };
28424
28486
  for (const key of CARRIED_OVER) {
@@ -28445,7 +28507,7 @@ function compileCommandsAsSkills(commandsRoot, target) {
28445
28507
  return [];
28446
28508
  }
28447
28509
  return fs40.readdirSync(commandsRoot).filter((entry) => entry.endsWith(".md")).sort().map(
28448
- (entry) => compileCommandAsSkill(path39.join(commandsRoot, entry), target)
28510
+ (entry) => compileCommandAsSkill(path40.join(commandsRoot, entry), target)
28449
28511
  );
28450
28512
  }
28451
28513
 
@@ -28728,7 +28790,7 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
28728
28790
  }
28729
28791
 
28730
28792
  // src/compiler/rules.ts
28731
- import path40 from "path";
28793
+ import path41 from "path";
28732
28794
  var import_yaml10 = __toESM(require_dist(), 1);
28733
28795
  import fs41 from "fs";
28734
28796
  function compileRules(sourceRulesDir, target, _mappings, lossReport) {
@@ -28749,13 +28811,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
28749
28811
  }
28750
28812
  const appendixParts = [];
28751
28813
  const dotRulesFiles = [];
28752
- for (const ruleFile of ts(path40.join(sourceRulesDir, "*.md")).sort()) {
28814
+ for (const ruleFile of ts(path41.join(sourceRulesDir, "*.md")).sort()) {
28753
28815
  const parsed = parseRule(ruleFile);
28754
- const name = path40.basename(ruleFile, ".md");
28816
+ const name = path41.basename(ruleFile, ".md");
28755
28817
  if (parsed.mode === "exec-policy") {
28756
28818
  dotRulesFiles.push({
28757
28819
  name: `${name}.rules`,
28758
- content: `${formatProvenanceMarker("toml", `rules/${path40.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
28820
+ content: `${formatProvenanceMarker("toml", `rules/${path41.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
28759
28821
  ${parsed.body}`
28760
28822
  });
28761
28823
  continue;
@@ -28764,7 +28826,7 @@ ${parsed.body}`
28764
28826
 
28765
28827
  ${parsed.body.trim()}`);
28766
28828
  addLoss(lossReport, "codex", "rules", {
28767
- source: `rules/${path40.basename(ruleFile)}`,
28829
+ source: `rules/${path41.basename(ruleFile)}`,
28768
28830
  fields: [
28769
28831
  {
28770
28832
  field: "mode",
@@ -28774,7 +28836,7 @@ ${parsed.body.trim()}`);
28774
28836
  "mode",
28775
28837
  "rule-as-instruction"
28776
28838
  ),
28777
- detail: `${path40.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
28839
+ detail: `${path41.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
28778
28840
  }
28779
28841
  ]
28780
28842
  });
@@ -28806,14 +28868,14 @@ function isRuleMode(value) {
28806
28868
  }
28807
28869
  function compileOpenCodeRules(sourceRulesDir, lossReport) {
28808
28870
  const appendixParts = [];
28809
- for (const ruleFile of ts(path40.join(sourceRulesDir, "*.md")).sort()) {
28871
+ for (const ruleFile of ts(path41.join(sourceRulesDir, "*.md")).sort()) {
28810
28872
  const parsed = parseRule(ruleFile);
28811
- const name = path40.basename(ruleFile, ".md");
28873
+ const name = path41.basename(ruleFile, ".md");
28812
28874
  appendixParts.push(`## ${name}
28813
28875
 
28814
28876
  ${parsed.body.trim()}`);
28815
28877
  addLoss(lossReport, "opencode", "rules", {
28816
- source: `rules/${path40.basename(ruleFile)}`,
28878
+ source: `rules/${path41.basename(ruleFile)}`,
28817
28879
  fields: [
28818
28880
  {
28819
28881
  field: "rule",
@@ -28823,7 +28885,7 @@ ${parsed.body.trim()}`);
28823
28885
  "rule",
28824
28886
  "rule-path-scoping"
28825
28887
  ),
28826
- detail: `${path40.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to its instructions file`
28888
+ detail: `${path41.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to its instructions file`
28827
28889
  }
28828
28890
  ]
28829
28891
  });
@@ -28832,9 +28894,9 @@ ${parsed.body.trim()}`);
28832
28894
  }
28833
28895
  function compileCursorRules(sourceRulesDir, _lossReport) {
28834
28896
  const dotRulesFiles = [];
28835
- for (const ruleFile of ts(path40.join(sourceRulesDir, "*.md")).sort()) {
28897
+ for (const ruleFile of ts(path41.join(sourceRulesDir, "*.md")).sort()) {
28836
28898
  const content = fs41.readFileSync(ruleFile, "utf8");
28837
- const name = path40.basename(ruleFile, ".md");
28899
+ const name = path41.basename(ruleFile, ".md");
28838
28900
  let frontmatterData = {};
28839
28901
  let body = content;
28840
28902
  if (content.startsWith("---\n")) {
@@ -28863,7 +28925,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
28863
28925
  }
28864
28926
  const marker = formatProvenanceMarker(
28865
28927
  "markdown",
28866
- `rules/${path40.basename(ruleFile)}`,
28928
+ `rules/${path41.basename(ruleFile)}`,
28867
28929
  computeSourceHash(ruleFile),
28868
28930
  "cursor"
28869
28931
  );
@@ -28879,9 +28941,9 @@ ${body}`;
28879
28941
  }
28880
28942
  function compileClineRules(sourceRulesDir, lossReport) {
28881
28943
  const dotRulesFiles = [];
28882
- for (const ruleFile of ts(path40.join(sourceRulesDir, "*.md")).sort()) {
28944
+ for (const ruleFile of ts(path41.join(sourceRulesDir, "*.md")).sort()) {
28883
28945
  const content = fs41.readFileSync(ruleFile, "utf8");
28884
- const name = path40.basename(ruleFile, ".md");
28946
+ const name = path41.basename(ruleFile, ".md");
28885
28947
  let frontmatterData = {};
28886
28948
  let body = content;
28887
28949
  if (content.startsWith("---\n")) {
@@ -28898,13 +28960,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
28898
28960
  }
28899
28961
  const marker = formatProvenanceMarker(
28900
28962
  "markdown",
28901
- `rules/${path40.basename(ruleFile)}`,
28963
+ `rules/${path41.basename(ruleFile)}`,
28902
28964
  computeSourceHash(ruleFile),
28903
28965
  "cline"
28904
28966
  );
28905
28967
  if (frontmatterData.mode === "exec-policy") {
28906
28968
  addLoss(lossReport, "cline", "rules", {
28907
- source: `rules/${path40.basename(ruleFile)}`,
28969
+ source: `rules/${path41.basename(ruleFile)}`,
28908
28970
  fields: [
28909
28971
  {
28910
28972
  field: "mode",
@@ -28914,7 +28976,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
28914
28976
  "mode",
28915
28977
  "rule-mode-downgrade"
28916
28978
  ),
28917
- detail: `${path40.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28979
+ detail: `${path41.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
28918
28980
  }
28919
28981
  ]
28920
28982
  });
@@ -28938,8 +29000,8 @@ function compileCopilotRules(sourceRulesDir) {
28938
29000
  return [];
28939
29001
  }
28940
29002
  const files = [];
28941
- for (const ruleFile of ts(path40.join(sourceRulesDir, "*.md")).sort()) {
28942
- const name = path40.basename(ruleFile, ".md");
29003
+ for (const ruleFile of ts(path41.join(sourceRulesDir, "*.md")).sort()) {
29004
+ const name = path41.basename(ruleFile, ".md");
28943
29005
  const { data } = parseMarkdownFrontmatter(ruleFile);
28944
29006
  const { body } = parseRule(ruleFile);
28945
29007
  const declared = data.paths;
@@ -28948,7 +29010,7 @@ function compileCopilotRules(sourceRulesDir) {
28948
29010
  "---",
28949
29011
  `applyTo: ${JSON.stringify(applyTo)}`,
28950
29012
  "x-tangyr:",
28951
- ` source: rules/${path40.basename(ruleFile)}`,
29013
+ ` source: rules/${path41.basename(ruleFile)}`,
28952
29014
  ` hash: ${computeSourceHash(ruleFile)}`,
28953
29015
  " target: copilot",
28954
29016
  "---"
@@ -28985,7 +29047,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
28985
29047
  rules: profile.rules
28986
29048
  };
28987
29049
  const rules = compileRules(
28988
- path41.join(sourceRoot, config.source.rules),
29050
+ path42.join(sourceRoot, config.source.rules),
28989
29051
  "codex",
28990
29052
  mappings,
28991
29053
  lossReport
@@ -29065,7 +29127,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
29065
29127
  if (!shouldSkipComponent2(options, "hooks")) {
29066
29128
  outcomes.push(
29067
29129
  syncHookScriptsBridge({
29068
- source: path41.resolve(sourceRoot, config.source.hooks),
29130
+ source: path42.resolve(sourceRoot, config.source.hooks),
29069
29131
  destination: resolveTargetPath(paths.hook_scripts),
29070
29132
  config,
29071
29133
  sourceRoot,
@@ -29166,9 +29228,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
29166
29228
  function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
29167
29229
  const cp = mappings.modelTiers.custom_provider;
29168
29230
  if (!cp) return "";
29169
- const agentsDir = path41.join(sourceRoot, config.source.agents);
29231
+ const agentsDir = path42.join(sourceRoot, config.source.agents);
29170
29232
  if (!fs42.existsSync(agentsDir)) return "";
29171
- const agentFiles = ts(path41.join(agentsDir, "*.md")).sort();
29233
+ const agentFiles = ts(path42.join(agentsDir, "*.md")).sort();
29172
29234
  const hasProviderAgent = agentFiles.some((agentFile) => {
29173
29235
  const { data } = parseMarkdownFrontmatter(agentFile);
29174
29236
  return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
@@ -29233,7 +29295,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
29233
29295
  }
29234
29296
  ];
29235
29297
  for (const ruleFile of rules.dotRulesFiles) {
29236
- const destination = path41.join(rulesRoot, ruleFile.name);
29298
+ const destination = path42.join(rulesRoot, ruleFile.name);
29237
29299
  if (options.dryRun) {
29238
29300
  logger.info(`[dry-run] rules: write ${destination}`);
29239
29301
  outcomes.push({
@@ -29272,7 +29334,7 @@ function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, lo
29272
29334
  ${agentsAppendix}`.trim();
29273
29335
  const marker = formatProvenanceMarker(
29274
29336
  "markdown",
29275
- path41.basename(instructionsSourceLabel(sourceRoot, config)),
29337
+ path42.basename(instructionsSourceLabel(sourceRoot, config)),
29276
29338
  hashString(composed),
29277
29339
  "codex"
29278
29340
  );
@@ -29302,7 +29364,7 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
29302
29364
  return syncSkillsSlot({
29303
29365
  config,
29304
29366
  sourceRoot,
29305
- source: path41.resolve(sourceRoot, config.source.skills),
29367
+ source: path42.resolve(sourceRoot, config.source.skills),
29306
29368
  destination: resolveTargetPath(paths.skills),
29307
29369
  dryRun: options.dryRun,
29308
29370
  logger,
@@ -29317,13 +29379,13 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
29317
29379
  });
29318
29380
  }
29319
29381
  function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, logger, manifest, scopePath) {
29320
- const commandsRoot = path41.resolve(sourceRoot, config.source.commands);
29382
+ const commandsRoot = path42.resolve(sourceRoot, config.source.commands);
29321
29383
  if (!fs42.existsSync(commandsRoot)) {
29322
29384
  return [skippedMissingSource2("commands", commandsRoot)];
29323
29385
  }
29324
29386
  const skillsRoot = resolveTargetPath(paths.skills);
29325
29387
  return compileCommandsAsSkills(commandsRoot, "codex").map((skill) => {
29326
- const destination = path41.join(skillsRoot, skill.name, "SKILL.md");
29388
+ const destination = path42.join(skillsRoot, skill.name, "SKILL.md");
29327
29389
  if (options.dryRun) {
29328
29390
  logger.info(
29329
29391
  `[dry-run] commands: compile ${skill.relativeSource} -> ${destination}`
@@ -29349,16 +29411,16 @@ function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, l
29349
29411
  });
29350
29412
  }
29351
29413
  function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29352
- const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
29414
+ const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
29353
29415
  if (!fs42.existsSync(sourceAgentsRoot)) {
29354
29416
  return [skippedMissingSource2("agents", sourceAgentsRoot)];
29355
29417
  }
29356
- const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
29418
+ const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
29357
29419
  const agentsRoot = resolveTargetPath(paths.agents);
29358
29420
  return sourceAgents.map((agentFile) => {
29359
- const destination = path41.join(
29421
+ const destination = path42.join(
29360
29422
  agentsRoot,
29361
- `${path41.basename(agentFile, ".md")}.toml`
29423
+ `${path42.basename(agentFile, ".md")}.toml`
29362
29424
  );
29363
29425
  const compiled = compileAgent(
29364
29426
  agentFile,
@@ -29494,7 +29556,7 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
29494
29556
  if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
29495
29557
  return { component, status: "conflict", path: destination };
29496
29558
  }
29497
- ensureDir(path41.dirname(destination));
29559
+ ensureDir(path42.dirname(destination));
29498
29560
  const clearedLink = clearSymlinkAtDestination(destination);
29499
29561
  if (clearedLink !== null) {
29500
29562
  logger.verbose(
@@ -29523,7 +29585,7 @@ ${managedMcpEnd}
29523
29585
  if (current === next.trimStart()) {
29524
29586
  return false;
29525
29587
  }
29526
- ensureDir(path41.dirname(destination));
29588
+ ensureDir(path42.dirname(destination));
29527
29589
  fs42.writeFileSync(destination, next.trimStart());
29528
29590
  return true;
29529
29591
  }
@@ -29598,15 +29660,15 @@ function hashString(value) {
29598
29660
  // src/adapters/copilot.ts
29599
29661
  import crypto7 from "crypto";
29600
29662
  import fs43 from "fs";
29601
- import path43 from "path";
29663
+ import path44 from "path";
29602
29664
 
29603
29665
  // src/compiler/commands.ts
29604
29666
  var import_yaml11 = __toESM(require_dist(), 1);
29605
- import path42 from "path";
29667
+ import path43 from "path";
29606
29668
  function compileCommandPrompt(sourceFile) {
29607
29669
  const { data, body } = parseMarkdownFrontmatter(sourceFile);
29608
- const relativeSource = `commands/${path42.basename(sourceFile)}`;
29609
- const fields = promptFrontmatter(data, path42.basename(sourceFile, ".md"));
29670
+ const relativeSource = `commands/${path43.basename(sourceFile)}`;
29671
+ const fields = promptFrontmatter(data, path43.basename(sourceFile, ".md"));
29610
29672
  const marker = formatProvenanceMarker(
29611
29673
  "markdown",
29612
29674
  relativeSource,
@@ -29747,7 +29809,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29747
29809
  if (!shouldSkipComponent3(options, "hooks")) {
29748
29810
  outcomes.push(
29749
29811
  syncHookScriptsBridge({
29750
- source: path43.resolve(sourceRoot, config.source.hooks),
29812
+ source: path44.resolve(sourceRoot, config.source.hooks),
29751
29813
  destination: resolveTargetPath(paths.hook_scripts),
29752
29814
  config,
29753
29815
  sourceRoot,
@@ -29828,13 +29890,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
29828
29890
  }
29829
29891
  function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
29830
29892
  if (!mappings.modelTiers.custom_provider) return;
29831
- const agentsDir = path43.join(sourceRoot, config.source.agents);
29893
+ const agentsDir = path44.join(sourceRoot, config.source.agents);
29832
29894
  if (!fs43.existsSync(agentsDir)) return;
29833
- for (const agentFile of ts(path43.join(agentsDir, "*.md")).sort()) {
29895
+ for (const agentFile of ts(path44.join(agentsDir, "*.md")).sort()) {
29834
29896
  const { data } = parseMarkdownFrontmatter(agentFile);
29835
29897
  const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
29836
29898
  if (hasProvider) {
29837
- const basename = path43.basename(agentFile);
29899
+ const basename = path44.basename(agentFile);
29838
29900
  addLoss(lossReport, "copilot", "agents", {
29839
29901
  source: `agents/${basename}`,
29840
29902
  fields: [
@@ -29867,15 +29929,15 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
29867
29929
  const contentHash = hashString2(rawContent);
29868
29930
  const marker = formatProvenanceMarker(
29869
29931
  "markdown",
29870
- path43.basename(instructionsSourceLabel(sourceRoot, config)),
29932
+ path44.basename(instructionsSourceLabel(sourceRoot, config)),
29871
29933
  contentHash,
29872
29934
  "copilot"
29873
29935
  );
29874
29936
  const composedContent = `${marker}
29875
29937
  ${rawContent}`;
29876
29938
  const projectRoot = options.projectRoot ?? process.cwd();
29877
- const agentsMdDest = path43.resolve(projectRoot, "AGENTS.md");
29878
- const mirrorDest = path43.resolve(
29939
+ const agentsMdDest = path44.resolve(projectRoot, "AGENTS.md");
29940
+ const mirrorDest = path44.resolve(
29879
29941
  projectRoot,
29880
29942
  ".github",
29881
29943
  "copilot-instructions.md"
@@ -29929,7 +29991,7 @@ function writeInstructionsFile(component, destination, content, contentHash, con
29929
29991
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
29930
29992
  return { component, status: "conflict", path: destination };
29931
29993
  }
29932
- ensureDir(path43.dirname(destination));
29994
+ ensureDir(path44.dirname(destination));
29933
29995
  const clearedLink = clearSymlinkAtDestination(destination);
29934
29996
  if (clearedLink !== null) {
29935
29997
  logger.verbose(
@@ -29946,7 +30008,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29946
30008
  return syncSkillsSlot({
29947
30009
  config,
29948
30010
  sourceRoot,
29949
- source: path43.resolve(sourceRoot, config.source.skills),
30011
+ source: path44.resolve(sourceRoot, config.source.skills),
29950
30012
  destination: resolveTargetPath(paths.skills),
29951
30013
  dryRun: options.dryRun,
29952
30014
  logger,
@@ -29961,16 +30023,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
29961
30023
  });
29962
30024
  }
29963
30025
  function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
29964
- const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
30026
+ const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
29965
30027
  if (!fs43.existsSync(sourceAgentsRoot)) {
29966
30028
  return [skippedMissingSource3("agents", sourceAgentsRoot)];
29967
30029
  }
29968
- const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
30030
+ const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
29969
30031
  const agentsRoot = resolveTargetPath(paths.agents);
29970
30032
  return sourceAgents.map((agentFile) => {
29971
- const destination = path43.join(
30033
+ const destination = path44.join(
29972
30034
  agentsRoot,
29973
- `${path43.basename(agentFile, ".md")}.agent.md`
30035
+ `${path44.basename(agentFile, ".md")}.agent.md`
29974
30036
  );
29975
30037
  const compiled = compileAgent(
29976
30038
  agentFile,
@@ -29998,16 +30060,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
29998
30060
  });
29999
30061
  }
30000
30062
  function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30001
- const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
30063
+ const sourceCommandsRoot = path44.join(sourceRoot, config.source.commands);
30002
30064
  if (!fs43.existsSync(sourceCommandsRoot)) {
30003
30065
  return [skippedMissingSource3("commands", sourceCommandsRoot)];
30004
30066
  }
30005
- const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
30067
+ const sourceCommands = ts(path44.join(sourceCommandsRoot, "*.md")).sort();
30006
30068
  const promptsRoot = resolveTargetPath(paths.prompts);
30007
30069
  return sourceCommands.map((commandFile) => {
30008
- const destination = path43.join(
30070
+ const destination = path44.join(
30009
30071
  promptsRoot,
30010
- `${path43.basename(commandFile, ".md")}.prompt.md`
30072
+ `${path44.basename(commandFile, ".md")}.prompt.md`
30011
30073
  );
30012
30074
  const compiled = compileCommandPrompt(commandFile);
30013
30075
  if (options.dryRun) {
@@ -30031,7 +30093,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
30031
30093
  });
30032
30094
  }
30033
30095
  function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
30034
- const destination = path43.join(
30096
+ const destination = path44.join(
30035
30097
  resolveTargetPath(paths.hooks),
30036
30098
  "tangyr-managed.json"
30037
30099
  );
@@ -30120,13 +30182,13 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
30120
30182
  );
30121
30183
  }
30122
30184
  function syncRules2(config, sourceRoot, rulesSlot, options, logger, manifest, scopePath) {
30123
- const sourceRulesDir = path43.resolve(sourceRoot, config.source.rules);
30185
+ const sourceRulesDir = path44.resolve(sourceRoot, config.source.rules);
30124
30186
  if (!fs43.existsSync(sourceRulesDir)) {
30125
30187
  return [skippedMissingSource3("rules", sourceRulesDir)];
30126
30188
  }
30127
30189
  const destinationRoot = resolveTargetPath(rulesSlot);
30128
30190
  return compileCopilotRules(sourceRulesDir).map((file) => {
30129
- const destination = path43.join(destinationRoot, file.name);
30191
+ const destination = path44.join(destinationRoot, file.name);
30130
30192
  if (options.dryRun) {
30131
30193
  logger.info(`[dry-run] rules: compile -> ${destination}`);
30132
30194
  return {
@@ -30160,7 +30222,7 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
30160
30222
  if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
30161
30223
  return { component, status: "conflict", path: destination };
30162
30224
  }
30163
- ensureDir(path43.dirname(destination));
30225
+ ensureDir(path44.dirname(destination));
30164
30226
  const clearedLink = clearSymlinkAtDestination(destination);
30165
30227
  if (clearedLink !== null) {
30166
30228
  logger.verbose(
@@ -30216,12 +30278,12 @@ function shouldSkipComponent3(options, component) {
30216
30278
  function cleanupLegacyAgents(paths, options, logger) {
30217
30279
  const currentAgentsRoot = resolveTargetPath(paths.agents);
30218
30280
  const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
30219
- if (path43.resolve(currentAgentsRoot) === path43.resolve(legacyAgentsRoot)) {
30281
+ if (path44.resolve(currentAgentsRoot) === path44.resolve(legacyAgentsRoot)) {
30220
30282
  return [];
30221
30283
  }
30222
30284
  const outcomes = [];
30223
30285
  for (const filePath of ts(
30224
- path43.join(legacyAgentsRoot, "*.agent.md")
30286
+ path44.join(legacyAgentsRoot, "*.agent.md")
30225
30287
  ).sort()) {
30226
30288
  if (!isCopilotManagedCompiledFile(filePath)) {
30227
30289
  continue;
@@ -30254,7 +30316,7 @@ function skippedMissingSource3(component, source) {
30254
30316
  // src/adapters/cursor.ts
30255
30317
  import crypto8 from "crypto";
30256
30318
  import fs44 from "fs";
30257
- import path44 from "path";
30319
+ import path45 from "path";
30258
30320
  function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30259
30321
  const scope = options.scope ?? "global";
30260
30322
  const profile = resolveTargetPaths({
@@ -30366,7 +30428,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
30366
30428
  if (!shouldSkipComponent4(options, "hooks")) {
30367
30429
  outcomes.push(
30368
30430
  syncHookScriptsBridge({
30369
- source: path44.resolve(sourceRoot, config.source.hooks),
30431
+ source: path45.resolve(sourceRoot, config.source.hooks),
30370
30432
  destination: resolveTargetPath(paths.hook_scripts),
30371
30433
  config,
30372
30434
  sourceRoot,
@@ -30431,7 +30493,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
30431
30493
  const composed = composeCursorInstructions(config, sourceRoot, lossReport);
30432
30494
  const marker = formatProvenanceMarker(
30433
30495
  "markdown",
30434
- path44.basename(instructionsSourceLabel(sourceRoot, config)),
30496
+ path45.basename(instructionsSourceLabel(sourceRoot, config)),
30435
30497
  hashString3(composed),
30436
30498
  "cursor"
30437
30499
  );
@@ -30470,11 +30532,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
30470
30532
  ${personaContent}`.trim() : baseContent;
30471
30533
  }
30472
30534
  function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
30473
- const agentsDir = path44.join(sourceRoot, config.source.agents);
30535
+ const agentsDir = path45.join(sourceRoot, config.source.agents);
30474
30536
  if (!fs44.existsSync(agentsDir)) {
30475
30537
  return null;
30476
30538
  }
30477
- const agentFiles = ts(path44.join(agentsDir, "*.md")).sort();
30539
+ const agentFiles = ts(path45.join(agentsDir, "*.md")).sort();
30478
30540
  if (agentFiles.length === 0) {
30479
30541
  return null;
30480
30542
  }
@@ -30497,7 +30559,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
30497
30559
  return null;
30498
30560
  }
30499
30561
  addLoss(lossReport, "cursor", "instructions", {
30500
- source: `agents/${path44.basename(primaryFile)}`,
30562
+ source: `agents/${path45.basename(primaryFile)}`,
30501
30563
  fields: [
30502
30564
  {
30503
30565
  field: "persona",
@@ -30507,23 +30569,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
30507
30569
  "persona",
30508
30570
  "instructions-shim"
30509
30571
  ),
30510
- detail: `Primary persona from ${path44.basename(primaryFile)} folded into its instructions file (Cursor has no custom modes surface)`
30572
+ detail: `Primary persona from ${path45.basename(primaryFile)} folded into its instructions file (Cursor has no custom modes surface)`
30511
30573
  }
30512
30574
  ]
30513
30575
  });
30514
30576
  return body.trim();
30515
30577
  }
30516
30578
  function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30517
- const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
30579
+ const sourceAgentsRoot = path45.join(sourceRoot, config.source.agents);
30518
30580
  if (!fs44.existsSync(sourceAgentsRoot)) {
30519
30581
  return [skippedMissingSource4("agents", sourceAgentsRoot)];
30520
30582
  }
30521
- const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
30583
+ const sourceAgents = ts(path45.join(sourceAgentsRoot, "*.md")).sort();
30522
30584
  const agentsRoot = resolveTargetPath(paths.agents);
30523
30585
  return sourceAgents.map((agentFile) => {
30524
- const destination = path44.join(
30586
+ const destination = path45.join(
30525
30587
  agentsRoot,
30526
- `${path44.basename(agentFile, ".md")}.md`
30588
+ `${path45.basename(agentFile, ".md")}.md`
30527
30589
  );
30528
30590
  let compiled;
30529
30591
  try {
@@ -30564,14 +30626,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
30564
30626
  });
30565
30627
  }
30566
30628
  function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
30567
- const sourceRulesDir = path44.join(sourceRoot, config.source.rules);
30629
+ const sourceRulesDir = path45.join(sourceRoot, config.source.rules);
30568
30630
  if (!fs44.existsSync(sourceRulesDir)) {
30569
30631
  return [skippedMissingSource4("rules", sourceRulesDir)];
30570
30632
  }
30571
30633
  const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
30572
30634
  const rulesDir = resolveTargetPath(paths.rules);
30573
30635
  return compiled.dotRulesFiles.map(({ name, content }) => {
30574
- const destination = path44.join(rulesDir, name);
30636
+ const destination = path45.join(rulesDir, name);
30575
30637
  if (options.dryRun) {
30576
30638
  logger.info(`[dry-run] rules: write ${destination}`);
30577
30639
  return {
@@ -30595,15 +30657,15 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
30595
30657
  });
30596
30658
  }
30597
30659
  function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
30598
- const sourceCommandsRoot = path44.join(sourceRoot, config.source.commands);
30660
+ const sourceCommandsRoot = path45.join(sourceRoot, config.source.commands);
30599
30661
  if (!fs44.existsSync(sourceCommandsRoot)) {
30600
30662
  return [skippedMissingSource4("commands", sourceCommandsRoot)];
30601
30663
  }
30602
- const sourceCommands = ts(path44.join(sourceCommandsRoot, "*.md")).sort();
30664
+ const sourceCommands = ts(path45.join(sourceCommandsRoot, "*.md")).sort();
30603
30665
  const skillsRoot = resolveTargetPath(paths.skills);
30604
30666
  return sourceCommands.map((commandFile) => {
30605
- const baseName = path44.basename(commandFile, ".md");
30606
- const destination = path44.join(skillsRoot, baseName, "SKILL.md");
30667
+ const baseName = path45.basename(commandFile, ".md");
30668
+ const destination = path45.join(skillsRoot, baseName, "SKILL.md");
30607
30669
  const { content } = compileCommandAsSkill(commandFile, "cursor");
30608
30670
  if (options.dryRun) {
30609
30671
  logger.info(
@@ -30633,7 +30695,7 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, _
30633
30695
  return syncSkillsSlot({
30634
30696
  config,
30635
30697
  sourceRoot,
30636
- source: path44.resolve(sourceRoot, config.source.skills),
30698
+ source: path45.resolve(sourceRoot, config.source.skills),
30637
30699
  destination,
30638
30700
  dryRun: options.dryRun,
30639
30701
  logger,
@@ -30681,7 +30743,7 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
30681
30743
  }
30682
30744
  const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
30683
30745
  `;
30684
- ensureDir(path44.dirname(destination));
30746
+ ensureDir(path45.dirname(destination));
30685
30747
  fs44.writeFileSync(destination, hooksFileContent);
30686
30748
  return { component: "hooks", status: "success", path: destination };
30687
30749
  }
@@ -30745,13 +30807,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
30745
30807
  );
30746
30808
  }
30747
30809
  function syncProviderPin(config, sourceRoot, lossReport) {
30748
- const agentsDir = path44.join(sourceRoot, config.source.agents);
30810
+ const agentsDir = path45.join(sourceRoot, config.source.agents);
30749
30811
  if (!fs44.existsSync(agentsDir)) return;
30750
- for (const agentFile of ts(path44.join(agentsDir, "*.md")).sort()) {
30812
+ for (const agentFile of ts(path45.join(agentsDir, "*.md")).sort()) {
30751
30813
  const { data } = parseMarkdownFrontmatter(agentFile);
30752
30814
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
30753
30815
  if (hasCustomProvider) {
30754
- const relativeSource = `agents/${path44.basename(agentFile)}`;
30816
+ const relativeSource = `agents/${path45.basename(agentFile)}`;
30755
30817
  addLoss(lossReport, "cursor", "agents", {
30756
30818
  source: relativeSource,
30757
30819
  fields: [
@@ -30763,7 +30825,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
30763
30825
  "provider",
30764
30826
  "provider-not-representable"
30765
30827
  ),
30766
- detail: `${path44.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
30828
+ detail: `${path45.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
30767
30829
  }
30768
30830
  ]
30769
30831
  });
@@ -30781,7 +30843,7 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
30781
30843
  if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
30782
30844
  return { component, status: "conflict", path: destination };
30783
30845
  }
30784
- ensureDir(path44.dirname(destination));
30846
+ ensureDir(path45.dirname(destination));
30785
30847
  const clearedLink = clearSymlinkAtDestination(destination);
30786
30848
  if (clearedLink !== null) {
30787
30849
  logger.verbose(
@@ -30848,7 +30910,7 @@ function hashString3(value) {
30848
30910
  // src/adapters/cline.ts
30849
30911
  import crypto9 from "crypto";
30850
30912
  import fs45 from "fs";
30851
- import path45 from "path";
30913
+ import path46 from "path";
30852
30914
  function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
30853
30915
  const scope = options.scope ?? "global";
30854
30916
  const profile = resolveTargetPaths({
@@ -30961,7 +31023,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
30961
31023
  function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
30962
31024
  if (scope === "global" || paths.instructions === null) {
30963
31025
  addLoss(lossReport, "cline", "instructions", {
30964
- source: path45.basename(instructionsSourceLabel(sourceRoot, config)),
31026
+ source: path46.basename(instructionsSourceLabel(sourceRoot, config)),
30965
31027
  fields: [
30966
31028
  {
30967
31029
  field: "instructions",
@@ -30986,7 +31048,7 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
30986
31048
  const baseContent = fs45.existsSync(source) ? fs45.readFileSync(source, "utf8").trim() : "";
30987
31049
  const marker = formatProvenanceMarker(
30988
31050
  "markdown",
30989
- path45.basename(instructionsSourceLabel(sourceRoot, config)),
31051
+ path46.basename(instructionsSourceLabel(sourceRoot, config)),
30990
31052
  hashString4(baseContent),
30991
31053
  "cline"
30992
31054
  );
@@ -31011,11 +31073,11 @@ ${baseContent}
31011
31073
  );
31012
31074
  }
31013
31075
  function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
31014
- const sourceAgentsRoot = path45.join(sourceRoot, config.source.agents);
31076
+ const sourceAgentsRoot = path46.join(sourceRoot, config.source.agents);
31015
31077
  if (!fs45.existsSync(sourceAgentsRoot)) {
31016
31078
  return [skippedMissingSource5("agents", sourceAgentsRoot)];
31017
31079
  }
31018
- const sourceAgents = ts(path45.join(sourceAgentsRoot, "*.md")).sort();
31080
+ const sourceAgents = ts(path46.join(sourceAgentsRoot, "*.md")).sort();
31019
31081
  return sourceAgents.map((agentFile) => {
31020
31082
  compileAgent(agentFile, "cline", mappings, extensions, lossReport);
31021
31083
  if (options.dryRun) {
@@ -31031,14 +31093,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
31031
31093
  });
31032
31094
  }
31033
31095
  function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
31034
- const sourceRulesDir = path45.join(sourceRoot, config.source.rules);
31096
+ const sourceRulesDir = path46.join(sourceRoot, config.source.rules);
31035
31097
  if (!fs45.existsSync(sourceRulesDir)) {
31036
31098
  return [skippedMissingSource5("rules", sourceRulesDir)];
31037
31099
  }
31038
31100
  const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
31039
31101
  const rulesDir = resolveTargetPath(paths.rules);
31040
31102
  return compiled.dotRulesFiles.map(({ name, content }) => {
31041
- const destination = path45.join(rulesDir, name);
31103
+ const destination = path46.join(rulesDir, name);
31042
31104
  if (options.dryRun) {
31043
31105
  logger.info(`[dry-run] rules: write ${destination}`);
31044
31106
  return {
@@ -31062,17 +31124,17 @@ function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, lo
31062
31124
  });
31063
31125
  }
31064
31126
  function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
31065
- const sourceCommandsRoot = path45.join(sourceRoot, config.source.commands);
31127
+ const sourceCommandsRoot = path46.join(sourceRoot, config.source.commands);
31066
31128
  if (!fs45.existsSync(sourceCommandsRoot)) {
31067
31129
  return [skippedMissingSource5("commands", sourceCommandsRoot)];
31068
31130
  }
31069
- const sourceCommands = ts(path45.join(sourceCommandsRoot, "*.md")).sort();
31131
+ const sourceCommands = ts(path46.join(sourceCommandsRoot, "*.md")).sort();
31070
31132
  const workflowsRoot = resolveTargetPath(paths.workflows);
31071
31133
  return sourceCommands.map((commandFile) => {
31072
- const baseName = path45.basename(commandFile);
31073
- const destination = path45.join(workflowsRoot, baseName);
31134
+ const baseName = path46.basename(commandFile);
31135
+ const destination = path46.join(workflowsRoot, baseName);
31074
31136
  const commandContent = fs45.readFileSync(commandFile, "utf8");
31075
- const relativeSource = `commands/${path45.basename(commandFile)}`;
31137
+ const relativeSource = `commands/${path46.basename(commandFile)}`;
31076
31138
  const marker = formatProvenanceMarker(
31077
31139
  "markdown",
31078
31140
  relativeSource,
@@ -31110,7 +31172,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
31110
31172
  return syncSkillsSlot({
31111
31173
  config,
31112
31174
  sourceRoot,
31113
- source: path45.resolve(sourceRoot, config.source.skills),
31175
+ source: path46.resolve(sourceRoot, config.source.skills),
31114
31176
  destination: resolveTargetPath(paths.skills),
31115
31177
  dryRun: options.dryRun,
31116
31178
  logger,
@@ -31189,11 +31251,11 @@ function syncSettings2(lossReport) {
31189
31251
  };
31190
31252
  }
31191
31253
  function syncProviderAndModel(config, sourceRoot, lossReport) {
31192
- const agentsDir = path45.join(sourceRoot, config.source.agents);
31254
+ const agentsDir = path46.join(sourceRoot, config.source.agents);
31193
31255
  if (!fs45.existsSync(agentsDir)) return;
31194
- for (const agentFile of ts(path45.join(agentsDir, "*.md")).sort()) {
31256
+ for (const agentFile of ts(path46.join(agentsDir, "*.md")).sort()) {
31195
31257
  const { data } = parseMarkdownFrontmatter(agentFile);
31196
- const relativeSource = `agents/${path45.basename(agentFile)}`;
31258
+ const relativeSource = `agents/${path46.basename(agentFile)}`;
31197
31259
  const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
31198
31260
  if (hasCustomProvider) {
31199
31261
  addLoss(lossReport, "cline", "agents", {
@@ -31207,7 +31269,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
31207
31269
  "provider",
31208
31270
  "provider-not-representable"
31209
31271
  ),
31210
- detail: `${path45.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
31272
+ detail: `${path46.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
31211
31273
  }
31212
31274
  ]
31213
31275
  });
@@ -31225,7 +31287,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
31225
31287
  "model",
31226
31288
  "model-not-representable"
31227
31289
  ),
31228
- detail: `${path45.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
31290
+ detail: `${path46.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
31229
31291
  }
31230
31292
  ]
31231
31293
  });
@@ -31243,7 +31305,7 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
31243
31305
  if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
31244
31306
  return { component, status: "conflict", path: destination };
31245
31307
  }
31246
- ensureDir(path45.dirname(destination));
31308
+ ensureDir(path46.dirname(destination));
31247
31309
  const clearedLink = clearSymlinkAtDestination(destination);
31248
31310
  if (clearedLink !== null) {
31249
31311
  logger.verbose(
@@ -31311,7 +31373,7 @@ function hashString4(value) {
31311
31373
  import crypto10 from "crypto";
31312
31374
  import fs46 from "fs";
31313
31375
  import os6 from "os";
31314
- import path46 from "path";
31376
+ import path47 from "path";
31315
31377
  var import_yaml12 = __toESM(require_dist(), 1);
31316
31378
  function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
31317
31379
  const scope = options.scope ?? "global";
@@ -31329,7 +31391,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
31329
31391
  config_doc: profile.config_doc
31330
31392
  };
31331
31393
  const rules = compileRules(
31332
- path46.join(sourceRoot, config.source.rules),
31394
+ path47.join(sourceRoot, config.source.rules),
31333
31395
  "opencode",
31334
31396
  mappings,
31335
31397
  lossReport
@@ -31449,7 +31511,7 @@ function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, l
31449
31511
  ${agentsAppendix}`.trim() : baseContent;
31450
31512
  const marker = formatProvenanceMarker(
31451
31513
  "markdown",
31452
- path46.basename(instructionsSourceLabel(sourceRoot, config)),
31514
+ path47.basename(instructionsSourceLabel(sourceRoot, config)),
31453
31515
  hashString5(composed),
31454
31516
  "opencode"
31455
31517
  );
@@ -31483,13 +31545,13 @@ ${composed}
31483
31545
  ];
31484
31546
  }
31485
31547
  function declaredInstructionsPath(paths) {
31486
- const configDir = path46.dirname(resolveTargetPath(paths.config_doc));
31548
+ const configDir = path47.dirname(resolveTargetPath(paths.config_doc));
31487
31549
  const instructions = resolveTargetPath(paths.instructions);
31488
- const relative = path46.relative(configDir, instructions);
31550
+ const relative = path47.relative(configDir, instructions);
31489
31551
  if (relative === "AGENTS.md" || relative.startsWith("..")) {
31490
31552
  return null;
31491
31553
  }
31492
- return relative.split(path46.sep).join("/");
31554
+ return relative.split(path47.sep).join("/");
31493
31555
  }
31494
31556
  function withDeclaredInstructions(existing, reference) {
31495
31557
  const listed = Array.isArray(existing) ? existing.filter((entry) => typeof entry === "string") : [];
@@ -31518,22 +31580,22 @@ function declareInstructions(paths, manifest) {
31518
31580
  const host = { ...existing };
31519
31581
  const written = mergeIntoHost(host, config);
31520
31582
  recordSharedWrite(manifest, destination, "opencode", existed, written);
31521
- ensureDir(path46.dirname(destination));
31583
+ ensureDir(path47.dirname(destination));
31522
31584
  fs46.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31523
31585
  `);
31524
31586
  return destination;
31525
31587
  }
31526
31588
  function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
31527
- const sourceAgentsRoot = path46.join(sourceRoot, config.source.agents);
31589
+ const sourceAgentsRoot = path47.join(sourceRoot, config.source.agents);
31528
31590
  if (!fs46.existsSync(sourceAgentsRoot)) {
31529
31591
  return [skippedMissingSource6("agents", sourceAgentsRoot)];
31530
31592
  }
31531
- const sourceAgents = ts(path46.join(sourceAgentsRoot, "*.md")).sort();
31593
+ const sourceAgents = ts(path47.join(sourceAgentsRoot, "*.md")).sort();
31532
31594
  const agentsRoot = resolveTargetPath(paths.agents);
31533
31595
  return sourceAgents.map((agentFile) => {
31534
- const destination = path46.join(
31596
+ const destination = path47.join(
31535
31597
  agentsRoot,
31536
- `${path46.basename(agentFile, ".md")}.md`
31598
+ `${path47.basename(agentFile, ".md")}.md`
31537
31599
  );
31538
31600
  let compiled;
31539
31601
  try {
@@ -31597,11 +31659,11 @@ function applyProviderModelBinding(compiled, mappings) {
31597
31659
  return `${before}${(0, import_yaml12.stringify)(fields).trim()}${after}`;
31598
31660
  }
31599
31661
  function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
31600
- const sourceCommandsRoot = path46.join(sourceRoot, config.source.commands);
31662
+ const sourceCommandsRoot = path47.join(sourceRoot, config.source.commands);
31601
31663
  if (!fs46.existsSync(sourceCommandsRoot)) {
31602
31664
  return [skippedMissingSource6("commands", sourceCommandsRoot)];
31603
31665
  }
31604
- const sourceCommands = ts(path46.join(sourceCommandsRoot, "*.md")).sort();
31666
+ const sourceCommands = ts(path47.join(sourceCommandsRoot, "*.md")).sort();
31605
31667
  const commandsRoot = resolveTargetPath(paths.commands);
31606
31668
  return sourceCommands.map((commandFile) => {
31607
31669
  const { data, body } = parseCommandFile(commandFile);
@@ -31615,7 +31677,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
31615
31677
  if (typeof data.model === "string") {
31616
31678
  frontmatter.model = data.model;
31617
31679
  }
31618
- const relativeSource = `commands/${path46.basename(commandFile)}`;
31680
+ const relativeSource = `commands/${path47.basename(commandFile)}`;
31619
31681
  const marker = formatProvenanceMarker(
31620
31682
  "markdown",
31621
31683
  relativeSource,
@@ -31631,9 +31693,9 @@ ${body.trimEnd()}
31631
31693
  ` : `${marker}
31632
31694
  ${body.trimEnd()}
31633
31695
  `;
31634
- const destination = path46.join(
31696
+ const destination = path47.join(
31635
31697
  commandsRoot,
31636
- `${path46.basename(commandFile, ".md")}.md`
31698
+ `${path47.basename(commandFile, ".md")}.md`
31637
31699
  );
31638
31700
  if (options.dryRun) {
31639
31701
  logger.info(
@@ -31663,7 +31725,7 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
31663
31725
  return syncSkillsSlot({
31664
31726
  config,
31665
31727
  sourceRoot,
31666
- source: path46.resolve(sourceRoot, config.source.skills),
31728
+ source: path47.resolve(sourceRoot, config.source.skills),
31667
31729
  destination,
31668
31730
  dryRun: options.dryRun,
31669
31731
  logger,
@@ -31797,7 +31859,7 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings,
31797
31859
  )
31798
31860
  });
31799
31861
  recordSharedWrite(manifest, destination, "opencode", existed, written);
31800
- ensureDir(path46.dirname(destination));
31862
+ ensureDir(path47.dirname(destination));
31801
31863
  fs46.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
31802
31864
  `);
31803
31865
  }
@@ -31812,7 +31874,7 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
31812
31874
  if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
31813
31875
  return { component, status: "conflict", path: destination };
31814
31876
  }
31815
- ensureDir(path46.dirname(destination));
31877
+ ensureDir(path47.dirname(destination));
31816
31878
  const clearedLink = clearSymlinkAtDestination(destination);
31817
31879
  if (clearedLink !== null) {
31818
31880
  logger.verbose(
@@ -31933,7 +31995,7 @@ async function runInstallCommand(options, logger) {
31933
31995
  );
31934
31996
  }
31935
31997
  const kitName = resolvedKitName ?? config.kit;
31936
- const kitPath = kitPathOverride ?? (options.kitPath ? path47.resolve(options.kitPath) : config.kitPath);
31998
+ const kitPath = kitPathOverride ?? (options.kitPath ? path48.resolve(options.kitPath) : config.kitPath);
31937
31999
  if (!kitName && !kitPath) {
31938
32000
  logger.error(
31939
32001
  "No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
@@ -31986,9 +32048,35 @@ async function runInstallCommand(options, logger) {
31986
32048
  logger.warn(
31987
32049
  `Existing Tangyr installation found in ${scopePath} (archetype: ${existingManifest.archetype}, version: ${existingManifest.version})`
31988
32050
  );
32051
+ const installedKit = existingManifest.kit;
32052
+ const switchingKit = installedKit !== void 0 && installedKit.name !== kitInfo.name;
31989
32053
  let action;
31990
- if (options.yes) {
32054
+ if (switchingKit && options.replace) {
32055
+ logger.warn(
32056
+ `Replacing '${installedKit.name}' (${installedKit.version}) with '${kitInfo.name}' (${kitInfo.version}): the installed kit is uninstalled first, which restores what it displaced.`
32057
+ );
32058
+ action = "clean-install";
32059
+ } else if (switchingKit && options.yes) {
32060
+ logger.error(
32061
+ `This scope holds the kit '${installedKit.name}' (${installedKit.version}), not '${kitInfo.name}'.`
32062
+ );
32063
+ logger.error(
32064
+ `Installing over it would leave both kits' artifacts in place, and every target would read both. Pass --replace to uninstall '${installedKit.name}' first and install '${kitInfo.name}' in its place, or run \`tangyr uninstall\` yourself. If you meant to update '${installedKit.name}', check kitPath in your configuration.`
32065
+ );
32066
+ process.exit(1);
32067
+ } else if (options.yes) {
31991
32068
  action = "update";
32069
+ } else if (switchingKit) {
32070
+ action = await dist_default8({
32071
+ message: `This scope holds '${installedKit.name}'. Installing '${kitInfo.name}' over it would leave both. Choose an action:`,
32072
+ choices: [
32073
+ {
32074
+ name: `Replace (uninstall '${installedKit.name}', then install '${kitInfo.name}')`,
32075
+ value: "clean-install"
32076
+ },
32077
+ { name: "Abort", value: "abort" }
32078
+ ]
32079
+ });
31992
32080
  } else if (!process.stdin.isTTY) {
31993
32081
  logger.error(
31994
32082
  "Existing installation requires an explicit action. Pass --yes to update, or run interactively."
@@ -32038,8 +32126,8 @@ async function runInstallCommand(options, logger) {
32038
32126
  config: options.config,
32039
32127
  scope
32040
32128
  });
32041
- const skillsSource = path47.resolve(kitInfo.path, config.source.skills);
32042
- const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path47.basename(f.path) === "skills";
32129
+ const skillsSource = path48.resolve(kitInfo.path, config.source.skills);
32130
+ const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path48.basename(f.path) === "skills";
32043
32131
  const foreignSkillsSlots = new Set(
32044
32132
  assessResult.findings.filter(
32045
32133
  (f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
@@ -32077,7 +32165,7 @@ async function runInstallCommand(options, logger) {
32077
32165
  let instructionsLabel;
32078
32166
  try {
32079
32167
  const resolved = resolveInstructionsSource(kitInfo.path, config);
32080
- instructionsLabel = resolved ? path47.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
32168
+ instructionsLabel = resolved ? path48.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
32081
32169
  } catch (err) {
32082
32170
  logger.error(
32083
32171
  `[dry-run] ${err instanceof Error ? err.message : String(err)}`
@@ -32105,7 +32193,7 @@ async function runInstallCommand(options, logger) {
32105
32193
  }
32106
32194
  }
32107
32195
  logger.info(
32108
- `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path47.join(scopePath, "manifest.json")}`
32196
+ `[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path48.join(scopePath, "manifest.json")}`
32109
32197
  );
32110
32198
  return;
32111
32199
  }
@@ -32247,6 +32335,7 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
32247
32335
  ensureScope(scopePath);
32248
32336
  const manifest = existingManifest ?? createEmptyManifest(kitInfo.archetype, kitInfo.kitFormat, scope);
32249
32337
  manifest.tools = [.../* @__PURE__ */ new Set([...manifest.tools, ...tools])];
32338
+ manifest.kit = { name: kitInfo.name, version: kitInfo.version };
32250
32339
  manifest.files = [];
32251
32340
  for (const backup of backupsToAdd) {
32252
32341
  manifest.backups.push(backup);
@@ -32306,26 +32395,26 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
32306
32395
  writeManifest(scopePath, manifest);
32307
32396
  logger.info(`
32308
32397
  Installation complete: ${installedCount} files installed.`);
32309
- logger.info(`Manifest written to ${path47.join(scopePath, "manifest.json")}`);
32398
+ logger.info(`Manifest written to ${path48.join(scopePath, "manifest.json")}`);
32310
32399
  logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
32311
32400
  logger.info(`Scope: ${scope}`);
32312
32401
  logger.info(`Tools: ${tools.join(", ")}`);
32313
32402
  reportHookRejections(
32314
32403
  installLossReport,
32315
32404
  tools,
32316
- path47.resolve(kitInfo.path, "hooks"),
32405
+ path48.resolve(kitInfo.path, "hooks"),
32317
32406
  kitInfo.components.hooks.declared
32318
32407
  );
32319
32408
  const hooksConflict = reportHooksSourceConflict(
32320
32409
  installLossReport,
32321
32410
  tools,
32322
- path47.resolve(kitInfo.path, "hooks"),
32411
+ path48.resolve(kitInfo.path, "hooks"),
32323
32412
  kitInfo.components.hooks.declared
32324
32413
  );
32325
32414
  if (hooksConflict) {
32326
32415
  logger.warn(hooksConflict);
32327
32416
  }
32328
- writeLossReport(options.lossReport, installLossReport);
32417
+ writeLossReport(options.lossReport, installLossReport, scopePath);
32329
32418
  exitOnErrorSeverityLoss(installLossReport, logger, {
32330
32419
  acceptedLoss: config.acceptedLoss,
32331
32420
  ignoreErrors: options.ignoreErrors ?? false
@@ -32712,17 +32801,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
32712
32801
  manifest,
32713
32802
  scopePath
32714
32803
  );
32715
- const skillsSource = path47.resolve(kitInfo.path, config.source.skills);
32804
+ const skillsSource = path48.resolve(kitInfo.path, config.source.skills);
32716
32805
  let count = 0;
32717
32806
  for (const outcome of outcomes) {
32718
32807
  if (outcome.status !== "success" && outcome.status !== "skipped-current") {
32719
32808
  continue;
32720
32809
  }
32721
- const skillName = path47.basename(outcome.path);
32810
+ const skillName = path48.basename(outcome.path);
32722
32811
  addArtifactToManifest(manifest, {
32723
32812
  relativePath: `claude-code/skills/${skillName}`,
32724
32813
  path: outcome.path,
32725
- hash: describeArtifactState(outcome.path) ?? `dir:${path47.join(skillsSource, skillName)}`,
32814
+ hash: describeArtifactState(outcome.path) ?? `dir:${path48.join(skillsSource, skillName)}`,
32726
32815
  origin: "tangyr-managed"
32727
32816
  });
32728
32817
  count++;
@@ -32736,7 +32825,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
32736
32825
  logger.verbose(` skipped (operator choice): ${placement.destination}`);
32737
32826
  continue;
32738
32827
  }
32739
- const destDir = path47.dirname(placement.destination);
32828
+ const destDir = path48.dirname(placement.destination);
32740
32829
  fs47.mkdirSync(destDir, { recursive: true });
32741
32830
  if (placement.type === "symlink") {
32742
32831
  if (fs47.existsSync(placement.destination) || isSymlink2(placement.destination)) {
@@ -33053,11 +33142,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
33053
33142
  if (outcome.path === mcpFile2) {
33054
33143
  return "cline/mcp.json";
33055
33144
  }
33056
- if (outcome.path.startsWith(`${workflowsRoot}${path47.sep}`)) {
33057
- return `cline/workflows/${path47.basename(outcome.path)}`;
33145
+ if (outcome.path.startsWith(`${workflowsRoot}${path48.sep}`)) {
33146
+ return `cline/workflows/${path48.basename(outcome.path)}`;
33058
33147
  }
33059
- if (outcome.path.startsWith(`${rulesRoot2}${path47.sep}`)) {
33060
- return `cline/rules/${path47.basename(outcome.path)}`;
33148
+ if (outcome.path.startsWith(`${rulesRoot2}${path48.sep}`)) {
33149
+ return `cline/rules/${path48.basename(outcome.path)}`;
33061
33150
  }
33062
33151
  return null;
33063
33152
  }
@@ -33093,14 +33182,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
33093
33182
  if (outcome.path === permissionsFile) {
33094
33183
  return "cursor/permissions.json";
33095
33184
  }
33096
- if (outcome.path.startsWith(`${agentsRoot2}${path47.sep}`)) {
33097
- return `cursor/agents/${path47.basename(outcome.path)}`;
33185
+ if (outcome.path.startsWith(`${agentsRoot2}${path48.sep}`)) {
33186
+ return `cursor/agents/${path48.basename(outcome.path)}`;
33098
33187
  }
33099
- if (outcome.path.startsWith(`${rulesRoot2}${path47.sep}`)) {
33100
- return `cursor/rules/${path47.basename(outcome.path)}`;
33188
+ if (outcome.path.startsWith(`${rulesRoot2}${path48.sep}`)) {
33189
+ return `cursor/rules/${path48.basename(outcome.path)}`;
33101
33190
  }
33102
- if (outcome.path.startsWith(`${skillsRoot2}${path47.sep}`)) {
33103
- const rel = path47.relative(skillsRoot2, outcome.path);
33191
+ if (outcome.path.startsWith(`${skillsRoot2}${path48.sep}`)) {
33192
+ const rel = path48.relative(skillsRoot2, outcome.path);
33104
33193
  return `cursor/skills/${rel}`;
33105
33194
  }
33106
33195
  return null;
@@ -33126,14 +33215,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
33126
33215
  if (outcome.path === skillsSharedRoot) {
33127
33216
  return "opencode/skills_shared";
33128
33217
  }
33129
- if (outcome.path.startsWith(`${agentsRoot2}${path47.sep}`)) {
33130
- return `opencode/agents/${path47.basename(outcome.path)}`;
33218
+ if (outcome.path.startsWith(`${agentsRoot2}${path48.sep}`)) {
33219
+ return `opencode/agents/${path48.basename(outcome.path)}`;
33131
33220
  }
33132
- if (outcome.path.startsWith(`${commandsRoot}${path47.sep}`)) {
33133
- return `opencode/commands/${path47.basename(outcome.path)}`;
33221
+ if (outcome.path.startsWith(`${commandsRoot}${path48.sep}`)) {
33222
+ return `opencode/commands/${path48.basename(outcome.path)}`;
33134
33223
  }
33135
33224
  if (outcome.path === configDocFile) {
33136
- return `opencode/${path47.basename(outcome.path)}`;
33225
+ return `opencode/${path48.basename(outcome.path)}`;
33137
33226
  }
33138
33227
  return null;
33139
33228
  }
@@ -33150,29 +33239,29 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
33150
33239
  const hooksRoot = resolveTargetPath(copilot.hooks);
33151
33240
  const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
33152
33241
  const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
33153
- if (copilot.rules !== null && outcome.path.startsWith(`${resolveTargetPath(copilot.rules)}${path47.sep}`)) {
33154
- return `copilot/rules/${path47.relative(resolveTargetPath(copilot.rules), outcome.path)}`;
33242
+ if (copilot.rules !== null && outcome.path.startsWith(`${resolveTargetPath(copilot.rules)}${path48.sep}`)) {
33243
+ return `copilot/rules/${path48.relative(resolveTargetPath(copilot.rules), outcome.path)}`;
33155
33244
  }
33156
- if (outcome.path.startsWith(`${skillsRoot2}${path47.sep}`)) {
33157
- return `copilot/skills/${path47.relative(skillsRoot2, outcome.path)}`;
33245
+ if (outcome.path.startsWith(`${skillsRoot2}${path48.sep}`)) {
33246
+ return `copilot/skills/${path48.relative(skillsRoot2, outcome.path)}`;
33158
33247
  }
33159
33248
  if (outcome.path === skillsRoot2) {
33160
33249
  return "copilot/skills";
33161
33250
  }
33162
33251
  if (instructionsMirror !== null && outcome.path === instructionsMirror) {
33163
- return `copilot/${path47.basename(outcome.path)}`;
33252
+ return `copilot/${path48.basename(outcome.path)}`;
33164
33253
  }
33165
- if (outcome.path.startsWith(`${agentsRoot2}${path47.sep}`)) {
33166
- return `copilot/agents/${path47.basename(outcome.path)}`;
33254
+ if (outcome.path.startsWith(`${agentsRoot2}${path48.sep}`)) {
33255
+ return `copilot/agents/${path48.basename(outcome.path)}`;
33167
33256
  }
33168
- if (outcome.path.startsWith(`${promptsRoot}${path47.sep}`)) {
33169
- return `copilot/prompts/${path47.basename(outcome.path)}`;
33257
+ if (outcome.path.startsWith(`${promptsRoot}${path48.sep}`)) {
33258
+ return `copilot/prompts/${path48.basename(outcome.path)}`;
33170
33259
  }
33171
- if (outcome.path.startsWith(`${hooksRoot}${path47.sep}`)) {
33172
- return `copilot/hooks/${path47.basename(outcome.path)}`;
33260
+ if (outcome.path.startsWith(`${hooksRoot}${path48.sep}`)) {
33261
+ return `copilot/hooks/${path48.basename(outcome.path)}`;
33173
33262
  }
33174
33263
  if (outcome.path === mcpFile2) {
33175
- return `copilot/${path47.basename(outcome.path)}`;
33264
+ return `copilot/${path48.basename(outcome.path)}`;
33176
33265
  }
33177
33266
  return null;
33178
33267
  }
@@ -33189,17 +33278,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
33189
33278
  if (outcome.path === skillsRoot) {
33190
33279
  return "codex/skills";
33191
33280
  }
33192
- if (outcome.path.startsWith(`${agentsRoot}${path47.sep}`)) {
33193
- return `codex/agents/${path47.basename(outcome.path)}`;
33281
+ if (outcome.path.startsWith(`${agentsRoot}${path48.sep}`)) {
33282
+ return `codex/agents/${path48.basename(outcome.path)}`;
33194
33283
  }
33195
- if (outcome.path.startsWith(`${rulesRoot}${path47.sep}`)) {
33196
- return `codex/rules/${path47.basename(outcome.path)}`;
33284
+ if (outcome.path.startsWith(`${rulesRoot}${path48.sep}`)) {
33285
+ return `codex/rules/${path48.basename(outcome.path)}`;
33197
33286
  }
33198
33287
  if (outcome.path === hooksFile) {
33199
- return `codex/${path47.basename(outcome.path)}`;
33288
+ return `codex/${path48.basename(outcome.path)}`;
33200
33289
  }
33201
33290
  if (outcome.path === mcpFile) {
33202
- return `codex/${path47.basename(outcome.path)}`;
33291
+ return `codex/${path48.basename(outcome.path)}`;
33203
33292
  }
33204
33293
  return null;
33205
33294
  }
@@ -33268,7 +33357,7 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
33268
33357
  rules: resolvedPaths.rules
33269
33358
  };
33270
33359
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
33271
- const componentDir = path47.join(kitInfo.path, component);
33360
+ const componentDir = path48.join(kitInfo.path, component);
33272
33361
  if (fs47.existsSync(componentDir) && fs47.statSync(componentDir).isDirectory()) {
33273
33362
  placements.push({
33274
33363
  source: componentDir,
@@ -33299,7 +33388,7 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
33299
33388
  rules: profile.rules
33300
33389
  };
33301
33390
  for (const [component, targetPath] of Object.entries(componentDirMap)) {
33302
- const componentDir = path47.join(kitInfo.path, component);
33391
+ const componentDir = path48.join(kitInfo.path, component);
33303
33392
  if (fs47.existsSync(componentDir) && fs47.statSync(componentDir).isDirectory()) {
33304
33393
  placements.push({
33305
33394
  source: componentDir,
@@ -33316,7 +33405,7 @@ function collectAllFiles(kitInfo, config) {
33316
33405
  const files = /* @__PURE__ */ new Map();
33317
33406
  const entrypoint = resolveInstructionsSource(kitInfo.path, config);
33318
33407
  if (entrypoint) {
33319
- files.set(path47.basename(entrypoint.file), entrypoint.file);
33408
+ files.set(path48.basename(entrypoint.file), entrypoint.file);
33320
33409
  }
33321
33410
  for (const [component, reconciliation] of Object.entries(
33322
33411
  kitInfo.components
@@ -33325,8 +33414,8 @@ function collectAllFiles(kitInfo, config) {
33325
33414
  const missingSet = new Set(reconciliation.missing);
33326
33415
  for (const entry of reconciliation.declared) {
33327
33416
  if (missingSet.has(entry)) continue;
33328
- const relPath = isSkills ? path47.join(component, entry) : path47.join(component, `${entry}.md`);
33329
- files.set(relPath, path47.join(kitInfo.path, relPath));
33417
+ const relPath = isSkills ? path48.join(component, entry) : path48.join(component, `${entry}.md`);
33418
+ files.set(relPath, path48.join(kitInfo.path, relPath));
33330
33419
  }
33331
33420
  }
33332
33421
  return files;
@@ -33359,10 +33448,10 @@ function skillsSubPathKey(tool, outcomePath, mappings, scope, projectRoot) {
33359
33448
  continue;
33360
33449
  }
33361
33450
  const root = resolveTargetPath(slot);
33362
- if (!outcomePath.startsWith(`${root}${path47.sep}`)) {
33451
+ if (!outcomePath.startsWith(`${root}${path48.sep}`)) {
33363
33452
  continue;
33364
33453
  }
33365
- const inside = path47.relative(root, outcomePath).split(path47.sep).join("/");
33454
+ const inside = path48.relative(root, outcomePath).split(path48.sep).join("/");
33366
33455
  return `${tool}/skills/${inside}`;
33367
33456
  }
33368
33457
  return null;
@@ -33407,14 +33496,14 @@ async function runKitUpdateCommand(options, logger) {
33407
33496
  }
33408
33497
 
33409
33498
  // src/commands/list.ts
33410
- import path48 from "path";
33499
+ import path49 from "path";
33411
33500
  function runListCommand(options, logger) {
33412
33501
  let searchPaths = [];
33413
- let directKitPath = options.kitPath ? path48.resolve(options.kitPath) : void 0;
33502
+ let directKitPath = options.kitPath ? path49.resolve(options.kitPath) : void 0;
33414
33503
  try {
33415
33504
  const { config, configDir } = resolveConfig(options.config);
33416
33505
  searchPaths = config.kitSearchPaths ?? [
33417
- path48.join(configDir, "operating-kits")
33506
+ path49.join(configDir, "operating-kits")
33418
33507
  ];
33419
33508
  directKitPath = directKitPath ?? config.kitPath;
33420
33509
  } catch (err) {
@@ -33489,7 +33578,7 @@ function withDirectKit(kits, directKitPath) {
33489
33578
  return kits;
33490
33579
  }
33491
33580
  const directKit = loadKit(directKitPath);
33492
- if (kits.some((kit) => path48.resolve(kit.path) === directKit.path)) {
33581
+ if (kits.some((kit) => path49.resolve(kit.path) === directKit.path)) {
33493
33582
  return kits;
33494
33583
  }
33495
33584
  return [...kits, directKit];
@@ -33498,7 +33587,7 @@ function withDirectKit(kits, directKitPath) {
33498
33587
  // src/commands/probe.ts
33499
33588
  import { spawnSync as spawnSync2 } from "child_process";
33500
33589
  import fs48 from "fs";
33501
- import path49 from "path";
33590
+ import path50 from "path";
33502
33591
  function runProbeCommand(options, logger) {
33503
33592
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
33504
33593
  options,
@@ -33526,7 +33615,7 @@ function runProbeCommand(options, logger) {
33526
33615
  toProbeRow(
33527
33616
  target,
33528
33617
  key,
33529
- scope === "project" ? path49.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
33618
+ scope === "project" ? path50.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
33530
33619
  )
33531
33620
  );
33532
33621
  }
@@ -33592,7 +33681,7 @@ function commandProbeRows(target, key, command, args) {
33592
33681
  // src/commands/status.ts
33593
33682
  import crypto11 from "crypto";
33594
33683
  import fs49 from "fs";
33595
- import path50 from "path";
33684
+ import path51 from "path";
33596
33685
  function runStatusCommand(options, logger) {
33597
33686
  const { config, configDir, configSource, sourceRoot } = resolveRuntime(
33598
33687
  options,
@@ -33698,11 +33787,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
33698
33787
  }
33699
33788
  }
33700
33789
  function sourceMarkdownFiles(sourceRoot, componentPath) {
33701
- const root = path50.join(sourceRoot, componentPath);
33790
+ const root = path51.join(sourceRoot, componentPath);
33702
33791
  if (!fs49.existsSync(root)) {
33703
33792
  return [];
33704
33793
  }
33705
- return ts(path50.join(root, "*.md")).sort();
33794
+ return ts(path51.join(root, "*.md")).sort();
33706
33795
  }
33707
33796
  function notRepresentableRow(component, detail) {
33708
33797
  return {
@@ -33849,7 +33938,7 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
33849
33938
  const rows = [];
33850
33939
  const instructionsSource = instructionsSourcePath(sourceRoot, config);
33851
33940
  const rules = compileRules(
33852
- path50.join(sourceRoot, config.source.rules),
33941
+ path51.join(sourceRoot, config.source.rules),
33853
33942
  "opencode",
33854
33943
  mappings,
33855
33944
  createLossReport()
@@ -33876,10 +33965,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
33876
33965
  )) {
33877
33966
  rows.push(
33878
33967
  classifyCompiledFile(
33879
- `agents/${path50.basename(agentFile, ".md")}`,
33880
- path50.join(
33968
+ `agents/${path51.basename(agentFile, ".md")}`,
33969
+ path51.join(
33881
33970
  resolveTargetPath(paths.agents),
33882
- `${path50.basename(agentFile, ".md")}.md`
33971
+ `${path51.basename(agentFile, ".md")}.md`
33883
33972
  ),
33884
33973
  "opencode",
33885
33974
  computeSourceHash(agentFile),
@@ -33894,10 +33983,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
33894
33983
  )) {
33895
33984
  rows.push(
33896
33985
  classifyCompiledFile(
33897
- `commands/${path50.basename(commandFile, ".md")}`,
33898
- path50.join(
33986
+ `commands/${path51.basename(commandFile, ".md")}`,
33987
+ path51.join(
33899
33988
  resolveTargetPath(paths.commands),
33900
- `${path50.basename(commandFile, ".md")}.md`
33989
+ `${path51.basename(commandFile, ".md")}.md`
33901
33990
  ),
33902
33991
  "opencode",
33903
33992
  computeSourceHash(commandFile),
@@ -33979,10 +34068,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33979
34068
  )) {
33980
34069
  rows.push(
33981
34070
  classifyCompiledFile(
33982
- `agents/${path50.basename(agentFile, ".md")}`,
33983
- path50.join(
34071
+ `agents/${path51.basename(agentFile, ".md")}`,
34072
+ path51.join(
33984
34073
  resolveTargetPath(paths.agents),
33985
- `${path50.basename(agentFile, ".md")}.md`
34074
+ `${path51.basename(agentFile, ".md")}.md`
33986
34075
  ),
33987
34076
  "cursor",
33988
34077
  computeSourceHash(agentFile),
@@ -33999,7 +34088,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
33999
34088
  rows.push(
34000
34089
  classifyCompiledFile(
34001
34090
  `rules/${ruleFile.name}`,
34002
- path50.join(resolveTargetPath(paths.rules), ruleFile.name),
34091
+ path51.join(resolveTargetPath(paths.rules), ruleFile.name),
34003
34092
  "cursor",
34004
34093
  void 0,
34005
34094
  config,
@@ -34013,11 +34102,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
34013
34102
  sourceRoot,
34014
34103
  config.source.commands
34015
34104
  )) {
34016
- const baseName = path50.basename(commandFile, ".md");
34105
+ const baseName = path51.basename(commandFile, ".md");
34017
34106
  rows.push(
34018
34107
  classifyCompiledFile(
34019
34108
  `commands/${baseName}`,
34020
- path50.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
34109
+ path51.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
34021
34110
  "cursor",
34022
34111
  computeSourceHash(commandFile),
34023
34112
  config,
@@ -34100,7 +34189,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
34100
34189
  rows.push(
34101
34190
  classifyCompiledFile(
34102
34191
  `rules/${ruleFile.name}`,
34103
- path50.join(resolveTargetPath(paths.rules), ruleFile.name),
34192
+ path51.join(resolveTargetPath(paths.rules), ruleFile.name),
34104
34193
  "cline",
34105
34194
  void 0,
34106
34195
  config,
@@ -34116,10 +34205,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
34116
34205
  )) {
34117
34206
  rows.push(
34118
34207
  classifyCompiledFile(
34119
- `commands/${path50.basename(commandFile, ".md")}`,
34120
- path50.join(
34208
+ `commands/${path51.basename(commandFile, ".md")}`,
34209
+ path51.join(
34121
34210
  resolveTargetPath(paths.workflows),
34122
- path50.basename(commandFile)
34211
+ path51.basename(commandFile)
34123
34212
  ),
34124
34213
  "cline",
34125
34214
  computeSourceHash(commandFile),
@@ -34160,7 +34249,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
34160
34249
  return rows;
34161
34250
  }
34162
34251
  function compileRulesFiles(config, sourceRoot, target, mappings) {
34163
- const rulesSource = path50.join(sourceRoot, config.source.rules);
34252
+ const rulesSource = path51.join(sourceRoot, config.source.rules);
34164
34253
  if (!fs49.existsSync(rulesSource)) {
34165
34254
  return [];
34166
34255
  }
@@ -34175,25 +34264,10 @@ function classifyDirectoryPresence(component, dirPath) {
34175
34264
  conformant: present
34176
34265
  };
34177
34266
  }
34178
- function slotsForScope2(scopeMap, scope, projectRoot) {
34179
- if (scope !== "project") {
34180
- return scopeMap?.global;
34181
- }
34182
- const projectSlots = scopeMap?.project;
34183
- if (!projectSlots) {
34184
- return void 0;
34185
- }
34186
- const root = projectRoot ?? process.cwd();
34187
- const resolved = {};
34188
- for (const [slot, value] of Object.entries(projectSlots)) {
34189
- resolved[slot] = typeof value === "string" ? path50.resolve(root, value) : value;
34190
- }
34191
- return resolved;
34192
- }
34193
34267
  function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
34194
34268
  const mappings = loadMappings(sourceRoot, config, configDir);
34195
34269
  const scopeMap = mappings.platformPaths.targets.codex;
34196
- const paths = slotsForScope2(scopeMap, scope, projectRoot);
34270
+ const paths = slotsForScope(scopeMap, scope, projectRoot);
34197
34271
  if (!paths?.instructions || !paths.agents || !paths.skills || !paths.hooks_shared_file || !paths.mcp_shared_file || !paths.rules) {
34198
34272
  throw new Error("platform-paths.yaml: incomplete codex path mapping");
34199
34273
  }
@@ -34206,7 +34280,7 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
34206
34280
  rules: paths.rules
34207
34281
  };
34208
34282
  const rules = compileRules(
34209
- path50.join(sourceRoot, config.source.rules),
34283
+ path51.join(sourceRoot, config.source.rules),
34210
34284
  "codex",
34211
34285
  mappings,
34212
34286
  createLossReport()
@@ -34217,10 +34291,10 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
34217
34291
  --- tangyr managed rules ---
34218
34292
  ${rules.agentsAppendix}`.trim();
34219
34293
  const agentFiles = ts(
34220
- path50.join(sourceRoot, config.source.agents, "*.md")
34294
+ path51.join(sourceRoot, config.source.agents, "*.md")
34221
34295
  ).sort();
34222
34296
  const hooksPresent = hooksSourceExists(sourceRoot, config);
34223
- const mcpSource = path50.join(sourceRoot, config.source.mcp);
34297
+ const mcpSource = path51.join(sourceRoot, config.source.mcp);
34224
34298
  const ruleRows = rules.dotRulesFiles.length === 0 ? [
34225
34299
  {
34226
34300
  component: "rules",
@@ -34231,7 +34305,7 @@ ${rules.agentsAppendix}`.trim();
34231
34305
  ] : rules.dotRulesFiles.map(
34232
34306
  (ruleFile) => classifyCompiledFile(
34233
34307
  `rules/${ruleFile.name}`,
34234
- path50.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
34308
+ path51.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
34235
34309
  "codex",
34236
34310
  void 0,
34237
34311
  config,
@@ -34239,20 +34313,27 @@ ${rules.agentsAppendix}`.trim();
34239
34313
  )
34240
34314
  );
34241
34315
  return [
34242
- classifyCompiledFile(
34243
- "instructions",
34316
+ // Through `classifyInstructions`, like every other target, because the
34317
+ // destination may be the shared project-root `AGENTS.md`. Asking
34318
+ // `classifyCompiledFile` directly compares the marker's target against
34319
+ // "codex", and on that file the marker names whoever wrote last — so any
34320
+ // run where another target wrote after codex reported drift on a file that
34321
+ // was exactly what the kit said it should be.
34322
+ classifyInstructions(
34244
34323
  resolveTargetPath(codexPaths.instructions),
34245
34324
  "codex",
34246
34325
  hashString6(composedInstructions),
34247
34326
  config,
34248
- sourceRoot
34327
+ sourceRoot,
34328
+ scope,
34329
+ projectRoot
34249
34330
  ),
34250
34331
  ...agentFiles.map(
34251
34332
  (agentFile) => classifyCompiledFile(
34252
- `agents/${path50.basename(agentFile, ".md")}`,
34253
- path50.join(
34333
+ `agents/${path51.basename(agentFile, ".md")}`,
34334
+ path51.join(
34254
34335
  resolveTargetPath(codexPaths.agents),
34255
- `${path50.basename(agentFile, ".md")}.toml`
34336
+ `${path51.basename(agentFile, ".md")}.toml`
34256
34337
  ),
34257
34338
  "codex",
34258
34339
  computeSourceHash(agentFile),
@@ -34334,7 +34415,7 @@ function classifyCodexHooksFile(filePath) {
34334
34415
  function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot) {
34335
34416
  const mappings = loadMappings(sourceRoot, config, configDir);
34336
34417
  const scopeMap = mappings.platformPaths.targets.copilot;
34337
- const paths = slotsForScope2(scopeMap, scope, projectRoot);
34418
+ const paths = slotsForScope(scopeMap, scope, projectRoot);
34338
34419
  if (!paths?.agents || !paths.skills || !paths.prompts || !paths.hooks || !paths.mcp_shared_file) {
34339
34420
  throw new Error("platform-paths.yaml: incomplete copilot path mapping");
34340
34421
  }
@@ -34346,20 +34427,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
34346
34427
  mcpSharedFile: paths.mcp_shared_file
34347
34428
  };
34348
34429
  const agentFiles = ts(
34349
- path50.join(sourceRoot, config.source.agents, "*.md")
34430
+ path51.join(sourceRoot, config.source.agents, "*.md")
34350
34431
  ).sort();
34351
34432
  const commandFiles = ts(
34352
- path50.join(sourceRoot, config.source.commands, "*.md")
34433
+ path51.join(sourceRoot, config.source.commands, "*.md")
34353
34434
  ).sort();
34354
34435
  const hooksPresent = hooksSourceExists(sourceRoot, config);
34355
- const mcpSource = path50.join(sourceRoot, config.source.mcp);
34436
+ const mcpSource = path51.join(sourceRoot, config.source.mcp);
34356
34437
  return [
34357
34438
  ...agentFiles.map(
34358
34439
  (agentFile) => classifyCompiledFile(
34359
- `agents/${path50.basename(agentFile, ".md")}`,
34360
- path50.join(
34440
+ `agents/${path51.basename(agentFile, ".md")}`,
34441
+ path51.join(
34361
34442
  resolveTargetPath(copilotPaths.agents),
34362
- `${path50.basename(agentFile, ".md")}.agent.md`
34443
+ `${path51.basename(agentFile, ".md")}.agent.md`
34363
34444
  ),
34364
34445
  "copilot",
34365
34446
  computeSourceHash(agentFile),
@@ -34376,10 +34457,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
34376
34457
  ),
34377
34458
  ...commandFiles.map(
34378
34459
  (commandFile) => classifyCompiledFile(
34379
- `commands/${path50.basename(commandFile, ".md")}`,
34380
- path50.join(
34460
+ `commands/${path51.basename(commandFile, ".md")}`,
34461
+ path51.join(
34381
34462
  resolveTargetPath(copilotPaths.prompts),
34382
- `${path50.basename(commandFile, ".md")}.prompt.md`
34463
+ `${path51.basename(commandFile, ".md")}.prompt.md`
34383
34464
  ),
34384
34465
  "copilot",
34385
34466
  computeSourceHash(commandFile),
@@ -34398,14 +34479,14 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
34398
34479
  sourceRoot
34399
34480
  ),
34400
34481
  hooksPresent ? classifyCompiledHooksByProvenance(
34401
- path50.join(
34482
+ path51.join(
34402
34483
  resolveTargetPath(copilotPaths.hooks),
34403
34484
  "tangyr-managed.json"
34404
34485
  ),
34405
34486
  "copilot"
34406
34487
  ) : notConfiguredRow(
34407
34488
  "hooks",
34408
- path50.join(
34489
+ path51.join(
34409
34490
  resolveTargetPath(copilotPaths.hooks),
34410
34491
  "tangyr-managed.json"
34411
34492
  )
@@ -34430,7 +34511,7 @@ function notConfiguredRow(component, filePath) {
34430
34511
  }
34431
34512
  function classifyDirectArtifact(artifact, config, sourceRoot) {
34432
34513
  const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
34433
- const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path50.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
34514
+ const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path51.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
34434
34515
  if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
34435
34516
  const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
34436
34517
  if (perSkill) {
@@ -34450,7 +34531,7 @@ function classifyDirectArtifact(artifact, config, sourceRoot) {
34450
34531
  conformant: false
34451
34532
  };
34452
34533
  }
34453
- if (artifactClass === "managed-compiled" && sourcePath && !isCompiledCurrent6(artifact.path, sourcePath)) {
34534
+ if (artifactClass === "managed-compiled" && !isCompiledCurrent6(artifact.path)) {
34454
34535
  return {
34455
34536
  component: artifact.component,
34456
34537
  className: "drift",
@@ -34542,7 +34623,7 @@ function classifyPerSkillSlot(slotPath, sourceRoot) {
34542
34623
  return null;
34543
34624
  }
34544
34625
  const ours = links.filter(
34545
- (entry) => isOurSymlink(path50.join(slotPath, entry.name), sourceRoot)
34626
+ (entry) => isOurSymlink(path51.join(slotPath, entry.name), sourceRoot)
34546
34627
  );
34547
34628
  if (ours.length === 0) {
34548
34629
  return null;
@@ -34554,9 +34635,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
34554
34635
  classifyHooks(settingsPath),
34555
34636
  classifySettings(
34556
34637
  settingsPath,
34557
- path50.resolve(sourceRoot, config.source.settings)
34638
+ path51.resolve(sourceRoot, config.source.settings)
34558
34639
  ),
34559
- classifyMcp(claudeJsonPath, path50.resolve(sourceRoot, config.source.mcp))
34640
+ classifyMcp(claudeJsonPath, path51.resolve(sourceRoot, config.source.mcp))
34560
34641
  ];
34561
34642
  }
34562
34643
  function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
@@ -34658,14 +34739,26 @@ function isSymlinkCurrent(linkPath, sourcePath) {
34658
34739
  return false;
34659
34740
  }
34660
34741
  }
34661
- function isCompiledCurrent6(filePath, sourcePath) {
34742
+ function isCompiledCurrent6(filePath) {
34662
34743
  try {
34663
- const marker = extractProvenanceMarker(fs49.readFileSync(filePath, "utf8"));
34664
- return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
34744
+ const content = fs49.readFileSync(filePath, "utf8");
34745
+ const marker = extractProvenanceMarker(content);
34746
+ if (!marker) {
34747
+ return false;
34748
+ }
34749
+ return marker.hash === hashString6(compiledBody(content));
34665
34750
  } catch {
34666
34751
  return false;
34667
34752
  }
34668
34753
  }
34754
+ function compiledBody(content) {
34755
+ const lines = content.split("\n");
34756
+ const first = lines.findIndex((line) => line.trim().length > 0);
34757
+ if (first >= 0 && extractProvenanceMarker(lines[first])) {
34758
+ return lines.slice(first + 1).join("\n").trim();
34759
+ }
34760
+ return content.trim();
34761
+ }
34669
34762
  function classifyCompiledFile(component, filePath, target, expectedHash, config, sourceRoot, expectedContent) {
34670
34763
  const artifactClass = classifyArtifact(filePath, config, sourceRoot);
34671
34764
  if (artifactClass !== "managed-compiled") {
@@ -34722,7 +34815,7 @@ function hashString6(value) {
34722
34815
 
34723
34816
  // src/commands/sync.ts
34724
34817
  import fs50 from "fs";
34725
- import path51 from "path";
34818
+ import path52 from "path";
34726
34819
 
34727
34820
  // node_modules/chalk/source/vendor/ansi-styles/index.js
34728
34821
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -35262,6 +35355,16 @@ async function runSyncCommand(options, logger) {
35262
35355
  const lossReport = createLossReport();
35263
35356
  const mappings = targets.includes("copilot") || targets.includes("codex") || targets.includes("opencode") || targets.includes("cursor") || targets.includes("cline") || targets.some((target) => isDeferredTarget(target)) ? loadMappings(sourceRoot, config, configDir) : void 0;
35264
35357
  const kitSync = kitInfo ? prepareKitManifest(syncOptions.scope, syncOptions.projectRoot, kitInfo) : void 0;
35358
+ const installedKit = kitSync?.manifest.kit;
35359
+ if (kitInfo && installedKit && installedKit.name !== kitInfo.name) {
35360
+ logger.error(
35361
+ `This scope holds the kit '${installedKit.name}' (${installedKit.version}), and the configuration names '${kitInfo.name}'.`
35362
+ );
35363
+ logger.error(
35364
+ `sync updates the installed kit; it does not replace it. Run \`tangyr install --replace\` to put '${kitInfo.name}' in its place, or check kitPath if you meant to update '${installedKit.name}'.`
35365
+ );
35366
+ process.exit(1);
35367
+ }
35265
35368
  if (kitInfo && kitSync && options.dryRun) {
35266
35369
  printManifestDiff(logger, kitInfo.name, kitSync.diff);
35267
35370
  }
@@ -35392,13 +35495,13 @@ async function runSyncCommand(options, logger) {
35392
35495
  reportHookRejections(
35393
35496
  lossReport,
35394
35497
  targets,
35395
- path51.resolve(kitInfo.path, "hooks"),
35498
+ path52.resolve(kitInfo.path, "hooks"),
35396
35499
  kitInfo.components.hooks.declared
35397
35500
  );
35398
35501
  const hooksConflict = reportHooksSourceConflict(
35399
35502
  lossReport,
35400
35503
  targets,
35401
- path51.resolve(kitInfo.path, "hooks"),
35504
+ path52.resolve(kitInfo.path, "hooks"),
35402
35505
  kitInfo.components.hooks.declared
35403
35506
  );
35404
35507
  if (hooksConflict) {
@@ -35430,7 +35533,11 @@ async function runSyncCommand(options, logger) {
35430
35533
  recordCoverageLoss(coverage, lossReport);
35431
35534
  }
35432
35535
  }
35433
- writeLossReport(options.lossReport, lossReport);
35536
+ writeLossReport(
35537
+ options.lossReport,
35538
+ lossReport,
35539
+ resolveScopePath(syncOptions.scope, syncOptions.projectRoot)
35540
+ );
35434
35541
  printOutcomeTable(results);
35435
35542
  if (kitInfo && kitSync && !options.dryRun) {
35436
35543
  cleanupRemovedManagedArtifacts(
@@ -35540,6 +35647,7 @@ function updateManifest(kitInfo, kitSync) {
35540
35647
  });
35541
35648
  }
35542
35649
  }
35650
+ kitSync.manifest.kit = { name: kitInfo.name, version: kitInfo.version };
35543
35651
  refreshArtifactStates(kitSync.manifest.artifacts);
35544
35652
  writeManifest(kitSync.scopePath, kitSync.manifest);
35545
35653
  }
@@ -35614,7 +35722,7 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
35614
35722
  }
35615
35723
  }
35616
35724
  function resolveKitFilePath(kitPath, relativePath) {
35617
- const fullPath = path51.join(kitPath, relativePath);
35725
+ const fullPath = path52.join(kitPath, relativePath);
35618
35726
  return fs50.existsSync(fullPath) ? fullPath : null;
35619
35727
  }
35620
35728
  function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
@@ -35622,11 +35730,16 @@ function cleanupRemovedManagedArtifacts(config, mappings, targets, options, remo
35622
35730
  return;
35623
35731
  }
35624
35732
  const currentComponent = options.component;
35625
- const copilotPaths = mappings.platformPaths.targets.copilot.global;
35626
- const codexPaths = mappings.platformPaths.targets.codex.global;
35627
- const opencodePaths = mappings.platformPaths.targets.opencode.global;
35628
- const cursorPaths = mappings.platformPaths.targets.cursor.global;
35629
- const clinePaths = mappings.platformPaths.targets.cline.global;
35733
+ const scopeOf = (target) => slotsForScope(
35734
+ mappings.platformPaths.targets[target],
35735
+ options.scope,
35736
+ options.projectRoot
35737
+ );
35738
+ const copilotPaths = scopeOf("copilot");
35739
+ const codexPaths = scopeOf("codex");
35740
+ const opencodePaths = scopeOf("opencode");
35741
+ const cursorPaths = scopeOf("cursor");
35742
+ const clinePaths = scopeOf("cline");
35630
35743
  for (const relativePath of removedSourcePaths) {
35631
35744
  const component = componentForRemovedSource(relativePath, config);
35632
35745
  if (currentComponent && component !== currentComponent) {
@@ -35678,9 +35791,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
35678
35791
  }
35679
35792
  if (relativePath.startsWith("agents/")) {
35680
35793
  removeManagedCompiledArtifact2(
35681
- path51.join(
35794
+ path52.join(
35682
35795
  resolveTargetPath(paths.agents ?? ""),
35683
- `${path51.parse(relativePath).name}.agent.md`
35796
+ `${path52.parse(relativePath).name}.agent.md`
35684
35797
  ),
35685
35798
  "copilot",
35686
35799
  relativePath,
@@ -35690,9 +35803,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
35690
35803
  }
35691
35804
  if (relativePath.startsWith("commands/")) {
35692
35805
  removeManagedCompiledArtifact2(
35693
- path51.join(
35806
+ path52.join(
35694
35807
  resolveTargetPath(paths.prompts ?? ""),
35695
- `${path51.parse(relativePath).name}.prompt.md`
35808
+ `${path52.parse(relativePath).name}.prompt.md`
35696
35809
  ),
35697
35810
  "copilot",
35698
35811
  relativePath,
@@ -35702,7 +35815,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
35702
35815
  }
35703
35816
  if (relativePath.endsWith("hooks.json")) {
35704
35817
  removeManagedCompiledArtifact2(
35705
- path51.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
35818
+ path52.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
35706
35819
  "copilot",
35707
35820
  relativePath,
35708
35821
  logger
@@ -35732,9 +35845,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
35732
35845
  }
35733
35846
  if (relativePath.startsWith("agents/")) {
35734
35847
  removeManagedCompiledArtifact2(
35735
- path51.join(
35848
+ path52.join(
35736
35849
  resolveTargetPath(paths.agents ?? ""),
35737
- `${path51.parse(relativePath).name}.toml`
35850
+ `${path52.parse(relativePath).name}.toml`
35738
35851
  ),
35739
35852
  "codex",
35740
35853
  relativePath,
@@ -35744,9 +35857,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
35744
35857
  }
35745
35858
  if (relativePath.startsWith("rules/")) {
35746
35859
  removeManagedCompiledArtifact2(
35747
- path51.join(
35860
+ path52.join(
35748
35861
  resolveTargetPath(paths.rules ?? ""),
35749
- `${path51.parse(relativePath).name}.rules`
35862
+ `${path52.parse(relativePath).name}.rules`
35750
35863
  ),
35751
35864
  "codex",
35752
35865
  relativePath,
@@ -35785,9 +35898,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
35785
35898
  }
35786
35899
  if (relativePath.startsWith("agents/")) {
35787
35900
  removeManagedCompiledArtifact2(
35788
- path51.join(
35901
+ path52.join(
35789
35902
  resolveTargetPath(paths.agents ?? ""),
35790
- `${path51.parse(relativePath).name}.md`
35903
+ `${path52.parse(relativePath).name}.md`
35791
35904
  ),
35792
35905
  "opencode",
35793
35906
  relativePath,
@@ -35797,9 +35910,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
35797
35910
  }
35798
35911
  if (relativePath.startsWith("commands/")) {
35799
35912
  removeManagedCompiledArtifact2(
35800
- path51.join(
35913
+ path52.join(
35801
35914
  resolveTargetPath(paths.commands ?? ""),
35802
- `${path51.parse(relativePath).name}.md`
35915
+ `${path52.parse(relativePath).name}.md`
35803
35916
  ),
35804
35917
  "opencode",
35805
35918
  relativePath,
@@ -35831,9 +35944,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35831
35944
  }
35832
35945
  if (relativePath.startsWith("agents/")) {
35833
35946
  removeManagedCompiledArtifact2(
35834
- path51.join(
35947
+ path52.join(
35835
35948
  resolveTargetPath(paths.agents ?? ""),
35836
- `${path51.parse(relativePath).name}.md`
35949
+ `${path52.parse(relativePath).name}.md`
35837
35950
  ),
35838
35951
  "cursor",
35839
35952
  relativePath,
@@ -35843,9 +35956,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35843
35956
  }
35844
35957
  if (relativePath.startsWith("rules/")) {
35845
35958
  removeManagedCompiledArtifact2(
35846
- path51.join(
35959
+ path52.join(
35847
35960
  resolveTargetPath(paths.rules ?? ""),
35848
- `${path51.parse(relativePath).name}.mdc`
35961
+ `${path52.parse(relativePath).name}.mdc`
35849
35962
  ),
35850
35963
  "cursor",
35851
35964
  relativePath,
@@ -35855,9 +35968,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
35855
35968
  }
35856
35969
  if (relativePath.startsWith("commands/")) {
35857
35970
  removeManagedCompiledArtifact2(
35858
- path51.join(
35971
+ path52.join(
35859
35972
  resolveTargetPath(paths.skills ?? ""),
35860
- path51.parse(relativePath).name,
35973
+ path52.parse(relativePath).name,
35861
35974
  "SKILL.md"
35862
35975
  ),
35863
35976
  "cursor",
@@ -35901,9 +36014,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35901
36014
  }
35902
36015
  if (relativePath.startsWith("rules/")) {
35903
36016
  removeManagedCompiledArtifact2(
35904
- path51.join(
36017
+ path52.join(
35905
36018
  resolveTargetPath(paths.rules ?? ""),
35906
- `${path51.parse(relativePath).name}.md`
36019
+ `${path52.parse(relativePath).name}.md`
35907
36020
  ),
35908
36021
  "cline",
35909
36022
  relativePath,
@@ -35913,9 +36026,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
35913
36026
  }
35914
36027
  if (relativePath.startsWith("commands/")) {
35915
36028
  removeManagedCompiledArtifact2(
35916
- path51.join(
36029
+ path52.join(
35917
36030
  resolveTargetPath(paths.workflows ?? ""),
35918
- path51.basename(relativePath)
36031
+ path52.basename(relativePath)
35919
36032
  ),
35920
36033
  "cline",
35921
36034
  relativePath,
@@ -36084,7 +36197,7 @@ function removeManagedHookEntries(value, expectedSource) {
36084
36197
 
36085
36198
  // src/commands/validate.ts
36086
36199
  import fs51 from "fs";
36087
- import path52 from "path";
36200
+ import path53 from "path";
36088
36201
  var SUPPORTED_KIT_FORMATS2 = [1];
36089
36202
  var SUPPORTED_DISCIPLINE_VERSIONS = [
36090
36203
  "0.14.0",
@@ -36199,11 +36312,11 @@ function checkArchetype(kit) {
36199
36312
  }
36200
36313
  function checkHookScriptsExist(kit) {
36201
36314
  const violations = [];
36202
- const hooksDir = path52.join(kit.path, "hooks");
36315
+ const hooksDir = path53.join(kit.path, "hooks");
36203
36316
  const missingSet = new Set(kit.components.hooks.missing);
36204
36317
  for (const name of kit.components.hooks.declared) {
36205
36318
  if (missingSet.has(name)) continue;
36206
- const declarationPath = path52.join(hooksDir, `${name}.md`);
36319
+ const declarationPath = path53.join(hooksDir, `${name}.md`);
36207
36320
  if (!fs51.existsSync(declarationPath)) continue;
36208
36321
  let data;
36209
36322
  try {
@@ -36214,7 +36327,7 @@ function checkHookScriptsExist(kit) {
36214
36327
  if (typeof data.command === "string" && data.command.trim().length > 0) {
36215
36328
  continue;
36216
36329
  }
36217
- const scriptPath = path52.join(hooksDir, "scripts", `${name}.ts`);
36330
+ const scriptPath = path53.join(hooksDir, "scripts", `${name}.ts`);
36218
36331
  if (!fs51.existsSync(scriptPath)) {
36219
36332
  violations.push({
36220
36333
  code: "hook-script-missing",
@@ -36228,7 +36341,7 @@ function checkHookScriptsExist(kit) {
36228
36341
  function checkOptionalSourceDocuments(kit) {
36229
36342
  const violations = [];
36230
36343
  for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
36231
- const filePath = path52.join(kit.path, name);
36344
+ const filePath = path53.join(kit.path, name);
36232
36345
  if (!fs51.existsSync(filePath)) continue;
36233
36346
  try {
36234
36347
  const parsed = JSON.parse(fs51.readFileSync(filePath, "utf8"));
@@ -36253,7 +36366,7 @@ function checkSkillSubfolderNames(kit) {
36253
36366
  const notices = [];
36254
36367
  const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
36255
36368
  for (const name of kit.components.skills.declared) {
36256
- const skillDir = path52.join(kit.path, "skills", name);
36369
+ const skillDir = path53.join(kit.path, "skills", name);
36257
36370
  let entries;
36258
36371
  try {
36259
36372
  entries = fs51.readdirSync(skillDir, { withFileTypes: true });
@@ -36274,7 +36387,7 @@ function checkSkillSubfolderNames(kit) {
36274
36387
  return notices;
36275
36388
  }
36276
36389
  function checkHooksSourceForm(kit) {
36277
- const hooksDir = path52.join(kit.path, "hooks");
36390
+ const hooksDir = path53.join(kit.path, "hooks");
36278
36391
  const message = describeHooksSourceConflict(
36279
36392
  hooksDir,
36280
36393
  kit.components.hooks.declared
@@ -36286,12 +36399,12 @@ function checkHooksSourceForm(kit) {
36286
36399
  } : null;
36287
36400
  }
36288
36401
  function checkHookDeclarations(kit) {
36289
- const hooksDir = path52.join(kit.path, "hooks");
36402
+ const hooksDir = path53.join(kit.path, "hooks");
36290
36403
  return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
36291
36404
  (r) => ({
36292
36405
  code: "hook-declaration-invalid",
36293
- location: `hooks/${path52.basename(r.file)}`,
36294
- message: `hooks: '${path52.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.`
36406
+ location: `hooks/${path53.basename(r.file)}`,
36407
+ message: `hooks: '${path53.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.`
36295
36408
  })
36296
36409
  );
36297
36410
  }
@@ -36311,11 +36424,11 @@ function checkKitFormatSupported(kit) {
36311
36424
  function checkEntrypointExists(kit) {
36312
36425
  const declared = kit.entrypoint;
36313
36426
  const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
36314
- const entrypointPath = path52.join(kit.path, entrypoint);
36427
+ const entrypointPath = path53.join(kit.path, entrypoint);
36315
36428
  if (fs51.existsSync(entrypointPath)) {
36316
36429
  return null;
36317
36430
  }
36318
- const legacyPresent = declared === void 0 && fs51.existsSync(path52.join(kit.path, LEGACY_ENTRYPOINT));
36431
+ const legacyPresent = declared === void 0 && fs51.existsSync(path53.join(kit.path, LEGACY_ENTRYPOINT));
36319
36432
  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.`;
36320
36433
  return {
36321
36434
  code: "entrypoint-missing",
@@ -36374,9 +36487,9 @@ function checkComponentFrontmatter(kit) {
36374
36487
  const missingSet = new Set(kit.components[cat].missing);
36375
36488
  for (const name of kit.components[cat].declared) {
36376
36489
  if (missingSet.has(name)) continue;
36377
- const filePath = cat === "skills" ? path52.join(kit.path, cat, name, "SKILL.md") : path52.join(kit.path, cat, `${name}.md`);
36490
+ const filePath = cat === "skills" ? path53.join(kit.path, cat, name, "SKILL.md") : path53.join(kit.path, cat, `${name}.md`);
36378
36491
  if (!fs51.existsSync(filePath)) continue;
36379
- const relPath = path52.relative(kit.path, filePath);
36492
+ const relPath = path53.relative(kit.path, filePath);
36380
36493
  try {
36381
36494
  const { data } = parseMarkdownFrontmatter(filePath);
36382
36495
  for (const field of requiredFields) {
@@ -36421,7 +36534,7 @@ function checkHumanOnlyCommandInvocation(kit) {
36421
36534
  const missingSet = new Set(kit.components.commands.missing);
36422
36535
  for (const name of kit.components.commands.declared) {
36423
36536
  if (missingSet.has(name)) continue;
36424
- const filePath = path52.join(kit.path, "commands", `${name}.md`);
36537
+ const filePath = path53.join(kit.path, "commands", `${name}.md`);
36425
36538
  if (!fs51.existsSync(filePath)) continue;
36426
36539
  let data;
36427
36540
  try {
@@ -36435,7 +36548,7 @@ function checkHumanOnlyCommandInvocation(kit) {
36435
36548
  if (!barred) {
36436
36549
  violations.push({
36437
36550
  code: "command-human-only-model-invocable",
36438
- location: path52.relative(kit.path, filePath),
36551
+ location: path53.relative(kit.path, filePath),
36439
36552
  message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
36440
36553
  });
36441
36554
  }
@@ -36445,7 +36558,7 @@ function checkHumanOnlyCommandInvocation(kit) {
36445
36558
 
36446
36559
  // src/commands/verify.ts
36447
36560
  import fs52 from "fs";
36448
- import path53 from "path";
36561
+ import path54 from "path";
36449
36562
  function runVerifyCommand(options, logger) {
36450
36563
  if (options.target && !isKnownTarget(options.target)) {
36451
36564
  throwUnrecognizedTarget(options.target);
@@ -36626,7 +36739,7 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
36626
36739
  if (!slotPath) {
36627
36740
  continue;
36628
36741
  }
36629
- const fullPath = subPath ? path53.join(slotPath, subPath) : slotPath;
36742
+ const fullPath = subPath ? path54.join(slotPath, subPath) : slotPath;
36630
36743
  if (!fs52.existsSync(fullPath)) {
36631
36744
  failures.push(
36632
36745
  `claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
@@ -36760,7 +36873,10 @@ function buildProgram() {
36760
36873
  ).option(
36761
36874
  "--json",
36762
36875
  `Emit {"degraded": true} on stderr only when this resolution fell back to a warm cache after a network failure; otherwise this flag has no effect and output is unchanged \u2014 unlike --json on other commands, which always replaces the command's entire output.`
36763
- ).option("--tools <list>", "Comma-separated list of target tools").option("--loss-report <path>", "Write semantic loss report JSON to a file").option("--scope <scope>", "Installation scope: global or project").option(
36876
+ ).option("--tools <list>", "Comma-separated list of target tools").option("--loss-report <path>", "Write semantic loss report JSON to a file").option(
36877
+ "--replace",
36878
+ "Install this kit over a different one already in this scope, uninstalling that one first"
36879
+ ).option("--scope <scope>", "Installation scope: global or project").option(
36764
36880
  "--ignore-errors",
36765
36881
  "Suppress exit code 3 when error-severity loss entries are present"
36766
36882
  ).action(