@alessandroraffa/tangyr 3.0.0 → 3.0.1
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 +700 -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":
|
|
@@ -25152,8 +25152,8 @@ function toConflictPolicy2(value) {
|
|
|
25152
25152
|
}
|
|
25153
25153
|
|
|
25154
25154
|
// src/commands/install.ts
|
|
25155
|
-
import
|
|
25156
|
-
import
|
|
25155
|
+
import fs44 from "fs";
|
|
25156
|
+
import path44 from "path";
|
|
25157
25157
|
|
|
25158
25158
|
// src/core/channel-state.ts
|
|
25159
25159
|
import fs32 from "fs";
|
|
@@ -26059,9 +26059,91 @@ function sleep(ms2) {
|
|
|
26059
26059
|
});
|
|
26060
26060
|
}
|
|
26061
26061
|
|
|
26062
|
+
// src/core/contested-instructions.ts
|
|
26063
|
+
import fs34 from "fs";
|
|
26064
|
+
import path31 from "path";
|
|
26065
|
+
var FOLDS_RULES_INTO_INSTRUCTIONS = {
|
|
26066
|
+
codex: "its own rules slot takes only exec-policy rules, so guidance rules are folded in",
|
|
26067
|
+
opencode: "it has no rules slot of its own, so every rule is folded in"
|
|
26068
|
+
};
|
|
26069
|
+
function markerTarget(destination) {
|
|
26070
|
+
try {
|
|
26071
|
+
if (fs34.lstatSync(destination).isSymbolicLink()) {
|
|
26072
|
+
return null;
|
|
26073
|
+
}
|
|
26074
|
+
const firstNonEmpty = fs34.readFileSync(destination, "utf8").split("\n").find((line) => line.trim().length > 0) ?? "";
|
|
26075
|
+
return extractProvenanceMarker(firstNonEmpty)?.target ?? null;
|
|
26076
|
+
} catch {
|
|
26077
|
+
return null;
|
|
26078
|
+
}
|
|
26079
|
+
}
|
|
26080
|
+
function findContestedInstructions(instructionsByTarget) {
|
|
26081
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
26082
|
+
for (const [target, destination] of instructionsByTarget) {
|
|
26083
|
+
const resolved = path31.resolve(destination);
|
|
26084
|
+
byPath.set(resolved, [...byPath.get(resolved) ?? [], target]);
|
|
26085
|
+
}
|
|
26086
|
+
const contested = [];
|
|
26087
|
+
for (const [destination, claimants] of byPath) {
|
|
26088
|
+
if (claimants.length < 2) {
|
|
26089
|
+
continue;
|
|
26090
|
+
}
|
|
26091
|
+
const losers = claimants.filter(
|
|
26092
|
+
(target) => target in FOLDS_RULES_INTO_INSTRUCTIONS
|
|
26093
|
+
);
|
|
26094
|
+
contested.push({
|
|
26095
|
+
destination,
|
|
26096
|
+
claimants: [...claimants].sort(),
|
|
26097
|
+
losers: losers.sort(),
|
|
26098
|
+
survivor: markerTarget(destination)
|
|
26099
|
+
});
|
|
26100
|
+
}
|
|
26101
|
+
return contested;
|
|
26102
|
+
}
|
|
26103
|
+
function reportContestedInstructions(instructionsByTarget, kitDeclaresRules, logger) {
|
|
26104
|
+
if (!kitDeclaresRules) {
|
|
26105
|
+
return;
|
|
26106
|
+
}
|
|
26107
|
+
for (const contested of findContestedInstructions(instructionsByTarget)) {
|
|
26108
|
+
if (contested.losers.length === 0) {
|
|
26109
|
+
continue;
|
|
26110
|
+
}
|
|
26111
|
+
logger.warn(
|
|
26112
|
+
`
|
|
26113
|
+
${contested.destination} is the instructions file for ${contested.claimants.join(", ")} at once, and they write it in turn.`
|
|
26114
|
+
);
|
|
26115
|
+
if (contested.survivor) {
|
|
26116
|
+
logger.warn(` The content on disk is ${contested.survivor}'s.`);
|
|
26117
|
+
}
|
|
26118
|
+
for (const target of contested.losers) {
|
|
26119
|
+
logger.warn(
|
|
26120
|
+
` ${target} does NOT get its rules: ${FOLDS_RULES_INTO_INSTRUCTIONS[target]}, and that content is overwritten here.`
|
|
26121
|
+
);
|
|
26122
|
+
}
|
|
26123
|
+
logger.warn(
|
|
26124
|
+
` Give those targets an instructions path of their own, or disable them. Their own rules slot, where they have one, is unaffected.`
|
|
26125
|
+
);
|
|
26126
|
+
}
|
|
26127
|
+
}
|
|
26128
|
+
function instructionsByActiveTarget(tools, scope, projectRoot, mappings) {
|
|
26129
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
26130
|
+
const resolved = resolveTargetPaths({
|
|
26131
|
+
scope,
|
|
26132
|
+
projectRoot,
|
|
26133
|
+
mappings: mappings.platformPaths
|
|
26134
|
+
});
|
|
26135
|
+
for (const tool of tools) {
|
|
26136
|
+
const instructions = resolved[tool]?.instructions;
|
|
26137
|
+
if (typeof instructions === "string" && instructions.length > 0) {
|
|
26138
|
+
byTarget.set(tool, instructions);
|
|
26139
|
+
}
|
|
26140
|
+
}
|
|
26141
|
+
return byTarget;
|
|
26142
|
+
}
|
|
26143
|
+
|
|
26062
26144
|
// src/adapters/claude-code.ts
|
|
26063
|
-
import
|
|
26064
|
-
import
|
|
26145
|
+
import fs37 from "fs";
|
|
26146
|
+
import path35 from "path";
|
|
26065
26147
|
|
|
26066
26148
|
// src/core/shim.ts
|
|
26067
26149
|
import crypto4 from "crypto";
|
|
@@ -26083,8 +26165,8 @@ ${SHIM_BODY}`;
|
|
|
26083
26165
|
}
|
|
26084
26166
|
|
|
26085
26167
|
// src/core/skills-slot.ts
|
|
26086
|
-
import
|
|
26087
|
-
import
|
|
26168
|
+
import fs35 from "fs";
|
|
26169
|
+
import path32 from "path";
|
|
26088
26170
|
function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
|
|
26089
26171
|
if (!isSymlinkPath(destination)) {
|
|
26090
26172
|
return false;
|
|
@@ -26097,7 +26179,7 @@ function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
|
|
|
26097
26179
|
}
|
|
26098
26180
|
function syncSkillsSlot(sync) {
|
|
26099
26181
|
const { source, destination, logger } = sync;
|
|
26100
|
-
if (!
|
|
26182
|
+
if (!fs35.existsSync(source)) {
|
|
26101
26183
|
return [
|
|
26102
26184
|
{
|
|
26103
26185
|
component: "skills",
|
|
@@ -26125,7 +26207,7 @@ function syncSkillsSlot(sync) {
|
|
|
26125
26207
|
if (isLegacyWholesaleSymlink) {
|
|
26126
26208
|
for (const name of foreignSkillNames(source, declaredNames)) {
|
|
26127
26209
|
logger.info(
|
|
26128
|
-
`[dry-run] skills: migrate foreign skill ${
|
|
26210
|
+
`[dry-run] skills: migrate foreign skill ${path32.join(source, name)} -> ${path32.join(destination, name)}`
|
|
26129
26211
|
);
|
|
26130
26212
|
}
|
|
26131
26213
|
logger.info(
|
|
@@ -26133,9 +26215,9 @@ function syncSkillsSlot(sync) {
|
|
|
26133
26215
|
);
|
|
26134
26216
|
}
|
|
26135
26217
|
for (const name of declaredNames ?? listSkillDirNames(source)) {
|
|
26136
|
-
const skillDestination =
|
|
26218
|
+
const skillDestination = path32.join(destination, name);
|
|
26137
26219
|
logger.info(
|
|
26138
|
-
`[dry-run] skills: symlink ${
|
|
26220
|
+
`[dry-run] skills: symlink ${path32.join(source, name)} -> ${skillDestination}`
|
|
26139
26221
|
);
|
|
26140
26222
|
outcomes2.push({
|
|
26141
26223
|
component: "skills",
|
|
@@ -26162,9 +26244,9 @@ function syncSkillsSlot(sync) {
|
|
|
26162
26244
|
}
|
|
26163
26245
|
function syncSingleSkill(sync, name) {
|
|
26164
26246
|
const { config, sourceRoot, source, destination } = sync;
|
|
26165
|
-
const skillSource =
|
|
26166
|
-
const skillDestination =
|
|
26167
|
-
if (!
|
|
26247
|
+
const skillSource = path32.join(source, name);
|
|
26248
|
+
const skillDestination = path32.join(destination, name);
|
|
26249
|
+
if (!fs35.existsSync(skillSource)) {
|
|
26168
26250
|
return {
|
|
26169
26251
|
component: "skills",
|
|
26170
26252
|
status: "skipped",
|
|
@@ -26180,29 +26262,29 @@ function syncSingleSkill(sync, name) {
|
|
|
26180
26262
|
};
|
|
26181
26263
|
}
|
|
26182
26264
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
|
|
26183
|
-
|
|
26265
|
+
fs35.unlinkSync(skillDestination);
|
|
26184
26266
|
} else if (artifactClass === "unmanaged-conflict" && !sync.onUnmanagedConflict(skillDestination)) {
|
|
26185
26267
|
return { component: "skills", status: "conflict", path: skillDestination };
|
|
26186
26268
|
} else if (artifactClass === "managed-symlink") {
|
|
26187
|
-
|
|
26269
|
+
fs35.unlinkSync(skillDestination);
|
|
26188
26270
|
}
|
|
26189
26271
|
createRelativeSymlink(skillSource, skillDestination, "dir");
|
|
26190
26272
|
return { component: "skills", status: "success", path: skillDestination };
|
|
26191
26273
|
}
|
|
26192
26274
|
function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
|
|
26193
26275
|
const foreignNames = foreignSkillNames(source, declaredNames);
|
|
26194
|
-
|
|
26276
|
+
fs35.unlinkSync(destination);
|
|
26195
26277
|
ensureDir(destination);
|
|
26196
26278
|
for (const name of foreignNames) {
|
|
26197
|
-
const from =
|
|
26198
|
-
const to =
|
|
26199
|
-
if (
|
|
26279
|
+
const from = path32.join(source, name);
|
|
26280
|
+
const to = path32.join(destination, name);
|
|
26281
|
+
if (fs35.existsSync(to)) {
|
|
26200
26282
|
logger.warn(
|
|
26201
26283
|
`skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
|
|
26202
26284
|
);
|
|
26203
26285
|
continue;
|
|
26204
26286
|
}
|
|
26205
|
-
|
|
26287
|
+
fs35.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
|
|
26206
26288
|
logger.warn(
|
|
26207
26289
|
`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
26290
|
);
|
|
@@ -26216,44 +26298,44 @@ function foreignSkillNames(source, declaredNames) {
|
|
|
26216
26298
|
return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
|
|
26217
26299
|
}
|
|
26218
26300
|
function listSkillDirNames(dir) {
|
|
26219
|
-
if (!
|
|
26301
|
+
if (!fs35.existsSync(dir)) {
|
|
26220
26302
|
return [];
|
|
26221
26303
|
}
|
|
26222
|
-
return
|
|
26304
|
+
return fs35.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
26223
26305
|
}
|
|
26224
26306
|
function isSymlinkPath(filePath) {
|
|
26225
26307
|
try {
|
|
26226
|
-
return
|
|
26308
|
+
return fs35.lstatSync(filePath).isSymbolicLink();
|
|
26227
26309
|
} catch {
|
|
26228
26310
|
return false;
|
|
26229
26311
|
}
|
|
26230
26312
|
}
|
|
26231
26313
|
function isSymlinkTo2(linkPath, source) {
|
|
26232
26314
|
try {
|
|
26233
|
-
return
|
|
26315
|
+
return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
|
|
26234
26316
|
} catch {
|
|
26235
26317
|
return false;
|
|
26236
26318
|
}
|
|
26237
26319
|
}
|
|
26238
26320
|
|
|
26239
26321
|
// src/core/hook-scripts.ts
|
|
26240
|
-
import
|
|
26322
|
+
import path33 from "path";
|
|
26241
26323
|
function hookScriptsDir(bridge, target, projectRoot) {
|
|
26242
26324
|
const globalBridge = resolveTargetPath("~/.agents/hooks");
|
|
26243
|
-
if (
|
|
26325
|
+
if (path33.resolve(bridge) === path33.resolve(globalBridge)) {
|
|
26244
26326
|
return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
|
|
26245
26327
|
}
|
|
26246
|
-
const relative =
|
|
26247
|
-
const insideProject = !relative.startsWith("..") && !
|
|
26328
|
+
const relative = path33.relative(projectRoot ?? process.cwd(), bridge);
|
|
26329
|
+
const insideProject = !relative.startsWith("..") && !path33.isAbsolute(relative) && relative !== "";
|
|
26248
26330
|
const variable = PROJECT_DIR_VARIABLE[target];
|
|
26249
26331
|
if (insideProject && variable) {
|
|
26250
|
-
const posix =
|
|
26251
|
-
relative.split(
|
|
26332
|
+
const posix = path33.posix.join(
|
|
26333
|
+
relative.split(path33.sep).join("/"),
|
|
26252
26334
|
"scripts"
|
|
26253
26335
|
);
|
|
26254
26336
|
return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
|
|
26255
26337
|
}
|
|
26256
|
-
return { prefix:
|
|
26338
|
+
return { prefix: path33.join(bridge, "scripts"), machineLocal: true };
|
|
26257
26339
|
}
|
|
26258
26340
|
var PROJECT_DIR_VARIABLE = {
|
|
26259
26341
|
"claude-code": "$CLAUDE_PROJECT_DIR"
|
|
@@ -26263,19 +26345,19 @@ function machineLocalScriptPathNotice(target, prefix) {
|
|
|
26263
26345
|
}
|
|
26264
26346
|
|
|
26265
26347
|
// src/core/instructions-source.ts
|
|
26266
|
-
import
|
|
26267
|
-
import
|
|
26348
|
+
import fs36 from "fs";
|
|
26349
|
+
import path34 from "path";
|
|
26268
26350
|
var PORTABLE_INSTRUCTIONS_NAME = "AGENTS.md";
|
|
26269
26351
|
var InstructionsSourceMissingError = class extends Error {
|
|
26270
26352
|
constructor(kitRoot, expected, declaredBy) {
|
|
26271
26353
|
super(
|
|
26272
|
-
`${
|
|
26354
|
+
`${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
26355
|
);
|
|
26274
26356
|
this.name = "InstructionsSourceMissingError";
|
|
26275
26357
|
}
|
|
26276
26358
|
};
|
|
26277
26359
|
function normalizeLabel(kitRoot, file) {
|
|
26278
|
-
return
|
|
26360
|
+
return path34.relative(kitRoot, file).split(path34.sep).join("/");
|
|
26279
26361
|
}
|
|
26280
26362
|
function isExplicitOverride(configured) {
|
|
26281
26363
|
const normalize = (value) => value.replace(/\\/gu, "/").replace(/^\.\//u, "");
|
|
@@ -26284,8 +26366,8 @@ function isExplicitOverride(configured) {
|
|
|
26284
26366
|
function resolveInstructionsSource(kitRoot, config) {
|
|
26285
26367
|
const configured = config.source.instructions;
|
|
26286
26368
|
if (isExplicitOverride(configured)) {
|
|
26287
|
-
const file =
|
|
26288
|
-
if (!
|
|
26369
|
+
const file = path34.resolve(kitRoot, configured);
|
|
26370
|
+
if (!fs36.existsSync(file)) {
|
|
26289
26371
|
throw new InstructionsSourceMissingError(
|
|
26290
26372
|
kitRoot,
|
|
26291
26373
|
configured,
|
|
@@ -26300,8 +26382,8 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26300
26382
|
}
|
|
26301
26383
|
const declared = resolveKitEntrypointName(kitRoot);
|
|
26302
26384
|
if (declared !== void 0) {
|
|
26303
|
-
const file =
|
|
26304
|
-
if (!
|
|
26385
|
+
const file = path34.resolve(kitRoot, declared);
|
|
26386
|
+
if (!fs36.existsSync(file)) {
|
|
26305
26387
|
throw new InstructionsSourceMissingError(
|
|
26306
26388
|
kitRoot,
|
|
26307
26389
|
declared,
|
|
@@ -26315,13 +26397,13 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26315
26397
|
};
|
|
26316
26398
|
}
|
|
26317
26399
|
for (const name of [DEFAULT_ENTRYPOINT, PORTABLE_INSTRUCTIONS_NAME]) {
|
|
26318
|
-
const file =
|
|
26319
|
-
if (
|
|
26400
|
+
const file = path34.resolve(kitRoot, name);
|
|
26401
|
+
if (fs36.existsSync(file)) {
|
|
26320
26402
|
return { file, label: name, origin: "convention" };
|
|
26321
26403
|
}
|
|
26322
26404
|
}
|
|
26323
|
-
const legacy =
|
|
26324
|
-
if (
|
|
26405
|
+
const legacy = path34.resolve(kitRoot, LEGACY_ENTRYPOINT);
|
|
26406
|
+
if (fs36.existsSync(legacy)) {
|
|
26325
26407
|
return {
|
|
26326
26408
|
file: legacy,
|
|
26327
26409
|
label: LEGACY_ENTRYPOINT,
|
|
@@ -26333,7 +26415,7 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26333
26415
|
}
|
|
26334
26416
|
function instructionsSourcePath(kitRoot, config) {
|
|
26335
26417
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
26336
|
-
return resolved ? resolved.file :
|
|
26418
|
+
return resolved ? resolved.file : path34.resolve(kitRoot, config.source.instructions);
|
|
26337
26419
|
}
|
|
26338
26420
|
function instructionsSourceLabel(kitRoot, config) {
|
|
26339
26421
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
@@ -26454,7 +26536,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
26454
26536
|
if (!shouldSkipComponent(options, "hooks")) {
|
|
26455
26537
|
outcomes.push(
|
|
26456
26538
|
syncHookScriptsBridge({
|
|
26457
|
-
source:
|
|
26539
|
+
source: path35.resolve(sourceRoot, config.source.hooks),
|
|
26458
26540
|
destination: profile.hook_scripts,
|
|
26459
26541
|
config,
|
|
26460
26542
|
sourceRoot,
|
|
@@ -26506,13 +26588,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
26506
26588
|
}
|
|
26507
26589
|
function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
|
|
26508
26590
|
if (!mappings.modelTiers.custom_provider) return;
|
|
26509
|
-
const agentsDir =
|
|
26510
|
-
if (!
|
|
26511
|
-
for (const agentFile of ts(
|
|
26591
|
+
const agentsDir = path35.join(sourceRoot, config.source.agents);
|
|
26592
|
+
if (!fs37.existsSync(agentsDir)) return;
|
|
26593
|
+
for (const agentFile of ts(path35.join(agentsDir, "*.md")).sort()) {
|
|
26512
26594
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
26513
26595
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
26514
26596
|
if (hasProvider) {
|
|
26515
|
-
const basename =
|
|
26597
|
+
const basename = path35.basename(agentFile);
|
|
26516
26598
|
addLoss(lossReport, "claude-code", "agents", {
|
|
26517
26599
|
source: `agents/${basename}`,
|
|
26518
26600
|
fields: [
|
|
@@ -26537,7 +26619,7 @@ function shouldSkipComponent(options, component) {
|
|
|
26537
26619
|
var SHIM_MANIFEST_KEY = "claude-code/instructions_shim";
|
|
26538
26620
|
function lstatOrNull(p) {
|
|
26539
26621
|
try {
|
|
26540
|
-
return
|
|
26622
|
+
return fs37.lstatSync(p);
|
|
26541
26623
|
} catch {
|
|
26542
26624
|
return null;
|
|
26543
26625
|
}
|
|
@@ -26549,12 +26631,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26549
26631
|
if (shimLink?.isSymbolicLink()) {
|
|
26550
26632
|
backupFile(shimPath, manifest, scopePath);
|
|
26551
26633
|
writeManifest(scopePath, manifest);
|
|
26552
|
-
|
|
26634
|
+
fs37.unlinkSync(shimPath);
|
|
26553
26635
|
logger?.verbose(
|
|
26554
26636
|
`instructions-shim: replaced an unmanaged symlink at ${shimPath}`
|
|
26555
26637
|
);
|
|
26556
26638
|
}
|
|
26557
|
-
if (!
|
|
26639
|
+
if (!fs37.existsSync(shimPath)) {
|
|
26558
26640
|
addArtifactToManifest(manifest, {
|
|
26559
26641
|
relativePath: SHIM_MANIFEST_KEY,
|
|
26560
26642
|
path: shimPath,
|
|
@@ -26562,12 +26644,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26562
26644
|
origin: "tangyr-managed"
|
|
26563
26645
|
});
|
|
26564
26646
|
writeManifest(scopePath, manifest);
|
|
26565
|
-
|
|
26566
|
-
|
|
26647
|
+
fs37.mkdirSync(path35.dirname(shimPath), { recursive: true });
|
|
26648
|
+
fs37.writeFileSync(shimPath, shimContent);
|
|
26567
26649
|
logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
|
|
26568
26650
|
return;
|
|
26569
26651
|
}
|
|
26570
|
-
const existing =
|
|
26652
|
+
const existing = fs37.readFileSync(shimPath, "utf8");
|
|
26571
26653
|
const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
|
|
26572
26654
|
const marker = extractProvenanceMarker(firstNonEmptyLine);
|
|
26573
26655
|
if (marker !== null && marker.hash === expectedBodyHash) {
|
|
@@ -26584,7 +26666,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26584
26666
|
}
|
|
26585
26667
|
backupFile(shimPath, manifest, scopePath);
|
|
26586
26668
|
writeManifest(scopePath, manifest);
|
|
26587
|
-
|
|
26669
|
+
fs37.writeFileSync(shimPath, shimContent);
|
|
26588
26670
|
addArtifactToManifest(manifest, {
|
|
26589
26671
|
relativePath: SHIM_MANIFEST_KEY,
|
|
26590
26672
|
path: shimPath,
|
|
@@ -26594,10 +26676,10 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26594
26676
|
logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
|
|
26595
26677
|
}
|
|
26596
26678
|
function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
|
|
26597
|
-
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) :
|
|
26679
|
+
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path35.resolve(sourceRoot, config.source[directComponent.sourceKey]);
|
|
26598
26680
|
const sourceLabel = directComponent.sourceKey === "instructions" ? instructionsSourceLabel(sourceRoot, config) : config.source[directComponent.sourceKey];
|
|
26599
26681
|
const destination = directComponent.destination;
|
|
26600
|
-
if (!
|
|
26682
|
+
if (!fs37.existsSync(source)) {
|
|
26601
26683
|
return skippedMissingSource(directComponent.component, source);
|
|
26602
26684
|
}
|
|
26603
26685
|
if (options.dryRun) {
|
|
@@ -26619,7 +26701,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
26619
26701
|
};
|
|
26620
26702
|
}
|
|
26621
26703
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
26622
|
-
|
|
26704
|
+
fs37.unlinkSync(destination);
|
|
26623
26705
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
|
|
26624
26706
|
return {
|
|
26625
26707
|
component: directComponent.component,
|
|
@@ -26627,14 +26709,11 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
26627
26709
|
path: destination
|
|
26628
26710
|
};
|
|
26629
26711
|
} else if (artifactClass === "managed-symlink") {
|
|
26630
|
-
|
|
26712
|
+
fs37.unlinkSync(destination);
|
|
26631
26713
|
} 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);
|
|
26714
|
+
fs37.unlinkSync(destination);
|
|
26636
26715
|
}
|
|
26637
|
-
ensureDir(
|
|
26716
|
+
ensureDir(path35.dirname(destination));
|
|
26638
26717
|
createRelativeSymlink(source, destination, directComponent.type, {
|
|
26639
26718
|
logger,
|
|
26640
26719
|
provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
|
|
@@ -26654,7 +26733,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
26654
26733
|
return syncSkillsSlot({
|
|
26655
26734
|
config,
|
|
26656
26735
|
sourceRoot,
|
|
26657
|
-
source:
|
|
26736
|
+
source: path35.resolve(sourceRoot, config.source.skills),
|
|
26658
26737
|
destination,
|
|
26659
26738
|
dryRun: options.dryRun,
|
|
26660
26739
|
logger,
|
|
@@ -26688,7 +26767,7 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
|
|
|
26688
26767
|
destination,
|
|
26689
26768
|
settings,
|
|
26690
26769
|
stringifyJson2,
|
|
26691
|
-
!
|
|
26770
|
+
!fs37.existsSync(destination),
|
|
26692
26771
|
logger
|
|
26693
26772
|
);
|
|
26694
26773
|
return {
|
|
@@ -26698,8 +26777,8 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
|
|
|
26698
26777
|
};
|
|
26699
26778
|
}
|
|
26700
26779
|
function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
26701
|
-
const source =
|
|
26702
|
-
if (!
|
|
26780
|
+
const source = path35.resolve(sourceRoot, config.source.mcp);
|
|
26781
|
+
if (!fs37.existsSync(source)) {
|
|
26703
26782
|
return skippedMissingSource("mcp", source);
|
|
26704
26783
|
}
|
|
26705
26784
|
if (options.dryRun) {
|
|
@@ -26724,7 +26803,7 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
|
26724
26803
|
destination,
|
|
26725
26804
|
hostConfig,
|
|
26726
26805
|
stringifyJson2,
|
|
26727
|
-
!
|
|
26806
|
+
!fs37.existsSync(destination),
|
|
26728
26807
|
logger
|
|
26729
26808
|
);
|
|
26730
26809
|
return {
|
|
@@ -26734,8 +26813,8 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
|
26734
26813
|
};
|
|
26735
26814
|
}
|
|
26736
26815
|
function syncSettings(config, sourceRoot, options, logger, destination) {
|
|
26737
|
-
const source =
|
|
26738
|
-
if (!
|
|
26816
|
+
const source = path35.resolve(sourceRoot, config.source.settings);
|
|
26817
|
+
if (!fs37.existsSync(source)) {
|
|
26739
26818
|
return skippedMissingSource("settings", source);
|
|
26740
26819
|
}
|
|
26741
26820
|
if (options.dryRun) {
|
|
@@ -26753,7 +26832,7 @@ function syncSettings(config, sourceRoot, options, logger, destination) {
|
|
|
26753
26832
|
destination,
|
|
26754
26833
|
settings,
|
|
26755
26834
|
stringifyJson2,
|
|
26756
|
-
!
|
|
26835
|
+
!fs37.existsSync(destination),
|
|
26757
26836
|
logger
|
|
26758
26837
|
);
|
|
26759
26838
|
return {
|
|
@@ -26777,13 +26856,13 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
|
|
|
26777
26856
|
if (manifest && scopePath) {
|
|
26778
26857
|
backupFile(destination, manifest, scopePath);
|
|
26779
26858
|
writeManifest(scopePath, manifest);
|
|
26780
|
-
|
|
26859
|
+
fs37.rmSync(destination, { recursive: true, force: true });
|
|
26781
26860
|
} else {
|
|
26782
|
-
|
|
26861
|
+
fs37.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
26783
26862
|
}
|
|
26784
26863
|
return true;
|
|
26785
26864
|
}
|
|
26786
|
-
|
|
26865
|
+
fs37.rmSync(destination, { recursive: true, force: true });
|
|
26787
26866
|
return true;
|
|
26788
26867
|
}
|
|
26789
26868
|
function skippedMissingSource(component, source) {
|
|
@@ -26795,16 +26874,16 @@ function skippedMissingSource(component, source) {
|
|
|
26795
26874
|
}
|
|
26796
26875
|
function isSymlinkTo3(linkPath, source) {
|
|
26797
26876
|
try {
|
|
26798
|
-
return
|
|
26877
|
+
return fs37.realpathSync(linkPath) === fs37.realpathSync(source);
|
|
26799
26878
|
} catch {
|
|
26800
26879
|
return false;
|
|
26801
26880
|
}
|
|
26802
26881
|
}
|
|
26803
26882
|
function readJsonObject3(filePath) {
|
|
26804
|
-
if (!
|
|
26883
|
+
if (!fs37.existsSync(filePath)) {
|
|
26805
26884
|
return {};
|
|
26806
26885
|
}
|
|
26807
|
-
const parsed = JSON.parse(
|
|
26886
|
+
const parsed = JSON.parse(fs37.readFileSync(filePath, "utf8"));
|
|
26808
26887
|
return isRecord3(parsed) ? parsed : {};
|
|
26809
26888
|
}
|
|
26810
26889
|
function markManaged(value) {
|
|
@@ -26831,13 +26910,13 @@ function isRecord3(value) {
|
|
|
26831
26910
|
// src/adapters/codex.ts
|
|
26832
26911
|
var TOML3 = __toESM(require_toml(), 1);
|
|
26833
26912
|
import crypto6 from "crypto";
|
|
26834
|
-
import
|
|
26835
|
-
import
|
|
26913
|
+
import fs39 from "fs";
|
|
26914
|
+
import path38 from "path";
|
|
26836
26915
|
|
|
26837
26916
|
// src/compiler/agents.ts
|
|
26838
26917
|
var TOML = __toESM(require_toml(), 1);
|
|
26839
26918
|
var import_yaml8 = __toESM(require_dist(), 1);
|
|
26840
|
-
import
|
|
26919
|
+
import path36 from "path";
|
|
26841
26920
|
var writeCapabilityClasses = /* @__PURE__ */ new Set(["filesystem-write", "shell-execution"]);
|
|
26842
26921
|
var copilotToolAliasesByClass = {
|
|
26843
26922
|
delegation: "agent",
|
|
@@ -26849,7 +26928,7 @@ var copilotToolAliasesByClass = {
|
|
|
26849
26928
|
};
|
|
26850
26929
|
function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
26851
26930
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
26852
|
-
const relativeSource = `agents/${
|
|
26931
|
+
const relativeSource = `agents/${path36.basename(sourceFile)}`;
|
|
26853
26932
|
if (target === "opencode") {
|
|
26854
26933
|
return compileOpenCodeAgent(
|
|
26855
26934
|
sourceFile,
|
|
@@ -26890,7 +26969,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
|
26890
26969
|
mappings,
|
|
26891
26970
|
lossReport
|
|
26892
26971
|
);
|
|
26893
|
-
const overlayKey = `agents/${
|
|
26972
|
+
const overlayKey = `agents/${path36.basename(sourceFile, ".md")}.${target}.yaml`;
|
|
26894
26973
|
const targetFields = {
|
|
26895
26974
|
...translated.fields,
|
|
26896
26975
|
...extensions[overlayKey] ?? {}
|
|
@@ -26924,7 +27003,7 @@ ${TOML.stringify({
|
|
|
26924
27003
|
function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
26925
27004
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
26926
27005
|
throw new Error(
|
|
26927
|
-
`${
|
|
27006
|
+
`${path36.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
|
|
26928
27007
|
);
|
|
26929
27008
|
}
|
|
26930
27009
|
const frontmatter = {
|
|
@@ -26978,7 +27057,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
|
|
|
26978
27057
|
"permission",
|
|
26979
27058
|
"permission-coarsening"
|
|
26980
27059
|
),
|
|
26981
|
-
detail: `${
|
|
27060
|
+
detail: `${path36.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
|
|
26982
27061
|
}
|
|
26983
27062
|
]
|
|
26984
27063
|
});
|
|
@@ -27003,7 +27082,7 @@ ${(0, import_yaml8.stringify)(frontmatter).trim()}
|
|
|
27003
27082
|
function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
27004
27083
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
27005
27084
|
throw new Error(
|
|
27006
|
-
`${
|
|
27085
|
+
`${path36.basename(sourceFile)}: Cursor agent requires a non-empty description field`
|
|
27007
27086
|
);
|
|
27008
27087
|
}
|
|
27009
27088
|
const frontmatter = {
|
|
@@ -27040,7 +27119,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
27040
27119
|
"permission",
|
|
27041
27120
|
"permission-coarsening"
|
|
27042
27121
|
),
|
|
27043
|
-
detail: `${
|
|
27122
|
+
detail: `${path36.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
|
|
27044
27123
|
}
|
|
27045
27124
|
]
|
|
27046
27125
|
});
|
|
@@ -27059,7 +27138,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
27059
27138
|
"provider",
|
|
27060
27139
|
"provider-not-representable"
|
|
27061
27140
|
),
|
|
27062
|
-
detail: `${
|
|
27141
|
+
detail: `${path36.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
27063
27142
|
}
|
|
27064
27143
|
]
|
|
27065
27144
|
});
|
|
@@ -27091,7 +27170,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
|
|
|
27091
27170
|
"persona",
|
|
27092
27171
|
"persona-not-representable"
|
|
27093
27172
|
),
|
|
27094
|
-
detail: `${
|
|
27173
|
+
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
27174
|
}
|
|
27096
27175
|
]
|
|
27097
27176
|
});
|
|
@@ -27139,7 +27218,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27139
27218
|
field,
|
|
27140
27219
|
"model-not-representable"
|
|
27141
27220
|
),
|
|
27142
|
-
detail: `${
|
|
27221
|
+
detail: `${path36.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
|
|
27143
27222
|
});
|
|
27144
27223
|
return;
|
|
27145
27224
|
}
|
|
@@ -27157,9 +27236,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27157
27236
|
lossReport,
|
|
27158
27237
|
target,
|
|
27159
27238
|
"agents",
|
|
27160
|
-
`agents/${
|
|
27239
|
+
`agents/${path36.basename(sourceFile)}`,
|
|
27161
27240
|
"info",
|
|
27162
|
-
`${
|
|
27241
|
+
`${path36.basename(sourceFile)}: ${field} is delivered through another managed surface.`
|
|
27163
27242
|
);
|
|
27164
27243
|
return;
|
|
27165
27244
|
}
|
|
@@ -27168,7 +27247,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27168
27247
|
field,
|
|
27169
27248
|
action: entryType,
|
|
27170
27249
|
severity: resolveLossSeverity("agent-field", field, entryType),
|
|
27171
|
-
detail: `${
|
|
27250
|
+
detail: `${path36.basename(sourceFile)}: ${field} has no emitted field for this target.`
|
|
27172
27251
|
});
|
|
27173
27252
|
}
|
|
27174
27253
|
function mapToolsToCapabilities(value, mappings) {
|
|
@@ -27909,9 +27988,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
|
|
|
27909
27988
|
}
|
|
27910
27989
|
|
|
27911
27990
|
// src/compiler/rules.ts
|
|
27912
|
-
import
|
|
27991
|
+
import path37 from "path";
|
|
27913
27992
|
var import_yaml9 = __toESM(require_dist(), 1);
|
|
27914
|
-
import
|
|
27993
|
+
import fs38 from "fs";
|
|
27915
27994
|
function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
27916
27995
|
if (target === "copilot") {
|
|
27917
27996
|
addLoss(lossReport, "copilot", "rules", {
|
|
@@ -27948,13 +28027,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
|
27948
28027
|
}
|
|
27949
28028
|
const appendixParts = [];
|
|
27950
28029
|
const dotRulesFiles = [];
|
|
27951
|
-
for (const ruleFile of ts(
|
|
28030
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
27952
28031
|
const parsed = parseRule(ruleFile);
|
|
27953
|
-
const name =
|
|
28032
|
+
const name = path37.basename(ruleFile, ".md");
|
|
27954
28033
|
if (parsed.mode === "exec-policy") {
|
|
27955
28034
|
dotRulesFiles.push({
|
|
27956
28035
|
name: `${name}.rules`,
|
|
27957
|
-
content: `${formatProvenanceMarker("toml", `rules/${
|
|
28036
|
+
content: `${formatProvenanceMarker("toml", `rules/${path37.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
|
|
27958
28037
|
${parsed.body}`
|
|
27959
28038
|
});
|
|
27960
28039
|
continue;
|
|
@@ -27963,7 +28042,7 @@ ${parsed.body}`
|
|
|
27963
28042
|
|
|
27964
28043
|
${parsed.body.trim()}`);
|
|
27965
28044
|
addLoss(lossReport, "codex", "rules", {
|
|
27966
|
-
source: `rules/${
|
|
28045
|
+
source: `rules/${path37.basename(ruleFile)}`,
|
|
27967
28046
|
fields: [
|
|
27968
28047
|
{
|
|
27969
28048
|
field: "mode",
|
|
@@ -27973,7 +28052,7 @@ ${parsed.body.trim()}`);
|
|
|
27973
28052
|
"mode",
|
|
27974
28053
|
"rule-as-instruction"
|
|
27975
28054
|
),
|
|
27976
|
-
detail: `${
|
|
28055
|
+
detail: `${path37.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
|
|
27977
28056
|
}
|
|
27978
28057
|
]
|
|
27979
28058
|
});
|
|
@@ -27981,7 +28060,7 @@ ${parsed.body.trim()}`);
|
|
|
27981
28060
|
return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
|
|
27982
28061
|
}
|
|
27983
28062
|
function parseRule(ruleFile) {
|
|
27984
|
-
const content =
|
|
28063
|
+
const content = fs38.readFileSync(ruleFile, "utf8");
|
|
27985
28064
|
if (!content.startsWith("---\n")) {
|
|
27986
28065
|
return { mode: "guidance", body: content };
|
|
27987
28066
|
}
|
|
@@ -28005,14 +28084,14 @@ function isRuleMode(value) {
|
|
|
28005
28084
|
}
|
|
28006
28085
|
function compileOpenCodeRules(sourceRulesDir, lossReport) {
|
|
28007
28086
|
const appendixParts = [];
|
|
28008
|
-
for (const ruleFile of ts(
|
|
28087
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
28009
28088
|
const parsed = parseRule(ruleFile);
|
|
28010
|
-
const name =
|
|
28089
|
+
const name = path37.basename(ruleFile, ".md");
|
|
28011
28090
|
appendixParts.push(`## ${name}
|
|
28012
28091
|
|
|
28013
28092
|
${parsed.body.trim()}`);
|
|
28014
28093
|
addLoss(lossReport, "opencode", "rules", {
|
|
28015
|
-
source: `rules/${
|
|
28094
|
+
source: `rules/${path37.basename(ruleFile)}`,
|
|
28016
28095
|
fields: [
|
|
28017
28096
|
{
|
|
28018
28097
|
field: "rule",
|
|
@@ -28022,7 +28101,7 @@ ${parsed.body.trim()}`);
|
|
|
28022
28101
|
"rule",
|
|
28023
28102
|
"rule-path-scoping"
|
|
28024
28103
|
),
|
|
28025
|
-
detail: `${
|
|
28104
|
+
detail: `${path37.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
|
|
28026
28105
|
}
|
|
28027
28106
|
]
|
|
28028
28107
|
});
|
|
@@ -28031,9 +28110,9 @@ ${parsed.body.trim()}`);
|
|
|
28031
28110
|
}
|
|
28032
28111
|
function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
28033
28112
|
const dotRulesFiles = [];
|
|
28034
|
-
for (const ruleFile of ts(
|
|
28035
|
-
const content =
|
|
28036
|
-
const name =
|
|
28113
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
28114
|
+
const content = fs38.readFileSync(ruleFile, "utf8");
|
|
28115
|
+
const name = path37.basename(ruleFile, ".md");
|
|
28037
28116
|
let frontmatterData = {};
|
|
28038
28117
|
let body = content;
|
|
28039
28118
|
if (content.startsWith("---\n")) {
|
|
@@ -28062,7 +28141,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
|
28062
28141
|
}
|
|
28063
28142
|
const marker = formatProvenanceMarker(
|
|
28064
28143
|
"markdown",
|
|
28065
|
-
`rules/${
|
|
28144
|
+
`rules/${path37.basename(ruleFile)}`,
|
|
28066
28145
|
computeSourceHash(ruleFile),
|
|
28067
28146
|
"cursor"
|
|
28068
28147
|
);
|
|
@@ -28078,9 +28157,9 @@ ${body}`;
|
|
|
28078
28157
|
}
|
|
28079
28158
|
function compileClineRules(sourceRulesDir, lossReport) {
|
|
28080
28159
|
const dotRulesFiles = [];
|
|
28081
|
-
for (const ruleFile of ts(
|
|
28082
|
-
const content =
|
|
28083
|
-
const name =
|
|
28160
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
28161
|
+
const content = fs38.readFileSync(ruleFile, "utf8");
|
|
28162
|
+
const name = path37.basename(ruleFile, ".md");
|
|
28084
28163
|
let frontmatterData = {};
|
|
28085
28164
|
let body = content;
|
|
28086
28165
|
if (content.startsWith("---\n")) {
|
|
@@ -28097,13 +28176,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28097
28176
|
}
|
|
28098
28177
|
const marker = formatProvenanceMarker(
|
|
28099
28178
|
"markdown",
|
|
28100
|
-
`rules/${
|
|
28179
|
+
`rules/${path37.basename(ruleFile)}`,
|
|
28101
28180
|
computeSourceHash(ruleFile),
|
|
28102
28181
|
"cline"
|
|
28103
28182
|
);
|
|
28104
28183
|
if (frontmatterData.mode === "exec-policy") {
|
|
28105
28184
|
addLoss(lossReport, "cline", "rules", {
|
|
28106
|
-
source: `rules/${
|
|
28185
|
+
source: `rules/${path37.basename(ruleFile)}`,
|
|
28107
28186
|
fields: [
|
|
28108
28187
|
{
|
|
28109
28188
|
field: "mode",
|
|
@@ -28113,7 +28192,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28113
28192
|
"mode",
|
|
28114
28193
|
"rule-mode-downgrade"
|
|
28115
28194
|
),
|
|
28116
|
-
detail: `${
|
|
28195
|
+
detail: `${path37.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
|
|
28117
28196
|
}
|
|
28118
28197
|
]
|
|
28119
28198
|
});
|
|
@@ -28159,7 +28238,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28159
28238
|
rules: profile.rules
|
|
28160
28239
|
};
|
|
28161
28240
|
const rules = compileRules(
|
|
28162
|
-
|
|
28241
|
+
path38.join(sourceRoot, config.source.rules),
|
|
28163
28242
|
"codex",
|
|
28164
28243
|
mappings,
|
|
28165
28244
|
lossReport
|
|
@@ -28225,7 +28304,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28225
28304
|
if (!shouldSkipComponent2(options, "hooks")) {
|
|
28226
28305
|
outcomes.push(
|
|
28227
28306
|
syncHookScriptsBridge({
|
|
28228
|
-
source:
|
|
28307
|
+
source: path38.resolve(sourceRoot, config.source.hooks),
|
|
28229
28308
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
28230
28309
|
config,
|
|
28231
28310
|
sourceRoot,
|
|
@@ -28324,9 +28403,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28324
28403
|
function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
|
|
28325
28404
|
const cp = mappings.modelTiers.custom_provider;
|
|
28326
28405
|
if (!cp) return "";
|
|
28327
|
-
const agentsDir =
|
|
28328
|
-
if (!
|
|
28329
|
-
const agentFiles = ts(
|
|
28406
|
+
const agentsDir = path38.join(sourceRoot, config.source.agents);
|
|
28407
|
+
if (!fs39.existsSync(agentsDir)) return "";
|
|
28408
|
+
const agentFiles = ts(path38.join(agentsDir, "*.md")).sort();
|
|
28330
28409
|
const hasProviderAgent = agentFiles.some((agentFile) => {
|
|
28331
28410
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28332
28411
|
return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
@@ -28391,7 +28470,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28391
28470
|
}
|
|
28392
28471
|
];
|
|
28393
28472
|
for (const ruleFile of rules.dotRulesFiles) {
|
|
28394
|
-
const destination =
|
|
28473
|
+
const destination = path38.join(rulesRoot, ruleFile.name);
|
|
28395
28474
|
if (options.dryRun) {
|
|
28396
28475
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
28397
28476
|
outcomes.push({
|
|
@@ -28421,16 +28500,16 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28421
28500
|
function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
28422
28501
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
28423
28502
|
const destination = resolveTargetPath(paths.instructions);
|
|
28424
|
-
if (!
|
|
28503
|
+
if (!fs39.existsSync(source)) {
|
|
28425
28504
|
return skippedMissingSource2("instructions", source);
|
|
28426
28505
|
}
|
|
28427
|
-
const composed = `${
|
|
28506
|
+
const composed = `${fs39.readFileSync(source, "utf8").trim()}
|
|
28428
28507
|
|
|
28429
28508
|
--- tangyr managed rules ---
|
|
28430
28509
|
${agentsAppendix}`.trim();
|
|
28431
28510
|
const marker = formatProvenanceMarker(
|
|
28432
28511
|
"markdown",
|
|
28433
|
-
|
|
28512
|
+
path38.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
28434
28513
|
hashString(composed),
|
|
28435
28514
|
"codex"
|
|
28436
28515
|
);
|
|
@@ -28457,9 +28536,9 @@ ${composed}
|
|
|
28457
28536
|
);
|
|
28458
28537
|
}
|
|
28459
28538
|
function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
28460
|
-
const source =
|
|
28539
|
+
const source = path38.resolve(sourceRoot, config.source.skills);
|
|
28461
28540
|
const destination = resolveTargetPath(paths.skills);
|
|
28462
|
-
if (!
|
|
28541
|
+
if (!fs39.existsSync(source)) {
|
|
28463
28542
|
return skippedMissingSource2("skills", source);
|
|
28464
28543
|
}
|
|
28465
28544
|
if (options.dryRun) {
|
|
@@ -28475,29 +28554,29 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
28475
28554
|
};
|
|
28476
28555
|
}
|
|
28477
28556
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
28478
|
-
|
|
28557
|
+
fs39.unlinkSync(destination);
|
|
28479
28558
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
28480
28559
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
28481
28560
|
return { component: "skills", status: "conflict", path: destination };
|
|
28482
28561
|
} else if (artifactClass === "managed-symlink") {
|
|
28483
|
-
|
|
28562
|
+
fs39.unlinkSync(destination);
|
|
28484
28563
|
}
|
|
28485
|
-
ensureDir(
|
|
28564
|
+
ensureDir(path38.dirname(destination));
|
|
28486
28565
|
createRelativeSymlink(source, destination, "dir");
|
|
28487
28566
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
28488
28567
|
return { component: "skills", status: "success", path: destination };
|
|
28489
28568
|
}
|
|
28490
28569
|
function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
28491
|
-
const sourceAgentsRoot =
|
|
28492
|
-
if (!
|
|
28570
|
+
const sourceAgentsRoot = path38.join(sourceRoot, config.source.agents);
|
|
28571
|
+
if (!fs39.existsSync(sourceAgentsRoot)) {
|
|
28493
28572
|
return [skippedMissingSource2("agents", sourceAgentsRoot)];
|
|
28494
28573
|
}
|
|
28495
|
-
const sourceAgents = ts(
|
|
28574
|
+
const sourceAgents = ts(path38.join(sourceAgentsRoot, "*.md")).sort();
|
|
28496
28575
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
28497
28576
|
return sourceAgents.map((agentFile) => {
|
|
28498
|
-
const destination =
|
|
28577
|
+
const destination = path38.join(
|
|
28499
28578
|
agentsRoot,
|
|
28500
|
-
`${
|
|
28579
|
+
`${path38.basename(agentFile, ".md")}.toml`
|
|
28501
28580
|
);
|
|
28502
28581
|
const compiled = compileAgent(
|
|
28503
28582
|
agentFile,
|
|
@@ -28575,7 +28654,7 @@ function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
28575
28654
|
destination,
|
|
28576
28655
|
hostHooks,
|
|
28577
28656
|
stringifyJson3,
|
|
28578
|
-
!
|
|
28657
|
+
!fs39.existsSync(destination),
|
|
28579
28658
|
logger
|
|
28580
28659
|
);
|
|
28581
28660
|
return {
|
|
@@ -28588,7 +28667,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28588
28667
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
28589
28668
|
const sourceLabel = mcpSourceLabel(config);
|
|
28590
28669
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
28591
|
-
if (!
|
|
28670
|
+
if (!fs39.existsSync(source)) {
|
|
28592
28671
|
if (providerToml && !options.dryRun) {
|
|
28593
28672
|
const changed2 = writeTomlManagedSection(
|
|
28594
28673
|
destination,
|
|
@@ -28603,7 +28682,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28603
28682
|
}
|
|
28604
28683
|
return skippedMissingSource2("mcp", source);
|
|
28605
28684
|
}
|
|
28606
|
-
const sourceMcpJson = JSON.parse(
|
|
28685
|
+
const sourceMcpJson = JSON.parse(fs39.readFileSync(source, "utf8"));
|
|
28607
28686
|
const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
|
|
28608
28687
|
const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
|
|
28609
28688
|
if (options.dryRun) {
|
|
@@ -28625,18 +28704,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
|
|
|
28625
28704
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
28626
28705
|
return { component, status: "conflict", path: destination };
|
|
28627
28706
|
}
|
|
28628
|
-
ensureDir(
|
|
28707
|
+
ensureDir(path38.dirname(destination));
|
|
28629
28708
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
28630
28709
|
if (clearedLink !== null) {
|
|
28631
28710
|
logger.verbose(
|
|
28632
28711
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
28633
28712
|
);
|
|
28634
28713
|
}
|
|
28635
|
-
|
|
28714
|
+
fs39.writeFileSync(destination, content);
|
|
28636
28715
|
return { component, status: "success", path: destination };
|
|
28637
28716
|
}
|
|
28638
28717
|
function writeTomlManagedSection(destination, managedContent, logger) {
|
|
28639
|
-
const current =
|
|
28718
|
+
const current = fs39.existsSync(destination) ? fs39.readFileSync(destination, "utf8") : "";
|
|
28640
28719
|
const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
|
|
28641
28720
|
if (isFirstWrite) {
|
|
28642
28721
|
logger.warn(
|
|
@@ -28652,8 +28731,8 @@ ${managedMcpEnd}
|
|
|
28652
28731
|
if (current === next.trimStart()) {
|
|
28653
28732
|
return false;
|
|
28654
28733
|
}
|
|
28655
|
-
ensureDir(
|
|
28656
|
-
|
|
28734
|
+
ensureDir(path38.dirname(destination));
|
|
28735
|
+
fs39.writeFileSync(destination, next.trimStart());
|
|
28657
28736
|
return true;
|
|
28658
28737
|
}
|
|
28659
28738
|
function removeManagedTomlSection(content) {
|
|
@@ -28679,18 +28758,18 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
|
|
|
28679
28758
|
if (manifest && scopePath) {
|
|
28680
28759
|
backupFile(destination, manifest, scopePath);
|
|
28681
28760
|
writeManifest(scopePath, manifest);
|
|
28682
|
-
|
|
28761
|
+
fs39.rmSync(destination, { recursive: true, force: true });
|
|
28683
28762
|
} else {
|
|
28684
|
-
|
|
28763
|
+
fs39.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
28685
28764
|
}
|
|
28686
28765
|
return true;
|
|
28687
28766
|
}
|
|
28688
|
-
|
|
28767
|
+
fs39.rmSync(destination, { recursive: true, force: true });
|
|
28689
28768
|
return true;
|
|
28690
28769
|
}
|
|
28691
28770
|
function isCompiledCurrent(destination, expectedContent, expectedHash) {
|
|
28692
28771
|
try {
|
|
28693
|
-
const current =
|
|
28772
|
+
const current = fs39.readFileSync(destination, "utf8");
|
|
28694
28773
|
const marker = extractProvenanceMarker(current);
|
|
28695
28774
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "codex" && current === expectedContent : current === expectedContent;
|
|
28696
28775
|
} catch {
|
|
@@ -28709,16 +28788,16 @@ function shouldSkipComponent2(options, component) {
|
|
|
28709
28788
|
}
|
|
28710
28789
|
function isSymlinkTo4(linkPath, source) {
|
|
28711
28790
|
try {
|
|
28712
|
-
return
|
|
28791
|
+
return fs39.realpathSync(linkPath) === fs39.realpathSync(source);
|
|
28713
28792
|
} catch {
|
|
28714
28793
|
return false;
|
|
28715
28794
|
}
|
|
28716
28795
|
}
|
|
28717
28796
|
function readJsonObject4(filePath) {
|
|
28718
|
-
if (!
|
|
28797
|
+
if (!fs39.existsSync(filePath)) {
|
|
28719
28798
|
return {};
|
|
28720
28799
|
}
|
|
28721
|
-
const parsed = JSON.parse(
|
|
28800
|
+
const parsed = JSON.parse(fs39.readFileSync(filePath, "utf8"));
|
|
28722
28801
|
return isRecord5(parsed) ? parsed : {};
|
|
28723
28802
|
}
|
|
28724
28803
|
function stringifyJson3(value) {
|
|
@@ -28734,16 +28813,16 @@ function hashString(value) {
|
|
|
28734
28813
|
|
|
28735
28814
|
// src/adapters/copilot.ts
|
|
28736
28815
|
import crypto7 from "crypto";
|
|
28737
|
-
import
|
|
28738
|
-
import
|
|
28816
|
+
import fs40 from "fs";
|
|
28817
|
+
import path40 from "path";
|
|
28739
28818
|
|
|
28740
28819
|
// src/compiler/commands.ts
|
|
28741
28820
|
var import_yaml10 = __toESM(require_dist(), 1);
|
|
28742
|
-
import
|
|
28821
|
+
import path39 from "path";
|
|
28743
28822
|
function compileCommandPrompt(sourceFile) {
|
|
28744
28823
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
28745
|
-
const relativeSource = `commands/${
|
|
28746
|
-
const fields = promptFrontmatter(data,
|
|
28824
|
+
const relativeSource = `commands/${path39.basename(sourceFile)}`;
|
|
28825
|
+
const fields = promptFrontmatter(data, path39.basename(sourceFile, ".md"));
|
|
28747
28826
|
const marker = formatProvenanceMarker(
|
|
28748
28827
|
"markdown",
|
|
28749
28828
|
relativeSource,
|
|
@@ -28858,7 +28937,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
28858
28937
|
if (!shouldSkipComponent3(options, "hooks")) {
|
|
28859
28938
|
outcomes.push(
|
|
28860
28939
|
syncHookScriptsBridge({
|
|
28861
|
-
source:
|
|
28940
|
+
source: path40.resolve(sourceRoot, config.source.hooks),
|
|
28862
28941
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
28863
28942
|
config,
|
|
28864
28943
|
sourceRoot,
|
|
@@ -28939,13 +29018,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
28939
29018
|
}
|
|
28940
29019
|
function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
|
|
28941
29020
|
if (!mappings.modelTiers.custom_provider) return;
|
|
28942
|
-
const agentsDir =
|
|
28943
|
-
if (!
|
|
28944
|
-
for (const agentFile of ts(
|
|
29021
|
+
const agentsDir = path40.join(sourceRoot, config.source.agents);
|
|
29022
|
+
if (!fs40.existsSync(agentsDir)) return;
|
|
29023
|
+
for (const agentFile of ts(path40.join(agentsDir, "*.md")).sort()) {
|
|
28945
29024
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28946
29025
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
28947
29026
|
if (hasProvider) {
|
|
28948
|
-
const basename =
|
|
29027
|
+
const basename = path40.basename(agentFile);
|
|
28949
29028
|
addLoss(lossReport, "copilot", "agents", {
|
|
28950
29029
|
source: `agents/${basename}`,
|
|
28951
29030
|
fields: [
|
|
@@ -28971,22 +29050,22 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
|
|
|
28971
29050
|
return [{ component: "instructions", status: "skipped", path: message }];
|
|
28972
29051
|
}
|
|
28973
29052
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
28974
|
-
if (!
|
|
29053
|
+
if (!fs40.existsSync(source)) {
|
|
28975
29054
|
return [skippedMissingSource3("instructions", source)];
|
|
28976
29055
|
}
|
|
28977
|
-
const rawContent =
|
|
29056
|
+
const rawContent = fs40.readFileSync(source, "utf8");
|
|
28978
29057
|
const contentHash = hashString2(rawContent);
|
|
28979
29058
|
const marker = formatProvenanceMarker(
|
|
28980
29059
|
"markdown",
|
|
28981
|
-
|
|
29060
|
+
path40.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
28982
29061
|
contentHash,
|
|
28983
29062
|
"copilot"
|
|
28984
29063
|
);
|
|
28985
29064
|
const composedContent = `${marker}
|
|
28986
29065
|
${rawContent}`;
|
|
28987
29066
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
28988
|
-
const agentsMdDest =
|
|
28989
|
-
const mirrorDest =
|
|
29067
|
+
const agentsMdDest = path40.resolve(projectRoot, "AGENTS.md");
|
|
29068
|
+
const mirrorDest = path40.resolve(
|
|
28990
29069
|
projectRoot,
|
|
28991
29070
|
".github",
|
|
28992
29071
|
"copilot-instructions.md"
|
|
@@ -29040,14 +29119,14 @@ function writeInstructionsFile(component, destination, content, contentHash, con
|
|
|
29040
29119
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29041
29120
|
return { component, status: "conflict", path: destination };
|
|
29042
29121
|
}
|
|
29043
|
-
ensureDir(
|
|
29122
|
+
ensureDir(path40.dirname(destination));
|
|
29044
29123
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29045
29124
|
if (clearedLink !== null) {
|
|
29046
29125
|
logger.verbose(
|
|
29047
29126
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29048
29127
|
);
|
|
29049
29128
|
}
|
|
29050
|
-
|
|
29129
|
+
fs40.writeFileSync(destination, content);
|
|
29051
29130
|
return { component, status: "success", path: destination };
|
|
29052
29131
|
}
|
|
29053
29132
|
function hashString2(value) {
|
|
@@ -29057,7 +29136,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29057
29136
|
return syncSkillsSlot({
|
|
29058
29137
|
config,
|
|
29059
29138
|
sourceRoot,
|
|
29060
|
-
source:
|
|
29139
|
+
source: path40.resolve(sourceRoot, config.source.skills),
|
|
29061
29140
|
destination: resolveTargetPath(paths.skills),
|
|
29062
29141
|
dryRun: options.dryRun,
|
|
29063
29142
|
logger,
|
|
@@ -29072,16 +29151,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29072
29151
|
});
|
|
29073
29152
|
}
|
|
29074
29153
|
function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29075
|
-
const sourceAgentsRoot =
|
|
29076
|
-
if (!
|
|
29154
|
+
const sourceAgentsRoot = path40.join(sourceRoot, config.source.agents);
|
|
29155
|
+
if (!fs40.existsSync(sourceAgentsRoot)) {
|
|
29077
29156
|
return [skippedMissingSource3("agents", sourceAgentsRoot)];
|
|
29078
29157
|
}
|
|
29079
|
-
const sourceAgents = ts(
|
|
29158
|
+
const sourceAgents = ts(path40.join(sourceAgentsRoot, "*.md")).sort();
|
|
29080
29159
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29081
29160
|
return sourceAgents.map((agentFile) => {
|
|
29082
|
-
const destination =
|
|
29161
|
+
const destination = path40.join(
|
|
29083
29162
|
agentsRoot,
|
|
29084
|
-
`${
|
|
29163
|
+
`${path40.basename(agentFile, ".md")}.agent.md`
|
|
29085
29164
|
);
|
|
29086
29165
|
const compiled = compileAgent(
|
|
29087
29166
|
agentFile,
|
|
@@ -29109,16 +29188,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29109
29188
|
});
|
|
29110
29189
|
}
|
|
29111
29190
|
function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29112
|
-
const sourceCommandsRoot =
|
|
29113
|
-
if (!
|
|
29191
|
+
const sourceCommandsRoot = path40.join(sourceRoot, config.source.commands);
|
|
29192
|
+
if (!fs40.existsSync(sourceCommandsRoot)) {
|
|
29114
29193
|
return [skippedMissingSource3("commands", sourceCommandsRoot)];
|
|
29115
29194
|
}
|
|
29116
|
-
const sourceCommands = ts(
|
|
29195
|
+
const sourceCommands = ts(path40.join(sourceCommandsRoot, "*.md")).sort();
|
|
29117
29196
|
const promptsRoot = resolveTargetPath(paths.prompts);
|
|
29118
29197
|
return sourceCommands.map((commandFile) => {
|
|
29119
|
-
const destination =
|
|
29198
|
+
const destination = path40.join(
|
|
29120
29199
|
promptsRoot,
|
|
29121
|
-
`${
|
|
29200
|
+
`${path40.basename(commandFile, ".md")}.prompt.md`
|
|
29122
29201
|
);
|
|
29123
29202
|
const compiled = compileCommandPrompt(commandFile);
|
|
29124
29203
|
if (options.dryRun) {
|
|
@@ -29142,7 +29221,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
|
|
|
29142
29221
|
});
|
|
29143
29222
|
}
|
|
29144
29223
|
function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
29145
|
-
const destination =
|
|
29224
|
+
const destination = path40.join(
|
|
29146
29225
|
resolveTargetPath(paths.hooks),
|
|
29147
29226
|
"tangyr-managed.json"
|
|
29148
29227
|
);
|
|
@@ -29205,10 +29284,10 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
29205
29284
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
29206
29285
|
const sourceLabel = mcpSourceLabel(config);
|
|
29207
29286
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
29208
|
-
if (!
|
|
29287
|
+
if (!fs40.existsSync(source)) {
|
|
29209
29288
|
return skippedMissingSource3("mcp", source);
|
|
29210
29289
|
}
|
|
29211
|
-
const sourceMcpJson = JSON.parse(
|
|
29290
|
+
const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
|
|
29212
29291
|
const compiled = compileMcp(
|
|
29213
29292
|
sourceMcpJson,
|
|
29214
29293
|
"copilot",
|
|
@@ -29238,19 +29317,19 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
|
|
|
29238
29317
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29239
29318
|
return { component, status: "conflict", path: destination };
|
|
29240
29319
|
}
|
|
29241
|
-
ensureDir(
|
|
29320
|
+
ensureDir(path40.dirname(destination));
|
|
29242
29321
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29243
29322
|
if (clearedLink !== null) {
|
|
29244
29323
|
logger.verbose(
|
|
29245
29324
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29246
29325
|
);
|
|
29247
29326
|
}
|
|
29248
|
-
|
|
29327
|
+
fs40.writeFileSync(destination, content);
|
|
29249
29328
|
return { component, status: "success", path: destination };
|
|
29250
29329
|
}
|
|
29251
29330
|
function isCompiledCurrent2(destination, expectedContent, expectedHash) {
|
|
29252
29331
|
try {
|
|
29253
|
-
const current =
|
|
29332
|
+
const current = fs40.readFileSync(destination, "utf8");
|
|
29254
29333
|
const marker = extractProvenanceMarker(current);
|
|
29255
29334
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "copilot" && current === expectedContent : current === expectedContent;
|
|
29256
29335
|
} catch {
|
|
@@ -29272,13 +29351,13 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
|
|
|
29272
29351
|
if (manifest && scopePath) {
|
|
29273
29352
|
backupFile(destination, manifest, scopePath);
|
|
29274
29353
|
writeManifest(scopePath, manifest);
|
|
29275
|
-
|
|
29354
|
+
fs40.rmSync(destination, { recursive: true, force: true });
|
|
29276
29355
|
} else {
|
|
29277
|
-
|
|
29356
|
+
fs40.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
29278
29357
|
}
|
|
29279
29358
|
return true;
|
|
29280
29359
|
}
|
|
29281
|
-
|
|
29360
|
+
fs40.rmSync(destination, { recursive: true, force: true });
|
|
29282
29361
|
return true;
|
|
29283
29362
|
}
|
|
29284
29363
|
function shouldSkipComponent3(options, component) {
|
|
@@ -29287,12 +29366,12 @@ function shouldSkipComponent3(options, component) {
|
|
|
29287
29366
|
function cleanupLegacyAgents(paths, options, logger) {
|
|
29288
29367
|
const currentAgentsRoot = resolveTargetPath(paths.agents);
|
|
29289
29368
|
const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
|
|
29290
|
-
if (
|
|
29369
|
+
if (path40.resolve(currentAgentsRoot) === path40.resolve(legacyAgentsRoot)) {
|
|
29291
29370
|
return [];
|
|
29292
29371
|
}
|
|
29293
29372
|
const outcomes = [];
|
|
29294
29373
|
for (const filePath of ts(
|
|
29295
|
-
|
|
29374
|
+
path40.join(legacyAgentsRoot, "*.agent.md")
|
|
29296
29375
|
).sort()) {
|
|
29297
29376
|
if (!isCopilotManagedCompiledFile(filePath)) {
|
|
29298
29377
|
continue;
|
|
@@ -29302,14 +29381,14 @@ function cleanupLegacyAgents(paths, options, logger) {
|
|
|
29302
29381
|
outcomes.push({ component: "agents", status: "dry-run", path: filePath });
|
|
29303
29382
|
continue;
|
|
29304
29383
|
}
|
|
29305
|
-
|
|
29384
|
+
fs40.rmSync(filePath, { force: true });
|
|
29306
29385
|
outcomes.push({ component: "agents", status: "success", path: filePath });
|
|
29307
29386
|
}
|
|
29308
29387
|
return outcomes;
|
|
29309
29388
|
}
|
|
29310
29389
|
function isCopilotManagedCompiledFile(filePath) {
|
|
29311
29390
|
try {
|
|
29312
|
-
return extractProvenanceMarker(
|
|
29391
|
+
return extractProvenanceMarker(fs40.readFileSync(filePath, "utf8"))?.target === "copilot";
|
|
29313
29392
|
} catch {
|
|
29314
29393
|
return false;
|
|
29315
29394
|
}
|
|
@@ -29324,8 +29403,8 @@ function skippedMissingSource3(component, source) {
|
|
|
29324
29403
|
|
|
29325
29404
|
// src/adapters/cursor.ts
|
|
29326
29405
|
import crypto8 from "crypto";
|
|
29327
|
-
import
|
|
29328
|
-
import
|
|
29406
|
+
import fs41 from "fs";
|
|
29407
|
+
import path41 from "path";
|
|
29329
29408
|
function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29330
29409
|
const scope = options.scope ?? "global";
|
|
29331
29410
|
const profile = resolveTargetPaths({
|
|
@@ -29437,7 +29516,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
29437
29516
|
if (!shouldSkipComponent4(options, "hooks")) {
|
|
29438
29517
|
outcomes.push(
|
|
29439
29518
|
syncHookScriptsBridge({
|
|
29440
|
-
source:
|
|
29519
|
+
source: path41.resolve(sourceRoot, config.source.hooks),
|
|
29441
29520
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
29442
29521
|
config,
|
|
29443
29522
|
sourceRoot,
|
|
@@ -29502,7 +29581,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
|
|
|
29502
29581
|
const composed = composeCursorInstructions(config, sourceRoot, lossReport);
|
|
29503
29582
|
const marker = formatProvenanceMarker(
|
|
29504
29583
|
"markdown",
|
|
29505
|
-
|
|
29584
|
+
path41.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
29506
29585
|
hashString3(composed),
|
|
29507
29586
|
"cursor"
|
|
29508
29587
|
);
|
|
@@ -29528,7 +29607,7 @@ ${composed}
|
|
|
29528
29607
|
}
|
|
29529
29608
|
function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
29530
29609
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
29531
|
-
const baseContent =
|
|
29610
|
+
const baseContent = fs41.existsSync(source) ? fs41.readFileSync(source, "utf8").trim() : "";
|
|
29532
29611
|
const personaContent = extractPrimaryPersonaContent(
|
|
29533
29612
|
config,
|
|
29534
29613
|
sourceRoot,
|
|
@@ -29541,11 +29620,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
|
29541
29620
|
${personaContent}`.trim() : baseContent;
|
|
29542
29621
|
}
|
|
29543
29622
|
function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
29544
|
-
const agentsDir =
|
|
29545
|
-
if (!
|
|
29623
|
+
const agentsDir = path41.join(sourceRoot, config.source.agents);
|
|
29624
|
+
if (!fs41.existsSync(agentsDir)) {
|
|
29546
29625
|
return null;
|
|
29547
29626
|
}
|
|
29548
|
-
const agentFiles = ts(
|
|
29627
|
+
const agentFiles = ts(path41.join(agentsDir, "*.md")).sort();
|
|
29549
29628
|
if (agentFiles.length === 0) {
|
|
29550
29629
|
return null;
|
|
29551
29630
|
}
|
|
@@ -29568,7 +29647,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29568
29647
|
return null;
|
|
29569
29648
|
}
|
|
29570
29649
|
addLoss(lossReport, "cursor", "instructions", {
|
|
29571
|
-
source: `agents/${
|
|
29650
|
+
source: `agents/${path41.basename(primaryFile)}`,
|
|
29572
29651
|
fields: [
|
|
29573
29652
|
{
|
|
29574
29653
|
field: "persona",
|
|
@@ -29578,23 +29657,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29578
29657
|
"persona",
|
|
29579
29658
|
"instructions-shim"
|
|
29580
29659
|
),
|
|
29581
|
-
detail: `Primary persona from ${
|
|
29660
|
+
detail: `Primary persona from ${path41.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
|
|
29582
29661
|
}
|
|
29583
29662
|
]
|
|
29584
29663
|
});
|
|
29585
29664
|
return body.trim();
|
|
29586
29665
|
}
|
|
29587
29666
|
function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29588
|
-
const sourceAgentsRoot =
|
|
29589
|
-
if (!
|
|
29667
|
+
const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
|
|
29668
|
+
if (!fs41.existsSync(sourceAgentsRoot)) {
|
|
29590
29669
|
return [skippedMissingSource4("agents", sourceAgentsRoot)];
|
|
29591
29670
|
}
|
|
29592
|
-
const sourceAgents = ts(
|
|
29671
|
+
const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
|
|
29593
29672
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29594
29673
|
return sourceAgents.map((agentFile) => {
|
|
29595
|
-
const destination =
|
|
29674
|
+
const destination = path41.join(
|
|
29596
29675
|
agentsRoot,
|
|
29597
|
-
`${
|
|
29676
|
+
`${path41.basename(agentFile, ".md")}.md`
|
|
29598
29677
|
);
|
|
29599
29678
|
let compiled;
|
|
29600
29679
|
try {
|
|
@@ -29635,14 +29714,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29635
29714
|
});
|
|
29636
29715
|
}
|
|
29637
29716
|
function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
29638
|
-
const sourceRulesDir =
|
|
29639
|
-
if (!
|
|
29717
|
+
const sourceRulesDir = path41.join(sourceRoot, config.source.rules);
|
|
29718
|
+
if (!fs41.existsSync(sourceRulesDir)) {
|
|
29640
29719
|
return [skippedMissingSource4("rules", sourceRulesDir)];
|
|
29641
29720
|
}
|
|
29642
29721
|
const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
|
|
29643
29722
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
29644
29723
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
29645
|
-
const destination =
|
|
29724
|
+
const destination = path41.join(rulesDir, name);
|
|
29646
29725
|
if (options.dryRun) {
|
|
29647
29726
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
29648
29727
|
return {
|
|
@@ -29666,17 +29745,17 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
29666
29745
|
});
|
|
29667
29746
|
}
|
|
29668
29747
|
function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29669
|
-
const sourceCommandsRoot =
|
|
29670
|
-
if (!
|
|
29748
|
+
const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
|
|
29749
|
+
if (!fs41.existsSync(sourceCommandsRoot)) {
|
|
29671
29750
|
return [skippedMissingSource4("commands", sourceCommandsRoot)];
|
|
29672
29751
|
}
|
|
29673
|
-
const sourceCommands = ts(
|
|
29752
|
+
const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
|
|
29674
29753
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
29675
29754
|
return sourceCommands.map((commandFile) => {
|
|
29676
|
-
const baseName =
|
|
29677
|
-
const destination =
|
|
29678
|
-
const commandContent =
|
|
29679
|
-
const relativeSource = `commands/${
|
|
29755
|
+
const baseName = path41.basename(commandFile, ".md");
|
|
29756
|
+
const destination = path41.join(skillsRoot, baseName, "SKILL.md");
|
|
29757
|
+
const commandContent = fs41.readFileSync(commandFile, "utf8");
|
|
29758
|
+
const relativeSource = `commands/${path41.basename(commandFile)}`;
|
|
29680
29759
|
const marker = formatProvenanceMarker(
|
|
29681
29760
|
"markdown",
|
|
29682
29761
|
relativeSource,
|
|
@@ -29715,8 +29794,8 @@ ${commandContent.trim()}
|
|
|
29715
29794
|
});
|
|
29716
29795
|
}
|
|
29717
29796
|
function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
|
|
29718
|
-
const source =
|
|
29719
|
-
if (!
|
|
29797
|
+
const source = path41.resolve(sourceRoot, config.source.skills);
|
|
29798
|
+
if (!fs41.existsSync(source)) {
|
|
29720
29799
|
return skippedMissingSource4(component, source);
|
|
29721
29800
|
}
|
|
29722
29801
|
if (options.dryRun) {
|
|
@@ -29730,18 +29809,18 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
|
|
|
29730
29809
|
return { component, status: "skipped-current", path: destination };
|
|
29731
29810
|
}
|
|
29732
29811
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
29733
|
-
|
|
29812
|
+
fs41.unlinkSync(destination);
|
|
29734
29813
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
29735
29814
|
return { component, status: "conflict", path: destination };
|
|
29736
29815
|
} else if (artifactClass === "managed-symlink") {
|
|
29737
|
-
|
|
29816
|
+
fs41.unlinkSync(destination);
|
|
29738
29817
|
}
|
|
29739
|
-
ensureDir(
|
|
29818
|
+
ensureDir(path41.dirname(destination));
|
|
29740
29819
|
createRelativeSymlink(source, destination, "dir");
|
|
29741
29820
|
logger.verbose(`Skills: created shared skills symlink ${destination}`);
|
|
29742
29821
|
return { component, status: "success", path: destination };
|
|
29743
29822
|
}
|
|
29744
|
-
if (
|
|
29823
|
+
if (fs41.existsSync(destination)) {
|
|
29745
29824
|
return { component, status: "skipped-current", path: destination };
|
|
29746
29825
|
}
|
|
29747
29826
|
ensureDir(destination);
|
|
@@ -29782,18 +29861,18 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
29782
29861
|
}
|
|
29783
29862
|
const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
|
|
29784
29863
|
`;
|
|
29785
|
-
ensureDir(
|
|
29786
|
-
|
|
29864
|
+
ensureDir(path41.dirname(destination));
|
|
29865
|
+
fs41.writeFileSync(destination, hooksFileContent);
|
|
29787
29866
|
return { component: "hooks", status: "success", path: destination };
|
|
29788
29867
|
}
|
|
29789
29868
|
function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
|
|
29790
29869
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
29791
29870
|
const sourceLabel = mcpSourceLabel(config);
|
|
29792
29871
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
29793
|
-
if (!
|
|
29872
|
+
if (!fs41.existsSync(source)) {
|
|
29794
29873
|
return skippedMissingSource4("mcp", source);
|
|
29795
29874
|
}
|
|
29796
|
-
const sourceMcpJson = JSON.parse(
|
|
29875
|
+
const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
|
|
29797
29876
|
const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
|
|
29798
29877
|
if (options.dryRun) {
|
|
29799
29878
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -29846,13 +29925,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
|
|
|
29846
29925
|
);
|
|
29847
29926
|
}
|
|
29848
29927
|
function syncProviderPin(config, sourceRoot, lossReport) {
|
|
29849
|
-
const agentsDir =
|
|
29850
|
-
if (!
|
|
29851
|
-
for (const agentFile of ts(
|
|
29928
|
+
const agentsDir = path41.join(sourceRoot, config.source.agents);
|
|
29929
|
+
if (!fs41.existsSync(agentsDir)) return;
|
|
29930
|
+
for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
|
|
29852
29931
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
29853
29932
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
29854
29933
|
if (hasCustomProvider) {
|
|
29855
|
-
const relativeSource = `agents/${
|
|
29934
|
+
const relativeSource = `agents/${path41.basename(agentFile)}`;
|
|
29856
29935
|
addLoss(lossReport, "cursor", "agents", {
|
|
29857
29936
|
source: relativeSource,
|
|
29858
29937
|
fields: [
|
|
@@ -29864,7 +29943,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
|
|
|
29864
29943
|
"provider",
|
|
29865
29944
|
"provider-not-representable"
|
|
29866
29945
|
),
|
|
29867
|
-
detail: `${
|
|
29946
|
+
detail: `${path41.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
29868
29947
|
}
|
|
29869
29948
|
]
|
|
29870
29949
|
});
|
|
@@ -29879,14 +29958,14 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
|
|
|
29879
29958
|
if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
29880
29959
|
return { component, status: "conflict", path: destination };
|
|
29881
29960
|
}
|
|
29882
|
-
ensureDir(
|
|
29961
|
+
ensureDir(path41.dirname(destination));
|
|
29883
29962
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29884
29963
|
if (clearedLink !== null) {
|
|
29885
29964
|
logger.verbose(
|
|
29886
29965
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29887
29966
|
);
|
|
29888
29967
|
}
|
|
29889
|
-
|
|
29968
|
+
fs41.writeFileSync(destination, content);
|
|
29890
29969
|
return { component, status: "success", path: destination };
|
|
29891
29970
|
}
|
|
29892
29971
|
function handleConflict4(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -29904,18 +29983,18 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
|
|
|
29904
29983
|
if (manifest && scopePath) {
|
|
29905
29984
|
backupFile(destination, manifest, scopePath);
|
|
29906
29985
|
writeManifest(scopePath, manifest);
|
|
29907
|
-
|
|
29986
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
29908
29987
|
} else {
|
|
29909
|
-
|
|
29988
|
+
fs41.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
29910
29989
|
}
|
|
29911
29990
|
return true;
|
|
29912
29991
|
}
|
|
29913
|
-
|
|
29992
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
29914
29993
|
return true;
|
|
29915
29994
|
}
|
|
29916
29995
|
function isCompiledCurrent3(destination, expectedContent, expectedHash) {
|
|
29917
29996
|
try {
|
|
29918
|
-
const current =
|
|
29997
|
+
const current = fs41.readFileSync(destination, "utf8");
|
|
29919
29998
|
const marker = extractProvenanceMarker(current);
|
|
29920
29999
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cursor" && current === expectedContent : current === expectedContent;
|
|
29921
30000
|
} catch {
|
|
@@ -29934,7 +30013,7 @@ function shouldSkipComponent4(options, component) {
|
|
|
29934
30013
|
}
|
|
29935
30014
|
function isSymlinkTo5(linkPath, source) {
|
|
29936
30015
|
try {
|
|
29937
|
-
return
|
|
30016
|
+
return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
|
|
29938
30017
|
} catch {
|
|
29939
30018
|
return false;
|
|
29940
30019
|
}
|
|
@@ -29945,8 +30024,8 @@ function hashString3(value) {
|
|
|
29945
30024
|
|
|
29946
30025
|
// src/adapters/cline.ts
|
|
29947
30026
|
import crypto9 from "crypto";
|
|
29948
|
-
import
|
|
29949
|
-
import
|
|
30027
|
+
import fs42 from "fs";
|
|
30028
|
+
import path42 from "path";
|
|
29950
30029
|
function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29951
30030
|
const scope = options.scope ?? "global";
|
|
29952
30031
|
const profile = resolveTargetPaths({
|
|
@@ -30059,7 +30138,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
30059
30138
|
function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
|
|
30060
30139
|
if (scope === "global" || paths.instructions === null) {
|
|
30061
30140
|
addLoss(lossReport, "cline", "instructions", {
|
|
30062
|
-
source:
|
|
30141
|
+
source: path42.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30063
30142
|
fields: [
|
|
30064
30143
|
{
|
|
30065
30144
|
field: "instructions",
|
|
@@ -30081,10 +30160,10 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
|
|
|
30081
30160
|
}
|
|
30082
30161
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30083
30162
|
const destination = resolveTargetPath(paths.instructions);
|
|
30084
|
-
const baseContent =
|
|
30163
|
+
const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
|
|
30085
30164
|
const marker = formatProvenanceMarker(
|
|
30086
30165
|
"markdown",
|
|
30087
|
-
|
|
30166
|
+
path42.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30088
30167
|
hashString4(baseContent),
|
|
30089
30168
|
"cline"
|
|
30090
30169
|
);
|
|
@@ -30109,11 +30188,11 @@ ${baseContent}
|
|
|
30109
30188
|
);
|
|
30110
30189
|
}
|
|
30111
30190
|
function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
|
|
30112
|
-
const sourceAgentsRoot =
|
|
30113
|
-
if (!
|
|
30191
|
+
const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
|
|
30192
|
+
if (!fs42.existsSync(sourceAgentsRoot)) {
|
|
30114
30193
|
return [skippedMissingSource5("agents", sourceAgentsRoot)];
|
|
30115
30194
|
}
|
|
30116
|
-
const sourceAgents = ts(
|
|
30195
|
+
const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
|
|
30117
30196
|
return sourceAgents.map((agentFile) => {
|
|
30118
30197
|
compileAgent(agentFile, "cline", mappings, extensions, lossReport);
|
|
30119
30198
|
if (options.dryRun) {
|
|
@@ -30129,14 +30208,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
30129
30208
|
});
|
|
30130
30209
|
}
|
|
30131
30210
|
function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
30132
|
-
const sourceRulesDir =
|
|
30133
|
-
if (!
|
|
30211
|
+
const sourceRulesDir = path42.join(sourceRoot, config.source.rules);
|
|
30212
|
+
if (!fs42.existsSync(sourceRulesDir)) {
|
|
30134
30213
|
return [skippedMissingSource5("rules", sourceRulesDir)];
|
|
30135
30214
|
}
|
|
30136
30215
|
const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
|
|
30137
30216
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
30138
30217
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
30139
|
-
const destination =
|
|
30218
|
+
const destination = path42.join(rulesDir, name);
|
|
30140
30219
|
if (options.dryRun) {
|
|
30141
30220
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
30142
30221
|
return {
|
|
@@ -30160,17 +30239,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
30160
30239
|
});
|
|
30161
30240
|
}
|
|
30162
30241
|
function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30163
|
-
const sourceCommandsRoot =
|
|
30164
|
-
if (!
|
|
30242
|
+
const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
|
|
30243
|
+
if (!fs42.existsSync(sourceCommandsRoot)) {
|
|
30165
30244
|
return [skippedMissingSource5("commands", sourceCommandsRoot)];
|
|
30166
30245
|
}
|
|
30167
|
-
const sourceCommands = ts(
|
|
30246
|
+
const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
|
|
30168
30247
|
const workflowsRoot = resolveTargetPath(paths.workflows);
|
|
30169
30248
|
return sourceCommands.map((commandFile) => {
|
|
30170
|
-
const baseName =
|
|
30171
|
-
const destination =
|
|
30172
|
-
const commandContent =
|
|
30173
|
-
const relativeSource = `commands/${
|
|
30249
|
+
const baseName = path42.basename(commandFile);
|
|
30250
|
+
const destination = path42.join(workflowsRoot, baseName);
|
|
30251
|
+
const commandContent = fs42.readFileSync(commandFile, "utf8");
|
|
30252
|
+
const relativeSource = `commands/${path42.basename(commandFile)}`;
|
|
30174
30253
|
const marker = formatProvenanceMarker(
|
|
30175
30254
|
"markdown",
|
|
30176
30255
|
relativeSource,
|
|
@@ -30205,9 +30284,9 @@ ${commandContent.trim()}
|
|
|
30205
30284
|
});
|
|
30206
30285
|
}
|
|
30207
30286
|
function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30208
|
-
const source =
|
|
30287
|
+
const source = path42.resolve(sourceRoot, config.source.skills);
|
|
30209
30288
|
const destination = resolveTargetPath(paths.skills);
|
|
30210
|
-
if (!
|
|
30289
|
+
if (!fs42.existsSync(source)) {
|
|
30211
30290
|
return skippedMissingSource5("skills", source);
|
|
30212
30291
|
}
|
|
30213
30292
|
if (options.dryRun) {
|
|
@@ -30231,15 +30310,15 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
30231
30310
|
// unsynced.
|
|
30232
30311
|
artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)
|
|
30233
30312
|
) {
|
|
30234
|
-
|
|
30313
|
+
fs42.unlinkSync(destination);
|
|
30235
30314
|
} else if (artifactClass === "unmanaged-conflict") {
|
|
30236
30315
|
if (!handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
30237
30316
|
return { component: "skills", status: "conflict", path: destination };
|
|
30238
30317
|
}
|
|
30239
30318
|
} else if (artifactClass === "managed-symlink") {
|
|
30240
|
-
|
|
30319
|
+
fs42.unlinkSync(destination);
|
|
30241
30320
|
}
|
|
30242
|
-
ensureDir(
|
|
30321
|
+
ensureDir(path42.dirname(destination));
|
|
30243
30322
|
createRelativeSymlink(source, destination, "dir");
|
|
30244
30323
|
logger.verbose(`Skills: created Cline skills symlink ${destination}`);
|
|
30245
30324
|
return { component: "skills", status: "success", path: destination };
|
|
@@ -30263,10 +30342,10 @@ function syncMcp5(config, sourceRoot, paths, options, lossReport, logger, manife
|
|
|
30263
30342
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30264
30343
|
const sourceLabel = mcpSourceLabel(config);
|
|
30265
30344
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
30266
|
-
if (!
|
|
30345
|
+
if (!fs42.existsSync(source)) {
|
|
30267
30346
|
return skippedMissingSource5("mcp", source);
|
|
30268
30347
|
}
|
|
30269
|
-
const sourceMcpJson = JSON.parse(
|
|
30348
|
+
const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
|
|
30270
30349
|
const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
|
|
30271
30350
|
if (options.dryRun) {
|
|
30272
30351
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -30309,11 +30388,11 @@ function syncSettings2(lossReport) {
|
|
|
30309
30388
|
};
|
|
30310
30389
|
}
|
|
30311
30390
|
function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
30312
|
-
const agentsDir =
|
|
30313
|
-
if (!
|
|
30314
|
-
for (const agentFile of ts(
|
|
30391
|
+
const agentsDir = path42.join(sourceRoot, config.source.agents);
|
|
30392
|
+
if (!fs42.existsSync(agentsDir)) return;
|
|
30393
|
+
for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
|
|
30315
30394
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
30316
|
-
const relativeSource = `agents/${
|
|
30395
|
+
const relativeSource = `agents/${path42.basename(agentFile)}`;
|
|
30317
30396
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
30318
30397
|
if (hasCustomProvider) {
|
|
30319
30398
|
addLoss(lossReport, "cline", "agents", {
|
|
@@ -30327,7 +30406,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30327
30406
|
"provider",
|
|
30328
30407
|
"provider-not-representable"
|
|
30329
30408
|
),
|
|
30330
|
-
detail: `${
|
|
30409
|
+
detail: `${path42.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
|
|
30331
30410
|
}
|
|
30332
30411
|
]
|
|
30333
30412
|
});
|
|
@@ -30345,7 +30424,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30345
30424
|
"model",
|
|
30346
30425
|
"model-not-representable"
|
|
30347
30426
|
),
|
|
30348
|
-
detail: `${
|
|
30427
|
+
detail: `${path42.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
|
|
30349
30428
|
}
|
|
30350
30429
|
]
|
|
30351
30430
|
});
|
|
@@ -30360,14 +30439,14 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
|
|
|
30360
30439
|
if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
30361
30440
|
return { component, status: "conflict", path: destination };
|
|
30362
30441
|
}
|
|
30363
|
-
ensureDir(
|
|
30442
|
+
ensureDir(path42.dirname(destination));
|
|
30364
30443
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30365
30444
|
if (clearedLink !== null) {
|
|
30366
30445
|
logger.verbose(
|
|
30367
30446
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30368
30447
|
);
|
|
30369
30448
|
}
|
|
30370
|
-
|
|
30449
|
+
fs42.writeFileSync(destination, content);
|
|
30371
30450
|
return { component, status: "success", path: destination };
|
|
30372
30451
|
}
|
|
30373
30452
|
function handleConflict5(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30385,18 +30464,18 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
|
|
|
30385
30464
|
if (manifest && scopePath) {
|
|
30386
30465
|
backupFile(destination, manifest, scopePath);
|
|
30387
30466
|
writeManifest(scopePath, manifest);
|
|
30388
|
-
|
|
30467
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
30389
30468
|
} else {
|
|
30390
|
-
|
|
30469
|
+
fs42.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
30391
30470
|
}
|
|
30392
30471
|
return true;
|
|
30393
30472
|
}
|
|
30394
|
-
|
|
30473
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
30395
30474
|
return true;
|
|
30396
30475
|
}
|
|
30397
30476
|
function isCompiledCurrent4(destination, expectedContent, expectedHash) {
|
|
30398
30477
|
try {
|
|
30399
|
-
const current =
|
|
30478
|
+
const current = fs42.readFileSync(destination, "utf8");
|
|
30400
30479
|
const marker = extractProvenanceMarker(current);
|
|
30401
30480
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cline" && current === expectedContent : current === expectedContent;
|
|
30402
30481
|
} catch {
|
|
@@ -30415,7 +30494,7 @@ function shouldSkipComponent5(options, component) {
|
|
|
30415
30494
|
}
|
|
30416
30495
|
function isSymlinkTo6(linkPath, source) {
|
|
30417
30496
|
try {
|
|
30418
|
-
return
|
|
30497
|
+
return fs42.realpathSync(linkPath) === fs42.realpathSync(source);
|
|
30419
30498
|
} catch {
|
|
30420
30499
|
return false;
|
|
30421
30500
|
}
|
|
@@ -30426,9 +30505,9 @@ function hashString4(value) {
|
|
|
30426
30505
|
|
|
30427
30506
|
// src/adapters/opencode.ts
|
|
30428
30507
|
import crypto10 from "crypto";
|
|
30429
|
-
import
|
|
30508
|
+
import fs43 from "fs";
|
|
30430
30509
|
import os6 from "os";
|
|
30431
|
-
import
|
|
30510
|
+
import path43 from "path";
|
|
30432
30511
|
var import_yaml11 = __toESM(require_dist(), 1);
|
|
30433
30512
|
function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30434
30513
|
const scope = options.scope ?? "global";
|
|
@@ -30446,7 +30525,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30446
30525
|
config_doc: profile.config_doc
|
|
30447
30526
|
};
|
|
30448
30527
|
const rules = compileRules(
|
|
30449
|
-
|
|
30528
|
+
path43.join(sourceRoot, config.source.rules),
|
|
30450
30529
|
"opencode",
|
|
30451
30530
|
mappings,
|
|
30452
30531
|
lossReport
|
|
@@ -30550,14 +30629,14 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30550
30629
|
function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
30551
30630
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30552
30631
|
const destination = resolveTargetPath(paths.instructions);
|
|
30553
|
-
const baseContent =
|
|
30632
|
+
const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
|
|
30554
30633
|
const composed = agentsAppendix ? `${baseContent}
|
|
30555
30634
|
|
|
30556
30635
|
--- tangyr managed rules ---
|
|
30557
30636
|
${agentsAppendix}`.trim() : baseContent;
|
|
30558
30637
|
const marker = formatProvenanceMarker(
|
|
30559
30638
|
"markdown",
|
|
30560
|
-
|
|
30639
|
+
path43.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30561
30640
|
hashString5(composed),
|
|
30562
30641
|
"opencode"
|
|
30563
30642
|
);
|
|
@@ -30584,16 +30663,16 @@ ${composed}
|
|
|
30584
30663
|
);
|
|
30585
30664
|
}
|
|
30586
30665
|
function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30587
|
-
const sourceAgentsRoot =
|
|
30588
|
-
if (!
|
|
30666
|
+
const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
|
|
30667
|
+
if (!fs43.existsSync(sourceAgentsRoot)) {
|
|
30589
30668
|
return [skippedMissingSource6("agents", sourceAgentsRoot)];
|
|
30590
30669
|
}
|
|
30591
|
-
const sourceAgents = ts(
|
|
30670
|
+
const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
|
|
30592
30671
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
30593
30672
|
return sourceAgents.map((agentFile) => {
|
|
30594
|
-
const destination =
|
|
30673
|
+
const destination = path43.join(
|
|
30595
30674
|
agentsRoot,
|
|
30596
|
-
`${
|
|
30675
|
+
`${path43.basename(agentFile, ".md")}.md`
|
|
30597
30676
|
);
|
|
30598
30677
|
let compiled;
|
|
30599
30678
|
try {
|
|
@@ -30657,11 +30736,11 @@ function applyProviderModelBinding(compiled, mappings) {
|
|
|
30657
30736
|
return `${before}${(0, import_yaml11.stringify)(fields).trim()}${after}`;
|
|
30658
30737
|
}
|
|
30659
30738
|
function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30660
|
-
const sourceCommandsRoot =
|
|
30661
|
-
if (!
|
|
30739
|
+
const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
|
|
30740
|
+
if (!fs43.existsSync(sourceCommandsRoot)) {
|
|
30662
30741
|
return [skippedMissingSource6("commands", sourceCommandsRoot)];
|
|
30663
30742
|
}
|
|
30664
|
-
const sourceCommands = ts(
|
|
30743
|
+
const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
|
|
30665
30744
|
const commandsRoot = resolveTargetPath(paths.commands);
|
|
30666
30745
|
return sourceCommands.map((commandFile) => {
|
|
30667
30746
|
const { data, body } = parseCommandFile(commandFile);
|
|
@@ -30675,7 +30754,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
|
|
|
30675
30754
|
if (typeof data.model === "string") {
|
|
30676
30755
|
frontmatter.model = data.model;
|
|
30677
30756
|
}
|
|
30678
|
-
const relativeSource = `commands/${
|
|
30757
|
+
const relativeSource = `commands/${path43.basename(commandFile)}`;
|
|
30679
30758
|
const marker = formatProvenanceMarker(
|
|
30680
30759
|
"markdown",
|
|
30681
30760
|
relativeSource,
|
|
@@ -30691,9 +30770,9 @@ ${body.trimEnd()}
|
|
|
30691
30770
|
` : `${marker}
|
|
30692
30771
|
${body.trimEnd()}
|
|
30693
30772
|
`;
|
|
30694
|
-
const destination =
|
|
30773
|
+
const destination = path43.join(
|
|
30695
30774
|
commandsRoot,
|
|
30696
|
-
`${
|
|
30775
|
+
`${path43.basename(commandFile, ".md")}.md`
|
|
30697
30776
|
);
|
|
30698
30777
|
if (options.dryRun) {
|
|
30699
30778
|
logger.info(
|
|
@@ -30720,8 +30799,8 @@ ${body.trimEnd()}
|
|
|
30720
30799
|
});
|
|
30721
30800
|
}
|
|
30722
30801
|
function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
|
|
30723
|
-
const source =
|
|
30724
|
-
if (!
|
|
30802
|
+
const source = path43.resolve(sourceRoot, config.source.skills);
|
|
30803
|
+
if (!fs43.existsSync(source)) {
|
|
30725
30804
|
return skippedMissingSource6(component, source);
|
|
30726
30805
|
}
|
|
30727
30806
|
if (options.dryRun) {
|
|
@@ -30733,13 +30812,13 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
|
|
|
30733
30812
|
return { component, status: "skipped-current", path: destination };
|
|
30734
30813
|
}
|
|
30735
30814
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
30736
|
-
|
|
30815
|
+
fs43.unlinkSync(destination);
|
|
30737
30816
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
30738
30817
|
return { component, status: "conflict", path: destination };
|
|
30739
30818
|
} else if (artifactClass === "managed-symlink") {
|
|
30740
|
-
|
|
30819
|
+
fs43.unlinkSync(destination);
|
|
30741
30820
|
}
|
|
30742
|
-
ensureDir(
|
|
30821
|
+
ensureDir(path43.dirname(destination));
|
|
30743
30822
|
createRelativeSymlink(source, destination, "dir");
|
|
30744
30823
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
30745
30824
|
return { component, status: "success", path: destination };
|
|
@@ -30748,13 +30827,13 @@ function syncMcp6(config, sourceRoot, paths, mappings, options, lossReport, logg
|
|
|
30748
30827
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30749
30828
|
const sourceLabel = mcpSourceLabel(config);
|
|
30750
30829
|
const destination = resolveTargetPath(paths.config_doc);
|
|
30751
|
-
if (!
|
|
30830
|
+
if (!fs43.existsSync(source)) {
|
|
30752
30831
|
if (!options.dryRun) {
|
|
30753
30832
|
syncConfigDoc(paths, {}, lossReport, {}, mappings);
|
|
30754
30833
|
}
|
|
30755
30834
|
return skippedMissingSource6("mcp", source);
|
|
30756
30835
|
}
|
|
30757
|
-
const sourceMcpJson = JSON.parse(
|
|
30836
|
+
const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
|
|
30758
30837
|
const mcpJson = compileMcp(
|
|
30759
30838
|
sourceMcpJson,
|
|
30760
30839
|
"opencode",
|
|
@@ -30820,9 +30899,9 @@ function syncProviderBlock(mappings) {
|
|
|
30820
30899
|
function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
|
|
30821
30900
|
const destination = resolveTargetPath(paths.config_doc);
|
|
30822
30901
|
let existing = {};
|
|
30823
|
-
if (
|
|
30902
|
+
if (fs43.existsSync(destination)) {
|
|
30824
30903
|
try {
|
|
30825
|
-
existing = JSON.parse(
|
|
30904
|
+
existing = JSON.parse(fs43.readFileSync(destination, "utf8"));
|
|
30826
30905
|
} catch {
|
|
30827
30906
|
existing = {};
|
|
30828
30907
|
}
|
|
@@ -30847,8 +30926,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
|
|
|
30847
30926
|
};
|
|
30848
30927
|
}
|
|
30849
30928
|
}
|
|
30850
|
-
ensureDir(
|
|
30851
|
-
|
|
30929
|
+
ensureDir(path43.dirname(destination));
|
|
30930
|
+
fs43.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
30852
30931
|
`);
|
|
30853
30932
|
}
|
|
30854
30933
|
function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
|
|
@@ -30859,14 +30938,14 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
|
|
|
30859
30938
|
if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
30860
30939
|
return { component, status: "conflict", path: destination };
|
|
30861
30940
|
}
|
|
30862
|
-
ensureDir(
|
|
30941
|
+
ensureDir(path43.dirname(destination));
|
|
30863
30942
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30864
30943
|
if (clearedLink !== null) {
|
|
30865
30944
|
logger.verbose(
|
|
30866
30945
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30867
30946
|
);
|
|
30868
30947
|
}
|
|
30869
|
-
|
|
30948
|
+
fs43.writeFileSync(destination, content);
|
|
30870
30949
|
return { component, status: "success", path: destination };
|
|
30871
30950
|
}
|
|
30872
30951
|
function handleConflict6(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30884,18 +30963,18 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
|
|
|
30884
30963
|
if (manifest && scopePath) {
|
|
30885
30964
|
backupFile(destination, manifest, scopePath);
|
|
30886
30965
|
writeManifest(scopePath, manifest);
|
|
30887
|
-
|
|
30966
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30888
30967
|
} else {
|
|
30889
|
-
|
|
30968
|
+
fs43.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
30890
30969
|
}
|
|
30891
30970
|
return true;
|
|
30892
30971
|
}
|
|
30893
|
-
|
|
30972
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30894
30973
|
return true;
|
|
30895
30974
|
}
|
|
30896
30975
|
function isCompiledCurrent5(destination, expectedContent, expectedHash) {
|
|
30897
30976
|
try {
|
|
30898
|
-
const current =
|
|
30977
|
+
const current = fs43.readFileSync(destination, "utf8");
|
|
30899
30978
|
const marker = extractProvenanceMarker(current);
|
|
30900
30979
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "opencode" && current === expectedContent : current === expectedContent;
|
|
30901
30980
|
} catch {
|
|
@@ -30914,7 +30993,7 @@ function shouldSkipComponent6(options, component) {
|
|
|
30914
30993
|
}
|
|
30915
30994
|
function isSymlinkTo7(linkPath, source) {
|
|
30916
30995
|
try {
|
|
30917
|
-
return
|
|
30996
|
+
return fs43.realpathSync(linkPath) === fs43.realpathSync(source);
|
|
30918
30997
|
} catch {
|
|
30919
30998
|
return false;
|
|
30920
30999
|
}
|
|
@@ -30923,7 +31002,7 @@ function hashString5(value) {
|
|
|
30923
31002
|
return `sha256:${crypto10.createHash("sha256").update(value).digest("hex")}`;
|
|
30924
31003
|
}
|
|
30925
31004
|
function parseCommandFile(commandFile) {
|
|
30926
|
-
const content =
|
|
31005
|
+
const content = fs43.readFileSync(commandFile, "utf8");
|
|
30927
31006
|
if (!content.startsWith("---\n")) {
|
|
30928
31007
|
return { data: {}, body: content };
|
|
30929
31008
|
}
|
|
@@ -30943,7 +31022,7 @@ function parseCommandFile(commandFile) {
|
|
|
30943
31022
|
// src/commands/install.ts
|
|
30944
31023
|
function isBackupablePath(targetPath) {
|
|
30945
31024
|
try {
|
|
30946
|
-
const lstat =
|
|
31025
|
+
const lstat = fs44.lstatSync(targetPath);
|
|
30947
31026
|
return lstat.isSymbolicLink() || lstat.isFile() || lstat.isDirectory();
|
|
30948
31027
|
} catch {
|
|
30949
31028
|
return false;
|
|
@@ -30980,7 +31059,7 @@ async function runInstallCommand(options, logger) {
|
|
|
30980
31059
|
);
|
|
30981
31060
|
}
|
|
30982
31061
|
const kitName = resolvedKitName ?? config.kit;
|
|
30983
|
-
const kitPath = kitPathOverride ?? (options.kitPath ?
|
|
31062
|
+
const kitPath = kitPathOverride ?? (options.kitPath ? path44.resolve(options.kitPath) : config.kitPath);
|
|
30984
31063
|
if (!kitName && !kitPath) {
|
|
30985
31064
|
logger.error(
|
|
30986
31065
|
"No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
|
|
@@ -31085,8 +31164,8 @@ async function runInstallCommand(options, logger) {
|
|
|
31085
31164
|
config: options.config,
|
|
31086
31165
|
scope
|
|
31087
31166
|
});
|
|
31088
|
-
const skillsSource =
|
|
31089
|
-
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") &&
|
|
31167
|
+
const skillsSource = path44.resolve(kitInfo.path, config.source.skills);
|
|
31168
|
+
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path44.basename(f.path) === "skills";
|
|
31090
31169
|
const foreignSkillsSlots = new Set(
|
|
31091
31170
|
assessResult.findings.filter(
|
|
31092
31171
|
(f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
|
|
@@ -31124,7 +31203,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31124
31203
|
let instructionsLabel;
|
|
31125
31204
|
try {
|
|
31126
31205
|
const resolved = resolveInstructionsSource(kitInfo.path, config);
|
|
31127
|
-
instructionsLabel = resolved ?
|
|
31206
|
+
instructionsLabel = resolved ? path44.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
|
|
31128
31207
|
} catch (err) {
|
|
31129
31208
|
logger.error(
|
|
31130
31209
|
`[dry-run] ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -31152,7 +31231,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31152
31231
|
}
|
|
31153
31232
|
}
|
|
31154
31233
|
logger.info(
|
|
31155
|
-
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${
|
|
31234
|
+
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path44.join(scopePath, "manifest.json")}`
|
|
31156
31235
|
);
|
|
31157
31236
|
return;
|
|
31158
31237
|
}
|
|
@@ -31211,7 +31290,7 @@ ACCEPTED CONFLICTS (posture: ${posture}; ${replaceable.length} target(s)):`
|
|
|
31211
31290
|
logger.info(` - ${finding.path}`);
|
|
31212
31291
|
logger.info(` source: ${sources}`);
|
|
31213
31292
|
logger.info(
|
|
31214
|
-
` action: backup-and-replace${
|
|
31293
|
+
` action: backup-and-replace${fs44.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
|
|
31215
31294
|
);
|
|
31216
31295
|
logger.info(` backup: ${backupLocation}`);
|
|
31217
31296
|
continue;
|
|
@@ -31319,6 +31398,11 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
31319
31398
|
installLossReport
|
|
31320
31399
|
);
|
|
31321
31400
|
}
|
|
31401
|
+
reportContestedInstructions(
|
|
31402
|
+
instructionsByActiveTarget(tools, scope, projectRoot, mappings),
|
|
31403
|
+
(kitInfo.components.rules?.declared.length ?? 0) > 0,
|
|
31404
|
+
logger
|
|
31405
|
+
);
|
|
31322
31406
|
for (const [relativePath, sourcePath] of collectAllFiles(kitInfo, config)) {
|
|
31323
31407
|
addFileToManifest(manifest, {
|
|
31324
31408
|
relativePath,
|
|
@@ -31330,20 +31414,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
31330
31414
|
writeManifest(scopePath, manifest);
|
|
31331
31415
|
logger.info(`
|
|
31332
31416
|
Installation complete: ${installedCount} files installed.`);
|
|
31333
|
-
logger.info(`Manifest written to ${
|
|
31417
|
+
logger.info(`Manifest written to ${path44.join(scopePath, "manifest.json")}`);
|
|
31334
31418
|
logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
|
|
31335
31419
|
logger.info(`Scope: ${scope}`);
|
|
31336
31420
|
logger.info(`Tools: ${tools.join(", ")}`);
|
|
31337
31421
|
reportHookRejections(
|
|
31338
31422
|
installLossReport,
|
|
31339
31423
|
tools,
|
|
31340
|
-
|
|
31424
|
+
path44.resolve(kitInfo.path, "hooks"),
|
|
31341
31425
|
kitInfo.components.hooks.declared
|
|
31342
31426
|
);
|
|
31343
31427
|
const hooksConflict = reportHooksSourceConflict(
|
|
31344
31428
|
installLossReport,
|
|
31345
31429
|
tools,
|
|
31346
|
-
|
|
31430
|
+
path44.resolve(kitInfo.path, "hooks"),
|
|
31347
31431
|
kitInfo.components.hooks.declared
|
|
31348
31432
|
);
|
|
31349
31433
|
if (hooksConflict) {
|
|
@@ -31702,7 +31786,7 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
31702
31786
|
return 0;
|
|
31703
31787
|
}
|
|
31704
31788
|
try {
|
|
31705
|
-
const stat =
|
|
31789
|
+
const stat = fs44.lstatSync(destination);
|
|
31706
31790
|
if (stat.isFile() && !stat.isSymbolicLink()) {
|
|
31707
31791
|
logger.warn(
|
|
31708
31792
|
`${destination}: a regular file occupies the skills slot \u2014 skipping skills. Move or remove it, then re-run install.`
|
|
@@ -31730,17 +31814,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
31730
31814
|
manifest,
|
|
31731
31815
|
scopePath
|
|
31732
31816
|
);
|
|
31733
|
-
const skillsSource =
|
|
31817
|
+
const skillsSource = path44.resolve(kitInfo.path, config.source.skills);
|
|
31734
31818
|
let count = 0;
|
|
31735
31819
|
for (const outcome of outcomes) {
|
|
31736
31820
|
if (outcome.status !== "success" && outcome.status !== "skipped-current") {
|
|
31737
31821
|
continue;
|
|
31738
31822
|
}
|
|
31739
|
-
const skillName =
|
|
31823
|
+
const skillName = path44.basename(outcome.path);
|
|
31740
31824
|
addArtifactToManifest(manifest, {
|
|
31741
31825
|
relativePath: `claude-code/skills/${skillName}`,
|
|
31742
31826
|
path: outcome.path,
|
|
31743
|
-
hash: describeArtifactState(outcome.path) ?? `dir:${
|
|
31827
|
+
hash: describeArtifactState(outcome.path) ?? `dir:${path44.join(skillsSource, skillName)}`,
|
|
31744
31828
|
origin: "tangyr-managed"
|
|
31745
31829
|
});
|
|
31746
31830
|
count++;
|
|
@@ -31754,10 +31838,10 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
31754
31838
|
logger.verbose(` skipped (operator choice): ${placement.destination}`);
|
|
31755
31839
|
continue;
|
|
31756
31840
|
}
|
|
31757
|
-
const destDir =
|
|
31758
|
-
|
|
31841
|
+
const destDir = path44.dirname(placement.destination);
|
|
31842
|
+
fs44.mkdirSync(destDir, { recursive: true });
|
|
31759
31843
|
if (placement.type === "symlink") {
|
|
31760
|
-
if (
|
|
31844
|
+
if (fs44.existsSync(placement.destination) || isSymlink2(placement.destination)) {
|
|
31761
31845
|
removeManagedPath(placement.destination);
|
|
31762
31846
|
}
|
|
31763
31847
|
createRelativeSymlink(
|
|
@@ -31774,7 +31858,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
31774
31858
|
` symlink: ${placement.source} \u2192 ${placement.destination}`
|
|
31775
31859
|
);
|
|
31776
31860
|
} else {
|
|
31777
|
-
|
|
31861
|
+
fs44.copyFileSync(placement.source, placement.destination);
|
|
31778
31862
|
logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
|
|
31779
31863
|
}
|
|
31780
31864
|
addArtifactToManifest(manifest, {
|
|
@@ -32056,11 +32140,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32056
32140
|
if (outcome.path === mcpFile2) {
|
|
32057
32141
|
return "cline/mcp.json";
|
|
32058
32142
|
}
|
|
32059
|
-
if (outcome.path.startsWith(`${workflowsRoot}${
|
|
32060
|
-
return `cline/workflows/${
|
|
32143
|
+
if (outcome.path.startsWith(`${workflowsRoot}${path44.sep}`)) {
|
|
32144
|
+
return `cline/workflows/${path44.basename(outcome.path)}`;
|
|
32061
32145
|
}
|
|
32062
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32063
|
-
return `cline/rules/${
|
|
32146
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
|
|
32147
|
+
return `cline/rules/${path44.basename(outcome.path)}`;
|
|
32064
32148
|
}
|
|
32065
32149
|
return null;
|
|
32066
32150
|
}
|
|
@@ -32096,14 +32180,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32096
32180
|
if (outcome.path === permissionsFile) {
|
|
32097
32181
|
return "cursor/permissions.json";
|
|
32098
32182
|
}
|
|
32099
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32100
|
-
return `cursor/agents/${
|
|
32183
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
|
|
32184
|
+
return `cursor/agents/${path44.basename(outcome.path)}`;
|
|
32101
32185
|
}
|
|
32102
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32103
|
-
return `cursor/rules/${
|
|
32186
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
|
|
32187
|
+
return `cursor/rules/${path44.basename(outcome.path)}`;
|
|
32104
32188
|
}
|
|
32105
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
32106
|
-
const rel =
|
|
32189
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
|
|
32190
|
+
const rel = path44.relative(skillsRoot2, outcome.path);
|
|
32107
32191
|
return `cursor/skills/${rel}`;
|
|
32108
32192
|
}
|
|
32109
32193
|
return null;
|
|
@@ -32129,14 +32213,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32129
32213
|
if (outcome.path === skillsSharedRoot) {
|
|
32130
32214
|
return "opencode/skills_shared";
|
|
32131
32215
|
}
|
|
32132
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32133
|
-
return `opencode/agents/${
|
|
32216
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
|
|
32217
|
+
return `opencode/agents/${path44.basename(outcome.path)}`;
|
|
32134
32218
|
}
|
|
32135
|
-
if (outcome.path.startsWith(`${commandsRoot}${
|
|
32136
|
-
return `opencode/commands/${
|
|
32219
|
+
if (outcome.path.startsWith(`${commandsRoot}${path44.sep}`)) {
|
|
32220
|
+
return `opencode/commands/${path44.basename(outcome.path)}`;
|
|
32137
32221
|
}
|
|
32138
32222
|
if (outcome.path === configDocFile) {
|
|
32139
|
-
return `opencode/${
|
|
32223
|
+
return `opencode/${path44.basename(outcome.path)}`;
|
|
32140
32224
|
}
|
|
32141
32225
|
return null;
|
|
32142
32226
|
}
|
|
@@ -32153,26 +32237,26 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32153
32237
|
const hooksRoot = resolveTargetPath(copilot.hooks);
|
|
32154
32238
|
const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
|
|
32155
32239
|
const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
|
|
32156
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
32157
|
-
return `copilot/skills/${
|
|
32240
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
|
|
32241
|
+
return `copilot/skills/${path44.relative(skillsRoot2, outcome.path)}`;
|
|
32158
32242
|
}
|
|
32159
32243
|
if (outcome.path === skillsRoot2) {
|
|
32160
32244
|
return "copilot/skills";
|
|
32161
32245
|
}
|
|
32162
32246
|
if (instructionsMirror !== null && outcome.path === instructionsMirror) {
|
|
32163
|
-
return `copilot/${
|
|
32247
|
+
return `copilot/${path44.basename(outcome.path)}`;
|
|
32164
32248
|
}
|
|
32165
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32166
|
-
return `copilot/agents/${
|
|
32249
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
|
|
32250
|
+
return `copilot/agents/${path44.basename(outcome.path)}`;
|
|
32167
32251
|
}
|
|
32168
|
-
if (outcome.path.startsWith(`${promptsRoot}${
|
|
32169
|
-
return `copilot/prompts/${
|
|
32252
|
+
if (outcome.path.startsWith(`${promptsRoot}${path44.sep}`)) {
|
|
32253
|
+
return `copilot/prompts/${path44.basename(outcome.path)}`;
|
|
32170
32254
|
}
|
|
32171
|
-
if (outcome.path.startsWith(`${hooksRoot}${
|
|
32172
|
-
return `copilot/hooks/${
|
|
32255
|
+
if (outcome.path.startsWith(`${hooksRoot}${path44.sep}`)) {
|
|
32256
|
+
return `copilot/hooks/${path44.basename(outcome.path)}`;
|
|
32173
32257
|
}
|
|
32174
32258
|
if (outcome.path === mcpFile2) {
|
|
32175
|
-
return `copilot/${
|
|
32259
|
+
return `copilot/${path44.basename(outcome.path)}`;
|
|
32176
32260
|
}
|
|
32177
32261
|
return null;
|
|
32178
32262
|
}
|
|
@@ -32189,17 +32273,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32189
32273
|
if (outcome.path === skillsRoot) {
|
|
32190
32274
|
return "codex/skills";
|
|
32191
32275
|
}
|
|
32192
|
-
if (outcome.path.startsWith(`${agentsRoot}${
|
|
32193
|
-
return `codex/agents/${
|
|
32276
|
+
if (outcome.path.startsWith(`${agentsRoot}${path44.sep}`)) {
|
|
32277
|
+
return `codex/agents/${path44.basename(outcome.path)}`;
|
|
32194
32278
|
}
|
|
32195
|
-
if (outcome.path.startsWith(`${rulesRoot}${
|
|
32196
|
-
return `codex/rules/${
|
|
32279
|
+
if (outcome.path.startsWith(`${rulesRoot}${path44.sep}`)) {
|
|
32280
|
+
return `codex/rules/${path44.basename(outcome.path)}`;
|
|
32197
32281
|
}
|
|
32198
32282
|
if (outcome.path === hooksFile) {
|
|
32199
|
-
return `codex/${
|
|
32283
|
+
return `codex/${path44.basename(outcome.path)}`;
|
|
32200
32284
|
}
|
|
32201
32285
|
if (outcome.path === mcpFile) {
|
|
32202
|
-
return `codex/${
|
|
32286
|
+
return `codex/${path44.basename(outcome.path)}`;
|
|
32203
32287
|
}
|
|
32204
32288
|
return null;
|
|
32205
32289
|
}
|
|
@@ -32268,8 +32352,8 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
|
|
|
32268
32352
|
rules: resolvedPaths.rules
|
|
32269
32353
|
};
|
|
32270
32354
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32271
|
-
const componentDir =
|
|
32272
|
-
if (
|
|
32355
|
+
const componentDir = path44.join(kitInfo.path, component);
|
|
32356
|
+
if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
|
|
32273
32357
|
placements.push({
|
|
32274
32358
|
source: componentDir,
|
|
32275
32359
|
destination: targetPath,
|
|
@@ -32299,8 +32383,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
|
|
|
32299
32383
|
rules: profile.rules
|
|
32300
32384
|
};
|
|
32301
32385
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32302
|
-
const componentDir =
|
|
32303
|
-
if (
|
|
32386
|
+
const componentDir = path44.join(kitInfo.path, component);
|
|
32387
|
+
if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
|
|
32304
32388
|
placements.push({
|
|
32305
32389
|
source: componentDir,
|
|
32306
32390
|
destination: targetPath,
|
|
@@ -32316,7 +32400,7 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32316
32400
|
const files = /* @__PURE__ */ new Map();
|
|
32317
32401
|
const entrypoint = resolveInstructionsSource(kitInfo.path, config);
|
|
32318
32402
|
if (entrypoint) {
|
|
32319
|
-
files.set(
|
|
32403
|
+
files.set(path44.basename(entrypoint.file), entrypoint.file);
|
|
32320
32404
|
}
|
|
32321
32405
|
for (const [component, reconciliation] of Object.entries(
|
|
32322
32406
|
kitInfo.components
|
|
@@ -32325,22 +32409,22 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32325
32409
|
const missingSet = new Set(reconciliation.missing);
|
|
32326
32410
|
for (const entry of reconciliation.declared) {
|
|
32327
32411
|
if (missingSet.has(entry)) continue;
|
|
32328
|
-
const relPath = isSkills ?
|
|
32329
|
-
files.set(relPath,
|
|
32412
|
+
const relPath = isSkills ? path44.join(component, entry) : path44.join(component, `${entry}.md`);
|
|
32413
|
+
files.set(relPath, path44.join(kitInfo.path, relPath));
|
|
32330
32414
|
}
|
|
32331
32415
|
}
|
|
32332
32416
|
return files;
|
|
32333
32417
|
}
|
|
32334
32418
|
function readLinkTarget(p) {
|
|
32335
32419
|
try {
|
|
32336
|
-
return
|
|
32420
|
+
return fs44.readlinkSync(p);
|
|
32337
32421
|
} catch {
|
|
32338
32422
|
return null;
|
|
32339
32423
|
}
|
|
32340
32424
|
}
|
|
32341
32425
|
function isSymlink2(p) {
|
|
32342
32426
|
try {
|
|
32343
|
-
return
|
|
32427
|
+
return fs44.lstatSync(p).isSymbolicLink();
|
|
32344
32428
|
} catch {
|
|
32345
32429
|
return false;
|
|
32346
32430
|
}
|
|
@@ -32385,14 +32469,14 @@ async function runKitUpdateCommand(options, logger) {
|
|
|
32385
32469
|
}
|
|
32386
32470
|
|
|
32387
32471
|
// src/commands/list.ts
|
|
32388
|
-
import
|
|
32472
|
+
import path45 from "path";
|
|
32389
32473
|
function runListCommand(options, logger) {
|
|
32390
32474
|
let searchPaths = [];
|
|
32391
|
-
let directKitPath = options.kitPath ?
|
|
32475
|
+
let directKitPath = options.kitPath ? path45.resolve(options.kitPath) : void 0;
|
|
32392
32476
|
try {
|
|
32393
32477
|
const { config, configDir } = resolveConfig(options.config);
|
|
32394
32478
|
searchPaths = config.kitSearchPaths ?? [
|
|
32395
|
-
|
|
32479
|
+
path45.join(configDir, "operating-kits")
|
|
32396
32480
|
];
|
|
32397
32481
|
directKitPath = directKitPath ?? config.kitPath;
|
|
32398
32482
|
} catch (err) {
|
|
@@ -32467,7 +32551,7 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32467
32551
|
return kits;
|
|
32468
32552
|
}
|
|
32469
32553
|
const directKit = loadKit(directKitPath);
|
|
32470
|
-
if (kits.some((kit) =>
|
|
32554
|
+
if (kits.some((kit) => path45.resolve(kit.path) === directKit.path)) {
|
|
32471
32555
|
return kits;
|
|
32472
32556
|
}
|
|
32473
32557
|
return [...kits, directKit];
|
|
@@ -32475,8 +32559,8 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32475
32559
|
|
|
32476
32560
|
// src/commands/probe.ts
|
|
32477
32561
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
32478
|
-
import
|
|
32479
|
-
import
|
|
32562
|
+
import fs45 from "fs";
|
|
32563
|
+
import path46 from "path";
|
|
32480
32564
|
function runProbeCommand(options, logger) {
|
|
32481
32565
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32482
32566
|
options,
|
|
@@ -32504,7 +32588,7 @@ function runProbeCommand(options, logger) {
|
|
|
32504
32588
|
toProbeRow(
|
|
32505
32589
|
target,
|
|
32506
32590
|
key,
|
|
32507
|
-
scope === "project" ?
|
|
32591
|
+
scope === "project" ? path46.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
|
|
32508
32592
|
)
|
|
32509
32593
|
);
|
|
32510
32594
|
}
|
|
@@ -32526,7 +32610,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32526
32610
|
const resolved = resolveTargetPath(rawPath);
|
|
32527
32611
|
let accessible = false;
|
|
32528
32612
|
try {
|
|
32529
|
-
|
|
32613
|
+
fs45.accessSync(resolved);
|
|
32530
32614
|
accessible = true;
|
|
32531
32615
|
} catch {
|
|
32532
32616
|
accessible = false;
|
|
@@ -32535,7 +32619,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32535
32619
|
target,
|
|
32536
32620
|
key,
|
|
32537
32621
|
path: resolved,
|
|
32538
|
-
exists:
|
|
32622
|
+
exists: fs45.existsSync(resolved),
|
|
32539
32623
|
accessible
|
|
32540
32624
|
};
|
|
32541
32625
|
}
|
|
@@ -32553,7 +32637,7 @@ function codexRuntimeProbeRows() {
|
|
|
32553
32637
|
["binary_snap", "/snap/bin/codex"],
|
|
32554
32638
|
["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
|
|
32555
32639
|
]) {
|
|
32556
|
-
if (
|
|
32640
|
+
if (fs45.existsSync(candidatePath)) {
|
|
32557
32641
|
rows.push(toProbeRow("codex", key, candidatePath));
|
|
32558
32642
|
}
|
|
32559
32643
|
}
|
|
@@ -32569,8 +32653,8 @@ function commandProbeRows(target, key, command, args) {
|
|
|
32569
32653
|
|
|
32570
32654
|
// src/commands/status.ts
|
|
32571
32655
|
import crypto11 from "crypto";
|
|
32572
|
-
import
|
|
32573
|
-
import
|
|
32656
|
+
import fs46 from "fs";
|
|
32657
|
+
import path47 from "path";
|
|
32574
32658
|
function runStatusCommand(options, logger) {
|
|
32575
32659
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32576
32660
|
options,
|
|
@@ -32676,11 +32760,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
|
|
|
32676
32760
|
}
|
|
32677
32761
|
}
|
|
32678
32762
|
function sourceMarkdownFiles(sourceRoot, componentPath) {
|
|
32679
|
-
const root =
|
|
32680
|
-
if (!
|
|
32763
|
+
const root = path47.join(sourceRoot, componentPath);
|
|
32764
|
+
if (!fs46.existsSync(root)) {
|
|
32681
32765
|
return [];
|
|
32682
32766
|
}
|
|
32683
|
-
return ts(
|
|
32767
|
+
return ts(path47.join(root, "*.md")).sort();
|
|
32684
32768
|
}
|
|
32685
32769
|
function notRepresentableRow(component, detail) {
|
|
32686
32770
|
return {
|
|
@@ -32691,11 +32775,11 @@ function notRepresentableRow(component, detail) {
|
|
|
32691
32775
|
};
|
|
32692
32776
|
}
|
|
32693
32777
|
function readTargetJson(filePath) {
|
|
32694
|
-
if (!
|
|
32778
|
+
if (!fs46.existsSync(filePath)) {
|
|
32695
32779
|
return { kind: "missing" };
|
|
32696
32780
|
}
|
|
32697
32781
|
try {
|
|
32698
|
-
const parsed = JSON.parse(
|
|
32782
|
+
const parsed = JSON.parse(fs46.readFileSync(filePath, "utf8"));
|
|
32699
32783
|
return { kind: "object", value: isRecord(parsed) ? parsed : {} };
|
|
32700
32784
|
} catch (err) {
|
|
32701
32785
|
return {
|
|
@@ -32784,7 +32868,7 @@ function classifyInstructions(filePath, target, expectedHash, config, sourceRoot
|
|
|
32784
32868
|
}
|
|
32785
32869
|
function compiledMcpDocument(config, sourceRoot, target) {
|
|
32786
32870
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
32787
|
-
if (!
|
|
32871
|
+
if (!fs46.existsSync(source)) {
|
|
32788
32872
|
return {};
|
|
32789
32873
|
}
|
|
32790
32874
|
const compiled = compileMcp(
|
|
@@ -32797,7 +32881,7 @@ function compiledMcpDocument(config, sourceRoot, target) {
|
|
|
32797
32881
|
return isRecord(parsed) ? parsed : {};
|
|
32798
32882
|
}
|
|
32799
32883
|
function classifyMcpDocument(config, sourceRoot, target, filePath) {
|
|
32800
|
-
if (!
|
|
32884
|
+
if (!fs46.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
|
|
32801
32885
|
return notConfiguredRow("mcp", filePath);
|
|
32802
32886
|
}
|
|
32803
32887
|
return classifyJsonDocument(
|
|
@@ -32827,12 +32911,12 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
|
|
|
32827
32911
|
const rows = [];
|
|
32828
32912
|
const instructionsSource = instructionsSourcePath(sourceRoot, config);
|
|
32829
32913
|
const rules = compileRules(
|
|
32830
|
-
|
|
32914
|
+
path47.join(sourceRoot, config.source.rules),
|
|
32831
32915
|
"opencode",
|
|
32832
32916
|
mappings,
|
|
32833
32917
|
createLossReport()
|
|
32834
32918
|
);
|
|
32835
|
-
const baseInstructions =
|
|
32919
|
+
const baseInstructions = fs46.existsSync(instructionsSource) ? fs46.readFileSync(instructionsSource, "utf8").trim() : "";
|
|
32836
32920
|
const composedInstructions = rules.agentsAppendix ? `${baseInstructions}
|
|
32837
32921
|
|
|
32838
32922
|
--- tangyr managed rules ---
|
|
@@ -32854,10 +32938,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
32854
32938
|
)) {
|
|
32855
32939
|
rows.push(
|
|
32856
32940
|
classifyCompiledFile(
|
|
32857
|
-
`agents/${
|
|
32858
|
-
|
|
32941
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
32942
|
+
path47.join(
|
|
32859
32943
|
resolveTargetPath(paths.agents),
|
|
32860
|
-
`${
|
|
32944
|
+
`${path47.basename(agentFile, ".md")}.md`
|
|
32861
32945
|
),
|
|
32862
32946
|
"opencode",
|
|
32863
32947
|
computeSourceHash(agentFile),
|
|
@@ -32872,10 +32956,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
32872
32956
|
)) {
|
|
32873
32957
|
rows.push(
|
|
32874
32958
|
classifyCompiledFile(
|
|
32875
|
-
`commands/${
|
|
32876
|
-
|
|
32959
|
+
`commands/${path47.basename(commandFile, ".md")}`,
|
|
32960
|
+
path47.join(
|
|
32877
32961
|
resolveTargetPath(paths.commands),
|
|
32878
|
-
`${
|
|
32962
|
+
`${path47.basename(commandFile, ".md")}.md`
|
|
32879
32963
|
),
|
|
32880
32964
|
"opencode",
|
|
32881
32965
|
computeSourceHash(commandFile),
|
|
@@ -32957,10 +33041,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
32957
33041
|
)) {
|
|
32958
33042
|
rows.push(
|
|
32959
33043
|
classifyCompiledFile(
|
|
32960
|
-
`agents/${
|
|
32961
|
-
|
|
33044
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33045
|
+
path47.join(
|
|
32962
33046
|
resolveTargetPath(paths.agents),
|
|
32963
|
-
`${
|
|
33047
|
+
`${path47.basename(agentFile, ".md")}.md`
|
|
32964
33048
|
),
|
|
32965
33049
|
"cursor",
|
|
32966
33050
|
computeSourceHash(agentFile),
|
|
@@ -32977,7 +33061,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
32977
33061
|
rows.push(
|
|
32978
33062
|
classifyCompiledFile(
|
|
32979
33063
|
`rules/${ruleFile.name}`,
|
|
32980
|
-
|
|
33064
|
+
path47.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
32981
33065
|
"cursor",
|
|
32982
33066
|
void 0,
|
|
32983
33067
|
config,
|
|
@@ -32991,11 +33075,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
32991
33075
|
sourceRoot,
|
|
32992
33076
|
config.source.commands
|
|
32993
33077
|
)) {
|
|
32994
|
-
const baseName =
|
|
33078
|
+
const baseName = path47.basename(commandFile, ".md");
|
|
32995
33079
|
rows.push(
|
|
32996
33080
|
classifyCompiledFile(
|
|
32997
33081
|
`commands/${baseName}`,
|
|
32998
|
-
|
|
33082
|
+
path47.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
|
|
32999
33083
|
"cursor",
|
|
33000
33084
|
computeSourceHash(commandFile),
|
|
33001
33085
|
config,
|
|
@@ -33078,7 +33162,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33078
33162
|
rows.push(
|
|
33079
33163
|
classifyCompiledFile(
|
|
33080
33164
|
`rules/${ruleFile.name}`,
|
|
33081
|
-
|
|
33165
|
+
path47.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
33082
33166
|
"cline",
|
|
33083
33167
|
void 0,
|
|
33084
33168
|
config,
|
|
@@ -33094,10 +33178,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33094
33178
|
)) {
|
|
33095
33179
|
rows.push(
|
|
33096
33180
|
classifyCompiledFile(
|
|
33097
|
-
`commands/${
|
|
33098
|
-
|
|
33181
|
+
`commands/${path47.basename(commandFile, ".md")}`,
|
|
33182
|
+
path47.join(
|
|
33099
33183
|
resolveTargetPath(paths.workflows),
|
|
33100
|
-
|
|
33184
|
+
path47.basename(commandFile)
|
|
33101
33185
|
),
|
|
33102
33186
|
"cline",
|
|
33103
33187
|
computeSourceHash(commandFile),
|
|
@@ -33138,14 +33222,14 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33138
33222
|
return rows;
|
|
33139
33223
|
}
|
|
33140
33224
|
function compileRulesFiles(config, sourceRoot, target, mappings) {
|
|
33141
|
-
const rulesSource =
|
|
33142
|
-
if (!
|
|
33225
|
+
const rulesSource = path47.join(sourceRoot, config.source.rules);
|
|
33226
|
+
if (!fs46.existsSync(rulesSource)) {
|
|
33143
33227
|
return [];
|
|
33144
33228
|
}
|
|
33145
33229
|
return compileRules(rulesSource, target, mappings, createLossReport()).dotRulesFiles;
|
|
33146
33230
|
}
|
|
33147
33231
|
function classifyDirectoryPresence(component, dirPath) {
|
|
33148
|
-
const present =
|
|
33232
|
+
const present = fs46.existsSync(dirPath) && fs46.statSync(dirPath).isDirectory();
|
|
33149
33233
|
return {
|
|
33150
33234
|
component,
|
|
33151
33235
|
className: present ? "current" : "missing",
|
|
@@ -33164,7 +33248,7 @@ function slotsForScope2(scopeMap, scope, projectRoot) {
|
|
|
33164
33248
|
const root = projectRoot ?? process.cwd();
|
|
33165
33249
|
const resolved = {};
|
|
33166
33250
|
for (const [slot, value] of Object.entries(projectSlots)) {
|
|
33167
|
-
resolved[slot] = typeof value === "string" ?
|
|
33251
|
+
resolved[slot] = typeof value === "string" ? path47.resolve(root, value) : value;
|
|
33168
33252
|
}
|
|
33169
33253
|
return resolved;
|
|
33170
33254
|
}
|
|
@@ -33184,21 +33268,21 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33184
33268
|
rules: paths.rules
|
|
33185
33269
|
};
|
|
33186
33270
|
const rules = compileRules(
|
|
33187
|
-
|
|
33271
|
+
path47.join(sourceRoot, config.source.rules),
|
|
33188
33272
|
"codex",
|
|
33189
33273
|
mappings,
|
|
33190
33274
|
createLossReport()
|
|
33191
33275
|
);
|
|
33192
|
-
const instructionsSource =
|
|
33276
|
+
const instructionsSource = fs46.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
|
|
33193
33277
|
const composedInstructions = `${instructionsSource}
|
|
33194
33278
|
|
|
33195
33279
|
--- tangyr managed rules ---
|
|
33196
33280
|
${rules.agentsAppendix}`.trim();
|
|
33197
33281
|
const agentFiles = ts(
|
|
33198
|
-
|
|
33282
|
+
path47.join(sourceRoot, config.source.agents, "*.md")
|
|
33199
33283
|
).sort();
|
|
33200
33284
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33201
|
-
const mcpSource =
|
|
33285
|
+
const mcpSource = path47.join(sourceRoot, config.source.mcp);
|
|
33202
33286
|
const ruleRows = rules.dotRulesFiles.length === 0 ? [
|
|
33203
33287
|
{
|
|
33204
33288
|
component: "rules",
|
|
@@ -33209,7 +33293,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33209
33293
|
] : rules.dotRulesFiles.map(
|
|
33210
33294
|
(ruleFile) => classifyCompiledFile(
|
|
33211
33295
|
`rules/${ruleFile.name}`,
|
|
33212
|
-
|
|
33296
|
+
path47.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
|
|
33213
33297
|
"codex",
|
|
33214
33298
|
void 0,
|
|
33215
33299
|
config,
|
|
@@ -33227,10 +33311,10 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33227
33311
|
),
|
|
33228
33312
|
...agentFiles.map(
|
|
33229
33313
|
(agentFile) => classifyCompiledFile(
|
|
33230
|
-
`agents/${
|
|
33231
|
-
|
|
33314
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33315
|
+
path47.join(
|
|
33232
33316
|
resolveTargetPath(codexPaths.agents),
|
|
33233
|
-
`${
|
|
33317
|
+
`${path47.basename(agentFile, ".md")}.toml`
|
|
33234
33318
|
),
|
|
33235
33319
|
"codex",
|
|
33236
33320
|
computeSourceHash(agentFile),
|
|
@@ -33258,7 +33342,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33258
33342
|
"hooks",
|
|
33259
33343
|
resolveTargetPath(codexPaths.hooksSharedFile)
|
|
33260
33344
|
),
|
|
33261
|
-
|
|
33345
|
+
fs46.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33262
33346
|
"mcp",
|
|
33263
33347
|
resolveTargetPath(codexPaths.mcpSharedFile),
|
|
33264
33348
|
"codex",
|
|
@@ -33324,20 +33408,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33324
33408
|
mcpSharedFile: paths.mcp_shared_file
|
|
33325
33409
|
};
|
|
33326
33410
|
const agentFiles = ts(
|
|
33327
|
-
|
|
33411
|
+
path47.join(sourceRoot, config.source.agents, "*.md")
|
|
33328
33412
|
).sort();
|
|
33329
33413
|
const commandFiles = ts(
|
|
33330
|
-
|
|
33414
|
+
path47.join(sourceRoot, config.source.commands, "*.md")
|
|
33331
33415
|
).sort();
|
|
33332
33416
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33333
|
-
const mcpSource =
|
|
33417
|
+
const mcpSource = path47.join(sourceRoot, config.source.mcp);
|
|
33334
33418
|
return [
|
|
33335
33419
|
...agentFiles.map(
|
|
33336
33420
|
(agentFile) => classifyCompiledFile(
|
|
33337
|
-
`agents/${
|
|
33338
|
-
|
|
33421
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33422
|
+
path47.join(
|
|
33339
33423
|
resolveTargetPath(copilotPaths.agents),
|
|
33340
|
-
`${
|
|
33424
|
+
`${path47.basename(agentFile, ".md")}.agent.md`
|
|
33341
33425
|
),
|
|
33342
33426
|
"copilot",
|
|
33343
33427
|
computeSourceHash(agentFile),
|
|
@@ -33354,10 +33438,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33354
33438
|
),
|
|
33355
33439
|
...commandFiles.map(
|
|
33356
33440
|
(commandFile) => classifyCompiledFile(
|
|
33357
|
-
`commands/${
|
|
33358
|
-
|
|
33441
|
+
`commands/${path47.basename(commandFile, ".md")}`,
|
|
33442
|
+
path47.join(
|
|
33359
33443
|
resolveTargetPath(copilotPaths.prompts),
|
|
33360
|
-
`${
|
|
33444
|
+
`${path47.basename(commandFile, ".md")}.prompt.md`
|
|
33361
33445
|
),
|
|
33362
33446
|
"copilot",
|
|
33363
33447
|
computeSourceHash(commandFile),
|
|
@@ -33376,19 +33460,19 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33376
33460
|
sourceRoot
|
|
33377
33461
|
),
|
|
33378
33462
|
hooksPresent ? classifyCompiledHooksByProvenance(
|
|
33379
|
-
|
|
33463
|
+
path47.join(
|
|
33380
33464
|
resolveTargetPath(copilotPaths.hooks),
|
|
33381
33465
|
"tangyr-managed.json"
|
|
33382
33466
|
),
|
|
33383
33467
|
"copilot"
|
|
33384
33468
|
) : notConfiguredRow(
|
|
33385
33469
|
"hooks",
|
|
33386
|
-
|
|
33470
|
+
path47.join(
|
|
33387
33471
|
resolveTargetPath(copilotPaths.hooks),
|
|
33388
33472
|
"tangyr-managed.json"
|
|
33389
33473
|
)
|
|
33390
33474
|
),
|
|
33391
|
-
|
|
33475
|
+
fs46.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33392
33476
|
"mcp",
|
|
33393
33477
|
resolveTargetPath(copilotPaths.mcpSharedFile),
|
|
33394
33478
|
"copilot",
|
|
@@ -33408,7 +33492,7 @@ function notConfiguredRow(component, filePath) {
|
|
|
33408
33492
|
}
|
|
33409
33493
|
function classifyDirectArtifact(artifact, config, sourceRoot) {
|
|
33410
33494
|
const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
|
|
33411
|
-
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ?
|
|
33495
|
+
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path47.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
|
|
33412
33496
|
if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
|
|
33413
33497
|
const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
|
|
33414
33498
|
if (perSkill) {
|
|
@@ -33504,11 +33588,11 @@ function classifyClaudeCodeRows(sourceRoot, config, configDir, scope, projectRoo
|
|
|
33504
33588
|
function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
33505
33589
|
let entries;
|
|
33506
33590
|
try {
|
|
33507
|
-
const stat =
|
|
33591
|
+
const stat = fs46.lstatSync(slotPath);
|
|
33508
33592
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
33509
33593
|
return null;
|
|
33510
33594
|
}
|
|
33511
|
-
entries =
|
|
33595
|
+
entries = fs46.readdirSync(slotPath, { withFileTypes: true });
|
|
33512
33596
|
} catch {
|
|
33513
33597
|
return null;
|
|
33514
33598
|
}
|
|
@@ -33517,7 +33601,7 @@ function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
|
33517
33601
|
return null;
|
|
33518
33602
|
}
|
|
33519
33603
|
const ours = links.filter(
|
|
33520
|
-
(entry) => isOurSymlink(
|
|
33604
|
+
(entry) => isOurSymlink(path47.join(slotPath, entry.name), sourceRoot)
|
|
33521
33605
|
);
|
|
33522
33606
|
if (ours.length === 0) {
|
|
33523
33607
|
return null;
|
|
@@ -33529,9 +33613,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
|
|
|
33529
33613
|
classifyHooks(settingsPath),
|
|
33530
33614
|
classifySettings(
|
|
33531
33615
|
settingsPath,
|
|
33532
|
-
|
|
33616
|
+
path47.resolve(sourceRoot, config.source.settings)
|
|
33533
33617
|
),
|
|
33534
|
-
classifyMcp(claudeJsonPath,
|
|
33618
|
+
classifyMcp(claudeJsonPath, path47.resolve(sourceRoot, config.source.mcp))
|
|
33535
33619
|
];
|
|
33536
33620
|
}
|
|
33537
33621
|
function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
|
|
@@ -33628,14 +33712,14 @@ function classifyMcp(filePath, sourcePath) {
|
|
|
33628
33712
|
}
|
|
33629
33713
|
function isSymlinkCurrent(linkPath, sourcePath) {
|
|
33630
33714
|
try {
|
|
33631
|
-
return
|
|
33715
|
+
return fs46.realpathSync(linkPath) === fs46.realpathSync(sourcePath);
|
|
33632
33716
|
} catch {
|
|
33633
33717
|
return false;
|
|
33634
33718
|
}
|
|
33635
33719
|
}
|
|
33636
33720
|
function isCompiledCurrent6(filePath, sourcePath) {
|
|
33637
33721
|
try {
|
|
33638
|
-
const marker = extractProvenanceMarker(
|
|
33722
|
+
const marker = extractProvenanceMarker(fs46.readFileSync(filePath, "utf8"));
|
|
33639
33723
|
return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
|
|
33640
33724
|
} catch {
|
|
33641
33725
|
return false;
|
|
@@ -33665,7 +33749,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
|
|
|
33665
33749
|
}
|
|
33666
33750
|
function readCompiledContent(filePath) {
|
|
33667
33751
|
try {
|
|
33668
|
-
return
|
|
33752
|
+
return fs46.readFileSync(filePath, "utf8");
|
|
33669
33753
|
} catch {
|
|
33670
33754
|
return null;
|
|
33671
33755
|
}
|
|
@@ -33696,8 +33780,8 @@ function hashString6(value) {
|
|
|
33696
33780
|
}
|
|
33697
33781
|
|
|
33698
33782
|
// src/commands/sync.ts
|
|
33699
|
-
import
|
|
33700
|
-
import
|
|
33783
|
+
import fs47 from "fs";
|
|
33784
|
+
import path48 from "path";
|
|
33701
33785
|
|
|
33702
33786
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
33703
33787
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -34367,18 +34451,30 @@ async function runSyncCommand(options, logger) {
|
|
|
34367
34451
|
reportHookRejections(
|
|
34368
34452
|
lossReport,
|
|
34369
34453
|
targets,
|
|
34370
|
-
|
|
34454
|
+
path48.resolve(kitInfo.path, "hooks"),
|
|
34371
34455
|
kitInfo.components.hooks.declared
|
|
34372
34456
|
);
|
|
34373
34457
|
const hooksConflict = reportHooksSourceConflict(
|
|
34374
34458
|
lossReport,
|
|
34375
34459
|
targets,
|
|
34376
|
-
|
|
34460
|
+
path48.resolve(kitInfo.path, "hooks"),
|
|
34377
34461
|
kitInfo.components.hooks.declared
|
|
34378
34462
|
);
|
|
34379
34463
|
if (hooksConflict) {
|
|
34380
34464
|
logger.warn(hooksConflict);
|
|
34381
34465
|
}
|
|
34466
|
+
if (allMappings) {
|
|
34467
|
+
reportContestedInstructions(
|
|
34468
|
+
instructionsByActiveTarget(
|
|
34469
|
+
targets,
|
|
34470
|
+
syncOptions.scope,
|
|
34471
|
+
syncOptions.projectRoot,
|
|
34472
|
+
allMappings
|
|
34473
|
+
),
|
|
34474
|
+
kitInfo.components.rules.declared.length > 0,
|
|
34475
|
+
logger
|
|
34476
|
+
);
|
|
34477
|
+
}
|
|
34382
34478
|
}
|
|
34383
34479
|
writeLossReport(options.lossReport, lossReport);
|
|
34384
34480
|
printOutcomeTable(results);
|
|
@@ -34564,8 +34660,8 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
|
|
|
34564
34660
|
}
|
|
34565
34661
|
}
|
|
34566
34662
|
function resolveKitFilePath(kitPath, relativePath) {
|
|
34567
|
-
const fullPath =
|
|
34568
|
-
return
|
|
34663
|
+
const fullPath = path48.join(kitPath, relativePath);
|
|
34664
|
+
return fs47.existsSync(fullPath) ? fullPath : null;
|
|
34569
34665
|
}
|
|
34570
34666
|
function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
|
|
34571
34667
|
if (removedSourcePaths.length === 0 || !mappings) {
|
|
@@ -34628,9 +34724,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34628
34724
|
}
|
|
34629
34725
|
if (relativePath.startsWith("agents/")) {
|
|
34630
34726
|
removeManagedCompiledArtifact2(
|
|
34631
|
-
|
|
34727
|
+
path48.join(
|
|
34632
34728
|
resolveTargetPath(paths.agents ?? ""),
|
|
34633
|
-
`${
|
|
34729
|
+
`${path48.parse(relativePath).name}.agent.md`
|
|
34634
34730
|
),
|
|
34635
34731
|
"copilot",
|
|
34636
34732
|
relativePath,
|
|
@@ -34640,9 +34736,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34640
34736
|
}
|
|
34641
34737
|
if (relativePath.startsWith("commands/")) {
|
|
34642
34738
|
removeManagedCompiledArtifact2(
|
|
34643
|
-
|
|
34739
|
+
path48.join(
|
|
34644
34740
|
resolveTargetPath(paths.prompts ?? ""),
|
|
34645
|
-
`${
|
|
34741
|
+
`${path48.parse(relativePath).name}.prompt.md`
|
|
34646
34742
|
),
|
|
34647
34743
|
"copilot",
|
|
34648
34744
|
relativePath,
|
|
@@ -34652,7 +34748,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34652
34748
|
}
|
|
34653
34749
|
if (relativePath.endsWith("hooks.json")) {
|
|
34654
34750
|
removeManagedCompiledArtifact2(
|
|
34655
|
-
|
|
34751
|
+
path48.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
|
|
34656
34752
|
"copilot",
|
|
34657
34753
|
relativePath,
|
|
34658
34754
|
logger
|
|
@@ -34682,9 +34778,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
34682
34778
|
}
|
|
34683
34779
|
if (relativePath.startsWith("agents/")) {
|
|
34684
34780
|
removeManagedCompiledArtifact2(
|
|
34685
|
-
|
|
34781
|
+
path48.join(
|
|
34686
34782
|
resolveTargetPath(paths.agents ?? ""),
|
|
34687
|
-
`${
|
|
34783
|
+
`${path48.parse(relativePath).name}.toml`
|
|
34688
34784
|
),
|
|
34689
34785
|
"codex",
|
|
34690
34786
|
relativePath,
|
|
@@ -34694,9 +34790,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
34694
34790
|
}
|
|
34695
34791
|
if (relativePath.startsWith("rules/")) {
|
|
34696
34792
|
removeManagedCompiledArtifact2(
|
|
34697
|
-
|
|
34793
|
+
path48.join(
|
|
34698
34794
|
resolveTargetPath(paths.rules ?? ""),
|
|
34699
|
-
`${
|
|
34795
|
+
`${path48.parse(relativePath).name}.rules`
|
|
34700
34796
|
),
|
|
34701
34797
|
"codex",
|
|
34702
34798
|
relativePath,
|
|
@@ -34735,9 +34831,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
34735
34831
|
}
|
|
34736
34832
|
if (relativePath.startsWith("agents/")) {
|
|
34737
34833
|
removeManagedCompiledArtifact2(
|
|
34738
|
-
|
|
34834
|
+
path48.join(
|
|
34739
34835
|
resolveTargetPath(paths.agents ?? ""),
|
|
34740
|
-
`${
|
|
34836
|
+
`${path48.parse(relativePath).name}.md`
|
|
34741
34837
|
),
|
|
34742
34838
|
"opencode",
|
|
34743
34839
|
relativePath,
|
|
@@ -34747,9 +34843,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
34747
34843
|
}
|
|
34748
34844
|
if (relativePath.startsWith("commands/")) {
|
|
34749
34845
|
removeManagedCompiledArtifact2(
|
|
34750
|
-
|
|
34846
|
+
path48.join(
|
|
34751
34847
|
resolveTargetPath(paths.commands ?? ""),
|
|
34752
|
-
`${
|
|
34848
|
+
`${path48.parse(relativePath).name}.md`
|
|
34753
34849
|
),
|
|
34754
34850
|
"opencode",
|
|
34755
34851
|
relativePath,
|
|
@@ -34781,9 +34877,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34781
34877
|
}
|
|
34782
34878
|
if (relativePath.startsWith("agents/")) {
|
|
34783
34879
|
removeManagedCompiledArtifact2(
|
|
34784
|
-
|
|
34880
|
+
path48.join(
|
|
34785
34881
|
resolveTargetPath(paths.agents ?? ""),
|
|
34786
|
-
`${
|
|
34882
|
+
`${path48.parse(relativePath).name}.md`
|
|
34787
34883
|
),
|
|
34788
34884
|
"cursor",
|
|
34789
34885
|
relativePath,
|
|
@@ -34793,9 +34889,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34793
34889
|
}
|
|
34794
34890
|
if (relativePath.startsWith("rules/")) {
|
|
34795
34891
|
removeManagedCompiledArtifact2(
|
|
34796
|
-
|
|
34892
|
+
path48.join(
|
|
34797
34893
|
resolveTargetPath(paths.rules ?? ""),
|
|
34798
|
-
`${
|
|
34894
|
+
`${path48.parse(relativePath).name}.mdc`
|
|
34799
34895
|
),
|
|
34800
34896
|
"cursor",
|
|
34801
34897
|
relativePath,
|
|
@@ -34805,9 +34901,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34805
34901
|
}
|
|
34806
34902
|
if (relativePath.startsWith("commands/")) {
|
|
34807
34903
|
removeManagedCompiledArtifact2(
|
|
34808
|
-
|
|
34904
|
+
path48.join(
|
|
34809
34905
|
resolveTargetPath(paths.skills ?? ""),
|
|
34810
|
-
|
|
34906
|
+
path48.parse(relativePath).name,
|
|
34811
34907
|
"SKILL.md"
|
|
34812
34908
|
),
|
|
34813
34909
|
"cursor",
|
|
@@ -34851,9 +34947,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
34851
34947
|
}
|
|
34852
34948
|
if (relativePath.startsWith("rules/")) {
|
|
34853
34949
|
removeManagedCompiledArtifact2(
|
|
34854
|
-
|
|
34950
|
+
path48.join(
|
|
34855
34951
|
resolveTargetPath(paths.rules ?? ""),
|
|
34856
|
-
`${
|
|
34952
|
+
`${path48.parse(relativePath).name}.md`
|
|
34857
34953
|
),
|
|
34858
34954
|
"cline",
|
|
34859
34955
|
relativePath,
|
|
@@ -34863,9 +34959,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
34863
34959
|
}
|
|
34864
34960
|
if (relativePath.startsWith("commands/")) {
|
|
34865
34961
|
removeManagedCompiledArtifact2(
|
|
34866
|
-
|
|
34962
|
+
path48.join(
|
|
34867
34963
|
resolveTargetPath(paths.workflows ?? ""),
|
|
34868
|
-
|
|
34964
|
+
path48.basename(relativePath)
|
|
34869
34965
|
),
|
|
34870
34966
|
"cline",
|
|
34871
34967
|
relativePath,
|
|
@@ -34883,17 +34979,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
34883
34979
|
}
|
|
34884
34980
|
}
|
|
34885
34981
|
function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
|
|
34886
|
-
if (!
|
|
34982
|
+
if (!fs47.existsSync(artifactPath)) {
|
|
34887
34983
|
return;
|
|
34888
34984
|
}
|
|
34889
|
-
if (!
|
|
34985
|
+
if (!fs47.statSync(artifactPath).isFile()) {
|
|
34890
34986
|
return;
|
|
34891
34987
|
}
|
|
34892
|
-
const marker = extractProvenanceMarker(
|
|
34988
|
+
const marker = extractProvenanceMarker(fs47.readFileSync(artifactPath, "utf8"));
|
|
34893
34989
|
if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
|
|
34894
34990
|
return;
|
|
34895
34991
|
}
|
|
34896
|
-
|
|
34992
|
+
fs47.rmSync(artifactPath, { force: true });
|
|
34897
34993
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
34898
34994
|
}
|
|
34899
34995
|
function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
@@ -34924,10 +35020,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
|
|
|
34924
35020
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
34925
35021
|
}
|
|
34926
35022
|
function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
34927
|
-
if (!
|
|
35023
|
+
if (!fs47.existsSync(artifactPath)) {
|
|
34928
35024
|
return;
|
|
34929
35025
|
}
|
|
34930
|
-
const content =
|
|
35026
|
+
const content = fs47.readFileSync(artifactPath, "utf8");
|
|
34931
35027
|
const startMarker = "# tangyr: managed mcp start";
|
|
34932
35028
|
const endMarker = "# tangyr: managed mcp end";
|
|
34933
35029
|
const startIndex = content.indexOf(startMarker);
|
|
@@ -34944,19 +35040,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
|
34944
35040
|
const after = content.slice(endIndex + endMarker.length).trimStart();
|
|
34945
35041
|
const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
|
|
34946
35042
|
if (cleaned.length === 0) {
|
|
34947
|
-
|
|
35043
|
+
fs47.rmSync(artifactPath, { force: true });
|
|
34948
35044
|
} else {
|
|
34949
|
-
|
|
35045
|
+
fs47.writeFileSync(artifactPath, `${cleaned}
|
|
34950
35046
|
`);
|
|
34951
35047
|
}
|
|
34952
35048
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
34953
35049
|
}
|
|
34954
35050
|
function readJsonObject5(filePath) {
|
|
34955
|
-
if (!
|
|
35051
|
+
if (!fs47.existsSync(filePath)) {
|
|
34956
35052
|
return null;
|
|
34957
35053
|
}
|
|
34958
35054
|
try {
|
|
34959
|
-
const parsed = JSON.parse(
|
|
35055
|
+
const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
|
|
34960
35056
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
34961
35057
|
} catch {
|
|
34962
35058
|
return null;
|
|
@@ -34970,10 +35066,10 @@ function readJsonMetadata(value) {
|
|
|
34970
35066
|
}
|
|
34971
35067
|
function writeJsonOrRemove2(filePath, parsed) {
|
|
34972
35068
|
if (isEmptyJsonValue2(parsed)) {
|
|
34973
|
-
|
|
35069
|
+
fs47.rmSync(filePath, { force: true });
|
|
34974
35070
|
return;
|
|
34975
35071
|
}
|
|
34976
|
-
|
|
35072
|
+
fs47.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
34977
35073
|
`);
|
|
34978
35074
|
}
|
|
34979
35075
|
function isEmptyJsonValue2(value) {
|
|
@@ -35033,8 +35129,8 @@ function removeManagedHookEntries(value, expectedSource) {
|
|
|
35033
35129
|
}
|
|
35034
35130
|
|
|
35035
35131
|
// src/commands/validate.ts
|
|
35036
|
-
import
|
|
35037
|
-
import
|
|
35132
|
+
import fs48 from "fs";
|
|
35133
|
+
import path49 from "path";
|
|
35038
35134
|
var SUPPORTED_KIT_FORMATS2 = [1];
|
|
35039
35135
|
var SUPPORTED_DISCIPLINE_VERSIONS = [
|
|
35040
35136
|
"0.14.0",
|
|
@@ -35149,12 +35245,12 @@ function checkArchetype(kit) {
|
|
|
35149
35245
|
}
|
|
35150
35246
|
function checkHookScriptsExist(kit) {
|
|
35151
35247
|
const violations = [];
|
|
35152
|
-
const hooksDir =
|
|
35248
|
+
const hooksDir = path49.join(kit.path, "hooks");
|
|
35153
35249
|
const missingSet = new Set(kit.components.hooks.missing);
|
|
35154
35250
|
for (const name of kit.components.hooks.declared) {
|
|
35155
35251
|
if (missingSet.has(name)) continue;
|
|
35156
|
-
const declarationPath =
|
|
35157
|
-
if (!
|
|
35252
|
+
const declarationPath = path49.join(hooksDir, `${name}.md`);
|
|
35253
|
+
if (!fs48.existsSync(declarationPath)) continue;
|
|
35158
35254
|
let data;
|
|
35159
35255
|
try {
|
|
35160
35256
|
({ data } = parseMarkdownFrontmatter(declarationPath));
|
|
@@ -35164,8 +35260,8 @@ function checkHookScriptsExist(kit) {
|
|
|
35164
35260
|
if (typeof data.command === "string" && data.command.trim().length > 0) {
|
|
35165
35261
|
continue;
|
|
35166
35262
|
}
|
|
35167
|
-
const scriptPath =
|
|
35168
|
-
if (!
|
|
35263
|
+
const scriptPath = path49.join(hooksDir, "scripts", `${name}.ts`);
|
|
35264
|
+
if (!fs48.existsSync(scriptPath)) {
|
|
35169
35265
|
violations.push({
|
|
35170
35266
|
code: "hook-script-missing",
|
|
35171
35267
|
location: `hooks/scripts/${name}.ts`,
|
|
@@ -35178,10 +35274,10 @@ function checkHookScriptsExist(kit) {
|
|
|
35178
35274
|
function checkOptionalSourceDocuments(kit) {
|
|
35179
35275
|
const violations = [];
|
|
35180
35276
|
for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
|
|
35181
|
-
const filePath =
|
|
35182
|
-
if (!
|
|
35277
|
+
const filePath = path49.join(kit.path, name);
|
|
35278
|
+
if (!fs48.existsSync(filePath)) continue;
|
|
35183
35279
|
try {
|
|
35184
|
-
const parsed = JSON.parse(
|
|
35280
|
+
const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
|
|
35185
35281
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
35186
35282
|
violations.push({
|
|
35187
35283
|
code: "optional-source-malformed",
|
|
@@ -35203,10 +35299,10 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35203
35299
|
const notices = [];
|
|
35204
35300
|
const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
|
|
35205
35301
|
for (const name of kit.components.skills.declared) {
|
|
35206
|
-
const skillDir =
|
|
35302
|
+
const skillDir = path49.join(kit.path, "skills", name);
|
|
35207
35303
|
let entries;
|
|
35208
35304
|
try {
|
|
35209
|
-
entries =
|
|
35305
|
+
entries = fs48.readdirSync(skillDir, { withFileTypes: true });
|
|
35210
35306
|
} catch {
|
|
35211
35307
|
continue;
|
|
35212
35308
|
}
|
|
@@ -35224,7 +35320,7 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35224
35320
|
return notices;
|
|
35225
35321
|
}
|
|
35226
35322
|
function checkHooksSourceForm(kit) {
|
|
35227
|
-
const hooksDir =
|
|
35323
|
+
const hooksDir = path49.join(kit.path, "hooks");
|
|
35228
35324
|
const message = describeHooksSourceConflict(
|
|
35229
35325
|
hooksDir,
|
|
35230
35326
|
kit.components.hooks.declared
|
|
@@ -35236,12 +35332,12 @@ function checkHooksSourceForm(kit) {
|
|
|
35236
35332
|
} : null;
|
|
35237
35333
|
}
|
|
35238
35334
|
function checkHookDeclarations(kit) {
|
|
35239
|
-
const hooksDir =
|
|
35335
|
+
const hooksDir = path49.join(kit.path, "hooks");
|
|
35240
35336
|
return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
|
|
35241
35337
|
(r) => ({
|
|
35242
35338
|
code: "hook-declaration-invalid",
|
|
35243
|
-
location: `hooks/${
|
|
35244
|
-
message: `hooks: '${
|
|
35339
|
+
location: `hooks/${path49.basename(r.file)}`,
|
|
35340
|
+
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
35341
|
})
|
|
35246
35342
|
);
|
|
35247
35343
|
}
|
|
@@ -35261,11 +35357,11 @@ function checkKitFormatSupported(kit) {
|
|
|
35261
35357
|
function checkEntrypointExists(kit) {
|
|
35262
35358
|
const declared = kit.entrypoint;
|
|
35263
35359
|
const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
|
|
35264
|
-
const entrypointPath =
|
|
35265
|
-
if (
|
|
35360
|
+
const entrypointPath = path49.join(kit.path, entrypoint);
|
|
35361
|
+
if (fs48.existsSync(entrypointPath)) {
|
|
35266
35362
|
return null;
|
|
35267
35363
|
}
|
|
35268
|
-
const legacyPresent = declared === void 0 &&
|
|
35364
|
+
const legacyPresent = declared === void 0 && fs48.existsSync(path49.join(kit.path, LEGACY_ENTRYPOINT));
|
|
35269
35365
|
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
35366
|
return {
|
|
35271
35367
|
code: "entrypoint-missing",
|
|
@@ -35324,9 +35420,9 @@ function checkComponentFrontmatter(kit) {
|
|
|
35324
35420
|
const missingSet = new Set(kit.components[cat].missing);
|
|
35325
35421
|
for (const name of kit.components[cat].declared) {
|
|
35326
35422
|
if (missingSet.has(name)) continue;
|
|
35327
|
-
const filePath = cat === "skills" ?
|
|
35328
|
-
if (!
|
|
35329
|
-
const relPath =
|
|
35423
|
+
const filePath = cat === "skills" ? path49.join(kit.path, cat, name, "SKILL.md") : path49.join(kit.path, cat, `${name}.md`);
|
|
35424
|
+
if (!fs48.existsSync(filePath)) continue;
|
|
35425
|
+
const relPath = path49.relative(kit.path, filePath);
|
|
35330
35426
|
try {
|
|
35331
35427
|
const { data } = parseMarkdownFrontmatter(filePath);
|
|
35332
35428
|
for (const field of requiredFields) {
|
|
@@ -35351,10 +35447,10 @@ function checkComponentFrontmatter(kit) {
|
|
|
35351
35447
|
}
|
|
35352
35448
|
function checkReservedRootNames(kit) {
|
|
35353
35449
|
const violations = [];
|
|
35354
|
-
if (!
|
|
35450
|
+
if (!fs48.existsSync(kit.path) || !fs48.statSync(kit.path).isDirectory()) {
|
|
35355
35451
|
return violations;
|
|
35356
35452
|
}
|
|
35357
|
-
const entries =
|
|
35453
|
+
const entries = fs48.readdirSync(kit.path, { withFileTypes: true });
|
|
35358
35454
|
for (const entry of entries) {
|
|
35359
35455
|
if (RESERVED_ROOT_NAMES.includes(entry.name)) {
|
|
35360
35456
|
violations.push({
|
|
@@ -35371,8 +35467,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35371
35467
|
const missingSet = new Set(kit.components.commands.missing);
|
|
35372
35468
|
for (const name of kit.components.commands.declared) {
|
|
35373
35469
|
if (missingSet.has(name)) continue;
|
|
35374
|
-
const filePath =
|
|
35375
|
-
if (!
|
|
35470
|
+
const filePath = path49.join(kit.path, "commands", `${name}.md`);
|
|
35471
|
+
if (!fs48.existsSync(filePath)) continue;
|
|
35376
35472
|
let data;
|
|
35377
35473
|
try {
|
|
35378
35474
|
({ data } = parseMarkdownFrontmatter(filePath));
|
|
@@ -35385,7 +35481,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35385
35481
|
if (!barred) {
|
|
35386
35482
|
violations.push({
|
|
35387
35483
|
code: "command-human-only-model-invocable",
|
|
35388
|
-
location:
|
|
35484
|
+
location: path49.relative(kit.path, filePath),
|
|
35389
35485
|
message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
|
|
35390
35486
|
});
|
|
35391
35487
|
}
|
|
@@ -35394,8 +35490,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35394
35490
|
}
|
|
35395
35491
|
|
|
35396
35492
|
// src/commands/verify.ts
|
|
35397
|
-
import
|
|
35398
|
-
import
|
|
35493
|
+
import fs49 from "fs";
|
|
35494
|
+
import path50 from "path";
|
|
35399
35495
|
function runVerifyCommand(options, logger) {
|
|
35400
35496
|
if (options.target && !isKnownTarget(options.target)) {
|
|
35401
35497
|
throwUnrecognizedTarget(options.target);
|
|
@@ -35576,8 +35672,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
|
|
|
35576
35672
|
if (!slotPath) {
|
|
35577
35673
|
continue;
|
|
35578
35674
|
}
|
|
35579
|
-
const fullPath = subPath ?
|
|
35580
|
-
if (!
|
|
35675
|
+
const fullPath = subPath ? path50.join(slotPath, subPath) : slotPath;
|
|
35676
|
+
if (!fs49.existsSync(fullPath)) {
|
|
35581
35677
|
failures.push(
|
|
35582
35678
|
`claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
|
|
35583
35679
|
);
|