@alessandroraffa/tangyr 2.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 +756 -600
- 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":
|
|
@@ -21980,6 +21980,25 @@ function realPathOrInput(filePath) {
|
|
|
21980
21980
|
return filePath;
|
|
21981
21981
|
}
|
|
21982
21982
|
}
|
|
21983
|
+
function clearSymlinkAtDestination(destination) {
|
|
21984
|
+
let stat;
|
|
21985
|
+
try {
|
|
21986
|
+
stat = fs23.lstatSync(destination);
|
|
21987
|
+
} catch {
|
|
21988
|
+
return null;
|
|
21989
|
+
}
|
|
21990
|
+
if (!stat.isSymbolicLink()) {
|
|
21991
|
+
return null;
|
|
21992
|
+
}
|
|
21993
|
+
let target = null;
|
|
21994
|
+
try {
|
|
21995
|
+
target = fs23.readlinkSync(destination);
|
|
21996
|
+
} catch {
|
|
21997
|
+
target = null;
|
|
21998
|
+
}
|
|
21999
|
+
fs23.unlinkSync(destination);
|
|
22000
|
+
return target ?? "(unreadable link target)";
|
|
22001
|
+
}
|
|
21983
22002
|
|
|
21984
22003
|
// src/core/artifact-state.ts
|
|
21985
22004
|
import fs24 from "fs";
|
|
@@ -25133,8 +25152,8 @@ function toConflictPolicy2(value) {
|
|
|
25133
25152
|
}
|
|
25134
25153
|
|
|
25135
25154
|
// src/commands/install.ts
|
|
25136
|
-
import
|
|
25137
|
-
import
|
|
25155
|
+
import fs44 from "fs";
|
|
25156
|
+
import path44 from "path";
|
|
25138
25157
|
|
|
25139
25158
|
// src/core/channel-state.ts
|
|
25140
25159
|
import fs32 from "fs";
|
|
@@ -26040,9 +26059,91 @@ function sleep(ms2) {
|
|
|
26040
26059
|
});
|
|
26041
26060
|
}
|
|
26042
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
|
+
|
|
26043
26144
|
// src/adapters/claude-code.ts
|
|
26044
|
-
import
|
|
26045
|
-
import
|
|
26145
|
+
import fs37 from "fs";
|
|
26146
|
+
import path35 from "path";
|
|
26046
26147
|
|
|
26047
26148
|
// src/core/shim.ts
|
|
26048
26149
|
import crypto4 from "crypto";
|
|
@@ -26064,8 +26165,8 @@ ${SHIM_BODY}`;
|
|
|
26064
26165
|
}
|
|
26065
26166
|
|
|
26066
26167
|
// src/core/skills-slot.ts
|
|
26067
|
-
import
|
|
26068
|
-
import
|
|
26168
|
+
import fs35 from "fs";
|
|
26169
|
+
import path32 from "path";
|
|
26069
26170
|
function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
|
|
26070
26171
|
if (!isSymlinkPath(destination)) {
|
|
26071
26172
|
return false;
|
|
@@ -26078,7 +26179,7 @@ function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
|
|
|
26078
26179
|
}
|
|
26079
26180
|
function syncSkillsSlot(sync) {
|
|
26080
26181
|
const { source, destination, logger } = sync;
|
|
26081
|
-
if (!
|
|
26182
|
+
if (!fs35.existsSync(source)) {
|
|
26082
26183
|
return [
|
|
26083
26184
|
{
|
|
26084
26185
|
component: "skills",
|
|
@@ -26106,7 +26207,7 @@ function syncSkillsSlot(sync) {
|
|
|
26106
26207
|
if (isLegacyWholesaleSymlink) {
|
|
26107
26208
|
for (const name of foreignSkillNames(source, declaredNames)) {
|
|
26108
26209
|
logger.info(
|
|
26109
|
-
`[dry-run] skills: migrate foreign skill ${
|
|
26210
|
+
`[dry-run] skills: migrate foreign skill ${path32.join(source, name)} -> ${path32.join(destination, name)}`
|
|
26110
26211
|
);
|
|
26111
26212
|
}
|
|
26112
26213
|
logger.info(
|
|
@@ -26114,9 +26215,9 @@ function syncSkillsSlot(sync) {
|
|
|
26114
26215
|
);
|
|
26115
26216
|
}
|
|
26116
26217
|
for (const name of declaredNames ?? listSkillDirNames(source)) {
|
|
26117
|
-
const skillDestination =
|
|
26218
|
+
const skillDestination = path32.join(destination, name);
|
|
26118
26219
|
logger.info(
|
|
26119
|
-
`[dry-run] skills: symlink ${
|
|
26220
|
+
`[dry-run] skills: symlink ${path32.join(source, name)} -> ${skillDestination}`
|
|
26120
26221
|
);
|
|
26121
26222
|
outcomes2.push({
|
|
26122
26223
|
component: "skills",
|
|
@@ -26143,9 +26244,9 @@ function syncSkillsSlot(sync) {
|
|
|
26143
26244
|
}
|
|
26144
26245
|
function syncSingleSkill(sync, name) {
|
|
26145
26246
|
const { config, sourceRoot, source, destination } = sync;
|
|
26146
|
-
const skillSource =
|
|
26147
|
-
const skillDestination =
|
|
26148
|
-
if (!
|
|
26247
|
+
const skillSource = path32.join(source, name);
|
|
26248
|
+
const skillDestination = path32.join(destination, name);
|
|
26249
|
+
if (!fs35.existsSync(skillSource)) {
|
|
26149
26250
|
return {
|
|
26150
26251
|
component: "skills",
|
|
26151
26252
|
status: "skipped",
|
|
@@ -26161,29 +26262,29 @@ function syncSingleSkill(sync, name) {
|
|
|
26161
26262
|
};
|
|
26162
26263
|
}
|
|
26163
26264
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
|
|
26164
|
-
|
|
26265
|
+
fs35.unlinkSync(skillDestination);
|
|
26165
26266
|
} else if (artifactClass === "unmanaged-conflict" && !sync.onUnmanagedConflict(skillDestination)) {
|
|
26166
26267
|
return { component: "skills", status: "conflict", path: skillDestination };
|
|
26167
26268
|
} else if (artifactClass === "managed-symlink") {
|
|
26168
|
-
|
|
26269
|
+
fs35.unlinkSync(skillDestination);
|
|
26169
26270
|
}
|
|
26170
26271
|
createRelativeSymlink(skillSource, skillDestination, "dir");
|
|
26171
26272
|
return { component: "skills", status: "success", path: skillDestination };
|
|
26172
26273
|
}
|
|
26173
26274
|
function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
|
|
26174
26275
|
const foreignNames = foreignSkillNames(source, declaredNames);
|
|
26175
|
-
|
|
26276
|
+
fs35.unlinkSync(destination);
|
|
26176
26277
|
ensureDir(destination);
|
|
26177
26278
|
for (const name of foreignNames) {
|
|
26178
|
-
const from =
|
|
26179
|
-
const to =
|
|
26180
|
-
if (
|
|
26279
|
+
const from = path32.join(source, name);
|
|
26280
|
+
const to = path32.join(destination, name);
|
|
26281
|
+
if (fs35.existsSync(to)) {
|
|
26181
26282
|
logger.warn(
|
|
26182
26283
|
`skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
|
|
26183
26284
|
);
|
|
26184
26285
|
continue;
|
|
26185
26286
|
}
|
|
26186
|
-
|
|
26287
|
+
fs35.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
|
|
26187
26288
|
logger.warn(
|
|
26188
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.`
|
|
26189
26290
|
);
|
|
@@ -26197,44 +26298,44 @@ function foreignSkillNames(source, declaredNames) {
|
|
|
26197
26298
|
return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
|
|
26198
26299
|
}
|
|
26199
26300
|
function listSkillDirNames(dir) {
|
|
26200
|
-
if (!
|
|
26301
|
+
if (!fs35.existsSync(dir)) {
|
|
26201
26302
|
return [];
|
|
26202
26303
|
}
|
|
26203
|
-
return
|
|
26304
|
+
return fs35.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
26204
26305
|
}
|
|
26205
26306
|
function isSymlinkPath(filePath) {
|
|
26206
26307
|
try {
|
|
26207
|
-
return
|
|
26308
|
+
return fs35.lstatSync(filePath).isSymbolicLink();
|
|
26208
26309
|
} catch {
|
|
26209
26310
|
return false;
|
|
26210
26311
|
}
|
|
26211
26312
|
}
|
|
26212
26313
|
function isSymlinkTo2(linkPath, source) {
|
|
26213
26314
|
try {
|
|
26214
|
-
return
|
|
26315
|
+
return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
|
|
26215
26316
|
} catch {
|
|
26216
26317
|
return false;
|
|
26217
26318
|
}
|
|
26218
26319
|
}
|
|
26219
26320
|
|
|
26220
26321
|
// src/core/hook-scripts.ts
|
|
26221
|
-
import
|
|
26322
|
+
import path33 from "path";
|
|
26222
26323
|
function hookScriptsDir(bridge, target, projectRoot) {
|
|
26223
26324
|
const globalBridge = resolveTargetPath("~/.agents/hooks");
|
|
26224
|
-
if (
|
|
26325
|
+
if (path33.resolve(bridge) === path33.resolve(globalBridge)) {
|
|
26225
26326
|
return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
|
|
26226
26327
|
}
|
|
26227
|
-
const relative =
|
|
26228
|
-
const insideProject = !relative.startsWith("..") && !
|
|
26328
|
+
const relative = path33.relative(projectRoot ?? process.cwd(), bridge);
|
|
26329
|
+
const insideProject = !relative.startsWith("..") && !path33.isAbsolute(relative) && relative !== "";
|
|
26229
26330
|
const variable = PROJECT_DIR_VARIABLE[target];
|
|
26230
26331
|
if (insideProject && variable) {
|
|
26231
|
-
const posix =
|
|
26232
|
-
relative.split(
|
|
26332
|
+
const posix = path33.posix.join(
|
|
26333
|
+
relative.split(path33.sep).join("/"),
|
|
26233
26334
|
"scripts"
|
|
26234
26335
|
);
|
|
26235
26336
|
return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
|
|
26236
26337
|
}
|
|
26237
|
-
return { prefix:
|
|
26338
|
+
return { prefix: path33.join(bridge, "scripts"), machineLocal: true };
|
|
26238
26339
|
}
|
|
26239
26340
|
var PROJECT_DIR_VARIABLE = {
|
|
26240
26341
|
"claude-code": "$CLAUDE_PROJECT_DIR"
|
|
@@ -26244,19 +26345,19 @@ function machineLocalScriptPathNotice(target, prefix) {
|
|
|
26244
26345
|
}
|
|
26245
26346
|
|
|
26246
26347
|
// src/core/instructions-source.ts
|
|
26247
|
-
import
|
|
26248
|
-
import
|
|
26348
|
+
import fs36 from "fs";
|
|
26349
|
+
import path34 from "path";
|
|
26249
26350
|
var PORTABLE_INSTRUCTIONS_NAME = "AGENTS.md";
|
|
26250
26351
|
var InstructionsSourceMissingError = class extends Error {
|
|
26251
26352
|
constructor(kitRoot, expected, declaredBy) {
|
|
26252
26353
|
super(
|
|
26253
|
-
`${
|
|
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.`
|
|
26254
26355
|
);
|
|
26255
26356
|
this.name = "InstructionsSourceMissingError";
|
|
26256
26357
|
}
|
|
26257
26358
|
};
|
|
26258
26359
|
function normalizeLabel(kitRoot, file) {
|
|
26259
|
-
return
|
|
26360
|
+
return path34.relative(kitRoot, file).split(path34.sep).join("/");
|
|
26260
26361
|
}
|
|
26261
26362
|
function isExplicitOverride(configured) {
|
|
26262
26363
|
const normalize = (value) => value.replace(/\\/gu, "/").replace(/^\.\//u, "");
|
|
@@ -26265,8 +26366,8 @@ function isExplicitOverride(configured) {
|
|
|
26265
26366
|
function resolveInstructionsSource(kitRoot, config) {
|
|
26266
26367
|
const configured = config.source.instructions;
|
|
26267
26368
|
if (isExplicitOverride(configured)) {
|
|
26268
|
-
const file =
|
|
26269
|
-
if (!
|
|
26369
|
+
const file = path34.resolve(kitRoot, configured);
|
|
26370
|
+
if (!fs36.existsSync(file)) {
|
|
26270
26371
|
throw new InstructionsSourceMissingError(
|
|
26271
26372
|
kitRoot,
|
|
26272
26373
|
configured,
|
|
@@ -26281,8 +26382,8 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26281
26382
|
}
|
|
26282
26383
|
const declared = resolveKitEntrypointName(kitRoot);
|
|
26283
26384
|
if (declared !== void 0) {
|
|
26284
|
-
const file =
|
|
26285
|
-
if (!
|
|
26385
|
+
const file = path34.resolve(kitRoot, declared);
|
|
26386
|
+
if (!fs36.existsSync(file)) {
|
|
26286
26387
|
throw new InstructionsSourceMissingError(
|
|
26287
26388
|
kitRoot,
|
|
26288
26389
|
declared,
|
|
@@ -26296,13 +26397,13 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26296
26397
|
};
|
|
26297
26398
|
}
|
|
26298
26399
|
for (const name of [DEFAULT_ENTRYPOINT, PORTABLE_INSTRUCTIONS_NAME]) {
|
|
26299
|
-
const file =
|
|
26300
|
-
if (
|
|
26400
|
+
const file = path34.resolve(kitRoot, name);
|
|
26401
|
+
if (fs36.existsSync(file)) {
|
|
26301
26402
|
return { file, label: name, origin: "convention" };
|
|
26302
26403
|
}
|
|
26303
26404
|
}
|
|
26304
|
-
const legacy =
|
|
26305
|
-
if (
|
|
26405
|
+
const legacy = path34.resolve(kitRoot, LEGACY_ENTRYPOINT);
|
|
26406
|
+
if (fs36.existsSync(legacy)) {
|
|
26306
26407
|
return {
|
|
26307
26408
|
file: legacy,
|
|
26308
26409
|
label: LEGACY_ENTRYPOINT,
|
|
@@ -26314,7 +26415,7 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26314
26415
|
}
|
|
26315
26416
|
function instructionsSourcePath(kitRoot, config) {
|
|
26316
26417
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
26317
|
-
return resolved ? resolved.file :
|
|
26418
|
+
return resolved ? resolved.file : path34.resolve(kitRoot, config.source.instructions);
|
|
26318
26419
|
}
|
|
26319
26420
|
function instructionsSourceLabel(kitRoot, config) {
|
|
26320
26421
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
@@ -26435,7 +26536,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
26435
26536
|
if (!shouldSkipComponent(options, "hooks")) {
|
|
26436
26537
|
outcomes.push(
|
|
26437
26538
|
syncHookScriptsBridge({
|
|
26438
|
-
source:
|
|
26539
|
+
source: path35.resolve(sourceRoot, config.source.hooks),
|
|
26439
26540
|
destination: profile.hook_scripts,
|
|
26440
26541
|
config,
|
|
26441
26542
|
sourceRoot,
|
|
@@ -26487,13 +26588,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
26487
26588
|
}
|
|
26488
26589
|
function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
|
|
26489
26590
|
if (!mappings.modelTiers.custom_provider) return;
|
|
26490
|
-
const agentsDir =
|
|
26491
|
-
if (!
|
|
26492
|
-
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()) {
|
|
26493
26594
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
26494
26595
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
26495
26596
|
if (hasProvider) {
|
|
26496
|
-
const basename =
|
|
26597
|
+
const basename = path35.basename(agentFile);
|
|
26497
26598
|
addLoss(lossReport, "claude-code", "agents", {
|
|
26498
26599
|
source: `agents/${basename}`,
|
|
26499
26600
|
fields: [
|
|
@@ -26518,7 +26619,7 @@ function shouldSkipComponent(options, component) {
|
|
|
26518
26619
|
var SHIM_MANIFEST_KEY = "claude-code/instructions_shim";
|
|
26519
26620
|
function lstatOrNull(p) {
|
|
26520
26621
|
try {
|
|
26521
|
-
return
|
|
26622
|
+
return fs37.lstatSync(p);
|
|
26522
26623
|
} catch {
|
|
26523
26624
|
return null;
|
|
26524
26625
|
}
|
|
@@ -26530,12 +26631,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26530
26631
|
if (shimLink?.isSymbolicLink()) {
|
|
26531
26632
|
backupFile(shimPath, manifest, scopePath);
|
|
26532
26633
|
writeManifest(scopePath, manifest);
|
|
26533
|
-
|
|
26634
|
+
fs37.unlinkSync(shimPath);
|
|
26534
26635
|
logger?.verbose(
|
|
26535
26636
|
`instructions-shim: replaced an unmanaged symlink at ${shimPath}`
|
|
26536
26637
|
);
|
|
26537
26638
|
}
|
|
26538
|
-
if (!
|
|
26639
|
+
if (!fs37.existsSync(shimPath)) {
|
|
26539
26640
|
addArtifactToManifest(manifest, {
|
|
26540
26641
|
relativePath: SHIM_MANIFEST_KEY,
|
|
26541
26642
|
path: shimPath,
|
|
@@ -26543,12 +26644,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26543
26644
|
origin: "tangyr-managed"
|
|
26544
26645
|
});
|
|
26545
26646
|
writeManifest(scopePath, manifest);
|
|
26546
|
-
|
|
26547
|
-
|
|
26647
|
+
fs37.mkdirSync(path35.dirname(shimPath), { recursive: true });
|
|
26648
|
+
fs37.writeFileSync(shimPath, shimContent);
|
|
26548
26649
|
logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
|
|
26549
26650
|
return;
|
|
26550
26651
|
}
|
|
26551
|
-
const existing =
|
|
26652
|
+
const existing = fs37.readFileSync(shimPath, "utf8");
|
|
26552
26653
|
const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
|
|
26553
26654
|
const marker = extractProvenanceMarker(firstNonEmptyLine);
|
|
26554
26655
|
if (marker !== null && marker.hash === expectedBodyHash) {
|
|
@@ -26565,7 +26666,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26565
26666
|
}
|
|
26566
26667
|
backupFile(shimPath, manifest, scopePath);
|
|
26567
26668
|
writeManifest(scopePath, manifest);
|
|
26568
|
-
|
|
26669
|
+
fs37.writeFileSync(shimPath, shimContent);
|
|
26569
26670
|
addArtifactToManifest(manifest, {
|
|
26570
26671
|
relativePath: SHIM_MANIFEST_KEY,
|
|
26571
26672
|
path: shimPath,
|
|
@@ -26575,10 +26676,10 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26575
26676
|
logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
|
|
26576
26677
|
}
|
|
26577
26678
|
function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
|
|
26578
|
-
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) :
|
|
26679
|
+
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path35.resolve(sourceRoot, config.source[directComponent.sourceKey]);
|
|
26579
26680
|
const sourceLabel = directComponent.sourceKey === "instructions" ? instructionsSourceLabel(sourceRoot, config) : config.source[directComponent.sourceKey];
|
|
26580
26681
|
const destination = directComponent.destination;
|
|
26581
|
-
if (!
|
|
26682
|
+
if (!fs37.existsSync(source)) {
|
|
26582
26683
|
return skippedMissingSource(directComponent.component, source);
|
|
26583
26684
|
}
|
|
26584
26685
|
if (options.dryRun) {
|
|
@@ -26600,7 +26701,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
26600
26701
|
};
|
|
26601
26702
|
}
|
|
26602
26703
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
26603
|
-
|
|
26704
|
+
fs37.unlinkSync(destination);
|
|
26604
26705
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
|
|
26605
26706
|
return {
|
|
26606
26707
|
component: directComponent.component,
|
|
@@ -26608,9 +26709,11 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
26608
26709
|
path: destination
|
|
26609
26710
|
};
|
|
26610
26711
|
} else if (artifactClass === "managed-symlink") {
|
|
26611
|
-
|
|
26712
|
+
fs37.unlinkSync(destination);
|
|
26713
|
+
} else if (artifactClass === "managed-compiled") {
|
|
26714
|
+
fs37.unlinkSync(destination);
|
|
26612
26715
|
}
|
|
26613
|
-
ensureDir(
|
|
26716
|
+
ensureDir(path35.dirname(destination));
|
|
26614
26717
|
createRelativeSymlink(source, destination, directComponent.type, {
|
|
26615
26718
|
logger,
|
|
26616
26719
|
provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
|
|
@@ -26630,7 +26733,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
26630
26733
|
return syncSkillsSlot({
|
|
26631
26734
|
config,
|
|
26632
26735
|
sourceRoot,
|
|
26633
|
-
source:
|
|
26736
|
+
source: path35.resolve(sourceRoot, config.source.skills),
|
|
26634
26737
|
destination,
|
|
26635
26738
|
dryRun: options.dryRun,
|
|
26636
26739
|
logger,
|
|
@@ -26664,7 +26767,7 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
|
|
|
26664
26767
|
destination,
|
|
26665
26768
|
settings,
|
|
26666
26769
|
stringifyJson2,
|
|
26667
|
-
!
|
|
26770
|
+
!fs37.existsSync(destination),
|
|
26668
26771
|
logger
|
|
26669
26772
|
);
|
|
26670
26773
|
return {
|
|
@@ -26674,8 +26777,8 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
|
|
|
26674
26777
|
};
|
|
26675
26778
|
}
|
|
26676
26779
|
function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
26677
|
-
const source =
|
|
26678
|
-
if (!
|
|
26780
|
+
const source = path35.resolve(sourceRoot, config.source.mcp);
|
|
26781
|
+
if (!fs37.existsSync(source)) {
|
|
26679
26782
|
return skippedMissingSource("mcp", source);
|
|
26680
26783
|
}
|
|
26681
26784
|
if (options.dryRun) {
|
|
@@ -26700,7 +26803,7 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
|
26700
26803
|
destination,
|
|
26701
26804
|
hostConfig,
|
|
26702
26805
|
stringifyJson2,
|
|
26703
|
-
!
|
|
26806
|
+
!fs37.existsSync(destination),
|
|
26704
26807
|
logger
|
|
26705
26808
|
);
|
|
26706
26809
|
return {
|
|
@@ -26710,8 +26813,8 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
|
26710
26813
|
};
|
|
26711
26814
|
}
|
|
26712
26815
|
function syncSettings(config, sourceRoot, options, logger, destination) {
|
|
26713
|
-
const source =
|
|
26714
|
-
if (!
|
|
26816
|
+
const source = path35.resolve(sourceRoot, config.source.settings);
|
|
26817
|
+
if (!fs37.existsSync(source)) {
|
|
26715
26818
|
return skippedMissingSource("settings", source);
|
|
26716
26819
|
}
|
|
26717
26820
|
if (options.dryRun) {
|
|
@@ -26729,7 +26832,7 @@ function syncSettings(config, sourceRoot, options, logger, destination) {
|
|
|
26729
26832
|
destination,
|
|
26730
26833
|
settings,
|
|
26731
26834
|
stringifyJson2,
|
|
26732
|
-
!
|
|
26835
|
+
!fs37.existsSync(destination),
|
|
26733
26836
|
logger
|
|
26734
26837
|
);
|
|
26735
26838
|
return {
|
|
@@ -26753,13 +26856,13 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
|
|
|
26753
26856
|
if (manifest && scopePath) {
|
|
26754
26857
|
backupFile(destination, manifest, scopePath);
|
|
26755
26858
|
writeManifest(scopePath, manifest);
|
|
26756
|
-
|
|
26859
|
+
fs37.rmSync(destination, { recursive: true, force: true });
|
|
26757
26860
|
} else {
|
|
26758
|
-
|
|
26861
|
+
fs37.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
26759
26862
|
}
|
|
26760
26863
|
return true;
|
|
26761
26864
|
}
|
|
26762
|
-
|
|
26865
|
+
fs37.rmSync(destination, { recursive: true, force: true });
|
|
26763
26866
|
return true;
|
|
26764
26867
|
}
|
|
26765
26868
|
function skippedMissingSource(component, source) {
|
|
@@ -26771,16 +26874,16 @@ function skippedMissingSource(component, source) {
|
|
|
26771
26874
|
}
|
|
26772
26875
|
function isSymlinkTo3(linkPath, source) {
|
|
26773
26876
|
try {
|
|
26774
|
-
return
|
|
26877
|
+
return fs37.realpathSync(linkPath) === fs37.realpathSync(source);
|
|
26775
26878
|
} catch {
|
|
26776
26879
|
return false;
|
|
26777
26880
|
}
|
|
26778
26881
|
}
|
|
26779
26882
|
function readJsonObject3(filePath) {
|
|
26780
|
-
if (!
|
|
26883
|
+
if (!fs37.existsSync(filePath)) {
|
|
26781
26884
|
return {};
|
|
26782
26885
|
}
|
|
26783
|
-
const parsed = JSON.parse(
|
|
26886
|
+
const parsed = JSON.parse(fs37.readFileSync(filePath, "utf8"));
|
|
26784
26887
|
return isRecord3(parsed) ? parsed : {};
|
|
26785
26888
|
}
|
|
26786
26889
|
function markManaged(value) {
|
|
@@ -26807,13 +26910,13 @@ function isRecord3(value) {
|
|
|
26807
26910
|
// src/adapters/codex.ts
|
|
26808
26911
|
var TOML3 = __toESM(require_toml(), 1);
|
|
26809
26912
|
import crypto6 from "crypto";
|
|
26810
|
-
import
|
|
26811
|
-
import
|
|
26913
|
+
import fs39 from "fs";
|
|
26914
|
+
import path38 from "path";
|
|
26812
26915
|
|
|
26813
26916
|
// src/compiler/agents.ts
|
|
26814
26917
|
var TOML = __toESM(require_toml(), 1);
|
|
26815
26918
|
var import_yaml8 = __toESM(require_dist(), 1);
|
|
26816
|
-
import
|
|
26919
|
+
import path36 from "path";
|
|
26817
26920
|
var writeCapabilityClasses = /* @__PURE__ */ new Set(["filesystem-write", "shell-execution"]);
|
|
26818
26921
|
var copilotToolAliasesByClass = {
|
|
26819
26922
|
delegation: "agent",
|
|
@@ -26825,7 +26928,7 @@ var copilotToolAliasesByClass = {
|
|
|
26825
26928
|
};
|
|
26826
26929
|
function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
26827
26930
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
26828
|
-
const relativeSource = `agents/${
|
|
26931
|
+
const relativeSource = `agents/${path36.basename(sourceFile)}`;
|
|
26829
26932
|
if (target === "opencode") {
|
|
26830
26933
|
return compileOpenCodeAgent(
|
|
26831
26934
|
sourceFile,
|
|
@@ -26866,7 +26969,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
|
26866
26969
|
mappings,
|
|
26867
26970
|
lossReport
|
|
26868
26971
|
);
|
|
26869
|
-
const overlayKey = `agents/${
|
|
26972
|
+
const overlayKey = `agents/${path36.basename(sourceFile, ".md")}.${target}.yaml`;
|
|
26870
26973
|
const targetFields = {
|
|
26871
26974
|
...translated.fields,
|
|
26872
26975
|
...extensions[overlayKey] ?? {}
|
|
@@ -26900,7 +27003,7 @@ ${TOML.stringify({
|
|
|
26900
27003
|
function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
26901
27004
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
26902
27005
|
throw new Error(
|
|
26903
|
-
`${
|
|
27006
|
+
`${path36.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
|
|
26904
27007
|
);
|
|
26905
27008
|
}
|
|
26906
27009
|
const frontmatter = {
|
|
@@ -26954,7 +27057,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
|
|
|
26954
27057
|
"permission",
|
|
26955
27058
|
"permission-coarsening"
|
|
26956
27059
|
),
|
|
26957
|
-
detail: `${
|
|
27060
|
+
detail: `${path36.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
|
|
26958
27061
|
}
|
|
26959
27062
|
]
|
|
26960
27063
|
});
|
|
@@ -26979,7 +27082,7 @@ ${(0, import_yaml8.stringify)(frontmatter).trim()}
|
|
|
26979
27082
|
function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
26980
27083
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
26981
27084
|
throw new Error(
|
|
26982
|
-
`${
|
|
27085
|
+
`${path36.basename(sourceFile)}: Cursor agent requires a non-empty description field`
|
|
26983
27086
|
);
|
|
26984
27087
|
}
|
|
26985
27088
|
const frontmatter = {
|
|
@@ -27016,7 +27119,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
27016
27119
|
"permission",
|
|
27017
27120
|
"permission-coarsening"
|
|
27018
27121
|
),
|
|
27019
|
-
detail: `${
|
|
27122
|
+
detail: `${path36.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
|
|
27020
27123
|
}
|
|
27021
27124
|
]
|
|
27022
27125
|
});
|
|
@@ -27035,7 +27138,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
27035
27138
|
"provider",
|
|
27036
27139
|
"provider-not-representable"
|
|
27037
27140
|
),
|
|
27038
|
-
detail: `${
|
|
27141
|
+
detail: `${path36.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
27039
27142
|
}
|
|
27040
27143
|
]
|
|
27041
27144
|
});
|
|
@@ -27067,7 +27170,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
|
|
|
27067
27170
|
"persona",
|
|
27068
27171
|
"persona-not-representable"
|
|
27069
27172
|
),
|
|
27070
|
-
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.`
|
|
27071
27174
|
}
|
|
27072
27175
|
]
|
|
27073
27176
|
});
|
|
@@ -27115,7 +27218,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27115
27218
|
field,
|
|
27116
27219
|
"model-not-representable"
|
|
27117
27220
|
),
|
|
27118
|
-
detail: `${
|
|
27221
|
+
detail: `${path36.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
|
|
27119
27222
|
});
|
|
27120
27223
|
return;
|
|
27121
27224
|
}
|
|
@@ -27133,9 +27236,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27133
27236
|
lossReport,
|
|
27134
27237
|
target,
|
|
27135
27238
|
"agents",
|
|
27136
|
-
`agents/${
|
|
27239
|
+
`agents/${path36.basename(sourceFile)}`,
|
|
27137
27240
|
"info",
|
|
27138
|
-
`${
|
|
27241
|
+
`${path36.basename(sourceFile)}: ${field} is delivered through another managed surface.`
|
|
27139
27242
|
);
|
|
27140
27243
|
return;
|
|
27141
27244
|
}
|
|
@@ -27144,7 +27247,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27144
27247
|
field,
|
|
27145
27248
|
action: entryType,
|
|
27146
27249
|
severity: resolveLossSeverity("agent-field", field, entryType),
|
|
27147
|
-
detail: `${
|
|
27250
|
+
detail: `${path36.basename(sourceFile)}: ${field} has no emitted field for this target.`
|
|
27148
27251
|
});
|
|
27149
27252
|
}
|
|
27150
27253
|
function mapToolsToCapabilities(value, mappings) {
|
|
@@ -27885,9 +27988,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
|
|
|
27885
27988
|
}
|
|
27886
27989
|
|
|
27887
27990
|
// src/compiler/rules.ts
|
|
27888
|
-
import
|
|
27991
|
+
import path37 from "path";
|
|
27889
27992
|
var import_yaml9 = __toESM(require_dist(), 1);
|
|
27890
|
-
import
|
|
27993
|
+
import fs38 from "fs";
|
|
27891
27994
|
function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
27892
27995
|
if (target === "copilot") {
|
|
27893
27996
|
addLoss(lossReport, "copilot", "rules", {
|
|
@@ -27924,13 +28027,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
|
27924
28027
|
}
|
|
27925
28028
|
const appendixParts = [];
|
|
27926
28029
|
const dotRulesFiles = [];
|
|
27927
|
-
for (const ruleFile of ts(
|
|
28030
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
27928
28031
|
const parsed = parseRule(ruleFile);
|
|
27929
|
-
const name =
|
|
28032
|
+
const name = path37.basename(ruleFile, ".md");
|
|
27930
28033
|
if (parsed.mode === "exec-policy") {
|
|
27931
28034
|
dotRulesFiles.push({
|
|
27932
28035
|
name: `${name}.rules`,
|
|
27933
|
-
content: `${formatProvenanceMarker("toml", `rules/${
|
|
28036
|
+
content: `${formatProvenanceMarker("toml", `rules/${path37.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
|
|
27934
28037
|
${parsed.body}`
|
|
27935
28038
|
});
|
|
27936
28039
|
continue;
|
|
@@ -27939,7 +28042,7 @@ ${parsed.body}`
|
|
|
27939
28042
|
|
|
27940
28043
|
${parsed.body.trim()}`);
|
|
27941
28044
|
addLoss(lossReport, "codex", "rules", {
|
|
27942
|
-
source: `rules/${
|
|
28045
|
+
source: `rules/${path37.basename(ruleFile)}`,
|
|
27943
28046
|
fields: [
|
|
27944
28047
|
{
|
|
27945
28048
|
field: "mode",
|
|
@@ -27949,7 +28052,7 @@ ${parsed.body.trim()}`);
|
|
|
27949
28052
|
"mode",
|
|
27950
28053
|
"rule-as-instruction"
|
|
27951
28054
|
),
|
|
27952
|
-
detail: `${
|
|
28055
|
+
detail: `${path37.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
|
|
27953
28056
|
}
|
|
27954
28057
|
]
|
|
27955
28058
|
});
|
|
@@ -27957,7 +28060,7 @@ ${parsed.body.trim()}`);
|
|
|
27957
28060
|
return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
|
|
27958
28061
|
}
|
|
27959
28062
|
function parseRule(ruleFile) {
|
|
27960
|
-
const content =
|
|
28063
|
+
const content = fs38.readFileSync(ruleFile, "utf8");
|
|
27961
28064
|
if (!content.startsWith("---\n")) {
|
|
27962
28065
|
return { mode: "guidance", body: content };
|
|
27963
28066
|
}
|
|
@@ -27981,14 +28084,14 @@ function isRuleMode(value) {
|
|
|
27981
28084
|
}
|
|
27982
28085
|
function compileOpenCodeRules(sourceRulesDir, lossReport) {
|
|
27983
28086
|
const appendixParts = [];
|
|
27984
|
-
for (const ruleFile of ts(
|
|
28087
|
+
for (const ruleFile of ts(path37.join(sourceRulesDir, "*.md")).sort()) {
|
|
27985
28088
|
const parsed = parseRule(ruleFile);
|
|
27986
|
-
const name =
|
|
28089
|
+
const name = path37.basename(ruleFile, ".md");
|
|
27987
28090
|
appendixParts.push(`## ${name}
|
|
27988
28091
|
|
|
27989
28092
|
${parsed.body.trim()}`);
|
|
27990
28093
|
addLoss(lossReport, "opencode", "rules", {
|
|
27991
|
-
source: `rules/${
|
|
28094
|
+
source: `rules/${path37.basename(ruleFile)}`,
|
|
27992
28095
|
fields: [
|
|
27993
28096
|
{
|
|
27994
28097
|
field: "rule",
|
|
@@ -27998,7 +28101,7 @@ ${parsed.body.trim()}`);
|
|
|
27998
28101
|
"rule",
|
|
27999
28102
|
"rule-path-scoping"
|
|
28000
28103
|
),
|
|
28001
|
-
detail: `${
|
|
28104
|
+
detail: `${path37.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
|
|
28002
28105
|
}
|
|
28003
28106
|
]
|
|
28004
28107
|
});
|
|
@@ -28007,9 +28110,9 @@ ${parsed.body.trim()}`);
|
|
|
28007
28110
|
}
|
|
28008
28111
|
function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
28009
28112
|
const dotRulesFiles = [];
|
|
28010
|
-
for (const ruleFile of ts(
|
|
28011
|
-
const content =
|
|
28012
|
-
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");
|
|
28013
28116
|
let frontmatterData = {};
|
|
28014
28117
|
let body = content;
|
|
28015
28118
|
if (content.startsWith("---\n")) {
|
|
@@ -28038,7 +28141,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
|
28038
28141
|
}
|
|
28039
28142
|
const marker = formatProvenanceMarker(
|
|
28040
28143
|
"markdown",
|
|
28041
|
-
`rules/${
|
|
28144
|
+
`rules/${path37.basename(ruleFile)}`,
|
|
28042
28145
|
computeSourceHash(ruleFile),
|
|
28043
28146
|
"cursor"
|
|
28044
28147
|
);
|
|
@@ -28054,9 +28157,9 @@ ${body}`;
|
|
|
28054
28157
|
}
|
|
28055
28158
|
function compileClineRules(sourceRulesDir, lossReport) {
|
|
28056
28159
|
const dotRulesFiles = [];
|
|
28057
|
-
for (const ruleFile of ts(
|
|
28058
|
-
const content =
|
|
28059
|
-
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");
|
|
28060
28163
|
let frontmatterData = {};
|
|
28061
28164
|
let body = content;
|
|
28062
28165
|
if (content.startsWith("---\n")) {
|
|
@@ -28073,13 +28176,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28073
28176
|
}
|
|
28074
28177
|
const marker = formatProvenanceMarker(
|
|
28075
28178
|
"markdown",
|
|
28076
|
-
`rules/${
|
|
28179
|
+
`rules/${path37.basename(ruleFile)}`,
|
|
28077
28180
|
computeSourceHash(ruleFile),
|
|
28078
28181
|
"cline"
|
|
28079
28182
|
);
|
|
28080
28183
|
if (frontmatterData.mode === "exec-policy") {
|
|
28081
28184
|
addLoss(lossReport, "cline", "rules", {
|
|
28082
|
-
source: `rules/${
|
|
28185
|
+
source: `rules/${path37.basename(ruleFile)}`,
|
|
28083
28186
|
fields: [
|
|
28084
28187
|
{
|
|
28085
28188
|
field: "mode",
|
|
@@ -28089,7 +28192,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28089
28192
|
"mode",
|
|
28090
28193
|
"rule-mode-downgrade"
|
|
28091
28194
|
),
|
|
28092
|
-
detail: `${
|
|
28195
|
+
detail: `${path37.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
|
|
28093
28196
|
}
|
|
28094
28197
|
]
|
|
28095
28198
|
});
|
|
@@ -28135,7 +28238,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28135
28238
|
rules: profile.rules
|
|
28136
28239
|
};
|
|
28137
28240
|
const rules = compileRules(
|
|
28138
|
-
|
|
28241
|
+
path38.join(sourceRoot, config.source.rules),
|
|
28139
28242
|
"codex",
|
|
28140
28243
|
mappings,
|
|
28141
28244
|
lossReport
|
|
@@ -28201,7 +28304,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28201
28304
|
if (!shouldSkipComponent2(options, "hooks")) {
|
|
28202
28305
|
outcomes.push(
|
|
28203
28306
|
syncHookScriptsBridge({
|
|
28204
|
-
source:
|
|
28307
|
+
source: path38.resolve(sourceRoot, config.source.hooks),
|
|
28205
28308
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
28206
28309
|
config,
|
|
28207
28310
|
sourceRoot,
|
|
@@ -28300,9 +28403,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28300
28403
|
function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
|
|
28301
28404
|
const cp = mappings.modelTiers.custom_provider;
|
|
28302
28405
|
if (!cp) return "";
|
|
28303
|
-
const agentsDir =
|
|
28304
|
-
if (!
|
|
28305
|
-
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();
|
|
28306
28409
|
const hasProviderAgent = agentFiles.some((agentFile) => {
|
|
28307
28410
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28308
28411
|
return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
@@ -28367,7 +28470,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28367
28470
|
}
|
|
28368
28471
|
];
|
|
28369
28472
|
for (const ruleFile of rules.dotRulesFiles) {
|
|
28370
|
-
const destination =
|
|
28473
|
+
const destination = path38.join(rulesRoot, ruleFile.name);
|
|
28371
28474
|
if (options.dryRun) {
|
|
28372
28475
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
28373
28476
|
outcomes.push({
|
|
@@ -28397,16 +28500,16 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28397
28500
|
function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
28398
28501
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
28399
28502
|
const destination = resolveTargetPath(paths.instructions);
|
|
28400
|
-
if (!
|
|
28503
|
+
if (!fs39.existsSync(source)) {
|
|
28401
28504
|
return skippedMissingSource2("instructions", source);
|
|
28402
28505
|
}
|
|
28403
|
-
const composed = `${
|
|
28506
|
+
const composed = `${fs39.readFileSync(source, "utf8").trim()}
|
|
28404
28507
|
|
|
28405
28508
|
--- tangyr managed rules ---
|
|
28406
28509
|
${agentsAppendix}`.trim();
|
|
28407
28510
|
const marker = formatProvenanceMarker(
|
|
28408
28511
|
"markdown",
|
|
28409
|
-
|
|
28512
|
+
path38.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
28410
28513
|
hashString(composed),
|
|
28411
28514
|
"codex"
|
|
28412
28515
|
);
|
|
@@ -28433,9 +28536,9 @@ ${composed}
|
|
|
28433
28536
|
);
|
|
28434
28537
|
}
|
|
28435
28538
|
function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
28436
|
-
const source =
|
|
28539
|
+
const source = path38.resolve(sourceRoot, config.source.skills);
|
|
28437
28540
|
const destination = resolveTargetPath(paths.skills);
|
|
28438
|
-
if (!
|
|
28541
|
+
if (!fs39.existsSync(source)) {
|
|
28439
28542
|
return skippedMissingSource2("skills", source);
|
|
28440
28543
|
}
|
|
28441
28544
|
if (options.dryRun) {
|
|
@@ -28451,29 +28554,29 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
28451
28554
|
};
|
|
28452
28555
|
}
|
|
28453
28556
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
28454
|
-
|
|
28557
|
+
fs39.unlinkSync(destination);
|
|
28455
28558
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
28456
28559
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
28457
28560
|
return { component: "skills", status: "conflict", path: destination };
|
|
28458
28561
|
} else if (artifactClass === "managed-symlink") {
|
|
28459
|
-
|
|
28562
|
+
fs39.unlinkSync(destination);
|
|
28460
28563
|
}
|
|
28461
|
-
ensureDir(
|
|
28564
|
+
ensureDir(path38.dirname(destination));
|
|
28462
28565
|
createRelativeSymlink(source, destination, "dir");
|
|
28463
28566
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
28464
28567
|
return { component: "skills", status: "success", path: destination };
|
|
28465
28568
|
}
|
|
28466
28569
|
function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
28467
|
-
const sourceAgentsRoot =
|
|
28468
|
-
if (!
|
|
28570
|
+
const sourceAgentsRoot = path38.join(sourceRoot, config.source.agents);
|
|
28571
|
+
if (!fs39.existsSync(sourceAgentsRoot)) {
|
|
28469
28572
|
return [skippedMissingSource2("agents", sourceAgentsRoot)];
|
|
28470
28573
|
}
|
|
28471
|
-
const sourceAgents = ts(
|
|
28574
|
+
const sourceAgents = ts(path38.join(sourceAgentsRoot, "*.md")).sort();
|
|
28472
28575
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
28473
28576
|
return sourceAgents.map((agentFile) => {
|
|
28474
|
-
const destination =
|
|
28577
|
+
const destination = path38.join(
|
|
28475
28578
|
agentsRoot,
|
|
28476
|
-
`${
|
|
28579
|
+
`${path38.basename(agentFile, ".md")}.toml`
|
|
28477
28580
|
);
|
|
28478
28581
|
const compiled = compileAgent(
|
|
28479
28582
|
agentFile,
|
|
@@ -28551,7 +28654,7 @@ function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
28551
28654
|
destination,
|
|
28552
28655
|
hostHooks,
|
|
28553
28656
|
stringifyJson3,
|
|
28554
|
-
!
|
|
28657
|
+
!fs39.existsSync(destination),
|
|
28555
28658
|
logger
|
|
28556
28659
|
);
|
|
28557
28660
|
return {
|
|
@@ -28564,7 +28667,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28564
28667
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
28565
28668
|
const sourceLabel = mcpSourceLabel(config);
|
|
28566
28669
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
28567
|
-
if (!
|
|
28670
|
+
if (!fs39.existsSync(source)) {
|
|
28568
28671
|
if (providerToml && !options.dryRun) {
|
|
28569
28672
|
const changed2 = writeTomlManagedSection(
|
|
28570
28673
|
destination,
|
|
@@ -28579,7 +28682,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28579
28682
|
}
|
|
28580
28683
|
return skippedMissingSource2("mcp", source);
|
|
28581
28684
|
}
|
|
28582
|
-
const sourceMcpJson = JSON.parse(
|
|
28685
|
+
const sourceMcpJson = JSON.parse(fs39.readFileSync(source, "utf8"));
|
|
28583
28686
|
const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
|
|
28584
28687
|
const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
|
|
28585
28688
|
if (options.dryRun) {
|
|
@@ -28601,12 +28704,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
|
|
|
28601
28704
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
28602
28705
|
return { component, status: "conflict", path: destination };
|
|
28603
28706
|
}
|
|
28604
|
-
ensureDir(
|
|
28605
|
-
|
|
28707
|
+
ensureDir(path38.dirname(destination));
|
|
28708
|
+
const clearedLink = clearSymlinkAtDestination(destination);
|
|
28709
|
+
if (clearedLink !== null) {
|
|
28710
|
+
logger.verbose(
|
|
28711
|
+
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
28712
|
+
);
|
|
28713
|
+
}
|
|
28714
|
+
fs39.writeFileSync(destination, content);
|
|
28606
28715
|
return { component, status: "success", path: destination };
|
|
28607
28716
|
}
|
|
28608
28717
|
function writeTomlManagedSection(destination, managedContent, logger) {
|
|
28609
|
-
const current =
|
|
28718
|
+
const current = fs39.existsSync(destination) ? fs39.readFileSync(destination, "utf8") : "";
|
|
28610
28719
|
const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
|
|
28611
28720
|
if (isFirstWrite) {
|
|
28612
28721
|
logger.warn(
|
|
@@ -28622,8 +28731,8 @@ ${managedMcpEnd}
|
|
|
28622
28731
|
if (current === next.trimStart()) {
|
|
28623
28732
|
return false;
|
|
28624
28733
|
}
|
|
28625
|
-
ensureDir(
|
|
28626
|
-
|
|
28734
|
+
ensureDir(path38.dirname(destination));
|
|
28735
|
+
fs39.writeFileSync(destination, next.trimStart());
|
|
28627
28736
|
return true;
|
|
28628
28737
|
}
|
|
28629
28738
|
function removeManagedTomlSection(content) {
|
|
@@ -28649,18 +28758,18 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
|
|
|
28649
28758
|
if (manifest && scopePath) {
|
|
28650
28759
|
backupFile(destination, manifest, scopePath);
|
|
28651
28760
|
writeManifest(scopePath, manifest);
|
|
28652
|
-
|
|
28761
|
+
fs39.rmSync(destination, { recursive: true, force: true });
|
|
28653
28762
|
} else {
|
|
28654
|
-
|
|
28763
|
+
fs39.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
28655
28764
|
}
|
|
28656
28765
|
return true;
|
|
28657
28766
|
}
|
|
28658
|
-
|
|
28767
|
+
fs39.rmSync(destination, { recursive: true, force: true });
|
|
28659
28768
|
return true;
|
|
28660
28769
|
}
|
|
28661
28770
|
function isCompiledCurrent(destination, expectedContent, expectedHash) {
|
|
28662
28771
|
try {
|
|
28663
|
-
const current =
|
|
28772
|
+
const current = fs39.readFileSync(destination, "utf8");
|
|
28664
28773
|
const marker = extractProvenanceMarker(current);
|
|
28665
28774
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "codex" && current === expectedContent : current === expectedContent;
|
|
28666
28775
|
} catch {
|
|
@@ -28679,16 +28788,16 @@ function shouldSkipComponent2(options, component) {
|
|
|
28679
28788
|
}
|
|
28680
28789
|
function isSymlinkTo4(linkPath, source) {
|
|
28681
28790
|
try {
|
|
28682
|
-
return
|
|
28791
|
+
return fs39.realpathSync(linkPath) === fs39.realpathSync(source);
|
|
28683
28792
|
} catch {
|
|
28684
28793
|
return false;
|
|
28685
28794
|
}
|
|
28686
28795
|
}
|
|
28687
28796
|
function readJsonObject4(filePath) {
|
|
28688
|
-
if (!
|
|
28797
|
+
if (!fs39.existsSync(filePath)) {
|
|
28689
28798
|
return {};
|
|
28690
28799
|
}
|
|
28691
|
-
const parsed = JSON.parse(
|
|
28800
|
+
const parsed = JSON.parse(fs39.readFileSync(filePath, "utf8"));
|
|
28692
28801
|
return isRecord5(parsed) ? parsed : {};
|
|
28693
28802
|
}
|
|
28694
28803
|
function stringifyJson3(value) {
|
|
@@ -28704,16 +28813,16 @@ function hashString(value) {
|
|
|
28704
28813
|
|
|
28705
28814
|
// src/adapters/copilot.ts
|
|
28706
28815
|
import crypto7 from "crypto";
|
|
28707
|
-
import
|
|
28708
|
-
import
|
|
28816
|
+
import fs40 from "fs";
|
|
28817
|
+
import path40 from "path";
|
|
28709
28818
|
|
|
28710
28819
|
// src/compiler/commands.ts
|
|
28711
28820
|
var import_yaml10 = __toESM(require_dist(), 1);
|
|
28712
|
-
import
|
|
28821
|
+
import path39 from "path";
|
|
28713
28822
|
function compileCommandPrompt(sourceFile) {
|
|
28714
28823
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
28715
|
-
const relativeSource = `commands/${
|
|
28716
|
-
const fields = promptFrontmatter(data,
|
|
28824
|
+
const relativeSource = `commands/${path39.basename(sourceFile)}`;
|
|
28825
|
+
const fields = promptFrontmatter(data, path39.basename(sourceFile, ".md"));
|
|
28717
28826
|
const marker = formatProvenanceMarker(
|
|
28718
28827
|
"markdown",
|
|
28719
28828
|
relativeSource,
|
|
@@ -28828,7 +28937,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
28828
28937
|
if (!shouldSkipComponent3(options, "hooks")) {
|
|
28829
28938
|
outcomes.push(
|
|
28830
28939
|
syncHookScriptsBridge({
|
|
28831
|
-
source:
|
|
28940
|
+
source: path40.resolve(sourceRoot, config.source.hooks),
|
|
28832
28941
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
28833
28942
|
config,
|
|
28834
28943
|
sourceRoot,
|
|
@@ -28909,13 +29018,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
28909
29018
|
}
|
|
28910
29019
|
function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
|
|
28911
29020
|
if (!mappings.modelTiers.custom_provider) return;
|
|
28912
|
-
const agentsDir =
|
|
28913
|
-
if (!
|
|
28914
|
-
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()) {
|
|
28915
29024
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28916
29025
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
28917
29026
|
if (hasProvider) {
|
|
28918
|
-
const basename =
|
|
29027
|
+
const basename = path40.basename(agentFile);
|
|
28919
29028
|
addLoss(lossReport, "copilot", "agents", {
|
|
28920
29029
|
source: `agents/${basename}`,
|
|
28921
29030
|
fields: [
|
|
@@ -28941,22 +29050,22 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
|
|
|
28941
29050
|
return [{ component: "instructions", status: "skipped", path: message }];
|
|
28942
29051
|
}
|
|
28943
29052
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
28944
|
-
if (!
|
|
29053
|
+
if (!fs40.existsSync(source)) {
|
|
28945
29054
|
return [skippedMissingSource3("instructions", source)];
|
|
28946
29055
|
}
|
|
28947
|
-
const rawContent =
|
|
29056
|
+
const rawContent = fs40.readFileSync(source, "utf8");
|
|
28948
29057
|
const contentHash = hashString2(rawContent);
|
|
28949
29058
|
const marker = formatProvenanceMarker(
|
|
28950
29059
|
"markdown",
|
|
28951
|
-
|
|
29060
|
+
path40.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
28952
29061
|
contentHash,
|
|
28953
29062
|
"copilot"
|
|
28954
29063
|
);
|
|
28955
29064
|
const composedContent = `${marker}
|
|
28956
29065
|
${rawContent}`;
|
|
28957
29066
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
28958
|
-
const agentsMdDest =
|
|
28959
|
-
const mirrorDest =
|
|
29067
|
+
const agentsMdDest = path40.resolve(projectRoot, "AGENTS.md");
|
|
29068
|
+
const mirrorDest = path40.resolve(
|
|
28960
29069
|
projectRoot,
|
|
28961
29070
|
".github",
|
|
28962
29071
|
"copilot-instructions.md"
|
|
@@ -29010,8 +29119,14 @@ function writeInstructionsFile(component, destination, content, contentHash, con
|
|
|
29010
29119
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29011
29120
|
return { component, status: "conflict", path: destination };
|
|
29012
29121
|
}
|
|
29013
|
-
ensureDir(
|
|
29014
|
-
|
|
29122
|
+
ensureDir(path40.dirname(destination));
|
|
29123
|
+
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29124
|
+
if (clearedLink !== null) {
|
|
29125
|
+
logger.verbose(
|
|
29126
|
+
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29127
|
+
);
|
|
29128
|
+
}
|
|
29129
|
+
fs40.writeFileSync(destination, content);
|
|
29015
29130
|
return { component, status: "success", path: destination };
|
|
29016
29131
|
}
|
|
29017
29132
|
function hashString2(value) {
|
|
@@ -29021,7 +29136,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29021
29136
|
return syncSkillsSlot({
|
|
29022
29137
|
config,
|
|
29023
29138
|
sourceRoot,
|
|
29024
|
-
source:
|
|
29139
|
+
source: path40.resolve(sourceRoot, config.source.skills),
|
|
29025
29140
|
destination: resolveTargetPath(paths.skills),
|
|
29026
29141
|
dryRun: options.dryRun,
|
|
29027
29142
|
logger,
|
|
@@ -29036,16 +29151,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29036
29151
|
});
|
|
29037
29152
|
}
|
|
29038
29153
|
function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29039
|
-
const sourceAgentsRoot =
|
|
29040
|
-
if (!
|
|
29154
|
+
const sourceAgentsRoot = path40.join(sourceRoot, config.source.agents);
|
|
29155
|
+
if (!fs40.existsSync(sourceAgentsRoot)) {
|
|
29041
29156
|
return [skippedMissingSource3("agents", sourceAgentsRoot)];
|
|
29042
29157
|
}
|
|
29043
|
-
const sourceAgents = ts(
|
|
29158
|
+
const sourceAgents = ts(path40.join(sourceAgentsRoot, "*.md")).sort();
|
|
29044
29159
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29045
29160
|
return sourceAgents.map((agentFile) => {
|
|
29046
|
-
const destination =
|
|
29161
|
+
const destination = path40.join(
|
|
29047
29162
|
agentsRoot,
|
|
29048
|
-
`${
|
|
29163
|
+
`${path40.basename(agentFile, ".md")}.agent.md`
|
|
29049
29164
|
);
|
|
29050
29165
|
const compiled = compileAgent(
|
|
29051
29166
|
agentFile,
|
|
@@ -29073,16 +29188,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29073
29188
|
});
|
|
29074
29189
|
}
|
|
29075
29190
|
function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29076
|
-
const sourceCommandsRoot =
|
|
29077
|
-
if (!
|
|
29191
|
+
const sourceCommandsRoot = path40.join(sourceRoot, config.source.commands);
|
|
29192
|
+
if (!fs40.existsSync(sourceCommandsRoot)) {
|
|
29078
29193
|
return [skippedMissingSource3("commands", sourceCommandsRoot)];
|
|
29079
29194
|
}
|
|
29080
|
-
const sourceCommands = ts(
|
|
29195
|
+
const sourceCommands = ts(path40.join(sourceCommandsRoot, "*.md")).sort();
|
|
29081
29196
|
const promptsRoot = resolveTargetPath(paths.prompts);
|
|
29082
29197
|
return sourceCommands.map((commandFile) => {
|
|
29083
|
-
const destination =
|
|
29198
|
+
const destination = path40.join(
|
|
29084
29199
|
promptsRoot,
|
|
29085
|
-
`${
|
|
29200
|
+
`${path40.basename(commandFile, ".md")}.prompt.md`
|
|
29086
29201
|
);
|
|
29087
29202
|
const compiled = compileCommandPrompt(commandFile);
|
|
29088
29203
|
if (options.dryRun) {
|
|
@@ -29106,7 +29221,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
|
|
|
29106
29221
|
});
|
|
29107
29222
|
}
|
|
29108
29223
|
function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
29109
|
-
const destination =
|
|
29224
|
+
const destination = path40.join(
|
|
29110
29225
|
resolveTargetPath(paths.hooks),
|
|
29111
29226
|
"tangyr-managed.json"
|
|
29112
29227
|
);
|
|
@@ -29169,10 +29284,10 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
29169
29284
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
29170
29285
|
const sourceLabel = mcpSourceLabel(config);
|
|
29171
29286
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
29172
|
-
if (!
|
|
29287
|
+
if (!fs40.existsSync(source)) {
|
|
29173
29288
|
return skippedMissingSource3("mcp", source);
|
|
29174
29289
|
}
|
|
29175
|
-
const sourceMcpJson = JSON.parse(
|
|
29290
|
+
const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
|
|
29176
29291
|
const compiled = compileMcp(
|
|
29177
29292
|
sourceMcpJson,
|
|
29178
29293
|
"copilot",
|
|
@@ -29202,13 +29317,19 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
|
|
|
29202
29317
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29203
29318
|
return { component, status: "conflict", path: destination };
|
|
29204
29319
|
}
|
|
29205
|
-
ensureDir(
|
|
29206
|
-
|
|
29320
|
+
ensureDir(path40.dirname(destination));
|
|
29321
|
+
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29322
|
+
if (clearedLink !== null) {
|
|
29323
|
+
logger.verbose(
|
|
29324
|
+
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29325
|
+
);
|
|
29326
|
+
}
|
|
29327
|
+
fs40.writeFileSync(destination, content);
|
|
29207
29328
|
return { component, status: "success", path: destination };
|
|
29208
29329
|
}
|
|
29209
29330
|
function isCompiledCurrent2(destination, expectedContent, expectedHash) {
|
|
29210
29331
|
try {
|
|
29211
|
-
const current =
|
|
29332
|
+
const current = fs40.readFileSync(destination, "utf8");
|
|
29212
29333
|
const marker = extractProvenanceMarker(current);
|
|
29213
29334
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "copilot" && current === expectedContent : current === expectedContent;
|
|
29214
29335
|
} catch {
|
|
@@ -29230,13 +29351,13 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
|
|
|
29230
29351
|
if (manifest && scopePath) {
|
|
29231
29352
|
backupFile(destination, manifest, scopePath);
|
|
29232
29353
|
writeManifest(scopePath, manifest);
|
|
29233
|
-
|
|
29354
|
+
fs40.rmSync(destination, { recursive: true, force: true });
|
|
29234
29355
|
} else {
|
|
29235
|
-
|
|
29356
|
+
fs40.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
29236
29357
|
}
|
|
29237
29358
|
return true;
|
|
29238
29359
|
}
|
|
29239
|
-
|
|
29360
|
+
fs40.rmSync(destination, { recursive: true, force: true });
|
|
29240
29361
|
return true;
|
|
29241
29362
|
}
|
|
29242
29363
|
function shouldSkipComponent3(options, component) {
|
|
@@ -29245,12 +29366,12 @@ function shouldSkipComponent3(options, component) {
|
|
|
29245
29366
|
function cleanupLegacyAgents(paths, options, logger) {
|
|
29246
29367
|
const currentAgentsRoot = resolveTargetPath(paths.agents);
|
|
29247
29368
|
const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
|
|
29248
|
-
if (
|
|
29369
|
+
if (path40.resolve(currentAgentsRoot) === path40.resolve(legacyAgentsRoot)) {
|
|
29249
29370
|
return [];
|
|
29250
29371
|
}
|
|
29251
29372
|
const outcomes = [];
|
|
29252
29373
|
for (const filePath of ts(
|
|
29253
|
-
|
|
29374
|
+
path40.join(legacyAgentsRoot, "*.agent.md")
|
|
29254
29375
|
).sort()) {
|
|
29255
29376
|
if (!isCopilotManagedCompiledFile(filePath)) {
|
|
29256
29377
|
continue;
|
|
@@ -29260,14 +29381,14 @@ function cleanupLegacyAgents(paths, options, logger) {
|
|
|
29260
29381
|
outcomes.push({ component: "agents", status: "dry-run", path: filePath });
|
|
29261
29382
|
continue;
|
|
29262
29383
|
}
|
|
29263
|
-
|
|
29384
|
+
fs40.rmSync(filePath, { force: true });
|
|
29264
29385
|
outcomes.push({ component: "agents", status: "success", path: filePath });
|
|
29265
29386
|
}
|
|
29266
29387
|
return outcomes;
|
|
29267
29388
|
}
|
|
29268
29389
|
function isCopilotManagedCompiledFile(filePath) {
|
|
29269
29390
|
try {
|
|
29270
|
-
return extractProvenanceMarker(
|
|
29391
|
+
return extractProvenanceMarker(fs40.readFileSync(filePath, "utf8"))?.target === "copilot";
|
|
29271
29392
|
} catch {
|
|
29272
29393
|
return false;
|
|
29273
29394
|
}
|
|
@@ -29282,8 +29403,8 @@ function skippedMissingSource3(component, source) {
|
|
|
29282
29403
|
|
|
29283
29404
|
// src/adapters/cursor.ts
|
|
29284
29405
|
import crypto8 from "crypto";
|
|
29285
|
-
import
|
|
29286
|
-
import
|
|
29406
|
+
import fs41 from "fs";
|
|
29407
|
+
import path41 from "path";
|
|
29287
29408
|
function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29288
29409
|
const scope = options.scope ?? "global";
|
|
29289
29410
|
const profile = resolveTargetPaths({
|
|
@@ -29395,7 +29516,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
29395
29516
|
if (!shouldSkipComponent4(options, "hooks")) {
|
|
29396
29517
|
outcomes.push(
|
|
29397
29518
|
syncHookScriptsBridge({
|
|
29398
|
-
source:
|
|
29519
|
+
source: path41.resolve(sourceRoot, config.source.hooks),
|
|
29399
29520
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
29400
29521
|
config,
|
|
29401
29522
|
sourceRoot,
|
|
@@ -29460,7 +29581,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
|
|
|
29460
29581
|
const composed = composeCursorInstructions(config, sourceRoot, lossReport);
|
|
29461
29582
|
const marker = formatProvenanceMarker(
|
|
29462
29583
|
"markdown",
|
|
29463
|
-
|
|
29584
|
+
path41.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
29464
29585
|
hashString3(composed),
|
|
29465
29586
|
"cursor"
|
|
29466
29587
|
);
|
|
@@ -29486,7 +29607,7 @@ ${composed}
|
|
|
29486
29607
|
}
|
|
29487
29608
|
function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
29488
29609
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
29489
|
-
const baseContent =
|
|
29610
|
+
const baseContent = fs41.existsSync(source) ? fs41.readFileSync(source, "utf8").trim() : "";
|
|
29490
29611
|
const personaContent = extractPrimaryPersonaContent(
|
|
29491
29612
|
config,
|
|
29492
29613
|
sourceRoot,
|
|
@@ -29499,11 +29620,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
|
29499
29620
|
${personaContent}`.trim() : baseContent;
|
|
29500
29621
|
}
|
|
29501
29622
|
function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
29502
|
-
const agentsDir =
|
|
29503
|
-
if (!
|
|
29623
|
+
const agentsDir = path41.join(sourceRoot, config.source.agents);
|
|
29624
|
+
if (!fs41.existsSync(agentsDir)) {
|
|
29504
29625
|
return null;
|
|
29505
29626
|
}
|
|
29506
|
-
const agentFiles = ts(
|
|
29627
|
+
const agentFiles = ts(path41.join(agentsDir, "*.md")).sort();
|
|
29507
29628
|
if (agentFiles.length === 0) {
|
|
29508
29629
|
return null;
|
|
29509
29630
|
}
|
|
@@ -29526,7 +29647,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29526
29647
|
return null;
|
|
29527
29648
|
}
|
|
29528
29649
|
addLoss(lossReport, "cursor", "instructions", {
|
|
29529
|
-
source: `agents/${
|
|
29650
|
+
source: `agents/${path41.basename(primaryFile)}`,
|
|
29530
29651
|
fields: [
|
|
29531
29652
|
{
|
|
29532
29653
|
field: "persona",
|
|
@@ -29536,23 +29657,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29536
29657
|
"persona",
|
|
29537
29658
|
"instructions-shim"
|
|
29538
29659
|
),
|
|
29539
|
-
detail: `Primary persona from ${
|
|
29660
|
+
detail: `Primary persona from ${path41.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
|
|
29540
29661
|
}
|
|
29541
29662
|
]
|
|
29542
29663
|
});
|
|
29543
29664
|
return body.trim();
|
|
29544
29665
|
}
|
|
29545
29666
|
function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29546
|
-
const sourceAgentsRoot =
|
|
29547
|
-
if (!
|
|
29667
|
+
const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
|
|
29668
|
+
if (!fs41.existsSync(sourceAgentsRoot)) {
|
|
29548
29669
|
return [skippedMissingSource4("agents", sourceAgentsRoot)];
|
|
29549
29670
|
}
|
|
29550
|
-
const sourceAgents = ts(
|
|
29671
|
+
const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
|
|
29551
29672
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29552
29673
|
return sourceAgents.map((agentFile) => {
|
|
29553
|
-
const destination =
|
|
29674
|
+
const destination = path41.join(
|
|
29554
29675
|
agentsRoot,
|
|
29555
|
-
`${
|
|
29676
|
+
`${path41.basename(agentFile, ".md")}.md`
|
|
29556
29677
|
);
|
|
29557
29678
|
let compiled;
|
|
29558
29679
|
try {
|
|
@@ -29593,14 +29714,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29593
29714
|
});
|
|
29594
29715
|
}
|
|
29595
29716
|
function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
29596
|
-
const sourceRulesDir =
|
|
29597
|
-
if (!
|
|
29717
|
+
const sourceRulesDir = path41.join(sourceRoot, config.source.rules);
|
|
29718
|
+
if (!fs41.existsSync(sourceRulesDir)) {
|
|
29598
29719
|
return [skippedMissingSource4("rules", sourceRulesDir)];
|
|
29599
29720
|
}
|
|
29600
29721
|
const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
|
|
29601
29722
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
29602
29723
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
29603
|
-
const destination =
|
|
29724
|
+
const destination = path41.join(rulesDir, name);
|
|
29604
29725
|
if (options.dryRun) {
|
|
29605
29726
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
29606
29727
|
return {
|
|
@@ -29624,17 +29745,17 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
29624
29745
|
});
|
|
29625
29746
|
}
|
|
29626
29747
|
function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29627
|
-
const sourceCommandsRoot =
|
|
29628
|
-
if (!
|
|
29748
|
+
const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
|
|
29749
|
+
if (!fs41.existsSync(sourceCommandsRoot)) {
|
|
29629
29750
|
return [skippedMissingSource4("commands", sourceCommandsRoot)];
|
|
29630
29751
|
}
|
|
29631
|
-
const sourceCommands = ts(
|
|
29752
|
+
const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
|
|
29632
29753
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
29633
29754
|
return sourceCommands.map((commandFile) => {
|
|
29634
|
-
const baseName =
|
|
29635
|
-
const destination =
|
|
29636
|
-
const commandContent =
|
|
29637
|
-
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)}`;
|
|
29638
29759
|
const marker = formatProvenanceMarker(
|
|
29639
29760
|
"markdown",
|
|
29640
29761
|
relativeSource,
|
|
@@ -29673,8 +29794,8 @@ ${commandContent.trim()}
|
|
|
29673
29794
|
});
|
|
29674
29795
|
}
|
|
29675
29796
|
function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
|
|
29676
|
-
const source =
|
|
29677
|
-
if (!
|
|
29797
|
+
const source = path41.resolve(sourceRoot, config.source.skills);
|
|
29798
|
+
if (!fs41.existsSync(source)) {
|
|
29678
29799
|
return skippedMissingSource4(component, source);
|
|
29679
29800
|
}
|
|
29680
29801
|
if (options.dryRun) {
|
|
@@ -29688,18 +29809,18 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
|
|
|
29688
29809
|
return { component, status: "skipped-current", path: destination };
|
|
29689
29810
|
}
|
|
29690
29811
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
29691
|
-
|
|
29812
|
+
fs41.unlinkSync(destination);
|
|
29692
29813
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
29693
29814
|
return { component, status: "conflict", path: destination };
|
|
29694
29815
|
} else if (artifactClass === "managed-symlink") {
|
|
29695
|
-
|
|
29816
|
+
fs41.unlinkSync(destination);
|
|
29696
29817
|
}
|
|
29697
|
-
ensureDir(
|
|
29818
|
+
ensureDir(path41.dirname(destination));
|
|
29698
29819
|
createRelativeSymlink(source, destination, "dir");
|
|
29699
29820
|
logger.verbose(`Skills: created shared skills symlink ${destination}`);
|
|
29700
29821
|
return { component, status: "success", path: destination };
|
|
29701
29822
|
}
|
|
29702
|
-
if (
|
|
29823
|
+
if (fs41.existsSync(destination)) {
|
|
29703
29824
|
return { component, status: "skipped-current", path: destination };
|
|
29704
29825
|
}
|
|
29705
29826
|
ensureDir(destination);
|
|
@@ -29740,18 +29861,18 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
29740
29861
|
}
|
|
29741
29862
|
const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
|
|
29742
29863
|
`;
|
|
29743
|
-
ensureDir(
|
|
29744
|
-
|
|
29864
|
+
ensureDir(path41.dirname(destination));
|
|
29865
|
+
fs41.writeFileSync(destination, hooksFileContent);
|
|
29745
29866
|
return { component: "hooks", status: "success", path: destination };
|
|
29746
29867
|
}
|
|
29747
29868
|
function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
|
|
29748
29869
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
29749
29870
|
const sourceLabel = mcpSourceLabel(config);
|
|
29750
29871
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
29751
|
-
if (!
|
|
29872
|
+
if (!fs41.existsSync(source)) {
|
|
29752
29873
|
return skippedMissingSource4("mcp", source);
|
|
29753
29874
|
}
|
|
29754
|
-
const sourceMcpJson = JSON.parse(
|
|
29875
|
+
const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
|
|
29755
29876
|
const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
|
|
29756
29877
|
if (options.dryRun) {
|
|
29757
29878
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -29804,13 +29925,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
|
|
|
29804
29925
|
);
|
|
29805
29926
|
}
|
|
29806
29927
|
function syncProviderPin(config, sourceRoot, lossReport) {
|
|
29807
|
-
const agentsDir =
|
|
29808
|
-
if (!
|
|
29809
|
-
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()) {
|
|
29810
29931
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
29811
29932
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
29812
29933
|
if (hasCustomProvider) {
|
|
29813
|
-
const relativeSource = `agents/${
|
|
29934
|
+
const relativeSource = `agents/${path41.basename(agentFile)}`;
|
|
29814
29935
|
addLoss(lossReport, "cursor", "agents", {
|
|
29815
29936
|
source: relativeSource,
|
|
29816
29937
|
fields: [
|
|
@@ -29822,7 +29943,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
|
|
|
29822
29943
|
"provider",
|
|
29823
29944
|
"provider-not-representable"
|
|
29824
29945
|
),
|
|
29825
|
-
detail: `${
|
|
29946
|
+
detail: `${path41.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
29826
29947
|
}
|
|
29827
29948
|
]
|
|
29828
29949
|
});
|
|
@@ -29837,8 +29958,14 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
|
|
|
29837
29958
|
if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
29838
29959
|
return { component, status: "conflict", path: destination };
|
|
29839
29960
|
}
|
|
29840
|
-
ensureDir(
|
|
29841
|
-
|
|
29961
|
+
ensureDir(path41.dirname(destination));
|
|
29962
|
+
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29963
|
+
if (clearedLink !== null) {
|
|
29964
|
+
logger.verbose(
|
|
29965
|
+
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29966
|
+
);
|
|
29967
|
+
}
|
|
29968
|
+
fs41.writeFileSync(destination, content);
|
|
29842
29969
|
return { component, status: "success", path: destination };
|
|
29843
29970
|
}
|
|
29844
29971
|
function handleConflict4(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -29856,18 +29983,18 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
|
|
|
29856
29983
|
if (manifest && scopePath) {
|
|
29857
29984
|
backupFile(destination, manifest, scopePath);
|
|
29858
29985
|
writeManifest(scopePath, manifest);
|
|
29859
|
-
|
|
29986
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
29860
29987
|
} else {
|
|
29861
|
-
|
|
29988
|
+
fs41.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
29862
29989
|
}
|
|
29863
29990
|
return true;
|
|
29864
29991
|
}
|
|
29865
|
-
|
|
29992
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
29866
29993
|
return true;
|
|
29867
29994
|
}
|
|
29868
29995
|
function isCompiledCurrent3(destination, expectedContent, expectedHash) {
|
|
29869
29996
|
try {
|
|
29870
|
-
const current =
|
|
29997
|
+
const current = fs41.readFileSync(destination, "utf8");
|
|
29871
29998
|
const marker = extractProvenanceMarker(current);
|
|
29872
29999
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cursor" && current === expectedContent : current === expectedContent;
|
|
29873
30000
|
} catch {
|
|
@@ -29886,7 +30013,7 @@ function shouldSkipComponent4(options, component) {
|
|
|
29886
30013
|
}
|
|
29887
30014
|
function isSymlinkTo5(linkPath, source) {
|
|
29888
30015
|
try {
|
|
29889
|
-
return
|
|
30016
|
+
return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
|
|
29890
30017
|
} catch {
|
|
29891
30018
|
return false;
|
|
29892
30019
|
}
|
|
@@ -29897,8 +30024,8 @@ function hashString3(value) {
|
|
|
29897
30024
|
|
|
29898
30025
|
// src/adapters/cline.ts
|
|
29899
30026
|
import crypto9 from "crypto";
|
|
29900
|
-
import
|
|
29901
|
-
import
|
|
30027
|
+
import fs42 from "fs";
|
|
30028
|
+
import path42 from "path";
|
|
29902
30029
|
function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29903
30030
|
const scope = options.scope ?? "global";
|
|
29904
30031
|
const profile = resolveTargetPaths({
|
|
@@ -30011,7 +30138,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
30011
30138
|
function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
|
|
30012
30139
|
if (scope === "global" || paths.instructions === null) {
|
|
30013
30140
|
addLoss(lossReport, "cline", "instructions", {
|
|
30014
|
-
source:
|
|
30141
|
+
source: path42.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30015
30142
|
fields: [
|
|
30016
30143
|
{
|
|
30017
30144
|
field: "instructions",
|
|
@@ -30033,10 +30160,10 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
|
|
|
30033
30160
|
}
|
|
30034
30161
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30035
30162
|
const destination = resolveTargetPath(paths.instructions);
|
|
30036
|
-
const baseContent =
|
|
30163
|
+
const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
|
|
30037
30164
|
const marker = formatProvenanceMarker(
|
|
30038
30165
|
"markdown",
|
|
30039
|
-
|
|
30166
|
+
path42.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30040
30167
|
hashString4(baseContent),
|
|
30041
30168
|
"cline"
|
|
30042
30169
|
);
|
|
@@ -30061,11 +30188,11 @@ ${baseContent}
|
|
|
30061
30188
|
);
|
|
30062
30189
|
}
|
|
30063
30190
|
function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
|
|
30064
|
-
const sourceAgentsRoot =
|
|
30065
|
-
if (!
|
|
30191
|
+
const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
|
|
30192
|
+
if (!fs42.existsSync(sourceAgentsRoot)) {
|
|
30066
30193
|
return [skippedMissingSource5("agents", sourceAgentsRoot)];
|
|
30067
30194
|
}
|
|
30068
|
-
const sourceAgents = ts(
|
|
30195
|
+
const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
|
|
30069
30196
|
return sourceAgents.map((agentFile) => {
|
|
30070
30197
|
compileAgent(agentFile, "cline", mappings, extensions, lossReport);
|
|
30071
30198
|
if (options.dryRun) {
|
|
@@ -30081,14 +30208,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
30081
30208
|
});
|
|
30082
30209
|
}
|
|
30083
30210
|
function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
30084
|
-
const sourceRulesDir =
|
|
30085
|
-
if (!
|
|
30211
|
+
const sourceRulesDir = path42.join(sourceRoot, config.source.rules);
|
|
30212
|
+
if (!fs42.existsSync(sourceRulesDir)) {
|
|
30086
30213
|
return [skippedMissingSource5("rules", sourceRulesDir)];
|
|
30087
30214
|
}
|
|
30088
30215
|
const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
|
|
30089
30216
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
30090
30217
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
30091
|
-
const destination =
|
|
30218
|
+
const destination = path42.join(rulesDir, name);
|
|
30092
30219
|
if (options.dryRun) {
|
|
30093
30220
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
30094
30221
|
return {
|
|
@@ -30112,17 +30239,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
30112
30239
|
});
|
|
30113
30240
|
}
|
|
30114
30241
|
function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30115
|
-
const sourceCommandsRoot =
|
|
30116
|
-
if (!
|
|
30242
|
+
const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
|
|
30243
|
+
if (!fs42.existsSync(sourceCommandsRoot)) {
|
|
30117
30244
|
return [skippedMissingSource5("commands", sourceCommandsRoot)];
|
|
30118
30245
|
}
|
|
30119
|
-
const sourceCommands = ts(
|
|
30246
|
+
const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
|
|
30120
30247
|
const workflowsRoot = resolveTargetPath(paths.workflows);
|
|
30121
30248
|
return sourceCommands.map((commandFile) => {
|
|
30122
|
-
const baseName =
|
|
30123
|
-
const destination =
|
|
30124
|
-
const commandContent =
|
|
30125
|
-
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)}`;
|
|
30126
30253
|
const marker = formatProvenanceMarker(
|
|
30127
30254
|
"markdown",
|
|
30128
30255
|
relativeSource,
|
|
@@ -30157,9 +30284,9 @@ ${commandContent.trim()}
|
|
|
30157
30284
|
});
|
|
30158
30285
|
}
|
|
30159
30286
|
function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30160
|
-
const source =
|
|
30287
|
+
const source = path42.resolve(sourceRoot, config.source.skills);
|
|
30161
30288
|
const destination = resolveTargetPath(paths.skills);
|
|
30162
|
-
if (!
|
|
30289
|
+
if (!fs42.existsSync(source)) {
|
|
30163
30290
|
return skippedMissingSource5("skills", source);
|
|
30164
30291
|
}
|
|
30165
30292
|
if (options.dryRun) {
|
|
@@ -30183,15 +30310,15 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
30183
30310
|
// unsynced.
|
|
30184
30311
|
artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)
|
|
30185
30312
|
) {
|
|
30186
|
-
|
|
30313
|
+
fs42.unlinkSync(destination);
|
|
30187
30314
|
} else if (artifactClass === "unmanaged-conflict") {
|
|
30188
30315
|
if (!handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
30189
30316
|
return { component: "skills", status: "conflict", path: destination };
|
|
30190
30317
|
}
|
|
30191
30318
|
} else if (artifactClass === "managed-symlink") {
|
|
30192
|
-
|
|
30319
|
+
fs42.unlinkSync(destination);
|
|
30193
30320
|
}
|
|
30194
|
-
ensureDir(
|
|
30321
|
+
ensureDir(path42.dirname(destination));
|
|
30195
30322
|
createRelativeSymlink(source, destination, "dir");
|
|
30196
30323
|
logger.verbose(`Skills: created Cline skills symlink ${destination}`);
|
|
30197
30324
|
return { component: "skills", status: "success", path: destination };
|
|
@@ -30215,10 +30342,10 @@ function syncMcp5(config, sourceRoot, paths, options, lossReport, logger, manife
|
|
|
30215
30342
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30216
30343
|
const sourceLabel = mcpSourceLabel(config);
|
|
30217
30344
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
30218
|
-
if (!
|
|
30345
|
+
if (!fs42.existsSync(source)) {
|
|
30219
30346
|
return skippedMissingSource5("mcp", source);
|
|
30220
30347
|
}
|
|
30221
|
-
const sourceMcpJson = JSON.parse(
|
|
30348
|
+
const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
|
|
30222
30349
|
const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
|
|
30223
30350
|
if (options.dryRun) {
|
|
30224
30351
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -30261,11 +30388,11 @@ function syncSettings2(lossReport) {
|
|
|
30261
30388
|
};
|
|
30262
30389
|
}
|
|
30263
30390
|
function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
30264
|
-
const agentsDir =
|
|
30265
|
-
if (!
|
|
30266
|
-
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()) {
|
|
30267
30394
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
30268
|
-
const relativeSource = `agents/${
|
|
30395
|
+
const relativeSource = `agents/${path42.basename(agentFile)}`;
|
|
30269
30396
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
30270
30397
|
if (hasCustomProvider) {
|
|
30271
30398
|
addLoss(lossReport, "cline", "agents", {
|
|
@@ -30279,7 +30406,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30279
30406
|
"provider",
|
|
30280
30407
|
"provider-not-representable"
|
|
30281
30408
|
),
|
|
30282
|
-
detail: `${
|
|
30409
|
+
detail: `${path42.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
|
|
30283
30410
|
}
|
|
30284
30411
|
]
|
|
30285
30412
|
});
|
|
@@ -30297,7 +30424,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30297
30424
|
"model",
|
|
30298
30425
|
"model-not-representable"
|
|
30299
30426
|
),
|
|
30300
|
-
detail: `${
|
|
30427
|
+
detail: `${path42.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
|
|
30301
30428
|
}
|
|
30302
30429
|
]
|
|
30303
30430
|
});
|
|
@@ -30312,8 +30439,14 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
|
|
|
30312
30439
|
if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
30313
30440
|
return { component, status: "conflict", path: destination };
|
|
30314
30441
|
}
|
|
30315
|
-
ensureDir(
|
|
30316
|
-
|
|
30442
|
+
ensureDir(path42.dirname(destination));
|
|
30443
|
+
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30444
|
+
if (clearedLink !== null) {
|
|
30445
|
+
logger.verbose(
|
|
30446
|
+
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30447
|
+
);
|
|
30448
|
+
}
|
|
30449
|
+
fs42.writeFileSync(destination, content);
|
|
30317
30450
|
return { component, status: "success", path: destination };
|
|
30318
30451
|
}
|
|
30319
30452
|
function handleConflict5(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30331,18 +30464,18 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
|
|
|
30331
30464
|
if (manifest && scopePath) {
|
|
30332
30465
|
backupFile(destination, manifest, scopePath);
|
|
30333
30466
|
writeManifest(scopePath, manifest);
|
|
30334
|
-
|
|
30467
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
30335
30468
|
} else {
|
|
30336
|
-
|
|
30469
|
+
fs42.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
30337
30470
|
}
|
|
30338
30471
|
return true;
|
|
30339
30472
|
}
|
|
30340
|
-
|
|
30473
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
30341
30474
|
return true;
|
|
30342
30475
|
}
|
|
30343
30476
|
function isCompiledCurrent4(destination, expectedContent, expectedHash) {
|
|
30344
30477
|
try {
|
|
30345
|
-
const current =
|
|
30478
|
+
const current = fs42.readFileSync(destination, "utf8");
|
|
30346
30479
|
const marker = extractProvenanceMarker(current);
|
|
30347
30480
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cline" && current === expectedContent : current === expectedContent;
|
|
30348
30481
|
} catch {
|
|
@@ -30361,7 +30494,7 @@ function shouldSkipComponent5(options, component) {
|
|
|
30361
30494
|
}
|
|
30362
30495
|
function isSymlinkTo6(linkPath, source) {
|
|
30363
30496
|
try {
|
|
30364
|
-
return
|
|
30497
|
+
return fs42.realpathSync(linkPath) === fs42.realpathSync(source);
|
|
30365
30498
|
} catch {
|
|
30366
30499
|
return false;
|
|
30367
30500
|
}
|
|
@@ -30372,9 +30505,9 @@ function hashString4(value) {
|
|
|
30372
30505
|
|
|
30373
30506
|
// src/adapters/opencode.ts
|
|
30374
30507
|
import crypto10 from "crypto";
|
|
30375
|
-
import
|
|
30508
|
+
import fs43 from "fs";
|
|
30376
30509
|
import os6 from "os";
|
|
30377
|
-
import
|
|
30510
|
+
import path43 from "path";
|
|
30378
30511
|
var import_yaml11 = __toESM(require_dist(), 1);
|
|
30379
30512
|
function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30380
30513
|
const scope = options.scope ?? "global";
|
|
@@ -30392,7 +30525,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30392
30525
|
config_doc: profile.config_doc
|
|
30393
30526
|
};
|
|
30394
30527
|
const rules = compileRules(
|
|
30395
|
-
|
|
30528
|
+
path43.join(sourceRoot, config.source.rules),
|
|
30396
30529
|
"opencode",
|
|
30397
30530
|
mappings,
|
|
30398
30531
|
lossReport
|
|
@@ -30496,14 +30629,14 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30496
30629
|
function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
30497
30630
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30498
30631
|
const destination = resolveTargetPath(paths.instructions);
|
|
30499
|
-
const baseContent =
|
|
30632
|
+
const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
|
|
30500
30633
|
const composed = agentsAppendix ? `${baseContent}
|
|
30501
30634
|
|
|
30502
30635
|
--- tangyr managed rules ---
|
|
30503
30636
|
${agentsAppendix}`.trim() : baseContent;
|
|
30504
30637
|
const marker = formatProvenanceMarker(
|
|
30505
30638
|
"markdown",
|
|
30506
|
-
|
|
30639
|
+
path43.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30507
30640
|
hashString5(composed),
|
|
30508
30641
|
"opencode"
|
|
30509
30642
|
);
|
|
@@ -30530,16 +30663,16 @@ ${composed}
|
|
|
30530
30663
|
);
|
|
30531
30664
|
}
|
|
30532
30665
|
function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30533
|
-
const sourceAgentsRoot =
|
|
30534
|
-
if (!
|
|
30666
|
+
const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
|
|
30667
|
+
if (!fs43.existsSync(sourceAgentsRoot)) {
|
|
30535
30668
|
return [skippedMissingSource6("agents", sourceAgentsRoot)];
|
|
30536
30669
|
}
|
|
30537
|
-
const sourceAgents = ts(
|
|
30670
|
+
const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
|
|
30538
30671
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
30539
30672
|
return sourceAgents.map((agentFile) => {
|
|
30540
|
-
const destination =
|
|
30673
|
+
const destination = path43.join(
|
|
30541
30674
|
agentsRoot,
|
|
30542
|
-
`${
|
|
30675
|
+
`${path43.basename(agentFile, ".md")}.md`
|
|
30543
30676
|
);
|
|
30544
30677
|
let compiled;
|
|
30545
30678
|
try {
|
|
@@ -30603,11 +30736,11 @@ function applyProviderModelBinding(compiled, mappings) {
|
|
|
30603
30736
|
return `${before}${(0, import_yaml11.stringify)(fields).trim()}${after}`;
|
|
30604
30737
|
}
|
|
30605
30738
|
function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30606
|
-
const sourceCommandsRoot =
|
|
30607
|
-
if (!
|
|
30739
|
+
const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
|
|
30740
|
+
if (!fs43.existsSync(sourceCommandsRoot)) {
|
|
30608
30741
|
return [skippedMissingSource6("commands", sourceCommandsRoot)];
|
|
30609
30742
|
}
|
|
30610
|
-
const sourceCommands = ts(
|
|
30743
|
+
const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
|
|
30611
30744
|
const commandsRoot = resolveTargetPath(paths.commands);
|
|
30612
30745
|
return sourceCommands.map((commandFile) => {
|
|
30613
30746
|
const { data, body } = parseCommandFile(commandFile);
|
|
@@ -30621,7 +30754,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
|
|
|
30621
30754
|
if (typeof data.model === "string") {
|
|
30622
30755
|
frontmatter.model = data.model;
|
|
30623
30756
|
}
|
|
30624
|
-
const relativeSource = `commands/${
|
|
30757
|
+
const relativeSource = `commands/${path43.basename(commandFile)}`;
|
|
30625
30758
|
const marker = formatProvenanceMarker(
|
|
30626
30759
|
"markdown",
|
|
30627
30760
|
relativeSource,
|
|
@@ -30637,9 +30770,9 @@ ${body.trimEnd()}
|
|
|
30637
30770
|
` : `${marker}
|
|
30638
30771
|
${body.trimEnd()}
|
|
30639
30772
|
`;
|
|
30640
|
-
const destination =
|
|
30773
|
+
const destination = path43.join(
|
|
30641
30774
|
commandsRoot,
|
|
30642
|
-
`${
|
|
30775
|
+
`${path43.basename(commandFile, ".md")}.md`
|
|
30643
30776
|
);
|
|
30644
30777
|
if (options.dryRun) {
|
|
30645
30778
|
logger.info(
|
|
@@ -30666,8 +30799,8 @@ ${body.trimEnd()}
|
|
|
30666
30799
|
});
|
|
30667
30800
|
}
|
|
30668
30801
|
function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
|
|
30669
|
-
const source =
|
|
30670
|
-
if (!
|
|
30802
|
+
const source = path43.resolve(sourceRoot, config.source.skills);
|
|
30803
|
+
if (!fs43.existsSync(source)) {
|
|
30671
30804
|
return skippedMissingSource6(component, source);
|
|
30672
30805
|
}
|
|
30673
30806
|
if (options.dryRun) {
|
|
@@ -30679,13 +30812,13 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
|
|
|
30679
30812
|
return { component, status: "skipped-current", path: destination };
|
|
30680
30813
|
}
|
|
30681
30814
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
30682
|
-
|
|
30815
|
+
fs43.unlinkSync(destination);
|
|
30683
30816
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
30684
30817
|
return { component, status: "conflict", path: destination };
|
|
30685
30818
|
} else if (artifactClass === "managed-symlink") {
|
|
30686
|
-
|
|
30819
|
+
fs43.unlinkSync(destination);
|
|
30687
30820
|
}
|
|
30688
|
-
ensureDir(
|
|
30821
|
+
ensureDir(path43.dirname(destination));
|
|
30689
30822
|
createRelativeSymlink(source, destination, "dir");
|
|
30690
30823
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
30691
30824
|
return { component, status: "success", path: destination };
|
|
@@ -30694,13 +30827,13 @@ function syncMcp6(config, sourceRoot, paths, mappings, options, lossReport, logg
|
|
|
30694
30827
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30695
30828
|
const sourceLabel = mcpSourceLabel(config);
|
|
30696
30829
|
const destination = resolveTargetPath(paths.config_doc);
|
|
30697
|
-
if (!
|
|
30830
|
+
if (!fs43.existsSync(source)) {
|
|
30698
30831
|
if (!options.dryRun) {
|
|
30699
30832
|
syncConfigDoc(paths, {}, lossReport, {}, mappings);
|
|
30700
30833
|
}
|
|
30701
30834
|
return skippedMissingSource6("mcp", source);
|
|
30702
30835
|
}
|
|
30703
|
-
const sourceMcpJson = JSON.parse(
|
|
30836
|
+
const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
|
|
30704
30837
|
const mcpJson = compileMcp(
|
|
30705
30838
|
sourceMcpJson,
|
|
30706
30839
|
"opencode",
|
|
@@ -30766,9 +30899,9 @@ function syncProviderBlock(mappings) {
|
|
|
30766
30899
|
function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
|
|
30767
30900
|
const destination = resolveTargetPath(paths.config_doc);
|
|
30768
30901
|
let existing = {};
|
|
30769
|
-
if (
|
|
30902
|
+
if (fs43.existsSync(destination)) {
|
|
30770
30903
|
try {
|
|
30771
|
-
existing = JSON.parse(
|
|
30904
|
+
existing = JSON.parse(fs43.readFileSync(destination, "utf8"));
|
|
30772
30905
|
} catch {
|
|
30773
30906
|
existing = {};
|
|
30774
30907
|
}
|
|
@@ -30793,8 +30926,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
|
|
|
30793
30926
|
};
|
|
30794
30927
|
}
|
|
30795
30928
|
}
|
|
30796
|
-
ensureDir(
|
|
30797
|
-
|
|
30929
|
+
ensureDir(path43.dirname(destination));
|
|
30930
|
+
fs43.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
30798
30931
|
`);
|
|
30799
30932
|
}
|
|
30800
30933
|
function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
|
|
@@ -30805,8 +30938,14 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
|
|
|
30805
30938
|
if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
30806
30939
|
return { component, status: "conflict", path: destination };
|
|
30807
30940
|
}
|
|
30808
|
-
ensureDir(
|
|
30809
|
-
|
|
30941
|
+
ensureDir(path43.dirname(destination));
|
|
30942
|
+
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30943
|
+
if (clearedLink !== null) {
|
|
30944
|
+
logger.verbose(
|
|
30945
|
+
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30946
|
+
);
|
|
30947
|
+
}
|
|
30948
|
+
fs43.writeFileSync(destination, content);
|
|
30810
30949
|
return { component, status: "success", path: destination };
|
|
30811
30950
|
}
|
|
30812
30951
|
function handleConflict6(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30824,18 +30963,18 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
|
|
|
30824
30963
|
if (manifest && scopePath) {
|
|
30825
30964
|
backupFile(destination, manifest, scopePath);
|
|
30826
30965
|
writeManifest(scopePath, manifest);
|
|
30827
|
-
|
|
30966
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30828
30967
|
} else {
|
|
30829
|
-
|
|
30968
|
+
fs43.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
30830
30969
|
}
|
|
30831
30970
|
return true;
|
|
30832
30971
|
}
|
|
30833
|
-
|
|
30972
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30834
30973
|
return true;
|
|
30835
30974
|
}
|
|
30836
30975
|
function isCompiledCurrent5(destination, expectedContent, expectedHash) {
|
|
30837
30976
|
try {
|
|
30838
|
-
const current =
|
|
30977
|
+
const current = fs43.readFileSync(destination, "utf8");
|
|
30839
30978
|
const marker = extractProvenanceMarker(current);
|
|
30840
30979
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "opencode" && current === expectedContent : current === expectedContent;
|
|
30841
30980
|
} catch {
|
|
@@ -30854,7 +30993,7 @@ function shouldSkipComponent6(options, component) {
|
|
|
30854
30993
|
}
|
|
30855
30994
|
function isSymlinkTo7(linkPath, source) {
|
|
30856
30995
|
try {
|
|
30857
|
-
return
|
|
30996
|
+
return fs43.realpathSync(linkPath) === fs43.realpathSync(source);
|
|
30858
30997
|
} catch {
|
|
30859
30998
|
return false;
|
|
30860
30999
|
}
|
|
@@ -30863,7 +31002,7 @@ function hashString5(value) {
|
|
|
30863
31002
|
return `sha256:${crypto10.createHash("sha256").update(value).digest("hex")}`;
|
|
30864
31003
|
}
|
|
30865
31004
|
function parseCommandFile(commandFile) {
|
|
30866
|
-
const content =
|
|
31005
|
+
const content = fs43.readFileSync(commandFile, "utf8");
|
|
30867
31006
|
if (!content.startsWith("---\n")) {
|
|
30868
31007
|
return { data: {}, body: content };
|
|
30869
31008
|
}
|
|
@@ -30883,7 +31022,7 @@ function parseCommandFile(commandFile) {
|
|
|
30883
31022
|
// src/commands/install.ts
|
|
30884
31023
|
function isBackupablePath(targetPath) {
|
|
30885
31024
|
try {
|
|
30886
|
-
const lstat =
|
|
31025
|
+
const lstat = fs44.lstatSync(targetPath);
|
|
30887
31026
|
return lstat.isSymbolicLink() || lstat.isFile() || lstat.isDirectory();
|
|
30888
31027
|
} catch {
|
|
30889
31028
|
return false;
|
|
@@ -30920,7 +31059,7 @@ async function runInstallCommand(options, logger) {
|
|
|
30920
31059
|
);
|
|
30921
31060
|
}
|
|
30922
31061
|
const kitName = resolvedKitName ?? config.kit;
|
|
30923
|
-
const kitPath = kitPathOverride ?? (options.kitPath ?
|
|
31062
|
+
const kitPath = kitPathOverride ?? (options.kitPath ? path44.resolve(options.kitPath) : config.kitPath);
|
|
30924
31063
|
if (!kitName && !kitPath) {
|
|
30925
31064
|
logger.error(
|
|
30926
31065
|
"No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
|
|
@@ -31025,8 +31164,8 @@ async function runInstallCommand(options, logger) {
|
|
|
31025
31164
|
config: options.config,
|
|
31026
31165
|
scope
|
|
31027
31166
|
});
|
|
31028
|
-
const skillsSource =
|
|
31029
|
-
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";
|
|
31030
31169
|
const foreignSkillsSlots = new Set(
|
|
31031
31170
|
assessResult.findings.filter(
|
|
31032
31171
|
(f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
|
|
@@ -31064,7 +31203,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31064
31203
|
let instructionsLabel;
|
|
31065
31204
|
try {
|
|
31066
31205
|
const resolved = resolveInstructionsSource(kitInfo.path, config);
|
|
31067
|
-
instructionsLabel = resolved ?
|
|
31206
|
+
instructionsLabel = resolved ? path44.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
|
|
31068
31207
|
} catch (err) {
|
|
31069
31208
|
logger.error(
|
|
31070
31209
|
`[dry-run] ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -31092,7 +31231,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31092
31231
|
}
|
|
31093
31232
|
}
|
|
31094
31233
|
logger.info(
|
|
31095
|
-
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${
|
|
31234
|
+
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path44.join(scopePath, "manifest.json")}`
|
|
31096
31235
|
);
|
|
31097
31236
|
return;
|
|
31098
31237
|
}
|
|
@@ -31151,7 +31290,7 @@ ACCEPTED CONFLICTS (posture: ${posture}; ${replaceable.length} target(s)):`
|
|
|
31151
31290
|
logger.info(` - ${finding.path}`);
|
|
31152
31291
|
logger.info(` source: ${sources}`);
|
|
31153
31292
|
logger.info(
|
|
31154
|
-
` action: backup-and-replace${
|
|
31293
|
+
` action: backup-and-replace${fs44.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
|
|
31155
31294
|
);
|
|
31156
31295
|
logger.info(` backup: ${backupLocation}`);
|
|
31157
31296
|
continue;
|
|
@@ -31259,6 +31398,11 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
31259
31398
|
installLossReport
|
|
31260
31399
|
);
|
|
31261
31400
|
}
|
|
31401
|
+
reportContestedInstructions(
|
|
31402
|
+
instructionsByActiveTarget(tools, scope, projectRoot, mappings),
|
|
31403
|
+
(kitInfo.components.rules?.declared.length ?? 0) > 0,
|
|
31404
|
+
logger
|
|
31405
|
+
);
|
|
31262
31406
|
for (const [relativePath, sourcePath] of collectAllFiles(kitInfo, config)) {
|
|
31263
31407
|
addFileToManifest(manifest, {
|
|
31264
31408
|
relativePath,
|
|
@@ -31270,20 +31414,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
31270
31414
|
writeManifest(scopePath, manifest);
|
|
31271
31415
|
logger.info(`
|
|
31272
31416
|
Installation complete: ${installedCount} files installed.`);
|
|
31273
|
-
logger.info(`Manifest written to ${
|
|
31417
|
+
logger.info(`Manifest written to ${path44.join(scopePath, "manifest.json")}`);
|
|
31274
31418
|
logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
|
|
31275
31419
|
logger.info(`Scope: ${scope}`);
|
|
31276
31420
|
logger.info(`Tools: ${tools.join(", ")}`);
|
|
31277
31421
|
reportHookRejections(
|
|
31278
31422
|
installLossReport,
|
|
31279
31423
|
tools,
|
|
31280
|
-
|
|
31424
|
+
path44.resolve(kitInfo.path, "hooks"),
|
|
31281
31425
|
kitInfo.components.hooks.declared
|
|
31282
31426
|
);
|
|
31283
31427
|
const hooksConflict = reportHooksSourceConflict(
|
|
31284
31428
|
installLossReport,
|
|
31285
31429
|
tools,
|
|
31286
|
-
|
|
31430
|
+
path44.resolve(kitInfo.path, "hooks"),
|
|
31287
31431
|
kitInfo.components.hooks.declared
|
|
31288
31432
|
);
|
|
31289
31433
|
if (hooksConflict) {
|
|
@@ -31642,7 +31786,7 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
31642
31786
|
return 0;
|
|
31643
31787
|
}
|
|
31644
31788
|
try {
|
|
31645
|
-
const stat =
|
|
31789
|
+
const stat = fs44.lstatSync(destination);
|
|
31646
31790
|
if (stat.isFile() && !stat.isSymbolicLink()) {
|
|
31647
31791
|
logger.warn(
|
|
31648
31792
|
`${destination}: a regular file occupies the skills slot \u2014 skipping skills. Move or remove it, then re-run install.`
|
|
@@ -31670,17 +31814,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
31670
31814
|
manifest,
|
|
31671
31815
|
scopePath
|
|
31672
31816
|
);
|
|
31673
|
-
const skillsSource =
|
|
31817
|
+
const skillsSource = path44.resolve(kitInfo.path, config.source.skills);
|
|
31674
31818
|
let count = 0;
|
|
31675
31819
|
for (const outcome of outcomes) {
|
|
31676
31820
|
if (outcome.status !== "success" && outcome.status !== "skipped-current") {
|
|
31677
31821
|
continue;
|
|
31678
31822
|
}
|
|
31679
|
-
const skillName =
|
|
31823
|
+
const skillName = path44.basename(outcome.path);
|
|
31680
31824
|
addArtifactToManifest(manifest, {
|
|
31681
31825
|
relativePath: `claude-code/skills/${skillName}`,
|
|
31682
31826
|
path: outcome.path,
|
|
31683
|
-
hash: describeArtifactState(outcome.path) ?? `dir:${
|
|
31827
|
+
hash: describeArtifactState(outcome.path) ?? `dir:${path44.join(skillsSource, skillName)}`,
|
|
31684
31828
|
origin: "tangyr-managed"
|
|
31685
31829
|
});
|
|
31686
31830
|
count++;
|
|
@@ -31694,10 +31838,10 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
31694
31838
|
logger.verbose(` skipped (operator choice): ${placement.destination}`);
|
|
31695
31839
|
continue;
|
|
31696
31840
|
}
|
|
31697
|
-
const destDir =
|
|
31698
|
-
|
|
31841
|
+
const destDir = path44.dirname(placement.destination);
|
|
31842
|
+
fs44.mkdirSync(destDir, { recursive: true });
|
|
31699
31843
|
if (placement.type === "symlink") {
|
|
31700
|
-
if (
|
|
31844
|
+
if (fs44.existsSync(placement.destination) || isSymlink2(placement.destination)) {
|
|
31701
31845
|
removeManagedPath(placement.destination);
|
|
31702
31846
|
}
|
|
31703
31847
|
createRelativeSymlink(
|
|
@@ -31714,7 +31858,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
31714
31858
|
` symlink: ${placement.source} \u2192 ${placement.destination}`
|
|
31715
31859
|
);
|
|
31716
31860
|
} else {
|
|
31717
|
-
|
|
31861
|
+
fs44.copyFileSync(placement.source, placement.destination);
|
|
31718
31862
|
logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
|
|
31719
31863
|
}
|
|
31720
31864
|
addArtifactToManifest(manifest, {
|
|
@@ -31996,11 +32140,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
31996
32140
|
if (outcome.path === mcpFile2) {
|
|
31997
32141
|
return "cline/mcp.json";
|
|
31998
32142
|
}
|
|
31999
|
-
if (outcome.path.startsWith(`${workflowsRoot}${
|
|
32000
|
-
return `cline/workflows/${
|
|
32143
|
+
if (outcome.path.startsWith(`${workflowsRoot}${path44.sep}`)) {
|
|
32144
|
+
return `cline/workflows/${path44.basename(outcome.path)}`;
|
|
32001
32145
|
}
|
|
32002
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32003
|
-
return `cline/rules/${
|
|
32146
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
|
|
32147
|
+
return `cline/rules/${path44.basename(outcome.path)}`;
|
|
32004
32148
|
}
|
|
32005
32149
|
return null;
|
|
32006
32150
|
}
|
|
@@ -32036,14 +32180,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32036
32180
|
if (outcome.path === permissionsFile) {
|
|
32037
32181
|
return "cursor/permissions.json";
|
|
32038
32182
|
}
|
|
32039
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32040
|
-
return `cursor/agents/${
|
|
32183
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
|
|
32184
|
+
return `cursor/agents/${path44.basename(outcome.path)}`;
|
|
32041
32185
|
}
|
|
32042
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32043
|
-
return `cursor/rules/${
|
|
32186
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path44.sep}`)) {
|
|
32187
|
+
return `cursor/rules/${path44.basename(outcome.path)}`;
|
|
32044
32188
|
}
|
|
32045
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
32046
|
-
const rel =
|
|
32189
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
|
|
32190
|
+
const rel = path44.relative(skillsRoot2, outcome.path);
|
|
32047
32191
|
return `cursor/skills/${rel}`;
|
|
32048
32192
|
}
|
|
32049
32193
|
return null;
|
|
@@ -32069,14 +32213,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32069
32213
|
if (outcome.path === skillsSharedRoot) {
|
|
32070
32214
|
return "opencode/skills_shared";
|
|
32071
32215
|
}
|
|
32072
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32073
|
-
return `opencode/agents/${
|
|
32216
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
|
|
32217
|
+
return `opencode/agents/${path44.basename(outcome.path)}`;
|
|
32074
32218
|
}
|
|
32075
|
-
if (outcome.path.startsWith(`${commandsRoot}${
|
|
32076
|
-
return `opencode/commands/${
|
|
32219
|
+
if (outcome.path.startsWith(`${commandsRoot}${path44.sep}`)) {
|
|
32220
|
+
return `opencode/commands/${path44.basename(outcome.path)}`;
|
|
32077
32221
|
}
|
|
32078
32222
|
if (outcome.path === configDocFile) {
|
|
32079
|
-
return `opencode/${
|
|
32223
|
+
return `opencode/${path44.basename(outcome.path)}`;
|
|
32080
32224
|
}
|
|
32081
32225
|
return null;
|
|
32082
32226
|
}
|
|
@@ -32093,26 +32237,26 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32093
32237
|
const hooksRoot = resolveTargetPath(copilot.hooks);
|
|
32094
32238
|
const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
|
|
32095
32239
|
const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
|
|
32096
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
32097
|
-
return `copilot/skills/${
|
|
32240
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path44.sep}`)) {
|
|
32241
|
+
return `copilot/skills/${path44.relative(skillsRoot2, outcome.path)}`;
|
|
32098
32242
|
}
|
|
32099
32243
|
if (outcome.path === skillsRoot2) {
|
|
32100
32244
|
return "copilot/skills";
|
|
32101
32245
|
}
|
|
32102
32246
|
if (instructionsMirror !== null && outcome.path === instructionsMirror) {
|
|
32103
|
-
return `copilot/${
|
|
32247
|
+
return `copilot/${path44.basename(outcome.path)}`;
|
|
32104
32248
|
}
|
|
32105
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32106
|
-
return `copilot/agents/${
|
|
32249
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path44.sep}`)) {
|
|
32250
|
+
return `copilot/agents/${path44.basename(outcome.path)}`;
|
|
32107
32251
|
}
|
|
32108
|
-
if (outcome.path.startsWith(`${promptsRoot}${
|
|
32109
|
-
return `copilot/prompts/${
|
|
32252
|
+
if (outcome.path.startsWith(`${promptsRoot}${path44.sep}`)) {
|
|
32253
|
+
return `copilot/prompts/${path44.basename(outcome.path)}`;
|
|
32110
32254
|
}
|
|
32111
|
-
if (outcome.path.startsWith(`${hooksRoot}${
|
|
32112
|
-
return `copilot/hooks/${
|
|
32255
|
+
if (outcome.path.startsWith(`${hooksRoot}${path44.sep}`)) {
|
|
32256
|
+
return `copilot/hooks/${path44.basename(outcome.path)}`;
|
|
32113
32257
|
}
|
|
32114
32258
|
if (outcome.path === mcpFile2) {
|
|
32115
|
-
return `copilot/${
|
|
32259
|
+
return `copilot/${path44.basename(outcome.path)}`;
|
|
32116
32260
|
}
|
|
32117
32261
|
return null;
|
|
32118
32262
|
}
|
|
@@ -32129,17 +32273,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32129
32273
|
if (outcome.path === skillsRoot) {
|
|
32130
32274
|
return "codex/skills";
|
|
32131
32275
|
}
|
|
32132
|
-
if (outcome.path.startsWith(`${agentsRoot}${
|
|
32133
|
-
return `codex/agents/${
|
|
32276
|
+
if (outcome.path.startsWith(`${agentsRoot}${path44.sep}`)) {
|
|
32277
|
+
return `codex/agents/${path44.basename(outcome.path)}`;
|
|
32134
32278
|
}
|
|
32135
|
-
if (outcome.path.startsWith(`${rulesRoot}${
|
|
32136
|
-
return `codex/rules/${
|
|
32279
|
+
if (outcome.path.startsWith(`${rulesRoot}${path44.sep}`)) {
|
|
32280
|
+
return `codex/rules/${path44.basename(outcome.path)}`;
|
|
32137
32281
|
}
|
|
32138
32282
|
if (outcome.path === hooksFile) {
|
|
32139
|
-
return `codex/${
|
|
32283
|
+
return `codex/${path44.basename(outcome.path)}`;
|
|
32140
32284
|
}
|
|
32141
32285
|
if (outcome.path === mcpFile) {
|
|
32142
|
-
return `codex/${
|
|
32286
|
+
return `codex/${path44.basename(outcome.path)}`;
|
|
32143
32287
|
}
|
|
32144
32288
|
return null;
|
|
32145
32289
|
}
|
|
@@ -32208,8 +32352,8 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
|
|
|
32208
32352
|
rules: resolvedPaths.rules
|
|
32209
32353
|
};
|
|
32210
32354
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32211
|
-
const componentDir =
|
|
32212
|
-
if (
|
|
32355
|
+
const componentDir = path44.join(kitInfo.path, component);
|
|
32356
|
+
if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
|
|
32213
32357
|
placements.push({
|
|
32214
32358
|
source: componentDir,
|
|
32215
32359
|
destination: targetPath,
|
|
@@ -32239,8 +32383,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
|
|
|
32239
32383
|
rules: profile.rules
|
|
32240
32384
|
};
|
|
32241
32385
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32242
|
-
const componentDir =
|
|
32243
|
-
if (
|
|
32386
|
+
const componentDir = path44.join(kitInfo.path, component);
|
|
32387
|
+
if (fs44.existsSync(componentDir) && fs44.statSync(componentDir).isDirectory()) {
|
|
32244
32388
|
placements.push({
|
|
32245
32389
|
source: componentDir,
|
|
32246
32390
|
destination: targetPath,
|
|
@@ -32256,7 +32400,7 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32256
32400
|
const files = /* @__PURE__ */ new Map();
|
|
32257
32401
|
const entrypoint = resolveInstructionsSource(kitInfo.path, config);
|
|
32258
32402
|
if (entrypoint) {
|
|
32259
|
-
files.set(
|
|
32403
|
+
files.set(path44.basename(entrypoint.file), entrypoint.file);
|
|
32260
32404
|
}
|
|
32261
32405
|
for (const [component, reconciliation] of Object.entries(
|
|
32262
32406
|
kitInfo.components
|
|
@@ -32265,22 +32409,22 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32265
32409
|
const missingSet = new Set(reconciliation.missing);
|
|
32266
32410
|
for (const entry of reconciliation.declared) {
|
|
32267
32411
|
if (missingSet.has(entry)) continue;
|
|
32268
|
-
const relPath = isSkills ?
|
|
32269
|
-
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));
|
|
32270
32414
|
}
|
|
32271
32415
|
}
|
|
32272
32416
|
return files;
|
|
32273
32417
|
}
|
|
32274
32418
|
function readLinkTarget(p) {
|
|
32275
32419
|
try {
|
|
32276
|
-
return
|
|
32420
|
+
return fs44.readlinkSync(p);
|
|
32277
32421
|
} catch {
|
|
32278
32422
|
return null;
|
|
32279
32423
|
}
|
|
32280
32424
|
}
|
|
32281
32425
|
function isSymlink2(p) {
|
|
32282
32426
|
try {
|
|
32283
|
-
return
|
|
32427
|
+
return fs44.lstatSync(p).isSymbolicLink();
|
|
32284
32428
|
} catch {
|
|
32285
32429
|
return false;
|
|
32286
32430
|
}
|
|
@@ -32325,14 +32469,14 @@ async function runKitUpdateCommand(options, logger) {
|
|
|
32325
32469
|
}
|
|
32326
32470
|
|
|
32327
32471
|
// src/commands/list.ts
|
|
32328
|
-
import
|
|
32472
|
+
import path45 from "path";
|
|
32329
32473
|
function runListCommand(options, logger) {
|
|
32330
32474
|
let searchPaths = [];
|
|
32331
|
-
let directKitPath = options.kitPath ?
|
|
32475
|
+
let directKitPath = options.kitPath ? path45.resolve(options.kitPath) : void 0;
|
|
32332
32476
|
try {
|
|
32333
32477
|
const { config, configDir } = resolveConfig(options.config);
|
|
32334
32478
|
searchPaths = config.kitSearchPaths ?? [
|
|
32335
|
-
|
|
32479
|
+
path45.join(configDir, "operating-kits")
|
|
32336
32480
|
];
|
|
32337
32481
|
directKitPath = directKitPath ?? config.kitPath;
|
|
32338
32482
|
} catch (err) {
|
|
@@ -32407,7 +32551,7 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32407
32551
|
return kits;
|
|
32408
32552
|
}
|
|
32409
32553
|
const directKit = loadKit(directKitPath);
|
|
32410
|
-
if (kits.some((kit) =>
|
|
32554
|
+
if (kits.some((kit) => path45.resolve(kit.path) === directKit.path)) {
|
|
32411
32555
|
return kits;
|
|
32412
32556
|
}
|
|
32413
32557
|
return [...kits, directKit];
|
|
@@ -32415,8 +32559,8 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32415
32559
|
|
|
32416
32560
|
// src/commands/probe.ts
|
|
32417
32561
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
32418
|
-
import
|
|
32419
|
-
import
|
|
32562
|
+
import fs45 from "fs";
|
|
32563
|
+
import path46 from "path";
|
|
32420
32564
|
function runProbeCommand(options, logger) {
|
|
32421
32565
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32422
32566
|
options,
|
|
@@ -32444,7 +32588,7 @@ function runProbeCommand(options, logger) {
|
|
|
32444
32588
|
toProbeRow(
|
|
32445
32589
|
target,
|
|
32446
32590
|
key,
|
|
32447
|
-
scope === "project" ?
|
|
32591
|
+
scope === "project" ? path46.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
|
|
32448
32592
|
)
|
|
32449
32593
|
);
|
|
32450
32594
|
}
|
|
@@ -32466,7 +32610,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32466
32610
|
const resolved = resolveTargetPath(rawPath);
|
|
32467
32611
|
let accessible = false;
|
|
32468
32612
|
try {
|
|
32469
|
-
|
|
32613
|
+
fs45.accessSync(resolved);
|
|
32470
32614
|
accessible = true;
|
|
32471
32615
|
} catch {
|
|
32472
32616
|
accessible = false;
|
|
@@ -32475,7 +32619,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32475
32619
|
target,
|
|
32476
32620
|
key,
|
|
32477
32621
|
path: resolved,
|
|
32478
|
-
exists:
|
|
32622
|
+
exists: fs45.existsSync(resolved),
|
|
32479
32623
|
accessible
|
|
32480
32624
|
};
|
|
32481
32625
|
}
|
|
@@ -32493,7 +32637,7 @@ function codexRuntimeProbeRows() {
|
|
|
32493
32637
|
["binary_snap", "/snap/bin/codex"],
|
|
32494
32638
|
["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
|
|
32495
32639
|
]) {
|
|
32496
|
-
if (
|
|
32640
|
+
if (fs45.existsSync(candidatePath)) {
|
|
32497
32641
|
rows.push(toProbeRow("codex", key, candidatePath));
|
|
32498
32642
|
}
|
|
32499
32643
|
}
|
|
@@ -32509,8 +32653,8 @@ function commandProbeRows(target, key, command, args) {
|
|
|
32509
32653
|
|
|
32510
32654
|
// src/commands/status.ts
|
|
32511
32655
|
import crypto11 from "crypto";
|
|
32512
|
-
import
|
|
32513
|
-
import
|
|
32656
|
+
import fs46 from "fs";
|
|
32657
|
+
import path47 from "path";
|
|
32514
32658
|
function runStatusCommand(options, logger) {
|
|
32515
32659
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32516
32660
|
options,
|
|
@@ -32616,11 +32760,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
|
|
|
32616
32760
|
}
|
|
32617
32761
|
}
|
|
32618
32762
|
function sourceMarkdownFiles(sourceRoot, componentPath) {
|
|
32619
|
-
const root =
|
|
32620
|
-
if (!
|
|
32763
|
+
const root = path47.join(sourceRoot, componentPath);
|
|
32764
|
+
if (!fs46.existsSync(root)) {
|
|
32621
32765
|
return [];
|
|
32622
32766
|
}
|
|
32623
|
-
return ts(
|
|
32767
|
+
return ts(path47.join(root, "*.md")).sort();
|
|
32624
32768
|
}
|
|
32625
32769
|
function notRepresentableRow(component, detail) {
|
|
32626
32770
|
return {
|
|
@@ -32631,11 +32775,11 @@ function notRepresentableRow(component, detail) {
|
|
|
32631
32775
|
};
|
|
32632
32776
|
}
|
|
32633
32777
|
function readTargetJson(filePath) {
|
|
32634
|
-
if (!
|
|
32778
|
+
if (!fs46.existsSync(filePath)) {
|
|
32635
32779
|
return { kind: "missing" };
|
|
32636
32780
|
}
|
|
32637
32781
|
try {
|
|
32638
|
-
const parsed = JSON.parse(
|
|
32782
|
+
const parsed = JSON.parse(fs46.readFileSync(filePath, "utf8"));
|
|
32639
32783
|
return { kind: "object", value: isRecord(parsed) ? parsed : {} };
|
|
32640
32784
|
} catch (err) {
|
|
32641
32785
|
return {
|
|
@@ -32724,7 +32868,7 @@ function classifyInstructions(filePath, target, expectedHash, config, sourceRoot
|
|
|
32724
32868
|
}
|
|
32725
32869
|
function compiledMcpDocument(config, sourceRoot, target) {
|
|
32726
32870
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
32727
|
-
if (!
|
|
32871
|
+
if (!fs46.existsSync(source)) {
|
|
32728
32872
|
return {};
|
|
32729
32873
|
}
|
|
32730
32874
|
const compiled = compileMcp(
|
|
@@ -32737,7 +32881,7 @@ function compiledMcpDocument(config, sourceRoot, target) {
|
|
|
32737
32881
|
return isRecord(parsed) ? parsed : {};
|
|
32738
32882
|
}
|
|
32739
32883
|
function classifyMcpDocument(config, sourceRoot, target, filePath) {
|
|
32740
|
-
if (!
|
|
32884
|
+
if (!fs46.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
|
|
32741
32885
|
return notConfiguredRow("mcp", filePath);
|
|
32742
32886
|
}
|
|
32743
32887
|
return classifyJsonDocument(
|
|
@@ -32767,12 +32911,12 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
|
|
|
32767
32911
|
const rows = [];
|
|
32768
32912
|
const instructionsSource = instructionsSourcePath(sourceRoot, config);
|
|
32769
32913
|
const rules = compileRules(
|
|
32770
|
-
|
|
32914
|
+
path47.join(sourceRoot, config.source.rules),
|
|
32771
32915
|
"opencode",
|
|
32772
32916
|
mappings,
|
|
32773
32917
|
createLossReport()
|
|
32774
32918
|
);
|
|
32775
|
-
const baseInstructions =
|
|
32919
|
+
const baseInstructions = fs46.existsSync(instructionsSource) ? fs46.readFileSync(instructionsSource, "utf8").trim() : "";
|
|
32776
32920
|
const composedInstructions = rules.agentsAppendix ? `${baseInstructions}
|
|
32777
32921
|
|
|
32778
32922
|
--- tangyr managed rules ---
|
|
@@ -32794,10 +32938,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
32794
32938
|
)) {
|
|
32795
32939
|
rows.push(
|
|
32796
32940
|
classifyCompiledFile(
|
|
32797
|
-
`agents/${
|
|
32798
|
-
|
|
32941
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
32942
|
+
path47.join(
|
|
32799
32943
|
resolveTargetPath(paths.agents),
|
|
32800
|
-
`${
|
|
32944
|
+
`${path47.basename(agentFile, ".md")}.md`
|
|
32801
32945
|
),
|
|
32802
32946
|
"opencode",
|
|
32803
32947
|
computeSourceHash(agentFile),
|
|
@@ -32812,10 +32956,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
32812
32956
|
)) {
|
|
32813
32957
|
rows.push(
|
|
32814
32958
|
classifyCompiledFile(
|
|
32815
|
-
`commands/${
|
|
32816
|
-
|
|
32959
|
+
`commands/${path47.basename(commandFile, ".md")}`,
|
|
32960
|
+
path47.join(
|
|
32817
32961
|
resolveTargetPath(paths.commands),
|
|
32818
|
-
`${
|
|
32962
|
+
`${path47.basename(commandFile, ".md")}.md`
|
|
32819
32963
|
),
|
|
32820
32964
|
"opencode",
|
|
32821
32965
|
computeSourceHash(commandFile),
|
|
@@ -32897,10 +33041,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
32897
33041
|
)) {
|
|
32898
33042
|
rows.push(
|
|
32899
33043
|
classifyCompiledFile(
|
|
32900
|
-
`agents/${
|
|
32901
|
-
|
|
33044
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33045
|
+
path47.join(
|
|
32902
33046
|
resolveTargetPath(paths.agents),
|
|
32903
|
-
`${
|
|
33047
|
+
`${path47.basename(agentFile, ".md")}.md`
|
|
32904
33048
|
),
|
|
32905
33049
|
"cursor",
|
|
32906
33050
|
computeSourceHash(agentFile),
|
|
@@ -32917,7 +33061,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
32917
33061
|
rows.push(
|
|
32918
33062
|
classifyCompiledFile(
|
|
32919
33063
|
`rules/${ruleFile.name}`,
|
|
32920
|
-
|
|
33064
|
+
path47.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
32921
33065
|
"cursor",
|
|
32922
33066
|
void 0,
|
|
32923
33067
|
config,
|
|
@@ -32931,11 +33075,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
32931
33075
|
sourceRoot,
|
|
32932
33076
|
config.source.commands
|
|
32933
33077
|
)) {
|
|
32934
|
-
const baseName =
|
|
33078
|
+
const baseName = path47.basename(commandFile, ".md");
|
|
32935
33079
|
rows.push(
|
|
32936
33080
|
classifyCompiledFile(
|
|
32937
33081
|
`commands/${baseName}`,
|
|
32938
|
-
|
|
33082
|
+
path47.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
|
|
32939
33083
|
"cursor",
|
|
32940
33084
|
computeSourceHash(commandFile),
|
|
32941
33085
|
config,
|
|
@@ -33018,7 +33162,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33018
33162
|
rows.push(
|
|
33019
33163
|
classifyCompiledFile(
|
|
33020
33164
|
`rules/${ruleFile.name}`,
|
|
33021
|
-
|
|
33165
|
+
path47.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
33022
33166
|
"cline",
|
|
33023
33167
|
void 0,
|
|
33024
33168
|
config,
|
|
@@ -33034,10 +33178,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33034
33178
|
)) {
|
|
33035
33179
|
rows.push(
|
|
33036
33180
|
classifyCompiledFile(
|
|
33037
|
-
`commands/${
|
|
33038
|
-
|
|
33181
|
+
`commands/${path47.basename(commandFile, ".md")}`,
|
|
33182
|
+
path47.join(
|
|
33039
33183
|
resolveTargetPath(paths.workflows),
|
|
33040
|
-
|
|
33184
|
+
path47.basename(commandFile)
|
|
33041
33185
|
),
|
|
33042
33186
|
"cline",
|
|
33043
33187
|
computeSourceHash(commandFile),
|
|
@@ -33078,14 +33222,14 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33078
33222
|
return rows;
|
|
33079
33223
|
}
|
|
33080
33224
|
function compileRulesFiles(config, sourceRoot, target, mappings) {
|
|
33081
|
-
const rulesSource =
|
|
33082
|
-
if (!
|
|
33225
|
+
const rulesSource = path47.join(sourceRoot, config.source.rules);
|
|
33226
|
+
if (!fs46.existsSync(rulesSource)) {
|
|
33083
33227
|
return [];
|
|
33084
33228
|
}
|
|
33085
33229
|
return compileRules(rulesSource, target, mappings, createLossReport()).dotRulesFiles;
|
|
33086
33230
|
}
|
|
33087
33231
|
function classifyDirectoryPresence(component, dirPath) {
|
|
33088
|
-
const present =
|
|
33232
|
+
const present = fs46.existsSync(dirPath) && fs46.statSync(dirPath).isDirectory();
|
|
33089
33233
|
return {
|
|
33090
33234
|
component,
|
|
33091
33235
|
className: present ? "current" : "missing",
|
|
@@ -33104,7 +33248,7 @@ function slotsForScope2(scopeMap, scope, projectRoot) {
|
|
|
33104
33248
|
const root = projectRoot ?? process.cwd();
|
|
33105
33249
|
const resolved = {};
|
|
33106
33250
|
for (const [slot, value] of Object.entries(projectSlots)) {
|
|
33107
|
-
resolved[slot] = typeof value === "string" ?
|
|
33251
|
+
resolved[slot] = typeof value === "string" ? path47.resolve(root, value) : value;
|
|
33108
33252
|
}
|
|
33109
33253
|
return resolved;
|
|
33110
33254
|
}
|
|
@@ -33124,21 +33268,21 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33124
33268
|
rules: paths.rules
|
|
33125
33269
|
};
|
|
33126
33270
|
const rules = compileRules(
|
|
33127
|
-
|
|
33271
|
+
path47.join(sourceRoot, config.source.rules),
|
|
33128
33272
|
"codex",
|
|
33129
33273
|
mappings,
|
|
33130
33274
|
createLossReport()
|
|
33131
33275
|
);
|
|
33132
|
-
const instructionsSource =
|
|
33276
|
+
const instructionsSource = fs46.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
|
|
33133
33277
|
const composedInstructions = `${instructionsSource}
|
|
33134
33278
|
|
|
33135
33279
|
--- tangyr managed rules ---
|
|
33136
33280
|
${rules.agentsAppendix}`.trim();
|
|
33137
33281
|
const agentFiles = ts(
|
|
33138
|
-
|
|
33282
|
+
path47.join(sourceRoot, config.source.agents, "*.md")
|
|
33139
33283
|
).sort();
|
|
33140
33284
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33141
|
-
const mcpSource =
|
|
33285
|
+
const mcpSource = path47.join(sourceRoot, config.source.mcp);
|
|
33142
33286
|
const ruleRows = rules.dotRulesFiles.length === 0 ? [
|
|
33143
33287
|
{
|
|
33144
33288
|
component: "rules",
|
|
@@ -33149,7 +33293,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33149
33293
|
] : rules.dotRulesFiles.map(
|
|
33150
33294
|
(ruleFile) => classifyCompiledFile(
|
|
33151
33295
|
`rules/${ruleFile.name}`,
|
|
33152
|
-
|
|
33296
|
+
path47.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
|
|
33153
33297
|
"codex",
|
|
33154
33298
|
void 0,
|
|
33155
33299
|
config,
|
|
@@ -33167,10 +33311,10 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33167
33311
|
),
|
|
33168
33312
|
...agentFiles.map(
|
|
33169
33313
|
(agentFile) => classifyCompiledFile(
|
|
33170
|
-
`agents/${
|
|
33171
|
-
|
|
33314
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33315
|
+
path47.join(
|
|
33172
33316
|
resolveTargetPath(codexPaths.agents),
|
|
33173
|
-
`${
|
|
33317
|
+
`${path47.basename(agentFile, ".md")}.toml`
|
|
33174
33318
|
),
|
|
33175
33319
|
"codex",
|
|
33176
33320
|
computeSourceHash(agentFile),
|
|
@@ -33198,7 +33342,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33198
33342
|
"hooks",
|
|
33199
33343
|
resolveTargetPath(codexPaths.hooksSharedFile)
|
|
33200
33344
|
),
|
|
33201
|
-
|
|
33345
|
+
fs46.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33202
33346
|
"mcp",
|
|
33203
33347
|
resolveTargetPath(codexPaths.mcpSharedFile),
|
|
33204
33348
|
"codex",
|
|
@@ -33264,20 +33408,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33264
33408
|
mcpSharedFile: paths.mcp_shared_file
|
|
33265
33409
|
};
|
|
33266
33410
|
const agentFiles = ts(
|
|
33267
|
-
|
|
33411
|
+
path47.join(sourceRoot, config.source.agents, "*.md")
|
|
33268
33412
|
).sort();
|
|
33269
33413
|
const commandFiles = ts(
|
|
33270
|
-
|
|
33414
|
+
path47.join(sourceRoot, config.source.commands, "*.md")
|
|
33271
33415
|
).sort();
|
|
33272
33416
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33273
|
-
const mcpSource =
|
|
33417
|
+
const mcpSource = path47.join(sourceRoot, config.source.mcp);
|
|
33274
33418
|
return [
|
|
33275
33419
|
...agentFiles.map(
|
|
33276
33420
|
(agentFile) => classifyCompiledFile(
|
|
33277
|
-
`agents/${
|
|
33278
|
-
|
|
33421
|
+
`agents/${path47.basename(agentFile, ".md")}`,
|
|
33422
|
+
path47.join(
|
|
33279
33423
|
resolveTargetPath(copilotPaths.agents),
|
|
33280
|
-
`${
|
|
33424
|
+
`${path47.basename(agentFile, ".md")}.agent.md`
|
|
33281
33425
|
),
|
|
33282
33426
|
"copilot",
|
|
33283
33427
|
computeSourceHash(agentFile),
|
|
@@ -33294,10 +33438,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33294
33438
|
),
|
|
33295
33439
|
...commandFiles.map(
|
|
33296
33440
|
(commandFile) => classifyCompiledFile(
|
|
33297
|
-
`commands/${
|
|
33298
|
-
|
|
33441
|
+
`commands/${path47.basename(commandFile, ".md")}`,
|
|
33442
|
+
path47.join(
|
|
33299
33443
|
resolveTargetPath(copilotPaths.prompts),
|
|
33300
|
-
`${
|
|
33444
|
+
`${path47.basename(commandFile, ".md")}.prompt.md`
|
|
33301
33445
|
),
|
|
33302
33446
|
"copilot",
|
|
33303
33447
|
computeSourceHash(commandFile),
|
|
@@ -33316,19 +33460,19 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33316
33460
|
sourceRoot
|
|
33317
33461
|
),
|
|
33318
33462
|
hooksPresent ? classifyCompiledHooksByProvenance(
|
|
33319
|
-
|
|
33463
|
+
path47.join(
|
|
33320
33464
|
resolveTargetPath(copilotPaths.hooks),
|
|
33321
33465
|
"tangyr-managed.json"
|
|
33322
33466
|
),
|
|
33323
33467
|
"copilot"
|
|
33324
33468
|
) : notConfiguredRow(
|
|
33325
33469
|
"hooks",
|
|
33326
|
-
|
|
33470
|
+
path47.join(
|
|
33327
33471
|
resolveTargetPath(copilotPaths.hooks),
|
|
33328
33472
|
"tangyr-managed.json"
|
|
33329
33473
|
)
|
|
33330
33474
|
),
|
|
33331
|
-
|
|
33475
|
+
fs46.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33332
33476
|
"mcp",
|
|
33333
33477
|
resolveTargetPath(copilotPaths.mcpSharedFile),
|
|
33334
33478
|
"copilot",
|
|
@@ -33348,7 +33492,7 @@ function notConfiguredRow(component, filePath) {
|
|
|
33348
33492
|
}
|
|
33349
33493
|
function classifyDirectArtifact(artifact, config, sourceRoot) {
|
|
33350
33494
|
const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
|
|
33351
|
-
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;
|
|
33352
33496
|
if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
|
|
33353
33497
|
const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
|
|
33354
33498
|
if (perSkill) {
|
|
@@ -33444,11 +33588,11 @@ function classifyClaudeCodeRows(sourceRoot, config, configDir, scope, projectRoo
|
|
|
33444
33588
|
function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
33445
33589
|
let entries;
|
|
33446
33590
|
try {
|
|
33447
|
-
const stat =
|
|
33591
|
+
const stat = fs46.lstatSync(slotPath);
|
|
33448
33592
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
33449
33593
|
return null;
|
|
33450
33594
|
}
|
|
33451
|
-
entries =
|
|
33595
|
+
entries = fs46.readdirSync(slotPath, { withFileTypes: true });
|
|
33452
33596
|
} catch {
|
|
33453
33597
|
return null;
|
|
33454
33598
|
}
|
|
@@ -33457,7 +33601,7 @@ function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
|
33457
33601
|
return null;
|
|
33458
33602
|
}
|
|
33459
33603
|
const ours = links.filter(
|
|
33460
|
-
(entry) => isOurSymlink(
|
|
33604
|
+
(entry) => isOurSymlink(path47.join(slotPath, entry.name), sourceRoot)
|
|
33461
33605
|
);
|
|
33462
33606
|
if (ours.length === 0) {
|
|
33463
33607
|
return null;
|
|
@@ -33469,9 +33613,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
|
|
|
33469
33613
|
classifyHooks(settingsPath),
|
|
33470
33614
|
classifySettings(
|
|
33471
33615
|
settingsPath,
|
|
33472
|
-
|
|
33616
|
+
path47.resolve(sourceRoot, config.source.settings)
|
|
33473
33617
|
),
|
|
33474
|
-
classifyMcp(claudeJsonPath,
|
|
33618
|
+
classifyMcp(claudeJsonPath, path47.resolve(sourceRoot, config.source.mcp))
|
|
33475
33619
|
];
|
|
33476
33620
|
}
|
|
33477
33621
|
function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
|
|
@@ -33568,14 +33712,14 @@ function classifyMcp(filePath, sourcePath) {
|
|
|
33568
33712
|
}
|
|
33569
33713
|
function isSymlinkCurrent(linkPath, sourcePath) {
|
|
33570
33714
|
try {
|
|
33571
|
-
return
|
|
33715
|
+
return fs46.realpathSync(linkPath) === fs46.realpathSync(sourcePath);
|
|
33572
33716
|
} catch {
|
|
33573
33717
|
return false;
|
|
33574
33718
|
}
|
|
33575
33719
|
}
|
|
33576
33720
|
function isCompiledCurrent6(filePath, sourcePath) {
|
|
33577
33721
|
try {
|
|
33578
|
-
const marker = extractProvenanceMarker(
|
|
33722
|
+
const marker = extractProvenanceMarker(fs46.readFileSync(filePath, "utf8"));
|
|
33579
33723
|
return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
|
|
33580
33724
|
} catch {
|
|
33581
33725
|
return false;
|
|
@@ -33605,7 +33749,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
|
|
|
33605
33749
|
}
|
|
33606
33750
|
function readCompiledContent(filePath) {
|
|
33607
33751
|
try {
|
|
33608
|
-
return
|
|
33752
|
+
return fs46.readFileSync(filePath, "utf8");
|
|
33609
33753
|
} catch {
|
|
33610
33754
|
return null;
|
|
33611
33755
|
}
|
|
@@ -33636,8 +33780,8 @@ function hashString6(value) {
|
|
|
33636
33780
|
}
|
|
33637
33781
|
|
|
33638
33782
|
// src/commands/sync.ts
|
|
33639
|
-
import
|
|
33640
|
-
import
|
|
33783
|
+
import fs47 from "fs";
|
|
33784
|
+
import path48 from "path";
|
|
33641
33785
|
|
|
33642
33786
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
33643
33787
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -34307,18 +34451,30 @@ async function runSyncCommand(options, logger) {
|
|
|
34307
34451
|
reportHookRejections(
|
|
34308
34452
|
lossReport,
|
|
34309
34453
|
targets,
|
|
34310
|
-
|
|
34454
|
+
path48.resolve(kitInfo.path, "hooks"),
|
|
34311
34455
|
kitInfo.components.hooks.declared
|
|
34312
34456
|
);
|
|
34313
34457
|
const hooksConflict = reportHooksSourceConflict(
|
|
34314
34458
|
lossReport,
|
|
34315
34459
|
targets,
|
|
34316
|
-
|
|
34460
|
+
path48.resolve(kitInfo.path, "hooks"),
|
|
34317
34461
|
kitInfo.components.hooks.declared
|
|
34318
34462
|
);
|
|
34319
34463
|
if (hooksConflict) {
|
|
34320
34464
|
logger.warn(hooksConflict);
|
|
34321
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
|
+
}
|
|
34322
34478
|
}
|
|
34323
34479
|
writeLossReport(options.lossReport, lossReport);
|
|
34324
34480
|
printOutcomeTable(results);
|
|
@@ -34504,8 +34660,8 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
|
|
|
34504
34660
|
}
|
|
34505
34661
|
}
|
|
34506
34662
|
function resolveKitFilePath(kitPath, relativePath) {
|
|
34507
|
-
const fullPath =
|
|
34508
|
-
return
|
|
34663
|
+
const fullPath = path48.join(kitPath, relativePath);
|
|
34664
|
+
return fs47.existsSync(fullPath) ? fullPath : null;
|
|
34509
34665
|
}
|
|
34510
34666
|
function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
|
|
34511
34667
|
if (removedSourcePaths.length === 0 || !mappings) {
|
|
@@ -34568,9 +34724,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34568
34724
|
}
|
|
34569
34725
|
if (relativePath.startsWith("agents/")) {
|
|
34570
34726
|
removeManagedCompiledArtifact2(
|
|
34571
|
-
|
|
34727
|
+
path48.join(
|
|
34572
34728
|
resolveTargetPath(paths.agents ?? ""),
|
|
34573
|
-
`${
|
|
34729
|
+
`${path48.parse(relativePath).name}.agent.md`
|
|
34574
34730
|
),
|
|
34575
34731
|
"copilot",
|
|
34576
34732
|
relativePath,
|
|
@@ -34580,9 +34736,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34580
34736
|
}
|
|
34581
34737
|
if (relativePath.startsWith("commands/")) {
|
|
34582
34738
|
removeManagedCompiledArtifact2(
|
|
34583
|
-
|
|
34739
|
+
path48.join(
|
|
34584
34740
|
resolveTargetPath(paths.prompts ?? ""),
|
|
34585
|
-
`${
|
|
34741
|
+
`${path48.parse(relativePath).name}.prompt.md`
|
|
34586
34742
|
),
|
|
34587
34743
|
"copilot",
|
|
34588
34744
|
relativePath,
|
|
@@ -34592,7 +34748,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34592
34748
|
}
|
|
34593
34749
|
if (relativePath.endsWith("hooks.json")) {
|
|
34594
34750
|
removeManagedCompiledArtifact2(
|
|
34595
|
-
|
|
34751
|
+
path48.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
|
|
34596
34752
|
"copilot",
|
|
34597
34753
|
relativePath,
|
|
34598
34754
|
logger
|
|
@@ -34622,9 +34778,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
34622
34778
|
}
|
|
34623
34779
|
if (relativePath.startsWith("agents/")) {
|
|
34624
34780
|
removeManagedCompiledArtifact2(
|
|
34625
|
-
|
|
34781
|
+
path48.join(
|
|
34626
34782
|
resolveTargetPath(paths.agents ?? ""),
|
|
34627
|
-
`${
|
|
34783
|
+
`${path48.parse(relativePath).name}.toml`
|
|
34628
34784
|
),
|
|
34629
34785
|
"codex",
|
|
34630
34786
|
relativePath,
|
|
@@ -34634,9 +34790,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
34634
34790
|
}
|
|
34635
34791
|
if (relativePath.startsWith("rules/")) {
|
|
34636
34792
|
removeManagedCompiledArtifact2(
|
|
34637
|
-
|
|
34793
|
+
path48.join(
|
|
34638
34794
|
resolveTargetPath(paths.rules ?? ""),
|
|
34639
|
-
`${
|
|
34795
|
+
`${path48.parse(relativePath).name}.rules`
|
|
34640
34796
|
),
|
|
34641
34797
|
"codex",
|
|
34642
34798
|
relativePath,
|
|
@@ -34675,9 +34831,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
34675
34831
|
}
|
|
34676
34832
|
if (relativePath.startsWith("agents/")) {
|
|
34677
34833
|
removeManagedCompiledArtifact2(
|
|
34678
|
-
|
|
34834
|
+
path48.join(
|
|
34679
34835
|
resolveTargetPath(paths.agents ?? ""),
|
|
34680
|
-
`${
|
|
34836
|
+
`${path48.parse(relativePath).name}.md`
|
|
34681
34837
|
),
|
|
34682
34838
|
"opencode",
|
|
34683
34839
|
relativePath,
|
|
@@ -34687,9 +34843,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
34687
34843
|
}
|
|
34688
34844
|
if (relativePath.startsWith("commands/")) {
|
|
34689
34845
|
removeManagedCompiledArtifact2(
|
|
34690
|
-
|
|
34846
|
+
path48.join(
|
|
34691
34847
|
resolveTargetPath(paths.commands ?? ""),
|
|
34692
|
-
`${
|
|
34848
|
+
`${path48.parse(relativePath).name}.md`
|
|
34693
34849
|
),
|
|
34694
34850
|
"opencode",
|
|
34695
34851
|
relativePath,
|
|
@@ -34721,9 +34877,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34721
34877
|
}
|
|
34722
34878
|
if (relativePath.startsWith("agents/")) {
|
|
34723
34879
|
removeManagedCompiledArtifact2(
|
|
34724
|
-
|
|
34880
|
+
path48.join(
|
|
34725
34881
|
resolveTargetPath(paths.agents ?? ""),
|
|
34726
|
-
`${
|
|
34882
|
+
`${path48.parse(relativePath).name}.md`
|
|
34727
34883
|
),
|
|
34728
34884
|
"cursor",
|
|
34729
34885
|
relativePath,
|
|
@@ -34733,9 +34889,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34733
34889
|
}
|
|
34734
34890
|
if (relativePath.startsWith("rules/")) {
|
|
34735
34891
|
removeManagedCompiledArtifact2(
|
|
34736
|
-
|
|
34892
|
+
path48.join(
|
|
34737
34893
|
resolveTargetPath(paths.rules ?? ""),
|
|
34738
|
-
`${
|
|
34894
|
+
`${path48.parse(relativePath).name}.mdc`
|
|
34739
34895
|
),
|
|
34740
34896
|
"cursor",
|
|
34741
34897
|
relativePath,
|
|
@@ -34745,9 +34901,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34745
34901
|
}
|
|
34746
34902
|
if (relativePath.startsWith("commands/")) {
|
|
34747
34903
|
removeManagedCompiledArtifact2(
|
|
34748
|
-
|
|
34904
|
+
path48.join(
|
|
34749
34905
|
resolveTargetPath(paths.skills ?? ""),
|
|
34750
|
-
|
|
34906
|
+
path48.parse(relativePath).name,
|
|
34751
34907
|
"SKILL.md"
|
|
34752
34908
|
),
|
|
34753
34909
|
"cursor",
|
|
@@ -34791,9 +34947,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
34791
34947
|
}
|
|
34792
34948
|
if (relativePath.startsWith("rules/")) {
|
|
34793
34949
|
removeManagedCompiledArtifact2(
|
|
34794
|
-
|
|
34950
|
+
path48.join(
|
|
34795
34951
|
resolveTargetPath(paths.rules ?? ""),
|
|
34796
|
-
`${
|
|
34952
|
+
`${path48.parse(relativePath).name}.md`
|
|
34797
34953
|
),
|
|
34798
34954
|
"cline",
|
|
34799
34955
|
relativePath,
|
|
@@ -34803,9 +34959,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
34803
34959
|
}
|
|
34804
34960
|
if (relativePath.startsWith("commands/")) {
|
|
34805
34961
|
removeManagedCompiledArtifact2(
|
|
34806
|
-
|
|
34962
|
+
path48.join(
|
|
34807
34963
|
resolveTargetPath(paths.workflows ?? ""),
|
|
34808
|
-
|
|
34964
|
+
path48.basename(relativePath)
|
|
34809
34965
|
),
|
|
34810
34966
|
"cline",
|
|
34811
34967
|
relativePath,
|
|
@@ -34823,17 +34979,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
34823
34979
|
}
|
|
34824
34980
|
}
|
|
34825
34981
|
function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
|
|
34826
|
-
if (!
|
|
34982
|
+
if (!fs47.existsSync(artifactPath)) {
|
|
34827
34983
|
return;
|
|
34828
34984
|
}
|
|
34829
|
-
if (!
|
|
34985
|
+
if (!fs47.statSync(artifactPath).isFile()) {
|
|
34830
34986
|
return;
|
|
34831
34987
|
}
|
|
34832
|
-
const marker = extractProvenanceMarker(
|
|
34988
|
+
const marker = extractProvenanceMarker(fs47.readFileSync(artifactPath, "utf8"));
|
|
34833
34989
|
if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
|
|
34834
34990
|
return;
|
|
34835
34991
|
}
|
|
34836
|
-
|
|
34992
|
+
fs47.rmSync(artifactPath, { force: true });
|
|
34837
34993
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
34838
34994
|
}
|
|
34839
34995
|
function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
@@ -34864,10 +35020,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
|
|
|
34864
35020
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
34865
35021
|
}
|
|
34866
35022
|
function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
34867
|
-
if (!
|
|
35023
|
+
if (!fs47.existsSync(artifactPath)) {
|
|
34868
35024
|
return;
|
|
34869
35025
|
}
|
|
34870
|
-
const content =
|
|
35026
|
+
const content = fs47.readFileSync(artifactPath, "utf8");
|
|
34871
35027
|
const startMarker = "# tangyr: managed mcp start";
|
|
34872
35028
|
const endMarker = "# tangyr: managed mcp end";
|
|
34873
35029
|
const startIndex = content.indexOf(startMarker);
|
|
@@ -34884,19 +35040,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
|
34884
35040
|
const after = content.slice(endIndex + endMarker.length).trimStart();
|
|
34885
35041
|
const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
|
|
34886
35042
|
if (cleaned.length === 0) {
|
|
34887
|
-
|
|
35043
|
+
fs47.rmSync(artifactPath, { force: true });
|
|
34888
35044
|
} else {
|
|
34889
|
-
|
|
35045
|
+
fs47.writeFileSync(artifactPath, `${cleaned}
|
|
34890
35046
|
`);
|
|
34891
35047
|
}
|
|
34892
35048
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
34893
35049
|
}
|
|
34894
35050
|
function readJsonObject5(filePath) {
|
|
34895
|
-
if (!
|
|
35051
|
+
if (!fs47.existsSync(filePath)) {
|
|
34896
35052
|
return null;
|
|
34897
35053
|
}
|
|
34898
35054
|
try {
|
|
34899
|
-
const parsed = JSON.parse(
|
|
35055
|
+
const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
|
|
34900
35056
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
34901
35057
|
} catch {
|
|
34902
35058
|
return null;
|
|
@@ -34910,10 +35066,10 @@ function readJsonMetadata(value) {
|
|
|
34910
35066
|
}
|
|
34911
35067
|
function writeJsonOrRemove2(filePath, parsed) {
|
|
34912
35068
|
if (isEmptyJsonValue2(parsed)) {
|
|
34913
|
-
|
|
35069
|
+
fs47.rmSync(filePath, { force: true });
|
|
34914
35070
|
return;
|
|
34915
35071
|
}
|
|
34916
|
-
|
|
35072
|
+
fs47.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
34917
35073
|
`);
|
|
34918
35074
|
}
|
|
34919
35075
|
function isEmptyJsonValue2(value) {
|
|
@@ -34973,8 +35129,8 @@ function removeManagedHookEntries(value, expectedSource) {
|
|
|
34973
35129
|
}
|
|
34974
35130
|
|
|
34975
35131
|
// src/commands/validate.ts
|
|
34976
|
-
import
|
|
34977
|
-
import
|
|
35132
|
+
import fs48 from "fs";
|
|
35133
|
+
import path49 from "path";
|
|
34978
35134
|
var SUPPORTED_KIT_FORMATS2 = [1];
|
|
34979
35135
|
var SUPPORTED_DISCIPLINE_VERSIONS = [
|
|
34980
35136
|
"0.14.0",
|
|
@@ -35089,12 +35245,12 @@ function checkArchetype(kit) {
|
|
|
35089
35245
|
}
|
|
35090
35246
|
function checkHookScriptsExist(kit) {
|
|
35091
35247
|
const violations = [];
|
|
35092
|
-
const hooksDir =
|
|
35248
|
+
const hooksDir = path49.join(kit.path, "hooks");
|
|
35093
35249
|
const missingSet = new Set(kit.components.hooks.missing);
|
|
35094
35250
|
for (const name of kit.components.hooks.declared) {
|
|
35095
35251
|
if (missingSet.has(name)) continue;
|
|
35096
|
-
const declarationPath =
|
|
35097
|
-
if (!
|
|
35252
|
+
const declarationPath = path49.join(hooksDir, `${name}.md`);
|
|
35253
|
+
if (!fs48.existsSync(declarationPath)) continue;
|
|
35098
35254
|
let data;
|
|
35099
35255
|
try {
|
|
35100
35256
|
({ data } = parseMarkdownFrontmatter(declarationPath));
|
|
@@ -35104,8 +35260,8 @@ function checkHookScriptsExist(kit) {
|
|
|
35104
35260
|
if (typeof data.command === "string" && data.command.trim().length > 0) {
|
|
35105
35261
|
continue;
|
|
35106
35262
|
}
|
|
35107
|
-
const scriptPath =
|
|
35108
|
-
if (!
|
|
35263
|
+
const scriptPath = path49.join(hooksDir, "scripts", `${name}.ts`);
|
|
35264
|
+
if (!fs48.existsSync(scriptPath)) {
|
|
35109
35265
|
violations.push({
|
|
35110
35266
|
code: "hook-script-missing",
|
|
35111
35267
|
location: `hooks/scripts/${name}.ts`,
|
|
@@ -35118,10 +35274,10 @@ function checkHookScriptsExist(kit) {
|
|
|
35118
35274
|
function checkOptionalSourceDocuments(kit) {
|
|
35119
35275
|
const violations = [];
|
|
35120
35276
|
for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
|
|
35121
|
-
const filePath =
|
|
35122
|
-
if (!
|
|
35277
|
+
const filePath = path49.join(kit.path, name);
|
|
35278
|
+
if (!fs48.existsSync(filePath)) continue;
|
|
35123
35279
|
try {
|
|
35124
|
-
const parsed = JSON.parse(
|
|
35280
|
+
const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
|
|
35125
35281
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
35126
35282
|
violations.push({
|
|
35127
35283
|
code: "optional-source-malformed",
|
|
@@ -35143,10 +35299,10 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35143
35299
|
const notices = [];
|
|
35144
35300
|
const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
|
|
35145
35301
|
for (const name of kit.components.skills.declared) {
|
|
35146
|
-
const skillDir =
|
|
35302
|
+
const skillDir = path49.join(kit.path, "skills", name);
|
|
35147
35303
|
let entries;
|
|
35148
35304
|
try {
|
|
35149
|
-
entries =
|
|
35305
|
+
entries = fs48.readdirSync(skillDir, { withFileTypes: true });
|
|
35150
35306
|
} catch {
|
|
35151
35307
|
continue;
|
|
35152
35308
|
}
|
|
@@ -35164,7 +35320,7 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35164
35320
|
return notices;
|
|
35165
35321
|
}
|
|
35166
35322
|
function checkHooksSourceForm(kit) {
|
|
35167
|
-
const hooksDir =
|
|
35323
|
+
const hooksDir = path49.join(kit.path, "hooks");
|
|
35168
35324
|
const message = describeHooksSourceConflict(
|
|
35169
35325
|
hooksDir,
|
|
35170
35326
|
kit.components.hooks.declared
|
|
@@ -35176,12 +35332,12 @@ function checkHooksSourceForm(kit) {
|
|
|
35176
35332
|
} : null;
|
|
35177
35333
|
}
|
|
35178
35334
|
function checkHookDeclarations(kit) {
|
|
35179
|
-
const hooksDir =
|
|
35335
|
+
const hooksDir = path49.join(kit.path, "hooks");
|
|
35180
35336
|
return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
|
|
35181
35337
|
(r) => ({
|
|
35182
35338
|
code: "hook-declaration-invalid",
|
|
35183
|
-
location: `hooks/${
|
|
35184
|
-
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.`
|
|
35185
35341
|
})
|
|
35186
35342
|
);
|
|
35187
35343
|
}
|
|
@@ -35201,11 +35357,11 @@ function checkKitFormatSupported(kit) {
|
|
|
35201
35357
|
function checkEntrypointExists(kit) {
|
|
35202
35358
|
const declared = kit.entrypoint;
|
|
35203
35359
|
const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
|
|
35204
|
-
const entrypointPath =
|
|
35205
|
-
if (
|
|
35360
|
+
const entrypointPath = path49.join(kit.path, entrypoint);
|
|
35361
|
+
if (fs48.existsSync(entrypointPath)) {
|
|
35206
35362
|
return null;
|
|
35207
35363
|
}
|
|
35208
|
-
const legacyPresent = declared === void 0 &&
|
|
35364
|
+
const legacyPresent = declared === void 0 && fs48.existsSync(path49.join(kit.path, LEGACY_ENTRYPOINT));
|
|
35209
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.`;
|
|
35210
35366
|
return {
|
|
35211
35367
|
code: "entrypoint-missing",
|
|
@@ -35264,9 +35420,9 @@ function checkComponentFrontmatter(kit) {
|
|
|
35264
35420
|
const missingSet = new Set(kit.components[cat].missing);
|
|
35265
35421
|
for (const name of kit.components[cat].declared) {
|
|
35266
35422
|
if (missingSet.has(name)) continue;
|
|
35267
|
-
const filePath = cat === "skills" ?
|
|
35268
|
-
if (!
|
|
35269
|
-
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);
|
|
35270
35426
|
try {
|
|
35271
35427
|
const { data } = parseMarkdownFrontmatter(filePath);
|
|
35272
35428
|
for (const field of requiredFields) {
|
|
@@ -35291,10 +35447,10 @@ function checkComponentFrontmatter(kit) {
|
|
|
35291
35447
|
}
|
|
35292
35448
|
function checkReservedRootNames(kit) {
|
|
35293
35449
|
const violations = [];
|
|
35294
|
-
if (!
|
|
35450
|
+
if (!fs48.existsSync(kit.path) || !fs48.statSync(kit.path).isDirectory()) {
|
|
35295
35451
|
return violations;
|
|
35296
35452
|
}
|
|
35297
|
-
const entries =
|
|
35453
|
+
const entries = fs48.readdirSync(kit.path, { withFileTypes: true });
|
|
35298
35454
|
for (const entry of entries) {
|
|
35299
35455
|
if (RESERVED_ROOT_NAMES.includes(entry.name)) {
|
|
35300
35456
|
violations.push({
|
|
@@ -35311,8 +35467,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35311
35467
|
const missingSet = new Set(kit.components.commands.missing);
|
|
35312
35468
|
for (const name of kit.components.commands.declared) {
|
|
35313
35469
|
if (missingSet.has(name)) continue;
|
|
35314
|
-
const filePath =
|
|
35315
|
-
if (!
|
|
35470
|
+
const filePath = path49.join(kit.path, "commands", `${name}.md`);
|
|
35471
|
+
if (!fs48.existsSync(filePath)) continue;
|
|
35316
35472
|
let data;
|
|
35317
35473
|
try {
|
|
35318
35474
|
({ data } = parseMarkdownFrontmatter(filePath));
|
|
@@ -35325,7 +35481,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35325
35481
|
if (!barred) {
|
|
35326
35482
|
violations.push({
|
|
35327
35483
|
code: "command-human-only-model-invocable",
|
|
35328
|
-
location:
|
|
35484
|
+
location: path49.relative(kit.path, filePath),
|
|
35329
35485
|
message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
|
|
35330
35486
|
});
|
|
35331
35487
|
}
|
|
@@ -35334,8 +35490,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35334
35490
|
}
|
|
35335
35491
|
|
|
35336
35492
|
// src/commands/verify.ts
|
|
35337
|
-
import
|
|
35338
|
-
import
|
|
35493
|
+
import fs49 from "fs";
|
|
35494
|
+
import path50 from "path";
|
|
35339
35495
|
function runVerifyCommand(options, logger) {
|
|
35340
35496
|
if (options.target && !isKnownTarget(options.target)) {
|
|
35341
35497
|
throwUnrecognizedTarget(options.target);
|
|
@@ -35516,8 +35672,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
|
|
|
35516
35672
|
if (!slotPath) {
|
|
35517
35673
|
continue;
|
|
35518
35674
|
}
|
|
35519
|
-
const fullPath = subPath ?
|
|
35520
|
-
if (!
|
|
35675
|
+
const fullPath = subPath ? path50.join(slotPath, subPath) : slotPath;
|
|
35676
|
+
if (!fs49.existsSync(fullPath)) {
|
|
35521
35677
|
failures.push(
|
|
35522
35678
|
`claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
|
|
35523
35679
|
);
|