@alessandroraffa/tangyr 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +760 -604
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1372,8 +1372,8 @@ var require_command = __commonJS({
|
|
|
1372
1372
|
"use strict";
|
|
1373
1373
|
var EventEmitter = __require("events").EventEmitter;
|
|
1374
1374
|
var childProcess = __require("child_process");
|
|
1375
|
-
var
|
|
1376
|
-
var
|
|
1375
|
+
var path51 = __require("path");
|
|
1376
|
+
var fs50 = __require("fs");
|
|
1377
1377
|
var process5 = __require("process");
|
|
1378
1378
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
1379
1379
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -2367,7 +2367,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2367
2367
|
* @param {string} subcommandName
|
|
2368
2368
|
*/
|
|
2369
2369
|
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
|
|
2370
|
-
if (
|
|
2370
|
+
if (fs50.existsSync(executableFile)) return;
|
|
2371
2371
|
const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
|
|
2372
2372
|
const executableMissing = `'${executableFile}' does not exist
|
|
2373
2373
|
- if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
|
@@ -2385,11 +2385,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2385
2385
|
let launchWithNode = false;
|
|
2386
2386
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
2387
2387
|
function findFile(baseDir, baseName) {
|
|
2388
|
-
const localBin =
|
|
2389
|
-
if (
|
|
2390
|
-
if (sourceExt.includes(
|
|
2388
|
+
const localBin = path51.resolve(baseDir, baseName);
|
|
2389
|
+
if (fs50.existsSync(localBin)) return localBin;
|
|
2390
|
+
if (sourceExt.includes(path51.extname(baseName))) return void 0;
|
|
2391
2391
|
const foundExt = sourceExt.find(
|
|
2392
|
-
(ext) =>
|
|
2392
|
+
(ext) => fs50.existsSync(`${localBin}${ext}`)
|
|
2393
2393
|
);
|
|
2394
2394
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
2395
2395
|
return void 0;
|
|
@@ -2401,21 +2401,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2401
2401
|
if (this._scriptPath) {
|
|
2402
2402
|
let resolvedScriptPath;
|
|
2403
2403
|
try {
|
|
2404
|
-
resolvedScriptPath =
|
|
2404
|
+
resolvedScriptPath = fs50.realpathSync(this._scriptPath);
|
|
2405
2405
|
} catch {
|
|
2406
2406
|
resolvedScriptPath = this._scriptPath;
|
|
2407
2407
|
}
|
|
2408
|
-
executableDir =
|
|
2409
|
-
|
|
2408
|
+
executableDir = path51.resolve(
|
|
2409
|
+
path51.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 = path51.basename(
|
|
2417
2417
|
this._scriptPath,
|
|
2418
|
-
|
|
2418
|
+
path51.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(path51.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 = path51.basename(filename, path51.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(path52) {
|
|
3359
|
+
if (path52 === void 0) return this._executableDir;
|
|
3360
|
+
this._executableDir = path52;
|
|
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, path51) {
|
|
3717
|
+
const ctrl = callVisitor(key, node, visitor, path51);
|
|
3718
3718
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3719
|
-
replaceNode(key,
|
|
3720
|
-
return visit_(key, ctrl, visitor,
|
|
3719
|
+
replaceNode(key, path51, ctrl);
|
|
3720
|
+
return visit_(key, ctrl, visitor, path51);
|
|
3721
3721
|
}
|
|
3722
3722
|
if (typeof ctrl !== "symbol") {
|
|
3723
3723
|
if (identity.isCollection(node)) {
|
|
3724
|
-
|
|
3724
|
+
path51 = Object.freeze(path51.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, path51);
|
|
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
|
+
path51 = Object.freeze(path51.concat(node));
|
|
3738
|
+
const ck = visit_("key", node.key, visitor, path51);
|
|
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, path51);
|
|
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, path51) {
|
|
3765
|
+
const ctrl = await callVisitor(key, node, visitor, path51);
|
|
3766
3766
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3767
|
-
replaceNode(key,
|
|
3768
|
-
return visitAsync_(key, ctrl, visitor,
|
|
3767
|
+
replaceNode(key, path51, ctrl);
|
|
3768
|
+
return visitAsync_(key, ctrl, visitor, path51);
|
|
3769
3769
|
}
|
|
3770
3770
|
if (typeof ctrl !== "symbol") {
|
|
3771
3771
|
if (identity.isCollection(node)) {
|
|
3772
|
-
|
|
3772
|
+
path51 = Object.freeze(path51.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, path51);
|
|
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
|
+
path51 = Object.freeze(path51.concat(node));
|
|
3786
|
+
const ck = await visitAsync_("key", node.key, visitor, path51);
|
|
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, path51);
|
|
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, path51) {
|
|
3819
3819
|
if (typeof visitor === "function")
|
|
3820
|
-
return visitor(key, node,
|
|
3820
|
+
return visitor(key, node, path51);
|
|
3821
3821
|
if (identity.isMap(node))
|
|
3822
|
-
return visitor.Map?.(key, node,
|
|
3822
|
+
return visitor.Map?.(key, node, path51);
|
|
3823
3823
|
if (identity.isSeq(node))
|
|
3824
|
-
return visitor.Seq?.(key, node,
|
|
3824
|
+
return visitor.Seq?.(key, node, path51);
|
|
3825
3825
|
if (identity.isPair(node))
|
|
3826
|
-
return visitor.Pair?.(key, node,
|
|
3826
|
+
return visitor.Pair?.(key, node, path51);
|
|
3827
3827
|
if (identity.isScalar(node))
|
|
3828
|
-
return visitor.Scalar?.(key, node,
|
|
3828
|
+
return visitor.Scalar?.(key, node, path51);
|
|
3829
3829
|
if (identity.isAlias(node))
|
|
3830
|
-
return visitor.Alias?.(key, node,
|
|
3830
|
+
return visitor.Alias?.(key, node, path51);
|
|
3831
3831
|
return void 0;
|
|
3832
3832
|
}
|
|
3833
|
-
function replaceNode(key,
|
|
3834
|
-
const parent =
|
|
3833
|
+
function replaceNode(key, path51, node) {
|
|
3834
|
+
const parent = path51[path51.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, path51, value) {
|
|
4443
4443
|
let v2 = value;
|
|
4444
|
-
for (let i =
|
|
4445
|
-
const k2 =
|
|
4444
|
+
for (let i = path51.length - 1; i >= 0; --i) {
|
|
4445
|
+
const k2 = path51[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 = (path51) => path51 == null || typeof path51 === "object" && !!path51[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(path51, value) {
|
|
4495
|
+
if (isEmptyPath(path51))
|
|
4496
4496
|
this.add(value);
|
|
4497
4497
|
else {
|
|
4498
|
-
const [key, ...rest] =
|
|
4498
|
+
const [key, ...rest] = path51;
|
|
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(path51) {
|
|
4513
|
+
const [key, ...rest] = path51;
|
|
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(path51, keepScalar) {
|
|
4528
|
+
const [key, ...rest] = path51;
|
|
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(path51) {
|
|
4547
|
+
const [key, ...rest] = path51;
|
|
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(path51, value) {
|
|
4558
|
+
const [key, ...rest] = path51;
|
|
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(path51, value) {
|
|
7071
7071
|
if (assertCollection(this.contents))
|
|
7072
|
-
this.contents.addIn(
|
|
7072
|
+
this.contents.addIn(path51, 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(path51) {
|
|
7148
|
+
if (Collection.isEmptyPath(path51)) {
|
|
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(path51) : 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(path51, keepScalar) {
|
|
7170
|
+
if (Collection.isEmptyPath(path51))
|
|
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(path51, 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(path51) {
|
|
7184
|
+
if (Collection.isEmptyPath(path51))
|
|
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(path51) : 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(path51, value) {
|
|
7204
|
+
if (Collection.isEmptyPath(path51)) {
|
|
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(path51), value);
|
|
7208
7208
|
} else if (assertCollection(this.contents)) {
|
|
7209
|
-
this.contents.setIn(
|
|
7209
|
+
this.contents.setIn(path51, 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, path51) => {
|
|
9167
9167
|
let item = cst;
|
|
9168
|
-
for (const [field, index] of
|
|
9168
|
+
for (const [field, index] of path51) {
|
|
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, path51) => {
|
|
9178
|
+
const parent = visit.itemAtPath(cst, path51.slice(0, -1));
|
|
9179
|
+
const field = path51[path51.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(path51, item, visitor) {
|
|
9186
|
+
let ctrl = visitor(item, path51);
|
|
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(path51.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, path51);
|
|
9205
9205
|
}
|
|
9206
9206
|
}
|
|
9207
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
9207
|
+
return typeof ctrl === "function" ? ctrl(item, path51) : ctrl;
|
|
9208
9208
|
}
|
|
9209
9209
|
exports2.visit = visit;
|
|
9210
9210
|
}
|
|
@@ -10489,14 +10489,14 @@ var require_parser = __commonJS({
|
|
|
10489
10489
|
case "scalar":
|
|
10490
10490
|
case "single-quoted-scalar":
|
|
10491
10491
|
case "double-quoted-scalar": {
|
|
10492
|
-
const
|
|
10492
|
+
const fs50 = this.flowScalar(this.type);
|
|
10493
10493
|
if (atNextItem || it2.value) {
|
|
10494
|
-
map.items.push({ start, key:
|
|
10494
|
+
map.items.push({ start, key: fs50, sep: [] });
|
|
10495
10495
|
this.onKeyLine = true;
|
|
10496
10496
|
} else if (it2.sep) {
|
|
10497
|
-
this.stack.push(
|
|
10497
|
+
this.stack.push(fs50);
|
|
10498
10498
|
} else {
|
|
10499
|
-
Object.assign(it2, { key:
|
|
10499
|
+
Object.assign(it2, { key: fs50, sep: [] });
|
|
10500
10500
|
this.onKeyLine = true;
|
|
10501
10501
|
}
|
|
10502
10502
|
return;
|
|
@@ -10624,13 +10624,13 @@ var require_parser = __commonJS({
|
|
|
10624
10624
|
case "scalar":
|
|
10625
10625
|
case "single-quoted-scalar":
|
|
10626
10626
|
case "double-quoted-scalar": {
|
|
10627
|
-
const
|
|
10627
|
+
const fs50 = this.flowScalar(this.type);
|
|
10628
10628
|
if (!it2 || it2.value)
|
|
10629
|
-
fc.items.push({ start: [], key:
|
|
10629
|
+
fc.items.push({ start: [], key: fs50, sep: [] });
|
|
10630
10630
|
else if (it2.sep)
|
|
10631
|
-
this.stack.push(
|
|
10631
|
+
this.stack.push(fs50);
|
|
10632
10632
|
else
|
|
10633
|
-
Object.assign(it2, { key:
|
|
10633
|
+
Object.assign(it2, { key: fs50, sep: [] });
|
|
10634
10634
|
return;
|
|
10635
10635
|
}
|
|
10636
10636
|
case "flow-map-end":
|
|
@@ -16114,6 +16114,12 @@ function addManagedLink(manifest, link) {
|
|
|
16114
16114
|
manifest.managedLinks.push(link);
|
|
16115
16115
|
}
|
|
16116
16116
|
}
|
|
16117
|
+
function parkConflictingPath(destination, scopePath) {
|
|
16118
|
+
const backupPath = resolveBackupPath(destination, scopePath);
|
|
16119
|
+
fs6.mkdirSync(path6.dirname(backupPath), { recursive: true });
|
|
16120
|
+
fs6.renameSync(destination, backupPath);
|
|
16121
|
+
return backupPath;
|
|
16122
|
+
}
|
|
16117
16123
|
|
|
16118
16124
|
// src/core/exit.ts
|
|
16119
16125
|
var EXIT_FAILURE = 1;
|
|
@@ -25152,8 +25158,8 @@ function toConflictPolicy2(value) {
|
|
|
25152
25158
|
}
|
|
25153
25159
|
|
|
25154
25160
|
// src/commands/install.ts
|
|
25155
|
-
import
|
|
25156
|
-
import
|
|
25161
|
+
import fs44 from "fs";
|
|
25162
|
+
import path44 from "path";
|
|
25157
25163
|
|
|
25158
25164
|
// src/core/channel-state.ts
|
|
25159
25165
|
import fs32 from "fs";
|
|
@@ -26059,9 +26065,91 @@ function sleep(ms2) {
|
|
|
26059
26065
|
});
|
|
26060
26066
|
}
|
|
26061
26067
|
|
|
26068
|
+
// src/core/contested-instructions.ts
|
|
26069
|
+
import fs34 from "fs";
|
|
26070
|
+
import path31 from "path";
|
|
26071
|
+
var FOLDS_RULES_INTO_INSTRUCTIONS = {
|
|
26072
|
+
codex: "its own rules slot takes only exec-policy rules, so guidance rules are folded in",
|
|
26073
|
+
opencode: "it has no rules slot of its own, so every rule is folded in"
|
|
26074
|
+
};
|
|
26075
|
+
function markerTarget(destination) {
|
|
26076
|
+
try {
|
|
26077
|
+
if (fs34.lstatSync(destination).isSymbolicLink()) {
|
|
26078
|
+
return null;
|
|
26079
|
+
}
|
|
26080
|
+
const firstNonEmpty = fs34.readFileSync(destination, "utf8").split("\n").find((line) => line.trim().length > 0) ?? "";
|
|
26081
|
+
return extractProvenanceMarker(firstNonEmpty)?.target ?? null;
|
|
26082
|
+
} catch {
|
|
26083
|
+
return null;
|
|
26084
|
+
}
|
|
26085
|
+
}
|
|
26086
|
+
function findContestedInstructions(instructionsByTarget) {
|
|
26087
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
26088
|
+
for (const [target, destination] of instructionsByTarget) {
|
|
26089
|
+
const resolved = path31.resolve(destination);
|
|
26090
|
+
byPath.set(resolved, [...byPath.get(resolved) ?? [], target]);
|
|
26091
|
+
}
|
|
26092
|
+
const contested = [];
|
|
26093
|
+
for (const [destination, claimants] of byPath) {
|
|
26094
|
+
if (claimants.length < 2) {
|
|
26095
|
+
continue;
|
|
26096
|
+
}
|
|
26097
|
+
const losers = claimants.filter(
|
|
26098
|
+
(target) => target in FOLDS_RULES_INTO_INSTRUCTIONS
|
|
26099
|
+
);
|
|
26100
|
+
contested.push({
|
|
26101
|
+
destination,
|
|
26102
|
+
claimants: [...claimants].sort(),
|
|
26103
|
+
losers: losers.sort(),
|
|
26104
|
+
survivor: markerTarget(destination)
|
|
26105
|
+
});
|
|
26106
|
+
}
|
|
26107
|
+
return contested;
|
|
26108
|
+
}
|
|
26109
|
+
function reportContestedInstructions(instructionsByTarget, kitDeclaresRules, logger) {
|
|
26110
|
+
if (!kitDeclaresRules) {
|
|
26111
|
+
return;
|
|
26112
|
+
}
|
|
26113
|
+
for (const contested of findContestedInstructions(instructionsByTarget)) {
|
|
26114
|
+
if (contested.losers.length === 0) {
|
|
26115
|
+
continue;
|
|
26116
|
+
}
|
|
26117
|
+
logger.warn(
|
|
26118
|
+
`
|
|
26119
|
+
${contested.destination} is the instructions file for ${contested.claimants.join(", ")} at once, and they write it in turn.`
|
|
26120
|
+
);
|
|
26121
|
+
if (contested.survivor) {
|
|
26122
|
+
logger.warn(` The content on disk is ${contested.survivor}'s.`);
|
|
26123
|
+
}
|
|
26124
|
+
for (const target of contested.losers) {
|
|
26125
|
+
logger.warn(
|
|
26126
|
+
` ${target} does NOT get its rules: ${FOLDS_RULES_INTO_INSTRUCTIONS[target]}, and that content is overwritten here.`
|
|
26127
|
+
);
|
|
26128
|
+
}
|
|
26129
|
+
logger.warn(
|
|
26130
|
+
` Give those targets an instructions path of their own, or disable them. Their own rules slot, where they have one, is unaffected.`
|
|
26131
|
+
);
|
|
26132
|
+
}
|
|
26133
|
+
}
|
|
26134
|
+
function instructionsByActiveTarget(tools, scope, projectRoot, mappings) {
|
|
26135
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
26136
|
+
const resolved = resolveTargetPaths({
|
|
26137
|
+
scope,
|
|
26138
|
+
projectRoot,
|
|
26139
|
+
mappings: mappings.platformPaths
|
|
26140
|
+
});
|
|
26141
|
+
for (const tool of tools) {
|
|
26142
|
+
const instructions = resolved[tool]?.instructions;
|
|
26143
|
+
if (typeof instructions === "string" && instructions.length > 0) {
|
|
26144
|
+
byTarget.set(tool, instructions);
|
|
26145
|
+
}
|
|
26146
|
+
}
|
|
26147
|
+
return byTarget;
|
|
26148
|
+
}
|
|
26149
|
+
|
|
26062
26150
|
// src/adapters/claude-code.ts
|
|
26063
|
-
import
|
|
26064
|
-
import
|
|
26151
|
+
import fs37 from "fs";
|
|
26152
|
+
import path35 from "path";
|
|
26065
26153
|
|
|
26066
26154
|
// src/core/shim.ts
|
|
26067
26155
|
import crypto4 from "crypto";
|
|
@@ -26083,8 +26171,8 @@ ${SHIM_BODY}`;
|
|
|
26083
26171
|
}
|
|
26084
26172
|
|
|
26085
26173
|
// src/core/skills-slot.ts
|
|
26086
|
-
import
|
|
26087
|
-
import
|
|
26174
|
+
import fs35 from "fs";
|
|
26175
|
+
import path32 from "path";
|
|
26088
26176
|
function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
|
|
26089
26177
|
if (!isSymlinkPath(destination)) {
|
|
26090
26178
|
return false;
|
|
@@ -26097,7 +26185,7 @@ function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
|
|
|
26097
26185
|
}
|
|
26098
26186
|
function syncSkillsSlot(sync) {
|
|
26099
26187
|
const { source, destination, logger } = sync;
|
|
26100
|
-
if (!
|
|
26188
|
+
if (!fs35.existsSync(source)) {
|
|
26101
26189
|
return [
|
|
26102
26190
|
{
|
|
26103
26191
|
component: "skills",
|
|
@@ -26125,7 +26213,7 @@ function syncSkillsSlot(sync) {
|
|
|
26125
26213
|
if (isLegacyWholesaleSymlink) {
|
|
26126
26214
|
for (const name of foreignSkillNames(source, declaredNames)) {
|
|
26127
26215
|
logger.info(
|
|
26128
|
-
`[dry-run] skills: migrate foreign skill ${
|
|
26216
|
+
`[dry-run] skills: migrate foreign skill ${path32.join(source, name)} -> ${path32.join(destination, name)}`
|
|
26129
26217
|
);
|
|
26130
26218
|
}
|
|
26131
26219
|
logger.info(
|
|
@@ -26133,9 +26221,9 @@ function syncSkillsSlot(sync) {
|
|
|
26133
26221
|
);
|
|
26134
26222
|
}
|
|
26135
26223
|
for (const name of declaredNames ?? listSkillDirNames(source)) {
|
|
26136
|
-
const skillDestination =
|
|
26224
|
+
const skillDestination = path32.join(destination, name);
|
|
26137
26225
|
logger.info(
|
|
26138
|
-
`[dry-run] skills: symlink ${
|
|
26226
|
+
`[dry-run] skills: symlink ${path32.join(source, name)} -> ${skillDestination}`
|
|
26139
26227
|
);
|
|
26140
26228
|
outcomes2.push({
|
|
26141
26229
|
component: "skills",
|
|
@@ -26162,9 +26250,9 @@ function syncSkillsSlot(sync) {
|
|
|
26162
26250
|
}
|
|
26163
26251
|
function syncSingleSkill(sync, name) {
|
|
26164
26252
|
const { config, sourceRoot, source, destination } = sync;
|
|
26165
|
-
const skillSource =
|
|
26166
|
-
const skillDestination =
|
|
26167
|
-
if (!
|
|
26253
|
+
const skillSource = path32.join(source, name);
|
|
26254
|
+
const skillDestination = path32.join(destination, name);
|
|
26255
|
+
if (!fs35.existsSync(skillSource)) {
|
|
26168
26256
|
return {
|
|
26169
26257
|
component: "skills",
|
|
26170
26258
|
status: "skipped",
|
|
@@ -26180,29 +26268,29 @@ function syncSingleSkill(sync, name) {
|
|
|
26180
26268
|
};
|
|
26181
26269
|
}
|
|
26182
26270
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
|
|
26183
|
-
|
|
26271
|
+
fs35.unlinkSync(skillDestination);
|
|
26184
26272
|
} else if (artifactClass === "unmanaged-conflict" && !sync.onUnmanagedConflict(skillDestination)) {
|
|
26185
26273
|
return { component: "skills", status: "conflict", path: skillDestination };
|
|
26186
26274
|
} else if (artifactClass === "managed-symlink") {
|
|
26187
|
-
|
|
26275
|
+
fs35.unlinkSync(skillDestination);
|
|
26188
26276
|
}
|
|
26189
26277
|
createRelativeSymlink(skillSource, skillDestination, "dir");
|
|
26190
26278
|
return { component: "skills", status: "success", path: skillDestination };
|
|
26191
26279
|
}
|
|
26192
26280
|
function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
|
|
26193
26281
|
const foreignNames = foreignSkillNames(source, declaredNames);
|
|
26194
|
-
|
|
26282
|
+
fs35.unlinkSync(destination);
|
|
26195
26283
|
ensureDir(destination);
|
|
26196
26284
|
for (const name of foreignNames) {
|
|
26197
|
-
const from =
|
|
26198
|
-
const to =
|
|
26199
|
-
if (
|
|
26285
|
+
const from = path32.join(source, name);
|
|
26286
|
+
const to = path32.join(destination, name);
|
|
26287
|
+
if (fs35.existsSync(to)) {
|
|
26200
26288
|
logger.warn(
|
|
26201
26289
|
`skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
|
|
26202
26290
|
);
|
|
26203
26291
|
continue;
|
|
26204
26292
|
}
|
|
26205
|
-
|
|
26293
|
+
fs35.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
|
|
26206
26294
|
logger.warn(
|
|
26207
26295
|
`skills migration: '${name}' is present under the kit's skills/ but is not declared in its manifest. Copied ${from} -> ${to} so the harness can read it. The original is left in the kit deliberately: this command does not modify a kit. Remove ${from} yourself if it does not belong there, or declare it in tangyr-kit.yaml if it does.`
|
|
26208
26296
|
);
|
|
@@ -26216,44 +26304,44 @@ function foreignSkillNames(source, declaredNames) {
|
|
|
26216
26304
|
return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
|
|
26217
26305
|
}
|
|
26218
26306
|
function listSkillDirNames(dir) {
|
|
26219
|
-
if (!
|
|
26307
|
+
if (!fs35.existsSync(dir)) {
|
|
26220
26308
|
return [];
|
|
26221
26309
|
}
|
|
26222
|
-
return
|
|
26310
|
+
return fs35.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
26223
26311
|
}
|
|
26224
26312
|
function isSymlinkPath(filePath) {
|
|
26225
26313
|
try {
|
|
26226
|
-
return
|
|
26314
|
+
return fs35.lstatSync(filePath).isSymbolicLink();
|
|
26227
26315
|
} catch {
|
|
26228
26316
|
return false;
|
|
26229
26317
|
}
|
|
26230
26318
|
}
|
|
26231
26319
|
function isSymlinkTo2(linkPath, source) {
|
|
26232
26320
|
try {
|
|
26233
|
-
return
|
|
26321
|
+
return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
|
|
26234
26322
|
} catch {
|
|
26235
26323
|
return false;
|
|
26236
26324
|
}
|
|
26237
26325
|
}
|
|
26238
26326
|
|
|
26239
26327
|
// src/core/hook-scripts.ts
|
|
26240
|
-
import
|
|
26328
|
+
import path33 from "path";
|
|
26241
26329
|
function hookScriptsDir(bridge, target, projectRoot) {
|
|
26242
26330
|
const globalBridge = resolveTargetPath("~/.agents/hooks");
|
|
26243
|
-
if (
|
|
26331
|
+
if (path33.resolve(bridge) === path33.resolve(globalBridge)) {
|
|
26244
26332
|
return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
|
|
26245
26333
|
}
|
|
26246
|
-
const relative =
|
|
26247
|
-
const insideProject = !relative.startsWith("..") && !
|
|
26334
|
+
const relative = path33.relative(projectRoot ?? process.cwd(), bridge);
|
|
26335
|
+
const insideProject = !relative.startsWith("..") && !path33.isAbsolute(relative) && relative !== "";
|
|
26248
26336
|
const variable = PROJECT_DIR_VARIABLE[target];
|
|
26249
26337
|
if (insideProject && variable) {
|
|
26250
|
-
const posix =
|
|
26251
|
-
relative.split(
|
|
26338
|
+
const posix = path33.posix.join(
|
|
26339
|
+
relative.split(path33.sep).join("/"),
|
|
26252
26340
|
"scripts"
|
|
26253
26341
|
);
|
|
26254
26342
|
return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
|
|
26255
26343
|
}
|
|
26256
|
-
return { prefix:
|
|
26344
|
+
return { prefix: path33.join(bridge, "scripts"), machineLocal: true };
|
|
26257
26345
|
}
|
|
26258
26346
|
var PROJECT_DIR_VARIABLE = {
|
|
26259
26347
|
"claude-code": "$CLAUDE_PROJECT_DIR"
|
|
@@ -26263,19 +26351,19 @@ function machineLocalScriptPathNotice(target, prefix) {
|
|
|
26263
26351
|
}
|
|
26264
26352
|
|
|
26265
26353
|
// src/core/instructions-source.ts
|
|
26266
|
-
import
|
|
26267
|
-
import
|
|
26354
|
+
import fs36 from "fs";
|
|
26355
|
+
import path34 from "path";
|
|
26268
26356
|
var PORTABLE_INSTRUCTIONS_NAME = "AGENTS.md";
|
|
26269
26357
|
var InstructionsSourceMissingError = class extends Error {
|
|
26270
26358
|
constructor(kitRoot, expected, declaredBy) {
|
|
26271
26359
|
super(
|
|
26272
|
-
`${
|
|
26360
|
+
`${path34.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.`
|
|
26273
26361
|
);
|
|
26274
26362
|
this.name = "InstructionsSourceMissingError";
|
|
26275
26363
|
}
|
|
26276
26364
|
};
|
|
26277
26365
|
function normalizeLabel(kitRoot, file) {
|
|
26278
|
-
return
|
|
26366
|
+
return path34.relative(kitRoot, file).split(path34.sep).join("/");
|
|
26279
26367
|
}
|
|
26280
26368
|
function isExplicitOverride(configured) {
|
|
26281
26369
|
const normalize = (value) => value.replace(/\\/gu, "/").replace(/^\.\//u, "");
|
|
@@ -26284,8 +26372,8 @@ function isExplicitOverride(configured) {
|
|
|
26284
26372
|
function resolveInstructionsSource(kitRoot, config) {
|
|
26285
26373
|
const configured = config.source.instructions;
|
|
26286
26374
|
if (isExplicitOverride(configured)) {
|
|
26287
|
-
const file =
|
|
26288
|
-
if (!
|
|
26375
|
+
const file = path34.resolve(kitRoot, configured);
|
|
26376
|
+
if (!fs36.existsSync(file)) {
|
|
26289
26377
|
throw new InstructionsSourceMissingError(
|
|
26290
26378
|
kitRoot,
|
|
26291
26379
|
configured,
|
|
@@ -26300,8 +26388,8 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26300
26388
|
}
|
|
26301
26389
|
const declared = resolveKitEntrypointName(kitRoot);
|
|
26302
26390
|
if (declared !== void 0) {
|
|
26303
|
-
const file =
|
|
26304
|
-
if (!
|
|
26391
|
+
const file = path34.resolve(kitRoot, declared);
|
|
26392
|
+
if (!fs36.existsSync(file)) {
|
|
26305
26393
|
throw new InstructionsSourceMissingError(
|
|
26306
26394
|
kitRoot,
|
|
26307
26395
|
declared,
|
|
@@ -26315,13 +26403,13 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26315
26403
|
};
|
|
26316
26404
|
}
|
|
26317
26405
|
for (const name of [DEFAULT_ENTRYPOINT, PORTABLE_INSTRUCTIONS_NAME]) {
|
|
26318
|
-
const file =
|
|
26319
|
-
if (
|
|
26406
|
+
const file = path34.resolve(kitRoot, name);
|
|
26407
|
+
if (fs36.existsSync(file)) {
|
|
26320
26408
|
return { file, label: name, origin: "convention" };
|
|
26321
26409
|
}
|
|
26322
26410
|
}
|
|
26323
|
-
const legacy =
|
|
26324
|
-
if (
|
|
26411
|
+
const legacy = path34.resolve(kitRoot, LEGACY_ENTRYPOINT);
|
|
26412
|
+
if (fs36.existsSync(legacy)) {
|
|
26325
26413
|
return {
|
|
26326
26414
|
file: legacy,
|
|
26327
26415
|
label: LEGACY_ENTRYPOINT,
|
|
@@ -26333,7 +26421,7 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26333
26421
|
}
|
|
26334
26422
|
function instructionsSourcePath(kitRoot, config) {
|
|
26335
26423
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
26336
|
-
return resolved ? resolved.file :
|
|
26424
|
+
return resolved ? resolved.file : path34.resolve(kitRoot, config.source.instructions);
|
|
26337
26425
|
}
|
|
26338
26426
|
function instructionsSourceLabel(kitRoot, config) {
|
|
26339
26427
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
@@ -26454,7 +26542,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
26454
26542
|
if (!shouldSkipComponent(options, "hooks")) {
|
|
26455
26543
|
outcomes.push(
|
|
26456
26544
|
syncHookScriptsBridge({
|
|
26457
|
-
source:
|
|
26545
|
+
source: path35.resolve(sourceRoot, config.source.hooks),
|
|
26458
26546
|
destination: profile.hook_scripts,
|
|
26459
26547
|
config,
|
|
26460
26548
|
sourceRoot,
|
|
@@ -26506,13 +26594,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
26506
26594
|
}
|
|
26507
26595
|
function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
|
|
26508
26596
|
if (!mappings.modelTiers.custom_provider) return;
|
|
26509
|
-
const agentsDir =
|
|
26510
|
-
if (!
|
|
26511
|
-
for (const agentFile of ts(
|
|
26597
|
+
const agentsDir = path35.join(sourceRoot, config.source.agents);
|
|
26598
|
+
if (!fs37.existsSync(agentsDir)) return;
|
|
26599
|
+
for (const agentFile of ts(path35.join(agentsDir, "*.md")).sort()) {
|
|
26512
26600
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
26513
26601
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
26514
26602
|
if (hasProvider) {
|
|
26515
|
-
const basename =
|
|
26603
|
+
const basename = path35.basename(agentFile);
|
|
26516
26604
|
addLoss(lossReport, "claude-code", "agents", {
|
|
26517
26605
|
source: `agents/${basename}`,
|
|
26518
26606
|
fields: [
|
|
@@ -26537,7 +26625,7 @@ function shouldSkipComponent(options, component) {
|
|
|
26537
26625
|
var SHIM_MANIFEST_KEY = "claude-code/instructions_shim";
|
|
26538
26626
|
function lstatOrNull(p) {
|
|
26539
26627
|
try {
|
|
26540
|
-
return
|
|
26628
|
+
return fs37.lstatSync(p);
|
|
26541
26629
|
} catch {
|
|
26542
26630
|
return null;
|
|
26543
26631
|
}
|
|
@@ -26549,12 +26637,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26549
26637
|
if (shimLink?.isSymbolicLink()) {
|
|
26550
26638
|
backupFile(shimPath, manifest, scopePath);
|
|
26551
26639
|
writeManifest(scopePath, manifest);
|
|
26552
|
-
|
|
26640
|
+
fs37.unlinkSync(shimPath);
|
|
26553
26641
|
logger?.verbose(
|
|
26554
26642
|
`instructions-shim: replaced an unmanaged symlink at ${shimPath}`
|
|
26555
26643
|
);
|
|
26556
26644
|
}
|
|
26557
|
-
if (!
|
|
26645
|
+
if (!fs37.existsSync(shimPath)) {
|
|
26558
26646
|
addArtifactToManifest(manifest, {
|
|
26559
26647
|
relativePath: SHIM_MANIFEST_KEY,
|
|
26560
26648
|
path: shimPath,
|
|
@@ -26562,12 +26650,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26562
26650
|
origin: "tangyr-managed"
|
|
26563
26651
|
});
|
|
26564
26652
|
writeManifest(scopePath, manifest);
|
|
26565
|
-
|
|
26566
|
-
|
|
26653
|
+
fs37.mkdirSync(path35.dirname(shimPath), { recursive: true });
|
|
26654
|
+
fs37.writeFileSync(shimPath, shimContent);
|
|
26567
26655
|
logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
|
|
26568
26656
|
return;
|
|
26569
26657
|
}
|
|
26570
|
-
const existing =
|
|
26658
|
+
const existing = fs37.readFileSync(shimPath, "utf8");
|
|
26571
26659
|
const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
|
|
26572
26660
|
const marker = extractProvenanceMarker(firstNonEmptyLine);
|
|
26573
26661
|
if (marker !== null && marker.hash === expectedBodyHash) {
|
|
@@ -26584,7 +26672,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26584
26672
|
}
|
|
26585
26673
|
backupFile(shimPath, manifest, scopePath);
|
|
26586
26674
|
writeManifest(scopePath, manifest);
|
|
26587
|
-
|
|
26675
|
+
fs37.writeFileSync(shimPath, shimContent);
|
|
26588
26676
|
addArtifactToManifest(manifest, {
|
|
26589
26677
|
relativePath: SHIM_MANIFEST_KEY,
|
|
26590
26678
|
path: shimPath,
|
|
@@ -26594,10 +26682,10 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26594
26682
|
logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
|
|
26595
26683
|
}
|
|
26596
26684
|
function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
|
|
26597
|
-
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) :
|
|
26685
|
+
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path35.resolve(sourceRoot, config.source[directComponent.sourceKey]);
|
|
26598
26686
|
const sourceLabel = directComponent.sourceKey === "instructions" ? instructionsSourceLabel(sourceRoot, config) : config.source[directComponent.sourceKey];
|
|
26599
26687
|
const destination = directComponent.destination;
|
|
26600
|
-
if (!
|
|
26688
|
+
if (!fs37.existsSync(source)) {
|
|
26601
26689
|
return skippedMissingSource(directComponent.component, source);
|
|
26602
26690
|
}
|
|
26603
26691
|
if (options.dryRun) {
|
|
@@ -26619,7 +26707,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
26619
26707
|
};
|
|
26620
26708
|
}
|
|
26621
26709
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
26622
|
-
|
|
26710
|
+
fs37.unlinkSync(destination);
|
|
26623
26711
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
|
|
26624
26712
|
return {
|
|
26625
26713
|
component: directComponent.component,
|
|
@@ -26627,14 +26715,11 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
26627
26715
|
path: destination
|
|
26628
26716
|
};
|
|
26629
26717
|
} else if (artifactClass === "managed-symlink") {
|
|
26630
|
-
|
|
26718
|
+
fs37.unlinkSync(destination);
|
|
26631
26719
|
} else if (artifactClass === "managed-compiled") {
|
|
26632
|
-
|
|
26633
|
-
`${destination}: replacing another target's compiled instructions file with a link to the kit. A target that appends its rules here (opencode has no rules slot of its own) does not get them. Give it its own instructions path, or disable it.`
|
|
26634
|
-
);
|
|
26635
|
-
fs36.unlinkSync(destination);
|
|
26720
|
+
fs37.unlinkSync(destination);
|
|
26636
26721
|
}
|
|
26637
|
-
ensureDir(
|
|
26722
|
+
ensureDir(path35.dirname(destination));
|
|
26638
26723
|
createRelativeSymlink(source, destination, directComponent.type, {
|
|
26639
26724
|
logger,
|
|
26640
26725
|
provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
|
|
@@ -26654,7 +26739,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
26654
26739
|
return syncSkillsSlot({
|
|
26655
26740
|
config,
|
|
26656
26741
|
sourceRoot,
|
|
26657
|
-
source:
|
|
26742
|
+
source: path35.resolve(sourceRoot, config.source.skills),
|
|
26658
26743
|
destination,
|
|
26659
26744
|
dryRun: options.dryRun,
|
|
26660
26745
|
logger,
|
|
@@ -26688,7 +26773,7 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
|
|
|
26688
26773
|
destination,
|
|
26689
26774
|
settings,
|
|
26690
26775
|
stringifyJson2,
|
|
26691
|
-
!
|
|
26776
|
+
!fs37.existsSync(destination),
|
|
26692
26777
|
logger
|
|
26693
26778
|
);
|
|
26694
26779
|
return {
|
|
@@ -26698,8 +26783,8 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
|
|
|
26698
26783
|
};
|
|
26699
26784
|
}
|
|
26700
26785
|
function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
26701
|
-
const source =
|
|
26702
|
-
if (!
|
|
26786
|
+
const source = path35.resolve(sourceRoot, config.source.mcp);
|
|
26787
|
+
if (!fs37.existsSync(source)) {
|
|
26703
26788
|
return skippedMissingSource("mcp", source);
|
|
26704
26789
|
}
|
|
26705
26790
|
if (options.dryRun) {
|
|
@@ -26724,7 +26809,7 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
|
26724
26809
|
destination,
|
|
26725
26810
|
hostConfig,
|
|
26726
26811
|
stringifyJson2,
|
|
26727
|
-
!
|
|
26812
|
+
!fs37.existsSync(destination),
|
|
26728
26813
|
logger
|
|
26729
26814
|
);
|
|
26730
26815
|
return {
|
|
@@ -26734,8 +26819,8 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
|
26734
26819
|
};
|
|
26735
26820
|
}
|
|
26736
26821
|
function syncSettings(config, sourceRoot, options, logger, destination) {
|
|
26737
|
-
const source =
|
|
26738
|
-
if (!
|
|
26822
|
+
const source = path35.resolve(sourceRoot, config.source.settings);
|
|
26823
|
+
if (!fs37.existsSync(source)) {
|
|
26739
26824
|
return skippedMissingSource("settings", source);
|
|
26740
26825
|
}
|
|
26741
26826
|
if (options.dryRun) {
|
|
@@ -26753,7 +26838,7 @@ function syncSettings(config, sourceRoot, options, logger, destination) {
|
|
|
26753
26838
|
destination,
|
|
26754
26839
|
settings,
|
|
26755
26840
|
stringifyJson2,
|
|
26756
|
-
!
|
|
26841
|
+
!fs37.existsSync(destination),
|
|
26757
26842
|
logger
|
|
26758
26843
|
);
|
|
26759
26844
|
return {
|
|
@@ -26777,13 +26862,22 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
|
|
|
26777
26862
|
if (manifest && scopePath) {
|
|
26778
26863
|
backupFile(destination, manifest, scopePath);
|
|
26779
26864
|
writeManifest(scopePath, manifest);
|
|
26780
|
-
|
|
26865
|
+
fs37.rmSync(destination, { recursive: true, force: true });
|
|
26781
26866
|
} else {
|
|
26782
|
-
|
|
26867
|
+
const parked = parkConflictingPath(
|
|
26868
|
+
destination,
|
|
26869
|
+
resolveScopePath(
|
|
26870
|
+
options.scope ?? "global",
|
|
26871
|
+
options.scope === "project" ? options.projectRoot : void 0
|
|
26872
|
+
)
|
|
26873
|
+
);
|
|
26874
|
+
logger.warn(
|
|
26875
|
+
`${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
|
|
26876
|
+
);
|
|
26783
26877
|
}
|
|
26784
26878
|
return true;
|
|
26785
26879
|
}
|
|
26786
|
-
|
|
26880
|
+
fs37.rmSync(destination, { recursive: true, force: true });
|
|
26787
26881
|
return true;
|
|
26788
26882
|
}
|
|
26789
26883
|
function skippedMissingSource(component, source) {
|
|
@@ -26795,16 +26889,16 @@ function skippedMissingSource(component, source) {
|
|
|
26795
26889
|
}
|
|
26796
26890
|
function isSymlinkTo3(linkPath, source) {
|
|
26797
26891
|
try {
|
|
26798
|
-
return
|
|
26892
|
+
return fs37.realpathSync(linkPath) === fs37.realpathSync(source);
|
|
26799
26893
|
} catch {
|
|
26800
26894
|
return false;
|
|
26801
26895
|
}
|
|
26802
26896
|
}
|
|
26803
26897
|
function readJsonObject3(filePath) {
|
|
26804
|
-
if (!
|
|
26898
|
+
if (!fs37.existsSync(filePath)) {
|
|
26805
26899
|
return {};
|
|
26806
26900
|
}
|
|
26807
|
-
const parsed = JSON.parse(
|
|
26901
|
+
const parsed = JSON.parse(fs37.readFileSync(filePath, "utf8"));
|
|
26808
26902
|
return isRecord3(parsed) ? parsed : {};
|
|
26809
26903
|
}
|
|
26810
26904
|
function markManaged(value) {
|
|
@@ -26831,13 +26925,13 @@ function isRecord3(value) {
|
|
|
26831
26925
|
// src/adapters/codex.ts
|
|
26832
26926
|
var TOML3 = __toESM(require_toml(), 1);
|
|
26833
26927
|
import crypto6 from "crypto";
|
|
26834
|
-
import
|
|
26835
|
-
import
|
|
26928
|
+
import fs39 from "fs";
|
|
26929
|
+
import path38 from "path";
|
|
26836
26930
|
|
|
26837
26931
|
// src/compiler/agents.ts
|
|
26838
26932
|
var TOML = __toESM(require_toml(), 1);
|
|
26839
26933
|
var import_yaml8 = __toESM(require_dist(), 1);
|
|
26840
|
-
import
|
|
26934
|
+
import path36 from "path";
|
|
26841
26935
|
var writeCapabilityClasses = /* @__PURE__ */ new Set(["filesystem-write", "shell-execution"]);
|
|
26842
26936
|
var copilotToolAliasesByClass = {
|
|
26843
26937
|
delegation: "agent",
|
|
@@ -26849,7 +26943,7 @@ var copilotToolAliasesByClass = {
|
|
|
26849
26943
|
};
|
|
26850
26944
|
function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
26851
26945
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
26852
|
-
const relativeSource = `agents/${
|
|
26946
|
+
const relativeSource = `agents/${path36.basename(sourceFile)}`;
|
|
26853
26947
|
if (target === "opencode") {
|
|
26854
26948
|
return compileOpenCodeAgent(
|
|
26855
26949
|
sourceFile,
|
|
@@ -26890,7 +26984,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
|
26890
26984
|
mappings,
|
|
26891
26985
|
lossReport
|
|
26892
26986
|
);
|
|
26893
|
-
const overlayKey = `agents/${
|
|
26987
|
+
const overlayKey = `agents/${path36.basename(sourceFile, ".md")}.${target}.yaml`;
|
|
26894
26988
|
const targetFields = {
|
|
26895
26989
|
...translated.fields,
|
|
26896
26990
|
...extensions[overlayKey] ?? {}
|
|
@@ -26924,7 +27018,7 @@ ${TOML.stringify({
|
|
|
26924
27018
|
function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
26925
27019
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
26926
27020
|
throw new Error(
|
|
26927
|
-
`${
|
|
27021
|
+
`${path36.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
|
|
26928
27022
|
);
|
|
26929
27023
|
}
|
|
26930
27024
|
const frontmatter = {
|
|
@@ -26978,7 +27072,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
|
|
|
26978
27072
|
"permission",
|
|
26979
27073
|
"permission-coarsening"
|
|
26980
27074
|
),
|
|
26981
|
-
detail: `${
|
|
27075
|
+
detail: `${path36.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
|
|
26982
27076
|
}
|
|
26983
27077
|
]
|
|
26984
27078
|
});
|
|
@@ -27003,7 +27097,7 @@ ${(0, import_yaml8.stringify)(frontmatter).trim()}
|
|
|
27003
27097
|
function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
27004
27098
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
27005
27099
|
throw new Error(
|
|
27006
|
-
`${
|
|
27100
|
+
`${path36.basename(sourceFile)}: Cursor agent requires a non-empty description field`
|
|
27007
27101
|
);
|
|
27008
27102
|
}
|
|
27009
27103
|
const frontmatter = {
|
|
@@ -27040,7 +27134,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
27040
27134
|
"permission",
|
|
27041
27135
|
"permission-coarsening"
|
|
27042
27136
|
),
|
|
27043
|
-
detail: `${
|
|
27137
|
+
detail: `${path36.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
|
|
27044
27138
|
}
|
|
27045
27139
|
]
|
|
27046
27140
|
});
|
|
@@ -27059,7 +27153,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
27059
27153
|
"provider",
|
|
27060
27154
|
"provider-not-representable"
|
|
27061
27155
|
),
|
|
27062
|
-
detail: `${
|
|
27156
|
+
detail: `${path36.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
27063
27157
|
}
|
|
27064
27158
|
]
|
|
27065
27159
|
});
|
|
@@ -27091,7 +27185,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
|
|
|
27091
27185
|
"persona",
|
|
27092
27186
|
"persona-not-representable"
|
|
27093
27187
|
),
|
|
27094
|
-
detail: `${
|
|
27188
|
+
detail: `${path36.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
|
|
27095
27189
|
}
|
|
27096
27190
|
]
|
|
27097
27191
|
});
|
|
@@ -27139,7 +27233,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27139
27233
|
field,
|
|
27140
27234
|
"model-not-representable"
|
|
27141
27235
|
),
|
|
27142
|
-
detail: `${
|
|
27236
|
+
detail: `${path36.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
|
|
27143
27237
|
});
|
|
27144
27238
|
return;
|
|
27145
27239
|
}
|
|
@@ -27157,9 +27251,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27157
27251
|
lossReport,
|
|
27158
27252
|
target,
|
|
27159
27253
|
"agents",
|
|
27160
|
-
`agents/${
|
|
27254
|
+
`agents/${path36.basename(sourceFile)}`,
|
|
27161
27255
|
"info",
|
|
27162
|
-
`${
|
|
27256
|
+
`${path36.basename(sourceFile)}: ${field} is delivered through another managed surface.`
|
|
27163
27257
|
);
|
|
27164
27258
|
return;
|
|
27165
27259
|
}
|
|
@@ -27168,7 +27262,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27168
27262
|
field,
|
|
27169
27263
|
action: entryType,
|
|
27170
27264
|
severity: resolveLossSeverity("agent-field", field, entryType),
|
|
27171
|
-
detail: `${
|
|
27265
|
+
detail: `${path36.basename(sourceFile)}: ${field} has no emitted field for this target.`
|
|
27172
27266
|
});
|
|
27173
27267
|
}
|
|
27174
27268
|
function mapToolsToCapabilities(value, mappings) {
|
|
@@ -27909,9 +28003,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
|
|
|
27909
28003
|
}
|
|
27910
28004
|
|
|
27911
28005
|
// src/compiler/rules.ts
|
|
27912
|
-
import
|
|
28006
|
+
import path37 from "path";
|
|
27913
28007
|
var import_yaml9 = __toESM(require_dist(), 1);
|
|
27914
|
-
import
|
|
28008
|
+
import fs38 from "fs";
|
|
27915
28009
|
function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
27916
28010
|
if (target === "copilot") {
|
|
27917
28011
|
addLoss(lossReport, "copilot", "rules", {
|
|
@@ -27948,13 +28042,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
|
27948
28042
|
}
|
|
27949
28043
|
const appendixParts = [];
|
|
27950
28044
|
const dotRulesFiles = [];
|
|
27951
|
-
for (const ruleFile of ts(
|
|
28045
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
27952
28046
|
const parsed = parseRule(ruleFile);
|
|
27953
|
-
const name =
|
|
28047
|
+
const name = path37.basename(ruleFile, ".md");
|
|
27954
28048
|
if (parsed.mode === "exec-policy") {
|
|
27955
28049
|
dotRulesFiles.push({
|
|
27956
28050
|
name: `${name}.rules`,
|
|
27957
|
-
content: `${formatProvenanceMarker("toml", `rules/${
|
|
28051
|
+
content: `${formatProvenanceMarker("toml", `rules/${path37.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
|
|
27958
28052
|
${parsed.body}`
|
|
27959
28053
|
});
|
|
27960
28054
|
continue;
|
|
@@ -27963,7 +28057,7 @@ ${parsed.body}`
|
|
|
27963
28057
|
|
|
27964
28058
|
${parsed.body.trim()}`);
|
|
27965
28059
|
addLoss(lossReport, "codex", "rules", {
|
|
27966
|
-
source: `rules/${
|
|
28060
|
+
source: `rules/${path37.basename(ruleFile)}`,
|
|
27967
28061
|
fields: [
|
|
27968
28062
|
{
|
|
27969
28063
|
field: "mode",
|
|
@@ -27973,7 +28067,7 @@ ${parsed.body.trim()}`);
|
|
|
27973
28067
|
"mode",
|
|
27974
28068
|
"rule-as-instruction"
|
|
27975
28069
|
),
|
|
27976
|
-
detail: `${
|
|
28070
|
+
detail: `${path37.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
|
|
27977
28071
|
}
|
|
27978
28072
|
]
|
|
27979
28073
|
});
|
|
@@ -27981,7 +28075,7 @@ ${parsed.body.trim()}`);
|
|
|
27981
28075
|
return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
|
|
27982
28076
|
}
|
|
27983
28077
|
function parseRule(ruleFile) {
|
|
27984
|
-
const content =
|
|
28078
|
+
const content = fs38.readFileSync(ruleFile, "utf8");
|
|
27985
28079
|
if (!content.startsWith("---\n")) {
|
|
27986
28080
|
return { mode: "guidance", body: content };
|
|
27987
28081
|
}
|
|
@@ -28005,14 +28099,14 @@ function isRuleMode(value) {
|
|
|
28005
28099
|
}
|
|
28006
28100
|
function compileOpenCodeRules(sourceRulesDir, lossReport) {
|
|
28007
28101
|
const appendixParts = [];
|
|
28008
|
-
for (const ruleFile of ts(
|
|
28102
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
28009
28103
|
const parsed = parseRule(ruleFile);
|
|
28010
|
-
const name =
|
|
28104
|
+
const name = path37.basename(ruleFile, ".md");
|
|
28011
28105
|
appendixParts.push(`## ${name}
|
|
28012
28106
|
|
|
28013
28107
|
${parsed.body.trim()}`);
|
|
28014
28108
|
addLoss(lossReport, "opencode", "rules", {
|
|
28015
|
-
source: `rules/${
|
|
28109
|
+
source: `rules/${path37.basename(ruleFile)}`,
|
|
28016
28110
|
fields: [
|
|
28017
28111
|
{
|
|
28018
28112
|
field: "rule",
|
|
@@ -28022,7 +28116,7 @@ ${parsed.body.trim()}`);
|
|
|
28022
28116
|
"rule",
|
|
28023
28117
|
"rule-path-scoping"
|
|
28024
28118
|
),
|
|
28025
|
-
detail: `${
|
|
28119
|
+
detail: `${path37.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
|
|
28026
28120
|
}
|
|
28027
28121
|
]
|
|
28028
28122
|
});
|
|
@@ -28031,9 +28125,9 @@ ${parsed.body.trim()}`);
|
|
|
28031
28125
|
}
|
|
28032
28126
|
function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
28033
28127
|
const dotRulesFiles = [];
|
|
28034
|
-
for (const ruleFile of ts(
|
|
28035
|
-
const content =
|
|
28036
|
-
const name =
|
|
28128
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
28129
|
+
const content = fs38.readFileSync(ruleFile, "utf8");
|
|
28130
|
+
const name = path37.basename(ruleFile, ".md");
|
|
28037
28131
|
let frontmatterData = {};
|
|
28038
28132
|
let body = content;
|
|
28039
28133
|
if (content.startsWith("---\n")) {
|
|
@@ -28062,7 +28156,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
|
28062
28156
|
}
|
|
28063
28157
|
const marker = formatProvenanceMarker(
|
|
28064
28158
|
"markdown",
|
|
28065
|
-
`rules/${
|
|
28159
|
+
`rules/${path37.basename(ruleFile)}`,
|
|
28066
28160
|
computeSourceHash(ruleFile),
|
|
28067
28161
|
"cursor"
|
|
28068
28162
|
);
|
|
@@ -28078,9 +28172,9 @@ ${body}`;
|
|
|
28078
28172
|
}
|
|
28079
28173
|
function compileClineRules(sourceRulesDir, lossReport) {
|
|
28080
28174
|
const dotRulesFiles = [];
|
|
28081
|
-
for (const ruleFile of ts(
|
|
28082
|
-
const content =
|
|
28083
|
-
const name =
|
|
28175
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
28176
|
+
const content = fs38.readFileSync(ruleFile, "utf8");
|
|
28177
|
+
const name = path37.basename(ruleFile, ".md");
|
|
28084
28178
|
let frontmatterData = {};
|
|
28085
28179
|
let body = content;
|
|
28086
28180
|
if (content.startsWith("---\n")) {
|
|
@@ -28097,13 +28191,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28097
28191
|
}
|
|
28098
28192
|
const marker = formatProvenanceMarker(
|
|
28099
28193
|
"markdown",
|
|
28100
|
-
`rules/${
|
|
28194
|
+
`rules/${path37.basename(ruleFile)}`,
|
|
28101
28195
|
computeSourceHash(ruleFile),
|
|
28102
28196
|
"cline"
|
|
28103
28197
|
);
|
|
28104
28198
|
if (frontmatterData.mode === "exec-policy") {
|
|
28105
28199
|
addLoss(lossReport, "cline", "rules", {
|
|
28106
|
-
source: `rules/${
|
|
28200
|
+
source: `rules/${path37.basename(ruleFile)}`,
|
|
28107
28201
|
fields: [
|
|
28108
28202
|
{
|
|
28109
28203
|
field: "mode",
|
|
@@ -28113,7 +28207,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28113
28207
|
"mode",
|
|
28114
28208
|
"rule-mode-downgrade"
|
|
28115
28209
|
),
|
|
28116
|
-
detail: `${
|
|
28210
|
+
detail: `${path37.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
|
|
28117
28211
|
}
|
|
28118
28212
|
]
|
|
28119
28213
|
});
|
|
@@ -28159,7 +28253,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28159
28253
|
rules: profile.rules
|
|
28160
28254
|
};
|
|
28161
28255
|
const rules = compileRules(
|
|
28162
|
-
|
|
28256
|
+
path38.join(sourceRoot, config.source.rules),
|
|
28163
28257
|
"codex",
|
|
28164
28258
|
mappings,
|
|
28165
28259
|
lossReport
|
|
@@ -28225,7 +28319,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28225
28319
|
if (!shouldSkipComponent2(options, "hooks")) {
|
|
28226
28320
|
outcomes.push(
|
|
28227
28321
|
syncHookScriptsBridge({
|
|
28228
|
-
source:
|
|
28322
|
+
source: path38.resolve(sourceRoot, config.source.hooks),
|
|
28229
28323
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
28230
28324
|
config,
|
|
28231
28325
|
sourceRoot,
|
|
@@ -28324,9 +28418,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28324
28418
|
function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
|
|
28325
28419
|
const cp = mappings.modelTiers.custom_provider;
|
|
28326
28420
|
if (!cp) return "";
|
|
28327
|
-
const agentsDir =
|
|
28328
|
-
if (!
|
|
28329
|
-
const agentFiles = ts(
|
|
28421
|
+
const agentsDir = path38.join(sourceRoot, config.source.agents);
|
|
28422
|
+
if (!fs39.existsSync(agentsDir)) return "";
|
|
28423
|
+
const agentFiles = ts(path38.join(agentsDir, "*.md")).sort();
|
|
28330
28424
|
const hasProviderAgent = agentFiles.some((agentFile) => {
|
|
28331
28425
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28332
28426
|
return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
@@ -28391,7 +28485,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28391
28485
|
}
|
|
28392
28486
|
];
|
|
28393
28487
|
for (const ruleFile of rules.dotRulesFiles) {
|
|
28394
|
-
const destination =
|
|
28488
|
+
const destination = path38.join(rulesRoot, ruleFile.name);
|
|
28395
28489
|
if (options.dryRun) {
|
|
28396
28490
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
28397
28491
|
outcomes.push({
|
|
@@ -28421,16 +28515,16 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28421
28515
|
function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
28422
28516
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
28423
28517
|
const destination = resolveTargetPath(paths.instructions);
|
|
28424
|
-
if (!
|
|
28518
|
+
if (!fs39.existsSync(source)) {
|
|
28425
28519
|
return skippedMissingSource2("instructions", source);
|
|
28426
28520
|
}
|
|
28427
|
-
const composed = `${
|
|
28521
|
+
const composed = `${fs39.readFileSync(source, "utf8").trim()}
|
|
28428
28522
|
|
|
28429
28523
|
--- tangyr managed rules ---
|
|
28430
28524
|
${agentsAppendix}`.trim();
|
|
28431
28525
|
const marker = formatProvenanceMarker(
|
|
28432
28526
|
"markdown",
|
|
28433
|
-
|
|
28527
|
+
path38.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
28434
28528
|
hashString(composed),
|
|
28435
28529
|
"codex"
|
|
28436
28530
|
);
|
|
@@ -28457,9 +28551,9 @@ ${composed}
|
|
|
28457
28551
|
);
|
|
28458
28552
|
}
|
|
28459
28553
|
function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
28460
|
-
const source =
|
|
28554
|
+
const source = path38.resolve(sourceRoot, config.source.skills);
|
|
28461
28555
|
const destination = resolveTargetPath(paths.skills);
|
|
28462
|
-
if (!
|
|
28556
|
+
if (!fs39.existsSync(source)) {
|
|
28463
28557
|
return skippedMissingSource2("skills", source);
|
|
28464
28558
|
}
|
|
28465
28559
|
if (options.dryRun) {
|
|
@@ -28475,29 +28569,29 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
28475
28569
|
};
|
|
28476
28570
|
}
|
|
28477
28571
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
28478
|
-
|
|
28572
|
+
fs39.unlinkSync(destination);
|
|
28479
28573
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
28480
28574
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
28481
28575
|
return { component: "skills", status: "conflict", path: destination };
|
|
28482
28576
|
} else if (artifactClass === "managed-symlink") {
|
|
28483
|
-
|
|
28577
|
+
fs39.unlinkSync(destination);
|
|
28484
28578
|
}
|
|
28485
|
-
ensureDir(
|
|
28579
|
+
ensureDir(path38.dirname(destination));
|
|
28486
28580
|
createRelativeSymlink(source, destination, "dir");
|
|
28487
28581
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
28488
28582
|
return { component: "skills", status: "success", path: destination };
|
|
28489
28583
|
}
|
|
28490
28584
|
function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
28491
|
-
const sourceAgentsRoot =
|
|
28492
|
-
if (!
|
|
28585
|
+
const sourceAgentsRoot = path38.join(sourceRoot, config.source.agents);
|
|
28586
|
+
if (!fs39.existsSync(sourceAgentsRoot)) {
|
|
28493
28587
|
return [skippedMissingSource2("agents", sourceAgentsRoot)];
|
|
28494
28588
|
}
|
|
28495
|
-
const sourceAgents = ts(
|
|
28589
|
+
const sourceAgents = ts(path38.join(sourceAgentsRoot, "*.md")).sort();
|
|
28496
28590
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
28497
28591
|
return sourceAgents.map((agentFile) => {
|
|
28498
|
-
const destination =
|
|
28592
|
+
const destination = path38.join(
|
|
28499
28593
|
agentsRoot,
|
|
28500
|
-
`${
|
|
28594
|
+
`${path38.basename(agentFile, ".md")}.toml`
|
|
28501
28595
|
);
|
|
28502
28596
|
const compiled = compileAgent(
|
|
28503
28597
|
agentFile,
|
|
@@ -28575,7 +28669,7 @@ function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
28575
28669
|
destination,
|
|
28576
28670
|
hostHooks,
|
|
28577
28671
|
stringifyJson3,
|
|
28578
|
-
!
|
|
28672
|
+
!fs39.existsSync(destination),
|
|
28579
28673
|
logger
|
|
28580
28674
|
);
|
|
28581
28675
|
return {
|
|
@@ -28588,7 +28682,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28588
28682
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
28589
28683
|
const sourceLabel = mcpSourceLabel(config);
|
|
28590
28684
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
28591
|
-
if (!
|
|
28685
|
+
if (!fs39.existsSync(source)) {
|
|
28592
28686
|
if (providerToml && !options.dryRun) {
|
|
28593
28687
|
const changed2 = writeTomlManagedSection(
|
|
28594
28688
|
destination,
|
|
@@ -28603,7 +28697,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28603
28697
|
}
|
|
28604
28698
|
return skippedMissingSource2("mcp", source);
|
|
28605
28699
|
}
|
|
28606
|
-
const sourceMcpJson = JSON.parse(
|
|
28700
|
+
const sourceMcpJson = JSON.parse(fs39.readFileSync(source, "utf8"));
|
|
28607
28701
|
const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
|
|
28608
28702
|
const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
|
|
28609
28703
|
if (options.dryRun) {
|
|
@@ -28625,18 +28719,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
|
|
|
28625
28719
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
28626
28720
|
return { component, status: "conflict", path: destination };
|
|
28627
28721
|
}
|
|
28628
|
-
ensureDir(
|
|
28722
|
+
ensureDir(path38.dirname(destination));
|
|
28629
28723
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
28630
28724
|
if (clearedLink !== null) {
|
|
28631
28725
|
logger.verbose(
|
|
28632
28726
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
28633
28727
|
);
|
|
28634
28728
|
}
|
|
28635
|
-
|
|
28729
|
+
fs39.writeFileSync(destination, content);
|
|
28636
28730
|
return { component, status: "success", path: destination };
|
|
28637
28731
|
}
|
|
28638
28732
|
function writeTomlManagedSection(destination, managedContent, logger) {
|
|
28639
|
-
const current =
|
|
28733
|
+
const current = fs39.existsSync(destination) ? fs39.readFileSync(destination, "utf8") : "";
|
|
28640
28734
|
const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
|
|
28641
28735
|
if (isFirstWrite) {
|
|
28642
28736
|
logger.warn(
|
|
@@ -28652,8 +28746,8 @@ ${managedMcpEnd}
|
|
|
28652
28746
|
if (current === next.trimStart()) {
|
|
28653
28747
|
return false;
|
|
28654
28748
|
}
|
|
28655
|
-
ensureDir(
|
|
28656
|
-
|
|
28749
|
+
ensureDir(path38.dirname(destination));
|
|
28750
|
+
fs39.writeFileSync(destination, next.trimStart());
|
|
28657
28751
|
return true;
|
|
28658
28752
|
}
|
|
28659
28753
|
function removeManagedTomlSection(content) {
|
|
@@ -28679,18 +28773,27 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
|
|
|
28679
28773
|
if (manifest && scopePath) {
|
|
28680
28774
|
backupFile(destination, manifest, scopePath);
|
|
28681
28775
|
writeManifest(scopePath, manifest);
|
|
28682
|
-
|
|
28776
|
+
fs39.rmSync(destination, { recursive: true, force: true });
|
|
28683
28777
|
} else {
|
|
28684
|
-
|
|
28778
|
+
const parked = parkConflictingPath(
|
|
28779
|
+
destination,
|
|
28780
|
+
resolveScopePath(
|
|
28781
|
+
options.scope ?? "global",
|
|
28782
|
+
options.scope === "project" ? options.projectRoot : void 0
|
|
28783
|
+
)
|
|
28784
|
+
);
|
|
28785
|
+
logger.warn(
|
|
28786
|
+
`${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
|
|
28787
|
+
);
|
|
28685
28788
|
}
|
|
28686
28789
|
return true;
|
|
28687
28790
|
}
|
|
28688
|
-
|
|
28791
|
+
fs39.rmSync(destination, { recursive: true, force: true });
|
|
28689
28792
|
return true;
|
|
28690
28793
|
}
|
|
28691
28794
|
function isCompiledCurrent(destination, expectedContent, expectedHash) {
|
|
28692
28795
|
try {
|
|
28693
|
-
const current =
|
|
28796
|
+
const current = fs39.readFileSync(destination, "utf8");
|
|
28694
28797
|
const marker = extractProvenanceMarker(current);
|
|
28695
28798
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "codex" && current === expectedContent : current === expectedContent;
|
|
28696
28799
|
} catch {
|
|
@@ -28709,16 +28812,16 @@ function shouldSkipComponent2(options, component) {
|
|
|
28709
28812
|
}
|
|
28710
28813
|
function isSymlinkTo4(linkPath, source) {
|
|
28711
28814
|
try {
|
|
28712
|
-
return
|
|
28815
|
+
return fs39.realpathSync(linkPath) === fs39.realpathSync(source);
|
|
28713
28816
|
} catch {
|
|
28714
28817
|
return false;
|
|
28715
28818
|
}
|
|
28716
28819
|
}
|
|
28717
28820
|
function readJsonObject4(filePath) {
|
|
28718
|
-
if (!
|
|
28821
|
+
if (!fs39.existsSync(filePath)) {
|
|
28719
28822
|
return {};
|
|
28720
28823
|
}
|
|
28721
|
-
const parsed = JSON.parse(
|
|
28824
|
+
const parsed = JSON.parse(fs39.readFileSync(filePath, "utf8"));
|
|
28722
28825
|
return isRecord5(parsed) ? parsed : {};
|
|
28723
28826
|
}
|
|
28724
28827
|
function stringifyJson3(value) {
|
|
@@ -28734,16 +28837,16 @@ function hashString(value) {
|
|
|
28734
28837
|
|
|
28735
28838
|
// src/adapters/copilot.ts
|
|
28736
28839
|
import crypto7 from "crypto";
|
|
28737
|
-
import
|
|
28738
|
-
import
|
|
28840
|
+
import fs40 from "fs";
|
|
28841
|
+
import path40 from "path";
|
|
28739
28842
|
|
|
28740
28843
|
// src/compiler/commands.ts
|
|
28741
28844
|
var import_yaml10 = __toESM(require_dist(), 1);
|
|
28742
|
-
import
|
|
28845
|
+
import path39 from "path";
|
|
28743
28846
|
function compileCommandPrompt(sourceFile) {
|
|
28744
28847
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
28745
|
-
const relativeSource = `commands/${
|
|
28746
|
-
const fields = promptFrontmatter(data,
|
|
28848
|
+
const relativeSource = `commands/${path39.basename(sourceFile)}`;
|
|
28849
|
+
const fields = promptFrontmatter(data, path39.basename(sourceFile, ".md"));
|
|
28747
28850
|
const marker = formatProvenanceMarker(
|
|
28748
28851
|
"markdown",
|
|
28749
28852
|
relativeSource,
|
|
@@ -28858,7 +28961,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
28858
28961
|
if (!shouldSkipComponent3(options, "hooks")) {
|
|
28859
28962
|
outcomes.push(
|
|
28860
28963
|
syncHookScriptsBridge({
|
|
28861
|
-
source:
|
|
28964
|
+
source: path40.resolve(sourceRoot, config.source.hooks),
|
|
28862
28965
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
28863
28966
|
config,
|
|
28864
28967
|
sourceRoot,
|
|
@@ -28939,13 +29042,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
28939
29042
|
}
|
|
28940
29043
|
function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
|
|
28941
29044
|
if (!mappings.modelTiers.custom_provider) return;
|
|
28942
|
-
const agentsDir =
|
|
28943
|
-
if (!
|
|
28944
|
-
for (const agentFile of ts(
|
|
29045
|
+
const agentsDir = path40.join(sourceRoot, config.source.agents);
|
|
29046
|
+
if (!fs40.existsSync(agentsDir)) return;
|
|
29047
|
+
for (const agentFile of ts(path40.join(agentsDir, "*.md")).sort()) {
|
|
28945
29048
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28946
29049
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
28947
29050
|
if (hasProvider) {
|
|
28948
|
-
const basename =
|
|
29051
|
+
const basename = path40.basename(agentFile);
|
|
28949
29052
|
addLoss(lossReport, "copilot", "agents", {
|
|
28950
29053
|
source: `agents/${basename}`,
|
|
28951
29054
|
fields: [
|
|
@@ -28971,22 +29074,22 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
|
|
|
28971
29074
|
return [{ component: "instructions", status: "skipped", path: message }];
|
|
28972
29075
|
}
|
|
28973
29076
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
28974
|
-
if (!
|
|
29077
|
+
if (!fs40.existsSync(source)) {
|
|
28975
29078
|
return [skippedMissingSource3("instructions", source)];
|
|
28976
29079
|
}
|
|
28977
|
-
const rawContent =
|
|
29080
|
+
const rawContent = fs40.readFileSync(source, "utf8");
|
|
28978
29081
|
const contentHash = hashString2(rawContent);
|
|
28979
29082
|
const marker = formatProvenanceMarker(
|
|
28980
29083
|
"markdown",
|
|
28981
|
-
|
|
29084
|
+
path40.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
28982
29085
|
contentHash,
|
|
28983
29086
|
"copilot"
|
|
28984
29087
|
);
|
|
28985
29088
|
const composedContent = `${marker}
|
|
28986
29089
|
${rawContent}`;
|
|
28987
29090
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
28988
|
-
const agentsMdDest =
|
|
28989
|
-
const mirrorDest =
|
|
29091
|
+
const agentsMdDest = path40.resolve(projectRoot, "AGENTS.md");
|
|
29092
|
+
const mirrorDest = path40.resolve(
|
|
28990
29093
|
projectRoot,
|
|
28991
29094
|
".github",
|
|
28992
29095
|
"copilot-instructions.md"
|
|
@@ -29040,14 +29143,14 @@ function writeInstructionsFile(component, destination, content, contentHash, con
|
|
|
29040
29143
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29041
29144
|
return { component, status: "conflict", path: destination };
|
|
29042
29145
|
}
|
|
29043
|
-
ensureDir(
|
|
29146
|
+
ensureDir(path40.dirname(destination));
|
|
29044
29147
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29045
29148
|
if (clearedLink !== null) {
|
|
29046
29149
|
logger.verbose(
|
|
29047
29150
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29048
29151
|
);
|
|
29049
29152
|
}
|
|
29050
|
-
|
|
29153
|
+
fs40.writeFileSync(destination, content);
|
|
29051
29154
|
return { component, status: "success", path: destination };
|
|
29052
29155
|
}
|
|
29053
29156
|
function hashString2(value) {
|
|
@@ -29057,7 +29160,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29057
29160
|
return syncSkillsSlot({
|
|
29058
29161
|
config,
|
|
29059
29162
|
sourceRoot,
|
|
29060
|
-
source:
|
|
29163
|
+
source: path40.resolve(sourceRoot, config.source.skills),
|
|
29061
29164
|
destination: resolveTargetPath(paths.skills),
|
|
29062
29165
|
dryRun: options.dryRun,
|
|
29063
29166
|
logger,
|
|
@@ -29072,16 +29175,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29072
29175
|
});
|
|
29073
29176
|
}
|
|
29074
29177
|
function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29075
|
-
const sourceAgentsRoot =
|
|
29076
|
-
if (!
|
|
29178
|
+
const sourceAgentsRoot = path40.join(sourceRoot, config.source.agents);
|
|
29179
|
+
if (!fs40.existsSync(sourceAgentsRoot)) {
|
|
29077
29180
|
return [skippedMissingSource3("agents", sourceAgentsRoot)];
|
|
29078
29181
|
}
|
|
29079
|
-
const sourceAgents = ts(
|
|
29182
|
+
const sourceAgents = ts(path40.join(sourceAgentsRoot, "*.md")).sort();
|
|
29080
29183
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29081
29184
|
return sourceAgents.map((agentFile) => {
|
|
29082
|
-
const destination =
|
|
29185
|
+
const destination = path40.join(
|
|
29083
29186
|
agentsRoot,
|
|
29084
|
-
`${
|
|
29187
|
+
`${path40.basename(agentFile, ".md")}.agent.md`
|
|
29085
29188
|
);
|
|
29086
29189
|
const compiled = compileAgent(
|
|
29087
29190
|
agentFile,
|
|
@@ -29109,16 +29212,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29109
29212
|
});
|
|
29110
29213
|
}
|
|
29111
29214
|
function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29112
|
-
const sourceCommandsRoot =
|
|
29113
|
-
if (!
|
|
29215
|
+
const sourceCommandsRoot = path40.join(sourceRoot, config.source.commands);
|
|
29216
|
+
if (!fs40.existsSync(sourceCommandsRoot)) {
|
|
29114
29217
|
return [skippedMissingSource3("commands", sourceCommandsRoot)];
|
|
29115
29218
|
}
|
|
29116
|
-
const sourceCommands = ts(
|
|
29219
|
+
const sourceCommands = ts(path40.join(sourceCommandsRoot, "*.md")).sort();
|
|
29117
29220
|
const promptsRoot = resolveTargetPath(paths.prompts);
|
|
29118
29221
|
return sourceCommands.map((commandFile) => {
|
|
29119
|
-
const destination =
|
|
29222
|
+
const destination = path40.join(
|
|
29120
29223
|
promptsRoot,
|
|
29121
|
-
`${
|
|
29224
|
+
`${path40.basename(commandFile, ".md")}.prompt.md`
|
|
29122
29225
|
);
|
|
29123
29226
|
const compiled = compileCommandPrompt(commandFile);
|
|
29124
29227
|
if (options.dryRun) {
|
|
@@ -29142,7 +29245,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
|
|
|
29142
29245
|
});
|
|
29143
29246
|
}
|
|
29144
29247
|
function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
29145
|
-
const destination =
|
|
29248
|
+
const destination = path40.join(
|
|
29146
29249
|
resolveTargetPath(paths.hooks),
|
|
29147
29250
|
"tangyr-managed.json"
|
|
29148
29251
|
);
|
|
@@ -29205,10 +29308,10 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
29205
29308
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
29206
29309
|
const sourceLabel = mcpSourceLabel(config);
|
|
29207
29310
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
29208
|
-
if (!
|
|
29311
|
+
if (!fs40.existsSync(source)) {
|
|
29209
29312
|
return skippedMissingSource3("mcp", source);
|
|
29210
29313
|
}
|
|
29211
|
-
const sourceMcpJson = JSON.parse(
|
|
29314
|
+
const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
|
|
29212
29315
|
const compiled = compileMcp(
|
|
29213
29316
|
sourceMcpJson,
|
|
29214
29317
|
"copilot",
|
|
@@ -29238,19 +29341,19 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
|
|
|
29238
29341
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29239
29342
|
return { component, status: "conflict", path: destination };
|
|
29240
29343
|
}
|
|
29241
|
-
ensureDir(
|
|
29344
|
+
ensureDir(path40.dirname(destination));
|
|
29242
29345
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29243
29346
|
if (clearedLink !== null) {
|
|
29244
29347
|
logger.verbose(
|
|
29245
29348
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29246
29349
|
);
|
|
29247
29350
|
}
|
|
29248
|
-
|
|
29351
|
+
fs40.writeFileSync(destination, content);
|
|
29249
29352
|
return { component, status: "success", path: destination };
|
|
29250
29353
|
}
|
|
29251
29354
|
function isCompiledCurrent2(destination, expectedContent, expectedHash) {
|
|
29252
29355
|
try {
|
|
29253
|
-
const current =
|
|
29356
|
+
const current = fs40.readFileSync(destination, "utf8");
|
|
29254
29357
|
const marker = extractProvenanceMarker(current);
|
|
29255
29358
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "copilot" && current === expectedContent : current === expectedContent;
|
|
29256
29359
|
} catch {
|
|
@@ -29272,13 +29375,22 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
|
|
|
29272
29375
|
if (manifest && scopePath) {
|
|
29273
29376
|
backupFile(destination, manifest, scopePath);
|
|
29274
29377
|
writeManifest(scopePath, manifest);
|
|
29275
|
-
|
|
29378
|
+
fs40.rmSync(destination, { recursive: true, force: true });
|
|
29276
29379
|
} else {
|
|
29277
|
-
|
|
29380
|
+
const parked = parkConflictingPath(
|
|
29381
|
+
destination,
|
|
29382
|
+
resolveScopePath(
|
|
29383
|
+
options.scope ?? "global",
|
|
29384
|
+
options.scope === "project" ? options.projectRoot : void 0
|
|
29385
|
+
)
|
|
29386
|
+
);
|
|
29387
|
+
logger.warn(
|
|
29388
|
+
`${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
|
|
29389
|
+
);
|
|
29278
29390
|
}
|
|
29279
29391
|
return true;
|
|
29280
29392
|
}
|
|
29281
|
-
|
|
29393
|
+
fs40.rmSync(destination, { recursive: true, force: true });
|
|
29282
29394
|
return true;
|
|
29283
29395
|
}
|
|
29284
29396
|
function shouldSkipComponent3(options, component) {
|
|
@@ -29287,12 +29399,12 @@ function shouldSkipComponent3(options, component) {
|
|
|
29287
29399
|
function cleanupLegacyAgents(paths, options, logger) {
|
|
29288
29400
|
const currentAgentsRoot = resolveTargetPath(paths.agents);
|
|
29289
29401
|
const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
|
|
29290
|
-
if (
|
|
29402
|
+
if (path40.resolve(currentAgentsRoot) === path40.resolve(legacyAgentsRoot)) {
|
|
29291
29403
|
return [];
|
|
29292
29404
|
}
|
|
29293
29405
|
const outcomes = [];
|
|
29294
29406
|
for (const filePath of ts(
|
|
29295
|
-
|
|
29407
|
+
path40.join(legacyAgentsRoot, "*.agent.md")
|
|
29296
29408
|
).sort()) {
|
|
29297
29409
|
if (!isCopilotManagedCompiledFile(filePath)) {
|
|
29298
29410
|
continue;
|
|
@@ -29302,14 +29414,14 @@ function cleanupLegacyAgents(paths, options, logger) {
|
|
|
29302
29414
|
outcomes.push({ component: "agents", status: "dry-run", path: filePath });
|
|
29303
29415
|
continue;
|
|
29304
29416
|
}
|
|
29305
|
-
|
|
29417
|
+
fs40.rmSync(filePath, { force: true });
|
|
29306
29418
|
outcomes.push({ component: "agents", status: "success", path: filePath });
|
|
29307
29419
|
}
|
|
29308
29420
|
return outcomes;
|
|
29309
29421
|
}
|
|
29310
29422
|
function isCopilotManagedCompiledFile(filePath) {
|
|
29311
29423
|
try {
|
|
29312
|
-
return extractProvenanceMarker(
|
|
29424
|
+
return extractProvenanceMarker(fs40.readFileSync(filePath, "utf8"))?.target === "copilot";
|
|
29313
29425
|
} catch {
|
|
29314
29426
|
return false;
|
|
29315
29427
|
}
|
|
@@ -29324,8 +29436,8 @@ function skippedMissingSource3(component, source) {
|
|
|
29324
29436
|
|
|
29325
29437
|
// src/adapters/cursor.ts
|
|
29326
29438
|
import crypto8 from "crypto";
|
|
29327
|
-
import
|
|
29328
|
-
import
|
|
29439
|
+
import fs41 from "fs";
|
|
29440
|
+
import path41 from "path";
|
|
29329
29441
|
function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29330
29442
|
const scope = options.scope ?? "global";
|
|
29331
29443
|
const profile = resolveTargetPaths({
|
|
@@ -29437,7 +29549,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
29437
29549
|
if (!shouldSkipComponent4(options, "hooks")) {
|
|
29438
29550
|
outcomes.push(
|
|
29439
29551
|
syncHookScriptsBridge({
|
|
29440
|
-
source:
|
|
29552
|
+
source: path41.resolve(sourceRoot, config.source.hooks),
|
|
29441
29553
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
29442
29554
|
config,
|
|
29443
29555
|
sourceRoot,
|
|
@@ -29502,7 +29614,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
|
|
|
29502
29614
|
const composed = composeCursorInstructions(config, sourceRoot, lossReport);
|
|
29503
29615
|
const marker = formatProvenanceMarker(
|
|
29504
29616
|
"markdown",
|
|
29505
|
-
|
|
29617
|
+
path41.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
29506
29618
|
hashString3(composed),
|
|
29507
29619
|
"cursor"
|
|
29508
29620
|
);
|
|
@@ -29528,7 +29640,7 @@ ${composed}
|
|
|
29528
29640
|
}
|
|
29529
29641
|
function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
29530
29642
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
29531
|
-
const baseContent =
|
|
29643
|
+
const baseContent = fs41.existsSync(source) ? fs41.readFileSync(source, "utf8").trim() : "";
|
|
29532
29644
|
const personaContent = extractPrimaryPersonaContent(
|
|
29533
29645
|
config,
|
|
29534
29646
|
sourceRoot,
|
|
@@ -29541,11 +29653,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
|
29541
29653
|
${personaContent}`.trim() : baseContent;
|
|
29542
29654
|
}
|
|
29543
29655
|
function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
29544
|
-
const agentsDir =
|
|
29545
|
-
if (!
|
|
29656
|
+
const agentsDir = path41.join(sourceRoot, config.source.agents);
|
|
29657
|
+
if (!fs41.existsSync(agentsDir)) {
|
|
29546
29658
|
return null;
|
|
29547
29659
|
}
|
|
29548
|
-
const agentFiles = ts(
|
|
29660
|
+
const agentFiles = ts(path41.join(agentsDir, "*.md")).sort();
|
|
29549
29661
|
if (agentFiles.length === 0) {
|
|
29550
29662
|
return null;
|
|
29551
29663
|
}
|
|
@@ -29568,7 +29680,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29568
29680
|
return null;
|
|
29569
29681
|
}
|
|
29570
29682
|
addLoss(lossReport, "cursor", "instructions", {
|
|
29571
|
-
source: `agents/${
|
|
29683
|
+
source: `agents/${path41.basename(primaryFile)}`,
|
|
29572
29684
|
fields: [
|
|
29573
29685
|
{
|
|
29574
29686
|
field: "persona",
|
|
@@ -29578,23 +29690,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29578
29690
|
"persona",
|
|
29579
29691
|
"instructions-shim"
|
|
29580
29692
|
),
|
|
29581
|
-
detail: `Primary persona from ${
|
|
29693
|
+
detail: `Primary persona from ${path41.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
|
|
29582
29694
|
}
|
|
29583
29695
|
]
|
|
29584
29696
|
});
|
|
29585
29697
|
return body.trim();
|
|
29586
29698
|
}
|
|
29587
29699
|
function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29588
|
-
const sourceAgentsRoot =
|
|
29589
|
-
if (!
|
|
29700
|
+
const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
|
|
29701
|
+
if (!fs41.existsSync(sourceAgentsRoot)) {
|
|
29590
29702
|
return [skippedMissingSource4("agents", sourceAgentsRoot)];
|
|
29591
29703
|
}
|
|
29592
|
-
const sourceAgents = ts(
|
|
29704
|
+
const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
|
|
29593
29705
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29594
29706
|
return sourceAgents.map((agentFile) => {
|
|
29595
|
-
const destination =
|
|
29707
|
+
const destination = path41.join(
|
|
29596
29708
|
agentsRoot,
|
|
29597
|
-
`${
|
|
29709
|
+
`${path41.basename(agentFile, ".md")}.md`
|
|
29598
29710
|
);
|
|
29599
29711
|
let compiled;
|
|
29600
29712
|
try {
|
|
@@ -29635,14 +29747,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29635
29747
|
});
|
|
29636
29748
|
}
|
|
29637
29749
|
function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
29638
|
-
const sourceRulesDir =
|
|
29639
|
-
if (!
|
|
29750
|
+
const sourceRulesDir = path41.join(sourceRoot, config.source.rules);
|
|
29751
|
+
if (!fs41.existsSync(sourceRulesDir)) {
|
|
29640
29752
|
return [skippedMissingSource4("rules", sourceRulesDir)];
|
|
29641
29753
|
}
|
|
29642
29754
|
const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
|
|
29643
29755
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
29644
29756
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
29645
|
-
const destination =
|
|
29757
|
+
const destination = path41.join(rulesDir, name);
|
|
29646
29758
|
if (options.dryRun) {
|
|
29647
29759
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
29648
29760
|
return {
|
|
@@ -29666,17 +29778,17 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
29666
29778
|
});
|
|
29667
29779
|
}
|
|
29668
29780
|
function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29669
|
-
const sourceCommandsRoot =
|
|
29670
|
-
if (!
|
|
29781
|
+
const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
|
|
29782
|
+
if (!fs41.existsSync(sourceCommandsRoot)) {
|
|
29671
29783
|
return [skippedMissingSource4("commands", sourceCommandsRoot)];
|
|
29672
29784
|
}
|
|
29673
|
-
const sourceCommands = ts(
|
|
29785
|
+
const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
|
|
29674
29786
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
29675
29787
|
return sourceCommands.map((commandFile) => {
|
|
29676
|
-
const baseName =
|
|
29677
|
-
const destination =
|
|
29678
|
-
const commandContent =
|
|
29679
|
-
const relativeSource = `commands/${
|
|
29788
|
+
const baseName = path41.basename(commandFile, ".md");
|
|
29789
|
+
const destination = path41.join(skillsRoot, baseName, "SKILL.md");
|
|
29790
|
+
const commandContent = fs41.readFileSync(commandFile, "utf8");
|
|
29791
|
+
const relativeSource = `commands/${path41.basename(commandFile)}`;
|
|
29680
29792
|
const marker = formatProvenanceMarker(
|
|
29681
29793
|
"markdown",
|
|
29682
29794
|
relativeSource,
|
|
@@ -29715,8 +29827,8 @@ ${commandContent.trim()}
|
|
|
29715
29827
|
});
|
|
29716
29828
|
}
|
|
29717
29829
|
function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
|
|
29718
|
-
const source =
|
|
29719
|
-
if (!
|
|
29830
|
+
const source = path41.resolve(sourceRoot, config.source.skills);
|
|
29831
|
+
if (!fs41.existsSync(source)) {
|
|
29720
29832
|
return skippedMissingSource4(component, source);
|
|
29721
29833
|
}
|
|
29722
29834
|
if (options.dryRun) {
|
|
@@ -29730,18 +29842,18 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
|
|
|
29730
29842
|
return { component, status: "skipped-current", path: destination };
|
|
29731
29843
|
}
|
|
29732
29844
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
29733
|
-
|
|
29845
|
+
fs41.unlinkSync(destination);
|
|
29734
29846
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
29735
29847
|
return { component, status: "conflict", path: destination };
|
|
29736
29848
|
} else if (artifactClass === "managed-symlink") {
|
|
29737
|
-
|
|
29849
|
+
fs41.unlinkSync(destination);
|
|
29738
29850
|
}
|
|
29739
|
-
ensureDir(
|
|
29851
|
+
ensureDir(path41.dirname(destination));
|
|
29740
29852
|
createRelativeSymlink(source, destination, "dir");
|
|
29741
29853
|
logger.verbose(`Skills: created shared skills symlink ${destination}`);
|
|
29742
29854
|
return { component, status: "success", path: destination };
|
|
29743
29855
|
}
|
|
29744
|
-
if (
|
|
29856
|
+
if (fs41.existsSync(destination)) {
|
|
29745
29857
|
return { component, status: "skipped-current", path: destination };
|
|
29746
29858
|
}
|
|
29747
29859
|
ensureDir(destination);
|
|
@@ -29782,18 +29894,18 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
29782
29894
|
}
|
|
29783
29895
|
const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
|
|
29784
29896
|
`;
|
|
29785
|
-
ensureDir(
|
|
29786
|
-
|
|
29897
|
+
ensureDir(path41.dirname(destination));
|
|
29898
|
+
fs41.writeFileSync(destination, hooksFileContent);
|
|
29787
29899
|
return { component: "hooks", status: "success", path: destination };
|
|
29788
29900
|
}
|
|
29789
29901
|
function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
|
|
29790
29902
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
29791
29903
|
const sourceLabel = mcpSourceLabel(config);
|
|
29792
29904
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
29793
|
-
if (!
|
|
29905
|
+
if (!fs41.existsSync(source)) {
|
|
29794
29906
|
return skippedMissingSource4("mcp", source);
|
|
29795
29907
|
}
|
|
29796
|
-
const sourceMcpJson = JSON.parse(
|
|
29908
|
+
const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
|
|
29797
29909
|
const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
|
|
29798
29910
|
if (options.dryRun) {
|
|
29799
29911
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -29846,13 +29958,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
|
|
|
29846
29958
|
);
|
|
29847
29959
|
}
|
|
29848
29960
|
function syncProviderPin(config, sourceRoot, lossReport) {
|
|
29849
|
-
const agentsDir =
|
|
29850
|
-
if (!
|
|
29851
|
-
for (const agentFile of ts(
|
|
29961
|
+
const agentsDir = path41.join(sourceRoot, config.source.agents);
|
|
29962
|
+
if (!fs41.existsSync(agentsDir)) return;
|
|
29963
|
+
for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
|
|
29852
29964
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
29853
29965
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
29854
29966
|
if (hasCustomProvider) {
|
|
29855
|
-
const relativeSource = `agents/${
|
|
29967
|
+
const relativeSource = `agents/${path41.basename(agentFile)}`;
|
|
29856
29968
|
addLoss(lossReport, "cursor", "agents", {
|
|
29857
29969
|
source: relativeSource,
|
|
29858
29970
|
fields: [
|
|
@@ -29864,7 +29976,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
|
|
|
29864
29976
|
"provider",
|
|
29865
29977
|
"provider-not-representable"
|
|
29866
29978
|
),
|
|
29867
|
-
detail: `${
|
|
29979
|
+
detail: `${path41.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
29868
29980
|
}
|
|
29869
29981
|
]
|
|
29870
29982
|
});
|
|
@@ -29879,14 +29991,14 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
|
|
|
29879
29991
|
if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
29880
29992
|
return { component, status: "conflict", path: destination };
|
|
29881
29993
|
}
|
|
29882
|
-
ensureDir(
|
|
29994
|
+
ensureDir(path41.dirname(destination));
|
|
29883
29995
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29884
29996
|
if (clearedLink !== null) {
|
|
29885
29997
|
logger.verbose(
|
|
29886
29998
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29887
29999
|
);
|
|
29888
30000
|
}
|
|
29889
|
-
|
|
30001
|
+
fs41.writeFileSync(destination, content);
|
|
29890
30002
|
return { component, status: "success", path: destination };
|
|
29891
30003
|
}
|
|
29892
30004
|
function handleConflict4(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -29904,18 +30016,27 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
|
|
|
29904
30016
|
if (manifest && scopePath) {
|
|
29905
30017
|
backupFile(destination, manifest, scopePath);
|
|
29906
30018
|
writeManifest(scopePath, manifest);
|
|
29907
|
-
|
|
30019
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
29908
30020
|
} else {
|
|
29909
|
-
|
|
30021
|
+
const parked = parkConflictingPath(
|
|
30022
|
+
destination,
|
|
30023
|
+
resolveScopePath(
|
|
30024
|
+
options.scope ?? "global",
|
|
30025
|
+
options.scope === "project" ? options.projectRoot : void 0
|
|
30026
|
+
)
|
|
30027
|
+
);
|
|
30028
|
+
logger.warn(
|
|
30029
|
+
`${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
|
|
30030
|
+
);
|
|
29910
30031
|
}
|
|
29911
30032
|
return true;
|
|
29912
30033
|
}
|
|
29913
|
-
|
|
30034
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
29914
30035
|
return true;
|
|
29915
30036
|
}
|
|
29916
30037
|
function isCompiledCurrent3(destination, expectedContent, expectedHash) {
|
|
29917
30038
|
try {
|
|
29918
|
-
const current =
|
|
30039
|
+
const current = fs41.readFileSync(destination, "utf8");
|
|
29919
30040
|
const marker = extractProvenanceMarker(current);
|
|
29920
30041
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cursor" && current === expectedContent : current === expectedContent;
|
|
29921
30042
|
} catch {
|
|
@@ -29934,7 +30055,7 @@ function shouldSkipComponent4(options, component) {
|
|
|
29934
30055
|
}
|
|
29935
30056
|
function isSymlinkTo5(linkPath, source) {
|
|
29936
30057
|
try {
|
|
29937
|
-
return
|
|
30058
|
+
return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
|
|
29938
30059
|
} catch {
|
|
29939
30060
|
return false;
|
|
29940
30061
|
}
|
|
@@ -29945,8 +30066,8 @@ function hashString3(value) {
|
|
|
29945
30066
|
|
|
29946
30067
|
// src/adapters/cline.ts
|
|
29947
30068
|
import crypto9 from "crypto";
|
|
29948
|
-
import
|
|
29949
|
-
import
|
|
30069
|
+
import fs42 from "fs";
|
|
30070
|
+
import path42 from "path";
|
|
29950
30071
|
function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29951
30072
|
const scope = options.scope ?? "global";
|
|
29952
30073
|
const profile = resolveTargetPaths({
|
|
@@ -30059,7 +30180,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
30059
30180
|
function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
|
|
30060
30181
|
if (scope === "global" || paths.instructions === null) {
|
|
30061
30182
|
addLoss(lossReport, "cline", "instructions", {
|
|
30062
|
-
source:
|
|
30183
|
+
source: path42.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30063
30184
|
fields: [
|
|
30064
30185
|
{
|
|
30065
30186
|
field: "instructions",
|
|
@@ -30081,10 +30202,10 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
|
|
|
30081
30202
|
}
|
|
30082
30203
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30083
30204
|
const destination = resolveTargetPath(paths.instructions);
|
|
30084
|
-
const baseContent =
|
|
30205
|
+
const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
|
|
30085
30206
|
const marker = formatProvenanceMarker(
|
|
30086
30207
|
"markdown",
|
|
30087
|
-
|
|
30208
|
+
path42.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30088
30209
|
hashString4(baseContent),
|
|
30089
30210
|
"cline"
|
|
30090
30211
|
);
|
|
@@ -30109,11 +30230,11 @@ ${baseContent}
|
|
|
30109
30230
|
);
|
|
30110
30231
|
}
|
|
30111
30232
|
function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
|
|
30112
|
-
const sourceAgentsRoot =
|
|
30113
|
-
if (!
|
|
30233
|
+
const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
|
|
30234
|
+
if (!fs42.existsSync(sourceAgentsRoot)) {
|
|
30114
30235
|
return [skippedMissingSource5("agents", sourceAgentsRoot)];
|
|
30115
30236
|
}
|
|
30116
|
-
const sourceAgents = ts(
|
|
30237
|
+
const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
|
|
30117
30238
|
return sourceAgents.map((agentFile) => {
|
|
30118
30239
|
compileAgent(agentFile, "cline", mappings, extensions, lossReport);
|
|
30119
30240
|
if (options.dryRun) {
|
|
@@ -30129,14 +30250,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
30129
30250
|
});
|
|
30130
30251
|
}
|
|
30131
30252
|
function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
30132
|
-
const sourceRulesDir =
|
|
30133
|
-
if (!
|
|
30253
|
+
const sourceRulesDir = path42.join(sourceRoot, config.source.rules);
|
|
30254
|
+
if (!fs42.existsSync(sourceRulesDir)) {
|
|
30134
30255
|
return [skippedMissingSource5("rules", sourceRulesDir)];
|
|
30135
30256
|
}
|
|
30136
30257
|
const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
|
|
30137
30258
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
30138
30259
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
30139
|
-
const destination =
|
|
30260
|
+
const destination = path42.join(rulesDir, name);
|
|
30140
30261
|
if (options.dryRun) {
|
|
30141
30262
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
30142
30263
|
return {
|
|
@@ -30160,17 +30281,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
30160
30281
|
});
|
|
30161
30282
|
}
|
|
30162
30283
|
function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30163
|
-
const sourceCommandsRoot =
|
|
30164
|
-
if (!
|
|
30284
|
+
const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
|
|
30285
|
+
if (!fs42.existsSync(sourceCommandsRoot)) {
|
|
30165
30286
|
return [skippedMissingSource5("commands", sourceCommandsRoot)];
|
|
30166
30287
|
}
|
|
30167
|
-
const sourceCommands = ts(
|
|
30288
|
+
const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
|
|
30168
30289
|
const workflowsRoot = resolveTargetPath(paths.workflows);
|
|
30169
30290
|
return sourceCommands.map((commandFile) => {
|
|
30170
|
-
const baseName =
|
|
30171
|
-
const destination =
|
|
30172
|
-
const commandContent =
|
|
30173
|
-
const relativeSource = `commands/${
|
|
30291
|
+
const baseName = path42.basename(commandFile);
|
|
30292
|
+
const destination = path42.join(workflowsRoot, baseName);
|
|
30293
|
+
const commandContent = fs42.readFileSync(commandFile, "utf8");
|
|
30294
|
+
const relativeSource = `commands/${path42.basename(commandFile)}`;
|
|
30174
30295
|
const marker = formatProvenanceMarker(
|
|
30175
30296
|
"markdown",
|
|
30176
30297
|
relativeSource,
|
|
@@ -30205,9 +30326,9 @@ ${commandContent.trim()}
|
|
|
30205
30326
|
});
|
|
30206
30327
|
}
|
|
30207
30328
|
function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30208
|
-
const source =
|
|
30329
|
+
const source = path42.resolve(sourceRoot, config.source.skills);
|
|
30209
30330
|
const destination = resolveTargetPath(paths.skills);
|
|
30210
|
-
if (!
|
|
30331
|
+
if (!fs42.existsSync(source)) {
|
|
30211
30332
|
return skippedMissingSource5("skills", source);
|
|
30212
30333
|
}
|
|
30213
30334
|
if (options.dryRun) {
|
|
@@ -30231,15 +30352,15 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
30231
30352
|
// unsynced.
|
|
30232
30353
|
artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)
|
|
30233
30354
|
) {
|
|
30234
|
-
|
|
30355
|
+
fs42.unlinkSync(destination);
|
|
30235
30356
|
} else if (artifactClass === "unmanaged-conflict") {
|
|
30236
30357
|
if (!handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
30237
30358
|
return { component: "skills", status: "conflict", path: destination };
|
|
30238
30359
|
}
|
|
30239
30360
|
} else if (artifactClass === "managed-symlink") {
|
|
30240
|
-
|
|
30361
|
+
fs42.unlinkSync(destination);
|
|
30241
30362
|
}
|
|
30242
|
-
ensureDir(
|
|
30363
|
+
ensureDir(path42.dirname(destination));
|
|
30243
30364
|
createRelativeSymlink(source, destination, "dir");
|
|
30244
30365
|
logger.verbose(`Skills: created Cline skills symlink ${destination}`);
|
|
30245
30366
|
return { component: "skills", status: "success", path: destination };
|
|
@@ -30263,10 +30384,10 @@ function syncMcp5(config, sourceRoot, paths, options, lossReport, logger, manife
|
|
|
30263
30384
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30264
30385
|
const sourceLabel = mcpSourceLabel(config);
|
|
30265
30386
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
30266
|
-
if (!
|
|
30387
|
+
if (!fs42.existsSync(source)) {
|
|
30267
30388
|
return skippedMissingSource5("mcp", source);
|
|
30268
30389
|
}
|
|
30269
|
-
const sourceMcpJson = JSON.parse(
|
|
30390
|
+
const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
|
|
30270
30391
|
const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
|
|
30271
30392
|
if (options.dryRun) {
|
|
30272
30393
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -30309,11 +30430,11 @@ function syncSettings2(lossReport) {
|
|
|
30309
30430
|
};
|
|
30310
30431
|
}
|
|
30311
30432
|
function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
30312
|
-
const agentsDir =
|
|
30313
|
-
if (!
|
|
30314
|
-
for (const agentFile of ts(
|
|
30433
|
+
const agentsDir = path42.join(sourceRoot, config.source.agents);
|
|
30434
|
+
if (!fs42.existsSync(agentsDir)) return;
|
|
30435
|
+
for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
|
|
30315
30436
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
30316
|
-
const relativeSource = `agents/${
|
|
30437
|
+
const relativeSource = `agents/${path42.basename(agentFile)}`;
|
|
30317
30438
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
30318
30439
|
if (hasCustomProvider) {
|
|
30319
30440
|
addLoss(lossReport, "cline", "agents", {
|
|
@@ -30327,7 +30448,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30327
30448
|
"provider",
|
|
30328
30449
|
"provider-not-representable"
|
|
30329
30450
|
),
|
|
30330
|
-
detail: `${
|
|
30451
|
+
detail: `${path42.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
|
|
30331
30452
|
}
|
|
30332
30453
|
]
|
|
30333
30454
|
});
|
|
@@ -30345,7 +30466,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30345
30466
|
"model",
|
|
30346
30467
|
"model-not-representable"
|
|
30347
30468
|
),
|
|
30348
|
-
detail: `${
|
|
30469
|
+
detail: `${path42.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
|
|
30349
30470
|
}
|
|
30350
30471
|
]
|
|
30351
30472
|
});
|
|
@@ -30360,14 +30481,14 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
|
|
|
30360
30481
|
if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
30361
30482
|
return { component, status: "conflict", path: destination };
|
|
30362
30483
|
}
|
|
30363
|
-
ensureDir(
|
|
30484
|
+
ensureDir(path42.dirname(destination));
|
|
30364
30485
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30365
30486
|
if (clearedLink !== null) {
|
|
30366
30487
|
logger.verbose(
|
|
30367
30488
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30368
30489
|
);
|
|
30369
30490
|
}
|
|
30370
|
-
|
|
30491
|
+
fs42.writeFileSync(destination, content);
|
|
30371
30492
|
return { component, status: "success", path: destination };
|
|
30372
30493
|
}
|
|
30373
30494
|
function handleConflict5(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30385,18 +30506,27 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
|
|
|
30385
30506
|
if (manifest && scopePath) {
|
|
30386
30507
|
backupFile(destination, manifest, scopePath);
|
|
30387
30508
|
writeManifest(scopePath, manifest);
|
|
30388
|
-
|
|
30509
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
30389
30510
|
} else {
|
|
30390
|
-
|
|
30511
|
+
const parked = parkConflictingPath(
|
|
30512
|
+
destination,
|
|
30513
|
+
resolveScopePath(
|
|
30514
|
+
options.scope ?? "global",
|
|
30515
|
+
options.scope === "project" ? options.projectRoot : void 0
|
|
30516
|
+
)
|
|
30517
|
+
);
|
|
30518
|
+
logger.warn(
|
|
30519
|
+
`${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
|
|
30520
|
+
);
|
|
30391
30521
|
}
|
|
30392
30522
|
return true;
|
|
30393
30523
|
}
|
|
30394
|
-
|
|
30524
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
30395
30525
|
return true;
|
|
30396
30526
|
}
|
|
30397
30527
|
function isCompiledCurrent4(destination, expectedContent, expectedHash) {
|
|
30398
30528
|
try {
|
|
30399
|
-
const current =
|
|
30529
|
+
const current = fs42.readFileSync(destination, "utf8");
|
|
30400
30530
|
const marker = extractProvenanceMarker(current);
|
|
30401
30531
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cline" && current === expectedContent : current === expectedContent;
|
|
30402
30532
|
} catch {
|
|
@@ -30415,7 +30545,7 @@ function shouldSkipComponent5(options, component) {
|
|
|
30415
30545
|
}
|
|
30416
30546
|
function isSymlinkTo6(linkPath, source) {
|
|
30417
30547
|
try {
|
|
30418
|
-
return
|
|
30548
|
+
return fs42.realpathSync(linkPath) === fs42.realpathSync(source);
|
|
30419
30549
|
} catch {
|
|
30420
30550
|
return false;
|
|
30421
30551
|
}
|
|
@@ -30426,9 +30556,9 @@ function hashString4(value) {
|
|
|
30426
30556
|
|
|
30427
30557
|
// src/adapters/opencode.ts
|
|
30428
30558
|
import crypto10 from "crypto";
|
|
30429
|
-
import
|
|
30559
|
+
import fs43 from "fs";
|
|
30430
30560
|
import os6 from "os";
|
|
30431
|
-
import
|
|
30561
|
+
import path43 from "path";
|
|
30432
30562
|
var import_yaml11 = __toESM(require_dist(), 1);
|
|
30433
30563
|
function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30434
30564
|
const scope = options.scope ?? "global";
|
|
@@ -30446,7 +30576,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30446
30576
|
config_doc: profile.config_doc
|
|
30447
30577
|
};
|
|
30448
30578
|
const rules = compileRules(
|
|
30449
|
-
|
|
30579
|
+
path43.join(sourceRoot, config.source.rules),
|
|
30450
30580
|
"opencode",
|
|
30451
30581
|
mappings,
|
|
30452
30582
|
lossReport
|
|
@@ -30550,14 +30680,14 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30550
30680
|
function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
30551
30681
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30552
30682
|
const destination = resolveTargetPath(paths.instructions);
|
|
30553
|
-
const baseContent =
|
|
30683
|
+
const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
|
|
30554
30684
|
const composed = agentsAppendix ? `${baseContent}
|
|
30555
30685
|
|
|
30556
30686
|
--- tangyr managed rules ---
|
|
30557
30687
|
${agentsAppendix}`.trim() : baseContent;
|
|
30558
30688
|
const marker = formatProvenanceMarker(
|
|
30559
30689
|
"markdown",
|
|
30560
|
-
|
|
30690
|
+
path43.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30561
30691
|
hashString5(composed),
|
|
30562
30692
|
"opencode"
|
|
30563
30693
|
);
|
|
@@ -30584,16 +30714,16 @@ ${composed}
|
|
|
30584
30714
|
);
|
|
30585
30715
|
}
|
|
30586
30716
|
function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30587
|
-
const sourceAgentsRoot =
|
|
30588
|
-
if (!
|
|
30717
|
+
const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
|
|
30718
|
+
if (!fs43.existsSync(sourceAgentsRoot)) {
|
|
30589
30719
|
return [skippedMissingSource6("agents", sourceAgentsRoot)];
|
|
30590
30720
|
}
|
|
30591
|
-
const sourceAgents = ts(
|
|
30721
|
+
const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
|
|
30592
30722
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
30593
30723
|
return sourceAgents.map((agentFile) => {
|
|
30594
|
-
const destination =
|
|
30724
|
+
const destination = path43.join(
|
|
30595
30725
|
agentsRoot,
|
|
30596
|
-
`${
|
|
30726
|
+
`${path43.basename(agentFile, ".md")}.md`
|
|
30597
30727
|
);
|
|
30598
30728
|
let compiled;
|
|
30599
30729
|
try {
|
|
@@ -30657,11 +30787,11 @@ function applyProviderModelBinding(compiled, mappings) {
|
|
|
30657
30787
|
return `${before}${(0, import_yaml11.stringify)(fields).trim()}${after}`;
|
|
30658
30788
|
}
|
|
30659
30789
|
function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30660
|
-
const sourceCommandsRoot =
|
|
30661
|
-
if (!
|
|
30790
|
+
const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
|
|
30791
|
+
if (!fs43.existsSync(sourceCommandsRoot)) {
|
|
30662
30792
|
return [skippedMissingSource6("commands", sourceCommandsRoot)];
|
|
30663
30793
|
}
|
|
30664
|
-
const sourceCommands = ts(
|
|
30794
|
+
const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
|
|
30665
30795
|
const commandsRoot = resolveTargetPath(paths.commands);
|
|
30666
30796
|
return sourceCommands.map((commandFile) => {
|
|
30667
30797
|
const { data, body } = parseCommandFile(commandFile);
|
|
@@ -30675,7 +30805,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
|
|
|
30675
30805
|
if (typeof data.model === "string") {
|
|
30676
30806
|
frontmatter.model = data.model;
|
|
30677
30807
|
}
|
|
30678
|
-
const relativeSource = `commands/${
|
|
30808
|
+
const relativeSource = `commands/${path43.basename(commandFile)}`;
|
|
30679
30809
|
const marker = formatProvenanceMarker(
|
|
30680
30810
|
"markdown",
|
|
30681
30811
|
relativeSource,
|
|
@@ -30691,9 +30821,9 @@ ${body.trimEnd()}
|
|
|
30691
30821
|
` : `${marker}
|
|
30692
30822
|
${body.trimEnd()}
|
|
30693
30823
|
`;
|
|
30694
|
-
const destination =
|
|
30824
|
+
const destination = path43.join(
|
|
30695
30825
|
commandsRoot,
|
|
30696
|
-
`${
|
|
30826
|
+
`${path43.basename(commandFile, ".md")}.md`
|
|
30697
30827
|
);
|
|
30698
30828
|
if (options.dryRun) {
|
|
30699
30829
|
logger.info(
|
|
@@ -30720,8 +30850,8 @@ ${body.trimEnd()}
|
|
|
30720
30850
|
});
|
|
30721
30851
|
}
|
|
30722
30852
|
function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
|
|
30723
|
-
const source =
|
|
30724
|
-
if (!
|
|
30853
|
+
const source = path43.resolve(sourceRoot, config.source.skills);
|
|
30854
|
+
if (!fs43.existsSync(source)) {
|
|
30725
30855
|
return skippedMissingSource6(component, source);
|
|
30726
30856
|
}
|
|
30727
30857
|
if (options.dryRun) {
|
|
@@ -30733,13 +30863,13 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
|
|
|
30733
30863
|
return { component, status: "skipped-current", path: destination };
|
|
30734
30864
|
}
|
|
30735
30865
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
30736
|
-
|
|
30866
|
+
fs43.unlinkSync(destination);
|
|
30737
30867
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
30738
30868
|
return { component, status: "conflict", path: destination };
|
|
30739
30869
|
} else if (artifactClass === "managed-symlink") {
|
|
30740
|
-
|
|
30870
|
+
fs43.unlinkSync(destination);
|
|
30741
30871
|
}
|
|
30742
|
-
ensureDir(
|
|
30872
|
+
ensureDir(path43.dirname(destination));
|
|
30743
30873
|
createRelativeSymlink(source, destination, "dir");
|
|
30744
30874
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
30745
30875
|
return { component, status: "success", path: destination };
|
|
@@ -30748,13 +30878,13 @@ function syncMcp6(config, sourceRoot, paths, mappings, options, lossReport, logg
|
|
|
30748
30878
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30749
30879
|
const sourceLabel = mcpSourceLabel(config);
|
|
30750
30880
|
const destination = resolveTargetPath(paths.config_doc);
|
|
30751
|
-
if (!
|
|
30881
|
+
if (!fs43.existsSync(source)) {
|
|
30752
30882
|
if (!options.dryRun) {
|
|
30753
30883
|
syncConfigDoc(paths, {}, lossReport, {}, mappings);
|
|
30754
30884
|
}
|
|
30755
30885
|
return skippedMissingSource6("mcp", source);
|
|
30756
30886
|
}
|
|
30757
|
-
const sourceMcpJson = JSON.parse(
|
|
30887
|
+
const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
|
|
30758
30888
|
const mcpJson = compileMcp(
|
|
30759
30889
|
sourceMcpJson,
|
|
30760
30890
|
"opencode",
|
|
@@ -30820,9 +30950,9 @@ function syncProviderBlock(mappings) {
|
|
|
30820
30950
|
function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
|
|
30821
30951
|
const destination = resolveTargetPath(paths.config_doc);
|
|
30822
30952
|
let existing = {};
|
|
30823
|
-
if (
|
|
30953
|
+
if (fs43.existsSync(destination)) {
|
|
30824
30954
|
try {
|
|
30825
|
-
existing = JSON.parse(
|
|
30955
|
+
existing = JSON.parse(fs43.readFileSync(destination, "utf8"));
|
|
30826
30956
|
} catch {
|
|
30827
30957
|
existing = {};
|
|
30828
30958
|
}
|
|
@@ -30847,8 +30977,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
|
|
|
30847
30977
|
};
|
|
30848
30978
|
}
|
|
30849
30979
|
}
|
|
30850
|
-
ensureDir(
|
|
30851
|
-
|
|
30980
|
+
ensureDir(path43.dirname(destination));
|
|
30981
|
+
fs43.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
30852
30982
|
`);
|
|
30853
30983
|
}
|
|
30854
30984
|
function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
|
|
@@ -30859,14 +30989,14 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
|
|
|
30859
30989
|
if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
30860
30990
|
return { component, status: "conflict", path: destination };
|
|
30861
30991
|
}
|
|
30862
|
-
ensureDir(
|
|
30992
|
+
ensureDir(path43.dirname(destination));
|
|
30863
30993
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30864
30994
|
if (clearedLink !== null) {
|
|
30865
30995
|
logger.verbose(
|
|
30866
30996
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30867
30997
|
);
|
|
30868
30998
|
}
|
|
30869
|
-
|
|
30999
|
+
fs43.writeFileSync(destination, content);
|
|
30870
31000
|
return { component, status: "success", path: destination };
|
|
30871
31001
|
}
|
|
30872
31002
|
function handleConflict6(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30884,18 +31014,27 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
|
|
|
30884
31014
|
if (manifest && scopePath) {
|
|
30885
31015
|
backupFile(destination, manifest, scopePath);
|
|
30886
31016
|
writeManifest(scopePath, manifest);
|
|
30887
|
-
|
|
31017
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30888
31018
|
} else {
|
|
30889
|
-
|
|
31019
|
+
const parked = parkConflictingPath(
|
|
31020
|
+
destination,
|
|
31021
|
+
resolveScopePath(
|
|
31022
|
+
options.scope ?? "global",
|
|
31023
|
+
options.scope === "project" ? options.projectRoot : void 0
|
|
31024
|
+
)
|
|
31025
|
+
);
|
|
31026
|
+
logger.warn(
|
|
31027
|
+
`${destination}: moved to ${parked} (unrecorded: this run has no manifest to note it in, so uninstall will not restore it)`
|
|
31028
|
+
);
|
|
30890
31029
|
}
|
|
30891
31030
|
return true;
|
|
30892
31031
|
}
|
|
30893
|
-
|
|
31032
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30894
31033
|
return true;
|
|
30895
31034
|
}
|
|
30896
31035
|
function isCompiledCurrent5(destination, expectedContent, expectedHash) {
|
|
30897
31036
|
try {
|
|
30898
|
-
const current =
|
|
31037
|
+
const current = fs43.readFileSync(destination, "utf8");
|
|
30899
31038
|
const marker = extractProvenanceMarker(current);
|
|
30900
31039
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "opencode" && current === expectedContent : current === expectedContent;
|
|
30901
31040
|
} catch {
|
|
@@ -30914,7 +31053,7 @@ function shouldSkipComponent6(options, component) {
|
|
|
30914
31053
|
}
|
|
30915
31054
|
function isSymlinkTo7(linkPath, source) {
|
|
30916
31055
|
try {
|
|
30917
|
-
return
|
|
31056
|
+
return fs43.realpathSync(linkPath) === fs43.realpathSync(source);
|
|
30918
31057
|
} catch {
|
|
30919
31058
|
return false;
|
|
30920
31059
|
}
|
|
@@ -30923,7 +31062,7 @@ function hashString5(value) {
|
|
|
30923
31062
|
return `sha256:${crypto10.createHash("sha256").update(value).digest("hex")}`;
|
|
30924
31063
|
}
|
|
30925
31064
|
function parseCommandFile(commandFile) {
|
|
30926
|
-
const content =
|
|
31065
|
+
const content = fs43.readFileSync(commandFile, "utf8");
|
|
30927
31066
|
if (!content.startsWith("---\n")) {
|
|
30928
31067
|
return { data: {}, body: content };
|
|
30929
31068
|
}
|
|
@@ -30943,7 +31082,7 @@ function parseCommandFile(commandFile) {
|
|
|
30943
31082
|
// src/commands/install.ts
|
|
30944
31083
|
function isBackupablePath(targetPath) {
|
|
30945
31084
|
try {
|
|
30946
|
-
const lstat =
|
|
31085
|
+
const lstat = fs44.lstatSync(targetPath);
|
|
30947
31086
|
return lstat.isSymbolicLink() || lstat.isFile() || lstat.isDirectory();
|
|
30948
31087
|
} catch {
|
|
30949
31088
|
return false;
|
|
@@ -30980,7 +31119,7 @@ async function runInstallCommand(options, logger) {
|
|
|
30980
31119
|
);
|
|
30981
31120
|
}
|
|
30982
31121
|
const kitName = resolvedKitName ?? config.kit;
|
|
30983
|
-
const kitPath = kitPathOverride ?? (options.kitPath ?
|
|
31122
|
+
const kitPath = kitPathOverride ?? (options.kitPath ? path44.resolve(options.kitPath) : config.kitPath);
|
|
30984
31123
|
if (!kitName && !kitPath) {
|
|
30985
31124
|
logger.error(
|
|
30986
31125
|
"No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
|
|
@@ -31085,8 +31224,8 @@ async function runInstallCommand(options, logger) {
|
|
|
31085
31224
|
config: options.config,
|
|
31086
31225
|
scope
|
|
31087
31226
|
});
|
|
31088
|
-
const skillsSource =
|
|
31089
|
-
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") &&
|
|
31227
|
+
const skillsSource = path44.resolve(kitInfo.path, config.source.skills);
|
|
31228
|
+
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path44.basename(f.path) === "skills";
|
|
31090
31229
|
const foreignSkillsSlots = new Set(
|
|
31091
31230
|
assessResult.findings.filter(
|
|
31092
31231
|
(f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
|
|
@@ -31124,7 +31263,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31124
31263
|
let instructionsLabel;
|
|
31125
31264
|
try {
|
|
31126
31265
|
const resolved = resolveInstructionsSource(kitInfo.path, config);
|
|
31127
|
-
instructionsLabel = resolved ?
|
|
31266
|
+
instructionsLabel = resolved ? path44.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
|
|
31128
31267
|
} catch (err) {
|
|
31129
31268
|
logger.error(
|
|
31130
31269
|
`[dry-run] ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -31152,7 +31291,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31152
31291
|
}
|
|
31153
31292
|
}
|
|
31154
31293
|
logger.info(
|
|
31155
|
-
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${
|
|
31294
|
+
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path44.join(scopePath, "manifest.json")}`
|
|
31156
31295
|
);
|
|
31157
31296
|
return;
|
|
31158
31297
|
}
|
|
@@ -31211,7 +31350,7 @@ ACCEPTED CONFLICTS (posture: ${posture}; ${replaceable.length} target(s)):`
|
|
|
31211
31350
|
logger.info(` - ${finding.path}`);
|
|
31212
31351
|
logger.info(` source: ${sources}`);
|
|
31213
31352
|
logger.info(
|
|
31214
|
-
` action: backup-and-replace${
|
|
31353
|
+
` action: backup-and-replace${fs44.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
|
|
31215
31354
|
);
|
|
31216
31355
|
logger.info(` backup: ${backupLocation}`);
|
|
31217
31356
|
continue;
|
|
@@ -31319,6 +31458,11 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
31319
31458
|
installLossReport
|
|
31320
31459
|
);
|
|
31321
31460
|
}
|
|
31461
|
+
reportContestedInstructions(
|
|
31462
|
+
instructionsByActiveTarget(tools, scope, projectRoot, mappings),
|
|
31463
|
+
(kitInfo.components.rules?.declared.length ?? 0) > 0,
|
|
31464
|
+
logger
|
|
31465
|
+
);
|
|
31322
31466
|
for (const [relativePath, sourcePath] of collectAllFiles(kitInfo, config)) {
|
|
31323
31467
|
addFileToManifest(manifest, {
|
|
31324
31468
|
relativePath,
|
|
@@ -31330,20 +31474,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
31330
31474
|
writeManifest(scopePath, manifest);
|
|
31331
31475
|
logger.info(`
|
|
31332
31476
|
Installation complete: ${installedCount} files installed.`);
|
|
31333
|
-
logger.info(`Manifest written to ${
|
|
31477
|
+
logger.info(`Manifest written to ${path44.join(scopePath, "manifest.json")}`);
|
|
31334
31478
|
logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
|
|
31335
31479
|
logger.info(`Scope: ${scope}`);
|
|
31336
31480
|
logger.info(`Tools: ${tools.join(", ")}`);
|
|
31337
31481
|
reportHookRejections(
|
|
31338
31482
|
installLossReport,
|
|
31339
31483
|
tools,
|
|
31340
|
-
|
|
31484
|
+
path44.resolve(kitInfo.path, "hooks"),
|
|
31341
31485
|
kitInfo.components.hooks.declared
|
|
31342
31486
|
);
|
|
31343
31487
|
const hooksConflict = reportHooksSourceConflict(
|
|
31344
31488
|
installLossReport,
|
|
31345
31489
|
tools,
|
|
31346
|
-
|
|
31490
|
+
path44.resolve(kitInfo.path, "hooks"),
|
|
31347
31491
|
kitInfo.components.hooks.declared
|
|
31348
31492
|
);
|
|
31349
31493
|
if (hooksConflict) {
|
|
@@ -31702,7 +31846,7 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
31702
31846
|
return 0;
|
|
31703
31847
|
}
|
|
31704
31848
|
try {
|
|
31705
|
-
const stat =
|
|
31849
|
+
const stat = fs44.lstatSync(destination);
|
|
31706
31850
|
if (stat.isFile() && !stat.isSymbolicLink()) {
|
|
31707
31851
|
logger.warn(
|
|
31708
31852
|
`${destination}: a regular file occupies the skills slot \u2014 skipping skills. Move or remove it, then re-run install.`
|
|
@@ -31730,17 +31874,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
31730
31874
|
manifest,
|
|
31731
31875
|
scopePath
|
|
31732
31876
|
);
|
|
31733
|
-
const skillsSource =
|
|
31877
|
+
const skillsSource = path44.resolve(kitInfo.path, config.source.skills);
|
|
31734
31878
|
let count = 0;
|
|
31735
31879
|
for (const outcome of outcomes) {
|
|
31736
31880
|
if (outcome.status !== "success" && outcome.status !== "skipped-current") {
|
|
31737
31881
|
continue;
|
|
31738
31882
|
}
|
|
31739
|
-
const skillName =
|
|
31883
|
+
const skillName = path44.basename(outcome.path);
|
|
31740
31884
|
addArtifactToManifest(manifest, {
|
|
31741
31885
|
relativePath: `claude-code/skills/${skillName}`,
|
|
31742
31886
|
path: outcome.path,
|
|
31743
|
-
hash: describeArtifactState(outcome.path) ?? `dir:${
|
|
31887
|
+
hash: describeArtifactState(outcome.path) ?? `dir:${path44.join(skillsSource, skillName)}`,
|
|
31744
31888
|
origin: "tangyr-managed"
|
|
31745
31889
|
});
|
|
31746
31890
|
count++;
|
|
@@ -31754,10 +31898,10 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
31754
31898
|
logger.verbose(` skipped (operator choice): ${placement.destination}`);
|
|
31755
31899
|
continue;
|
|
31756
31900
|
}
|
|
31757
|
-
const destDir =
|
|
31758
|
-
|
|
31901
|
+
const destDir = path44.dirname(placement.destination);
|
|
31902
|
+
fs44.mkdirSync(destDir, { recursive: true });
|
|
31759
31903
|
if (placement.type === "symlink") {
|
|
31760
|
-
if (
|
|
31904
|
+
if (fs44.existsSync(placement.destination) || isSymlink2(placement.destination)) {
|
|
31761
31905
|
removeManagedPath(placement.destination);
|
|
31762
31906
|
}
|
|
31763
31907
|
createRelativeSymlink(
|
|
@@ -31774,7 +31918,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
31774
31918
|
` symlink: ${placement.source} \u2192 ${placement.destination}`
|
|
31775
31919
|
);
|
|
31776
31920
|
} else {
|
|
31777
|
-
|
|
31921
|
+
fs44.copyFileSync(placement.source, placement.destination);
|
|
31778
31922
|
logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
|
|
31779
31923
|
}
|
|
31780
31924
|
addArtifactToManifest(manifest, {
|
|
@@ -32056,11 +32200,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32056
32200
|
if (outcome.path === mcpFile2) {
|
|
32057
32201
|
return "cline/mcp.json";
|
|
32058
32202
|
}
|
|
32059
|
-
if (outcome.path.startsWith(`${workflowsRoot}${
|
|
32060
|
-
return `cline/workflows/${
|
|
32203
|
+
if (outcome.path.startsWith(`${workflowsRoot}${path44.sep}`)) {
|
|
32204
|
+
return `cline/workflows/${path44.basename(outcome.path)}`;
|
|
32061
32205
|
}
|
|
32062
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32063
|
-
return `cline/rules/${
|
|
32206
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
|
|
32207
|
+
return `cline/rules/${path44.basename(outcome.path)}`;
|
|
32064
32208
|
}
|
|
32065
32209
|
return null;
|
|
32066
32210
|
}
|
|
@@ -32096,14 +32240,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32096
32240
|
if (outcome.path === permissionsFile) {
|
|
32097
32241
|
return "cursor/permissions.json";
|
|
32098
32242
|
}
|
|
32099
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32100
|
-
return `cursor/agents/${
|
|
32243
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
|
|
32244
|
+
return `cursor/agents/${path44.basename(outcome.path)}`;
|
|
32101
32245
|
}
|
|
32102
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32103
|
-
return `cursor/rules/${
|
|
32246
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
|
|
32247
|
+
return `cursor/rules/${path44.basename(outcome.path)}`;
|
|
32104
32248
|
}
|
|
32105
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
32106
|
-
const rel =
|
|
32249
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
|
|
32250
|
+
const rel = path44.relative(skillsRoot2, outcome.path);
|
|
32107
32251
|
return `cursor/skills/${rel}`;
|
|
32108
32252
|
}
|
|
32109
32253
|
return null;
|
|
@@ -32129,14 +32273,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32129
32273
|
if (outcome.path === skillsSharedRoot) {
|
|
32130
32274
|
return "opencode/skills_shared";
|
|
32131
32275
|
}
|
|
32132
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32133
|
-
return `opencode/agents/${
|
|
32276
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
|
|
32277
|
+
return `opencode/agents/${path44.basename(outcome.path)}`;
|
|
32134
32278
|
}
|
|
32135
|
-
if (outcome.path.startsWith(`${commandsRoot}${
|
|
32136
|
-
return `opencode/commands/${
|
|
32279
|
+
if (outcome.path.startsWith(`${commandsRoot}${path44.sep}`)) {
|
|
32280
|
+
return `opencode/commands/${path44.basename(outcome.path)}`;
|
|
32137
32281
|
}
|
|
32138
32282
|
if (outcome.path === configDocFile) {
|
|
32139
|
-
return `opencode/${
|
|
32283
|
+
return `opencode/${path44.basename(outcome.path)}`;
|
|
32140
32284
|
}
|
|
32141
32285
|
return null;
|
|
32142
32286
|
}
|
|
@@ -32153,26 +32297,26 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32153
32297
|
const hooksRoot = resolveTargetPath(copilot.hooks);
|
|
32154
32298
|
const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
|
|
32155
32299
|
const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
|
|
32156
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
32157
|
-
return `copilot/skills/${
|
|
32300
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
|
|
32301
|
+
return `copilot/skills/${path44.relative(skillsRoot2, outcome.path)}`;
|
|
32158
32302
|
}
|
|
32159
32303
|
if (outcome.path === skillsRoot2) {
|
|
32160
32304
|
return "copilot/skills";
|
|
32161
32305
|
}
|
|
32162
32306
|
if (instructionsMirror !== null && outcome.path === instructionsMirror) {
|
|
32163
|
-
return `copilot/${
|
|
32307
|
+
return `copilot/${path44.basename(outcome.path)}`;
|
|
32164
32308
|
}
|
|
32165
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32166
|
-
return `copilot/agents/${
|
|
32309
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
|
|
32310
|
+
return `copilot/agents/${path44.basename(outcome.path)}`;
|
|
32167
32311
|
}
|
|
32168
|
-
if (outcome.path.startsWith(`${promptsRoot}${
|
|
32169
|
-
return `copilot/prompts/${
|
|
32312
|
+
if (outcome.path.startsWith(`${promptsRoot}${path44.sep}`)) {
|
|
32313
|
+
return `copilot/prompts/${path44.basename(outcome.path)}`;
|
|
32170
32314
|
}
|
|
32171
|
-
if (outcome.path.startsWith(`${hooksRoot}${
|
|
32172
|
-
return `copilot/hooks/${
|
|
32315
|
+
if (outcome.path.startsWith(`${hooksRoot}${path44.sep}`)) {
|
|
32316
|
+
return `copilot/hooks/${path44.basename(outcome.path)}`;
|
|
32173
32317
|
}
|
|
32174
32318
|
if (outcome.path === mcpFile2) {
|
|
32175
|
-
return `copilot/${
|
|
32319
|
+
return `copilot/${path44.basename(outcome.path)}`;
|
|
32176
32320
|
}
|
|
32177
32321
|
return null;
|
|
32178
32322
|
}
|
|
@@ -32189,17 +32333,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32189
32333
|
if (outcome.path === skillsRoot) {
|
|
32190
32334
|
return "codex/skills";
|
|
32191
32335
|
}
|
|
32192
|
-
if (outcome.path.startsWith(`${agentsRoot}${
|
|
32193
|
-
return `codex/agents/${
|
|
32336
|
+
if (outcome.path.startsWith(`${agentsRoot}${path44.sep}`)) {
|
|
32337
|
+
return `codex/agents/${path44.basename(outcome.path)}`;
|
|
32194
32338
|
}
|
|
32195
|
-
if (outcome.path.startsWith(`${rulesRoot}${
|
|
32196
|
-
return `codex/rules/${
|
|
32339
|
+
if (outcome.path.startsWith(`${rulesRoot}${path44.sep}`)) {
|
|
32340
|
+
return `codex/rules/${path44.basename(outcome.path)}`;
|
|
32197
32341
|
}
|
|
32198
32342
|
if (outcome.path === hooksFile) {
|
|
32199
|
-
return `codex/${
|
|
32343
|
+
return `codex/${path44.basename(outcome.path)}`;
|
|
32200
32344
|
}
|
|
32201
32345
|
if (outcome.path === mcpFile) {
|
|
32202
|
-
return `codex/${
|
|
32346
|
+
return `codex/${path44.basename(outcome.path)}`;
|
|
32203
32347
|
}
|
|
32204
32348
|
return null;
|
|
32205
32349
|
}
|
|
@@ -32268,8 +32412,8 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
|
|
|
32268
32412
|
rules: resolvedPaths.rules
|
|
32269
32413
|
};
|
|
32270
32414
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32271
|
-
const componentDir =
|
|
32272
|
-
if (
|
|
32415
|
+
const componentDir = path44.join(kitInfo.path, component);
|
|
32416
|
+
if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
|
|
32273
32417
|
placements.push({
|
|
32274
32418
|
source: componentDir,
|
|
32275
32419
|
destination: targetPath,
|
|
@@ -32299,8 +32443,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
|
|
|
32299
32443
|
rules: profile.rules
|
|
32300
32444
|
};
|
|
32301
32445
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32302
|
-
const componentDir =
|
|
32303
|
-
if (
|
|
32446
|
+
const componentDir = path44.join(kitInfo.path, component);
|
|
32447
|
+
if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
|
|
32304
32448
|
placements.push({
|
|
32305
32449
|
source: componentDir,
|
|
32306
32450
|
destination: targetPath,
|
|
@@ -32316,7 +32460,7 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32316
32460
|
const files = /* @__PURE__ */ new Map();
|
|
32317
32461
|
const entrypoint = resolveInstructionsSource(kitInfo.path, config);
|
|
32318
32462
|
if (entrypoint) {
|
|
32319
|
-
files.set(
|
|
32463
|
+
files.set(path44.basename(entrypoint.file), entrypoint.file);
|
|
32320
32464
|
}
|
|
32321
32465
|
for (const [component, reconciliation] of Object.entries(
|
|
32322
32466
|
kitInfo.components
|
|
@@ -32325,22 +32469,22 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32325
32469
|
const missingSet = new Set(reconciliation.missing);
|
|
32326
32470
|
for (const entry of reconciliation.declared) {
|
|
32327
32471
|
if (missingSet.has(entry)) continue;
|
|
32328
|
-
const relPath = isSkills ?
|
|
32329
|
-
files.set(relPath,
|
|
32472
|
+
const relPath = isSkills ? path44.join(component, entry) : path44.join(component, `${entry}.md`);
|
|
32473
|
+
files.set(relPath, path44.join(kitInfo.path, relPath));
|
|
32330
32474
|
}
|
|
32331
32475
|
}
|
|
32332
32476
|
return files;
|
|
32333
32477
|
}
|
|
32334
32478
|
function readLinkTarget(p) {
|
|
32335
32479
|
try {
|
|
32336
|
-
return
|
|
32480
|
+
return fs44.readlinkSync(p);
|
|
32337
32481
|
} catch {
|
|
32338
32482
|
return null;
|
|
32339
32483
|
}
|
|
32340
32484
|
}
|
|
32341
32485
|
function isSymlink2(p) {
|
|
32342
32486
|
try {
|
|
32343
|
-
return
|
|
32487
|
+
return fs44.lstatSync(p).isSymbolicLink();
|
|
32344
32488
|
} catch {
|
|
32345
32489
|
return false;
|
|
32346
32490
|
}
|
|
@@ -32385,14 +32529,14 @@ async function runKitUpdateCommand(options, logger) {
|
|
|
32385
32529
|
}
|
|
32386
32530
|
|
|
32387
32531
|
// src/commands/list.ts
|
|
32388
|
-
import
|
|
32532
|
+
import path45 from "path";
|
|
32389
32533
|
function runListCommand(options, logger) {
|
|
32390
32534
|
let searchPaths = [];
|
|
32391
|
-
let directKitPath = options.kitPath ?
|
|
32535
|
+
let directKitPath = options.kitPath ? path45.resolve(options.kitPath) : void 0;
|
|
32392
32536
|
try {
|
|
32393
32537
|
const { config, configDir } = resolveConfig(options.config);
|
|
32394
32538
|
searchPaths = config.kitSearchPaths ?? [
|
|
32395
|
-
|
|
32539
|
+
path45.join(configDir, "operating-kits")
|
|
32396
32540
|
];
|
|
32397
32541
|
directKitPath = directKitPath ?? config.kitPath;
|
|
32398
32542
|
} catch (err) {
|
|
@@ -32467,7 +32611,7 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32467
32611
|
return kits;
|
|
32468
32612
|
}
|
|
32469
32613
|
const directKit = loadKit(directKitPath);
|
|
32470
|
-
if (kits.some((kit) =>
|
|
32614
|
+
if (kits.some((kit) => path45.resolve(kit.path) === directKit.path)) {
|
|
32471
32615
|
return kits;
|
|
32472
32616
|
}
|
|
32473
32617
|
return [...kits, directKit];
|
|
@@ -32475,8 +32619,8 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32475
32619
|
|
|
32476
32620
|
// src/commands/probe.ts
|
|
32477
32621
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
32478
|
-
import
|
|
32479
|
-
import
|
|
32622
|
+
import fs45 from "fs";
|
|
32623
|
+
import path46 from "path";
|
|
32480
32624
|
function runProbeCommand(options, logger) {
|
|
32481
32625
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32482
32626
|
options,
|
|
@@ -32504,7 +32648,7 @@ function runProbeCommand(options, logger) {
|
|
|
32504
32648
|
toProbeRow(
|
|
32505
32649
|
target,
|
|
32506
32650
|
key,
|
|
32507
|
-
scope === "project" ?
|
|
32651
|
+
scope === "project" ? path46.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
|
|
32508
32652
|
)
|
|
32509
32653
|
);
|
|
32510
32654
|
}
|
|
@@ -32526,7 +32670,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32526
32670
|
const resolved = resolveTargetPath(rawPath);
|
|
32527
32671
|
let accessible = false;
|
|
32528
32672
|
try {
|
|
32529
|
-
|
|
32673
|
+
fs45.accessSync(resolved);
|
|
32530
32674
|
accessible = true;
|
|
32531
32675
|
} catch {
|
|
32532
32676
|
accessible = false;
|
|
@@ -32535,7 +32679,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32535
32679
|
target,
|
|
32536
32680
|
key,
|
|
32537
32681
|
path: resolved,
|
|
32538
|
-
exists:
|
|
32682
|
+
exists: fs45.existsSync(resolved),
|
|
32539
32683
|
accessible
|
|
32540
32684
|
};
|
|
32541
32685
|
}
|
|
@@ -32553,7 +32697,7 @@ function codexRuntimeProbeRows() {
|
|
|
32553
32697
|
["binary_snap", "/snap/bin/codex"],
|
|
32554
32698
|
["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
|
|
32555
32699
|
]) {
|
|
32556
|
-
if (
|
|
32700
|
+
if (fs45.existsSync(candidatePath)) {
|
|
32557
32701
|
rows.push(toProbeRow("codex", key, candidatePath));
|
|
32558
32702
|
}
|
|
32559
32703
|
}
|
|
@@ -32569,8 +32713,8 @@ function commandProbeRows(target, key, command, args) {
|
|
|
32569
32713
|
|
|
32570
32714
|
// src/commands/status.ts
|
|
32571
32715
|
import crypto11 from "crypto";
|
|
32572
|
-
import
|
|
32573
|
-
import
|
|
32716
|
+
import fs46 from "fs";
|
|
32717
|
+
import path47 from "path";
|
|
32574
32718
|
function runStatusCommand(options, logger) {
|
|
32575
32719
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32576
32720
|
options,
|
|
@@ -32676,11 +32820,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
|
|
|
32676
32820
|
}
|
|
32677
32821
|
}
|
|
32678
32822
|
function sourceMarkdownFiles(sourceRoot, componentPath) {
|
|
32679
|
-
const root =
|
|
32680
|
-
if (!
|
|
32823
|
+
const root = path47.join(sourceRoot, componentPath);
|
|
32824
|
+
if (!fs46.existsSync(root)) {
|
|
32681
32825
|
return [];
|
|
32682
32826
|
}
|
|
32683
|
-
return ts(
|
|
32827
|
+
return ts(path47.join(root, "*.md")).sort();
|
|
32684
32828
|
}
|
|
32685
32829
|
function notRepresentableRow(component, detail) {
|
|
32686
32830
|
return {
|
|
@@ -32691,11 +32835,11 @@ function notRepresentableRow(component, detail) {
|
|
|
32691
32835
|
};
|
|
32692
32836
|
}
|
|
32693
32837
|
function readTargetJson(filePath) {
|
|
32694
|
-
if (!
|
|
32838
|
+
if (!fs46.existsSync(filePath)) {
|
|
32695
32839
|
return { kind: "missing" };
|
|
32696
32840
|
}
|
|
32697
32841
|
try {
|
|
32698
|
-
const parsed = JSON.parse(
|
|
32842
|
+
const parsed = JSON.parse(fs46.readFileSync(filePath, "utf8"));
|
|
32699
32843
|
return { kind: "object", value: isRecord(parsed) ? parsed : {} };
|
|
32700
32844
|
} catch (err) {
|
|
32701
32845
|
return {
|
|
@@ -32784,7 +32928,7 @@ function classifyInstructions(filePath, target, expectedHash, config, sourceRoot
|
|
|
32784
32928
|
}
|
|
32785
32929
|
function compiledMcpDocument(config, sourceRoot, target) {
|
|
32786
32930
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
32787
|
-
if (!
|
|
32931
|
+
if (!fs46.existsSync(source)) {
|
|
32788
32932
|
return {};
|
|
32789
32933
|
}
|
|
32790
32934
|
const compiled = compileMcp(
|
|
@@ -32797,7 +32941,7 @@ function compiledMcpDocument(config, sourceRoot, target) {
|
|
|
32797
32941
|
return isRecord(parsed) ? parsed : {};
|
|
32798
32942
|
}
|
|
32799
32943
|
function classifyMcpDocument(config, sourceRoot, target, filePath) {
|
|
32800
|
-
if (!
|
|
32944
|
+
if (!fs46.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
|
|
32801
32945
|
return notConfiguredRow("mcp", filePath);
|
|
32802
32946
|
}
|
|
32803
32947
|
return classifyJsonDocument(
|
|
@@ -32827,12 +32971,12 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
|
|
|
32827
32971
|
const rows = [];
|
|
32828
32972
|
const instructionsSource = instructionsSourcePath(sourceRoot, config);
|
|
32829
32973
|
const rules = compileRules(
|
|
32830
|
-
|
|
32974
|
+
path47.join(sourceRoot, config.source.rules),
|
|
32831
32975
|
"opencode",
|
|
32832
32976
|
mappings,
|
|
32833
32977
|
createLossReport()
|
|
32834
32978
|
);
|
|
32835
|
-
const baseInstructions =
|
|
32979
|
+
const baseInstructions = fs46.existsSync(instructionsSource) ? fs46.readFileSync(instructionsSource, "utf8").trim() : "";
|
|
32836
32980
|
const composedInstructions = rules.agentsAppendix ? `${baseInstructions}
|
|
32837
32981
|
|
|
32838
32982
|
--- tangyr managed rules ---
|
|
@@ -32854,10 +32998,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
32854
32998
|
)) {
|
|
32855
32999
|
rows.push(
|
|
32856
33000
|
classifyCompiledFile(
|
|
32857
|
-
`agents/${
|
|
32858
|
-
|
|
33001
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33002
|
+
path47.join(
|
|
32859
33003
|
resolveTargetPath(paths.agents),
|
|
32860
|
-
`${
|
|
33004
|
+
`${path47.basename(agentFile, ".md")}.md`
|
|
32861
33005
|
),
|
|
32862
33006
|
"opencode",
|
|
32863
33007
|
computeSourceHash(agentFile),
|
|
@@ -32872,10 +33016,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
32872
33016
|
)) {
|
|
32873
33017
|
rows.push(
|
|
32874
33018
|
classifyCompiledFile(
|
|
32875
|
-
`commands/${
|
|
32876
|
-
|
|
33019
|
+
`commands/${path47.basename(commandFile, ".md")}`,
|
|
33020
|
+
path47.join(
|
|
32877
33021
|
resolveTargetPath(paths.commands),
|
|
32878
|
-
`${
|
|
33022
|
+
`${path47.basename(commandFile, ".md")}.md`
|
|
32879
33023
|
),
|
|
32880
33024
|
"opencode",
|
|
32881
33025
|
computeSourceHash(commandFile),
|
|
@@ -32957,10 +33101,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
32957
33101
|
)) {
|
|
32958
33102
|
rows.push(
|
|
32959
33103
|
classifyCompiledFile(
|
|
32960
|
-
`agents/${
|
|
32961
|
-
|
|
33104
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33105
|
+
path47.join(
|
|
32962
33106
|
resolveTargetPath(paths.agents),
|
|
32963
|
-
`${
|
|
33107
|
+
`${path47.basename(agentFile, ".md")}.md`
|
|
32964
33108
|
),
|
|
32965
33109
|
"cursor",
|
|
32966
33110
|
computeSourceHash(agentFile),
|
|
@@ -32977,7 +33121,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
32977
33121
|
rows.push(
|
|
32978
33122
|
classifyCompiledFile(
|
|
32979
33123
|
`rules/${ruleFile.name}`,
|
|
32980
|
-
|
|
33124
|
+
path47.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
32981
33125
|
"cursor",
|
|
32982
33126
|
void 0,
|
|
32983
33127
|
config,
|
|
@@ -32991,11 +33135,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
32991
33135
|
sourceRoot,
|
|
32992
33136
|
config.source.commands
|
|
32993
33137
|
)) {
|
|
32994
|
-
const baseName =
|
|
33138
|
+
const baseName = path47.basename(commandFile, ".md");
|
|
32995
33139
|
rows.push(
|
|
32996
33140
|
classifyCompiledFile(
|
|
32997
33141
|
`commands/${baseName}`,
|
|
32998
|
-
|
|
33142
|
+
path47.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
|
|
32999
33143
|
"cursor",
|
|
33000
33144
|
computeSourceHash(commandFile),
|
|
33001
33145
|
config,
|
|
@@ -33078,7 +33222,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33078
33222
|
rows.push(
|
|
33079
33223
|
classifyCompiledFile(
|
|
33080
33224
|
`rules/${ruleFile.name}`,
|
|
33081
|
-
|
|
33225
|
+
path47.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
33082
33226
|
"cline",
|
|
33083
33227
|
void 0,
|
|
33084
33228
|
config,
|
|
@@ -33094,10 +33238,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33094
33238
|
)) {
|
|
33095
33239
|
rows.push(
|
|
33096
33240
|
classifyCompiledFile(
|
|
33097
|
-
`commands/${
|
|
33098
|
-
|
|
33241
|
+
`commands/${path47.basename(commandFile, ".md")}`,
|
|
33242
|
+
path47.join(
|
|
33099
33243
|
resolveTargetPath(paths.workflows),
|
|
33100
|
-
|
|
33244
|
+
path47.basename(commandFile)
|
|
33101
33245
|
),
|
|
33102
33246
|
"cline",
|
|
33103
33247
|
computeSourceHash(commandFile),
|
|
@@ -33138,14 +33282,14 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33138
33282
|
return rows;
|
|
33139
33283
|
}
|
|
33140
33284
|
function compileRulesFiles(config, sourceRoot, target, mappings) {
|
|
33141
|
-
const rulesSource =
|
|
33142
|
-
if (!
|
|
33285
|
+
const rulesSource = path47.join(sourceRoot, config.source.rules);
|
|
33286
|
+
if (!fs46.existsSync(rulesSource)) {
|
|
33143
33287
|
return [];
|
|
33144
33288
|
}
|
|
33145
33289
|
return compileRules(rulesSource, target, mappings, createLossReport()).dotRulesFiles;
|
|
33146
33290
|
}
|
|
33147
33291
|
function classifyDirectoryPresence(component, dirPath) {
|
|
33148
|
-
const present =
|
|
33292
|
+
const present = fs46.existsSync(dirPath) && fs46.statSync(dirPath).isDirectory();
|
|
33149
33293
|
return {
|
|
33150
33294
|
component,
|
|
33151
33295
|
className: present ? "current" : "missing",
|
|
@@ -33164,7 +33308,7 @@ function slotsForScope2(scopeMap, scope, projectRoot) {
|
|
|
33164
33308
|
const root = projectRoot ?? process.cwd();
|
|
33165
33309
|
const resolved = {};
|
|
33166
33310
|
for (const [slot, value] of Object.entries(projectSlots)) {
|
|
33167
|
-
resolved[slot] = typeof value === "string" ?
|
|
33311
|
+
resolved[slot] = typeof value === "string" ? path47.resolve(root, value) : value;
|
|
33168
33312
|
}
|
|
33169
33313
|
return resolved;
|
|
33170
33314
|
}
|
|
@@ -33184,21 +33328,21 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33184
33328
|
rules: paths.rules
|
|
33185
33329
|
};
|
|
33186
33330
|
const rules = compileRules(
|
|
33187
|
-
|
|
33331
|
+
path47.join(sourceRoot, config.source.rules),
|
|
33188
33332
|
"codex",
|
|
33189
33333
|
mappings,
|
|
33190
33334
|
createLossReport()
|
|
33191
33335
|
);
|
|
33192
|
-
const instructionsSource =
|
|
33336
|
+
const instructionsSource = fs46.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
|
|
33193
33337
|
const composedInstructions = `${instructionsSource}
|
|
33194
33338
|
|
|
33195
33339
|
--- tangyr managed rules ---
|
|
33196
33340
|
${rules.agentsAppendix}`.trim();
|
|
33197
33341
|
const agentFiles = ts(
|
|
33198
|
-
|
|
33342
|
+
path47.join(sourceRoot, config.source.agents, "*.md")
|
|
33199
33343
|
).sort();
|
|
33200
33344
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33201
|
-
const mcpSource =
|
|
33345
|
+
const mcpSource = path47.join(sourceRoot, config.source.mcp);
|
|
33202
33346
|
const ruleRows = rules.dotRulesFiles.length === 0 ? [
|
|
33203
33347
|
{
|
|
33204
33348
|
component: "rules",
|
|
@@ -33209,7 +33353,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33209
33353
|
] : rules.dotRulesFiles.map(
|
|
33210
33354
|
(ruleFile) => classifyCompiledFile(
|
|
33211
33355
|
`rules/${ruleFile.name}`,
|
|
33212
|
-
|
|
33356
|
+
path47.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
|
|
33213
33357
|
"codex",
|
|
33214
33358
|
void 0,
|
|
33215
33359
|
config,
|
|
@@ -33227,10 +33371,10 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33227
33371
|
),
|
|
33228
33372
|
...agentFiles.map(
|
|
33229
33373
|
(agentFile) => classifyCompiledFile(
|
|
33230
|
-
`agents/${
|
|
33231
|
-
|
|
33374
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33375
|
+
path47.join(
|
|
33232
33376
|
resolveTargetPath(codexPaths.agents),
|
|
33233
|
-
`${
|
|
33377
|
+
`${path47.basename(agentFile, ".md")}.toml`
|
|
33234
33378
|
),
|
|
33235
33379
|
"codex",
|
|
33236
33380
|
computeSourceHash(agentFile),
|
|
@@ -33258,7 +33402,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33258
33402
|
"hooks",
|
|
33259
33403
|
resolveTargetPath(codexPaths.hooksSharedFile)
|
|
33260
33404
|
),
|
|
33261
|
-
|
|
33405
|
+
fs46.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33262
33406
|
"mcp",
|
|
33263
33407
|
resolveTargetPath(codexPaths.mcpSharedFile),
|
|
33264
33408
|
"codex",
|
|
@@ -33324,20 +33468,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33324
33468
|
mcpSharedFile: paths.mcp_shared_file
|
|
33325
33469
|
};
|
|
33326
33470
|
const agentFiles = ts(
|
|
33327
|
-
|
|
33471
|
+
path47.join(sourceRoot, config.source.agents, "*.md")
|
|
33328
33472
|
).sort();
|
|
33329
33473
|
const commandFiles = ts(
|
|
33330
|
-
|
|
33474
|
+
path47.join(sourceRoot, config.source.commands, "*.md")
|
|
33331
33475
|
).sort();
|
|
33332
33476
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33333
|
-
const mcpSource =
|
|
33477
|
+
const mcpSource = path47.join(sourceRoot, config.source.mcp);
|
|
33334
33478
|
return [
|
|
33335
33479
|
...agentFiles.map(
|
|
33336
33480
|
(agentFile) => classifyCompiledFile(
|
|
33337
|
-
`agents/${
|
|
33338
|
-
|
|
33481
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33482
|
+
path47.join(
|
|
33339
33483
|
resolveTargetPath(copilotPaths.agents),
|
|
33340
|
-
`${
|
|
33484
|
+
`${path47.basename(agentFile, ".md")}.agent.md`
|
|
33341
33485
|
),
|
|
33342
33486
|
"copilot",
|
|
33343
33487
|
computeSourceHash(agentFile),
|
|
@@ -33354,10 +33498,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33354
33498
|
),
|
|
33355
33499
|
...commandFiles.map(
|
|
33356
33500
|
(commandFile) => classifyCompiledFile(
|
|
33357
|
-
`commands/${
|
|
33358
|
-
|
|
33501
|
+
`commands/${path47.basename(commandFile, ".md")}`,
|
|
33502
|
+
path47.join(
|
|
33359
33503
|
resolveTargetPath(copilotPaths.prompts),
|
|
33360
|
-
`${
|
|
33504
|
+
`${path47.basename(commandFile, ".md")}.prompt.md`
|
|
33361
33505
|
),
|
|
33362
33506
|
"copilot",
|
|
33363
33507
|
computeSourceHash(commandFile),
|
|
@@ -33376,19 +33520,19 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33376
33520
|
sourceRoot
|
|
33377
33521
|
),
|
|
33378
33522
|
hooksPresent ? classifyCompiledHooksByProvenance(
|
|
33379
|
-
|
|
33523
|
+
path47.join(
|
|
33380
33524
|
resolveTargetPath(copilotPaths.hooks),
|
|
33381
33525
|
"tangyr-managed.json"
|
|
33382
33526
|
),
|
|
33383
33527
|
"copilot"
|
|
33384
33528
|
) : notConfiguredRow(
|
|
33385
33529
|
"hooks",
|
|
33386
|
-
|
|
33530
|
+
path47.join(
|
|
33387
33531
|
resolveTargetPath(copilotPaths.hooks),
|
|
33388
33532
|
"tangyr-managed.json"
|
|
33389
33533
|
)
|
|
33390
33534
|
),
|
|
33391
|
-
|
|
33535
|
+
fs46.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33392
33536
|
"mcp",
|
|
33393
33537
|
resolveTargetPath(copilotPaths.mcpSharedFile),
|
|
33394
33538
|
"copilot",
|
|
@@ -33408,7 +33552,7 @@ function notConfiguredRow(component, filePath) {
|
|
|
33408
33552
|
}
|
|
33409
33553
|
function classifyDirectArtifact(artifact, config, sourceRoot) {
|
|
33410
33554
|
const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
|
|
33411
|
-
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ?
|
|
33555
|
+
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path47.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
|
|
33412
33556
|
if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
|
|
33413
33557
|
const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
|
|
33414
33558
|
if (perSkill) {
|
|
@@ -33504,11 +33648,11 @@ function classifyClaudeCodeRows(sourceRoot, config, configDir, scope, projectRoo
|
|
|
33504
33648
|
function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
33505
33649
|
let entries;
|
|
33506
33650
|
try {
|
|
33507
|
-
const stat =
|
|
33651
|
+
const stat = fs46.lstatSync(slotPath);
|
|
33508
33652
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
33509
33653
|
return null;
|
|
33510
33654
|
}
|
|
33511
|
-
entries =
|
|
33655
|
+
entries = fs46.readdirSync(slotPath, { withFileTypes: true });
|
|
33512
33656
|
} catch {
|
|
33513
33657
|
return null;
|
|
33514
33658
|
}
|
|
@@ -33517,7 +33661,7 @@ function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
|
33517
33661
|
return null;
|
|
33518
33662
|
}
|
|
33519
33663
|
const ours = links.filter(
|
|
33520
|
-
(entry) => isOurSymlink(
|
|
33664
|
+
(entry) => isOurSymlink(path47.join(slotPath, entry.name), sourceRoot)
|
|
33521
33665
|
);
|
|
33522
33666
|
if (ours.length === 0) {
|
|
33523
33667
|
return null;
|
|
@@ -33529,9 +33673,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
|
|
|
33529
33673
|
classifyHooks(settingsPath),
|
|
33530
33674
|
classifySettings(
|
|
33531
33675
|
settingsPath,
|
|
33532
|
-
|
|
33676
|
+
path47.resolve(sourceRoot, config.source.settings)
|
|
33533
33677
|
),
|
|
33534
|
-
classifyMcp(claudeJsonPath,
|
|
33678
|
+
classifyMcp(claudeJsonPath, path47.resolve(sourceRoot, config.source.mcp))
|
|
33535
33679
|
];
|
|
33536
33680
|
}
|
|
33537
33681
|
function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
|
|
@@ -33628,14 +33772,14 @@ function classifyMcp(filePath, sourcePath) {
|
|
|
33628
33772
|
}
|
|
33629
33773
|
function isSymlinkCurrent(linkPath, sourcePath) {
|
|
33630
33774
|
try {
|
|
33631
|
-
return
|
|
33775
|
+
return fs46.realpathSync(linkPath) === fs46.realpathSync(sourcePath);
|
|
33632
33776
|
} catch {
|
|
33633
33777
|
return false;
|
|
33634
33778
|
}
|
|
33635
33779
|
}
|
|
33636
33780
|
function isCompiledCurrent6(filePath, sourcePath) {
|
|
33637
33781
|
try {
|
|
33638
|
-
const marker = extractProvenanceMarker(
|
|
33782
|
+
const marker = extractProvenanceMarker(fs46.readFileSync(filePath, "utf8"));
|
|
33639
33783
|
return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
|
|
33640
33784
|
} catch {
|
|
33641
33785
|
return false;
|
|
@@ -33665,7 +33809,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
|
|
|
33665
33809
|
}
|
|
33666
33810
|
function readCompiledContent(filePath) {
|
|
33667
33811
|
try {
|
|
33668
|
-
return
|
|
33812
|
+
return fs46.readFileSync(filePath, "utf8");
|
|
33669
33813
|
} catch {
|
|
33670
33814
|
return null;
|
|
33671
33815
|
}
|
|
@@ -33696,8 +33840,8 @@ function hashString6(value) {
|
|
|
33696
33840
|
}
|
|
33697
33841
|
|
|
33698
33842
|
// src/commands/sync.ts
|
|
33699
|
-
import
|
|
33700
|
-
import
|
|
33843
|
+
import fs47 from "fs";
|
|
33844
|
+
import path48 from "path";
|
|
33701
33845
|
|
|
33702
33846
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
33703
33847
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -34367,18 +34511,30 @@ async function runSyncCommand(options, logger) {
|
|
|
34367
34511
|
reportHookRejections(
|
|
34368
34512
|
lossReport,
|
|
34369
34513
|
targets,
|
|
34370
|
-
|
|
34514
|
+
path48.resolve(kitInfo.path, "hooks"),
|
|
34371
34515
|
kitInfo.components.hooks.declared
|
|
34372
34516
|
);
|
|
34373
34517
|
const hooksConflict = reportHooksSourceConflict(
|
|
34374
34518
|
lossReport,
|
|
34375
34519
|
targets,
|
|
34376
|
-
|
|
34520
|
+
path48.resolve(kitInfo.path, "hooks"),
|
|
34377
34521
|
kitInfo.components.hooks.declared
|
|
34378
34522
|
);
|
|
34379
34523
|
if (hooksConflict) {
|
|
34380
34524
|
logger.warn(hooksConflict);
|
|
34381
34525
|
}
|
|
34526
|
+
if (allMappings) {
|
|
34527
|
+
reportContestedInstructions(
|
|
34528
|
+
instructionsByActiveTarget(
|
|
34529
|
+
targets,
|
|
34530
|
+
syncOptions.scope,
|
|
34531
|
+
syncOptions.projectRoot,
|
|
34532
|
+
allMappings
|
|
34533
|
+
),
|
|
34534
|
+
kitInfo.components.rules.declared.length > 0,
|
|
34535
|
+
logger
|
|
34536
|
+
);
|
|
34537
|
+
}
|
|
34382
34538
|
}
|
|
34383
34539
|
writeLossReport(options.lossReport, lossReport);
|
|
34384
34540
|
printOutcomeTable(results);
|
|
@@ -34564,8 +34720,8 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
|
|
|
34564
34720
|
}
|
|
34565
34721
|
}
|
|
34566
34722
|
function resolveKitFilePath(kitPath, relativePath) {
|
|
34567
|
-
const fullPath =
|
|
34568
|
-
return
|
|
34723
|
+
const fullPath = path48.join(kitPath, relativePath);
|
|
34724
|
+
return fs47.existsSync(fullPath) ? fullPath : null;
|
|
34569
34725
|
}
|
|
34570
34726
|
function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
|
|
34571
34727
|
if (removedSourcePaths.length === 0 || !mappings) {
|
|
@@ -34628,9 +34784,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34628
34784
|
}
|
|
34629
34785
|
if (relativePath.startsWith("agents/")) {
|
|
34630
34786
|
removeManagedCompiledArtifact2(
|
|
34631
|
-
|
|
34787
|
+
path48.join(
|
|
34632
34788
|
resolveTargetPath(paths.agents ?? ""),
|
|
34633
|
-
`${
|
|
34789
|
+
`${path48.parse(relativePath).name}.agent.md`
|
|
34634
34790
|
),
|
|
34635
34791
|
"copilot",
|
|
34636
34792
|
relativePath,
|
|
@@ -34640,9 +34796,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34640
34796
|
}
|
|
34641
34797
|
if (relativePath.startsWith("commands/")) {
|
|
34642
34798
|
removeManagedCompiledArtifact2(
|
|
34643
|
-
|
|
34799
|
+
path48.join(
|
|
34644
34800
|
resolveTargetPath(paths.prompts ?? ""),
|
|
34645
|
-
`${
|
|
34801
|
+
`${path48.parse(relativePath).name}.prompt.md`
|
|
34646
34802
|
),
|
|
34647
34803
|
"copilot",
|
|
34648
34804
|
relativePath,
|
|
@@ -34652,7 +34808,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34652
34808
|
}
|
|
34653
34809
|
if (relativePath.endsWith("hooks.json")) {
|
|
34654
34810
|
removeManagedCompiledArtifact2(
|
|
34655
|
-
|
|
34811
|
+
path48.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
|
|
34656
34812
|
"copilot",
|
|
34657
34813
|
relativePath,
|
|
34658
34814
|
logger
|
|
@@ -34682,9 +34838,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
34682
34838
|
}
|
|
34683
34839
|
if (relativePath.startsWith("agents/")) {
|
|
34684
34840
|
removeManagedCompiledArtifact2(
|
|
34685
|
-
|
|
34841
|
+
path48.join(
|
|
34686
34842
|
resolveTargetPath(paths.agents ?? ""),
|
|
34687
|
-
`${
|
|
34843
|
+
`${path48.parse(relativePath).name}.toml`
|
|
34688
34844
|
),
|
|
34689
34845
|
"codex",
|
|
34690
34846
|
relativePath,
|
|
@@ -34694,9 +34850,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
34694
34850
|
}
|
|
34695
34851
|
if (relativePath.startsWith("rules/")) {
|
|
34696
34852
|
removeManagedCompiledArtifact2(
|
|
34697
|
-
|
|
34853
|
+
path48.join(
|
|
34698
34854
|
resolveTargetPath(paths.rules ?? ""),
|
|
34699
|
-
`${
|
|
34855
|
+
`${path48.parse(relativePath).name}.rules`
|
|
34700
34856
|
),
|
|
34701
34857
|
"codex",
|
|
34702
34858
|
relativePath,
|
|
@@ -34735,9 +34891,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
34735
34891
|
}
|
|
34736
34892
|
if (relativePath.startsWith("agents/")) {
|
|
34737
34893
|
removeManagedCompiledArtifact2(
|
|
34738
|
-
|
|
34894
|
+
path48.join(
|
|
34739
34895
|
resolveTargetPath(paths.agents ?? ""),
|
|
34740
|
-
`${
|
|
34896
|
+
`${path48.parse(relativePath).name}.md`
|
|
34741
34897
|
),
|
|
34742
34898
|
"opencode",
|
|
34743
34899
|
relativePath,
|
|
@@ -34747,9 +34903,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
34747
34903
|
}
|
|
34748
34904
|
if (relativePath.startsWith("commands/")) {
|
|
34749
34905
|
removeManagedCompiledArtifact2(
|
|
34750
|
-
|
|
34906
|
+
path48.join(
|
|
34751
34907
|
resolveTargetPath(paths.commands ?? ""),
|
|
34752
|
-
`${
|
|
34908
|
+
`${path48.parse(relativePath).name}.md`
|
|
34753
34909
|
),
|
|
34754
34910
|
"opencode",
|
|
34755
34911
|
relativePath,
|
|
@@ -34781,9 +34937,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34781
34937
|
}
|
|
34782
34938
|
if (relativePath.startsWith("agents/")) {
|
|
34783
34939
|
removeManagedCompiledArtifact2(
|
|
34784
|
-
|
|
34940
|
+
path48.join(
|
|
34785
34941
|
resolveTargetPath(paths.agents ?? ""),
|
|
34786
|
-
`${
|
|
34942
|
+
`${path48.parse(relativePath).name}.md`
|
|
34787
34943
|
),
|
|
34788
34944
|
"cursor",
|
|
34789
34945
|
relativePath,
|
|
@@ -34793,9 +34949,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34793
34949
|
}
|
|
34794
34950
|
if (relativePath.startsWith("rules/")) {
|
|
34795
34951
|
removeManagedCompiledArtifact2(
|
|
34796
|
-
|
|
34952
|
+
path48.join(
|
|
34797
34953
|
resolveTargetPath(paths.rules ?? ""),
|
|
34798
|
-
`${
|
|
34954
|
+
`${path48.parse(relativePath).name}.mdc`
|
|
34799
34955
|
),
|
|
34800
34956
|
"cursor",
|
|
34801
34957
|
relativePath,
|
|
@@ -34805,9 +34961,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34805
34961
|
}
|
|
34806
34962
|
if (relativePath.startsWith("commands/")) {
|
|
34807
34963
|
removeManagedCompiledArtifact2(
|
|
34808
|
-
|
|
34964
|
+
path48.join(
|
|
34809
34965
|
resolveTargetPath(paths.skills ?? ""),
|
|
34810
|
-
|
|
34966
|
+
path48.parse(relativePath).name,
|
|
34811
34967
|
"SKILL.md"
|
|
34812
34968
|
),
|
|
34813
34969
|
"cursor",
|
|
@@ -34851,9 +35007,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
34851
35007
|
}
|
|
34852
35008
|
if (relativePath.startsWith("rules/")) {
|
|
34853
35009
|
removeManagedCompiledArtifact2(
|
|
34854
|
-
|
|
35010
|
+
path48.join(
|
|
34855
35011
|
resolveTargetPath(paths.rules ?? ""),
|
|
34856
|
-
`${
|
|
35012
|
+
`${path48.parse(relativePath).name}.md`
|
|
34857
35013
|
),
|
|
34858
35014
|
"cline",
|
|
34859
35015
|
relativePath,
|
|
@@ -34863,9 +35019,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
34863
35019
|
}
|
|
34864
35020
|
if (relativePath.startsWith("commands/")) {
|
|
34865
35021
|
removeManagedCompiledArtifact2(
|
|
34866
|
-
|
|
35022
|
+
path48.join(
|
|
34867
35023
|
resolveTargetPath(paths.workflows ?? ""),
|
|
34868
|
-
|
|
35024
|
+
path48.basename(relativePath)
|
|
34869
35025
|
),
|
|
34870
35026
|
"cline",
|
|
34871
35027
|
relativePath,
|
|
@@ -34883,17 +35039,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
34883
35039
|
}
|
|
34884
35040
|
}
|
|
34885
35041
|
function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
|
|
34886
|
-
if (!
|
|
35042
|
+
if (!fs47.existsSync(artifactPath)) {
|
|
34887
35043
|
return;
|
|
34888
35044
|
}
|
|
34889
|
-
if (!
|
|
35045
|
+
if (!fs47.statSync(artifactPath).isFile()) {
|
|
34890
35046
|
return;
|
|
34891
35047
|
}
|
|
34892
|
-
const marker = extractProvenanceMarker(
|
|
35048
|
+
const marker = extractProvenanceMarker(fs47.readFileSync(artifactPath, "utf8"));
|
|
34893
35049
|
if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
|
|
34894
35050
|
return;
|
|
34895
35051
|
}
|
|
34896
|
-
|
|
35052
|
+
fs47.rmSync(artifactPath, { force: true });
|
|
34897
35053
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
34898
35054
|
}
|
|
34899
35055
|
function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
@@ -34924,10 +35080,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
|
|
|
34924
35080
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
34925
35081
|
}
|
|
34926
35082
|
function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
34927
|
-
if (!
|
|
35083
|
+
if (!fs47.existsSync(artifactPath)) {
|
|
34928
35084
|
return;
|
|
34929
35085
|
}
|
|
34930
|
-
const content =
|
|
35086
|
+
const content = fs47.readFileSync(artifactPath, "utf8");
|
|
34931
35087
|
const startMarker = "# tangyr: managed mcp start";
|
|
34932
35088
|
const endMarker = "# tangyr: managed mcp end";
|
|
34933
35089
|
const startIndex = content.indexOf(startMarker);
|
|
@@ -34944,19 +35100,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
|
34944
35100
|
const after = content.slice(endIndex + endMarker.length).trimStart();
|
|
34945
35101
|
const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
|
|
34946
35102
|
if (cleaned.length === 0) {
|
|
34947
|
-
|
|
35103
|
+
fs47.rmSync(artifactPath, { force: true });
|
|
34948
35104
|
} else {
|
|
34949
|
-
|
|
35105
|
+
fs47.writeFileSync(artifactPath, `${cleaned}
|
|
34950
35106
|
`);
|
|
34951
35107
|
}
|
|
34952
35108
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
34953
35109
|
}
|
|
34954
35110
|
function readJsonObject5(filePath) {
|
|
34955
|
-
if (!
|
|
35111
|
+
if (!fs47.existsSync(filePath)) {
|
|
34956
35112
|
return null;
|
|
34957
35113
|
}
|
|
34958
35114
|
try {
|
|
34959
|
-
const parsed = JSON.parse(
|
|
35115
|
+
const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
|
|
34960
35116
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
34961
35117
|
} catch {
|
|
34962
35118
|
return null;
|
|
@@ -34970,10 +35126,10 @@ function readJsonMetadata(value) {
|
|
|
34970
35126
|
}
|
|
34971
35127
|
function writeJsonOrRemove2(filePath, parsed) {
|
|
34972
35128
|
if (isEmptyJsonValue2(parsed)) {
|
|
34973
|
-
|
|
35129
|
+
fs47.rmSync(filePath, { force: true });
|
|
34974
35130
|
return;
|
|
34975
35131
|
}
|
|
34976
|
-
|
|
35132
|
+
fs47.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
34977
35133
|
`);
|
|
34978
35134
|
}
|
|
34979
35135
|
function isEmptyJsonValue2(value) {
|
|
@@ -35033,8 +35189,8 @@ function removeManagedHookEntries(value, expectedSource) {
|
|
|
35033
35189
|
}
|
|
35034
35190
|
|
|
35035
35191
|
// src/commands/validate.ts
|
|
35036
|
-
import
|
|
35037
|
-
import
|
|
35192
|
+
import fs48 from "fs";
|
|
35193
|
+
import path49 from "path";
|
|
35038
35194
|
var SUPPORTED_KIT_FORMATS2 = [1];
|
|
35039
35195
|
var SUPPORTED_DISCIPLINE_VERSIONS = [
|
|
35040
35196
|
"0.14.0",
|
|
@@ -35149,12 +35305,12 @@ function checkArchetype(kit) {
|
|
|
35149
35305
|
}
|
|
35150
35306
|
function checkHookScriptsExist(kit) {
|
|
35151
35307
|
const violations = [];
|
|
35152
|
-
const hooksDir =
|
|
35308
|
+
const hooksDir = path49.join(kit.path, "hooks");
|
|
35153
35309
|
const missingSet = new Set(kit.components.hooks.missing);
|
|
35154
35310
|
for (const name of kit.components.hooks.declared) {
|
|
35155
35311
|
if (missingSet.has(name)) continue;
|
|
35156
|
-
const declarationPath =
|
|
35157
|
-
if (!
|
|
35312
|
+
const declarationPath = path49.join(hooksDir, `${name}.md`);
|
|
35313
|
+
if (!fs48.existsSync(declarationPath)) continue;
|
|
35158
35314
|
let data;
|
|
35159
35315
|
try {
|
|
35160
35316
|
({ data } = parseMarkdownFrontmatter(declarationPath));
|
|
@@ -35164,8 +35320,8 @@ function checkHookScriptsExist(kit) {
|
|
|
35164
35320
|
if (typeof data.command === "string" && data.command.trim().length > 0) {
|
|
35165
35321
|
continue;
|
|
35166
35322
|
}
|
|
35167
|
-
const scriptPath =
|
|
35168
|
-
if (!
|
|
35323
|
+
const scriptPath = path49.join(hooksDir, "scripts", `${name}.ts`);
|
|
35324
|
+
if (!fs48.existsSync(scriptPath)) {
|
|
35169
35325
|
violations.push({
|
|
35170
35326
|
code: "hook-script-missing",
|
|
35171
35327
|
location: `hooks/scripts/${name}.ts`,
|
|
@@ -35178,10 +35334,10 @@ function checkHookScriptsExist(kit) {
|
|
|
35178
35334
|
function checkOptionalSourceDocuments(kit) {
|
|
35179
35335
|
const violations = [];
|
|
35180
35336
|
for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
|
|
35181
|
-
const filePath =
|
|
35182
|
-
if (!
|
|
35337
|
+
const filePath = path49.join(kit.path, name);
|
|
35338
|
+
if (!fs48.existsSync(filePath)) continue;
|
|
35183
35339
|
try {
|
|
35184
|
-
const parsed = JSON.parse(
|
|
35340
|
+
const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
|
|
35185
35341
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
35186
35342
|
violations.push({
|
|
35187
35343
|
code: "optional-source-malformed",
|
|
@@ -35203,10 +35359,10 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35203
35359
|
const notices = [];
|
|
35204
35360
|
const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
|
|
35205
35361
|
for (const name of kit.components.skills.declared) {
|
|
35206
|
-
const skillDir =
|
|
35362
|
+
const skillDir = path49.join(kit.path, "skills", name);
|
|
35207
35363
|
let entries;
|
|
35208
35364
|
try {
|
|
35209
|
-
entries =
|
|
35365
|
+
entries = fs48.readdirSync(skillDir, { withFileTypes: true });
|
|
35210
35366
|
} catch {
|
|
35211
35367
|
continue;
|
|
35212
35368
|
}
|
|
@@ -35224,7 +35380,7 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35224
35380
|
return notices;
|
|
35225
35381
|
}
|
|
35226
35382
|
function checkHooksSourceForm(kit) {
|
|
35227
|
-
const hooksDir =
|
|
35383
|
+
const hooksDir = path49.join(kit.path, "hooks");
|
|
35228
35384
|
const message = describeHooksSourceConflict(
|
|
35229
35385
|
hooksDir,
|
|
35230
35386
|
kit.components.hooks.declared
|
|
@@ -35236,12 +35392,12 @@ function checkHooksSourceForm(kit) {
|
|
|
35236
35392
|
} : null;
|
|
35237
35393
|
}
|
|
35238
35394
|
function checkHookDeclarations(kit) {
|
|
35239
|
-
const hooksDir =
|
|
35395
|
+
const hooksDir = path49.join(kit.path, "hooks");
|
|
35240
35396
|
return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
|
|
35241
35397
|
(r) => ({
|
|
35242
35398
|
code: "hook-declaration-invalid",
|
|
35243
|
-
location: `hooks/${
|
|
35244
|
-
message: `hooks: '${
|
|
35399
|
+
location: `hooks/${path49.basename(r.file)}`,
|
|
35400
|
+
message: `hooks: '${path49.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.`
|
|
35245
35401
|
})
|
|
35246
35402
|
);
|
|
35247
35403
|
}
|
|
@@ -35261,11 +35417,11 @@ function checkKitFormatSupported(kit) {
|
|
|
35261
35417
|
function checkEntrypointExists(kit) {
|
|
35262
35418
|
const declared = kit.entrypoint;
|
|
35263
35419
|
const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
|
|
35264
|
-
const entrypointPath =
|
|
35265
|
-
if (
|
|
35420
|
+
const entrypointPath = path49.join(kit.path, entrypoint);
|
|
35421
|
+
if (fs48.existsSync(entrypointPath)) {
|
|
35266
35422
|
return null;
|
|
35267
35423
|
}
|
|
35268
|
-
const legacyPresent = declared === void 0 &&
|
|
35424
|
+
const legacyPresent = declared === void 0 && fs48.existsSync(path49.join(kit.path, LEGACY_ENTRYPOINT));
|
|
35269
35425
|
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.`;
|
|
35270
35426
|
return {
|
|
35271
35427
|
code: "entrypoint-missing",
|
|
@@ -35324,9 +35480,9 @@ function checkComponentFrontmatter(kit) {
|
|
|
35324
35480
|
const missingSet = new Set(kit.components[cat].missing);
|
|
35325
35481
|
for (const name of kit.components[cat].declared) {
|
|
35326
35482
|
if (missingSet.has(name)) continue;
|
|
35327
|
-
const filePath = cat === "skills" ?
|
|
35328
|
-
if (!
|
|
35329
|
-
const relPath =
|
|
35483
|
+
const filePath = cat === "skills" ? path49.join(kit.path, cat, name, "SKILL.md") : path49.join(kit.path, cat, `${name}.md`);
|
|
35484
|
+
if (!fs48.existsSync(filePath)) continue;
|
|
35485
|
+
const relPath = path49.relative(kit.path, filePath);
|
|
35330
35486
|
try {
|
|
35331
35487
|
const { data } = parseMarkdownFrontmatter(filePath);
|
|
35332
35488
|
for (const field of requiredFields) {
|
|
@@ -35351,10 +35507,10 @@ function checkComponentFrontmatter(kit) {
|
|
|
35351
35507
|
}
|
|
35352
35508
|
function checkReservedRootNames(kit) {
|
|
35353
35509
|
const violations = [];
|
|
35354
|
-
if (!
|
|
35510
|
+
if (!fs48.existsSync(kit.path) || !fs48.statSync(kit.path).isDirectory()) {
|
|
35355
35511
|
return violations;
|
|
35356
35512
|
}
|
|
35357
|
-
const entries =
|
|
35513
|
+
const entries = fs48.readdirSync(kit.path, { withFileTypes: true });
|
|
35358
35514
|
for (const entry of entries) {
|
|
35359
35515
|
if (RESERVED_ROOT_NAMES.includes(entry.name)) {
|
|
35360
35516
|
violations.push({
|
|
@@ -35371,8 +35527,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35371
35527
|
const missingSet = new Set(kit.components.commands.missing);
|
|
35372
35528
|
for (const name of kit.components.commands.declared) {
|
|
35373
35529
|
if (missingSet.has(name)) continue;
|
|
35374
|
-
const filePath =
|
|
35375
|
-
if (!
|
|
35530
|
+
const filePath = path49.join(kit.path, "commands", `${name}.md`);
|
|
35531
|
+
if (!fs48.existsSync(filePath)) continue;
|
|
35376
35532
|
let data;
|
|
35377
35533
|
try {
|
|
35378
35534
|
({ data } = parseMarkdownFrontmatter(filePath));
|
|
@@ -35385,7 +35541,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35385
35541
|
if (!barred) {
|
|
35386
35542
|
violations.push({
|
|
35387
35543
|
code: "command-human-only-model-invocable",
|
|
35388
|
-
location:
|
|
35544
|
+
location: path49.relative(kit.path, filePath),
|
|
35389
35545
|
message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
|
|
35390
35546
|
});
|
|
35391
35547
|
}
|
|
@@ -35394,8 +35550,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35394
35550
|
}
|
|
35395
35551
|
|
|
35396
35552
|
// src/commands/verify.ts
|
|
35397
|
-
import
|
|
35398
|
-
import
|
|
35553
|
+
import fs49 from "fs";
|
|
35554
|
+
import path50 from "path";
|
|
35399
35555
|
function runVerifyCommand(options, logger) {
|
|
35400
35556
|
if (options.target && !isKnownTarget(options.target)) {
|
|
35401
35557
|
throwUnrecognizedTarget(options.target);
|
|
@@ -35576,8 +35732,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
|
|
|
35576
35732
|
if (!slotPath) {
|
|
35577
35733
|
continue;
|
|
35578
35734
|
}
|
|
35579
|
-
const fullPath = subPath ?
|
|
35580
|
-
if (!
|
|
35735
|
+
const fullPath = subPath ? path50.join(slotPath, subPath) : slotPath;
|
|
35736
|
+
if (!fs49.existsSync(fullPath)) {
|
|
35581
35737
|
failures.push(
|
|
35582
35738
|
`claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
|
|
35583
35739
|
);
|