@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/README.md +37 -17
- package/dist/index.js +740 -624
- package/mappings/loss-severity.yaml +5 -0
- package/package.json +2 -2
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
|
|
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 =
|
|
2388
|
+
const localBin = path55.resolve(baseDir, baseName);
|
|
2389
2389
|
if (fs53.existsSync(localBin)) return localBin;
|
|
2390
|
-
if (sourceExt.includes(
|
|
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 =
|
|
2409
|
-
|
|
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 =
|
|
2416
|
+
const legacyName = path55.basename(
|
|
2417
2417
|
this._scriptPath,
|
|
2418
|
-
|
|
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(
|
|
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 =
|
|
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(
|
|
3359
|
-
if (
|
|
3360
|
-
this._executableDir =
|
|
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,
|
|
3717
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
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,
|
|
3720
|
-
return visit_(key, ctrl, visitor,
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
3738
|
-
const ck = visit_("key", node.key, visitor,
|
|
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,
|
|
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,
|
|
3765
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
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,
|
|
3768
|
-
return visitAsync_(key, ctrl, visitor,
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
3786
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
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,
|
|
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,
|
|
3818
|
+
function callVisitor(key, node, visitor, path55) {
|
|
3819
3819
|
if (typeof visitor === "function")
|
|
3820
|
-
return visitor(key, node,
|
|
3820
|
+
return visitor(key, node, path55);
|
|
3821
3821
|
if (identity.isMap(node))
|
|
3822
|
-
return visitor.Map?.(key, node,
|
|
3822
|
+
return visitor.Map?.(key, node, path55);
|
|
3823
3823
|
if (identity.isSeq(node))
|
|
3824
|
-
return visitor.Seq?.(key, node,
|
|
3824
|
+
return visitor.Seq?.(key, node, path55);
|
|
3825
3825
|
if (identity.isPair(node))
|
|
3826
|
-
return visitor.Pair?.(key, node,
|
|
3826
|
+
return visitor.Pair?.(key, node, path55);
|
|
3827
3827
|
if (identity.isScalar(node))
|
|
3828
|
-
return visitor.Scalar?.(key, node,
|
|
3828
|
+
return visitor.Scalar?.(key, node, path55);
|
|
3829
3829
|
if (identity.isAlias(node))
|
|
3830
|
-
return visitor.Alias?.(key, node,
|
|
3830
|
+
return visitor.Alias?.(key, node, path55);
|
|
3831
3831
|
return void 0;
|
|
3832
3832
|
}
|
|
3833
|
-
function replaceNode(key,
|
|
3834
|
-
const parent =
|
|
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,
|
|
4442
|
+
function collectionFromPath(schema, path55, value) {
|
|
4443
4443
|
let v2 = value;
|
|
4444
|
-
for (let i =
|
|
4445
|
-
const k2 =
|
|
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 = (
|
|
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(
|
|
4495
|
-
if (isEmptyPath(
|
|
4494
|
+
addIn(path55, value) {
|
|
4495
|
+
if (isEmptyPath(path55))
|
|
4496
4496
|
this.add(value);
|
|
4497
4497
|
else {
|
|
4498
|
-
const [key, ...rest] =
|
|
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(
|
|
4513
|
-
const [key, ...rest] =
|
|
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(
|
|
4528
|
-
const [key, ...rest] =
|
|
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(
|
|
4547
|
-
const [key, ...rest] =
|
|
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(
|
|
4558
|
-
const [key, ...rest] =
|
|
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(
|
|
7070
|
+
addIn(path55, value) {
|
|
7071
7071
|
if (assertCollection(this.contents))
|
|
7072
|
-
this.contents.addIn(
|
|
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(
|
|
7148
|
-
if (Collection.isEmptyPath(
|
|
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(
|
|
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(
|
|
7170
|
-
if (Collection.isEmptyPath(
|
|
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(
|
|
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(
|
|
7184
|
-
if (Collection.isEmptyPath(
|
|
7183
|
+
hasIn(path55) {
|
|
7184
|
+
if (Collection.isEmptyPath(path55))
|
|
7185
7185
|
return this.contents !== void 0;
|
|
7186
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
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(
|
|
7204
|
-
if (Collection.isEmptyPath(
|
|
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(
|
|
7207
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path55), value);
|
|
7208
7208
|
} else if (assertCollection(this.contents)) {
|
|
7209
|
-
this.contents.setIn(
|
|
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,
|
|
9166
|
+
visit.itemAtPath = (cst, path55) => {
|
|
9167
9167
|
let item = cst;
|
|
9168
|
-
for (const [field, index] of
|
|
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,
|
|
9178
|
-
const parent = visit.itemAtPath(cst,
|
|
9179
|
-
const field =
|
|
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(
|
|
9186
|
-
let ctrl = visitor(item,
|
|
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(
|
|
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,
|
|
9204
|
+
ctrl = ctrl(item, path55);
|
|
9205
9205
|
}
|
|
9206
9206
|
}
|
|
9207
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
21714
|
-
|
|
21715
|
-
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 =
|
|
21954
|
+
const name = path21.basename(rejection.file, ".md");
|
|
21926
21955
|
for (const target of targets) {
|
|
21927
21956
|
addLoss(report, target, "hooks", {
|
|
21928
|
-
source: `hooks/${
|
|
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(
|
|
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 =
|
|
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 :
|
|
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: `${
|
|
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
|
|
22085
|
+
import path24 from "path";
|
|
22057
22086
|
|
|
22058
22087
|
// src/utils/fs.ts
|
|
22059
22088
|
import fs23 from "fs";
|
|
22060
|
-
import
|
|
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 =
|
|
22066
|
-
const relative =
|
|
22067
|
-
realPathOrInput(
|
|
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(
|
|
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
|
|
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 =
|
|
22198
|
-
return
|
|
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
|
|
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 =
|
|
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 ===
|
|
22252
|
+
if (resolved === path23.resolve(profiles.codex.hook_scripts)) {
|
|
22224
22253
|
return SHARED_HOOK_SCRIPTS_KEY;
|
|
22225
22254
|
}
|
|
22226
|
-
const skillsRoot =
|
|
22227
|
-
if (resolved.startsWith(`${skillsRoot}${
|
|
22228
|
-
const inside =
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 ?
|
|
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
|
|
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
|
|
22851
|
+
return path26.join(copilotPaths.agents, component.slice("agents/".length));
|
|
22818
22852
|
}
|
|
22819
22853
|
if (component.startsWith("prompts/")) {
|
|
22820
|
-
return
|
|
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
|
|
22860
|
+
return path26.join(copilotPaths.hooks, component.slice("hooks/".length));
|
|
22827
22861
|
}
|
|
22828
|
-
if (component ===
|
|
22862
|
+
if (component === path26.basename(copilotPaths.mcpSharedFile)) {
|
|
22829
22863
|
return copilotPaths.mcpSharedFile;
|
|
22830
22864
|
}
|
|
22831
|
-
if (copilotPaths.instructions !== null && component ===
|
|
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
|
|
22879
|
+
return path26.join(codexPaths.agents, component.slice("agents/".length));
|
|
22846
22880
|
}
|
|
22847
22881
|
if (component.startsWith("rules/")) {
|
|
22848
|
-
return
|
|
22882
|
+
return path26.join(codexPaths.rules, component.slice("rules/".length));
|
|
22849
22883
|
}
|
|
22850
|
-
if (component ===
|
|
22884
|
+
if (component === path26.basename(codexPaths.hooksSharedFile)) {
|
|
22851
22885
|
return codexPaths.hooksSharedFile;
|
|
22852
22886
|
}
|
|
22853
|
-
if (component ===
|
|
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
|
|
22904
|
+
return path26.join(opencodePaths.agents, component.slice("agents/".length));
|
|
22871
22905
|
}
|
|
22872
22906
|
if (component.startsWith("commands/")) {
|
|
22873
|
-
return
|
|
22907
|
+
return path26.join(
|
|
22874
22908
|
opencodePaths.commands,
|
|
22875
22909
|
component.slice("commands/".length)
|
|
22876
22910
|
);
|
|
22877
22911
|
}
|
|
22878
|
-
if (component ===
|
|
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
|
|
22938
|
+
return path26.join(cursorPaths.agents, component.slice("agents/".length));
|
|
22905
22939
|
}
|
|
22906
22940
|
if (component.startsWith("rules/")) {
|
|
22907
|
-
return
|
|
22941
|
+
return path26.join(cursorPaths.rules, component.slice("rules/".length));
|
|
22908
22942
|
}
|
|
22909
22943
|
if (component.startsWith("skills/")) {
|
|
22910
|
-
return
|
|
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
|
|
22960
|
+
return path26.join(clinePaths.rules, component.slice("rules/".length));
|
|
22927
22961
|
}
|
|
22928
22962
|
if (component.startsWith("workflows/")) {
|
|
22929
|
-
return
|
|
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:
|
|
22964
|
-
agents:
|
|
22965
|
-
skills:
|
|
22966
|
-
commands:
|
|
22967
|
-
rules:
|
|
22968
|
-
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:
|
|
22974
|
-
agents:
|
|
22975
|
-
skills:
|
|
22976
|
-
commands:
|
|
22977
|
-
rules:
|
|
22978
|
-
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 [
|
|
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 [
|
|
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) =>
|
|
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(
|
|
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 =
|
|
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 ?
|
|
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 ?
|
|
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 =
|
|
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 ?
|
|
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
|
|
23132
|
+
return path26.join(root, relative);
|
|
23099
23133
|
}
|
|
23100
|
-
return
|
|
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 =
|
|
23173
|
-
let current =
|
|
23174
|
-
while (current !== boundary && current.startsWith(`${boundary}${
|
|
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 =
|
|
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(
|
|
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 =
|
|
23258
|
+
const resolved = path26.resolve(artifactPath);
|
|
23225
23259
|
return records.find(
|
|
23226
|
-
(record) =>
|
|
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 =
|
|
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(
|
|
23347
|
-
...ts(
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
23477
|
+
path26.join(copilotPaths.agents, "*.agent.md"),
|
|
23444
23478
|
"copilot",
|
|
23445
23479
|
"copilot agent residue"
|
|
23446
23480
|
);
|
|
23447
23481
|
addCompiledGlobPlans(
|
|
23448
23482
|
artifacts,
|
|
23449
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
23573
|
+
path26.join(codexPaths.agents, "*.toml"),
|
|
23540
23574
|
"codex",
|
|
23541
23575
|
"codex agent residue"
|
|
23542
23576
|
);
|
|
23543
23577
|
addCompiledGlobPlans(
|
|
23544
23578
|
artifacts,
|
|
23545
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
23654
|
+
path26.join(opencodePaths.agents, "*.md"),
|
|
23621
23655
|
"opencode",
|
|
23622
23656
|
"opencode agent residue"
|
|
23623
23657
|
);
|
|
23624
23658
|
addCompiledGlobPlans(
|
|
23625
23659
|
artifacts,
|
|
23626
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
23743
|
+
path26.join(cursorPaths.agents, "*.md"),
|
|
23710
23744
|
"cursor",
|
|
23711
23745
|
"cursor agent residue"
|
|
23712
23746
|
);
|
|
23713
23747
|
addCompiledGlobPlans(
|
|
23714
23748
|
artifacts,
|
|
23715
|
-
|
|
23749
|
+
path26.join(cursorPaths.rules, "*.mdc"),
|
|
23716
23750
|
"cursor",
|
|
23717
23751
|
"cursor rule residue"
|
|
23718
23752
|
);
|
|
23719
23753
|
addCompiledGlobPlans(
|
|
23720
23754
|
artifacts,
|
|
23721
|
-
|
|
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:
|
|
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
|
-
|
|
23806
|
+
path26.join(clinePaths.rules, "*.md"),
|
|
23773
23807
|
"cline",
|
|
23774
23808
|
"cline rule residue"
|
|
23775
23809
|
);
|
|
23776
23810
|
addCompiledGlobPlans(
|
|
23777
23811
|
artifacts,
|
|
23778
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
24151
|
-
agents:
|
|
24152
|
-
prompts:
|
|
24153
|
-
skills:
|
|
24154
|
-
hooks:
|
|
24155
|
-
mcpSharedFile:
|
|
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:
|
|
24196
|
-
agents:
|
|
24197
|
-
rules:
|
|
24198
|
-
skills:
|
|
24199
|
-
hooksSharedFile:
|
|
24200
|
-
mcpSharedFile:
|
|
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
|
|
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
|
|
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 &&
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 ?
|
|
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([
|
|
25378
|
+
/* @__PURE__ */ new Set([path29.resolve(artifact.path)]),
|
|
25345
25379
|
config
|
|
25346
25380
|
)) {
|
|
25347
25381
|
fs31.unlinkSync(artifact.path);
|
|
25348
|
-
ensureDir(
|
|
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(
|
|
25363
|
-
ensureDir(
|
|
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
|
|
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" ?
|
|
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 =
|
|
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") ||
|
|
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 =
|
|
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") ||
|
|
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
|
|
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(
|
|
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) =>
|
|
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 =
|
|
25489
|
-
|
|
25490
|
-
|
|
25522
|
+
const relative = path29.relative(
|
|
25523
|
+
path29.resolve(stopAt),
|
|
25524
|
+
path29.resolve(targetPath)
|
|
25491
25525
|
);
|
|
25492
|
-
if (relative.startsWith("..") ||
|
|
25526
|
+
if (relative.startsWith("..") || path29.isAbsolute(relative)) {
|
|
25493
25527
|
return false;
|
|
25494
25528
|
}
|
|
25495
|
-
return relative.split(
|
|
25496
|
-
const candidate =
|
|
25497
|
-
|
|
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 =
|
|
25509
|
-
return relative.length === 0 || !relative.startsWith("..") && !
|
|
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
|
|
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:
|
|
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(
|
|
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 =
|
|
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
|
|
25645
|
+
import path48 from "path";
|
|
25612
25646
|
|
|
25613
25647
|
// src/core/channel-state.ts
|
|
25614
25648
|
import fs33 from "fs";
|
|
25615
|
-
import
|
|
25649
|
+
import path31 from "path";
|
|
25616
25650
|
var CHANNEL_STATE_FILENAME = ".tangyr-channels.json";
|
|
25617
25651
|
function stateFilePath(cacheRoot) {
|
|
25618
|
-
return
|
|
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(
|
|
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
|
|
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 (
|
|
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 =
|
|
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 +
|
|
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(
|
|
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
|
|
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 =
|
|
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",
|
|
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
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
|
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
|
|
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 ${
|
|
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 =
|
|
26966
|
+
const skillDestination = path35.join(destination, name);
|
|
26933
26967
|
logger.info(
|
|
26934
|
-
`[dry-run] skills: symlink ${
|
|
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 =
|
|
26962
|
-
const skillDestination =
|
|
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 =
|
|
26994
|
-
const to =
|
|
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
|
|
27070
|
+
import path36 from "path";
|
|
27037
27071
|
function hookScriptsDir(bridge, target, projectRoot) {
|
|
27038
27072
|
const globalBridge = resolveTargetPath("~/.agents/hooks");
|
|
27039
|
-
if (
|
|
27073
|
+
if (path36.resolve(bridge) === path36.resolve(globalBridge)) {
|
|
27040
27074
|
return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
|
|
27041
27075
|
}
|
|
27042
|
-
const relative =
|
|
27043
|
-
const insideProject = !relative.startsWith("..") && !
|
|
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 =
|
|
27047
|
-
relative.split(
|
|
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:
|
|
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
|
|
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
|
-
`${
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 :
|
|
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:
|
|
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 =
|
|
27348
|
+
const agentsDir = path38.join(sourceRoot, config.source.agents);
|
|
27315
27349
|
if (!fs39.existsSync(agentsDir)) return;
|
|
27316
|
-
for (const agentFile of ts(
|
|
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 =
|
|
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(
|
|
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) :
|
|
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(
|
|
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:
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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/${
|
|
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/${
|
|
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
|
-
`${
|
|
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: `${
|
|
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
|
-
`${
|
|
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: `${
|
|
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: `${
|
|
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: `${
|
|
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
|
-
|
|
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: `${
|
|
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/${
|
|
28015
|
+
`agents/${path39.basename(sourceFile)}`,
|
|
27975
28016
|
"info",
|
|
27976
|
-
`${
|
|
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: `${
|
|
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
|
|
28478
|
+
import path40 from "path";
|
|
28417
28479
|
var CARRIED_OVER = ["argument-hint", "agent", "launch"];
|
|
28418
28480
|
function compileCommandAsSkill(commandFile, target) {
|
|
28419
|
-
const name =
|
|
28481
|
+
const name = path40.basename(commandFile, ".md");
|
|
28420
28482
|
const { data, body } = parseMarkdownFrontmatter(commandFile);
|
|
28421
|
-
const relativeSource = `commands/${
|
|
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(
|
|
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
|
|
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(
|
|
28814
|
+
for (const ruleFile of ts(path41.join(sourceRulesDir, "*.md")).sort()) {
|
|
28753
28815
|
const parsed = parseRule(ruleFile);
|
|
28754
|
-
const name =
|
|
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/${
|
|
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/${
|
|
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: `${
|
|
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(
|
|
28871
|
+
for (const ruleFile of ts(path41.join(sourceRulesDir, "*.md")).sort()) {
|
|
28810
28872
|
const parsed = parseRule(ruleFile);
|
|
28811
|
-
const name =
|
|
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/${
|
|
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: `${
|
|
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(
|
|
28897
|
+
for (const ruleFile of ts(path41.join(sourceRulesDir, "*.md")).sort()) {
|
|
28836
28898
|
const content = fs41.readFileSync(ruleFile, "utf8");
|
|
28837
|
-
const name =
|
|
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/${
|
|
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(
|
|
28944
|
+
for (const ruleFile of ts(path41.join(sourceRulesDir, "*.md")).sort()) {
|
|
28883
28945
|
const content = fs41.readFileSync(ruleFile, "utf8");
|
|
28884
|
-
const name =
|
|
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/${
|
|
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/${
|
|
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: `${
|
|
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(
|
|
28942
|
-
const name =
|
|
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/${
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
29231
|
+
const agentsDir = path42.join(sourceRoot, config.source.agents);
|
|
29170
29232
|
if (!fs42.existsSync(agentsDir)) return "";
|
|
29171
|
-
const agentFiles = ts(
|
|
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 =
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
29421
|
+
const destination = path42.join(
|
|
29360
29422
|
agentsRoot,
|
|
29361
|
-
`${
|
|
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(
|
|
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(
|
|
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
|
|
29663
|
+
import path44 from "path";
|
|
29602
29664
|
|
|
29603
29665
|
// src/compiler/commands.ts
|
|
29604
29666
|
var import_yaml11 = __toESM(require_dist(), 1);
|
|
29605
|
-
import
|
|
29667
|
+
import path43 from "path";
|
|
29606
29668
|
function compileCommandPrompt(sourceFile) {
|
|
29607
29669
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
29608
|
-
const relativeSource = `commands/${
|
|
29609
|
-
const fields = promptFrontmatter(data,
|
|
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:
|
|
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 =
|
|
29893
|
+
const agentsDir = path44.join(sourceRoot, config.source.agents);
|
|
29832
29894
|
if (!fs43.existsSync(agentsDir)) return;
|
|
29833
|
-
for (const agentFile of ts(
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
29878
|
-
const mirrorDest =
|
|
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(
|
|
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:
|
|
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 =
|
|
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(
|
|
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 =
|
|
30033
|
+
const destination = path44.join(
|
|
29972
30034
|
agentsRoot,
|
|
29973
|
-
`${
|
|
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 =
|
|
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(
|
|
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 =
|
|
30070
|
+
const destination = path44.join(
|
|
30009
30071
|
promptsRoot,
|
|
30010
|
-
`${
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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/${
|
|
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 ${
|
|
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 =
|
|
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(
|
|
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 =
|
|
30586
|
+
const destination = path45.join(
|
|
30525
30587
|
agentsRoot,
|
|
30526
|
-
`${
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
30606
|
-
const destination =
|
|
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:
|
|
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(
|
|
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 =
|
|
30810
|
+
const agentsDir = path45.join(sourceRoot, config.source.agents);
|
|
30749
30811
|
if (!fs44.existsSync(agentsDir)) return;
|
|
30750
|
-
for (const agentFile of ts(
|
|
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/${
|
|
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: `${
|
|
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(
|
|
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
|
|
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:
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
31073
|
-
const destination =
|
|
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/${
|
|
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:
|
|
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 =
|
|
31254
|
+
const agentsDir = path46.join(sourceRoot, config.source.agents);
|
|
31193
31255
|
if (!fs45.existsSync(agentsDir)) return;
|
|
31194
|
-
for (const agentFile of ts(
|
|
31256
|
+
for (const agentFile of ts(path46.join(agentsDir, "*.md")).sort()) {
|
|
31195
31257
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
31196
|
-
const relativeSource = `agents/${
|
|
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: `${
|
|
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: `${
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
31548
|
+
const configDir = path47.dirname(resolveTargetPath(paths.config_doc));
|
|
31487
31549
|
const instructions = resolveTargetPath(paths.instructions);
|
|
31488
|
-
const relative =
|
|
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(
|
|
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(
|
|
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 =
|
|
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(
|
|
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 =
|
|
31596
|
+
const destination = path47.join(
|
|
31535
31597
|
agentsRoot,
|
|
31536
|
-
`${
|
|
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 =
|
|
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(
|
|
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/${
|
|
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 =
|
|
31696
|
+
const destination = path47.join(
|
|
31635
31697
|
commandsRoot,
|
|
31636
|
-
`${
|
|
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:
|
|
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(
|
|
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(
|
|
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 ?
|
|
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.
|
|
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 =
|
|
32042
|
-
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") &&
|
|
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 ?
|
|
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 ${
|
|
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 ${
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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:${
|
|
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 =
|
|
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}${
|
|
33057
|
-
return `cline/workflows/${
|
|
33145
|
+
if (outcome.path.startsWith(`${workflowsRoot}${path48.sep}`)) {
|
|
33146
|
+
return `cline/workflows/${path48.basename(outcome.path)}`;
|
|
33058
33147
|
}
|
|
33059
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
33060
|
-
return `cline/rules/${
|
|
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}${
|
|
33097
|
-
return `cursor/agents/${
|
|
33185
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path48.sep}`)) {
|
|
33186
|
+
return `cursor/agents/${path48.basename(outcome.path)}`;
|
|
33098
33187
|
}
|
|
33099
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
33100
|
-
return `cursor/rules/${
|
|
33188
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path48.sep}`)) {
|
|
33189
|
+
return `cursor/rules/${path48.basename(outcome.path)}`;
|
|
33101
33190
|
}
|
|
33102
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
33103
|
-
const rel =
|
|
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}${
|
|
33130
|
-
return `opencode/agents/${
|
|
33218
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path48.sep}`)) {
|
|
33219
|
+
return `opencode/agents/${path48.basename(outcome.path)}`;
|
|
33131
33220
|
}
|
|
33132
|
-
if (outcome.path.startsWith(`${commandsRoot}${
|
|
33133
|
-
return `opencode/commands/${
|
|
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/${
|
|
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)}${
|
|
33154
|
-
return `copilot/rules/${
|
|
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}${
|
|
33157
|
-
return `copilot/skills/${
|
|
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/${
|
|
33252
|
+
return `copilot/${path48.basename(outcome.path)}`;
|
|
33164
33253
|
}
|
|
33165
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
33166
|
-
return `copilot/agents/${
|
|
33254
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path48.sep}`)) {
|
|
33255
|
+
return `copilot/agents/${path48.basename(outcome.path)}`;
|
|
33167
33256
|
}
|
|
33168
|
-
if (outcome.path.startsWith(`${promptsRoot}${
|
|
33169
|
-
return `copilot/prompts/${
|
|
33257
|
+
if (outcome.path.startsWith(`${promptsRoot}${path48.sep}`)) {
|
|
33258
|
+
return `copilot/prompts/${path48.basename(outcome.path)}`;
|
|
33170
33259
|
}
|
|
33171
|
-
if (outcome.path.startsWith(`${hooksRoot}${
|
|
33172
|
-
return `copilot/hooks/${
|
|
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/${
|
|
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}${
|
|
33193
|
-
return `codex/agents/${
|
|
33281
|
+
if (outcome.path.startsWith(`${agentsRoot}${path48.sep}`)) {
|
|
33282
|
+
return `codex/agents/${path48.basename(outcome.path)}`;
|
|
33194
33283
|
}
|
|
33195
|
-
if (outcome.path.startsWith(`${rulesRoot}${
|
|
33196
|
-
return `codex/rules/${
|
|
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/${
|
|
33288
|
+
return `codex/${path48.basename(outcome.path)}`;
|
|
33200
33289
|
}
|
|
33201
33290
|
if (outcome.path === mcpFile) {
|
|
33202
|
-
return `codex/${
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 ?
|
|
33329
|
-
files.set(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}${
|
|
33451
|
+
if (!outcomePath.startsWith(`${root}${path48.sep}`)) {
|
|
33363
33452
|
continue;
|
|
33364
33453
|
}
|
|
33365
|
-
const inside =
|
|
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
|
|
33499
|
+
import path49 from "path";
|
|
33411
33500
|
function runListCommand(options, logger) {
|
|
33412
33501
|
let searchPaths = [];
|
|
33413
|
-
let directKitPath = options.kitPath ?
|
|
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
|
-
|
|
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) =>
|
|
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
|
|
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" ?
|
|
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
|
|
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 =
|
|
33790
|
+
const root = path51.join(sourceRoot, componentPath);
|
|
33702
33791
|
if (!fs49.existsSync(root)) {
|
|
33703
33792
|
return [];
|
|
33704
33793
|
}
|
|
33705
|
-
return ts(
|
|
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
|
-
|
|
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/${
|
|
33880
|
-
|
|
33968
|
+
`agents/${path51.basename(agentFile, ".md")}`,
|
|
33969
|
+
path51.join(
|
|
33881
33970
|
resolveTargetPath(paths.agents),
|
|
33882
|
-
`${
|
|
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/${
|
|
33898
|
-
|
|
33986
|
+
`commands/${path51.basename(commandFile, ".md")}`,
|
|
33987
|
+
path51.join(
|
|
33899
33988
|
resolveTargetPath(paths.commands),
|
|
33900
|
-
`${
|
|
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/${
|
|
33983
|
-
|
|
34071
|
+
`agents/${path51.basename(agentFile, ".md")}`,
|
|
34072
|
+
path51.join(
|
|
33984
34073
|
resolveTargetPath(paths.agents),
|
|
33985
|
-
`${
|
|
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
|
-
|
|
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 =
|
|
34105
|
+
const baseName = path51.basename(commandFile, ".md");
|
|
34017
34106
|
rows.push(
|
|
34018
34107
|
classifyCompiledFile(
|
|
34019
34108
|
`commands/${baseName}`,
|
|
34020
|
-
|
|
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
|
-
|
|
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/${
|
|
34120
|
-
|
|
34208
|
+
`commands/${path51.basename(commandFile, ".md")}`,
|
|
34209
|
+
path51.join(
|
|
34121
34210
|
resolveTargetPath(paths.workflows),
|
|
34122
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
34294
|
+
path51.join(sourceRoot, config.source.agents, "*.md")
|
|
34221
34295
|
).sort();
|
|
34222
34296
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
34223
|
-
const mcpSource =
|
|
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
|
-
|
|
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
|
-
|
|
34243
|
-
|
|
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/${
|
|
34253
|
-
|
|
34333
|
+
`agents/${path51.basename(agentFile, ".md")}`,
|
|
34334
|
+
path51.join(
|
|
34254
34335
|
resolveTargetPath(codexPaths.agents),
|
|
34255
|
-
`${
|
|
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 =
|
|
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
|
-
|
|
34430
|
+
path51.join(sourceRoot, config.source.agents, "*.md")
|
|
34350
34431
|
).sort();
|
|
34351
34432
|
const commandFiles = ts(
|
|
34352
|
-
|
|
34433
|
+
path51.join(sourceRoot, config.source.commands, "*.md")
|
|
34353
34434
|
).sort();
|
|
34354
34435
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
34355
|
-
const mcpSource =
|
|
34436
|
+
const mcpSource = path51.join(sourceRoot, config.source.mcp);
|
|
34356
34437
|
return [
|
|
34357
34438
|
...agentFiles.map(
|
|
34358
34439
|
(agentFile) => classifyCompiledFile(
|
|
34359
|
-
`agents/${
|
|
34360
|
-
|
|
34440
|
+
`agents/${path51.basename(agentFile, ".md")}`,
|
|
34441
|
+
path51.join(
|
|
34361
34442
|
resolveTargetPath(copilotPaths.agents),
|
|
34362
|
-
`${
|
|
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/${
|
|
34380
|
-
|
|
34460
|
+
`commands/${path51.basename(commandFile, ".md")}`,
|
|
34461
|
+
path51.join(
|
|
34381
34462
|
resolveTargetPath(copilotPaths.prompts),
|
|
34382
|
-
`${
|
|
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
|
-
|
|
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
|
-
|
|
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 ?
|
|
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" &&
|
|
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(
|
|
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
|
-
|
|
34638
|
+
path51.resolve(sourceRoot, config.source.settings)
|
|
34558
34639
|
),
|
|
34559
|
-
classifyMcp(claudeJsonPath,
|
|
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
|
|
34742
|
+
function isCompiledCurrent6(filePath) {
|
|
34662
34743
|
try {
|
|
34663
|
-
const
|
|
34664
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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 =
|
|
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
|
|
35626
|
-
|
|
35627
|
-
|
|
35628
|
-
|
|
35629
|
-
|
|
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
|
-
|
|
35794
|
+
path52.join(
|
|
35682
35795
|
resolveTargetPath(paths.agents ?? ""),
|
|
35683
|
-
`${
|
|
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
|
-
|
|
35806
|
+
path52.join(
|
|
35694
35807
|
resolveTargetPath(paths.prompts ?? ""),
|
|
35695
|
-
`${
|
|
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
|
-
|
|
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
|
-
|
|
35848
|
+
path52.join(
|
|
35736
35849
|
resolveTargetPath(paths.agents ?? ""),
|
|
35737
|
-
`${
|
|
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
|
-
|
|
35860
|
+
path52.join(
|
|
35748
35861
|
resolveTargetPath(paths.rules ?? ""),
|
|
35749
|
-
`${
|
|
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
|
-
|
|
35901
|
+
path52.join(
|
|
35789
35902
|
resolveTargetPath(paths.agents ?? ""),
|
|
35790
|
-
`${
|
|
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
|
-
|
|
35913
|
+
path52.join(
|
|
35801
35914
|
resolveTargetPath(paths.commands ?? ""),
|
|
35802
|
-
`${
|
|
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
|
-
|
|
35947
|
+
path52.join(
|
|
35835
35948
|
resolveTargetPath(paths.agents ?? ""),
|
|
35836
|
-
`${
|
|
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
|
-
|
|
35959
|
+
path52.join(
|
|
35847
35960
|
resolveTargetPath(paths.rules ?? ""),
|
|
35848
|
-
`${
|
|
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
|
-
|
|
35971
|
+
path52.join(
|
|
35859
35972
|
resolveTargetPath(paths.skills ?? ""),
|
|
35860
|
-
|
|
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
|
-
|
|
36017
|
+
path52.join(
|
|
35905
36018
|
resolveTargetPath(paths.rules ?? ""),
|
|
35906
|
-
`${
|
|
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
|
-
|
|
36029
|
+
path52.join(
|
|
35917
36030
|
resolveTargetPath(paths.workflows ?? ""),
|
|
35918
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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/${
|
|
36294
|
-
message: `hooks: '${
|
|
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 =
|
|
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(
|
|
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" ?
|
|
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 =
|
|
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 =
|
|
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:
|
|
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
|
|
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 ?
|
|
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(
|
|
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(
|