@alessandroraffa/tangyr 8.0.0 → 9.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 +24 -24
- package/dist/index.js +738 -648
- package/package.json +1 -1
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 path57 = __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 = path57.resolve(baseDir, baseName);
|
|
2389
2389
|
if (fs53.existsSync(localBin)) return localBin;
|
|
2390
|
-
if (sourceExt.includes(
|
|
2390
|
+
if (sourceExt.includes(path57.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 = path57.resolve(
|
|
2409
|
+
path57.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 = path57.basename(
|
|
2417
2417
|
this._scriptPath,
|
|
2418
|
-
|
|
2418
|
+
path57.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(path57.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 = path57.basename(filename, path57.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(path58) {
|
|
3359
|
+
if (path58 === void 0) return this._executableDir;
|
|
3360
|
+
this._executableDir = path58;
|
|
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, path57) {
|
|
3717
|
+
const ctrl = callVisitor(key, node, visitor, path57);
|
|
3718
3718
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3719
|
-
replaceNode(key,
|
|
3720
|
-
return visit_(key, ctrl, visitor,
|
|
3719
|
+
replaceNode(key, path57, ctrl);
|
|
3720
|
+
return visit_(key, ctrl, visitor, path57);
|
|
3721
3721
|
}
|
|
3722
3722
|
if (typeof ctrl !== "symbol") {
|
|
3723
3723
|
if (identity.isCollection(node)) {
|
|
3724
|
-
|
|
3724
|
+
path57 = Object.freeze(path57.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, path57);
|
|
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
|
+
path57 = Object.freeze(path57.concat(node));
|
|
3738
|
+
const ck = visit_("key", node.key, visitor, path57);
|
|
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, path57);
|
|
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, path57) {
|
|
3765
|
+
const ctrl = await callVisitor(key, node, visitor, path57);
|
|
3766
3766
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3767
|
-
replaceNode(key,
|
|
3768
|
-
return visitAsync_(key, ctrl, visitor,
|
|
3767
|
+
replaceNode(key, path57, ctrl);
|
|
3768
|
+
return visitAsync_(key, ctrl, visitor, path57);
|
|
3769
3769
|
}
|
|
3770
3770
|
if (typeof ctrl !== "symbol") {
|
|
3771
3771
|
if (identity.isCollection(node)) {
|
|
3772
|
-
|
|
3772
|
+
path57 = Object.freeze(path57.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, path57);
|
|
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
|
+
path57 = Object.freeze(path57.concat(node));
|
|
3786
|
+
const ck = await visitAsync_("key", node.key, visitor, path57);
|
|
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, path57);
|
|
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, path57) {
|
|
3819
3819
|
if (typeof visitor === "function")
|
|
3820
|
-
return visitor(key, node,
|
|
3820
|
+
return visitor(key, node, path57);
|
|
3821
3821
|
if (identity.isMap(node))
|
|
3822
|
-
return visitor.Map?.(key, node,
|
|
3822
|
+
return visitor.Map?.(key, node, path57);
|
|
3823
3823
|
if (identity.isSeq(node))
|
|
3824
|
-
return visitor.Seq?.(key, node,
|
|
3824
|
+
return visitor.Seq?.(key, node, path57);
|
|
3825
3825
|
if (identity.isPair(node))
|
|
3826
|
-
return visitor.Pair?.(key, node,
|
|
3826
|
+
return visitor.Pair?.(key, node, path57);
|
|
3827
3827
|
if (identity.isScalar(node))
|
|
3828
|
-
return visitor.Scalar?.(key, node,
|
|
3828
|
+
return visitor.Scalar?.(key, node, path57);
|
|
3829
3829
|
if (identity.isAlias(node))
|
|
3830
|
-
return visitor.Alias?.(key, node,
|
|
3830
|
+
return visitor.Alias?.(key, node, path57);
|
|
3831
3831
|
return void 0;
|
|
3832
3832
|
}
|
|
3833
|
-
function replaceNode(key,
|
|
3834
|
-
const parent =
|
|
3833
|
+
function replaceNode(key, path57, node) {
|
|
3834
|
+
const parent = path57[path57.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, path57, value) {
|
|
4443
4443
|
let v2 = value;
|
|
4444
|
-
for (let i =
|
|
4445
|
-
const k2 =
|
|
4444
|
+
for (let i = path57.length - 1; i >= 0; --i) {
|
|
4445
|
+
const k2 = path57[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 = (path57) => path57 == null || typeof path57 === "object" && !!path57[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(path57, value) {
|
|
4495
|
+
if (isEmptyPath(path57))
|
|
4496
4496
|
this.add(value);
|
|
4497
4497
|
else {
|
|
4498
|
-
const [key, ...rest] =
|
|
4498
|
+
const [key, ...rest] = path57;
|
|
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(path57) {
|
|
4513
|
+
const [key, ...rest] = path57;
|
|
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(path57, keepScalar) {
|
|
4528
|
+
const [key, ...rest] = path57;
|
|
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(path57) {
|
|
4547
|
+
const [key, ...rest] = path57;
|
|
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(path57, value) {
|
|
4558
|
+
const [key, ...rest] = path57;
|
|
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(path57, value) {
|
|
7071
7071
|
if (assertCollection(this.contents))
|
|
7072
|
-
this.contents.addIn(
|
|
7072
|
+
this.contents.addIn(path57, 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(path57) {
|
|
7148
|
+
if (Collection.isEmptyPath(path57)) {
|
|
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(path57) : 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(path57, keepScalar) {
|
|
7170
|
+
if (Collection.isEmptyPath(path57))
|
|
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(path57, 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(path57) {
|
|
7184
|
+
if (Collection.isEmptyPath(path57))
|
|
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(path57) : 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(path57, value) {
|
|
7204
|
+
if (Collection.isEmptyPath(path57)) {
|
|
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(path57), value);
|
|
7208
7208
|
} else if (assertCollection(this.contents)) {
|
|
7209
|
-
this.contents.setIn(
|
|
7209
|
+
this.contents.setIn(path57, 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, path57) => {
|
|
9167
9167
|
let item = cst;
|
|
9168
|
-
for (const [field, index] of
|
|
9168
|
+
for (const [field, index] of path57) {
|
|
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, path57) => {
|
|
9178
|
+
const parent = visit.itemAtPath(cst, path57.slice(0, -1));
|
|
9179
|
+
const field = path57[path57.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(path57, item, visitor) {
|
|
9186
|
+
let ctrl = visitor(item, path57);
|
|
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(path57.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, path57);
|
|
9205
9205
|
}
|
|
9206
9206
|
}
|
|
9207
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
9207
|
+
return typeof ctrl === "function" ? ctrl(item, path57) : ctrl;
|
|
9208
9208
|
}
|
|
9209
9209
|
exports2.visit = visit;
|
|
9210
9210
|
}
|
|
@@ -15336,6 +15336,14 @@ function markerFromMatch(match) {
|
|
|
15336
15336
|
}
|
|
15337
15337
|
return { source, hash, target };
|
|
15338
15338
|
}
|
|
15339
|
+
function carriesProvenanceMarker(filePath) {
|
|
15340
|
+
try {
|
|
15341
|
+
const firstNonEmpty = fs2.readFileSync(filePath, "utf8").split("\n").find((line) => line.trim().length > 0) ?? "";
|
|
15342
|
+
return extractProvenanceMarker(firstNonEmpty) !== null;
|
|
15343
|
+
} catch {
|
|
15344
|
+
return false;
|
|
15345
|
+
}
|
|
15346
|
+
}
|
|
15339
15347
|
|
|
15340
15348
|
// src/core/kit.ts
|
|
15341
15349
|
import fs4 from "fs";
|
|
@@ -15644,6 +15652,10 @@ function findKit(registry, name) {
|
|
|
15644
15652
|
function defaultKitSearchPaths(configDir) {
|
|
15645
15653
|
return [path4.join(configDir, "operating-kits")];
|
|
15646
15654
|
}
|
|
15655
|
+
function conventionalKitPath(configDir) {
|
|
15656
|
+
const candidate = path4.join(configDir, "tangyr-kit");
|
|
15657
|
+
return fs4.existsSync(path4.join(candidate, "tangyr-kit.yaml")) ? candidate : void 0;
|
|
15658
|
+
}
|
|
15647
15659
|
function resolveKitSelection(selection) {
|
|
15648
15660
|
const registry = discoverKits(selection.searchPaths);
|
|
15649
15661
|
if (selection.kitPath) {
|
|
@@ -15659,6 +15671,10 @@ function resolveKitSelection(selection) {
|
|
|
15659
15671
|
};
|
|
15660
15672
|
}
|
|
15661
15673
|
if (!selection.kit) {
|
|
15674
|
+
if (selection.conventionalPath) {
|
|
15675
|
+
const kit2 = loadKit(selection.conventionalPath);
|
|
15676
|
+
return { kit: kit2, registry: mergeRegistryKit(registry, kit2) };
|
|
15677
|
+
}
|
|
15662
15678
|
return void 0;
|
|
15663
15679
|
}
|
|
15664
15680
|
const kit = findKit(registry, selection.kit);
|
|
@@ -16814,7 +16830,8 @@ function resolveRuntime(options, importMetaUrl) {
|
|
|
16814
16830
|
const kitResolution = resolveKitSelection({
|
|
16815
16831
|
kit: config.kit,
|
|
16816
16832
|
kitPath: config.kitPath,
|
|
16817
|
-
searchPaths
|
|
16833
|
+
searchPaths,
|
|
16834
|
+
conventionalPath: conventionalKitPath(configDir)
|
|
16818
16835
|
});
|
|
16819
16836
|
if ((config.kit || config.kitPath) && !kitResolution) {
|
|
16820
16837
|
throw new Error(
|
|
@@ -17338,9 +17355,6 @@ function instructionsByActiveTarget(tools, scope, projectRoot, mappings) {
|
|
|
17338
17355
|
}
|
|
17339
17356
|
|
|
17340
17357
|
// src/core/foreign-instructions.ts
|
|
17341
|
-
function postureLeavesConflicts(onConflict) {
|
|
17342
|
-
return onConflict === "ask" || onConflict === "skip";
|
|
17343
|
-
}
|
|
17344
17358
|
function instructionsEntrypoints(tools, scope, projectRoot, mappings) {
|
|
17345
17359
|
const byPath = /* @__PURE__ */ new Map();
|
|
17346
17360
|
const add = (destination, tool) => {
|
|
@@ -17383,7 +17397,7 @@ function findForeignInstructions(conflicting, entrypoints) {
|
|
|
17383
17397
|
}
|
|
17384
17398
|
return [...found2.values()].sort((a, b) => a.path.localeCompare(b.path));
|
|
17385
17399
|
}
|
|
17386
|
-
function describeForeignInstructions(foreign,
|
|
17400
|
+
function describeForeignInstructions(foreign, projectRoot) {
|
|
17387
17401
|
const display2 = (target) => {
|
|
17388
17402
|
if (!projectRoot) {
|
|
17389
17403
|
return target;
|
|
@@ -17392,6 +17406,7 @@ function describeForeignInstructions(foreign, posture, projectRoot) {
|
|
|
17392
17406
|
return relative.startsWith("..") ? target : relative;
|
|
17393
17407
|
};
|
|
17394
17408
|
const width = Math.max(...foreign.map((one) => display2(one.path).length));
|
|
17409
|
+
const first = display2(foreign[0].path);
|
|
17395
17410
|
return [
|
|
17396
17411
|
"",
|
|
17397
17412
|
"This project already has an instructions file that Tangyr did not write:",
|
|
@@ -17400,14 +17415,15 @@ function describeForeignInstructions(foreign, posture, projectRoot) {
|
|
|
17400
17415
|
(one) => ` ${display2(one.path).padEnd(width)} read by ${one.targets.join(", ")}`
|
|
17401
17416
|
),
|
|
17402
17417
|
"",
|
|
17403
|
-
"That file carries the working method the rest of the kit is used by
|
|
17404
|
-
|
|
17405
|
-
"
|
|
17406
|
-
"
|
|
17418
|
+
"That file carries the working method the rest of the kit is used by, so a",
|
|
17419
|
+
"kit installed beside it does nothing it was adopted for. No conflict",
|
|
17420
|
+
"posture changes this: replacing a document a repository wrote on purpose",
|
|
17421
|
+
"is not a decision Tangyr makes because a configuration key allows it.",
|
|
17407
17422
|
"",
|
|
17408
|
-
"
|
|
17409
|
-
|
|
17410
|
-
"
|
|
17423
|
+
"Do one of these, then install again:",
|
|
17424
|
+
` move it aside mv ${first} ${first}.before-tangyr`,
|
|
17425
|
+
" delete it if the kit's entrypoint already carries its content",
|
|
17426
|
+
" fold it in move what it says into the kit, and let the kit deliver it"
|
|
17411
17427
|
];
|
|
17412
17428
|
}
|
|
17413
17429
|
|
|
@@ -17632,25 +17648,19 @@ function runAssessCommand(options, logger) {
|
|
|
17632
17648
|
function reportWhatInstallWillDo(conflicts, scope, projectRoot, options, logger) {
|
|
17633
17649
|
const posture = configuredPosture(options);
|
|
17634
17650
|
const count = `${String(conflicts.length)} conflicting configuration(s) found.`;
|
|
17635
|
-
|
|
17636
|
-
|
|
17637
|
-
|
|
17638
|
-
|
|
17639
|
-
|
|
17640
|
-
|
|
17641
|
-
|
|
17642
|
-
|
|
17643
|
-
|
|
17644
|
-
|
|
17645
|
-
|
|
17646
|
-
foreign,
|
|
17647
|
-
posture === "ask" ? "ask" : "skip",
|
|
17648
|
-
projectRoot
|
|
17649
|
-
)) {
|
|
17650
|
-
logger.warn(line);
|
|
17651
|
-
}
|
|
17652
|
-
return;
|
|
17651
|
+
const foreign = foreignInstructionsAmong(
|
|
17652
|
+
conflicts,
|
|
17653
|
+
scope,
|
|
17654
|
+
projectRoot,
|
|
17655
|
+
options
|
|
17656
|
+
);
|
|
17657
|
+
if (foreign.length > 0) {
|
|
17658
|
+
logger.warn(`
|
|
17659
|
+
${count} Installation will be refused (exit 2).`);
|
|
17660
|
+
for (const line of describeForeignInstructions(foreign, projectRoot)) {
|
|
17661
|
+
logger.warn(line);
|
|
17653
17662
|
}
|
|
17663
|
+
return;
|
|
17654
17664
|
}
|
|
17655
17665
|
const outcome = {
|
|
17656
17666
|
ask: "With onConflict: ask, installation will ask you about each one; run non-interactively, where there is no one to ask, it leaves them as they are.",
|
|
@@ -17728,7 +17738,7 @@ function collectProjectScopeFindings(projectRoot, tools, options) {
|
|
|
17728
17738
|
continue;
|
|
17729
17739
|
}
|
|
17730
17740
|
const type = stat.isSymbolicLink() ? "symlink" : stat.isDirectory() ? "directory" : "file";
|
|
17731
|
-
const ours = type === "file" &&
|
|
17741
|
+
const ours = type === "file" && carriesProvenanceMarker(resolvedPath);
|
|
17732
17742
|
findings.push({
|
|
17733
17743
|
path: resolvedPath,
|
|
17734
17744
|
tool,
|
|
@@ -17740,14 +17750,6 @@ function collectProjectScopeFindings(projectRoot, tools, options) {
|
|
|
17740
17750
|
}
|
|
17741
17751
|
return findings;
|
|
17742
17752
|
}
|
|
17743
|
-
function carriesTangyrMarker(filePath) {
|
|
17744
|
-
try {
|
|
17745
|
-
const firstNonEmpty = fs12.readFileSync(filePath, "utf8").split("\n").find((line) => line.trim().length > 0) ?? "";
|
|
17746
|
-
return extractProvenanceMarker(firstNonEmpty) !== null;
|
|
17747
|
-
} catch {
|
|
17748
|
-
return false;
|
|
17749
|
-
}
|
|
17750
|
-
}
|
|
17751
17753
|
function requestedAssessTools(toolFilter) {
|
|
17752
17754
|
return toolFilter ?? [...DEFAULT_ASSESS_TARGETS];
|
|
17753
17755
|
}
|
|
@@ -17826,7 +17828,8 @@ function resolveKitPath(config, configDir) {
|
|
|
17826
17828
|
const resolution = resolveKitSelection({
|
|
17827
17829
|
kit: config.kit,
|
|
17828
17830
|
kitPath: config.kitPath,
|
|
17829
|
-
searchPaths
|
|
17831
|
+
searchPaths,
|
|
17832
|
+
conventionalPath: conventionalKitPath(configDir)
|
|
17830
17833
|
});
|
|
17831
17834
|
return resolution?.kit.path ?? null;
|
|
17832
17835
|
}
|
|
@@ -18627,7 +18630,7 @@ async function runCacheClearCommand(options, logger) {
|
|
|
18627
18630
|
|
|
18628
18631
|
// src/commands/cleanup.ts
|
|
18629
18632
|
import fs30 from "fs";
|
|
18630
|
-
import
|
|
18633
|
+
import path30 from "path";
|
|
18631
18634
|
|
|
18632
18635
|
// node_modules/glob/dist/esm/index.min.js
|
|
18633
18636
|
import { fileURLToPath as Wi } from "url";
|
|
@@ -21782,7 +21785,7 @@ function removeManagedEntries(filePath, parser, serializer, removeManaged, logge
|
|
|
21782
21785
|
|
|
21783
21786
|
// src/commands/uninstall.ts
|
|
21784
21787
|
import fs29 from "fs";
|
|
21785
|
-
import
|
|
21788
|
+
import path29 from "path";
|
|
21786
21789
|
|
|
21787
21790
|
// src/core/managed-sources.ts
|
|
21788
21791
|
var import_yaml5 = __toESM(require_dist(), 1);
|
|
@@ -22306,7 +22309,7 @@ function reportHooksSourceConflict(report, targets, hooksDir, hookNames) {
|
|
|
22306
22309
|
|
|
22307
22310
|
// src/adapters/hook-scripts-bridge.ts
|
|
22308
22311
|
import fs26 from "fs";
|
|
22309
|
-
import
|
|
22312
|
+
import path27 from "path";
|
|
22310
22313
|
|
|
22311
22314
|
// src/utils/fs.ts
|
|
22312
22315
|
import fs24 from "fs";
|
|
@@ -22388,6 +22391,7 @@ function clearSymlinkAtDestination(destination) {
|
|
|
22388
22391
|
|
|
22389
22392
|
// src/core/artifact-state.ts
|
|
22390
22393
|
import fs25 from "fs";
|
|
22394
|
+
import path25 from "path";
|
|
22391
22395
|
function isLegacyArtifactState(recorded) {
|
|
22392
22396
|
return recorded.startsWith("target:") || recorded.startsWith("dir:");
|
|
22393
22397
|
}
|
|
@@ -22414,11 +22418,14 @@ function describeArtifactState(artifactPath) {
|
|
|
22414
22418
|
return null;
|
|
22415
22419
|
}
|
|
22416
22420
|
}
|
|
22417
|
-
function refreshArtifactStates(artifacts) {
|
|
22421
|
+
function refreshArtifactStates(artifacts, written) {
|
|
22418
22422
|
for (const artifact of artifacts) {
|
|
22419
22423
|
if (!artifact.path) {
|
|
22420
22424
|
continue;
|
|
22421
22425
|
}
|
|
22426
|
+
if (written && !written.has(path25.resolve(artifact.path))) {
|
|
22427
|
+
continue;
|
|
22428
|
+
}
|
|
22422
22429
|
const state = describeArtifactState(artifact.path);
|
|
22423
22430
|
if (state !== null) {
|
|
22424
22431
|
artifact.hash = state;
|
|
@@ -22435,9 +22442,22 @@ function compareArtifactState(recorded, artifactPath) {
|
|
|
22435
22442
|
}
|
|
22436
22443
|
return current === recorded ? "current" : "modified";
|
|
22437
22444
|
}
|
|
22445
|
+
function hasDriftedSinceInstall(artifactPath, manifest) {
|
|
22446
|
+
if (!manifest) {
|
|
22447
|
+
return false;
|
|
22448
|
+
}
|
|
22449
|
+
const resolved = path25.resolve(artifactPath);
|
|
22450
|
+
const recorded = manifest.artifacts.find(
|
|
22451
|
+
(artifact) => artifact.path && path25.resolve(artifact.path) === resolved
|
|
22452
|
+
);
|
|
22453
|
+
if (!recorded) {
|
|
22454
|
+
return false;
|
|
22455
|
+
}
|
|
22456
|
+
return compareArtifactState(recorded.hash, artifactPath) === "modified";
|
|
22457
|
+
}
|
|
22438
22458
|
|
|
22439
22459
|
// src/core/shared-artifacts.ts
|
|
22440
|
-
import
|
|
22460
|
+
import path26 from "path";
|
|
22441
22461
|
var SHARED_NAMESPACE = "shared";
|
|
22442
22462
|
var SHARED_INSTRUCTIONS_KEY = `${SHARED_NAMESPACE}/AGENTS.md`;
|
|
22443
22463
|
var SHARED_INSTRUCTIONS_FILE = "AGENTS.md";
|
|
@@ -22447,14 +22467,14 @@ function sharedArtifactKey(destination, scope, projectRoot) {
|
|
|
22447
22467
|
return null;
|
|
22448
22468
|
}
|
|
22449
22469
|
const root = projectRoot ?? process.cwd();
|
|
22450
|
-
const shared =
|
|
22451
|
-
return
|
|
22470
|
+
const shared = path26.resolve(root, SHARED_INSTRUCTIONS_FILE);
|
|
22471
|
+
return path26.resolve(destination) === shared ? SHARED_INSTRUCTIONS_KEY : null;
|
|
22452
22472
|
}
|
|
22453
22473
|
function resolveSharedArtifactKey(key, scope, projectRoot) {
|
|
22454
22474
|
if (key !== SHARED_INSTRUCTIONS_KEY || scope !== "project") {
|
|
22455
22475
|
return null;
|
|
22456
22476
|
}
|
|
22457
|
-
return
|
|
22477
|
+
return path26.join(projectRoot ?? process.cwd(), SHARED_INSTRUCTIONS_FILE);
|
|
22458
22478
|
}
|
|
22459
22479
|
var SHARED_SKILLS_PREFIX = `${SHARED_NAMESPACE}/skills`;
|
|
22460
22480
|
function sharedKeyForDestination(destination, scope, projectRoot, platformPaths) {
|
|
@@ -22462,7 +22482,7 @@ function sharedKeyForDestination(destination, scope, projectRoot, platformPaths)
|
|
|
22462
22482
|
if (instructions) {
|
|
22463
22483
|
return instructions;
|
|
22464
22484
|
}
|
|
22465
|
-
const resolved =
|
|
22485
|
+
const resolved = path26.resolve(destination);
|
|
22466
22486
|
let profiles;
|
|
22467
22487
|
try {
|
|
22468
22488
|
profiles = resolveTargetPaths({
|
|
@@ -22473,12 +22493,12 @@ function sharedKeyForDestination(destination, scope, projectRoot, platformPaths)
|
|
|
22473
22493
|
} catch {
|
|
22474
22494
|
return null;
|
|
22475
22495
|
}
|
|
22476
|
-
if (resolved ===
|
|
22496
|
+
if (resolved === path26.resolve(profiles.codex.hook_scripts)) {
|
|
22477
22497
|
return SHARED_HOOK_SCRIPTS_KEY;
|
|
22478
22498
|
}
|
|
22479
|
-
const skillsRoot =
|
|
22480
|
-
if (resolved.startsWith(`${skillsRoot}${
|
|
22481
|
-
const inside =
|
|
22499
|
+
const skillsRoot = path26.resolve(profiles.opencode.skills_shared);
|
|
22500
|
+
if (resolved.startsWith(`${skillsRoot}${path26.sep}`)) {
|
|
22501
|
+
const inside = path26.relative(skillsRoot, resolved).split(path26.sep).join("/");
|
|
22482
22502
|
return `${SHARED_SKILLS_PREFIX}/${inside}`;
|
|
22483
22503
|
}
|
|
22484
22504
|
return null;
|
|
@@ -22488,7 +22508,7 @@ function resolveSharedSkillsKey(key, sharedSkillsRoot) {
|
|
|
22488
22508
|
return null;
|
|
22489
22509
|
}
|
|
22490
22510
|
const inside = key.slice(SHARED_SKILLS_PREFIX.length + 1);
|
|
22491
|
-
return
|
|
22511
|
+
return path26.join(sharedSkillsRoot, ...inside.split("/"));
|
|
22492
22512
|
}
|
|
22493
22513
|
|
|
22494
22514
|
// src/adapters/hook-scripts-bridge.ts
|
|
@@ -22516,7 +22536,7 @@ function syncHookScriptsBridge(args) {
|
|
|
22516
22536
|
} else if (artifactClass === "managed-symlink") {
|
|
22517
22537
|
fs26.unlinkSync(destination);
|
|
22518
22538
|
}
|
|
22519
|
-
ensureDir(
|
|
22539
|
+
ensureDir(path27.dirname(destination));
|
|
22520
22540
|
createRelativeSymlink(source, destination, "dir");
|
|
22521
22541
|
if (args.manifest) {
|
|
22522
22542
|
const state = describeArtifactState(destination);
|
|
@@ -22547,7 +22567,7 @@ function isSymlinkTo(linkPath, source) {
|
|
|
22547
22567
|
|
|
22548
22568
|
// src/core/shared-surface.ts
|
|
22549
22569
|
import fs27 from "fs";
|
|
22550
|
-
import
|
|
22570
|
+
import path28 from "path";
|
|
22551
22571
|
function isPlainObject2(value) {
|
|
22552
22572
|
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) !== null;
|
|
22553
22573
|
}
|
|
@@ -22887,7 +22907,7 @@ async function runUninstallCommand(options, logger) {
|
|
|
22887
22907
|
if (recorded) {
|
|
22888
22908
|
const outcome = revertSharedSurface(recorded, logger);
|
|
22889
22909
|
if (outcome === "reverted" || outcome === "removed") {
|
|
22890
|
-
removedParentDirs.add(
|
|
22910
|
+
removedParentDirs.add(path29.dirname(recorded.path));
|
|
22891
22911
|
removedCount++;
|
|
22892
22912
|
}
|
|
22893
22913
|
if (outcome === "reverted") {
|
|
@@ -22903,7 +22923,7 @@ async function runUninstallCommand(options, logger) {
|
|
|
22903
22923
|
uninstallProjectRoot
|
|
22904
22924
|
);
|
|
22905
22925
|
if (surfacePath && stripTangyrFromMergeSurface(surfacePath, logger)) {
|
|
22906
|
-
removedParentDirs.add(
|
|
22926
|
+
removedParentDirs.add(path29.dirname(surfacePath));
|
|
22907
22927
|
removedCount++;
|
|
22908
22928
|
if (fs29.existsSync(surfacePath)) {
|
|
22909
22929
|
keptSurfaces.push(surfacePath);
|
|
@@ -22925,7 +22945,7 @@ async function runUninstallCommand(options, logger) {
|
|
|
22925
22945
|
for (const actualPath of paths) {
|
|
22926
22946
|
if (actualPath && (fs29.existsSync(actualPath) || isSymlink(actualPath))) {
|
|
22927
22947
|
removeManagedPath(actualPath);
|
|
22928
|
-
removedParentDirs.add(
|
|
22948
|
+
removedParentDirs.add(path29.dirname(actualPath));
|
|
22929
22949
|
logger.verbose(` removed: ${actualPath}`);
|
|
22930
22950
|
removedCount++;
|
|
22931
22951
|
} else {
|
|
@@ -22947,7 +22967,7 @@ async function runUninstallCommand(options, logger) {
|
|
|
22947
22967
|
continue;
|
|
22948
22968
|
}
|
|
22949
22969
|
removeManagedPath(actualPath);
|
|
22950
|
-
removedParentDirs.add(
|
|
22970
|
+
removedParentDirs.add(path29.dirname(actualPath));
|
|
22951
22971
|
logger.verbose(` removed: ${actualPath}`);
|
|
22952
22972
|
removedCount++;
|
|
22953
22973
|
} else {
|
|
@@ -23004,17 +23024,17 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
|
|
|
23004
23024
|
" The manifest is removed below, so nothing will reference these copies afterwards. Move what you need out of the backups directory now."
|
|
23005
23025
|
);
|
|
23006
23026
|
}
|
|
23007
|
-
const manifestPath =
|
|
23027
|
+
const manifestPath = path29.join(scopePath, "manifest.json");
|
|
23008
23028
|
if (fs29.existsSync(manifestPath)) {
|
|
23009
23029
|
fs29.unlinkSync(manifestPath);
|
|
23010
23030
|
logger.verbose(` removed manifest: ${manifestPath}`);
|
|
23011
23031
|
}
|
|
23012
|
-
const lossReportPath =
|
|
23032
|
+
const lossReportPath = path29.join(scopePath, DEFAULT_LOSS_REPORT_FILE);
|
|
23013
23033
|
if (fs29.existsSync(lossReportPath)) {
|
|
23014
23034
|
fs29.unlinkSync(lossReportPath);
|
|
23015
23035
|
logger.verbose(` removed loss report: ${lossReportPath}`);
|
|
23016
23036
|
}
|
|
23017
|
-
pruneEmptyDirs(
|
|
23037
|
+
pruneEmptyDirs(path29.join(scopePath, "backups"), logger);
|
|
23018
23038
|
try {
|
|
23019
23039
|
const remaining = fs29.readdirSync(scopePath);
|
|
23020
23040
|
if (remaining.length === 0) {
|
|
@@ -23037,7 +23057,7 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
|
|
|
23037
23057
|
} else {
|
|
23038
23058
|
logger.verbose(" no manifest to update after partial residue cleanup");
|
|
23039
23059
|
}
|
|
23040
|
-
const pruneBoundary =
|
|
23060
|
+
const pruneBoundary = path29.dirname(scopePath);
|
|
23041
23061
|
for (const dir of removedParentDirs) {
|
|
23042
23062
|
pruneEmptyAncestors2(dir, pruneBoundary, logger);
|
|
23043
23063
|
}
|
|
@@ -23088,32 +23108,32 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
|
|
|
23088
23108
|
if (!slotPath) {
|
|
23089
23109
|
return null;
|
|
23090
23110
|
}
|
|
23091
|
-
return subPath ?
|
|
23111
|
+
return subPath ? path29.join(slotPath, subPath) : slotPath;
|
|
23092
23112
|
}
|
|
23093
23113
|
if (tool === "copilot") {
|
|
23094
23114
|
const copilotPaths = resolveCopilotPaths(runtime, scope, projectRoot);
|
|
23095
23115
|
if (component.startsWith("skills/")) {
|
|
23096
|
-
return
|
|
23116
|
+
return path29.join(copilotPaths.skills, component.slice("skills/".length));
|
|
23097
23117
|
}
|
|
23098
23118
|
if (component === "skills") {
|
|
23099
23119
|
return copilotPaths.skills;
|
|
23100
23120
|
}
|
|
23101
23121
|
if (component.startsWith("agents/")) {
|
|
23102
|
-
return
|
|
23122
|
+
return path29.join(copilotPaths.agents, component.slice("agents/".length));
|
|
23103
23123
|
}
|
|
23104
23124
|
if (component.startsWith("prompts/")) {
|
|
23105
|
-
return
|
|
23125
|
+
return path29.join(
|
|
23106
23126
|
copilotPaths.prompts,
|
|
23107
23127
|
component.slice("prompts/".length)
|
|
23108
23128
|
);
|
|
23109
23129
|
}
|
|
23110
23130
|
if (component.startsWith("hooks/")) {
|
|
23111
|
-
return
|
|
23131
|
+
return path29.join(copilotPaths.hooks, component.slice("hooks/".length));
|
|
23112
23132
|
}
|
|
23113
|
-
if (component ===
|
|
23133
|
+
if (component === path29.basename(copilotPaths.mcpSharedFile)) {
|
|
23114
23134
|
return copilotPaths.mcpSharedFile;
|
|
23115
23135
|
}
|
|
23116
|
-
if (copilotPaths.instructions !== null && component ===
|
|
23136
|
+
if (copilotPaths.instructions !== null && component === path29.basename(copilotPaths.instructions)) {
|
|
23117
23137
|
return copilotPaths.instructions;
|
|
23118
23138
|
}
|
|
23119
23139
|
return null;
|
|
@@ -23127,15 +23147,15 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
|
|
|
23127
23147
|
return codexPaths.skills;
|
|
23128
23148
|
}
|
|
23129
23149
|
if (component.startsWith("agents/")) {
|
|
23130
|
-
return
|
|
23150
|
+
return path29.join(codexPaths.agents, component.slice("agents/".length));
|
|
23131
23151
|
}
|
|
23132
23152
|
if (component.startsWith("rules/")) {
|
|
23133
|
-
return
|
|
23153
|
+
return path29.join(codexPaths.rules, component.slice("rules/".length));
|
|
23134
23154
|
}
|
|
23135
|
-
if (component ===
|
|
23155
|
+
if (component === path29.basename(codexPaths.hooksSharedFile)) {
|
|
23136
23156
|
return codexPaths.hooksSharedFile;
|
|
23137
23157
|
}
|
|
23138
|
-
if (component ===
|
|
23158
|
+
if (component === path29.basename(codexPaths.mcpSharedFile)) {
|
|
23139
23159
|
return codexPaths.mcpSharedFile;
|
|
23140
23160
|
}
|
|
23141
23161
|
return null;
|
|
@@ -23152,15 +23172,15 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
|
|
|
23152
23172
|
return opencodePaths.skillsShared;
|
|
23153
23173
|
}
|
|
23154
23174
|
if (component.startsWith("agents/")) {
|
|
23155
|
-
return
|
|
23175
|
+
return path29.join(opencodePaths.agents, component.slice("agents/".length));
|
|
23156
23176
|
}
|
|
23157
23177
|
if (component.startsWith("commands/")) {
|
|
23158
|
-
return
|
|
23178
|
+
return path29.join(
|
|
23159
23179
|
opencodePaths.commands,
|
|
23160
23180
|
component.slice("commands/".length)
|
|
23161
23181
|
);
|
|
23162
23182
|
}
|
|
23163
|
-
if (component ===
|
|
23183
|
+
if (component === path29.basename(opencodePaths.configDoc)) {
|
|
23164
23184
|
return opencodePaths.configDoc;
|
|
23165
23185
|
}
|
|
23166
23186
|
return null;
|
|
@@ -23186,13 +23206,13 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
|
|
|
23186
23206
|
return cursorPaths.permissionsFile;
|
|
23187
23207
|
}
|
|
23188
23208
|
if (component.startsWith("agents/")) {
|
|
23189
|
-
return
|
|
23209
|
+
return path29.join(cursorPaths.agents, component.slice("agents/".length));
|
|
23190
23210
|
}
|
|
23191
23211
|
if (component.startsWith("rules/")) {
|
|
23192
|
-
return
|
|
23212
|
+
return path29.join(cursorPaths.rules, component.slice("rules/".length));
|
|
23193
23213
|
}
|
|
23194
23214
|
if (component.startsWith("skills/")) {
|
|
23195
|
-
return
|
|
23215
|
+
return path29.join(cursorPaths.skills, component.slice("skills/".length));
|
|
23196
23216
|
}
|
|
23197
23217
|
return null;
|
|
23198
23218
|
}
|
|
@@ -23208,10 +23228,10 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
|
|
|
23208
23228
|
return clinePaths.mcpFile;
|
|
23209
23229
|
}
|
|
23210
23230
|
if (component.startsWith("rules/")) {
|
|
23211
|
-
return
|
|
23231
|
+
return path29.join(clinePaths.rules, component.slice("rules/".length));
|
|
23212
23232
|
}
|
|
23213
23233
|
if (component.startsWith("workflows/")) {
|
|
23214
|
-
return
|
|
23234
|
+
return path29.join(
|
|
23215
23235
|
clinePaths.workflows,
|
|
23216
23236
|
component.slice("workflows/".length)
|
|
23217
23237
|
);
|
|
@@ -23245,22 +23265,22 @@ function resolveClaudeCodePaths(runtime, scope, projectRoot) {
|
|
|
23245
23265
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
23246
23266
|
if (scope === "global") {
|
|
23247
23267
|
return {
|
|
23248
|
-
instructions:
|
|
23249
|
-
agents:
|
|
23250
|
-
skills:
|
|
23251
|
-
commands:
|
|
23252
|
-
rules:
|
|
23253
|
-
output_styles:
|
|
23268
|
+
instructions: path29.join(home, ".claude", "CLAUDE.md"),
|
|
23269
|
+
agents: path29.join(home, ".claude", "agents"),
|
|
23270
|
+
skills: path29.join(home, ".claude", "skills"),
|
|
23271
|
+
commands: path29.join(home, ".claude", "commands"),
|
|
23272
|
+
rules: path29.join(home, ".claude", "rules"),
|
|
23273
|
+
output_styles: path29.join(home, ".claude", "output-styles")
|
|
23254
23274
|
};
|
|
23255
23275
|
}
|
|
23256
23276
|
const root = projectRoot ?? process.cwd();
|
|
23257
23277
|
return {
|
|
23258
|
-
instructions:
|
|
23259
|
-
agents:
|
|
23260
|
-
skills:
|
|
23261
|
-
commands:
|
|
23262
|
-
rules:
|
|
23263
|
-
output_styles:
|
|
23278
|
+
instructions: path29.join(root, "CLAUDE.md"),
|
|
23279
|
+
agents: path29.join(root, ".claude", "agents"),
|
|
23280
|
+
skills: path29.join(root, ".claude", "skills"),
|
|
23281
|
+
commands: path29.join(root, ".claude", "commands"),
|
|
23282
|
+
rules: path29.join(root, ".claude", "rules"),
|
|
23283
|
+
output_styles: path29.join(root, ".claude", "output-styles")
|
|
23264
23284
|
};
|
|
23265
23285
|
}
|
|
23266
23286
|
function resolveClaudeRootsForUninstall(manifest, runtime) {
|
|
@@ -23279,12 +23299,12 @@ function resolveClaudeRootsForUninstall(manifest, runtime) {
|
|
|
23279
23299
|
projectRoot: void 0,
|
|
23280
23300
|
mappings: mappings.platformPaths
|
|
23281
23301
|
})["claude-code"];
|
|
23282
|
-
return [
|
|
23302
|
+
return [path29.dirname(profile.agents)];
|
|
23283
23303
|
} catch {
|
|
23284
23304
|
}
|
|
23285
23305
|
}
|
|
23286
23306
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
23287
|
-
return [
|
|
23307
|
+
return [path29.resolve(expandHome(`${home}/.claude`))];
|
|
23288
23308
|
}
|
|
23289
23309
|
function resolveAllClaudeRoots(manifest, runtime, claudeConfigDirs) {
|
|
23290
23310
|
const home = process.env.HOME ?? process.env.USERPROFILE;
|
|
@@ -23296,13 +23316,13 @@ function resolveAllClaudeRoots(manifest, runtime, claudeConfigDirs) {
|
|
|
23296
23316
|
env: process.env.TANGYR_CLAUDE_CONFIG_DIRS,
|
|
23297
23317
|
config: runtime.config.claudeCodeGlobalPaths
|
|
23298
23318
|
})
|
|
23299
|
-
].map((root) =>
|
|
23319
|
+
].map((root) => path29.resolve(root))
|
|
23300
23320
|
);
|
|
23301
23321
|
if (home && fs29.existsSync(home)) {
|
|
23302
23322
|
try {
|
|
23303
23323
|
for (const entry of fs29.readdirSync(home, { withFileTypes: true })) {
|
|
23304
23324
|
if (entry.isDirectory() && entry.name.startsWith(".claude-")) {
|
|
23305
|
-
roots.add(
|
|
23325
|
+
roots.add(path29.resolve(home, entry.name));
|
|
23306
23326
|
}
|
|
23307
23327
|
}
|
|
23308
23328
|
} catch {
|
|
@@ -23321,13 +23341,13 @@ function resolveManifestKeyToMultiPaths(key, claudeRoots, runtime) {
|
|
|
23321
23341
|
const rootsToResolve = isShared ? [claudeRoots[0]] : claudeRoots;
|
|
23322
23342
|
if (!runtime) {
|
|
23323
23343
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
23324
|
-
const defaultRoot =
|
|
23344
|
+
const defaultRoot = path29.resolve(expandHome(`${home}/.claude`));
|
|
23325
23345
|
return rootsToResolve.flatMap((root) => {
|
|
23326
23346
|
const hardcoded = resolveHardcodedClaudeSlot(root, defaultRoot, slotName);
|
|
23327
23347
|
if (!hardcoded) {
|
|
23328
23348
|
return [];
|
|
23329
23349
|
}
|
|
23330
|
-
return [subPath ?
|
|
23350
|
+
return [subPath ? path29.join(hardcoded, subPath) : hardcoded];
|
|
23331
23351
|
});
|
|
23332
23352
|
}
|
|
23333
23353
|
try {
|
|
@@ -23345,17 +23365,17 @@ function resolveManifestKeyToMultiPaths(key, claudeRoots, runtime) {
|
|
|
23345
23365
|
if (!slotPath) {
|
|
23346
23366
|
return [];
|
|
23347
23367
|
}
|
|
23348
|
-
return [subPath ?
|
|
23368
|
+
return [subPath ? path29.join(slotPath, subPath) : slotPath];
|
|
23349
23369
|
});
|
|
23350
23370
|
} catch {
|
|
23351
23371
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
23352
|
-
const defaultRoot =
|
|
23372
|
+
const defaultRoot = path29.resolve(expandHome(`${home}/.claude`));
|
|
23353
23373
|
return rootsToResolve.flatMap((root) => {
|
|
23354
23374
|
const hardcoded = resolveHardcodedClaudeSlot(root, defaultRoot, slotName);
|
|
23355
23375
|
if (!hardcoded) {
|
|
23356
23376
|
return [];
|
|
23357
23377
|
}
|
|
23358
|
-
return [subPath ?
|
|
23378
|
+
return [subPath ? path29.join(hardcoded, subPath) : hardcoded];
|
|
23359
23379
|
});
|
|
23360
23380
|
}
|
|
23361
23381
|
}
|
|
@@ -23380,9 +23400,9 @@ function resolveHardcodedClaudeSlot(root, defaultRoot, slotName) {
|
|
|
23380
23400
|
return null;
|
|
23381
23401
|
}
|
|
23382
23402
|
if (root === defaultRoot) {
|
|
23383
|
-
return
|
|
23403
|
+
return path29.join(root, relative);
|
|
23384
23404
|
}
|
|
23385
|
-
return
|
|
23405
|
+
return path29.join(root, relative);
|
|
23386
23406
|
}
|
|
23387
23407
|
function resolveRuntimeIfAvailable(options, logger) {
|
|
23388
23408
|
try {
|
|
@@ -23454,9 +23474,9 @@ function stripTangyrFromMergeSurface(filePath, logger) {
|
|
|
23454
23474
|
return true;
|
|
23455
23475
|
}
|
|
23456
23476
|
function pruneEmptyAncestors2(startDir, stopAt, logger) {
|
|
23457
|
-
const boundary =
|
|
23458
|
-
let current =
|
|
23459
|
-
while (current !== boundary && current.startsWith(`${boundary}${
|
|
23477
|
+
const boundary = path29.resolve(stopAt);
|
|
23478
|
+
let current = path29.resolve(startDir);
|
|
23479
|
+
while (current !== boundary && current.startsWith(`${boundary}${path29.sep}`)) {
|
|
23460
23480
|
try {
|
|
23461
23481
|
if (fs29.readdirSync(current).length > 0) {
|
|
23462
23482
|
return;
|
|
@@ -23466,7 +23486,7 @@ function pruneEmptyAncestors2(startDir, stopAt, logger) {
|
|
|
23466
23486
|
} catch {
|
|
23467
23487
|
return;
|
|
23468
23488
|
}
|
|
23469
|
-
current =
|
|
23489
|
+
current = path29.dirname(current);
|
|
23470
23490
|
}
|
|
23471
23491
|
}
|
|
23472
23492
|
function pruneEmptyDirs(dir, logger) {
|
|
@@ -23481,7 +23501,7 @@ function pruneEmptyDirs(dir, logger) {
|
|
|
23481
23501
|
}
|
|
23482
23502
|
for (const entry of fs29.readdirSync(dir, { withFileTypes: true })) {
|
|
23483
23503
|
if (entry.isDirectory() && !entry.isSymbolicLink()) {
|
|
23484
|
-
pruneEmptyDirs(
|
|
23504
|
+
pruneEmptyDirs(path29.join(dir, entry.name), logger);
|
|
23485
23505
|
}
|
|
23486
23506
|
}
|
|
23487
23507
|
try {
|
|
@@ -23506,9 +23526,9 @@ function sharedSurfaceFor(manifest, file, selectedTools, scope, runtime, project
|
|
|
23506
23526
|
if (!artifactPath) {
|
|
23507
23527
|
return null;
|
|
23508
23528
|
}
|
|
23509
|
-
const resolved =
|
|
23529
|
+
const resolved = path29.resolve(artifactPath);
|
|
23510
23530
|
return records.find(
|
|
23511
|
-
(record) =>
|
|
23531
|
+
(record) => path29.resolve(record.path) === resolved && selectedTools.has(record.tool)
|
|
23512
23532
|
) ?? null;
|
|
23513
23533
|
}
|
|
23514
23534
|
function revertSharedSurface(record, logger) {
|
|
@@ -23589,7 +23609,7 @@ function addManagedSymlinkChildren(artifacts, directory, runtime, component) {
|
|
|
23589
23609
|
return;
|
|
23590
23610
|
}
|
|
23591
23611
|
for (const entry of entries) {
|
|
23592
|
-
const artifactPath =
|
|
23612
|
+
const artifactPath = path29.join(directory, entry.name);
|
|
23593
23613
|
const artifactClass = classifyArtifact(
|
|
23594
23614
|
artifactPath,
|
|
23595
23615
|
runtime.config,
|
|
@@ -23628,8 +23648,8 @@ function collectStringValuesByKey(value, keyName, values) {
|
|
|
23628
23648
|
}
|
|
23629
23649
|
function addLegacyOperatingGuideCopies(artifacts, claudeRoot) {
|
|
23630
23650
|
for (const artifactPath of [
|
|
23631
|
-
...ts(
|
|
23632
|
-
...ts(
|
|
23651
|
+
...ts(path29.join(claudeRoot, "CLAUDE.md.bak.*")),
|
|
23652
|
+
...ts(path29.join(claudeRoot, "AGENTS.md.bak.*"))
|
|
23633
23653
|
].sort()) {
|
|
23634
23654
|
artifacts.push({
|
|
23635
23655
|
component: "claude-code legacy operating guide backup",
|
|
@@ -23683,7 +23703,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23683
23703
|
for (const skill of runtime.kitInfo.components.skills.declared) {
|
|
23684
23704
|
artifacts.push({
|
|
23685
23705
|
component: "claude-code skill",
|
|
23686
|
-
path:
|
|
23706
|
+
path: path29.join(profile.skills, skill),
|
|
23687
23707
|
kind: "direct"
|
|
23688
23708
|
});
|
|
23689
23709
|
}
|
|
@@ -23702,7 +23722,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23702
23722
|
if (isFullToolUninstall(manifest, selectedTools)) {
|
|
23703
23723
|
addLegacyOperatingGuideCopies(
|
|
23704
23724
|
artifacts,
|
|
23705
|
-
|
|
23725
|
+
path29.dirname(profile.instructions)
|
|
23706
23726
|
);
|
|
23707
23727
|
}
|
|
23708
23728
|
}
|
|
@@ -23725,20 +23745,20 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23725
23745
|
if (selectedTools.has("copilot")) {
|
|
23726
23746
|
addCompiledGlobPlans(
|
|
23727
23747
|
artifacts,
|
|
23728
|
-
|
|
23748
|
+
path29.join(copilotPaths.agents, "*.agent.md"),
|
|
23729
23749
|
"copilot",
|
|
23730
23750
|
"copilot agent residue"
|
|
23731
23751
|
);
|
|
23732
23752
|
addCompiledGlobPlans(
|
|
23733
23753
|
artifacts,
|
|
23734
|
-
|
|
23754
|
+
path29.join(copilotPaths.prompts, "*.prompt.md"),
|
|
23735
23755
|
"copilot",
|
|
23736
23756
|
"copilot prompt residue"
|
|
23737
23757
|
);
|
|
23738
23758
|
for (const agentEntry of runtime.kitInfo.components.agents.declared) {
|
|
23739
23759
|
artifacts.push({
|
|
23740
23760
|
component: "copilot agent",
|
|
23741
|
-
path:
|
|
23761
|
+
path: path29.join(copilotPaths.agents, `${agentEntry}.agent.md`),
|
|
23742
23762
|
kind: "compiled",
|
|
23743
23763
|
expectedTarget: "copilot",
|
|
23744
23764
|
expectedSource: `agents/${agentEntry}.md`
|
|
@@ -23747,7 +23767,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23747
23767
|
for (const commandEntry of runtime.kitInfo.components.commands.declared) {
|
|
23748
23768
|
artifacts.push({
|
|
23749
23769
|
component: "copilot prompt",
|
|
23750
|
-
path:
|
|
23770
|
+
path: path29.join(copilotPaths.prompts, `${commandEntry}.prompt.md`),
|
|
23751
23771
|
kind: "compiled",
|
|
23752
23772
|
expectedTarget: "copilot",
|
|
23753
23773
|
expectedSource: `commands/${commandEntry}.md`
|
|
@@ -23762,7 +23782,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23762
23782
|
for (const skill of runtime.kitInfo.components.skills.declared) {
|
|
23763
23783
|
artifacts.push({
|
|
23764
23784
|
component: "copilot skill",
|
|
23765
|
-
path:
|
|
23785
|
+
path: path29.join(copilotPaths.skills, skill),
|
|
23766
23786
|
kind: "direct"
|
|
23767
23787
|
});
|
|
23768
23788
|
}
|
|
@@ -23776,13 +23796,13 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23776
23796
|
artifacts.push(
|
|
23777
23797
|
{
|
|
23778
23798
|
component: "copilot hooks",
|
|
23779
|
-
path:
|
|
23799
|
+
path: path29.join(copilotPaths.hooks, "tangyr-managed.json"),
|
|
23780
23800
|
kind: "managed-json",
|
|
23781
23801
|
expectedTarget: "copilot"
|
|
23782
23802
|
},
|
|
23783
23803
|
{
|
|
23784
23804
|
component: "copilot legacy hooks",
|
|
23785
|
-
path:
|
|
23805
|
+
path: path29.join(copilotPaths.hooks, "proteus-managed.json"),
|
|
23786
23806
|
kind: "managed-json",
|
|
23787
23807
|
expectedTarget: "copilot"
|
|
23788
23808
|
}
|
|
@@ -23791,7 +23811,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23791
23811
|
if (hooksSourceExists(runtime.sourceRoot, runtime.config)) {
|
|
23792
23812
|
artifacts.push({
|
|
23793
23813
|
component: "copilot hooks",
|
|
23794
|
-
path:
|
|
23814
|
+
path: path29.join(copilotPaths.hooks, "tangyr-managed.json"),
|
|
23795
23815
|
kind: "compiled",
|
|
23796
23816
|
expectedTarget: "copilot",
|
|
23797
23817
|
expectedSource: hooksSource
|
|
@@ -23821,13 +23841,13 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23821
23841
|
);
|
|
23822
23842
|
addCompiledGlobPlans(
|
|
23823
23843
|
artifacts,
|
|
23824
|
-
|
|
23844
|
+
path29.join(codexPaths.agents, "*.toml"),
|
|
23825
23845
|
"codex",
|
|
23826
23846
|
"codex agent residue"
|
|
23827
23847
|
);
|
|
23828
23848
|
addCompiledGlobPlans(
|
|
23829
23849
|
artifacts,
|
|
23830
|
-
|
|
23850
|
+
path29.join(codexPaths.rules, "*.rules"),
|
|
23831
23851
|
"codex",
|
|
23832
23852
|
"codex rule residue"
|
|
23833
23853
|
);
|
|
@@ -23841,7 +23861,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23841
23861
|
for (const agentEntry of runtime.kitInfo.components.agents.declared) {
|
|
23842
23862
|
artifacts.push({
|
|
23843
23863
|
component: "codex agent",
|
|
23844
|
-
path:
|
|
23864
|
+
path: path29.join(codexPaths.agents, `${agentEntry}.toml`),
|
|
23845
23865
|
kind: "compiled",
|
|
23846
23866
|
expectedTarget: "codex",
|
|
23847
23867
|
expectedSource: `agents/${agentEntry}.md`
|
|
@@ -23850,7 +23870,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23850
23870
|
for (const ruleEntry of runtime.kitInfo.components.rules.declared) {
|
|
23851
23871
|
artifacts.push({
|
|
23852
23872
|
component: "codex rule",
|
|
23853
|
-
path:
|
|
23873
|
+
path: path29.join(codexPaths.rules, `${ruleEntry}.rules`),
|
|
23854
23874
|
kind: "compiled",
|
|
23855
23875
|
expectedTarget: "codex",
|
|
23856
23876
|
expectedSource: `rules/${ruleEntry}.md`
|
|
@@ -23902,13 +23922,13 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23902
23922
|
);
|
|
23903
23923
|
addCompiledGlobPlans(
|
|
23904
23924
|
artifacts,
|
|
23905
|
-
|
|
23925
|
+
path29.join(opencodePaths.agents, "*.md"),
|
|
23906
23926
|
"opencode",
|
|
23907
23927
|
"opencode agent residue"
|
|
23908
23928
|
);
|
|
23909
23929
|
addCompiledGlobPlans(
|
|
23910
23930
|
artifacts,
|
|
23911
|
-
|
|
23931
|
+
path29.join(opencodePaths.commands, "*.md"),
|
|
23912
23932
|
"opencode",
|
|
23913
23933
|
"opencode command residue"
|
|
23914
23934
|
);
|
|
@@ -23927,7 +23947,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23927
23947
|
for (const agentEntry of runtime.kitInfo.components.agents.declared) {
|
|
23928
23948
|
artifacts.push({
|
|
23929
23949
|
component: "opencode agent",
|
|
23930
|
-
path:
|
|
23950
|
+
path: path29.join(opencodePaths.agents, `${agentEntry}.md`),
|
|
23931
23951
|
kind: "compiled",
|
|
23932
23952
|
expectedTarget: "opencode",
|
|
23933
23953
|
expectedSource: `agents/${agentEntry}.md`
|
|
@@ -23936,7 +23956,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23936
23956
|
for (const commandEntry of runtime.kitInfo.components.commands.declared) {
|
|
23937
23957
|
artifacts.push({
|
|
23938
23958
|
component: "opencode command",
|
|
23939
|
-
path:
|
|
23959
|
+
path: path29.join(opencodePaths.commands, `${commandEntry}.md`),
|
|
23940
23960
|
kind: "compiled",
|
|
23941
23961
|
expectedTarget: "opencode",
|
|
23942
23962
|
expectedSource: `commands/${commandEntry}.md`
|
|
@@ -23991,19 +24011,19 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
23991
24011
|
);
|
|
23992
24012
|
addCompiledGlobPlans(
|
|
23993
24013
|
artifacts,
|
|
23994
|
-
|
|
24014
|
+
path29.join(cursorPaths.agents, "*.md"),
|
|
23995
24015
|
"cursor",
|
|
23996
24016
|
"cursor agent residue"
|
|
23997
24017
|
);
|
|
23998
24018
|
addCompiledGlobPlans(
|
|
23999
24019
|
artifacts,
|
|
24000
|
-
|
|
24020
|
+
path29.join(cursorPaths.rules, "*.mdc"),
|
|
24001
24021
|
"cursor",
|
|
24002
24022
|
"cursor rule residue"
|
|
24003
24023
|
);
|
|
24004
24024
|
addCompiledGlobPlans(
|
|
24005
24025
|
artifacts,
|
|
24006
|
-
|
|
24026
|
+
path29.join(cursorPaths.skills, "*", "SKILL.md"),
|
|
24007
24027
|
"cursor",
|
|
24008
24028
|
"cursor command residue"
|
|
24009
24029
|
);
|
|
@@ -24017,7 +24037,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
24017
24037
|
for (const agentEntry of runtime.kitInfo.components.agents.declared) {
|
|
24018
24038
|
artifacts.push({
|
|
24019
24039
|
component: "cursor agent",
|
|
24020
|
-
path:
|
|
24040
|
+
path: path29.join(cursorPaths.agents, `${agentEntry}.md`),
|
|
24021
24041
|
kind: "compiled",
|
|
24022
24042
|
expectedTarget: "cursor",
|
|
24023
24043
|
expectedSource: `agents/${agentEntry}.md`
|
|
@@ -24054,13 +24074,13 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
24054
24074
|
);
|
|
24055
24075
|
addCompiledGlobPlans(
|
|
24056
24076
|
artifacts,
|
|
24057
|
-
|
|
24077
|
+
path29.join(clinePaths.rules, "*.md"),
|
|
24058
24078
|
"cline",
|
|
24059
24079
|
"cline rule residue"
|
|
24060
24080
|
);
|
|
24061
24081
|
addCompiledGlobPlans(
|
|
24062
24082
|
artifacts,
|
|
24063
|
-
|
|
24083
|
+
path29.join(clinePaths.workflows, "*.md"),
|
|
24064
24084
|
"cline",
|
|
24065
24085
|
"cline workflow residue"
|
|
24066
24086
|
);
|
|
@@ -24088,7 +24108,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
24088
24108
|
for (const ruleEntry of runtime.kitInfo.components.rules.declared) {
|
|
24089
24109
|
artifacts.push({
|
|
24090
24110
|
component: "cline rule",
|
|
24091
|
-
path:
|
|
24111
|
+
path: path29.join(clinePaths.rules, `${ruleEntry}.md`),
|
|
24092
24112
|
kind: "compiled",
|
|
24093
24113
|
expectedTarget: "cline",
|
|
24094
24114
|
expectedSource: `rules/${ruleEntry}.md`
|
|
@@ -24097,7 +24117,7 @@ function resolveKitManagedArtifacts(runtime, scope, selectedTools, manifest, cla
|
|
|
24097
24117
|
for (const commandEntry of runtime.kitInfo.components.commands.declared) {
|
|
24098
24118
|
artifacts.push({
|
|
24099
24119
|
component: "cline workflow",
|
|
24100
|
-
path:
|
|
24120
|
+
path: path29.join(clinePaths.workflows, `${commandEntry}.md`),
|
|
24101
24121
|
kind: "compiled",
|
|
24102
24122
|
expectedTarget: "cline",
|
|
24103
24123
|
expectedSource: `commands/${commandEntry}.md`
|
|
@@ -24432,12 +24452,12 @@ function resolveCopilotPaths(runtime, scope = "global", projectRoot) {
|
|
|
24432
24452
|
if (scope === "project") {
|
|
24433
24453
|
const root = projectRoot ?? process.cwd();
|
|
24434
24454
|
return {
|
|
24435
|
-
instructions:
|
|
24436
|
-
agents:
|
|
24437
|
-
prompts:
|
|
24438
|
-
skills:
|
|
24439
|
-
hooks:
|
|
24440
|
-
mcpSharedFile:
|
|
24455
|
+
instructions: path29.join(root, ".github", "copilot-instructions.md"),
|
|
24456
|
+
agents: path29.join(root, ".github", "agents"),
|
|
24457
|
+
prompts: path29.join(root, ".github", "prompts"),
|
|
24458
|
+
skills: path29.join(root, ".github", "skills"),
|
|
24459
|
+
hooks: path29.join(root, ".github", "hooks"),
|
|
24460
|
+
mcpSharedFile: path29.join(root, ".vscode", "mcp.json")
|
|
24441
24461
|
};
|
|
24442
24462
|
}
|
|
24443
24463
|
return {
|
|
@@ -24477,12 +24497,12 @@ function resolveCodexPaths(runtime, scope = "global", projectRoot) {
|
|
|
24477
24497
|
if (scope === "project") {
|
|
24478
24498
|
const root = projectRoot ?? process.cwd();
|
|
24479
24499
|
return {
|
|
24480
|
-
instructions:
|
|
24481
|
-
agents:
|
|
24482
|
-
rules:
|
|
24483
|
-
skills:
|
|
24484
|
-
hooksSharedFile:
|
|
24485
|
-
mcpSharedFile:
|
|
24500
|
+
instructions: path29.join(root, "AGENTS.md"),
|
|
24501
|
+
agents: path29.join(root, ".codex", "agents"),
|
|
24502
|
+
rules: path29.join(root, ".codex", "rules"),
|
|
24503
|
+
skills: path29.join(root, ".codex", "skills"),
|
|
24504
|
+
hooksSharedFile: path29.join(root, ".codex", "hooks.json"),
|
|
24505
|
+
mcpSharedFile: path29.join(root, ".codex", "config.toml")
|
|
24486
24506
|
};
|
|
24487
24507
|
}
|
|
24488
24508
|
return {
|
|
@@ -24511,7 +24531,7 @@ function resolveSharedHookScriptsPath(runtime, scope, projectRoot) {
|
|
|
24511
24531
|
}
|
|
24512
24532
|
}
|
|
24513
24533
|
if (scope === "project") {
|
|
24514
|
-
return
|
|
24534
|
+
return path29.join(projectRoot ?? process.cwd(), ".agents", "hooks");
|
|
24515
24535
|
}
|
|
24516
24536
|
return resolveTargetPath("~/.agents/hooks");
|
|
24517
24537
|
}
|
|
@@ -24532,7 +24552,7 @@ function resolveSharedSkillsPath(runtime, scope, projectRoot) {
|
|
|
24532
24552
|
}
|
|
24533
24553
|
}
|
|
24534
24554
|
if (scope === "project") {
|
|
24535
|
-
return
|
|
24555
|
+
return path29.join(projectRoot ?? process.cwd(), ".agents", "skills");
|
|
24536
24556
|
}
|
|
24537
24557
|
return resolveTargetPath("~/.agents/skills");
|
|
24538
24558
|
}
|
|
@@ -24717,7 +24737,7 @@ function isKitPointer(artifact) {
|
|
|
24717
24737
|
}
|
|
24718
24738
|
try {
|
|
24719
24739
|
const recordedPath = fs29.readFileSync(artifact.path, "utf8").trim();
|
|
24720
|
-
return recordedPath.length > 0 &&
|
|
24740
|
+
return recordedPath.length > 0 && path29.resolve(recordedPath) === path29.resolve(artifact.expectedPath);
|
|
24721
24741
|
} catch {
|
|
24722
24742
|
return false;
|
|
24723
24743
|
}
|
|
@@ -24882,7 +24902,7 @@ function restoreBackup(backup, logger) {
|
|
|
24882
24902
|
logger.warn(` backup not found: ${backup.backupLocation}`);
|
|
24883
24903
|
return;
|
|
24884
24904
|
}
|
|
24885
|
-
const destDir =
|
|
24905
|
+
const destDir = path29.dirname(backup.originalPath);
|
|
24886
24906
|
fs29.mkdirSync(destDir, { recursive: true });
|
|
24887
24907
|
if (fs29.lstatSync(backup.backupLocation).isDirectory()) {
|
|
24888
24908
|
fs29.cpSync(backup.backupLocation, backup.originalPath, {
|
|
@@ -25044,7 +25064,7 @@ function cleanupCopilot(config, sourceRoot, configDir, logger) {
|
|
|
25044
25064
|
logger
|
|
25045
25065
|
);
|
|
25046
25066
|
removeManagedJsonFile(
|
|
25047
|
-
|
|
25067
|
+
path30.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
|
|
25048
25068
|
"_tangyr",
|
|
25049
25069
|
logger
|
|
25050
25070
|
);
|
|
@@ -25206,7 +25226,7 @@ function removeManagedDirectPath(artifactPath, config, sourceRoot, component, lo
|
|
|
25206
25226
|
}
|
|
25207
25227
|
}
|
|
25208
25228
|
function removeManagedCompiledFiles(dir, pattern, expectedTarget, logger) {
|
|
25209
|
-
for (const filePath of ts(
|
|
25229
|
+
for (const filePath of ts(path30.join(dir, pattern)).sort()) {
|
|
25210
25230
|
removeManagedCompiledFile(filePath, expectedTarget, logger);
|
|
25211
25231
|
}
|
|
25212
25232
|
}
|
|
@@ -25317,7 +25337,7 @@ function toVerbosity(value) {
|
|
|
25317
25337
|
// src/commands/detect.ts
|
|
25318
25338
|
import fs31 from "fs";
|
|
25319
25339
|
import os5 from "os";
|
|
25320
|
-
import
|
|
25340
|
+
import path31 from "path";
|
|
25321
25341
|
import { spawnSync } from "child_process";
|
|
25322
25342
|
var copilotEditorCommands = [
|
|
25323
25343
|
"code",
|
|
@@ -25449,7 +25469,7 @@ function detectEditorExtension(label, matchesExtension, logger, dependencies = {
|
|
|
25449
25469
|
}
|
|
25450
25470
|
}
|
|
25451
25471
|
for (const relativeDirectory of copilotExtensionDirectories) {
|
|
25452
|
-
const extensionDirectory =
|
|
25472
|
+
const extensionDirectory = path31.join(homeDirectory, relativeDirectory);
|
|
25453
25473
|
if (!pathExists(extensionDirectory)) {
|
|
25454
25474
|
continue;
|
|
25455
25475
|
}
|
|
@@ -25472,7 +25492,7 @@ function cursorExecutablePaths(platform, homeDirectory) {
|
|
|
25472
25492
|
}
|
|
25473
25493
|
return [
|
|
25474
25494
|
...systemPaths,
|
|
25475
|
-
|
|
25495
|
+
path31.join(
|
|
25476
25496
|
homeDirectory,
|
|
25477
25497
|
"Applications/Cursor.app/Contents/Resources/app/bin/cursor"
|
|
25478
25498
|
)
|
|
@@ -25533,7 +25553,7 @@ function logDetectionError(attemptedCommand, error, logger) {
|
|
|
25533
25553
|
|
|
25534
25554
|
// src/commands/doctor.ts
|
|
25535
25555
|
import fs32 from "fs";
|
|
25536
|
-
import
|
|
25556
|
+
import path32 from "path";
|
|
25537
25557
|
function runDoctorCommand(options, logger) {
|
|
25538
25558
|
const { config, configDir, configPath, sourceRoot } = resolveRuntime(
|
|
25539
25559
|
options,
|
|
@@ -25543,7 +25563,7 @@ function runDoctorCommand(options, logger) {
|
|
|
25543
25563
|
if (!fs32.existsSync(configPath)) {
|
|
25544
25564
|
findings.push(`${configPath}: missing`);
|
|
25545
25565
|
}
|
|
25546
|
-
const hooksJsonPath =
|
|
25566
|
+
const hooksJsonPath = path32.join(
|
|
25547
25567
|
sourceRoot,
|
|
25548
25568
|
config.source.hooks,
|
|
25549
25569
|
"hooks.json"
|
|
@@ -25619,18 +25639,18 @@ function checkClaudeCode(options, findings, config, sourceRoot, configDir, logge
|
|
|
25619
25639
|
projectRoot
|
|
25620
25640
|
)) {
|
|
25621
25641
|
const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
|
|
25622
|
-
const sourcePath = artifact.sourceKey ?
|
|
25642
|
+
const sourcePath = artifact.sourceKey ? path32.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
|
|
25623
25643
|
if (artifactClass === "managed-stale") {
|
|
25624
25644
|
findings.push(
|
|
25625
25645
|
`${artifact.component}: managed stale artifact at ${artifact.path}`
|
|
25626
25646
|
);
|
|
25627
25647
|
if (options.fix && sourcePath && isOurStaleSymlink(
|
|
25628
25648
|
artifact.path,
|
|
25629
|
-
/* @__PURE__ */ new Set([
|
|
25649
|
+
/* @__PURE__ */ new Set([path32.resolve(artifact.path)]),
|
|
25630
25650
|
config
|
|
25631
25651
|
)) {
|
|
25632
25652
|
fs32.unlinkSync(artifact.path);
|
|
25633
|
-
ensureDir(
|
|
25653
|
+
ensureDir(path32.dirname(artifact.path));
|
|
25634
25654
|
const symlinkType = fs32.statSync(sourcePath).isDirectory() ? "dir" : "file";
|
|
25635
25655
|
createRelativeSymlink(sourcePath, artifact.path, symlinkType, {
|
|
25636
25656
|
logger,
|
|
@@ -25644,8 +25664,8 @@ function checkClaudeCode(options, findings, config, sourceRoot, configDir, logge
|
|
|
25644
25664
|
logger.info(`${artifact.component}: recreated managed symlink`);
|
|
25645
25665
|
}
|
|
25646
25666
|
}
|
|
25647
|
-
if (options.fix && !fs32.existsSync(
|
|
25648
|
-
ensureDir(
|
|
25667
|
+
if (options.fix && !fs32.existsSync(path32.dirname(artifact.path))) {
|
|
25668
|
+
ensureDir(path32.dirname(artifact.path));
|
|
25649
25669
|
}
|
|
25650
25670
|
checkParentWritablePath(artifact.path, artifact.component, findings);
|
|
25651
25671
|
}
|
|
@@ -25667,7 +25687,7 @@ function slotsForScope2(config, sourceRoot, configDir, target, options) {
|
|
|
25667
25687
|
});
|
|
25668
25688
|
const resolved = {};
|
|
25669
25689
|
for (const [slot, value] of Object.entries(projectSlots)) {
|
|
25670
|
-
resolved[slot] = typeof value === "string" ?
|
|
25690
|
+
resolved[slot] = typeof value === "string" ? path32.resolve(root, value) : value;
|
|
25671
25691
|
}
|
|
25672
25692
|
return resolved;
|
|
25673
25693
|
}
|
|
@@ -25687,7 +25707,7 @@ function checkCopilot(config, sourceRoot, configDir, findings, options) {
|
|
|
25687
25707
|
continue;
|
|
25688
25708
|
}
|
|
25689
25709
|
const label = `copilot: ${rawPath}`;
|
|
25690
|
-
if (key.endsWith("_shared_file") ||
|
|
25710
|
+
if (key.endsWith("_shared_file") || path32.extname(rawPath).length > 0) {
|
|
25691
25711
|
checkParentWritablePath(resolveTargetPath(rawPath), label, findings);
|
|
25692
25712
|
continue;
|
|
25693
25713
|
}
|
|
@@ -25713,7 +25733,7 @@ function checkCodex(config, sourceRoot, configDir, findings, logger, options) {
|
|
|
25713
25733
|
continue;
|
|
25714
25734
|
}
|
|
25715
25735
|
const label = `codex: ${rawPath}`;
|
|
25716
|
-
if (key.endsWith("_shared_file") ||
|
|
25736
|
+
if (key.endsWith("_shared_file") || path32.extname(rawPath).length > 0) {
|
|
25717
25737
|
checkParentWritablePath(resolveTargetPath(rawPath), label, findings);
|
|
25718
25738
|
continue;
|
|
25719
25739
|
}
|
|
@@ -25730,13 +25750,13 @@ function resolveHooksScriptPath(config, sourceRoot, configDir) {
|
|
|
25730
25750
|
scope: "global",
|
|
25731
25751
|
mappings: mappings.platformPaths
|
|
25732
25752
|
});
|
|
25733
|
-
return
|
|
25753
|
+
return path32.join(profile["claude-code"].hooks, "scripts");
|
|
25734
25754
|
} catch {
|
|
25735
25755
|
return resolveTargetPath("~/.agents/hooks/scripts");
|
|
25736
25756
|
}
|
|
25737
25757
|
}
|
|
25738
25758
|
function checkParentWritablePath(targetPath, label, findings) {
|
|
25739
|
-
checkWritablePath(
|
|
25759
|
+
checkWritablePath(path32.dirname(targetPath), `${label} parent`, findings);
|
|
25740
25760
|
}
|
|
25741
25761
|
function checkWritablePath(checkPath, label, findings) {
|
|
25742
25762
|
if (!fs32.existsSync(checkPath)) {
|
|
@@ -25753,7 +25773,7 @@ function walkHookScripts(dir) {
|
|
|
25753
25773
|
if (!fs32.existsSync(dir)) {
|
|
25754
25774
|
return [];
|
|
25755
25775
|
}
|
|
25756
|
-
return fs32.readdirSync(dir).map((entry) =>
|
|
25776
|
+
return fs32.readdirSync(dir).map((entry) => path32.join(dir, entry)).filter((entryPath) => fs32.statSync(entryPath).isFile());
|
|
25757
25777
|
}
|
|
25758
25778
|
function fixManagedHookScriptModes(scriptRoot, sourceRoot, logger) {
|
|
25759
25779
|
if (!fs32.existsSync(scriptRoot)) {
|
|
@@ -25770,16 +25790,16 @@ function fixManagedHookScriptModes(scriptRoot, sourceRoot, logger) {
|
|
|
25770
25790
|
}
|
|
25771
25791
|
}
|
|
25772
25792
|
function hasSymlinkAncestor(targetPath, stopAt) {
|
|
25773
|
-
const relative =
|
|
25774
|
-
|
|
25775
|
-
|
|
25793
|
+
const relative = path32.relative(
|
|
25794
|
+
path32.resolve(stopAt),
|
|
25795
|
+
path32.resolve(targetPath)
|
|
25776
25796
|
);
|
|
25777
|
-
if (relative.startsWith("..") ||
|
|
25797
|
+
if (relative.startsWith("..") || path32.isAbsolute(relative)) {
|
|
25778
25798
|
return false;
|
|
25779
25799
|
}
|
|
25780
|
-
return relative.split(
|
|
25781
|
-
const candidate =
|
|
25782
|
-
|
|
25800
|
+
return relative.split(path32.sep).some((_segment, index, segments) => {
|
|
25801
|
+
const candidate = path32.join(
|
|
25802
|
+
path32.resolve(stopAt),
|
|
25783
25803
|
...segments.slice(0, index + 1)
|
|
25784
25804
|
);
|
|
25785
25805
|
try {
|
|
@@ -25790,8 +25810,8 @@ function hasSymlinkAncestor(targetPath, stopAt) {
|
|
|
25790
25810
|
});
|
|
25791
25811
|
}
|
|
25792
25812
|
function isInside(childPath, parentPath) {
|
|
25793
|
-
const relative =
|
|
25794
|
-
return relative.length === 0 || !relative.startsWith("..") && !
|
|
25813
|
+
const relative = path32.relative(parentPath, childPath);
|
|
25814
|
+
return relative.length === 0 || !relative.startsWith("..") && !path32.isAbsolute(relative);
|
|
25795
25815
|
}
|
|
25796
25816
|
function realPathOrInput2(filePath) {
|
|
25797
25817
|
try {
|
|
@@ -25803,12 +25823,12 @@ function realPathOrInput2(filePath) {
|
|
|
25803
25823
|
|
|
25804
25824
|
// src/commands/init.ts
|
|
25805
25825
|
import fs33 from "fs";
|
|
25806
|
-
import
|
|
25826
|
+
import path33 from "path";
|
|
25807
25827
|
var import_yaml7 = __toESM(require_dist(), 1);
|
|
25808
25828
|
async function runInitCommand(_options, logger) {
|
|
25809
25829
|
const sourceRoot = await dist_default6({
|
|
25810
25830
|
message: "Canonical Tangyr kit root",
|
|
25811
|
-
default:
|
|
25831
|
+
default: path33.resolve("projects/tangyr/agent-coding")
|
|
25812
25832
|
});
|
|
25813
25833
|
const componentCount = [
|
|
25814
25834
|
"CLAUDE.md",
|
|
@@ -25818,7 +25838,7 @@ async function runInitCommand(_options, logger) {
|
|
|
25818
25838
|
"rules",
|
|
25819
25839
|
"hooks"
|
|
25820
25840
|
].filter(
|
|
25821
|
-
(relativePath) => fs33.existsSync(
|
|
25841
|
+
(relativePath) => fs33.existsSync(path33.join(sourceRoot, relativePath))
|
|
25822
25842
|
).length;
|
|
25823
25843
|
const detectedTargets = detectTargets(logger);
|
|
25824
25844
|
const enabledTargets = await dist_default4({
|
|
@@ -25838,7 +25858,7 @@ async function runInitCommand(_options, logger) {
|
|
|
25838
25858
|
value
|
|
25839
25859
|
}))
|
|
25840
25860
|
});
|
|
25841
|
-
const configPath =
|
|
25861
|
+
const configPath = path33.join(sourceRoot, "tangyr.config.yaml");
|
|
25842
25862
|
if (fs33.existsSync(configPath)) {
|
|
25843
25863
|
const overwrite = await dist_default5({
|
|
25844
25864
|
message: `${configPath} exists. Overwrite?`,
|
|
@@ -25893,14 +25913,14 @@ function toConflictPolicy2(value) {
|
|
|
25893
25913
|
|
|
25894
25914
|
// src/commands/install.ts
|
|
25895
25915
|
import fs47 from "fs";
|
|
25896
|
-
import
|
|
25916
|
+
import path50 from "path";
|
|
25897
25917
|
|
|
25898
25918
|
// src/core/channel-state.ts
|
|
25899
25919
|
import fs34 from "fs";
|
|
25900
|
-
import
|
|
25920
|
+
import path34 from "path";
|
|
25901
25921
|
var CHANNEL_STATE_FILENAME = ".tangyr-channels.json";
|
|
25902
25922
|
function stateFilePath(cacheRoot) {
|
|
25903
|
-
return
|
|
25923
|
+
return path34.join(cacheRoot, CHANNEL_STATE_FILENAME);
|
|
25904
25924
|
}
|
|
25905
25925
|
function channelKey(kit, channel) {
|
|
25906
25926
|
return `${kit}/${channel}`;
|
|
@@ -25956,7 +25976,7 @@ function writeChannelSequence(params) {
|
|
|
25956
25976
|
[key]: { sequence, version, seenAt: now.toISOString() }
|
|
25957
25977
|
};
|
|
25958
25978
|
const filePath = stateFilePath(cacheRoot);
|
|
25959
|
-
fs34.mkdirSync(
|
|
25979
|
+
fs34.mkdirSync(path34.dirname(filePath), { recursive: true, mode: 448 });
|
|
25960
25980
|
const tempPath = `${filePath}.${process.pid}.tmp`;
|
|
25961
25981
|
fs34.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
|
|
25962
25982
|
`, {
|
|
@@ -25979,7 +25999,7 @@ var DEFAULT_CHANNEL = "stable";
|
|
|
25979
25999
|
|
|
25980
26000
|
// src/core/materialize.ts
|
|
25981
26001
|
import fs35 from "fs";
|
|
25982
|
-
import
|
|
26002
|
+
import path35 from "path";
|
|
25983
26003
|
|
|
25984
26004
|
// src/core/integrity.ts
|
|
25985
26005
|
import crypto3 from "crypto";
|
|
@@ -26315,7 +26335,7 @@ function assertFileWithinCeiling(entryPath, byteLength) {
|
|
|
26315
26335
|
}
|
|
26316
26336
|
var WINDOWS_DRIVE_ABSOLUTE = /^[a-zA-Z]:[\\/]/u;
|
|
26317
26337
|
function sanitizeBundleFilePath(entryPath, stagingDir) {
|
|
26318
|
-
if (
|
|
26338
|
+
if (path35.isAbsolute(entryPath) || WINDOWS_DRIVE_ABSOLUTE.test(entryPath)) {
|
|
26319
26339
|
throw new IntegrityError(
|
|
26320
26340
|
`Bundle file path "${entryPath}" is absolute \u2014 every file inside a bundle must use a relative path (REQ-INT-004).`
|
|
26321
26341
|
);
|
|
@@ -26331,13 +26351,13 @@ function sanitizeBundleFilePath(entryPath, stagingDir) {
|
|
|
26331
26351
|
`Bundle file path "${entryPath}" contains a ".." segment \u2014 directory traversal is rejected (REQ-INT-004).`
|
|
26332
26352
|
);
|
|
26333
26353
|
}
|
|
26334
|
-
const resolved =
|
|
26354
|
+
const resolved = path35.resolve(stagingDir, entryPath);
|
|
26335
26355
|
if (resolved === stagingDir) {
|
|
26336
26356
|
throw new IntegrityError(
|
|
26337
26357
|
`Bundle file path "${entryPath}" resolves to the staging directory itself \u2014 every entry must be a file inside it (REQ-INT-004).`
|
|
26338
26358
|
);
|
|
26339
26359
|
}
|
|
26340
|
-
if (!resolved.startsWith(stagingDir +
|
|
26360
|
+
if (!resolved.startsWith(stagingDir + path35.sep)) {
|
|
26341
26361
|
throw new IntegrityError(
|
|
26342
26362
|
`Bundle file path "${entryPath}" escapes the staging directory \u2014 refusing to write (REQ-INT-004).`
|
|
26343
26363
|
);
|
|
@@ -26389,7 +26409,7 @@ function verifyBundleFileHashes(bundle) {
|
|
|
26389
26409
|
function writeStagedFiles(stagingDir, decoded) {
|
|
26390
26410
|
for (const [rawPath, bytes] of decoded) {
|
|
26391
26411
|
const target = sanitizeBundleFilePath(rawPath, stagingDir);
|
|
26392
|
-
fs35.mkdirSync(
|
|
26412
|
+
fs35.mkdirSync(path35.dirname(target), { recursive: true, mode: 448 });
|
|
26393
26413
|
let existingStat;
|
|
26394
26414
|
try {
|
|
26395
26415
|
existingStat = fs35.lstatSync(target);
|
|
@@ -26801,7 +26821,7 @@ function sleep(ms2) {
|
|
|
26801
26821
|
|
|
26802
26822
|
// src/core/kit-coverage.ts
|
|
26803
26823
|
import fs36 from "fs";
|
|
26804
|
-
import
|
|
26824
|
+
import path36 from "path";
|
|
26805
26825
|
var COVERED_CATEGORIES = [
|
|
26806
26826
|
"agents",
|
|
26807
26827
|
"commands",
|
|
@@ -26859,35 +26879,35 @@ function deliveredPaths(manifest, outcomes = []) {
|
|
|
26859
26879
|
const delivered = /* @__PURE__ */ new Set();
|
|
26860
26880
|
for (const artifact of manifest?.artifacts ?? []) {
|
|
26861
26881
|
if (artifact.path) {
|
|
26862
|
-
delivered.add(
|
|
26882
|
+
delivered.add(path36.resolve(artifact.path));
|
|
26863
26883
|
}
|
|
26864
26884
|
}
|
|
26865
26885
|
for (const link of manifest?.managedLinks ?? []) {
|
|
26866
26886
|
if (link.path) {
|
|
26867
|
-
delivered.add(
|
|
26887
|
+
delivered.add(path36.resolve(link.path));
|
|
26868
26888
|
}
|
|
26869
26889
|
}
|
|
26870
26890
|
for (const outcome of outcomes) {
|
|
26871
26891
|
if (outcome.status === "success" || outcome.status === "skipped-current") {
|
|
26872
|
-
delivered.add(
|
|
26892
|
+
delivered.add(path36.resolve(outcome.path));
|
|
26873
26893
|
}
|
|
26874
26894
|
}
|
|
26875
26895
|
return delivered;
|
|
26876
26896
|
}
|
|
26877
26897
|
function wasDelivered(candidate, delivered) {
|
|
26878
|
-
const resolved =
|
|
26898
|
+
const resolved = path36.resolve(candidate);
|
|
26879
26899
|
let current = resolved;
|
|
26880
26900
|
for (; ; ) {
|
|
26881
26901
|
if (delivered.has(current)) {
|
|
26882
26902
|
return true;
|
|
26883
26903
|
}
|
|
26884
|
-
const parent =
|
|
26904
|
+
const parent = path36.dirname(current);
|
|
26885
26905
|
if (parent === current) {
|
|
26886
26906
|
break;
|
|
26887
26907
|
}
|
|
26888
26908
|
current = parent;
|
|
26889
26909
|
}
|
|
26890
|
-
const prefix = `${resolved}${
|
|
26910
|
+
const prefix = `${resolved}${path36.sep}`;
|
|
26891
26911
|
for (const one of delivered) {
|
|
26892
26912
|
if (one.startsWith(prefix)) {
|
|
26893
26913
|
return true;
|
|
@@ -26923,12 +26943,12 @@ function inSlot(slotPath, name, delivered) {
|
|
|
26923
26943
|
);
|
|
26924
26944
|
if (named.length > 0) {
|
|
26925
26945
|
return named.some(
|
|
26926
|
-
(entry) => wasDelivered(
|
|
26946
|
+
(entry) => wasDelivered(path36.join(slotPath, entry), delivered)
|
|
26927
26947
|
) ? true : null;
|
|
26928
26948
|
}
|
|
26929
26949
|
let found2 = false;
|
|
26930
26950
|
for (const entry of entries) {
|
|
26931
|
-
const full =
|
|
26951
|
+
const full = path36.join(slotPath, entry);
|
|
26932
26952
|
try {
|
|
26933
26953
|
if (!fs36.statSync(full).isFile()) {
|
|
26934
26954
|
continue;
|
|
@@ -27038,7 +27058,7 @@ function explain(target, category, surfaces, hasSurface, contestedByPath, lossRe
|
|
|
27038
27058
|
return `${displacedByName.join(", ")}: a file of that name is in ${where}, and this installation did not write it \u2014 the kit's version is not there`;
|
|
27039
27059
|
}
|
|
27040
27060
|
if (FOLDS_INTO_INSTRUCTIONS.has(category) && surfaces.instructions) {
|
|
27041
|
-
const contested = contestedByPath.get(
|
|
27061
|
+
const contested = contestedByPath.get(path36.resolve(surfaces.instructions));
|
|
27042
27062
|
if (contested && contested.survivor !== null && contested.survivor !== target) {
|
|
27043
27063
|
return `folded into ${display(surfaces.instructions, projectRoot)}, which ${contested.survivor} wrote last`;
|
|
27044
27064
|
}
|
|
@@ -27054,7 +27074,7 @@ function display(target, projectRoot) {
|
|
|
27054
27074
|
if (!projectRoot) {
|
|
27055
27075
|
return target;
|
|
27056
27076
|
}
|
|
27057
|
-
const relative =
|
|
27077
|
+
const relative = path36.relative(projectRoot, target);
|
|
27058
27078
|
return relative.startsWith("..") ? target : relative;
|
|
27059
27079
|
}
|
|
27060
27080
|
function reportKitCoverage(coverage, logger) {
|
|
@@ -27132,7 +27152,7 @@ function declaredComponents(kit) {
|
|
|
27132
27152
|
|
|
27133
27153
|
// src/adapters/claude-code.ts
|
|
27134
27154
|
import fs39 from "fs";
|
|
27135
|
-
import
|
|
27155
|
+
import path40 from "path";
|
|
27136
27156
|
|
|
27137
27157
|
// src/core/shim.ts
|
|
27138
27158
|
import crypto4 from "crypto";
|
|
@@ -27155,7 +27175,7 @@ ${SHIM_BODY}`;
|
|
|
27155
27175
|
|
|
27156
27176
|
// src/core/skills-slot.ts
|
|
27157
27177
|
import fs37 from "fs";
|
|
27158
|
-
import
|
|
27178
|
+
import path37 from "path";
|
|
27159
27179
|
function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
|
|
27160
27180
|
if (!isSymlinkPath(destination)) {
|
|
27161
27181
|
return false;
|
|
@@ -27196,7 +27216,7 @@ function syncSkillsSlot(sync) {
|
|
|
27196
27216
|
if (isLegacyWholesaleSymlink) {
|
|
27197
27217
|
for (const name of foreignSkillNames(source, declaredNames)) {
|
|
27198
27218
|
logger.info(
|
|
27199
|
-
`[dry-run] skills: migrate foreign skill ${
|
|
27219
|
+
`[dry-run] skills: migrate foreign skill ${path37.join(source, name)} -> ${path37.join(destination, name)}`
|
|
27200
27220
|
);
|
|
27201
27221
|
}
|
|
27202
27222
|
logger.info(
|
|
@@ -27204,9 +27224,9 @@ function syncSkillsSlot(sync) {
|
|
|
27204
27224
|
);
|
|
27205
27225
|
}
|
|
27206
27226
|
for (const name of declaredNames ?? listSkillDirNames(source)) {
|
|
27207
|
-
const skillDestination =
|
|
27227
|
+
const skillDestination = path37.join(destination, name);
|
|
27208
27228
|
logger.info(
|
|
27209
|
-
`[dry-run] skills: symlink ${
|
|
27229
|
+
`[dry-run] skills: symlink ${path37.join(source, name)} -> ${skillDestination}`
|
|
27210
27230
|
);
|
|
27211
27231
|
outcomes2.push({
|
|
27212
27232
|
component: "skills",
|
|
@@ -27233,8 +27253,8 @@ function syncSkillsSlot(sync) {
|
|
|
27233
27253
|
}
|
|
27234
27254
|
function syncSingleSkill(sync, name) {
|
|
27235
27255
|
const { config, sourceRoot, source, destination } = sync;
|
|
27236
|
-
const skillSource =
|
|
27237
|
-
const skillDestination =
|
|
27256
|
+
const skillSource = path37.join(source, name);
|
|
27257
|
+
const skillDestination = path37.join(destination, name);
|
|
27238
27258
|
if (!fs37.existsSync(skillSource)) {
|
|
27239
27259
|
return {
|
|
27240
27260
|
component: "skills",
|
|
@@ -27265,8 +27285,8 @@ function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logge
|
|
|
27265
27285
|
fs37.unlinkSync(destination);
|
|
27266
27286
|
ensureDir(destination);
|
|
27267
27287
|
for (const name of foreignNames) {
|
|
27268
|
-
const from =
|
|
27269
|
-
const to =
|
|
27288
|
+
const from = path37.join(source, name);
|
|
27289
|
+
const to = path37.join(destination, name);
|
|
27270
27290
|
if (fs37.existsSync(to)) {
|
|
27271
27291
|
logger.warn(
|
|
27272
27292
|
`skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
|
|
@@ -27308,23 +27328,23 @@ function isSymlinkTo2(linkPath, source) {
|
|
|
27308
27328
|
}
|
|
27309
27329
|
|
|
27310
27330
|
// src/core/hook-scripts.ts
|
|
27311
|
-
import
|
|
27331
|
+
import path38 from "path";
|
|
27312
27332
|
function hookScriptsDir(bridge, target, projectRoot) {
|
|
27313
27333
|
const globalBridge = resolveTargetPath("~/.agents/hooks");
|
|
27314
|
-
if (
|
|
27334
|
+
if (path38.resolve(bridge) === path38.resolve(globalBridge)) {
|
|
27315
27335
|
return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
|
|
27316
27336
|
}
|
|
27317
|
-
const relative =
|
|
27318
|
-
const insideProject = !relative.startsWith("..") && !
|
|
27337
|
+
const relative = path38.relative(projectRoot ?? process.cwd(), bridge);
|
|
27338
|
+
const insideProject = !relative.startsWith("..") && !path38.isAbsolute(relative) && relative !== "";
|
|
27319
27339
|
const variable = PROJECT_DIR_VARIABLE[target];
|
|
27320
27340
|
if (insideProject && variable) {
|
|
27321
|
-
const posix =
|
|
27322
|
-
relative.split(
|
|
27341
|
+
const posix = path38.posix.join(
|
|
27342
|
+
relative.split(path38.sep).join("/"),
|
|
27323
27343
|
"scripts"
|
|
27324
27344
|
);
|
|
27325
27345
|
return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
|
|
27326
27346
|
}
|
|
27327
|
-
return { prefix:
|
|
27347
|
+
return { prefix: path38.join(bridge, "scripts"), machineLocal: true };
|
|
27328
27348
|
}
|
|
27329
27349
|
var PROJECT_DIR_VARIABLE = {
|
|
27330
27350
|
"claude-code": "$CLAUDE_PROJECT_DIR"
|
|
@@ -27335,18 +27355,18 @@ function machineLocalScriptPathNotice(target, prefix) {
|
|
|
27335
27355
|
|
|
27336
27356
|
// src/core/instructions-source.ts
|
|
27337
27357
|
import fs38 from "fs";
|
|
27338
|
-
import
|
|
27358
|
+
import path39 from "path";
|
|
27339
27359
|
var PORTABLE_INSTRUCTIONS_NAME = "AGENTS.md";
|
|
27340
27360
|
var InstructionsSourceMissingError = class extends Error {
|
|
27341
27361
|
constructor(kitRoot, expected, declaredBy) {
|
|
27342
27362
|
super(
|
|
27343
|
-
`${
|
|
27363
|
+
`${path39.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.`
|
|
27344
27364
|
);
|
|
27345
27365
|
this.name = "InstructionsSourceMissingError";
|
|
27346
27366
|
}
|
|
27347
27367
|
};
|
|
27348
27368
|
function normalizeLabel(kitRoot, file) {
|
|
27349
|
-
return
|
|
27369
|
+
return path39.relative(kitRoot, file).split(path39.sep).join("/");
|
|
27350
27370
|
}
|
|
27351
27371
|
function isExplicitOverride(configured) {
|
|
27352
27372
|
const normalize = (value) => value.replace(/\\/gu, "/").replace(/^\.\//u, "");
|
|
@@ -27355,7 +27375,7 @@ function isExplicitOverride(configured) {
|
|
|
27355
27375
|
function resolveInstructionsSource(kitRoot, config) {
|
|
27356
27376
|
const configured = config.source.instructions;
|
|
27357
27377
|
if (isExplicitOverride(configured)) {
|
|
27358
|
-
const file =
|
|
27378
|
+
const file = path39.resolve(kitRoot, configured);
|
|
27359
27379
|
if (!fs38.existsSync(file)) {
|
|
27360
27380
|
throw new InstructionsSourceMissingError(
|
|
27361
27381
|
kitRoot,
|
|
@@ -27371,7 +27391,7 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
27371
27391
|
}
|
|
27372
27392
|
const declared = resolveKitEntrypointName(kitRoot);
|
|
27373
27393
|
if (declared !== void 0) {
|
|
27374
|
-
const file =
|
|
27394
|
+
const file = path39.resolve(kitRoot, declared);
|
|
27375
27395
|
if (!fs38.existsSync(file)) {
|
|
27376
27396
|
throw new InstructionsSourceMissingError(
|
|
27377
27397
|
kitRoot,
|
|
@@ -27386,12 +27406,12 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
27386
27406
|
};
|
|
27387
27407
|
}
|
|
27388
27408
|
for (const name of [DEFAULT_ENTRYPOINT, PORTABLE_INSTRUCTIONS_NAME]) {
|
|
27389
|
-
const file =
|
|
27409
|
+
const file = path39.resolve(kitRoot, name);
|
|
27390
27410
|
if (fs38.existsSync(file)) {
|
|
27391
27411
|
return { file, label: name, origin: "convention" };
|
|
27392
27412
|
}
|
|
27393
27413
|
}
|
|
27394
|
-
const legacy =
|
|
27414
|
+
const legacy = path39.resolve(kitRoot, LEGACY_ENTRYPOINT);
|
|
27395
27415
|
if (fs38.existsSync(legacy)) {
|
|
27396
27416
|
return {
|
|
27397
27417
|
file: legacy,
|
|
@@ -27404,7 +27424,7 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
27404
27424
|
}
|
|
27405
27425
|
function instructionsSourcePath(kitRoot, config) {
|
|
27406
27426
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
27407
|
-
return resolved ? resolved.file :
|
|
27427
|
+
return resolved ? resolved.file : path39.resolve(kitRoot, config.source.instructions);
|
|
27408
27428
|
}
|
|
27409
27429
|
function instructionsSourceLabel(kitRoot, config) {
|
|
27410
27430
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
@@ -27525,7 +27545,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
27525
27545
|
if (!shouldSkipComponent(options, "hooks")) {
|
|
27526
27546
|
outcomes.push(
|
|
27527
27547
|
syncHookScriptsBridge({
|
|
27528
|
-
source:
|
|
27548
|
+
source: path40.resolve(sourceRoot, config.source.hooks),
|
|
27529
27549
|
destination: profile.hook_scripts,
|
|
27530
27550
|
config,
|
|
27531
27551
|
sourceRoot,
|
|
@@ -27586,13 +27606,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
27586
27606
|
}
|
|
27587
27607
|
function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
|
|
27588
27608
|
if (!mappings.modelTiers.custom_provider) return;
|
|
27589
|
-
const agentsDir =
|
|
27609
|
+
const agentsDir = path40.join(sourceRoot, config.source.agents);
|
|
27590
27610
|
if (!fs39.existsSync(agentsDir)) return;
|
|
27591
|
-
for (const agentFile of ts(
|
|
27611
|
+
for (const agentFile of ts(path40.join(agentsDir, "*.md")).sort()) {
|
|
27592
27612
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
27593
27613
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
27594
27614
|
if (hasProvider) {
|
|
27595
|
-
const basename =
|
|
27615
|
+
const basename = path40.basename(agentFile);
|
|
27596
27616
|
addLoss(lossReport, "claude-code", "agents", {
|
|
27597
27617
|
source: `agents/${basename}`,
|
|
27598
27618
|
fields: [
|
|
@@ -27622,6 +27642,14 @@ function lstatOrNull(p) {
|
|
|
27622
27642
|
return null;
|
|
27623
27643
|
}
|
|
27624
27644
|
}
|
|
27645
|
+
function recordShimState(manifest, shimPath) {
|
|
27646
|
+
addArtifactToManifest(manifest, {
|
|
27647
|
+
relativePath: SHIM_MANIFEST_KEY,
|
|
27648
|
+
path: shimPath,
|
|
27649
|
+
hash: describeArtifactState(shimPath) ?? `target:${shimPath}`,
|
|
27650
|
+
origin: "tangyr-managed"
|
|
27651
|
+
});
|
|
27652
|
+
}
|
|
27625
27653
|
function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath, logger) {
|
|
27626
27654
|
const expectedBodyHash = shimBodyHash();
|
|
27627
27655
|
const shimContent = buildAgentsMdShim(shimPath, agentsMdPath, "claude-code");
|
|
@@ -27642,8 +27670,9 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
27642
27670
|
origin: "tangyr-managed"
|
|
27643
27671
|
});
|
|
27644
27672
|
writeManifest(scopePath, manifest);
|
|
27645
|
-
fs39.mkdirSync(
|
|
27673
|
+
fs39.mkdirSync(path40.dirname(shimPath), { recursive: true });
|
|
27646
27674
|
fs39.writeFileSync(shimPath, shimContent);
|
|
27675
|
+
recordShimState(manifest, shimPath);
|
|
27647
27676
|
logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
|
|
27648
27677
|
return;
|
|
27649
27678
|
}
|
|
@@ -27651,12 +27680,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
27651
27680
|
const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
|
|
27652
27681
|
const marker = extractProvenanceMarker(firstNonEmptyLine);
|
|
27653
27682
|
if (marker !== null && marker.hash === expectedBodyHash) {
|
|
27654
|
-
|
|
27655
|
-
relativePath: SHIM_MANIFEST_KEY,
|
|
27656
|
-
path: shimPath,
|
|
27657
|
-
hash: expectedBodyHash,
|
|
27658
|
-
origin: "tangyr-managed"
|
|
27659
|
-
});
|
|
27683
|
+
recordShimState(manifest, shimPath);
|
|
27660
27684
|
logger?.verbose(
|
|
27661
27685
|
`instructions-shim: already current, skipped -> ${shimPath}`
|
|
27662
27686
|
);
|
|
@@ -27665,16 +27689,11 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
27665
27689
|
backupFile(shimPath, manifest, scopePath);
|
|
27666
27690
|
writeManifest(scopePath, manifest);
|
|
27667
27691
|
fs39.writeFileSync(shimPath, shimContent);
|
|
27668
|
-
|
|
27669
|
-
relativePath: SHIM_MANIFEST_KEY,
|
|
27670
|
-
path: shimPath,
|
|
27671
|
-
hash: expectedBodyHash,
|
|
27672
|
-
origin: "tangyr-managed"
|
|
27673
|
-
});
|
|
27692
|
+
recordShimState(manifest, shimPath);
|
|
27674
27693
|
logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
|
|
27675
27694
|
}
|
|
27676
27695
|
function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
|
|
27677
|
-
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) :
|
|
27696
|
+
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path40.resolve(sourceRoot, config.source[directComponent.sourceKey]);
|
|
27678
27697
|
const sourceLabel = directComponent.sourceKey === "instructions" ? instructionsSourceLabel(sourceRoot, config) : config.source[directComponent.sourceKey];
|
|
27679
27698
|
const destination = directComponent.destination;
|
|
27680
27699
|
if (!fs39.existsSync(source)) {
|
|
@@ -27711,7 +27730,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
27711
27730
|
} else if (artifactClass === "managed-compiled") {
|
|
27712
27731
|
fs39.unlinkSync(destination);
|
|
27713
27732
|
}
|
|
27714
|
-
ensureDir(
|
|
27733
|
+
ensureDir(path40.dirname(destination));
|
|
27715
27734
|
createRelativeSymlink(source, destination, directComponent.type, {
|
|
27716
27735
|
logger,
|
|
27717
27736
|
provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
|
|
@@ -27731,7 +27750,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
27731
27750
|
return syncSkillsSlot({
|
|
27732
27751
|
config,
|
|
27733
27752
|
sourceRoot,
|
|
27734
|
-
source:
|
|
27753
|
+
source: path40.resolve(sourceRoot, config.source.skills),
|
|
27735
27754
|
destination,
|
|
27736
27755
|
dryRun: options.dryRun,
|
|
27737
27756
|
logger,
|
|
@@ -27780,7 +27799,7 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
|
|
|
27780
27799
|
};
|
|
27781
27800
|
}
|
|
27782
27801
|
function syncMcp(config, sourceRoot, options, logger, destination, manifest) {
|
|
27783
|
-
const source =
|
|
27802
|
+
const source = path40.resolve(sourceRoot, config.source.mcp);
|
|
27784
27803
|
if (!fs39.existsSync(source)) {
|
|
27785
27804
|
return skippedMissingSource("mcp", source);
|
|
27786
27805
|
}
|
|
@@ -27822,7 +27841,7 @@ function syncMcp(config, sourceRoot, options, logger, destination, manifest) {
|
|
|
27822
27841
|
};
|
|
27823
27842
|
}
|
|
27824
27843
|
function syncSettings(config, sourceRoot, options, logger, destination, manifest) {
|
|
27825
|
-
const source =
|
|
27844
|
+
const source = path40.resolve(sourceRoot, config.source.settings);
|
|
27826
27845
|
if (!fs39.existsSync(source)) {
|
|
27827
27846
|
return skippedMissingSource("settings", source);
|
|
27828
27847
|
}
|
|
@@ -27926,15 +27945,15 @@ function isRecord3(value) {
|
|
|
27926
27945
|
}
|
|
27927
27946
|
|
|
27928
27947
|
// src/adapters/codex.ts
|
|
27929
|
-
var TOML3 = __toESM(require_toml(), 1);
|
|
27930
27948
|
import crypto6 from "crypto";
|
|
27931
27949
|
import fs42 from "fs";
|
|
27932
|
-
|
|
27950
|
+
var TOML3 = __toESM(require_toml(), 1);
|
|
27951
|
+
import path44 from "path";
|
|
27933
27952
|
|
|
27934
27953
|
// src/compiler/agents.ts
|
|
27935
27954
|
var TOML = __toESM(require_toml(), 1);
|
|
27936
27955
|
var import_yaml8 = __toESM(require_dist(), 1);
|
|
27937
|
-
import
|
|
27956
|
+
import path41 from "path";
|
|
27938
27957
|
var writeCapabilityClasses = /* @__PURE__ */ new Set(["filesystem-write", "shell-execution"]);
|
|
27939
27958
|
var copilotToolAliasesByClass = {
|
|
27940
27959
|
delegation: "agent",
|
|
@@ -27946,7 +27965,7 @@ var copilotToolAliasesByClass = {
|
|
|
27946
27965
|
};
|
|
27947
27966
|
function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
27948
27967
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
27949
|
-
const relativeSource = `agents/${
|
|
27968
|
+
const relativeSource = `agents/${path41.basename(sourceFile)}`;
|
|
27950
27969
|
if (target === "opencode") {
|
|
27951
27970
|
return compileOpenCodeAgent(
|
|
27952
27971
|
sourceFile,
|
|
@@ -27987,7 +28006,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
|
27987
28006
|
mappings,
|
|
27988
28007
|
lossReport
|
|
27989
28008
|
);
|
|
27990
|
-
const overlayKey = `agents/${
|
|
28009
|
+
const overlayKey = `agents/${path41.basename(sourceFile, ".md")}.${target}.yaml`;
|
|
27991
28010
|
const targetFields = {
|
|
27992
28011
|
...translated.fields,
|
|
27993
28012
|
...extensions[overlayKey] ?? {}
|
|
@@ -28021,7 +28040,7 @@ ${TOML.stringify({
|
|
|
28021
28040
|
function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
28022
28041
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
28023
28042
|
throw new Error(
|
|
28024
|
-
`${
|
|
28043
|
+
`${path41.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
|
|
28025
28044
|
);
|
|
28026
28045
|
}
|
|
28027
28046
|
const frontmatter = {
|
|
@@ -28075,7 +28094,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
|
|
|
28075
28094
|
"permission",
|
|
28076
28095
|
"permission-coarsening"
|
|
28077
28096
|
),
|
|
28078
|
-
detail: `${
|
|
28097
|
+
detail: `${path41.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
|
|
28079
28098
|
}
|
|
28080
28099
|
]
|
|
28081
28100
|
});
|
|
@@ -28100,7 +28119,7 @@ ${(0, import_yaml8.stringify)(frontmatter).trim()}
|
|
|
28100
28119
|
function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
28101
28120
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
28102
28121
|
throw new Error(
|
|
28103
|
-
`${
|
|
28122
|
+
`${path41.basename(sourceFile)}: Cursor agent requires a non-empty description field`
|
|
28104
28123
|
);
|
|
28105
28124
|
}
|
|
28106
28125
|
const frontmatter = {
|
|
@@ -28137,7 +28156,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
28137
28156
|
"permission",
|
|
28138
28157
|
"permission-coarsening"
|
|
28139
28158
|
),
|
|
28140
|
-
detail: `${
|
|
28159
|
+
detail: `${path41.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
|
|
28141
28160
|
}
|
|
28142
28161
|
]
|
|
28143
28162
|
});
|
|
@@ -28156,7 +28175,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
28156
28175
|
"provider",
|
|
28157
28176
|
"provider-not-representable"
|
|
28158
28177
|
),
|
|
28159
|
-
detail: `${
|
|
28178
|
+
detail: `${path41.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
28160
28179
|
}
|
|
28161
28180
|
]
|
|
28162
28181
|
});
|
|
@@ -28188,7 +28207,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
|
|
|
28188
28207
|
"persona",
|
|
28189
28208
|
"persona-not-representable"
|
|
28190
28209
|
),
|
|
28191
|
-
detail: `${
|
|
28210
|
+
detail: `${path41.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
|
|
28192
28211
|
}
|
|
28193
28212
|
]
|
|
28194
28213
|
});
|
|
@@ -28243,7 +28262,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
28243
28262
|
field,
|
|
28244
28263
|
"model-not-representable"
|
|
28245
28264
|
),
|
|
28246
|
-
detail: `${
|
|
28265
|
+
detail: `${path41.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
|
|
28247
28266
|
});
|
|
28248
28267
|
return;
|
|
28249
28268
|
}
|
|
@@ -28261,9 +28280,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
28261
28280
|
lossReport,
|
|
28262
28281
|
target,
|
|
28263
28282
|
"agents",
|
|
28264
|
-
`agents/${
|
|
28283
|
+
`agents/${path41.basename(sourceFile)}`,
|
|
28265
28284
|
"info",
|
|
28266
|
-
`${
|
|
28285
|
+
`${path41.basename(sourceFile)}: ${field} is delivered through another managed surface.`
|
|
28267
28286
|
);
|
|
28268
28287
|
return;
|
|
28269
28288
|
}
|
|
@@ -28272,7 +28291,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
28272
28291
|
field,
|
|
28273
28292
|
action: entryType,
|
|
28274
28293
|
severity: resolveLossSeverity("agent-field", field, entryType),
|
|
28275
|
-
detail: `${
|
|
28294
|
+
detail: `${path41.basename(sourceFile)}: ${field} has no emitted field for this target.`
|
|
28276
28295
|
});
|
|
28277
28296
|
}
|
|
28278
28297
|
function mapToolsToCapabilities(value, mappings) {
|
|
@@ -28303,7 +28322,7 @@ function recordCodexToolCoarsening(sourceFile, tools, sandboxMode, losses) {
|
|
|
28303
28322
|
// reads, and the exit code it forces teaches `--ignore-errors`, which is
|
|
28304
28323
|
// how the losses that ARE actionable get missed.
|
|
28305
28324
|
severity: "warning",
|
|
28306
|
-
detail: `${
|
|
28325
|
+
detail: `${path41.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.`
|
|
28307
28326
|
});
|
|
28308
28327
|
}
|
|
28309
28328
|
function deriveCodexSandbox(value, mappings) {
|
|
@@ -28724,12 +28743,12 @@ function addHookLoss(lossReport, target, eventName, sourceLabel, severity, reaso
|
|
|
28724
28743
|
// src/compiler/command-as-skill.ts
|
|
28725
28744
|
var import_yaml9 = __toESM(require_dist(), 1);
|
|
28726
28745
|
import fs40 from "fs";
|
|
28727
|
-
import
|
|
28746
|
+
import path42 from "path";
|
|
28728
28747
|
var CARRIED_OVER = ["argument-hint", "agent", "launch"];
|
|
28729
28748
|
function compileCommandAsSkill(commandFile, target) {
|
|
28730
|
-
const name =
|
|
28749
|
+
const name = path42.basename(commandFile, ".md");
|
|
28731
28750
|
const { data, body } = parseMarkdownFrontmatter(commandFile);
|
|
28732
|
-
const relativeSource = `commands/${
|
|
28751
|
+
const relativeSource = `commands/${path42.basename(commandFile)}`;
|
|
28733
28752
|
const description = typeof data.description === "string" && data.description.trim().length > 0 ? data.description.trim() : `The ${name} command.`;
|
|
28734
28753
|
const frontmatter = { name, description };
|
|
28735
28754
|
for (const key of CARRIED_OVER) {
|
|
@@ -28756,7 +28775,7 @@ function compileCommandsAsSkills(commandsRoot, target) {
|
|
|
28756
28775
|
return [];
|
|
28757
28776
|
}
|
|
28758
28777
|
return fs40.readdirSync(commandsRoot).filter((entry) => entry.endsWith(".md")).sort().map(
|
|
28759
|
-
(entry) => compileCommandAsSkill(
|
|
28778
|
+
(entry) => compileCommandAsSkill(path42.join(commandsRoot, entry), target)
|
|
28760
28779
|
);
|
|
28761
28780
|
}
|
|
28762
28781
|
|
|
@@ -29039,7 +29058,7 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
|
|
|
29039
29058
|
}
|
|
29040
29059
|
|
|
29041
29060
|
// src/compiler/rules.ts
|
|
29042
|
-
import
|
|
29061
|
+
import path43 from "path";
|
|
29043
29062
|
var import_yaml10 = __toESM(require_dist(), 1);
|
|
29044
29063
|
import fs41 from "fs";
|
|
29045
29064
|
function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
@@ -29060,13 +29079,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
|
29060
29079
|
}
|
|
29061
29080
|
const appendixParts = [];
|
|
29062
29081
|
const dotRulesFiles = [];
|
|
29063
|
-
for (const ruleFile of ts(
|
|
29082
|
+
for (const ruleFile of ts(path43.join(sourceRulesDir, "*.md")).sort()) {
|
|
29064
29083
|
const parsed = parseRule(ruleFile);
|
|
29065
|
-
const name =
|
|
29084
|
+
const name = path43.basename(ruleFile, ".md");
|
|
29066
29085
|
if (parsed.mode === "exec-policy") {
|
|
29067
29086
|
dotRulesFiles.push({
|
|
29068
29087
|
name: `${name}.rules`,
|
|
29069
|
-
content: `${formatProvenanceMarker("toml", `rules/${
|
|
29088
|
+
content: `${formatProvenanceMarker("toml", `rules/${path43.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
|
|
29070
29089
|
${parsed.body}`
|
|
29071
29090
|
});
|
|
29072
29091
|
continue;
|
|
@@ -29075,7 +29094,7 @@ ${parsed.body}`
|
|
|
29075
29094
|
|
|
29076
29095
|
${parsed.body.trim()}`);
|
|
29077
29096
|
addLoss(lossReport, "codex", "rules", {
|
|
29078
|
-
source: `rules/${
|
|
29097
|
+
source: `rules/${path43.basename(ruleFile)}`,
|
|
29079
29098
|
fields: [
|
|
29080
29099
|
{
|
|
29081
29100
|
field: "mode",
|
|
@@ -29085,7 +29104,7 @@ ${parsed.body.trim()}`);
|
|
|
29085
29104
|
"mode",
|
|
29086
29105
|
"rule-as-instruction"
|
|
29087
29106
|
),
|
|
29088
|
-
detail: `${
|
|
29107
|
+
detail: `${path43.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
|
|
29089
29108
|
}
|
|
29090
29109
|
]
|
|
29091
29110
|
});
|
|
@@ -29117,14 +29136,14 @@ function isRuleMode(value) {
|
|
|
29117
29136
|
}
|
|
29118
29137
|
function compileOpenCodeRules(sourceRulesDir, lossReport) {
|
|
29119
29138
|
const appendixParts = [];
|
|
29120
|
-
for (const ruleFile of ts(
|
|
29139
|
+
for (const ruleFile of ts(path43.join(sourceRulesDir, "*.md")).sort()) {
|
|
29121
29140
|
const parsed = parseRule(ruleFile);
|
|
29122
|
-
const name =
|
|
29141
|
+
const name = path43.basename(ruleFile, ".md");
|
|
29123
29142
|
appendixParts.push(`## ${name}
|
|
29124
29143
|
|
|
29125
29144
|
${parsed.body.trim()}`);
|
|
29126
29145
|
addLoss(lossReport, "opencode", "rules", {
|
|
29127
|
-
source: `rules/${
|
|
29146
|
+
source: `rules/${path43.basename(ruleFile)}`,
|
|
29128
29147
|
fields: [
|
|
29129
29148
|
{
|
|
29130
29149
|
field: "rule",
|
|
@@ -29134,7 +29153,7 @@ ${parsed.body.trim()}`);
|
|
|
29134
29153
|
"rule",
|
|
29135
29154
|
"rule-path-scoping"
|
|
29136
29155
|
),
|
|
29137
|
-
detail: `${
|
|
29156
|
+
detail: `${path43.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to its instructions file`
|
|
29138
29157
|
}
|
|
29139
29158
|
]
|
|
29140
29159
|
});
|
|
@@ -29143,9 +29162,9 @@ ${parsed.body.trim()}`);
|
|
|
29143
29162
|
}
|
|
29144
29163
|
function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
29145
29164
|
const dotRulesFiles = [];
|
|
29146
|
-
for (const ruleFile of ts(
|
|
29165
|
+
for (const ruleFile of ts(path43.join(sourceRulesDir, "*.md")).sort()) {
|
|
29147
29166
|
const content = fs41.readFileSync(ruleFile, "utf8");
|
|
29148
|
-
const name =
|
|
29167
|
+
const name = path43.basename(ruleFile, ".md");
|
|
29149
29168
|
let frontmatterData = {};
|
|
29150
29169
|
let body = content;
|
|
29151
29170
|
if (content.startsWith("---\n")) {
|
|
@@ -29174,7 +29193,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
|
29174
29193
|
}
|
|
29175
29194
|
const marker = formatProvenanceMarker(
|
|
29176
29195
|
"markdown",
|
|
29177
|
-
`rules/${
|
|
29196
|
+
`rules/${path43.basename(ruleFile)}`,
|
|
29178
29197
|
computeSourceHash(ruleFile),
|
|
29179
29198
|
"cursor"
|
|
29180
29199
|
);
|
|
@@ -29190,9 +29209,9 @@ ${body}`;
|
|
|
29190
29209
|
}
|
|
29191
29210
|
function compileClineRules(sourceRulesDir, lossReport) {
|
|
29192
29211
|
const dotRulesFiles = [];
|
|
29193
|
-
for (const ruleFile of ts(
|
|
29212
|
+
for (const ruleFile of ts(path43.join(sourceRulesDir, "*.md")).sort()) {
|
|
29194
29213
|
const content = fs41.readFileSync(ruleFile, "utf8");
|
|
29195
|
-
const name =
|
|
29214
|
+
const name = path43.basename(ruleFile, ".md");
|
|
29196
29215
|
let frontmatterData = {};
|
|
29197
29216
|
let body = content;
|
|
29198
29217
|
if (content.startsWith("---\n")) {
|
|
@@ -29209,13 +29228,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
29209
29228
|
}
|
|
29210
29229
|
const marker = formatProvenanceMarker(
|
|
29211
29230
|
"markdown",
|
|
29212
|
-
`rules/${
|
|
29231
|
+
`rules/${path43.basename(ruleFile)}`,
|
|
29213
29232
|
computeSourceHash(ruleFile),
|
|
29214
29233
|
"cline"
|
|
29215
29234
|
);
|
|
29216
29235
|
if (frontmatterData.mode === "exec-policy") {
|
|
29217
29236
|
addLoss(lossReport, "cline", "rules", {
|
|
29218
|
-
source: `rules/${
|
|
29237
|
+
source: `rules/${path43.basename(ruleFile)}`,
|
|
29219
29238
|
fields: [
|
|
29220
29239
|
{
|
|
29221
29240
|
field: "mode",
|
|
@@ -29225,7 +29244,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
29225
29244
|
"mode",
|
|
29226
29245
|
"rule-mode-downgrade"
|
|
29227
29246
|
),
|
|
29228
|
-
detail: `${
|
|
29247
|
+
detail: `${path43.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
|
|
29229
29248
|
}
|
|
29230
29249
|
]
|
|
29231
29250
|
});
|
|
@@ -29249,8 +29268,8 @@ function compileCopilotRules(sourceRulesDir) {
|
|
|
29249
29268
|
return [];
|
|
29250
29269
|
}
|
|
29251
29270
|
const files = [];
|
|
29252
|
-
for (const ruleFile of ts(
|
|
29253
|
-
const name =
|
|
29271
|
+
for (const ruleFile of ts(path43.join(sourceRulesDir, "*.md")).sort()) {
|
|
29272
|
+
const name = path43.basename(ruleFile, ".md");
|
|
29254
29273
|
const { data } = parseMarkdownFrontmatter(ruleFile);
|
|
29255
29274
|
const { body } = parseRule(ruleFile);
|
|
29256
29275
|
const declared = data.paths;
|
|
@@ -29259,7 +29278,7 @@ function compileCopilotRules(sourceRulesDir) {
|
|
|
29259
29278
|
"---",
|
|
29260
29279
|
`applyTo: ${JSON.stringify(applyTo)}`,
|
|
29261
29280
|
"x-tangyr:",
|
|
29262
|
-
` source: rules/${
|
|
29281
|
+
` source: rules/${path43.basename(ruleFile)}`,
|
|
29263
29282
|
` hash: ${computeSourceHash(ruleFile)}`,
|
|
29264
29283
|
" target: copilot",
|
|
29265
29284
|
"---"
|
|
@@ -29296,7 +29315,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
29296
29315
|
rules: profile.rules
|
|
29297
29316
|
};
|
|
29298
29317
|
const rules = compileRules(
|
|
29299
|
-
|
|
29318
|
+
path44.join(sourceRoot, config.source.rules),
|
|
29300
29319
|
"codex",
|
|
29301
29320
|
mappings,
|
|
29302
29321
|
lossReport
|
|
@@ -29376,7 +29395,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
29376
29395
|
if (!shouldSkipComponent2(options, "hooks")) {
|
|
29377
29396
|
outcomes.push(
|
|
29378
29397
|
syncHookScriptsBridge({
|
|
29379
|
-
source:
|
|
29398
|
+
source: path44.resolve(sourceRoot, config.source.hooks),
|
|
29380
29399
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
29381
29400
|
config,
|
|
29382
29401
|
sourceRoot,
|
|
@@ -29477,9 +29496,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
29477
29496
|
function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
|
|
29478
29497
|
const cp = mappings.modelTiers.custom_provider;
|
|
29479
29498
|
if (!cp) return "";
|
|
29480
|
-
const agentsDir =
|
|
29499
|
+
const agentsDir = path44.join(sourceRoot, config.source.agents);
|
|
29481
29500
|
if (!fs42.existsSync(agentsDir)) return "";
|
|
29482
|
-
const agentFiles = ts(
|
|
29501
|
+
const agentFiles = ts(path44.join(agentsDir, "*.md")).sort();
|
|
29483
29502
|
const hasProviderAgent = agentFiles.some((agentFile) => {
|
|
29484
29503
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
29485
29504
|
return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
@@ -29544,7 +29563,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
29544
29563
|
}
|
|
29545
29564
|
];
|
|
29546
29565
|
for (const ruleFile of rules.dotRulesFiles) {
|
|
29547
|
-
const destination =
|
|
29566
|
+
const destination = path44.join(rulesRoot, ruleFile.name);
|
|
29548
29567
|
if (options.dryRun) {
|
|
29549
29568
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
29550
29569
|
outcomes.push({
|
|
@@ -29583,7 +29602,7 @@ function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, lo
|
|
|
29583
29602
|
${agentsAppendix}`.trim();
|
|
29584
29603
|
const marker = formatProvenanceMarker(
|
|
29585
29604
|
"markdown",
|
|
29586
|
-
|
|
29605
|
+
path44.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
29587
29606
|
hashString(composed),
|
|
29588
29607
|
"codex"
|
|
29589
29608
|
);
|
|
@@ -29613,7 +29632,7 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
29613
29632
|
return syncSkillsSlot({
|
|
29614
29633
|
config,
|
|
29615
29634
|
sourceRoot,
|
|
29616
|
-
source:
|
|
29635
|
+
source: path44.resolve(sourceRoot, config.source.skills),
|
|
29617
29636
|
destination: resolveTargetPath(paths.skills),
|
|
29618
29637
|
dryRun: options.dryRun,
|
|
29619
29638
|
logger,
|
|
@@ -29628,13 +29647,13 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
29628
29647
|
});
|
|
29629
29648
|
}
|
|
29630
29649
|
function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, logger, manifest, scopePath) {
|
|
29631
|
-
const commandsRoot =
|
|
29650
|
+
const commandsRoot = path44.resolve(sourceRoot, config.source.commands);
|
|
29632
29651
|
if (!fs42.existsSync(commandsRoot)) {
|
|
29633
29652
|
return [skippedMissingSource2("commands", commandsRoot)];
|
|
29634
29653
|
}
|
|
29635
29654
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
29636
29655
|
return compileCommandsAsSkills(commandsRoot, "codex").map((skill) => {
|
|
29637
|
-
const destination =
|
|
29656
|
+
const destination = path44.join(skillsRoot, skill.name, "SKILL.md");
|
|
29638
29657
|
if (options.dryRun) {
|
|
29639
29658
|
logger.info(
|
|
29640
29659
|
`[dry-run] commands: compile ${skill.relativeSource} -> ${destination}`
|
|
@@ -29660,16 +29679,16 @@ function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, l
|
|
|
29660
29679
|
});
|
|
29661
29680
|
}
|
|
29662
29681
|
function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29663
|
-
const sourceAgentsRoot =
|
|
29682
|
+
const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
|
|
29664
29683
|
if (!fs42.existsSync(sourceAgentsRoot)) {
|
|
29665
29684
|
return [skippedMissingSource2("agents", sourceAgentsRoot)];
|
|
29666
29685
|
}
|
|
29667
|
-
const sourceAgents = ts(
|
|
29686
|
+
const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
|
|
29668
29687
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29669
29688
|
return sourceAgents.map((agentFile) => {
|
|
29670
|
-
const destination =
|
|
29689
|
+
const destination = path44.join(
|
|
29671
29690
|
agentsRoot,
|
|
29672
|
-
`${
|
|
29691
|
+
`${path44.basename(agentFile, ".md")}.toml`
|
|
29673
29692
|
);
|
|
29674
29693
|
const compiled = compileAgent(
|
|
29675
29694
|
agentFile,
|
|
@@ -29801,10 +29820,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
|
|
|
29801
29820
|
if (artifactClass === "managed-compiled" && !options.force && isCompiledCurrent(destination, content, expectedHash)) {
|
|
29802
29821
|
return { component, status: "skipped-current", path: destination };
|
|
29803
29822
|
}
|
|
29823
|
+
if (artifactClass === "managed-compiled" && !options.force && hasDriftedSinceInstall(destination, manifest)) {
|
|
29824
|
+
logger.warn(
|
|
29825
|
+
`${destination}: edited since Tangyr wrote it \u2014 applying onConflict: ${config.onConflict}`
|
|
29826
|
+
);
|
|
29827
|
+
if (!handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
29828
|
+
return { component, status: "conflict", path: destination };
|
|
29829
|
+
}
|
|
29830
|
+
}
|
|
29804
29831
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
29805
29832
|
return { component, status: "conflict", path: destination };
|
|
29806
29833
|
}
|
|
29807
|
-
ensureDir(
|
|
29834
|
+
ensureDir(path44.dirname(destination));
|
|
29808
29835
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29809
29836
|
if (clearedLink !== null) {
|
|
29810
29837
|
logger.verbose(
|
|
@@ -29833,7 +29860,7 @@ ${managedMcpEnd}
|
|
|
29833
29860
|
if (current === next.trimStart()) {
|
|
29834
29861
|
return false;
|
|
29835
29862
|
}
|
|
29836
|
-
ensureDir(
|
|
29863
|
+
ensureDir(path44.dirname(destination));
|
|
29837
29864
|
fs42.writeFileSync(destination, next.trimStart());
|
|
29838
29865
|
return true;
|
|
29839
29866
|
}
|
|
@@ -29908,15 +29935,15 @@ function hashString(value) {
|
|
|
29908
29935
|
// src/adapters/copilot.ts
|
|
29909
29936
|
import crypto7 from "crypto";
|
|
29910
29937
|
import fs43 from "fs";
|
|
29911
|
-
import
|
|
29938
|
+
import path46 from "path";
|
|
29912
29939
|
|
|
29913
29940
|
// src/compiler/commands.ts
|
|
29914
29941
|
var import_yaml11 = __toESM(require_dist(), 1);
|
|
29915
|
-
import
|
|
29942
|
+
import path45 from "path";
|
|
29916
29943
|
function compileCommandPrompt(sourceFile) {
|
|
29917
29944
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
29918
|
-
const relativeSource = `commands/${
|
|
29919
|
-
const fields = promptFrontmatter(data,
|
|
29945
|
+
const relativeSource = `commands/${path45.basename(sourceFile)}`;
|
|
29946
|
+
const fields = promptFrontmatter(data, path45.basename(sourceFile, ".md"));
|
|
29920
29947
|
const marker = formatProvenanceMarker(
|
|
29921
29948
|
"markdown",
|
|
29922
29949
|
relativeSource,
|
|
@@ -30057,7 +30084,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
30057
30084
|
if (!shouldSkipComponent3(options, "hooks")) {
|
|
30058
30085
|
outcomes.push(
|
|
30059
30086
|
syncHookScriptsBridge({
|
|
30060
|
-
source:
|
|
30087
|
+
source: path46.resolve(sourceRoot, config.source.hooks),
|
|
30061
30088
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
30062
30089
|
config,
|
|
30063
30090
|
sourceRoot,
|
|
@@ -30138,13 +30165,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
30138
30165
|
}
|
|
30139
30166
|
function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
|
|
30140
30167
|
if (!mappings.modelTiers.custom_provider) return;
|
|
30141
|
-
const agentsDir =
|
|
30168
|
+
const agentsDir = path46.join(sourceRoot, config.source.agents);
|
|
30142
30169
|
if (!fs43.existsSync(agentsDir)) return;
|
|
30143
|
-
for (const agentFile of ts(
|
|
30170
|
+
for (const agentFile of ts(path46.join(agentsDir, "*.md")).sort()) {
|
|
30144
30171
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
30145
30172
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
30146
30173
|
if (hasProvider) {
|
|
30147
|
-
const basename =
|
|
30174
|
+
const basename = path46.basename(agentFile);
|
|
30148
30175
|
addLoss(lossReport, "copilot", "agents", {
|
|
30149
30176
|
source: `agents/${basename}`,
|
|
30150
30177
|
fields: [
|
|
@@ -30177,15 +30204,15 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
|
|
|
30177
30204
|
const contentHash = hashString2(rawContent);
|
|
30178
30205
|
const marker = formatProvenanceMarker(
|
|
30179
30206
|
"markdown",
|
|
30180
|
-
|
|
30207
|
+
path46.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30181
30208
|
contentHash,
|
|
30182
30209
|
"copilot"
|
|
30183
30210
|
);
|
|
30184
30211
|
const composedContent = `${marker}
|
|
30185
30212
|
${rawContent}`;
|
|
30186
30213
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
30187
|
-
const agentsMdDest =
|
|
30188
|
-
const mirrorDest =
|
|
30214
|
+
const agentsMdDest = path46.resolve(projectRoot, "AGENTS.md");
|
|
30215
|
+
const mirrorDest = path46.resolve(
|
|
30189
30216
|
projectRoot,
|
|
30190
30217
|
".github",
|
|
30191
30218
|
"copilot-instructions.md"
|
|
@@ -30236,10 +30263,18 @@ function writeInstructionsFile(component, destination, content, contentHash, con
|
|
|
30236
30263
|
if (artifactClass === "managed-compiled" && !options.force && isCompiledCurrent2(destination, content, contentHash)) {
|
|
30237
30264
|
return { component, status: "skipped-current", path: destination };
|
|
30238
30265
|
}
|
|
30266
|
+
if (artifactClass === "managed-compiled" && !options.force && hasDriftedSinceInstall(destination, manifest)) {
|
|
30267
|
+
logger.warn(
|
|
30268
|
+
`${destination}: edited since Tangyr wrote it \u2014 applying onConflict: ${config.onConflict}`
|
|
30269
|
+
);
|
|
30270
|
+
if (!handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
30271
|
+
return { component, status: "conflict", path: destination };
|
|
30272
|
+
}
|
|
30273
|
+
}
|
|
30239
30274
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
30240
30275
|
return { component, status: "conflict", path: destination };
|
|
30241
30276
|
}
|
|
30242
|
-
ensureDir(
|
|
30277
|
+
ensureDir(path46.dirname(destination));
|
|
30243
30278
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30244
30279
|
if (clearedLink !== null) {
|
|
30245
30280
|
logger.verbose(
|
|
@@ -30256,7 +30291,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
30256
30291
|
return syncSkillsSlot({
|
|
30257
30292
|
config,
|
|
30258
30293
|
sourceRoot,
|
|
30259
|
-
source:
|
|
30294
|
+
source: path46.resolve(sourceRoot, config.source.skills),
|
|
30260
30295
|
destination: resolveTargetPath(paths.skills),
|
|
30261
30296
|
dryRun: options.dryRun,
|
|
30262
30297
|
logger,
|
|
@@ -30271,16 +30306,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
30271
30306
|
});
|
|
30272
30307
|
}
|
|
30273
30308
|
function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30274
|
-
const sourceAgentsRoot =
|
|
30309
|
+
const sourceAgentsRoot = path46.join(sourceRoot, config.source.agents);
|
|
30275
30310
|
if (!fs43.existsSync(sourceAgentsRoot)) {
|
|
30276
30311
|
return [skippedMissingSource3("agents", sourceAgentsRoot)];
|
|
30277
30312
|
}
|
|
30278
|
-
const sourceAgents = ts(
|
|
30313
|
+
const sourceAgents = ts(path46.join(sourceAgentsRoot, "*.md")).sort();
|
|
30279
30314
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
30280
30315
|
return sourceAgents.map((agentFile) => {
|
|
30281
|
-
const destination =
|
|
30316
|
+
const destination = path46.join(
|
|
30282
30317
|
agentsRoot,
|
|
30283
|
-
`${
|
|
30318
|
+
`${path46.basename(agentFile, ".md")}.agent.md`
|
|
30284
30319
|
);
|
|
30285
30320
|
const compiled = compileAgent(
|
|
30286
30321
|
agentFile,
|
|
@@ -30308,16 +30343,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
30308
30343
|
});
|
|
30309
30344
|
}
|
|
30310
30345
|
function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30311
|
-
const sourceCommandsRoot =
|
|
30346
|
+
const sourceCommandsRoot = path46.join(sourceRoot, config.source.commands);
|
|
30312
30347
|
if (!fs43.existsSync(sourceCommandsRoot)) {
|
|
30313
30348
|
return [skippedMissingSource3("commands", sourceCommandsRoot)];
|
|
30314
30349
|
}
|
|
30315
|
-
const sourceCommands = ts(
|
|
30350
|
+
const sourceCommands = ts(path46.join(sourceCommandsRoot, "*.md")).sort();
|
|
30316
30351
|
const promptsRoot = resolveTargetPath(paths.prompts);
|
|
30317
30352
|
return sourceCommands.map((commandFile) => {
|
|
30318
|
-
const destination =
|
|
30353
|
+
const destination = path46.join(
|
|
30319
30354
|
promptsRoot,
|
|
30320
|
-
`${
|
|
30355
|
+
`${path46.basename(commandFile, ".md")}.prompt.md`
|
|
30321
30356
|
);
|
|
30322
30357
|
const compiled = compileCommandPrompt(commandFile);
|
|
30323
30358
|
if (options.dryRun) {
|
|
@@ -30341,7 +30376,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
|
|
|
30341
30376
|
});
|
|
30342
30377
|
}
|
|
30343
30378
|
function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
30344
|
-
const destination =
|
|
30379
|
+
const destination = path46.join(
|
|
30345
30380
|
resolveTargetPath(paths.hooks),
|
|
30346
30381
|
"tangyr-managed.json"
|
|
30347
30382
|
);
|
|
@@ -30430,13 +30465,13 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
30430
30465
|
);
|
|
30431
30466
|
}
|
|
30432
30467
|
function syncRules2(config, sourceRoot, rulesSlot, options, logger, manifest, scopePath) {
|
|
30433
|
-
const sourceRulesDir =
|
|
30468
|
+
const sourceRulesDir = path46.resolve(sourceRoot, config.source.rules);
|
|
30434
30469
|
if (!fs43.existsSync(sourceRulesDir)) {
|
|
30435
30470
|
return [skippedMissingSource3("rules", sourceRulesDir)];
|
|
30436
30471
|
}
|
|
30437
30472
|
const destinationRoot = resolveTargetPath(rulesSlot);
|
|
30438
30473
|
return compileCopilotRules(sourceRulesDir).map((file) => {
|
|
30439
|
-
const destination =
|
|
30474
|
+
const destination = path46.join(destinationRoot, file.name);
|
|
30440
30475
|
if (options.dryRun) {
|
|
30441
30476
|
logger.info(`[dry-run] rules: compile -> ${destination}`);
|
|
30442
30477
|
return {
|
|
@@ -30467,10 +30502,18 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
|
|
|
30467
30502
|
if (artifactClass === "managed-compiled" && !options.force && isCompiledCurrent2(destination, content, expectedHash)) {
|
|
30468
30503
|
return { component, status: "skipped-current", path: destination };
|
|
30469
30504
|
}
|
|
30505
|
+
if (artifactClass === "managed-compiled" && !options.force && hasDriftedSinceInstall(destination, manifest)) {
|
|
30506
|
+
logger.warn(
|
|
30507
|
+
`${destination}: edited since Tangyr wrote it \u2014 applying onConflict: ${config.onConflict}`
|
|
30508
|
+
);
|
|
30509
|
+
if (!handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
30510
|
+
return { component, status: "conflict", path: destination };
|
|
30511
|
+
}
|
|
30512
|
+
}
|
|
30470
30513
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
30471
30514
|
return { component, status: "conflict", path: destination };
|
|
30472
30515
|
}
|
|
30473
|
-
ensureDir(
|
|
30516
|
+
ensureDir(path46.dirname(destination));
|
|
30474
30517
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30475
30518
|
if (clearedLink !== null) {
|
|
30476
30519
|
logger.verbose(
|
|
@@ -30526,12 +30569,12 @@ function shouldSkipComponent3(options, component) {
|
|
|
30526
30569
|
function cleanupLegacyAgents(paths, options, logger) {
|
|
30527
30570
|
const currentAgentsRoot = resolveTargetPath(paths.agents);
|
|
30528
30571
|
const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
|
|
30529
|
-
if (
|
|
30572
|
+
if (path46.resolve(currentAgentsRoot) === path46.resolve(legacyAgentsRoot)) {
|
|
30530
30573
|
return [];
|
|
30531
30574
|
}
|
|
30532
30575
|
const outcomes = [];
|
|
30533
30576
|
for (const filePath of ts(
|
|
30534
|
-
|
|
30577
|
+
path46.join(legacyAgentsRoot, "*.agent.md")
|
|
30535
30578
|
).sort()) {
|
|
30536
30579
|
if (!isCopilotManagedCompiledFile(filePath)) {
|
|
30537
30580
|
continue;
|
|
@@ -30564,7 +30607,7 @@ function skippedMissingSource3(component, source) {
|
|
|
30564
30607
|
// src/adapters/cursor.ts
|
|
30565
30608
|
import crypto8 from "crypto";
|
|
30566
30609
|
import fs44 from "fs";
|
|
30567
|
-
import
|
|
30610
|
+
import path47 from "path";
|
|
30568
30611
|
function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30569
30612
|
const scope = options.scope ?? "global";
|
|
30570
30613
|
const profile = resolveTargetPaths({
|
|
@@ -30676,7 +30719,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
30676
30719
|
if (!shouldSkipComponent4(options, "hooks")) {
|
|
30677
30720
|
outcomes.push(
|
|
30678
30721
|
syncHookScriptsBridge({
|
|
30679
|
-
source:
|
|
30722
|
+
source: path47.resolve(sourceRoot, config.source.hooks),
|
|
30680
30723
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
30681
30724
|
config,
|
|
30682
30725
|
sourceRoot,
|
|
@@ -30741,7 +30784,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
|
|
|
30741
30784
|
const composed = composeCursorInstructions(config, sourceRoot, lossReport);
|
|
30742
30785
|
const marker = formatProvenanceMarker(
|
|
30743
30786
|
"markdown",
|
|
30744
|
-
|
|
30787
|
+
path47.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30745
30788
|
hashString3(composed),
|
|
30746
30789
|
"cursor"
|
|
30747
30790
|
);
|
|
@@ -30780,11 +30823,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
|
30780
30823
|
${personaContent}`.trim() : baseContent;
|
|
30781
30824
|
}
|
|
30782
30825
|
function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
30783
|
-
const agentsDir =
|
|
30826
|
+
const agentsDir = path47.join(sourceRoot, config.source.agents);
|
|
30784
30827
|
if (!fs44.existsSync(agentsDir)) {
|
|
30785
30828
|
return null;
|
|
30786
30829
|
}
|
|
30787
|
-
const agentFiles = ts(
|
|
30830
|
+
const agentFiles = ts(path47.join(agentsDir, "*.md")).sort();
|
|
30788
30831
|
if (agentFiles.length === 0) {
|
|
30789
30832
|
return null;
|
|
30790
30833
|
}
|
|
@@ -30807,7 +30850,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
30807
30850
|
return null;
|
|
30808
30851
|
}
|
|
30809
30852
|
addLoss(lossReport, "cursor", "instructions", {
|
|
30810
|
-
source: `agents/${
|
|
30853
|
+
source: `agents/${path47.basename(primaryFile)}`,
|
|
30811
30854
|
fields: [
|
|
30812
30855
|
{
|
|
30813
30856
|
field: "persona",
|
|
@@ -30817,23 +30860,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
30817
30860
|
"persona",
|
|
30818
30861
|
"instructions-shim"
|
|
30819
30862
|
),
|
|
30820
|
-
detail: `Primary persona from ${
|
|
30863
|
+
detail: `Primary persona from ${path47.basename(primaryFile)} folded into its instructions file (Cursor has no custom modes surface)`
|
|
30821
30864
|
}
|
|
30822
30865
|
]
|
|
30823
30866
|
});
|
|
30824
30867
|
return body.trim();
|
|
30825
30868
|
}
|
|
30826
30869
|
function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30827
|
-
const sourceAgentsRoot =
|
|
30870
|
+
const sourceAgentsRoot = path47.join(sourceRoot, config.source.agents);
|
|
30828
30871
|
if (!fs44.existsSync(sourceAgentsRoot)) {
|
|
30829
30872
|
return [skippedMissingSource4("agents", sourceAgentsRoot)];
|
|
30830
30873
|
}
|
|
30831
|
-
const sourceAgents = ts(
|
|
30874
|
+
const sourceAgents = ts(path47.join(sourceAgentsRoot, "*.md")).sort();
|
|
30832
30875
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
30833
30876
|
return sourceAgents.map((agentFile) => {
|
|
30834
|
-
const destination =
|
|
30877
|
+
const destination = path47.join(
|
|
30835
30878
|
agentsRoot,
|
|
30836
|
-
`${
|
|
30879
|
+
`${path47.basename(agentFile, ".md")}.md`
|
|
30837
30880
|
);
|
|
30838
30881
|
let compiled;
|
|
30839
30882
|
try {
|
|
@@ -30874,14 +30917,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
30874
30917
|
});
|
|
30875
30918
|
}
|
|
30876
30919
|
function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
30877
|
-
const sourceRulesDir =
|
|
30920
|
+
const sourceRulesDir = path47.join(sourceRoot, config.source.rules);
|
|
30878
30921
|
if (!fs44.existsSync(sourceRulesDir)) {
|
|
30879
30922
|
return [skippedMissingSource4("rules", sourceRulesDir)];
|
|
30880
30923
|
}
|
|
30881
30924
|
const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
|
|
30882
30925
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
30883
30926
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
30884
|
-
const destination =
|
|
30927
|
+
const destination = path47.join(rulesDir, name);
|
|
30885
30928
|
if (options.dryRun) {
|
|
30886
30929
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
30887
30930
|
return {
|
|
@@ -30905,15 +30948,15 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
30905
30948
|
});
|
|
30906
30949
|
}
|
|
30907
30950
|
function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30908
|
-
const sourceCommandsRoot =
|
|
30951
|
+
const sourceCommandsRoot = path47.join(sourceRoot, config.source.commands);
|
|
30909
30952
|
if (!fs44.existsSync(sourceCommandsRoot)) {
|
|
30910
30953
|
return [skippedMissingSource4("commands", sourceCommandsRoot)];
|
|
30911
30954
|
}
|
|
30912
|
-
const sourceCommands = ts(
|
|
30955
|
+
const sourceCommands = ts(path47.join(sourceCommandsRoot, "*.md")).sort();
|
|
30913
30956
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
30914
30957
|
return sourceCommands.map((commandFile) => {
|
|
30915
|
-
const baseName =
|
|
30916
|
-
const destination =
|
|
30958
|
+
const baseName = path47.basename(commandFile, ".md");
|
|
30959
|
+
const destination = path47.join(skillsRoot, baseName, "SKILL.md");
|
|
30917
30960
|
const { content } = compileCommandAsSkill(commandFile, "cursor");
|
|
30918
30961
|
if (options.dryRun) {
|
|
30919
30962
|
logger.info(
|
|
@@ -30943,7 +30986,7 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, _
|
|
|
30943
30986
|
return syncSkillsSlot({
|
|
30944
30987
|
config,
|
|
30945
30988
|
sourceRoot,
|
|
30946
|
-
source:
|
|
30989
|
+
source: path47.resolve(sourceRoot, config.source.skills),
|
|
30947
30990
|
destination,
|
|
30948
30991
|
dryRun: options.dryRun,
|
|
30949
30992
|
logger,
|
|
@@ -30991,7 +31034,7 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
30991
31034
|
}
|
|
30992
31035
|
const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
|
|
30993
31036
|
`;
|
|
30994
|
-
ensureDir(
|
|
31037
|
+
ensureDir(path47.dirname(destination));
|
|
30995
31038
|
fs44.writeFileSync(destination, hooksFileContent);
|
|
30996
31039
|
return { component: "hooks", status: "success", path: destination };
|
|
30997
31040
|
}
|
|
@@ -31055,13 +31098,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
|
|
|
31055
31098
|
);
|
|
31056
31099
|
}
|
|
31057
31100
|
function syncProviderPin(config, sourceRoot, lossReport) {
|
|
31058
|
-
const agentsDir =
|
|
31101
|
+
const agentsDir = path47.join(sourceRoot, config.source.agents);
|
|
31059
31102
|
if (!fs44.existsSync(agentsDir)) return;
|
|
31060
|
-
for (const agentFile of ts(
|
|
31103
|
+
for (const agentFile of ts(path47.join(agentsDir, "*.md")).sort()) {
|
|
31061
31104
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
31062
31105
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
31063
31106
|
if (hasCustomProvider) {
|
|
31064
|
-
const relativeSource = `agents/${
|
|
31107
|
+
const relativeSource = `agents/${path47.basename(agentFile)}`;
|
|
31065
31108
|
addLoss(lossReport, "cursor", "agents", {
|
|
31066
31109
|
source: relativeSource,
|
|
31067
31110
|
fields: [
|
|
@@ -31073,7 +31116,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
|
|
|
31073
31116
|
"provider",
|
|
31074
31117
|
"provider-not-representable"
|
|
31075
31118
|
),
|
|
31076
|
-
detail: `${
|
|
31119
|
+
detail: `${path47.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
31077
31120
|
}
|
|
31078
31121
|
]
|
|
31079
31122
|
});
|
|
@@ -31088,10 +31131,18 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
|
|
|
31088
31131
|
if (artifactClass === "managed-compiled" && !options.force && isCompiledCurrent3(destination, content, expectedHash)) {
|
|
31089
31132
|
return { component, status: "skipped-current", path: destination };
|
|
31090
31133
|
}
|
|
31134
|
+
if (artifactClass === "managed-compiled" && !options.force && hasDriftedSinceInstall(destination, manifest)) {
|
|
31135
|
+
logger.warn(
|
|
31136
|
+
`${destination}: edited since Tangyr wrote it \u2014 applying onConflict: ${config.onConflict}`
|
|
31137
|
+
);
|
|
31138
|
+
if (!handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
31139
|
+
return { component, status: "conflict", path: destination };
|
|
31140
|
+
}
|
|
31141
|
+
}
|
|
31091
31142
|
if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
31092
31143
|
return { component, status: "conflict", path: destination };
|
|
31093
31144
|
}
|
|
31094
|
-
ensureDir(
|
|
31145
|
+
ensureDir(path47.dirname(destination));
|
|
31095
31146
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
31096
31147
|
if (clearedLink !== null) {
|
|
31097
31148
|
logger.verbose(
|
|
@@ -31158,7 +31209,7 @@ function hashString3(value) {
|
|
|
31158
31209
|
// src/adapters/cline.ts
|
|
31159
31210
|
import crypto9 from "crypto";
|
|
31160
31211
|
import fs45 from "fs";
|
|
31161
|
-
import
|
|
31212
|
+
import path48 from "path";
|
|
31162
31213
|
function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
31163
31214
|
const scope = options.scope ?? "global";
|
|
31164
31215
|
const profile = resolveTargetPaths({
|
|
@@ -31271,7 +31322,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
31271
31322
|
function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
|
|
31272
31323
|
if (scope === "global" || paths.instructions === null) {
|
|
31273
31324
|
addLoss(lossReport, "cline", "instructions", {
|
|
31274
|
-
source:
|
|
31325
|
+
source: path48.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
31275
31326
|
fields: [
|
|
31276
31327
|
{
|
|
31277
31328
|
field: "instructions",
|
|
@@ -31296,7 +31347,7 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
|
|
|
31296
31347
|
const baseContent = fs45.existsSync(source) ? fs45.readFileSync(source, "utf8").trim() : "";
|
|
31297
31348
|
const marker = formatProvenanceMarker(
|
|
31298
31349
|
"markdown",
|
|
31299
|
-
|
|
31350
|
+
path48.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
31300
31351
|
hashString4(baseContent),
|
|
31301
31352
|
"cline"
|
|
31302
31353
|
);
|
|
@@ -31321,11 +31372,11 @@ ${baseContent}
|
|
|
31321
31372
|
);
|
|
31322
31373
|
}
|
|
31323
31374
|
function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
|
|
31324
|
-
const sourceAgentsRoot =
|
|
31375
|
+
const sourceAgentsRoot = path48.join(sourceRoot, config.source.agents);
|
|
31325
31376
|
if (!fs45.existsSync(sourceAgentsRoot)) {
|
|
31326
31377
|
return [skippedMissingSource5("agents", sourceAgentsRoot)];
|
|
31327
31378
|
}
|
|
31328
|
-
const sourceAgents = ts(
|
|
31379
|
+
const sourceAgents = ts(path48.join(sourceAgentsRoot, "*.md")).sort();
|
|
31329
31380
|
return sourceAgents.map((agentFile) => {
|
|
31330
31381
|
compileAgent(agentFile, "cline", mappings, extensions, lossReport);
|
|
31331
31382
|
if (options.dryRun) {
|
|
@@ -31341,14 +31392,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
31341
31392
|
});
|
|
31342
31393
|
}
|
|
31343
31394
|
function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
31344
|
-
const sourceRulesDir =
|
|
31395
|
+
const sourceRulesDir = path48.join(sourceRoot, config.source.rules);
|
|
31345
31396
|
if (!fs45.existsSync(sourceRulesDir)) {
|
|
31346
31397
|
return [skippedMissingSource5("rules", sourceRulesDir)];
|
|
31347
31398
|
}
|
|
31348
31399
|
const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
|
|
31349
31400
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
31350
31401
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
31351
|
-
const destination =
|
|
31402
|
+
const destination = path48.join(rulesDir, name);
|
|
31352
31403
|
if (options.dryRun) {
|
|
31353
31404
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
31354
31405
|
return {
|
|
@@ -31372,17 +31423,17 @@ function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
31372
31423
|
});
|
|
31373
31424
|
}
|
|
31374
31425
|
function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
31375
|
-
const sourceCommandsRoot =
|
|
31426
|
+
const sourceCommandsRoot = path48.join(sourceRoot, config.source.commands);
|
|
31376
31427
|
if (!fs45.existsSync(sourceCommandsRoot)) {
|
|
31377
31428
|
return [skippedMissingSource5("commands", sourceCommandsRoot)];
|
|
31378
31429
|
}
|
|
31379
|
-
const sourceCommands = ts(
|
|
31430
|
+
const sourceCommands = ts(path48.join(sourceCommandsRoot, "*.md")).sort();
|
|
31380
31431
|
const workflowsRoot = resolveTargetPath(paths.workflows);
|
|
31381
31432
|
return sourceCommands.map((commandFile) => {
|
|
31382
|
-
const baseName =
|
|
31383
|
-
const destination =
|
|
31433
|
+
const baseName = path48.basename(commandFile);
|
|
31434
|
+
const destination = path48.join(workflowsRoot, baseName);
|
|
31384
31435
|
const commandContent = fs45.readFileSync(commandFile, "utf8");
|
|
31385
|
-
const relativeSource = `commands/${
|
|
31436
|
+
const relativeSource = `commands/${path48.basename(commandFile)}`;
|
|
31386
31437
|
const marker = formatProvenanceMarker(
|
|
31387
31438
|
"markdown",
|
|
31388
31439
|
relativeSource,
|
|
@@ -31420,7 +31471,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
31420
31471
|
return syncSkillsSlot({
|
|
31421
31472
|
config,
|
|
31422
31473
|
sourceRoot,
|
|
31423
|
-
source:
|
|
31474
|
+
source: path48.resolve(sourceRoot, config.source.skills),
|
|
31424
31475
|
destination: resolveTargetPath(paths.skills),
|
|
31425
31476
|
dryRun: options.dryRun,
|
|
31426
31477
|
logger,
|
|
@@ -31499,11 +31550,11 @@ function syncSettings2(lossReport) {
|
|
|
31499
31550
|
};
|
|
31500
31551
|
}
|
|
31501
31552
|
function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
31502
|
-
const agentsDir =
|
|
31553
|
+
const agentsDir = path48.join(sourceRoot, config.source.agents);
|
|
31503
31554
|
if (!fs45.existsSync(agentsDir)) return;
|
|
31504
|
-
for (const agentFile of ts(
|
|
31555
|
+
for (const agentFile of ts(path48.join(agentsDir, "*.md")).sort()) {
|
|
31505
31556
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
31506
|
-
const relativeSource = `agents/${
|
|
31557
|
+
const relativeSource = `agents/${path48.basename(agentFile)}`;
|
|
31507
31558
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
31508
31559
|
if (hasCustomProvider) {
|
|
31509
31560
|
addLoss(lossReport, "cline", "agents", {
|
|
@@ -31517,7 +31568,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
31517
31568
|
"provider",
|
|
31518
31569
|
"provider-not-representable"
|
|
31519
31570
|
),
|
|
31520
|
-
detail: `${
|
|
31571
|
+
detail: `${path48.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
|
|
31521
31572
|
}
|
|
31522
31573
|
]
|
|
31523
31574
|
});
|
|
@@ -31535,7 +31586,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
31535
31586
|
"model",
|
|
31536
31587
|
"model-not-representable"
|
|
31537
31588
|
),
|
|
31538
|
-
detail: `${
|
|
31589
|
+
detail: `${path48.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
|
|
31539
31590
|
}
|
|
31540
31591
|
]
|
|
31541
31592
|
});
|
|
@@ -31550,10 +31601,18 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
|
|
|
31550
31601
|
if (artifactClass === "managed-compiled" && !options.force && isCompiledCurrent4(destination, content, expectedHash)) {
|
|
31551
31602
|
return { component, status: "skipped-current", path: destination };
|
|
31552
31603
|
}
|
|
31604
|
+
if (artifactClass === "managed-compiled" && !options.force && hasDriftedSinceInstall(destination, manifest)) {
|
|
31605
|
+
logger.warn(
|
|
31606
|
+
`${destination}: edited since Tangyr wrote it \u2014 applying onConflict: ${config.onConflict}`
|
|
31607
|
+
);
|
|
31608
|
+
if (!handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
31609
|
+
return { component, status: "conflict", path: destination };
|
|
31610
|
+
}
|
|
31611
|
+
}
|
|
31553
31612
|
if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
31554
31613
|
return { component, status: "conflict", path: destination };
|
|
31555
31614
|
}
|
|
31556
|
-
ensureDir(
|
|
31615
|
+
ensureDir(path48.dirname(destination));
|
|
31557
31616
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
31558
31617
|
if (clearedLink !== null) {
|
|
31559
31618
|
logger.verbose(
|
|
@@ -31621,7 +31680,7 @@ function hashString4(value) {
|
|
|
31621
31680
|
import crypto10 from "crypto";
|
|
31622
31681
|
import fs46 from "fs";
|
|
31623
31682
|
import os6 from "os";
|
|
31624
|
-
import
|
|
31683
|
+
import path49 from "path";
|
|
31625
31684
|
var import_yaml12 = __toESM(require_dist(), 1);
|
|
31626
31685
|
function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
31627
31686
|
const scope = options.scope ?? "global";
|
|
@@ -31639,7 +31698,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
31639
31698
|
config_doc: profile.config_doc
|
|
31640
31699
|
};
|
|
31641
31700
|
const rules = compileRules(
|
|
31642
|
-
|
|
31701
|
+
path49.join(sourceRoot, config.source.rules),
|
|
31643
31702
|
"opencode",
|
|
31644
31703
|
mappings,
|
|
31645
31704
|
lossReport
|
|
@@ -31759,7 +31818,7 @@ function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, l
|
|
|
31759
31818
|
${agentsAppendix}`.trim() : baseContent;
|
|
31760
31819
|
const marker = formatProvenanceMarker(
|
|
31761
31820
|
"markdown",
|
|
31762
|
-
|
|
31821
|
+
path49.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
31763
31822
|
hashString5(composed),
|
|
31764
31823
|
"opencode"
|
|
31765
31824
|
);
|
|
@@ -31793,13 +31852,13 @@ ${composed}
|
|
|
31793
31852
|
];
|
|
31794
31853
|
}
|
|
31795
31854
|
function declaredInstructionsPath(paths) {
|
|
31796
|
-
const configDir =
|
|
31855
|
+
const configDir = path49.dirname(resolveTargetPath(paths.config_doc));
|
|
31797
31856
|
const instructions = resolveTargetPath(paths.instructions);
|
|
31798
|
-
const relative =
|
|
31857
|
+
const relative = path49.relative(configDir, instructions);
|
|
31799
31858
|
if (relative === "AGENTS.md" || relative.startsWith("..")) {
|
|
31800
31859
|
return null;
|
|
31801
31860
|
}
|
|
31802
|
-
return relative.split(
|
|
31861
|
+
return relative.split(path49.sep).join("/");
|
|
31803
31862
|
}
|
|
31804
31863
|
function withDeclaredInstructions(existing, reference) {
|
|
31805
31864
|
const listed = Array.isArray(existing) ? existing.filter((entry) => typeof entry === "string") : [];
|
|
@@ -31835,22 +31894,22 @@ function declareInstructions(paths, manifest, logger) {
|
|
|
31835
31894
|
written,
|
|
31836
31895
|
logger
|
|
31837
31896
|
);
|
|
31838
|
-
ensureDir(
|
|
31897
|
+
ensureDir(path49.dirname(destination));
|
|
31839
31898
|
fs46.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
31840
31899
|
`);
|
|
31841
31900
|
return destination;
|
|
31842
31901
|
}
|
|
31843
31902
|
function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
31844
|
-
const sourceAgentsRoot =
|
|
31903
|
+
const sourceAgentsRoot = path49.join(sourceRoot, config.source.agents);
|
|
31845
31904
|
if (!fs46.existsSync(sourceAgentsRoot)) {
|
|
31846
31905
|
return [skippedMissingSource6("agents", sourceAgentsRoot)];
|
|
31847
31906
|
}
|
|
31848
|
-
const sourceAgents = ts(
|
|
31907
|
+
const sourceAgents = ts(path49.join(sourceAgentsRoot, "*.md")).sort();
|
|
31849
31908
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
31850
31909
|
return sourceAgents.map((agentFile) => {
|
|
31851
|
-
const destination =
|
|
31910
|
+
const destination = path49.join(
|
|
31852
31911
|
agentsRoot,
|
|
31853
|
-
`${
|
|
31912
|
+
`${path49.basename(agentFile, ".md")}.md`
|
|
31854
31913
|
);
|
|
31855
31914
|
let compiled;
|
|
31856
31915
|
try {
|
|
@@ -31914,11 +31973,11 @@ function applyProviderModelBinding(compiled, mappings) {
|
|
|
31914
31973
|
return `${before}${(0, import_yaml12.stringify)(fields).trim()}${after}`;
|
|
31915
31974
|
}
|
|
31916
31975
|
function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
31917
|
-
const sourceCommandsRoot =
|
|
31976
|
+
const sourceCommandsRoot = path49.join(sourceRoot, config.source.commands);
|
|
31918
31977
|
if (!fs46.existsSync(sourceCommandsRoot)) {
|
|
31919
31978
|
return [skippedMissingSource6("commands", sourceCommandsRoot)];
|
|
31920
31979
|
}
|
|
31921
|
-
const sourceCommands = ts(
|
|
31980
|
+
const sourceCommands = ts(path49.join(sourceCommandsRoot, "*.md")).sort();
|
|
31922
31981
|
const commandsRoot = resolveTargetPath(paths.commands);
|
|
31923
31982
|
return sourceCommands.map((commandFile) => {
|
|
31924
31983
|
const { data, body } = parseCommandFile(commandFile);
|
|
@@ -31932,7 +31991,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
|
|
|
31932
31991
|
if (typeof data.model === "string") {
|
|
31933
31992
|
frontmatter.model = data.model;
|
|
31934
31993
|
}
|
|
31935
|
-
const relativeSource = `commands/${
|
|
31994
|
+
const relativeSource = `commands/${path49.basename(commandFile)}`;
|
|
31936
31995
|
const marker = formatProvenanceMarker(
|
|
31937
31996
|
"markdown",
|
|
31938
31997
|
relativeSource,
|
|
@@ -31948,9 +32007,9 @@ ${body.trimEnd()}
|
|
|
31948
32007
|
` : `${marker}
|
|
31949
32008
|
${body.trimEnd()}
|
|
31950
32009
|
`;
|
|
31951
|
-
const destination =
|
|
32010
|
+
const destination = path49.join(
|
|
31952
32011
|
commandsRoot,
|
|
31953
|
-
`${
|
|
32012
|
+
`${path49.basename(commandFile, ".md")}.md`
|
|
31954
32013
|
);
|
|
31955
32014
|
if (options.dryRun) {
|
|
31956
32015
|
logger.info(
|
|
@@ -31980,7 +32039,7 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
|
|
|
31980
32039
|
return syncSkillsSlot({
|
|
31981
32040
|
config,
|
|
31982
32041
|
sourceRoot,
|
|
31983
|
-
source:
|
|
32042
|
+
source: path49.resolve(sourceRoot, config.source.skills),
|
|
31984
32043
|
destination,
|
|
31985
32044
|
dryRun: options.dryRun,
|
|
31986
32045
|
logger,
|
|
@@ -32122,7 +32181,7 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings,
|
|
|
32122
32181
|
written,
|
|
32123
32182
|
logger
|
|
32124
32183
|
);
|
|
32125
|
-
ensureDir(
|
|
32184
|
+
ensureDir(path49.dirname(destination));
|
|
32126
32185
|
fs46.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
32127
32186
|
`);
|
|
32128
32187
|
}
|
|
@@ -32134,10 +32193,18 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
|
|
|
32134
32193
|
if (artifactClass === "managed-compiled" && !options.force && isCompiledCurrent5(destination, content, expectedHash)) {
|
|
32135
32194
|
return { component, status: "skipped-current", path: destination };
|
|
32136
32195
|
}
|
|
32196
|
+
if (artifactClass === "managed-compiled" && !options.force && hasDriftedSinceInstall(destination, manifest)) {
|
|
32197
|
+
logger.warn(
|
|
32198
|
+
`${destination}: edited since Tangyr wrote it \u2014 applying onConflict: ${config.onConflict}`
|
|
32199
|
+
);
|
|
32200
|
+
if (!handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
32201
|
+
return { component, status: "conflict", path: destination };
|
|
32202
|
+
}
|
|
32203
|
+
}
|
|
32137
32204
|
if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
32138
32205
|
return { component, status: "conflict", path: destination };
|
|
32139
32206
|
}
|
|
32140
|
-
ensureDir(
|
|
32207
|
+
ensureDir(path49.dirname(destination));
|
|
32141
32208
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
32142
32209
|
if (clearedLink !== null) {
|
|
32143
32210
|
logger.verbose(
|
|
@@ -32258,10 +32325,11 @@ async function runInstallCommand(options, logger) {
|
|
|
32258
32325
|
);
|
|
32259
32326
|
}
|
|
32260
32327
|
const kitName = resolvedKitName ?? config.kit;
|
|
32261
|
-
const kitPath = kitPathOverride ?? (options.kitPath ?
|
|
32262
|
-
|
|
32328
|
+
const kitPath = kitPathOverride ?? (options.kitPath ? path50.resolve(options.kitPath) : config.kitPath);
|
|
32329
|
+
const conventional = conventionalKitPath(configDir);
|
|
32330
|
+
if (!kitName && !kitPath && !conventional) {
|
|
32263
32331
|
logger.error(
|
|
32264
|
-
"No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
|
|
32332
|
+
"No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml, or put the kit in ./tangyr-kit."
|
|
32265
32333
|
);
|
|
32266
32334
|
process.exit(1);
|
|
32267
32335
|
}
|
|
@@ -32269,7 +32337,8 @@ async function runInstallCommand(options, logger) {
|
|
|
32269
32337
|
const resolution = resolveKitSelection({
|
|
32270
32338
|
kit: kitName,
|
|
32271
32339
|
kitPath,
|
|
32272
|
-
searchPaths
|
|
32340
|
+
searchPaths,
|
|
32341
|
+
conventionalPath: conventional
|
|
32273
32342
|
});
|
|
32274
32343
|
if (!resolution) {
|
|
32275
32344
|
logger.error(
|
|
@@ -32389,8 +32458,8 @@ async function runInstallCommand(options, logger) {
|
|
|
32389
32458
|
config: options.config,
|
|
32390
32459
|
scope
|
|
32391
32460
|
});
|
|
32392
|
-
const skillsSource =
|
|
32393
|
-
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") &&
|
|
32461
|
+
const skillsSource = path50.resolve(kitInfo.path, config.source.skills);
|
|
32462
|
+
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path50.basename(f.path) === "skills";
|
|
32394
32463
|
const foreignSkillsSlots = new Set(
|
|
32395
32464
|
assessResult.findings.filter(
|
|
32396
32465
|
(f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
|
|
@@ -32403,7 +32472,7 @@ async function runInstallCommand(options, logger) {
|
|
|
32403
32472
|
);
|
|
32404
32473
|
const conflictingFindings = assessResult.findings.filter((f) => f.classification === "conflicting").filter((f) => !isPerSkillSkillsSlot(f) || foreignSkillsSlots.has(f.path)).sort((a, b) => a.path.localeCompare(b.path));
|
|
32405
32474
|
const mappings = loadMappings(kitInfo.path, config, configDir);
|
|
32406
|
-
|
|
32475
|
+
{
|
|
32407
32476
|
const foreign = findForeignInstructions(
|
|
32408
32477
|
conflictingFindings,
|
|
32409
32478
|
instructionsEntrypoints(tools, scope, projectRoot, mappings)
|
|
@@ -32413,7 +32482,6 @@ async function runInstallCommand(options, logger) {
|
|
|
32413
32482
|
{
|
|
32414
32483
|
code: "INSTALL_FOREIGN_INSTRUCTIONS",
|
|
32415
32484
|
scope,
|
|
32416
|
-
onConflict: config.onConflict,
|
|
32417
32485
|
instructions: foreign.map((one) => ({
|
|
32418
32486
|
path: one.path,
|
|
32419
32487
|
targets: one.targets
|
|
@@ -32425,14 +32493,12 @@ async function runInstallCommand(options, logger) {
|
|
|
32425
32493
|
process.stderr.write(`${payload}
|
|
32426
32494
|
`);
|
|
32427
32495
|
logger.error("Refusing to install: nothing has been written.");
|
|
32428
|
-
for (const line of describeForeignInstructions(
|
|
32429
|
-
foreign,
|
|
32430
|
-
config.onConflict === "ask" ? "ask" : "skip",
|
|
32431
|
-
projectRoot
|
|
32432
|
-
)) {
|
|
32496
|
+
for (const line of describeForeignInstructions(foreign, projectRoot)) {
|
|
32433
32497
|
logger.error(line);
|
|
32434
32498
|
}
|
|
32435
|
-
|
|
32499
|
+
logger.error("");
|
|
32500
|
+
logger.error("Exit code 2 (conflict). Nothing was written.");
|
|
32501
|
+
process.exit(2);
|
|
32436
32502
|
}
|
|
32437
32503
|
}
|
|
32438
32504
|
const skippedTargetPaths = /* @__PURE__ */ new Set();
|
|
@@ -32461,7 +32527,7 @@ async function runInstallCommand(options, logger) {
|
|
|
32461
32527
|
let instructionsLabel;
|
|
32462
32528
|
try {
|
|
32463
32529
|
const resolved = resolveInstructionsSource(kitInfo.path, config);
|
|
32464
|
-
instructionsLabel = resolved ?
|
|
32530
|
+
instructionsLabel = resolved ? path50.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
|
|
32465
32531
|
} catch (err) {
|
|
32466
32532
|
logger.error(
|
|
32467
32533
|
`[dry-run] ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -32489,7 +32555,7 @@ async function runInstallCommand(options, logger) {
|
|
|
32489
32555
|
}
|
|
32490
32556
|
}
|
|
32491
32557
|
logger.info(
|
|
32492
|
-
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${
|
|
32558
|
+
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path50.join(scopePath, "manifest.json")}`
|
|
32493
32559
|
);
|
|
32494
32560
|
return;
|
|
32495
32561
|
}
|
|
@@ -32693,20 +32759,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
32693
32759
|
writeManifest(scopePath, manifest);
|
|
32694
32760
|
logger.info(`
|
|
32695
32761
|
Installation complete: ${installedCount} files installed.`);
|
|
32696
|
-
logger.info(`Manifest written to ${
|
|
32762
|
+
logger.info(`Manifest written to ${path50.join(scopePath, "manifest.json")}`);
|
|
32697
32763
|
logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
|
|
32698
32764
|
logger.info(`Scope: ${scope}`);
|
|
32699
32765
|
logger.info(`Tools: ${tools.join(", ")}`);
|
|
32700
32766
|
reportHookRejections(
|
|
32701
32767
|
installLossReport,
|
|
32702
32768
|
tools,
|
|
32703
|
-
|
|
32769
|
+
path50.resolve(kitInfo.path, "hooks"),
|
|
32704
32770
|
kitInfo.components.hooks.declared
|
|
32705
32771
|
);
|
|
32706
32772
|
const hooksConflict = reportHooksSourceConflict(
|
|
32707
32773
|
installLossReport,
|
|
32708
32774
|
tools,
|
|
32709
|
-
|
|
32775
|
+
path50.resolve(kitInfo.path, "hooks"),
|
|
32710
32776
|
kitInfo.components.hooks.declared
|
|
32711
32777
|
);
|
|
32712
32778
|
if (hooksConflict) {
|
|
@@ -33099,17 +33165,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
33099
33165
|
manifest,
|
|
33100
33166
|
scopePath
|
|
33101
33167
|
);
|
|
33102
|
-
const skillsSource =
|
|
33168
|
+
const skillsSource = path50.resolve(kitInfo.path, config.source.skills);
|
|
33103
33169
|
let count = 0;
|
|
33104
33170
|
for (const outcome of outcomes) {
|
|
33105
33171
|
if (outcome.status !== "success" && outcome.status !== "skipped-current") {
|
|
33106
33172
|
continue;
|
|
33107
33173
|
}
|
|
33108
|
-
const skillName =
|
|
33174
|
+
const skillName = path50.basename(outcome.path);
|
|
33109
33175
|
addArtifactToManifest(manifest, {
|
|
33110
33176
|
relativePath: `claude-code/skills/${skillName}`,
|
|
33111
33177
|
path: outcome.path,
|
|
33112
|
-
hash: describeArtifactState(outcome.path) ?? `dir:${
|
|
33178
|
+
hash: describeArtifactState(outcome.path) ?? `dir:${path50.join(skillsSource, skillName)}`,
|
|
33113
33179
|
origin: "tangyr-managed"
|
|
33114
33180
|
});
|
|
33115
33181
|
count++;
|
|
@@ -33123,7 +33189,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
33123
33189
|
logger.verbose(` skipped (operator choice): ${placement.destination}`);
|
|
33124
33190
|
continue;
|
|
33125
33191
|
}
|
|
33126
|
-
const destDir =
|
|
33192
|
+
const destDir = path50.dirname(placement.destination);
|
|
33127
33193
|
fs47.mkdirSync(destDir, { recursive: true });
|
|
33128
33194
|
if (placement.type === "symlink") {
|
|
33129
33195
|
if (fs47.existsSync(placement.destination) || isSymlink2(placement.destination)) {
|
|
@@ -33440,11 +33506,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
33440
33506
|
if (outcome.path === mcpFile2) {
|
|
33441
33507
|
return "cline/mcp.json";
|
|
33442
33508
|
}
|
|
33443
|
-
if (outcome.path.startsWith(`${workflowsRoot}${
|
|
33444
|
-
return `cline/workflows/${
|
|
33509
|
+
if (outcome.path.startsWith(`${workflowsRoot}${path50.sep}`)) {
|
|
33510
|
+
return `cline/workflows/${path50.basename(outcome.path)}`;
|
|
33445
33511
|
}
|
|
33446
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
33447
|
-
return `cline/rules/${
|
|
33512
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path50.sep}`)) {
|
|
33513
|
+
return `cline/rules/${path50.basename(outcome.path)}`;
|
|
33448
33514
|
}
|
|
33449
33515
|
return null;
|
|
33450
33516
|
}
|
|
@@ -33480,14 +33546,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
33480
33546
|
if (outcome.path === permissionsFile) {
|
|
33481
33547
|
return "cursor/permissions.json";
|
|
33482
33548
|
}
|
|
33483
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
33484
|
-
return `cursor/agents/${
|
|
33549
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path50.sep}`)) {
|
|
33550
|
+
return `cursor/agents/${path50.basename(outcome.path)}`;
|
|
33485
33551
|
}
|
|
33486
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
33487
|
-
return `cursor/rules/${
|
|
33552
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path50.sep}`)) {
|
|
33553
|
+
return `cursor/rules/${path50.basename(outcome.path)}`;
|
|
33488
33554
|
}
|
|
33489
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
33490
|
-
const rel =
|
|
33555
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path50.sep}`)) {
|
|
33556
|
+
const rel = path50.relative(skillsRoot2, outcome.path);
|
|
33491
33557
|
return `cursor/skills/${rel}`;
|
|
33492
33558
|
}
|
|
33493
33559
|
return null;
|
|
@@ -33513,14 +33579,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
33513
33579
|
if (outcome.path === skillsSharedRoot) {
|
|
33514
33580
|
return "opencode/skills_shared";
|
|
33515
33581
|
}
|
|
33516
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
33517
|
-
return `opencode/agents/${
|
|
33582
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path50.sep}`)) {
|
|
33583
|
+
return `opencode/agents/${path50.basename(outcome.path)}`;
|
|
33518
33584
|
}
|
|
33519
|
-
if (outcome.path.startsWith(`${commandsRoot}${
|
|
33520
|
-
return `opencode/commands/${
|
|
33585
|
+
if (outcome.path.startsWith(`${commandsRoot}${path50.sep}`)) {
|
|
33586
|
+
return `opencode/commands/${path50.basename(outcome.path)}`;
|
|
33521
33587
|
}
|
|
33522
33588
|
if (outcome.path === configDocFile) {
|
|
33523
|
-
return `opencode/${
|
|
33589
|
+
return `opencode/${path50.basename(outcome.path)}`;
|
|
33524
33590
|
}
|
|
33525
33591
|
return null;
|
|
33526
33592
|
}
|
|
@@ -33537,29 +33603,29 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
33537
33603
|
const hooksRoot = resolveTargetPath(copilot.hooks);
|
|
33538
33604
|
const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
|
|
33539
33605
|
const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
|
|
33540
|
-
if (copilot.rules !== null && outcome.path.startsWith(`${resolveTargetPath(copilot.rules)}${
|
|
33541
|
-
return `copilot/rules/${
|
|
33606
|
+
if (copilot.rules !== null && outcome.path.startsWith(`${resolveTargetPath(copilot.rules)}${path50.sep}`)) {
|
|
33607
|
+
return `copilot/rules/${path50.relative(resolveTargetPath(copilot.rules), outcome.path)}`;
|
|
33542
33608
|
}
|
|
33543
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
33544
|
-
return `copilot/skills/${
|
|
33609
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path50.sep}`)) {
|
|
33610
|
+
return `copilot/skills/${path50.relative(skillsRoot2, outcome.path)}`;
|
|
33545
33611
|
}
|
|
33546
33612
|
if (outcome.path === skillsRoot2) {
|
|
33547
33613
|
return "copilot/skills";
|
|
33548
33614
|
}
|
|
33549
33615
|
if (instructionsMirror !== null && outcome.path === instructionsMirror) {
|
|
33550
|
-
return `copilot/${
|
|
33616
|
+
return `copilot/${path50.basename(outcome.path)}`;
|
|
33551
33617
|
}
|
|
33552
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
33553
|
-
return `copilot/agents/${
|
|
33618
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path50.sep}`)) {
|
|
33619
|
+
return `copilot/agents/${path50.basename(outcome.path)}`;
|
|
33554
33620
|
}
|
|
33555
|
-
if (outcome.path.startsWith(`${promptsRoot}${
|
|
33556
|
-
return `copilot/prompts/${
|
|
33621
|
+
if (outcome.path.startsWith(`${promptsRoot}${path50.sep}`)) {
|
|
33622
|
+
return `copilot/prompts/${path50.basename(outcome.path)}`;
|
|
33557
33623
|
}
|
|
33558
|
-
if (outcome.path.startsWith(`${hooksRoot}${
|
|
33559
|
-
return `copilot/hooks/${
|
|
33624
|
+
if (outcome.path.startsWith(`${hooksRoot}${path50.sep}`)) {
|
|
33625
|
+
return `copilot/hooks/${path50.basename(outcome.path)}`;
|
|
33560
33626
|
}
|
|
33561
33627
|
if (outcome.path === mcpFile2) {
|
|
33562
|
-
return `copilot/${
|
|
33628
|
+
return `copilot/${path50.basename(outcome.path)}`;
|
|
33563
33629
|
}
|
|
33564
33630
|
return null;
|
|
33565
33631
|
}
|
|
@@ -33576,17 +33642,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
33576
33642
|
if (outcome.path === skillsRoot) {
|
|
33577
33643
|
return "codex/skills";
|
|
33578
33644
|
}
|
|
33579
|
-
if (outcome.path.startsWith(`${agentsRoot}${
|
|
33580
|
-
return `codex/agents/${
|
|
33645
|
+
if (outcome.path.startsWith(`${agentsRoot}${path50.sep}`)) {
|
|
33646
|
+
return `codex/agents/${path50.basename(outcome.path)}`;
|
|
33581
33647
|
}
|
|
33582
|
-
if (outcome.path.startsWith(`${rulesRoot}${
|
|
33583
|
-
return `codex/rules/${
|
|
33648
|
+
if (outcome.path.startsWith(`${rulesRoot}${path50.sep}`)) {
|
|
33649
|
+
return `codex/rules/${path50.basename(outcome.path)}`;
|
|
33584
33650
|
}
|
|
33585
33651
|
if (outcome.path === hooksFile) {
|
|
33586
|
-
return `codex/${
|
|
33652
|
+
return `codex/${path50.basename(outcome.path)}`;
|
|
33587
33653
|
}
|
|
33588
33654
|
if (outcome.path === mcpFile) {
|
|
33589
|
-
return `codex/${
|
|
33655
|
+
return `codex/${path50.basename(outcome.path)}`;
|
|
33590
33656
|
}
|
|
33591
33657
|
return null;
|
|
33592
33658
|
}
|
|
@@ -33655,7 +33721,7 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
|
|
|
33655
33721
|
rules: resolvedPaths.rules
|
|
33656
33722
|
};
|
|
33657
33723
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
33658
|
-
const componentDir =
|
|
33724
|
+
const componentDir = path50.join(kitInfo.path, component);
|
|
33659
33725
|
if (fs47.existsSync(componentDir) && fs47.statSync(componentDir).isDirectory()) {
|
|
33660
33726
|
placements.push({
|
|
33661
33727
|
source: componentDir,
|
|
@@ -33686,7 +33752,7 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
|
|
|
33686
33752
|
rules: profile.rules
|
|
33687
33753
|
};
|
|
33688
33754
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
33689
|
-
const componentDir =
|
|
33755
|
+
const componentDir = path50.join(kitInfo.path, component);
|
|
33690
33756
|
if (fs47.existsSync(componentDir) && fs47.statSync(componentDir).isDirectory()) {
|
|
33691
33757
|
placements.push({
|
|
33692
33758
|
source: componentDir,
|
|
@@ -33703,7 +33769,7 @@ function collectAllFiles(kitInfo, config) {
|
|
|
33703
33769
|
const files = /* @__PURE__ */ new Map();
|
|
33704
33770
|
const entrypoint = resolveInstructionsSource(kitInfo.path, config);
|
|
33705
33771
|
if (entrypoint) {
|
|
33706
|
-
files.set(
|
|
33772
|
+
files.set(path50.basename(entrypoint.file), entrypoint.file);
|
|
33707
33773
|
}
|
|
33708
33774
|
for (const [component, reconciliation] of Object.entries(
|
|
33709
33775
|
kitInfo.components
|
|
@@ -33712,8 +33778,8 @@ function collectAllFiles(kitInfo, config) {
|
|
|
33712
33778
|
const missingSet = new Set(reconciliation.missing);
|
|
33713
33779
|
for (const entry of reconciliation.declared) {
|
|
33714
33780
|
if (missingSet.has(entry)) continue;
|
|
33715
|
-
const relPath = isSkills ?
|
|
33716
|
-
files.set(relPath,
|
|
33781
|
+
const relPath = isSkills ? path50.join(component, entry) : path50.join(component, `${entry}.md`);
|
|
33782
|
+
files.set(relPath, path50.join(kitInfo.path, relPath));
|
|
33717
33783
|
}
|
|
33718
33784
|
}
|
|
33719
33785
|
return files;
|
|
@@ -33746,10 +33812,10 @@ function skillsSubPathKey(tool, outcomePath, mappings, scope, projectRoot) {
|
|
|
33746
33812
|
continue;
|
|
33747
33813
|
}
|
|
33748
33814
|
const root = resolveTargetPath(slot);
|
|
33749
|
-
if (!outcomePath.startsWith(`${root}${
|
|
33815
|
+
if (!outcomePath.startsWith(`${root}${path50.sep}`)) {
|
|
33750
33816
|
continue;
|
|
33751
33817
|
}
|
|
33752
|
-
const inside =
|
|
33818
|
+
const inside = path50.relative(root, outcomePath).split(path50.sep).join("/");
|
|
33753
33819
|
return `${tool}/skills/${inside}`;
|
|
33754
33820
|
}
|
|
33755
33821
|
return null;
|
|
@@ -33794,14 +33860,14 @@ async function runKitUpdateCommand(options, logger) {
|
|
|
33794
33860
|
}
|
|
33795
33861
|
|
|
33796
33862
|
// src/commands/list.ts
|
|
33797
|
-
import
|
|
33863
|
+
import path51 from "path";
|
|
33798
33864
|
function runListCommand(options, logger) {
|
|
33799
33865
|
let searchPaths = [];
|
|
33800
|
-
let directKitPath = options.kitPath ?
|
|
33866
|
+
let directKitPath = options.kitPath ? path51.resolve(options.kitPath) : void 0;
|
|
33801
33867
|
try {
|
|
33802
33868
|
const { config, configDir } = resolveConfig(options.config);
|
|
33803
33869
|
searchPaths = config.kitSearchPaths ?? [
|
|
33804
|
-
|
|
33870
|
+
path51.join(configDir, "operating-kits")
|
|
33805
33871
|
];
|
|
33806
33872
|
directKitPath = directKitPath ?? config.kitPath;
|
|
33807
33873
|
} catch (err) {
|
|
@@ -33876,7 +33942,7 @@ function withDirectKit(kits, directKitPath) {
|
|
|
33876
33942
|
return kits;
|
|
33877
33943
|
}
|
|
33878
33944
|
const directKit = loadKit(directKitPath);
|
|
33879
|
-
if (kits.some((kit) =>
|
|
33945
|
+
if (kits.some((kit) => path51.resolve(kit.path) === directKit.path)) {
|
|
33880
33946
|
return kits;
|
|
33881
33947
|
}
|
|
33882
33948
|
return [...kits, directKit];
|
|
@@ -33885,7 +33951,7 @@ function withDirectKit(kits, directKitPath) {
|
|
|
33885
33951
|
// src/commands/probe.ts
|
|
33886
33952
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
33887
33953
|
import fs48 from "fs";
|
|
33888
|
-
import
|
|
33954
|
+
import path52 from "path";
|
|
33889
33955
|
function runProbeCommand(options, logger) {
|
|
33890
33956
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
33891
33957
|
options,
|
|
@@ -33913,7 +33979,7 @@ function runProbeCommand(options, logger) {
|
|
|
33913
33979
|
toProbeRow(
|
|
33914
33980
|
target,
|
|
33915
33981
|
key,
|
|
33916
|
-
scope === "project" ?
|
|
33982
|
+
scope === "project" ? path52.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
|
|
33917
33983
|
)
|
|
33918
33984
|
);
|
|
33919
33985
|
}
|
|
@@ -33979,7 +34045,7 @@ function commandProbeRows(target, key, command, args) {
|
|
|
33979
34045
|
// src/commands/status.ts
|
|
33980
34046
|
import crypto11 from "crypto";
|
|
33981
34047
|
import fs49 from "fs";
|
|
33982
|
-
import
|
|
34048
|
+
import path53 from "path";
|
|
33983
34049
|
function runStatusCommand(options, logger) {
|
|
33984
34050
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
33985
34051
|
options,
|
|
@@ -34085,11 +34151,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
|
|
|
34085
34151
|
}
|
|
34086
34152
|
}
|
|
34087
34153
|
function sourceMarkdownFiles(sourceRoot, componentPath) {
|
|
34088
|
-
const root =
|
|
34154
|
+
const root = path53.join(sourceRoot, componentPath);
|
|
34089
34155
|
if (!fs49.existsSync(root)) {
|
|
34090
34156
|
return [];
|
|
34091
34157
|
}
|
|
34092
|
-
return ts(
|
|
34158
|
+
return ts(path53.join(root, "*.md")).sort();
|
|
34093
34159
|
}
|
|
34094
34160
|
function notRepresentableRow(component, detail) {
|
|
34095
34161
|
return {
|
|
@@ -34236,7 +34302,7 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
|
|
|
34236
34302
|
const rows = [];
|
|
34237
34303
|
const instructionsSource = instructionsSourcePath(sourceRoot, config);
|
|
34238
34304
|
const rules = compileRules(
|
|
34239
|
-
|
|
34305
|
+
path53.join(sourceRoot, config.source.rules),
|
|
34240
34306
|
"opencode",
|
|
34241
34307
|
mappings,
|
|
34242
34308
|
createLossReport()
|
|
@@ -34263,10 +34329,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
34263
34329
|
)) {
|
|
34264
34330
|
rows.push(
|
|
34265
34331
|
classifyCompiledFile(
|
|
34266
|
-
`agents/${
|
|
34267
|
-
|
|
34332
|
+
`agents/${path53.basename(agentFile, ".md")}`,
|
|
34333
|
+
path53.join(
|
|
34268
34334
|
resolveTargetPath(paths.agents),
|
|
34269
|
-
`${
|
|
34335
|
+
`${path53.basename(agentFile, ".md")}.md`
|
|
34270
34336
|
),
|
|
34271
34337
|
"opencode",
|
|
34272
34338
|
computeSourceHash(agentFile),
|
|
@@ -34281,10 +34347,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
34281
34347
|
)) {
|
|
34282
34348
|
rows.push(
|
|
34283
34349
|
classifyCompiledFile(
|
|
34284
|
-
`commands/${
|
|
34285
|
-
|
|
34350
|
+
`commands/${path53.basename(commandFile, ".md")}`,
|
|
34351
|
+
path53.join(
|
|
34286
34352
|
resolveTargetPath(paths.commands),
|
|
34287
|
-
`${
|
|
34353
|
+
`${path53.basename(commandFile, ".md")}.md`
|
|
34288
34354
|
),
|
|
34289
34355
|
"opencode",
|
|
34290
34356
|
computeSourceHash(commandFile),
|
|
@@ -34366,10 +34432,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
34366
34432
|
)) {
|
|
34367
34433
|
rows.push(
|
|
34368
34434
|
classifyCompiledFile(
|
|
34369
|
-
`agents/${
|
|
34370
|
-
|
|
34435
|
+
`agents/${path53.basename(agentFile, ".md")}`,
|
|
34436
|
+
path53.join(
|
|
34371
34437
|
resolveTargetPath(paths.agents),
|
|
34372
|
-
`${
|
|
34438
|
+
`${path53.basename(agentFile, ".md")}.md`
|
|
34373
34439
|
),
|
|
34374
34440
|
"cursor",
|
|
34375
34441
|
computeSourceHash(agentFile),
|
|
@@ -34386,7 +34452,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
34386
34452
|
rows.push(
|
|
34387
34453
|
classifyCompiledFile(
|
|
34388
34454
|
`rules/${ruleFile.name}`,
|
|
34389
|
-
|
|
34455
|
+
path53.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
34390
34456
|
"cursor",
|
|
34391
34457
|
void 0,
|
|
34392
34458
|
config,
|
|
@@ -34400,11 +34466,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
34400
34466
|
sourceRoot,
|
|
34401
34467
|
config.source.commands
|
|
34402
34468
|
)) {
|
|
34403
|
-
const baseName =
|
|
34469
|
+
const baseName = path53.basename(commandFile, ".md");
|
|
34404
34470
|
rows.push(
|
|
34405
34471
|
classifyCompiledFile(
|
|
34406
34472
|
`commands/${baseName}`,
|
|
34407
|
-
|
|
34473
|
+
path53.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
|
|
34408
34474
|
"cursor",
|
|
34409
34475
|
computeSourceHash(commandFile),
|
|
34410
34476
|
config,
|
|
@@ -34487,7 +34553,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
34487
34553
|
rows.push(
|
|
34488
34554
|
classifyCompiledFile(
|
|
34489
34555
|
`rules/${ruleFile.name}`,
|
|
34490
|
-
|
|
34556
|
+
path53.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
34491
34557
|
"cline",
|
|
34492
34558
|
void 0,
|
|
34493
34559
|
config,
|
|
@@ -34503,10 +34569,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
34503
34569
|
)) {
|
|
34504
34570
|
rows.push(
|
|
34505
34571
|
classifyCompiledFile(
|
|
34506
|
-
`commands/${
|
|
34507
|
-
|
|
34572
|
+
`commands/${path53.basename(commandFile, ".md")}`,
|
|
34573
|
+
path53.join(
|
|
34508
34574
|
resolveTargetPath(paths.workflows),
|
|
34509
|
-
|
|
34575
|
+
path53.basename(commandFile)
|
|
34510
34576
|
),
|
|
34511
34577
|
"cline",
|
|
34512
34578
|
computeSourceHash(commandFile),
|
|
@@ -34547,7 +34613,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
34547
34613
|
return rows;
|
|
34548
34614
|
}
|
|
34549
34615
|
function compileRulesFiles(config, sourceRoot, target, mappings) {
|
|
34550
|
-
const rulesSource =
|
|
34616
|
+
const rulesSource = path53.join(sourceRoot, config.source.rules);
|
|
34551
34617
|
if (!fs49.existsSync(rulesSource)) {
|
|
34552
34618
|
return [];
|
|
34553
34619
|
}
|
|
@@ -34578,7 +34644,7 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
34578
34644
|
rules: paths.rules
|
|
34579
34645
|
};
|
|
34580
34646
|
const rules = compileRules(
|
|
34581
|
-
|
|
34647
|
+
path53.join(sourceRoot, config.source.rules),
|
|
34582
34648
|
"codex",
|
|
34583
34649
|
mappings,
|
|
34584
34650
|
createLossReport()
|
|
@@ -34589,10 +34655,10 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
34589
34655
|
--- tangyr managed rules ---
|
|
34590
34656
|
${rules.agentsAppendix}`.trim();
|
|
34591
34657
|
const agentFiles = ts(
|
|
34592
|
-
|
|
34658
|
+
path53.join(sourceRoot, config.source.agents, "*.md")
|
|
34593
34659
|
).sort();
|
|
34594
34660
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
34595
|
-
const mcpSource =
|
|
34661
|
+
const mcpSource = path53.join(sourceRoot, config.source.mcp);
|
|
34596
34662
|
const ruleRows = rules.dotRulesFiles.length === 0 ? [
|
|
34597
34663
|
{
|
|
34598
34664
|
component: "rules",
|
|
@@ -34603,7 +34669,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
34603
34669
|
] : rules.dotRulesFiles.map(
|
|
34604
34670
|
(ruleFile) => classifyCompiledFile(
|
|
34605
34671
|
`rules/${ruleFile.name}`,
|
|
34606
|
-
|
|
34672
|
+
path53.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
|
|
34607
34673
|
"codex",
|
|
34608
34674
|
void 0,
|
|
34609
34675
|
config,
|
|
@@ -34628,10 +34694,10 @@ ${rules.agentsAppendix}`.trim();
|
|
|
34628
34694
|
),
|
|
34629
34695
|
...agentFiles.map(
|
|
34630
34696
|
(agentFile) => classifyCompiledFile(
|
|
34631
|
-
`agents/${
|
|
34632
|
-
|
|
34697
|
+
`agents/${path53.basename(agentFile, ".md")}`,
|
|
34698
|
+
path53.join(
|
|
34633
34699
|
resolveTargetPath(codexPaths.agents),
|
|
34634
|
-
`${
|
|
34700
|
+
`${path53.basename(agentFile, ".md")}.toml`
|
|
34635
34701
|
),
|
|
34636
34702
|
"codex",
|
|
34637
34703
|
computeSourceHash(agentFile),
|
|
@@ -34725,20 +34791,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
34725
34791
|
mcpSharedFile: paths.mcp_shared_file
|
|
34726
34792
|
};
|
|
34727
34793
|
const agentFiles = ts(
|
|
34728
|
-
|
|
34794
|
+
path53.join(sourceRoot, config.source.agents, "*.md")
|
|
34729
34795
|
).sort();
|
|
34730
34796
|
const commandFiles = ts(
|
|
34731
|
-
|
|
34797
|
+
path53.join(sourceRoot, config.source.commands, "*.md")
|
|
34732
34798
|
).sort();
|
|
34733
34799
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
34734
|
-
const mcpSource =
|
|
34800
|
+
const mcpSource = path53.join(sourceRoot, config.source.mcp);
|
|
34735
34801
|
return [
|
|
34736
34802
|
...agentFiles.map(
|
|
34737
34803
|
(agentFile) => classifyCompiledFile(
|
|
34738
|
-
`agents/${
|
|
34739
|
-
|
|
34804
|
+
`agents/${path53.basename(agentFile, ".md")}`,
|
|
34805
|
+
path53.join(
|
|
34740
34806
|
resolveTargetPath(copilotPaths.agents),
|
|
34741
|
-
`${
|
|
34807
|
+
`${path53.basename(agentFile, ".md")}.agent.md`
|
|
34742
34808
|
),
|
|
34743
34809
|
"copilot",
|
|
34744
34810
|
computeSourceHash(agentFile),
|
|
@@ -34755,10 +34821,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
34755
34821
|
),
|
|
34756
34822
|
...commandFiles.map(
|
|
34757
34823
|
(commandFile) => classifyCompiledFile(
|
|
34758
|
-
`commands/${
|
|
34759
|
-
|
|
34824
|
+
`commands/${path53.basename(commandFile, ".md")}`,
|
|
34825
|
+
path53.join(
|
|
34760
34826
|
resolveTargetPath(copilotPaths.prompts),
|
|
34761
|
-
`${
|
|
34827
|
+
`${path53.basename(commandFile, ".md")}.prompt.md`
|
|
34762
34828
|
),
|
|
34763
34829
|
"copilot",
|
|
34764
34830
|
computeSourceHash(commandFile),
|
|
@@ -34777,14 +34843,14 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
34777
34843
|
sourceRoot
|
|
34778
34844
|
),
|
|
34779
34845
|
hooksPresent ? classifyCompiledHooksByProvenance(
|
|
34780
|
-
|
|
34846
|
+
path53.join(
|
|
34781
34847
|
resolveTargetPath(copilotPaths.hooks),
|
|
34782
34848
|
"tangyr-managed.json"
|
|
34783
34849
|
),
|
|
34784
34850
|
"copilot"
|
|
34785
34851
|
) : notConfiguredRow(
|
|
34786
34852
|
"hooks",
|
|
34787
|
-
|
|
34853
|
+
path53.join(
|
|
34788
34854
|
resolveTargetPath(copilotPaths.hooks),
|
|
34789
34855
|
"tangyr-managed.json"
|
|
34790
34856
|
)
|
|
@@ -34809,7 +34875,7 @@ function notConfiguredRow(component, filePath) {
|
|
|
34809
34875
|
}
|
|
34810
34876
|
function classifyDirectArtifact(artifact, config, sourceRoot) {
|
|
34811
34877
|
const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
|
|
34812
|
-
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ?
|
|
34878
|
+
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path53.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
|
|
34813
34879
|
if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
|
|
34814
34880
|
const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
|
|
34815
34881
|
if (perSkill) {
|
|
@@ -34921,7 +34987,7 @@ function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
|
34921
34987
|
return null;
|
|
34922
34988
|
}
|
|
34923
34989
|
const ours = links.filter(
|
|
34924
|
-
(entry) => isOurSymlink(
|
|
34990
|
+
(entry) => isOurSymlink(path53.join(slotPath, entry.name), sourceRoot)
|
|
34925
34991
|
);
|
|
34926
34992
|
if (ours.length === 0) {
|
|
34927
34993
|
return null;
|
|
@@ -34933,9 +34999,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
|
|
|
34933
34999
|
classifyHooks(settingsPath),
|
|
34934
35000
|
classifySettings(
|
|
34935
35001
|
settingsPath,
|
|
34936
|
-
|
|
35002
|
+
path53.resolve(sourceRoot, config.source.settings)
|
|
34937
35003
|
),
|
|
34938
|
-
classifyMcp(claudeJsonPath,
|
|
35004
|
+
classifyMcp(claudeJsonPath, path53.resolve(sourceRoot, config.source.mcp))
|
|
34939
35005
|
];
|
|
34940
35006
|
}
|
|
34941
35007
|
function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
|
|
@@ -35113,7 +35179,7 @@ function hashString6(value) {
|
|
|
35113
35179
|
|
|
35114
35180
|
// src/commands/sync.ts
|
|
35115
35181
|
import fs50 from "fs";
|
|
35116
|
-
import
|
|
35182
|
+
import path54 from "path";
|
|
35117
35183
|
|
|
35118
35184
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
35119
35185
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -35650,6 +35716,8 @@ async function runSyncCommand(options, logger) {
|
|
|
35650
35716
|
const syncOptions = toSyncOptions(options, config, configDir, configSource);
|
|
35651
35717
|
const targets = activeTargets(config, options.target);
|
|
35652
35718
|
const results = [];
|
|
35719
|
+
const recordInto = () => options.dryRun ? void 0 : kitSync?.manifest;
|
|
35720
|
+
const recordUnder = () => options.dryRun ? void 0 : kitSync?.scopePath;
|
|
35653
35721
|
const lossReport = createLossReport();
|
|
35654
35722
|
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;
|
|
35655
35723
|
const kitSync = kitInfo ? prepareKitManifest(syncOptions.scope, syncOptions.projectRoot, kitInfo) : void 0;
|
|
@@ -35684,8 +35752,8 @@ async function runSyncCommand(options, logger) {
|
|
|
35684
35752
|
{ ...syncOptions, claudeRoot },
|
|
35685
35753
|
logger,
|
|
35686
35754
|
allMappings?.platformPaths,
|
|
35687
|
-
|
|
35688
|
-
|
|
35755
|
+
recordInto(),
|
|
35756
|
+
recordUnder(),
|
|
35689
35757
|
allMappings,
|
|
35690
35758
|
lossReport
|
|
35691
35759
|
)
|
|
@@ -35699,8 +35767,8 @@ async function runSyncCommand(options, logger) {
|
|
|
35699
35767
|
syncOptions,
|
|
35700
35768
|
logger,
|
|
35701
35769
|
allMappings?.platformPaths,
|
|
35702
|
-
|
|
35703
|
-
|
|
35770
|
+
recordInto(),
|
|
35771
|
+
recordUnder(),
|
|
35704
35772
|
allMappings,
|
|
35705
35773
|
lossReport
|
|
35706
35774
|
)
|
|
@@ -35718,7 +35786,9 @@ async function runSyncCommand(options, logger) {
|
|
|
35718
35786
|
mappings.extensions,
|
|
35719
35787
|
syncOptions,
|
|
35720
35788
|
lossReport,
|
|
35721
|
-
logger
|
|
35789
|
+
logger,
|
|
35790
|
+
recordInto(),
|
|
35791
|
+
recordUnder()
|
|
35722
35792
|
)
|
|
35723
35793
|
);
|
|
35724
35794
|
} else if (target === "codex") {
|
|
@@ -35733,7 +35803,9 @@ async function runSyncCommand(options, logger) {
|
|
|
35733
35803
|
mappings.extensions,
|
|
35734
35804
|
syncOptions,
|
|
35735
35805
|
lossReport,
|
|
35736
|
-
logger
|
|
35806
|
+
logger,
|
|
35807
|
+
recordInto(),
|
|
35808
|
+
recordUnder()
|
|
35737
35809
|
)
|
|
35738
35810
|
);
|
|
35739
35811
|
} else if (target === "opencode") {
|
|
@@ -35748,7 +35820,9 @@ async function runSyncCommand(options, logger) {
|
|
|
35748
35820
|
mappings.extensions,
|
|
35749
35821
|
syncOptions,
|
|
35750
35822
|
lossReport,
|
|
35751
|
-
logger
|
|
35823
|
+
logger,
|
|
35824
|
+
recordInto(),
|
|
35825
|
+
recordUnder()
|
|
35752
35826
|
)
|
|
35753
35827
|
);
|
|
35754
35828
|
} else if (target === "cursor") {
|
|
@@ -35763,7 +35837,9 @@ async function runSyncCommand(options, logger) {
|
|
|
35763
35837
|
mappings.extensions,
|
|
35764
35838
|
syncOptions,
|
|
35765
35839
|
lossReport,
|
|
35766
|
-
logger
|
|
35840
|
+
logger,
|
|
35841
|
+
recordInto(),
|
|
35842
|
+
recordUnder()
|
|
35767
35843
|
)
|
|
35768
35844
|
);
|
|
35769
35845
|
} else if (target === "cline") {
|
|
@@ -35778,7 +35854,9 @@ async function runSyncCommand(options, logger) {
|
|
|
35778
35854
|
mappings.extensions,
|
|
35779
35855
|
syncOptions,
|
|
35780
35856
|
lossReport,
|
|
35781
|
-
logger
|
|
35857
|
+
logger,
|
|
35858
|
+
recordInto(),
|
|
35859
|
+
recordUnder()
|
|
35782
35860
|
)
|
|
35783
35861
|
);
|
|
35784
35862
|
} else if (isDeferredTarget(target)) {
|
|
@@ -35793,13 +35871,13 @@ async function runSyncCommand(options, logger) {
|
|
|
35793
35871
|
reportHookRejections(
|
|
35794
35872
|
lossReport,
|
|
35795
35873
|
targets,
|
|
35796
|
-
|
|
35874
|
+
path54.resolve(kitInfo.path, "hooks"),
|
|
35797
35875
|
kitInfo.components.hooks.declared
|
|
35798
35876
|
);
|
|
35799
35877
|
const hooksConflict = reportHooksSourceConflict(
|
|
35800
35878
|
lossReport,
|
|
35801
35879
|
targets,
|
|
35802
|
-
|
|
35880
|
+
path54.resolve(kitInfo.path, "hooks"),
|
|
35803
35881
|
kitInfo.components.hooks.declared
|
|
35804
35882
|
);
|
|
35805
35883
|
if (hooksConflict) {
|
|
@@ -35865,7 +35943,13 @@ async function runSyncCommand(options, logger) {
|
|
|
35865
35943
|
syncOptions.scope,
|
|
35866
35944
|
syncOptions.projectRoot
|
|
35867
35945
|
);
|
|
35868
|
-
updateManifest(
|
|
35946
|
+
updateManifest(
|
|
35947
|
+
kitInfo,
|
|
35948
|
+
kitSync,
|
|
35949
|
+
new Set(
|
|
35950
|
+
results.flatMap((result) => result.outcomes).filter((outcome) => outcome.status === "success").map((outcome) => path54.resolve(outcome.path))
|
|
35951
|
+
)
|
|
35952
|
+
);
|
|
35869
35953
|
logger.info(
|
|
35870
35954
|
`Sync complete for kit '${kitInfo.name}': ${kitSync.diff.added.length} added, ${kitSync.diff.modified.length} modified, ${kitSync.diff.removed.length} removed, ${kitSync.diff.unchanged.length} unchanged.`
|
|
35871
35955
|
);
|
|
@@ -35940,7 +36024,7 @@ function printManifestDiff(logger, kitName, diff) {
|
|
|
35940
36024
|
logger.info(` Unchanged: ${diff.unchanged.length} file(s)`);
|
|
35941
36025
|
}
|
|
35942
36026
|
}
|
|
35943
|
-
function updateManifest(kitInfo, kitSync) {
|
|
36027
|
+
function updateManifest(kitInfo, kitSync, written) {
|
|
35944
36028
|
for (const filePath of kitSync.diff.removed) {
|
|
35945
36029
|
removeFileFromManifest(kitSync.manifest, filePath);
|
|
35946
36030
|
}
|
|
@@ -35955,7 +36039,7 @@ function updateManifest(kitInfo, kitSync) {
|
|
|
35955
36039
|
}
|
|
35956
36040
|
}
|
|
35957
36041
|
kitSync.manifest.kit = { name: kitInfo.name, version: kitInfo.version };
|
|
35958
|
-
refreshArtifactStates(kitSync.manifest.artifacts);
|
|
36042
|
+
refreshArtifactStates(kitSync.manifest.artifacts, written);
|
|
35959
36043
|
writeManifest(kitSync.scopePath, kitSync.manifest);
|
|
35960
36044
|
}
|
|
35961
36045
|
var outcomeRecordableTargets = /* @__PURE__ */ new Set([
|
|
@@ -35984,6 +36068,7 @@ function manifestKeyForOutcome(target, outcome, mappings, scope, projectRoot) {
|
|
|
35984
36068
|
function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoot) {
|
|
35985
36069
|
const written = /* @__PURE__ */ new Map();
|
|
35986
36070
|
const refused = /* @__PURE__ */ new Set();
|
|
36071
|
+
const refusedPaths = /* @__PURE__ */ new Map();
|
|
35987
36072
|
for (const result of results) {
|
|
35988
36073
|
for (const outcome of result.outcomes) {
|
|
35989
36074
|
if (outcome.status !== "success" && outcome.status !== "skipped-current" && outcome.status !== "conflict") {
|
|
@@ -36001,6 +36086,7 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
|
|
|
36001
36086
|
}
|
|
36002
36087
|
if (outcome.status === "conflict") {
|
|
36003
36088
|
refused.add(key);
|
|
36089
|
+
refusedPaths.set(key, outcome.path);
|
|
36004
36090
|
} else {
|
|
36005
36091
|
written.set(key, outcome.path);
|
|
36006
36092
|
}
|
|
@@ -36010,6 +36096,10 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
|
|
|
36010
36096
|
if (written.has(key)) {
|
|
36011
36097
|
continue;
|
|
36012
36098
|
}
|
|
36099
|
+
const destination = refusedPaths.get(key);
|
|
36100
|
+
if (destination && carriesProvenanceMarker(destination)) {
|
|
36101
|
+
continue;
|
|
36102
|
+
}
|
|
36013
36103
|
removeArtifactFromManifest(manifest, key);
|
|
36014
36104
|
}
|
|
36015
36105
|
for (const [key, destination] of written) {
|
|
@@ -36029,7 +36119,7 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
|
|
|
36029
36119
|
}
|
|
36030
36120
|
}
|
|
36031
36121
|
function resolveKitFilePath(kitPath, relativePath) {
|
|
36032
|
-
const fullPath =
|
|
36122
|
+
const fullPath = path54.join(kitPath, relativePath);
|
|
36033
36123
|
return fs50.existsSync(fullPath) ? fullPath : null;
|
|
36034
36124
|
}
|
|
36035
36125
|
function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
|
|
@@ -36098,9 +36188,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
36098
36188
|
}
|
|
36099
36189
|
if (relativePath.startsWith("agents/")) {
|
|
36100
36190
|
removeManagedCompiledArtifact2(
|
|
36101
|
-
|
|
36191
|
+
path54.join(
|
|
36102
36192
|
resolveTargetPath(paths.agents ?? ""),
|
|
36103
|
-
`${
|
|
36193
|
+
`${path54.parse(relativePath).name}.agent.md`
|
|
36104
36194
|
),
|
|
36105
36195
|
"copilot",
|
|
36106
36196
|
relativePath,
|
|
@@ -36110,9 +36200,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
36110
36200
|
}
|
|
36111
36201
|
if (relativePath.startsWith("commands/")) {
|
|
36112
36202
|
removeManagedCompiledArtifact2(
|
|
36113
|
-
|
|
36203
|
+
path54.join(
|
|
36114
36204
|
resolveTargetPath(paths.prompts ?? ""),
|
|
36115
|
-
`${
|
|
36205
|
+
`${path54.parse(relativePath).name}.prompt.md`
|
|
36116
36206
|
),
|
|
36117
36207
|
"copilot",
|
|
36118
36208
|
relativePath,
|
|
@@ -36122,7 +36212,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
36122
36212
|
}
|
|
36123
36213
|
if (relativePath.endsWith("hooks.json")) {
|
|
36124
36214
|
removeManagedCompiledArtifact2(
|
|
36125
|
-
|
|
36215
|
+
path54.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
|
|
36126
36216
|
"copilot",
|
|
36127
36217
|
relativePath,
|
|
36128
36218
|
logger
|
|
@@ -36152,9 +36242,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
36152
36242
|
}
|
|
36153
36243
|
if (relativePath.startsWith("agents/")) {
|
|
36154
36244
|
removeManagedCompiledArtifact2(
|
|
36155
|
-
|
|
36245
|
+
path54.join(
|
|
36156
36246
|
resolveTargetPath(paths.agents ?? ""),
|
|
36157
|
-
`${
|
|
36247
|
+
`${path54.parse(relativePath).name}.toml`
|
|
36158
36248
|
),
|
|
36159
36249
|
"codex",
|
|
36160
36250
|
relativePath,
|
|
@@ -36164,9 +36254,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
36164
36254
|
}
|
|
36165
36255
|
if (relativePath.startsWith("rules/")) {
|
|
36166
36256
|
removeManagedCompiledArtifact2(
|
|
36167
|
-
|
|
36257
|
+
path54.join(
|
|
36168
36258
|
resolveTargetPath(paths.rules ?? ""),
|
|
36169
|
-
`${
|
|
36259
|
+
`${path54.parse(relativePath).name}.rules`
|
|
36170
36260
|
),
|
|
36171
36261
|
"codex",
|
|
36172
36262
|
relativePath,
|
|
@@ -36205,9 +36295,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
36205
36295
|
}
|
|
36206
36296
|
if (relativePath.startsWith("agents/")) {
|
|
36207
36297
|
removeManagedCompiledArtifact2(
|
|
36208
|
-
|
|
36298
|
+
path54.join(
|
|
36209
36299
|
resolveTargetPath(paths.agents ?? ""),
|
|
36210
|
-
`${
|
|
36300
|
+
`${path54.parse(relativePath).name}.md`
|
|
36211
36301
|
),
|
|
36212
36302
|
"opencode",
|
|
36213
36303
|
relativePath,
|
|
@@ -36217,9 +36307,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
36217
36307
|
}
|
|
36218
36308
|
if (relativePath.startsWith("commands/")) {
|
|
36219
36309
|
removeManagedCompiledArtifact2(
|
|
36220
|
-
|
|
36310
|
+
path54.join(
|
|
36221
36311
|
resolveTargetPath(paths.commands ?? ""),
|
|
36222
|
-
`${
|
|
36312
|
+
`${path54.parse(relativePath).name}.md`
|
|
36223
36313
|
),
|
|
36224
36314
|
"opencode",
|
|
36225
36315
|
relativePath,
|
|
@@ -36251,9 +36341,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
36251
36341
|
}
|
|
36252
36342
|
if (relativePath.startsWith("agents/")) {
|
|
36253
36343
|
removeManagedCompiledArtifact2(
|
|
36254
|
-
|
|
36344
|
+
path54.join(
|
|
36255
36345
|
resolveTargetPath(paths.agents ?? ""),
|
|
36256
|
-
`${
|
|
36346
|
+
`${path54.parse(relativePath).name}.md`
|
|
36257
36347
|
),
|
|
36258
36348
|
"cursor",
|
|
36259
36349
|
relativePath,
|
|
@@ -36263,9 +36353,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
36263
36353
|
}
|
|
36264
36354
|
if (relativePath.startsWith("rules/")) {
|
|
36265
36355
|
removeManagedCompiledArtifact2(
|
|
36266
|
-
|
|
36356
|
+
path54.join(
|
|
36267
36357
|
resolveTargetPath(paths.rules ?? ""),
|
|
36268
|
-
`${
|
|
36358
|
+
`${path54.parse(relativePath).name}.mdc`
|
|
36269
36359
|
),
|
|
36270
36360
|
"cursor",
|
|
36271
36361
|
relativePath,
|
|
@@ -36275,9 +36365,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
36275
36365
|
}
|
|
36276
36366
|
if (relativePath.startsWith("commands/")) {
|
|
36277
36367
|
removeManagedCompiledArtifact2(
|
|
36278
|
-
|
|
36368
|
+
path54.join(
|
|
36279
36369
|
resolveTargetPath(paths.skills ?? ""),
|
|
36280
|
-
|
|
36370
|
+
path54.parse(relativePath).name,
|
|
36281
36371
|
"SKILL.md"
|
|
36282
36372
|
),
|
|
36283
36373
|
"cursor",
|
|
@@ -36321,9 +36411,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
36321
36411
|
}
|
|
36322
36412
|
if (relativePath.startsWith("rules/")) {
|
|
36323
36413
|
removeManagedCompiledArtifact2(
|
|
36324
|
-
|
|
36414
|
+
path54.join(
|
|
36325
36415
|
resolveTargetPath(paths.rules ?? ""),
|
|
36326
|
-
`${
|
|
36416
|
+
`${path54.parse(relativePath).name}.md`
|
|
36327
36417
|
),
|
|
36328
36418
|
"cline",
|
|
36329
36419
|
relativePath,
|
|
@@ -36333,9 +36423,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
36333
36423
|
}
|
|
36334
36424
|
if (relativePath.startsWith("commands/")) {
|
|
36335
36425
|
removeManagedCompiledArtifact2(
|
|
36336
|
-
|
|
36426
|
+
path54.join(
|
|
36337
36427
|
resolveTargetPath(paths.workflows ?? ""),
|
|
36338
|
-
|
|
36428
|
+
path54.basename(relativePath)
|
|
36339
36429
|
),
|
|
36340
36430
|
"cline",
|
|
36341
36431
|
relativePath,
|
|
@@ -36504,7 +36594,7 @@ function removeManagedHookEntries(value, expectedSource) {
|
|
|
36504
36594
|
|
|
36505
36595
|
// src/commands/validate.ts
|
|
36506
36596
|
import fs51 from "fs";
|
|
36507
|
-
import
|
|
36597
|
+
import path55 from "path";
|
|
36508
36598
|
var SUPPORTED_KIT_FORMATS2 = [1];
|
|
36509
36599
|
var SUPPORTED_DISCIPLINE_VERSIONS = [
|
|
36510
36600
|
"0.14.0",
|
|
@@ -36619,11 +36709,11 @@ function checkArchetype(kit) {
|
|
|
36619
36709
|
}
|
|
36620
36710
|
function checkHookScriptsExist(kit) {
|
|
36621
36711
|
const violations = [];
|
|
36622
|
-
const hooksDir =
|
|
36712
|
+
const hooksDir = path55.join(kit.path, "hooks");
|
|
36623
36713
|
const missingSet = new Set(kit.components.hooks.missing);
|
|
36624
36714
|
for (const name of kit.components.hooks.declared) {
|
|
36625
36715
|
if (missingSet.has(name)) continue;
|
|
36626
|
-
const declarationPath =
|
|
36716
|
+
const declarationPath = path55.join(hooksDir, `${name}.md`);
|
|
36627
36717
|
if (!fs51.existsSync(declarationPath)) continue;
|
|
36628
36718
|
let data;
|
|
36629
36719
|
try {
|
|
@@ -36634,7 +36724,7 @@ function checkHookScriptsExist(kit) {
|
|
|
36634
36724
|
if (typeof data.command === "string" && data.command.trim().length > 0) {
|
|
36635
36725
|
continue;
|
|
36636
36726
|
}
|
|
36637
|
-
const scriptPath =
|
|
36727
|
+
const scriptPath = path55.join(hooksDir, "scripts", `${name}.ts`);
|
|
36638
36728
|
if (!fs51.existsSync(scriptPath)) {
|
|
36639
36729
|
violations.push({
|
|
36640
36730
|
code: "hook-script-missing",
|
|
@@ -36648,7 +36738,7 @@ function checkHookScriptsExist(kit) {
|
|
|
36648
36738
|
function checkOptionalSourceDocuments(kit) {
|
|
36649
36739
|
const violations = [];
|
|
36650
36740
|
for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
|
|
36651
|
-
const filePath =
|
|
36741
|
+
const filePath = path55.join(kit.path, name);
|
|
36652
36742
|
if (!fs51.existsSync(filePath)) continue;
|
|
36653
36743
|
try {
|
|
36654
36744
|
const parsed = JSON.parse(fs51.readFileSync(filePath, "utf8"));
|
|
@@ -36673,7 +36763,7 @@ function checkSkillSubfolderNames(kit) {
|
|
|
36673
36763
|
const notices = [];
|
|
36674
36764
|
const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
|
|
36675
36765
|
for (const name of kit.components.skills.declared) {
|
|
36676
|
-
const skillDir =
|
|
36766
|
+
const skillDir = path55.join(kit.path, "skills", name);
|
|
36677
36767
|
let entries;
|
|
36678
36768
|
try {
|
|
36679
36769
|
entries = fs51.readdirSync(skillDir, { withFileTypes: true });
|
|
@@ -36694,7 +36784,7 @@ function checkSkillSubfolderNames(kit) {
|
|
|
36694
36784
|
return notices;
|
|
36695
36785
|
}
|
|
36696
36786
|
function checkHooksSourceForm(kit) {
|
|
36697
|
-
const hooksDir =
|
|
36787
|
+
const hooksDir = path55.join(kit.path, "hooks");
|
|
36698
36788
|
const message = describeHooksSourceConflict(
|
|
36699
36789
|
hooksDir,
|
|
36700
36790
|
kit.components.hooks.declared
|
|
@@ -36706,12 +36796,12 @@ function checkHooksSourceForm(kit) {
|
|
|
36706
36796
|
} : null;
|
|
36707
36797
|
}
|
|
36708
36798
|
function checkHookDeclarations(kit) {
|
|
36709
|
-
const hooksDir =
|
|
36799
|
+
const hooksDir = path55.join(kit.path, "hooks");
|
|
36710
36800
|
return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
|
|
36711
36801
|
(r) => ({
|
|
36712
36802
|
code: "hook-declaration-invalid",
|
|
36713
|
-
location: `hooks/${
|
|
36714
|
-
message: `hooks: '${
|
|
36803
|
+
location: `hooks/${path55.basename(r.file)}`,
|
|
36804
|
+
message: `hooks: '${path55.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.`
|
|
36715
36805
|
})
|
|
36716
36806
|
);
|
|
36717
36807
|
}
|
|
@@ -36731,11 +36821,11 @@ function checkKitFormatSupported(kit) {
|
|
|
36731
36821
|
function checkEntrypointExists(kit) {
|
|
36732
36822
|
const declared = kit.entrypoint;
|
|
36733
36823
|
const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
|
|
36734
|
-
const entrypointPath =
|
|
36824
|
+
const entrypointPath = path55.join(kit.path, entrypoint);
|
|
36735
36825
|
if (fs51.existsSync(entrypointPath)) {
|
|
36736
36826
|
return null;
|
|
36737
36827
|
}
|
|
36738
|
-
const legacyPresent = declared === void 0 && fs51.existsSync(
|
|
36828
|
+
const legacyPresent = declared === void 0 && fs51.existsSync(path55.join(kit.path, LEGACY_ENTRYPOINT));
|
|
36739
36829
|
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.`;
|
|
36740
36830
|
return {
|
|
36741
36831
|
code: "entrypoint-missing",
|
|
@@ -36794,9 +36884,9 @@ function checkComponentFrontmatter(kit) {
|
|
|
36794
36884
|
const missingSet = new Set(kit.components[cat].missing);
|
|
36795
36885
|
for (const name of kit.components[cat].declared) {
|
|
36796
36886
|
if (missingSet.has(name)) continue;
|
|
36797
|
-
const filePath = cat === "skills" ?
|
|
36887
|
+
const filePath = cat === "skills" ? path55.join(kit.path, cat, name, "SKILL.md") : path55.join(kit.path, cat, `${name}.md`);
|
|
36798
36888
|
if (!fs51.existsSync(filePath)) continue;
|
|
36799
|
-
const relPath =
|
|
36889
|
+
const relPath = path55.relative(kit.path, filePath);
|
|
36800
36890
|
try {
|
|
36801
36891
|
const { data } = parseMarkdownFrontmatter(filePath);
|
|
36802
36892
|
for (const field of requiredFields) {
|
|
@@ -36841,7 +36931,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
36841
36931
|
const missingSet = new Set(kit.components.commands.missing);
|
|
36842
36932
|
for (const name of kit.components.commands.declared) {
|
|
36843
36933
|
if (missingSet.has(name)) continue;
|
|
36844
|
-
const filePath =
|
|
36934
|
+
const filePath = path55.join(kit.path, "commands", `${name}.md`);
|
|
36845
36935
|
if (!fs51.existsSync(filePath)) continue;
|
|
36846
36936
|
let data;
|
|
36847
36937
|
try {
|
|
@@ -36855,7 +36945,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
36855
36945
|
if (!barred) {
|
|
36856
36946
|
violations.push({
|
|
36857
36947
|
code: "command-human-only-model-invocable",
|
|
36858
|
-
location:
|
|
36948
|
+
location: path55.relative(kit.path, filePath),
|
|
36859
36949
|
message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
|
|
36860
36950
|
});
|
|
36861
36951
|
}
|
|
@@ -36865,7 +36955,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
36865
36955
|
|
|
36866
36956
|
// src/commands/verify.ts
|
|
36867
36957
|
import fs52 from "fs";
|
|
36868
|
-
import
|
|
36958
|
+
import path56 from "path";
|
|
36869
36959
|
function runVerifyCommand(options, logger) {
|
|
36870
36960
|
if (options.target && !isKnownTarget(options.target)) {
|
|
36871
36961
|
throwUnrecognizedTarget(options.target);
|
|
@@ -37046,7 +37136,7 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
|
|
|
37046
37136
|
if (!slotPath) {
|
|
37047
37137
|
continue;
|
|
37048
37138
|
}
|
|
37049
|
-
const fullPath = subPath ?
|
|
37139
|
+
const fullPath = subPath ? path56.join(slotPath, subPath) : slotPath;
|
|
37050
37140
|
if (!fs52.existsSync(fullPath)) {
|
|
37051
37141
|
failures.push(
|
|
37052
37142
|
`claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
|