@alessandroraffa/tangyr 3.0.4 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +796 -682
- package/mappings/platform-paths.yaml +23 -1
- 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 path52 = __require("path");
|
|
1376
|
+
var fs51 = __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 (fs51.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 = path52.resolve(baseDir, baseName);
|
|
2389
|
+
if (fs51.existsSync(localBin)) return localBin;
|
|
2390
|
+
if (sourceExt.includes(path52.extname(baseName))) return void 0;
|
|
2391
2391
|
const foundExt = sourceExt.find(
|
|
2392
|
-
(ext) =>
|
|
2392
|
+
(ext) => fs51.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 = fs51.realpathSync(this._scriptPath);
|
|
2405
2405
|
} catch {
|
|
2406
2406
|
resolvedScriptPath = this._scriptPath;
|
|
2407
2407
|
}
|
|
2408
|
-
executableDir =
|
|
2409
|
-
|
|
2408
|
+
executableDir = path52.resolve(
|
|
2409
|
+
path52.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 = path52.basename(
|
|
2417
2417
|
this._scriptPath,
|
|
2418
|
-
|
|
2418
|
+
path52.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(path52.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 = path52.basename(filename, path52.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(path53) {
|
|
3359
|
+
if (path53 === void 0) return this._executableDir;
|
|
3360
|
+
this._executableDir = path53;
|
|
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, path52) {
|
|
3717
|
+
const ctrl = callVisitor(key, node, visitor, path52);
|
|
3718
3718
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3719
|
-
replaceNode(key,
|
|
3720
|
-
return visit_(key, ctrl, visitor,
|
|
3719
|
+
replaceNode(key, path52, ctrl);
|
|
3720
|
+
return visit_(key, ctrl, visitor, path52);
|
|
3721
3721
|
}
|
|
3722
3722
|
if (typeof ctrl !== "symbol") {
|
|
3723
3723
|
if (identity.isCollection(node)) {
|
|
3724
|
-
|
|
3724
|
+
path52 = Object.freeze(path52.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, path52);
|
|
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
|
+
path52 = Object.freeze(path52.concat(node));
|
|
3738
|
+
const ck = visit_("key", node.key, visitor, path52);
|
|
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, path52);
|
|
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, path52) {
|
|
3765
|
+
const ctrl = await callVisitor(key, node, visitor, path52);
|
|
3766
3766
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3767
|
-
replaceNode(key,
|
|
3768
|
-
return visitAsync_(key, ctrl, visitor,
|
|
3767
|
+
replaceNode(key, path52, ctrl);
|
|
3768
|
+
return visitAsync_(key, ctrl, visitor, path52);
|
|
3769
3769
|
}
|
|
3770
3770
|
if (typeof ctrl !== "symbol") {
|
|
3771
3771
|
if (identity.isCollection(node)) {
|
|
3772
|
-
|
|
3772
|
+
path52 = Object.freeze(path52.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, path52);
|
|
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
|
+
path52 = Object.freeze(path52.concat(node));
|
|
3786
|
+
const ck = await visitAsync_("key", node.key, visitor, path52);
|
|
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, path52);
|
|
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, path52) {
|
|
3819
3819
|
if (typeof visitor === "function")
|
|
3820
|
-
return visitor(key, node,
|
|
3820
|
+
return visitor(key, node, path52);
|
|
3821
3821
|
if (identity.isMap(node))
|
|
3822
|
-
return visitor.Map?.(key, node,
|
|
3822
|
+
return visitor.Map?.(key, node, path52);
|
|
3823
3823
|
if (identity.isSeq(node))
|
|
3824
|
-
return visitor.Seq?.(key, node,
|
|
3824
|
+
return visitor.Seq?.(key, node, path52);
|
|
3825
3825
|
if (identity.isPair(node))
|
|
3826
|
-
return visitor.Pair?.(key, node,
|
|
3826
|
+
return visitor.Pair?.(key, node, path52);
|
|
3827
3827
|
if (identity.isScalar(node))
|
|
3828
|
-
return visitor.Scalar?.(key, node,
|
|
3828
|
+
return visitor.Scalar?.(key, node, path52);
|
|
3829
3829
|
if (identity.isAlias(node))
|
|
3830
|
-
return visitor.Alias?.(key, node,
|
|
3830
|
+
return visitor.Alias?.(key, node, path52);
|
|
3831
3831
|
return void 0;
|
|
3832
3832
|
}
|
|
3833
|
-
function replaceNode(key,
|
|
3834
|
-
const parent =
|
|
3833
|
+
function replaceNode(key, path52, node) {
|
|
3834
|
+
const parent = path52[path52.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, path52, value) {
|
|
4443
4443
|
let v2 = value;
|
|
4444
|
-
for (let i =
|
|
4445
|
-
const k2 =
|
|
4444
|
+
for (let i = path52.length - 1; i >= 0; --i) {
|
|
4445
|
+
const k2 = path52[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 = (path52) => path52 == null || typeof path52 === "object" && !!path52[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(path52, value) {
|
|
4495
|
+
if (isEmptyPath(path52))
|
|
4496
4496
|
this.add(value);
|
|
4497
4497
|
else {
|
|
4498
|
-
const [key, ...rest] =
|
|
4498
|
+
const [key, ...rest] = path52;
|
|
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(path52) {
|
|
4513
|
+
const [key, ...rest] = path52;
|
|
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(path52, keepScalar) {
|
|
4528
|
+
const [key, ...rest] = path52;
|
|
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(path52) {
|
|
4547
|
+
const [key, ...rest] = path52;
|
|
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(path52, value) {
|
|
4558
|
+
const [key, ...rest] = path52;
|
|
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(path52, value) {
|
|
7071
7071
|
if (assertCollection(this.contents))
|
|
7072
|
-
this.contents.addIn(
|
|
7072
|
+
this.contents.addIn(path52, 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(path52) {
|
|
7148
|
+
if (Collection.isEmptyPath(path52)) {
|
|
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(path52) : 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(path52, keepScalar) {
|
|
7170
|
+
if (Collection.isEmptyPath(path52))
|
|
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(path52, 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(path52) {
|
|
7184
|
+
if (Collection.isEmptyPath(path52))
|
|
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(path52) : 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(path52, value) {
|
|
7204
|
+
if (Collection.isEmptyPath(path52)) {
|
|
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(path52), value);
|
|
7208
7208
|
} else if (assertCollection(this.contents)) {
|
|
7209
|
-
this.contents.setIn(
|
|
7209
|
+
this.contents.setIn(path52, 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, path52) => {
|
|
9167
9167
|
let item = cst;
|
|
9168
|
-
for (const [field, index] of
|
|
9168
|
+
for (const [field, index] of path52) {
|
|
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, path52) => {
|
|
9178
|
+
const parent = visit.itemAtPath(cst, path52.slice(0, -1));
|
|
9179
|
+
const field = path52[path52.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(path52, item, visitor) {
|
|
9186
|
+
let ctrl = visitor(item, path52);
|
|
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(path52.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, path52);
|
|
9205
9205
|
}
|
|
9206
9206
|
}
|
|
9207
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
9207
|
+
return typeof ctrl === "function" ? ctrl(item, path52) : 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 fs51 = this.flowScalar(this.type);
|
|
10493
10493
|
if (atNextItem || it2.value) {
|
|
10494
|
-
map.items.push({ start, key:
|
|
10494
|
+
map.items.push({ start, key: fs51, sep: [] });
|
|
10495
10495
|
this.onKeyLine = true;
|
|
10496
10496
|
} else if (it2.sep) {
|
|
10497
|
-
this.stack.push(
|
|
10497
|
+
this.stack.push(fs51);
|
|
10498
10498
|
} else {
|
|
10499
|
-
Object.assign(it2, { key:
|
|
10499
|
+
Object.assign(it2, { key: fs51, 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 fs51 = this.flowScalar(this.type);
|
|
10628
10628
|
if (!it2 || it2.value)
|
|
10629
|
-
fc.items.push({ start: [], key:
|
|
10629
|
+
fc.items.push({ start: [], key: fs51, sep: [] });
|
|
10630
10630
|
else if (it2.sep)
|
|
10631
|
-
this.stack.push(
|
|
10631
|
+
this.stack.push(fs51);
|
|
10632
10632
|
else
|
|
10633
|
-
Object.assign(it2, { key:
|
|
10633
|
+
Object.assign(it2, { key: fs51, sep: [] });
|
|
10634
10634
|
return;
|
|
10635
10635
|
}
|
|
10636
10636
|
case "flow-map-end":
|
|
@@ -15320,6 +15320,13 @@ function extractProvenanceMarker(content) {
|
|
|
15320
15320
|
if (jsonProvenance) {
|
|
15321
15321
|
return jsonProvenance;
|
|
15322
15322
|
}
|
|
15323
|
+
const yamlMarker = /(?:^|\n)x-(?:tangyr|proteus):\s*\n\s+source:\s*(\S+)\s*\n\s+hash:\s*(sha256:[a-f0-9]+)\s*\n\s+target:\s*(\S+)/u.exec(
|
|
15324
|
+
content
|
|
15325
|
+
);
|
|
15326
|
+
const yamlProvenance = markerFromMatch(yamlMarker);
|
|
15327
|
+
if (yamlProvenance) {
|
|
15328
|
+
return yamlProvenance;
|
|
15329
|
+
}
|
|
15323
15330
|
return null;
|
|
15324
15331
|
}
|
|
15325
15332
|
function markerFromMatch(match) {
|
|
@@ -16490,7 +16497,10 @@ function resolveCopilotProfile(scope, projectRoot, mappings) {
|
|
|
16490
16497
|
hooks: r(slotMap, "hooks"),
|
|
16491
16498
|
hook_scripts: r(slotMap, "hook_scripts"),
|
|
16492
16499
|
mcp_shared_file: r(slotMap, "mcp_shared_file"),
|
|
16493
|
-
instructions
|
|
16500
|
+
instructions,
|
|
16501
|
+
// Project-only, like instructions: `.github/instructions` is a repository
|
|
16502
|
+
// surface and has no user-level equivalent Copilot documents.
|
|
16503
|
+
rules: r(slotMap, "rules")
|
|
16494
16504
|
};
|
|
16495
16505
|
}
|
|
16496
16506
|
function resolveCodexProfile(scope, projectRoot, mappings) {
|
|
@@ -25213,8 +25223,8 @@ function toConflictPolicy2(value) {
|
|
|
25213
25223
|
}
|
|
25214
25224
|
|
|
25215
25225
|
// src/commands/install.ts
|
|
25216
|
-
import
|
|
25217
|
-
import
|
|
25226
|
+
import fs45 from "fs";
|
|
25227
|
+
import path45 from "path";
|
|
25218
25228
|
|
|
25219
25229
|
// src/core/channel-state.ts
|
|
25220
25230
|
import fs32 from "fs";
|
|
@@ -26980,8 +26990,8 @@ function isRecord3(value) {
|
|
|
26980
26990
|
// src/adapters/codex.ts
|
|
26981
26991
|
var TOML3 = __toESM(require_toml(), 1);
|
|
26982
26992
|
import crypto6 from "crypto";
|
|
26983
|
-
import
|
|
26984
|
-
import
|
|
26993
|
+
import fs40 from "fs";
|
|
26994
|
+
import path39 from "path";
|
|
26985
26995
|
|
|
26986
26996
|
// src/compiler/agents.ts
|
|
26987
26997
|
var TOML = __toESM(require_toml(), 1);
|
|
@@ -27779,6 +27789,45 @@ function addHookLoss(lossReport, target, eventName, sourceLabel, severity, reaso
|
|
|
27779
27789
|
});
|
|
27780
27790
|
}
|
|
27781
27791
|
|
|
27792
|
+
// src/compiler/command-as-skill.ts
|
|
27793
|
+
var import_yaml9 = __toESM(require_dist(), 1);
|
|
27794
|
+
import fs38 from "fs";
|
|
27795
|
+
import path37 from "path";
|
|
27796
|
+
var CARRIED_OVER = ["argument-hint", "agent", "launch"];
|
|
27797
|
+
function compileCommandAsSkill(commandFile, target) {
|
|
27798
|
+
const name = path37.basename(commandFile, ".md");
|
|
27799
|
+
const { data, body } = parseMarkdownFrontmatter(commandFile);
|
|
27800
|
+
const relativeSource = `commands/${path37.basename(commandFile)}`;
|
|
27801
|
+
const description = typeof data.description === "string" && data.description.trim().length > 0 ? data.description.trim() : `The ${name} command.`;
|
|
27802
|
+
const frontmatter = { name, description };
|
|
27803
|
+
for (const key of CARRIED_OVER) {
|
|
27804
|
+
if (data[key] !== void 0) {
|
|
27805
|
+
frontmatter[key] = data[key];
|
|
27806
|
+
}
|
|
27807
|
+
}
|
|
27808
|
+
frontmatter["disable-model-invocation"] = true;
|
|
27809
|
+
frontmatter["x-tangyr"] = {
|
|
27810
|
+
source: relativeSource,
|
|
27811
|
+
hash: computeSourceHash(commandFile),
|
|
27812
|
+
target
|
|
27813
|
+
};
|
|
27814
|
+
const content = `---
|
|
27815
|
+
${(0, import_yaml9.stringify)(frontmatter).trimEnd()}
|
|
27816
|
+
---
|
|
27817
|
+
|
|
27818
|
+
${body.trim()}
|
|
27819
|
+
`;
|
|
27820
|
+
return { name, content, relativeSource };
|
|
27821
|
+
}
|
|
27822
|
+
function compileCommandsAsSkills(commandsRoot, target) {
|
|
27823
|
+
if (!fs38.existsSync(commandsRoot)) {
|
|
27824
|
+
return [];
|
|
27825
|
+
}
|
|
27826
|
+
return fs38.readdirSync(commandsRoot).filter((entry) => entry.endsWith(".md")).sort().map(
|
|
27827
|
+
(entry) => compileCommandAsSkill(path37.join(commandsRoot, entry), target)
|
|
27828
|
+
);
|
|
27829
|
+
}
|
|
27830
|
+
|
|
27782
27831
|
// src/compiler/mcp.ts
|
|
27783
27832
|
var TOML2 = __toESM(require_toml(), 1);
|
|
27784
27833
|
import crypto5 from "crypto";
|
|
@@ -28058,9 +28107,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
|
|
|
28058
28107
|
}
|
|
28059
28108
|
|
|
28060
28109
|
// src/compiler/rules.ts
|
|
28061
|
-
import
|
|
28062
|
-
var
|
|
28063
|
-
import
|
|
28110
|
+
import path38 from "path";
|
|
28111
|
+
var import_yaml10 = __toESM(require_dist(), 1);
|
|
28112
|
+
import fs39 from "fs";
|
|
28064
28113
|
function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
28065
28114
|
if (target === "copilot") {
|
|
28066
28115
|
addLoss(lossReport, "copilot", "rules", {
|
|
@@ -28097,13 +28146,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
|
28097
28146
|
}
|
|
28098
28147
|
const appendixParts = [];
|
|
28099
28148
|
const dotRulesFiles = [];
|
|
28100
|
-
for (const ruleFile of ts(
|
|
28149
|
+
for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
|
|
28101
28150
|
const parsed = parseRule(ruleFile);
|
|
28102
|
-
const name =
|
|
28151
|
+
const name = path38.basename(ruleFile, ".md");
|
|
28103
28152
|
if (parsed.mode === "exec-policy") {
|
|
28104
28153
|
dotRulesFiles.push({
|
|
28105
28154
|
name: `${name}.rules`,
|
|
28106
|
-
content: `${formatProvenanceMarker("toml", `rules/${
|
|
28155
|
+
content: `${formatProvenanceMarker("toml", `rules/${path38.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
|
|
28107
28156
|
${parsed.body}`
|
|
28108
28157
|
});
|
|
28109
28158
|
continue;
|
|
@@ -28112,7 +28161,7 @@ ${parsed.body}`
|
|
|
28112
28161
|
|
|
28113
28162
|
${parsed.body.trim()}`);
|
|
28114
28163
|
addLoss(lossReport, "codex", "rules", {
|
|
28115
|
-
source: `rules/${
|
|
28164
|
+
source: `rules/${path38.basename(ruleFile)}`,
|
|
28116
28165
|
fields: [
|
|
28117
28166
|
{
|
|
28118
28167
|
field: "mode",
|
|
@@ -28122,7 +28171,7 @@ ${parsed.body.trim()}`);
|
|
|
28122
28171
|
"mode",
|
|
28123
28172
|
"rule-as-instruction"
|
|
28124
28173
|
),
|
|
28125
|
-
detail: `${
|
|
28174
|
+
detail: `${path38.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
|
|
28126
28175
|
}
|
|
28127
28176
|
]
|
|
28128
28177
|
});
|
|
@@ -28130,7 +28179,7 @@ ${parsed.body.trim()}`);
|
|
|
28130
28179
|
return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
|
|
28131
28180
|
}
|
|
28132
28181
|
function parseRule(ruleFile) {
|
|
28133
|
-
const content =
|
|
28182
|
+
const content = fs39.readFileSync(ruleFile, "utf8");
|
|
28134
28183
|
if (!content.startsWith("---\n")) {
|
|
28135
28184
|
return { mode: "guidance", body: content };
|
|
28136
28185
|
}
|
|
@@ -28138,7 +28187,7 @@ function parseRule(ruleFile) {
|
|
|
28138
28187
|
if (endIndex === -1) {
|
|
28139
28188
|
throw new Error(`${ruleFile}: frontmatter is not closed`);
|
|
28140
28189
|
}
|
|
28141
|
-
const frontmatter = (0,
|
|
28190
|
+
const frontmatter = (0, import_yaml10.parse)(content.slice(4, endIndex));
|
|
28142
28191
|
const mode = isRuleMode(frontmatter) ? frontmatter.mode : "guidance";
|
|
28143
28192
|
return {
|
|
28144
28193
|
mode,
|
|
@@ -28154,14 +28203,14 @@ function isRuleMode(value) {
|
|
|
28154
28203
|
}
|
|
28155
28204
|
function compileOpenCodeRules(sourceRulesDir, lossReport) {
|
|
28156
28205
|
const appendixParts = [];
|
|
28157
|
-
for (const ruleFile of ts(
|
|
28206
|
+
for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
|
|
28158
28207
|
const parsed = parseRule(ruleFile);
|
|
28159
|
-
const name =
|
|
28208
|
+
const name = path38.basename(ruleFile, ".md");
|
|
28160
28209
|
appendixParts.push(`## ${name}
|
|
28161
28210
|
|
|
28162
28211
|
${parsed.body.trim()}`);
|
|
28163
28212
|
addLoss(lossReport, "opencode", "rules", {
|
|
28164
|
-
source: `rules/${
|
|
28213
|
+
source: `rules/${path38.basename(ruleFile)}`,
|
|
28165
28214
|
fields: [
|
|
28166
28215
|
{
|
|
28167
28216
|
field: "rule",
|
|
@@ -28171,7 +28220,7 @@ ${parsed.body.trim()}`);
|
|
|
28171
28220
|
"rule",
|
|
28172
28221
|
"rule-path-scoping"
|
|
28173
28222
|
),
|
|
28174
|
-
detail: `${
|
|
28223
|
+
detail: `${path38.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
|
|
28175
28224
|
}
|
|
28176
28225
|
]
|
|
28177
28226
|
});
|
|
@@ -28180,9 +28229,9 @@ ${parsed.body.trim()}`);
|
|
|
28180
28229
|
}
|
|
28181
28230
|
function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
28182
28231
|
const dotRulesFiles = [];
|
|
28183
|
-
for (const ruleFile of ts(
|
|
28184
|
-
const content =
|
|
28185
|
-
const name =
|
|
28232
|
+
for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
|
|
28233
|
+
const content = fs39.readFileSync(ruleFile, "utf8");
|
|
28234
|
+
const name = path38.basename(ruleFile, ".md");
|
|
28186
28235
|
let frontmatterData = {};
|
|
28187
28236
|
let body = content;
|
|
28188
28237
|
if (content.startsWith("---\n")) {
|
|
@@ -28190,7 +28239,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
|
28190
28239
|
if (endIndex !== -1) {
|
|
28191
28240
|
const frontmatterStr = content.slice(4, endIndex);
|
|
28192
28241
|
try {
|
|
28193
|
-
frontmatterData = (0,
|
|
28242
|
+
frontmatterData = (0, import_yaml10.parse)(frontmatterStr) ?? {};
|
|
28194
28243
|
} catch {
|
|
28195
28244
|
frontmatterData = {};
|
|
28196
28245
|
}
|
|
@@ -28211,7 +28260,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
|
28211
28260
|
}
|
|
28212
28261
|
const marker = formatProvenanceMarker(
|
|
28213
28262
|
"markdown",
|
|
28214
|
-
`rules/${
|
|
28263
|
+
`rules/${path38.basename(ruleFile)}`,
|
|
28215
28264
|
computeSourceHash(ruleFile),
|
|
28216
28265
|
"cursor"
|
|
28217
28266
|
);
|
|
@@ -28227,9 +28276,9 @@ ${body}`;
|
|
|
28227
28276
|
}
|
|
28228
28277
|
function compileClineRules(sourceRulesDir, lossReport) {
|
|
28229
28278
|
const dotRulesFiles = [];
|
|
28230
|
-
for (const ruleFile of ts(
|
|
28231
|
-
const content =
|
|
28232
|
-
const name =
|
|
28279
|
+
for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
|
|
28280
|
+
const content = fs39.readFileSync(ruleFile, "utf8");
|
|
28281
|
+
const name = path38.basename(ruleFile, ".md");
|
|
28233
28282
|
let frontmatterData = {};
|
|
28234
28283
|
let body = content;
|
|
28235
28284
|
if (content.startsWith("---\n")) {
|
|
@@ -28237,7 +28286,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28237
28286
|
if (endIndex !== -1) {
|
|
28238
28287
|
const frontmatterStr = content.slice(4, endIndex);
|
|
28239
28288
|
try {
|
|
28240
|
-
frontmatterData = (0,
|
|
28289
|
+
frontmatterData = (0, import_yaml10.parse)(frontmatterStr) ?? {};
|
|
28241
28290
|
} catch {
|
|
28242
28291
|
frontmatterData = {};
|
|
28243
28292
|
}
|
|
@@ -28246,13 +28295,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28246
28295
|
}
|
|
28247
28296
|
const marker = formatProvenanceMarker(
|
|
28248
28297
|
"markdown",
|
|
28249
|
-
`rules/${
|
|
28298
|
+
`rules/${path38.basename(ruleFile)}`,
|
|
28250
28299
|
computeSourceHash(ruleFile),
|
|
28251
28300
|
"cline"
|
|
28252
28301
|
);
|
|
28253
28302
|
if (frontmatterData.mode === "exec-policy") {
|
|
28254
28303
|
addLoss(lossReport, "cline", "rules", {
|
|
28255
|
-
source: `rules/${
|
|
28304
|
+
source: `rules/${path38.basename(ruleFile)}`,
|
|
28256
28305
|
fields: [
|
|
28257
28306
|
{
|
|
28258
28307
|
field: "mode",
|
|
@@ -28262,7 +28311,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28262
28311
|
"mode",
|
|
28263
28312
|
"rule-mode-downgrade"
|
|
28264
28313
|
),
|
|
28265
|
-
detail: `${
|
|
28314
|
+
detail: `${path38.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
|
|
28266
28315
|
}
|
|
28267
28316
|
]
|
|
28268
28317
|
});
|
|
@@ -28281,14 +28330,39 @@ ${frontmatterYaml}${body}`;
|
|
|
28281
28330
|
}
|
|
28282
28331
|
return { agentsAppendix: "", dotRulesFiles };
|
|
28283
28332
|
}
|
|
28333
|
+
function compileCopilotRules(sourceRulesDir) {
|
|
28334
|
+
if (!fs39.existsSync(sourceRulesDir)) {
|
|
28335
|
+
return [];
|
|
28336
|
+
}
|
|
28337
|
+
const files = [];
|
|
28338
|
+
for (const ruleFile of ts(path38.join(sourceRulesDir, "*.md")).sort()) {
|
|
28339
|
+
const name = path38.basename(ruleFile, ".md");
|
|
28340
|
+
const { data } = parseMarkdownFrontmatter(ruleFile);
|
|
28341
|
+
const { body } = parseRule(ruleFile);
|
|
28342
|
+
const declared = data.paths;
|
|
28343
|
+
const applyTo = Array.isArray(declared) ? declared.filter((p) => typeof p === "string").join(", ") : typeof declared === "string" && declared.trim() !== "" ? declared.trim() : "**";
|
|
28344
|
+
const frontmatter = [
|
|
28345
|
+
"---",
|
|
28346
|
+
`applyTo: ${JSON.stringify(applyTo)}`,
|
|
28347
|
+
"x-tangyr:",
|
|
28348
|
+
` source: rules/${path38.basename(ruleFile)}`,
|
|
28349
|
+
` hash: ${computeSourceHash(ruleFile)}`,
|
|
28350
|
+
" target: copilot",
|
|
28351
|
+
"---"
|
|
28352
|
+
].join("\n");
|
|
28353
|
+
files.push({
|
|
28354
|
+
name: `${name}.instructions.md`,
|
|
28355
|
+
content: `${frontmatter}
|
|
28356
|
+
|
|
28357
|
+
${body.trim()}
|
|
28358
|
+
`
|
|
28359
|
+
});
|
|
28360
|
+
}
|
|
28361
|
+
return files;
|
|
28362
|
+
}
|
|
28284
28363
|
|
|
28285
28364
|
// src/adapters/codex.ts
|
|
28286
|
-
var skippedComponents = [
|
|
28287
|
-
"commands",
|
|
28288
|
-
"settings",
|
|
28289
|
-
"lsp",
|
|
28290
|
-
"output-styles"
|
|
28291
|
-
];
|
|
28365
|
+
var skippedComponents = ["settings", "lsp", "output-styles"];
|
|
28292
28366
|
var managedMcpStart = "# tangyr: managed mcp start";
|
|
28293
28367
|
var managedMcpEnd = "# tangyr: managed mcp end";
|
|
28294
28368
|
function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
@@ -28308,7 +28382,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28308
28382
|
rules: profile.rules
|
|
28309
28383
|
};
|
|
28310
28384
|
const rules = compileRules(
|
|
28311
|
-
|
|
28385
|
+
path39.join(sourceRoot, config.source.rules),
|
|
28312
28386
|
"codex",
|
|
28313
28387
|
mappings,
|
|
28314
28388
|
lossReport
|
|
@@ -28344,7 +28418,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28344
28418
|
}
|
|
28345
28419
|
if (!shouldSkipComponent2(options, "skills")) {
|
|
28346
28420
|
outcomes.push(
|
|
28347
|
-
syncSkills(
|
|
28421
|
+
...syncSkills(
|
|
28348
28422
|
config,
|
|
28349
28423
|
sourceRoot,
|
|
28350
28424
|
paths,
|
|
@@ -28355,6 +28429,20 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28355
28429
|
)
|
|
28356
28430
|
);
|
|
28357
28431
|
}
|
|
28432
|
+
if (!shouldSkipComponent2(options, "commands")) {
|
|
28433
|
+
outcomes.push(
|
|
28434
|
+
...syncCommandsAsSkills(
|
|
28435
|
+
config,
|
|
28436
|
+
sourceRoot,
|
|
28437
|
+
paths,
|
|
28438
|
+
options,
|
|
28439
|
+
lossReport,
|
|
28440
|
+
logger,
|
|
28441
|
+
manifest,
|
|
28442
|
+
scopePath
|
|
28443
|
+
)
|
|
28444
|
+
);
|
|
28445
|
+
}
|
|
28358
28446
|
if (!shouldSkipComponent2(options, "agents")) {
|
|
28359
28447
|
outcomes.push(
|
|
28360
28448
|
...syncAgents(
|
|
@@ -28374,7 +28462,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28374
28462
|
if (!shouldSkipComponent2(options, "hooks")) {
|
|
28375
28463
|
outcomes.push(
|
|
28376
28464
|
syncHookScriptsBridge({
|
|
28377
|
-
source:
|
|
28465
|
+
source: path39.resolve(sourceRoot, config.source.hooks),
|
|
28378
28466
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
28379
28467
|
config,
|
|
28380
28468
|
sourceRoot,
|
|
@@ -28473,9 +28561,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28473
28561
|
function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
|
|
28474
28562
|
const cp = mappings.modelTiers.custom_provider;
|
|
28475
28563
|
if (!cp) return "";
|
|
28476
|
-
const agentsDir =
|
|
28477
|
-
if (!
|
|
28478
|
-
const agentFiles = ts(
|
|
28564
|
+
const agentsDir = path39.join(sourceRoot, config.source.agents);
|
|
28565
|
+
if (!fs40.existsSync(agentsDir)) return "";
|
|
28566
|
+
const agentFiles = ts(path39.join(agentsDir, "*.md")).sort();
|
|
28479
28567
|
const hasProviderAgent = agentFiles.some((agentFile) => {
|
|
28480
28568
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28481
28569
|
return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
@@ -28540,7 +28628,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28540
28628
|
}
|
|
28541
28629
|
];
|
|
28542
28630
|
for (const ruleFile of rules.dotRulesFiles) {
|
|
28543
|
-
const destination =
|
|
28631
|
+
const destination = path39.join(rulesRoot, ruleFile.name);
|
|
28544
28632
|
if (options.dryRun) {
|
|
28545
28633
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
28546
28634
|
outcomes.push({
|
|
@@ -28570,16 +28658,16 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28570
28658
|
function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
28571
28659
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
28572
28660
|
const destination = resolveTargetPath(paths.instructions);
|
|
28573
|
-
if (!
|
|
28661
|
+
if (!fs40.existsSync(source)) {
|
|
28574
28662
|
return skippedMissingSource2("instructions", source);
|
|
28575
28663
|
}
|
|
28576
|
-
const composed = `${
|
|
28664
|
+
const composed = `${fs40.readFileSync(source, "utf8").trim()}
|
|
28577
28665
|
|
|
28578
28666
|
--- tangyr managed rules ---
|
|
28579
28667
|
${agentsAppendix}`.trim();
|
|
28580
28668
|
const marker = formatProvenanceMarker(
|
|
28581
28669
|
"markdown",
|
|
28582
|
-
|
|
28670
|
+
path39.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
28583
28671
|
hashString(composed),
|
|
28584
28672
|
"codex"
|
|
28585
28673
|
);
|
|
@@ -28606,47 +28694,66 @@ ${composed}
|
|
|
28606
28694
|
);
|
|
28607
28695
|
}
|
|
28608
28696
|
function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
28609
|
-
|
|
28610
|
-
|
|
28611
|
-
|
|
28612
|
-
|
|
28613
|
-
|
|
28614
|
-
|
|
28615
|
-
logger
|
|
28616
|
-
|
|
28617
|
-
|
|
28618
|
-
|
|
28619
|
-
|
|
28620
|
-
|
|
28621
|
-
|
|
28622
|
-
|
|
28623
|
-
|
|
28624
|
-
|
|
28625
|
-
|
|
28626
|
-
|
|
28627
|
-
|
|
28628
|
-
|
|
28629
|
-
|
|
28630
|
-
return { component: "skills", status: "conflict", path: destination };
|
|
28631
|
-
} else if (artifactClass === "managed-symlink") {
|
|
28632
|
-
fs39.unlinkSync(destination);
|
|
28697
|
+
return syncSkillsSlot({
|
|
28698
|
+
config,
|
|
28699
|
+
sourceRoot,
|
|
28700
|
+
source: path39.resolve(sourceRoot, config.source.skills),
|
|
28701
|
+
destination: resolveTargetPath(paths.skills),
|
|
28702
|
+
dryRun: options.dryRun,
|
|
28703
|
+
logger,
|
|
28704
|
+
onUnmanagedConflict: (conflictPath) => handleConflict2(
|
|
28705
|
+
conflictPath,
|
|
28706
|
+
config,
|
|
28707
|
+
options,
|
|
28708
|
+
logger,
|
|
28709
|
+
manifest,
|
|
28710
|
+
scopePath
|
|
28711
|
+
)
|
|
28712
|
+
});
|
|
28713
|
+
}
|
|
28714
|
+
function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, logger, manifest, scopePath) {
|
|
28715
|
+
const commandsRoot = path39.resolve(sourceRoot, config.source.commands);
|
|
28716
|
+
if (!fs40.existsSync(commandsRoot)) {
|
|
28717
|
+
return [skippedMissingSource2("commands", commandsRoot)];
|
|
28633
28718
|
}
|
|
28634
|
-
|
|
28635
|
-
|
|
28636
|
-
|
|
28637
|
-
|
|
28719
|
+
const skillsRoot = resolveTargetPath(paths.skills);
|
|
28720
|
+
return compileCommandsAsSkills(commandsRoot, "codex").map((skill) => {
|
|
28721
|
+
const destination = path39.join(skillsRoot, skill.name, "SKILL.md");
|
|
28722
|
+
if (options.dryRun) {
|
|
28723
|
+
logger.info(
|
|
28724
|
+
`[dry-run] commands: compile ${skill.relativeSource} -> ${destination}`
|
|
28725
|
+
);
|
|
28726
|
+
return {
|
|
28727
|
+
component: "commands",
|
|
28728
|
+
status: "dry-run",
|
|
28729
|
+
path: destination
|
|
28730
|
+
};
|
|
28731
|
+
}
|
|
28732
|
+
return writeCompiledArtifact(
|
|
28733
|
+
"commands",
|
|
28734
|
+
destination,
|
|
28735
|
+
skill.content,
|
|
28736
|
+
void 0,
|
|
28737
|
+
config,
|
|
28738
|
+
sourceRoot,
|
|
28739
|
+
options,
|
|
28740
|
+
logger,
|
|
28741
|
+
manifest,
|
|
28742
|
+
scopePath
|
|
28743
|
+
);
|
|
28744
|
+
});
|
|
28638
28745
|
}
|
|
28639
28746
|
function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
28640
|
-
const sourceAgentsRoot =
|
|
28641
|
-
if (!
|
|
28747
|
+
const sourceAgentsRoot = path39.join(sourceRoot, config.source.agents);
|
|
28748
|
+
if (!fs40.existsSync(sourceAgentsRoot)) {
|
|
28642
28749
|
return [skippedMissingSource2("agents", sourceAgentsRoot)];
|
|
28643
28750
|
}
|
|
28644
|
-
const sourceAgents = ts(
|
|
28751
|
+
const sourceAgents = ts(path39.join(sourceAgentsRoot, "*.md")).sort();
|
|
28645
28752
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
28646
28753
|
return sourceAgents.map((agentFile) => {
|
|
28647
|
-
const destination =
|
|
28754
|
+
const destination = path39.join(
|
|
28648
28755
|
agentsRoot,
|
|
28649
|
-
`${
|
|
28756
|
+
`${path39.basename(agentFile, ".md")}.toml`
|
|
28650
28757
|
);
|
|
28651
28758
|
const compiled = compileAgent(
|
|
28652
28759
|
agentFile,
|
|
@@ -28724,7 +28831,7 @@ function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
28724
28831
|
destination,
|
|
28725
28832
|
hostHooks,
|
|
28726
28833
|
stringifyJson3,
|
|
28727
|
-
!
|
|
28834
|
+
!fs40.existsSync(destination),
|
|
28728
28835
|
logger
|
|
28729
28836
|
);
|
|
28730
28837
|
return {
|
|
@@ -28737,7 +28844,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28737
28844
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
28738
28845
|
const sourceLabel = mcpSourceLabel(config);
|
|
28739
28846
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
28740
|
-
if (!
|
|
28847
|
+
if (!fs40.existsSync(source)) {
|
|
28741
28848
|
if (providerToml && !options.dryRun) {
|
|
28742
28849
|
const changed2 = writeTomlManagedSection(
|
|
28743
28850
|
destination,
|
|
@@ -28752,7 +28859,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28752
28859
|
}
|
|
28753
28860
|
return skippedMissingSource2("mcp", source);
|
|
28754
28861
|
}
|
|
28755
|
-
const sourceMcpJson = JSON.parse(
|
|
28862
|
+
const sourceMcpJson = JSON.parse(fs40.readFileSync(source, "utf8"));
|
|
28756
28863
|
const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
|
|
28757
28864
|
const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
|
|
28758
28865
|
if (options.dryRun) {
|
|
@@ -28777,18 +28884,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
|
|
|
28777
28884
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
28778
28885
|
return { component, status: "conflict", path: destination };
|
|
28779
28886
|
}
|
|
28780
|
-
ensureDir(
|
|
28887
|
+
ensureDir(path39.dirname(destination));
|
|
28781
28888
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
28782
28889
|
if (clearedLink !== null) {
|
|
28783
28890
|
logger.verbose(
|
|
28784
28891
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
28785
28892
|
);
|
|
28786
28893
|
}
|
|
28787
|
-
|
|
28894
|
+
fs40.writeFileSync(destination, content);
|
|
28788
28895
|
return { component, status: "success", path: destination };
|
|
28789
28896
|
}
|
|
28790
28897
|
function writeTomlManagedSection(destination, managedContent, logger) {
|
|
28791
|
-
const current =
|
|
28898
|
+
const current = fs40.existsSync(destination) ? fs40.readFileSync(destination, "utf8") : "";
|
|
28792
28899
|
const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
|
|
28793
28900
|
if (isFirstWrite) {
|
|
28794
28901
|
logger.warn(
|
|
@@ -28804,8 +28911,8 @@ ${managedMcpEnd}
|
|
|
28804
28911
|
if (current === next.trimStart()) {
|
|
28805
28912
|
return false;
|
|
28806
28913
|
}
|
|
28807
|
-
ensureDir(
|
|
28808
|
-
|
|
28914
|
+
ensureDir(path39.dirname(destination));
|
|
28915
|
+
fs40.writeFileSync(destination, next.trimStart());
|
|
28809
28916
|
return true;
|
|
28810
28917
|
}
|
|
28811
28918
|
function removeManagedTomlSection(content) {
|
|
@@ -28831,7 +28938,7 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
|
|
|
28831
28938
|
if (manifest && scopePath) {
|
|
28832
28939
|
backupFile(destination, manifest, scopePath);
|
|
28833
28940
|
writeManifest(scopePath, manifest);
|
|
28834
|
-
|
|
28941
|
+
fs40.rmSync(destination, { recursive: true, force: true });
|
|
28835
28942
|
} else {
|
|
28836
28943
|
const parked = parkConflictingPath(
|
|
28837
28944
|
destination,
|
|
@@ -28846,12 +28953,12 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
|
|
|
28846
28953
|
}
|
|
28847
28954
|
return true;
|
|
28848
28955
|
}
|
|
28849
|
-
|
|
28956
|
+
fs40.rmSync(destination, { recursive: true, force: true });
|
|
28850
28957
|
return true;
|
|
28851
28958
|
}
|
|
28852
28959
|
function isCompiledCurrent(destination, expectedContent, _expectedHash) {
|
|
28853
28960
|
try {
|
|
28854
|
-
return
|
|
28961
|
+
return fs40.readFileSync(destination, "utf8") === expectedContent;
|
|
28855
28962
|
} catch {
|
|
28856
28963
|
return false;
|
|
28857
28964
|
}
|
|
@@ -28866,18 +28973,11 @@ function skippedMissingSource2(component, source) {
|
|
|
28866
28973
|
function shouldSkipComponent2(options, component) {
|
|
28867
28974
|
return Boolean(options.component && options.component !== component);
|
|
28868
28975
|
}
|
|
28869
|
-
function isSymlinkTo4(linkPath, source) {
|
|
28870
|
-
try {
|
|
28871
|
-
return fs39.realpathSync(linkPath) === fs39.realpathSync(source);
|
|
28872
|
-
} catch {
|
|
28873
|
-
return false;
|
|
28874
|
-
}
|
|
28875
|
-
}
|
|
28876
28976
|
function readJsonObject4(filePath) {
|
|
28877
|
-
if (!
|
|
28977
|
+
if (!fs40.existsSync(filePath)) {
|
|
28878
28978
|
return {};
|
|
28879
28979
|
}
|
|
28880
|
-
const parsed = JSON.parse(
|
|
28980
|
+
const parsed = JSON.parse(fs40.readFileSync(filePath, "utf8"));
|
|
28881
28981
|
return isRecord5(parsed) ? parsed : {};
|
|
28882
28982
|
}
|
|
28883
28983
|
function stringifyJson3(value) {
|
|
@@ -28893,16 +28993,16 @@ function hashString(value) {
|
|
|
28893
28993
|
|
|
28894
28994
|
// src/adapters/copilot.ts
|
|
28895
28995
|
import crypto7 from "crypto";
|
|
28896
|
-
import
|
|
28897
|
-
import
|
|
28996
|
+
import fs41 from "fs";
|
|
28997
|
+
import path41 from "path";
|
|
28898
28998
|
|
|
28899
28999
|
// src/compiler/commands.ts
|
|
28900
|
-
var
|
|
28901
|
-
import
|
|
29000
|
+
var import_yaml11 = __toESM(require_dist(), 1);
|
|
29001
|
+
import path40 from "path";
|
|
28902
29002
|
function compileCommandPrompt(sourceFile) {
|
|
28903
29003
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
28904
|
-
const relativeSource = `commands/${
|
|
28905
|
-
const fields = promptFrontmatter(data,
|
|
29004
|
+
const relativeSource = `commands/${path40.basename(sourceFile)}`;
|
|
29005
|
+
const fields = promptFrontmatter(data, path40.basename(sourceFile, ".md"));
|
|
28906
29006
|
const marker = formatProvenanceMarker(
|
|
28907
29007
|
"markdown",
|
|
28908
29008
|
relativeSource,
|
|
@@ -28911,7 +29011,7 @@ function compileCommandPrompt(sourceFile) {
|
|
|
28911
29011
|
);
|
|
28912
29012
|
return `${marker}
|
|
28913
29013
|
---
|
|
28914
|
-
${(0,
|
|
29014
|
+
${(0, import_yaml11.stringify)(fields).trim()}
|
|
28915
29015
|
---
|
|
28916
29016
|
|
|
28917
29017
|
${body.trimEnd()}
|
|
@@ -28935,12 +29035,7 @@ function promptFrontmatter(data, defaultName) {
|
|
|
28935
29035
|
}
|
|
28936
29036
|
|
|
28937
29037
|
// src/adapters/copilot.ts
|
|
28938
|
-
var skippedComponents2 = [
|
|
28939
|
-
"rules",
|
|
28940
|
-
"settings",
|
|
28941
|
-
"lsp",
|
|
28942
|
-
"output-styles"
|
|
28943
|
-
];
|
|
29038
|
+
var skippedComponents2 = ["settings", "lsp", "output-styles"];
|
|
28944
29039
|
var legacyCopilotAgentsPath = "~/.copilot/agents";
|
|
28945
29040
|
function syncCopilot(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
28946
29041
|
const scope = options.scope ?? "global";
|
|
@@ -28951,6 +29046,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
28951
29046
|
}).copilot;
|
|
28952
29047
|
const paths = {
|
|
28953
29048
|
agents: profile.agents,
|
|
29049
|
+
rules: profile.rules,
|
|
28954
29050
|
skills: profile.skills,
|
|
28955
29051
|
prompts: profile.prompts,
|
|
28956
29052
|
hooks: profile.hooks,
|
|
@@ -28984,6 +29080,36 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
28984
29080
|
)
|
|
28985
29081
|
);
|
|
28986
29082
|
}
|
|
29083
|
+
if (!shouldSkipComponent3(options, "rules") && !paths.rules) {
|
|
29084
|
+
addLoss(lossReport, "copilot", "rules", {
|
|
29085
|
+
source: "rules",
|
|
29086
|
+
fields: [
|
|
29087
|
+
{
|
|
29088
|
+
field: "rules",
|
|
29089
|
+
action: "rule-path-scoping",
|
|
29090
|
+
severity: resolveLossSeverity(
|
|
29091
|
+
"agent-field",
|
|
29092
|
+
"rules",
|
|
29093
|
+
"rule-path-scoping"
|
|
29094
|
+
),
|
|
29095
|
+
detail: "Rules: no user-level rules surface for Copilot; `.github/instructions` is a repository path and has no global equivalent"
|
|
29096
|
+
}
|
|
29097
|
+
]
|
|
29098
|
+
});
|
|
29099
|
+
}
|
|
29100
|
+
if (!shouldSkipComponent3(options, "rules") && paths.rules) {
|
|
29101
|
+
outcomes.push(
|
|
29102
|
+
...syncRules2(
|
|
29103
|
+
config,
|
|
29104
|
+
sourceRoot,
|
|
29105
|
+
paths.rules,
|
|
29106
|
+
options,
|
|
29107
|
+
logger,
|
|
29108
|
+
manifest,
|
|
29109
|
+
scopePath
|
|
29110
|
+
)
|
|
29111
|
+
);
|
|
29112
|
+
}
|
|
28987
29113
|
if (!shouldSkipComponent3(options, "agents")) {
|
|
28988
29114
|
outcomes.push(...cleanupLegacyAgents(paths, options, logger));
|
|
28989
29115
|
outcomes.push(
|
|
@@ -29017,7 +29143,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
29017
29143
|
if (!shouldSkipComponent3(options, "hooks")) {
|
|
29018
29144
|
outcomes.push(
|
|
29019
29145
|
syncHookScriptsBridge({
|
|
29020
|
-
source:
|
|
29146
|
+
source: path41.resolve(sourceRoot, config.source.hooks),
|
|
29021
29147
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
29022
29148
|
config,
|
|
29023
29149
|
sourceRoot,
|
|
@@ -29098,13 +29224,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
29098
29224
|
}
|
|
29099
29225
|
function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
|
|
29100
29226
|
if (!mappings.modelTiers.custom_provider) return;
|
|
29101
|
-
const agentsDir =
|
|
29102
|
-
if (!
|
|
29103
|
-
for (const agentFile of ts(
|
|
29227
|
+
const agentsDir = path41.join(sourceRoot, config.source.agents);
|
|
29228
|
+
if (!fs41.existsSync(agentsDir)) return;
|
|
29229
|
+
for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
|
|
29104
29230
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
29105
29231
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
29106
29232
|
if (hasProvider) {
|
|
29107
|
-
const basename =
|
|
29233
|
+
const basename = path41.basename(agentFile);
|
|
29108
29234
|
addLoss(lossReport, "copilot", "agents", {
|
|
29109
29235
|
source: `agents/${basename}`,
|
|
29110
29236
|
fields: [
|
|
@@ -29130,22 +29256,22 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
|
|
|
29130
29256
|
return [{ component: "instructions", status: "skipped", path: message }];
|
|
29131
29257
|
}
|
|
29132
29258
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
29133
|
-
if (!
|
|
29259
|
+
if (!fs41.existsSync(source)) {
|
|
29134
29260
|
return [skippedMissingSource3("instructions", source)];
|
|
29135
29261
|
}
|
|
29136
|
-
const rawContent =
|
|
29262
|
+
const rawContent = fs41.readFileSync(source, "utf8");
|
|
29137
29263
|
const contentHash = hashString2(rawContent);
|
|
29138
29264
|
const marker = formatProvenanceMarker(
|
|
29139
29265
|
"markdown",
|
|
29140
|
-
|
|
29266
|
+
path41.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
29141
29267
|
contentHash,
|
|
29142
29268
|
"copilot"
|
|
29143
29269
|
);
|
|
29144
29270
|
const composedContent = `${marker}
|
|
29145
29271
|
${rawContent}`;
|
|
29146
29272
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
29147
|
-
const agentsMdDest =
|
|
29148
|
-
const mirrorDest =
|
|
29273
|
+
const agentsMdDest = path41.resolve(projectRoot, "AGENTS.md");
|
|
29274
|
+
const mirrorDest = path41.resolve(
|
|
29149
29275
|
projectRoot,
|
|
29150
29276
|
".github",
|
|
29151
29277
|
"copilot-instructions.md"
|
|
@@ -29199,14 +29325,14 @@ function writeInstructionsFile(component, destination, content, contentHash, con
|
|
|
29199
29325
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29200
29326
|
return { component, status: "conflict", path: destination };
|
|
29201
29327
|
}
|
|
29202
|
-
ensureDir(
|
|
29328
|
+
ensureDir(path41.dirname(destination));
|
|
29203
29329
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29204
29330
|
if (clearedLink !== null) {
|
|
29205
29331
|
logger.verbose(
|
|
29206
29332
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29207
29333
|
);
|
|
29208
29334
|
}
|
|
29209
|
-
|
|
29335
|
+
fs41.writeFileSync(destination, content);
|
|
29210
29336
|
return { component, status: "success", path: destination };
|
|
29211
29337
|
}
|
|
29212
29338
|
function hashString2(value) {
|
|
@@ -29216,7 +29342,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29216
29342
|
return syncSkillsSlot({
|
|
29217
29343
|
config,
|
|
29218
29344
|
sourceRoot,
|
|
29219
|
-
source:
|
|
29345
|
+
source: path41.resolve(sourceRoot, config.source.skills),
|
|
29220
29346
|
destination: resolveTargetPath(paths.skills),
|
|
29221
29347
|
dryRun: options.dryRun,
|
|
29222
29348
|
logger,
|
|
@@ -29231,16 +29357,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29231
29357
|
});
|
|
29232
29358
|
}
|
|
29233
29359
|
function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29234
|
-
const sourceAgentsRoot =
|
|
29235
|
-
if (!
|
|
29360
|
+
const sourceAgentsRoot = path41.join(sourceRoot, config.source.agents);
|
|
29361
|
+
if (!fs41.existsSync(sourceAgentsRoot)) {
|
|
29236
29362
|
return [skippedMissingSource3("agents", sourceAgentsRoot)];
|
|
29237
29363
|
}
|
|
29238
|
-
const sourceAgents = ts(
|
|
29364
|
+
const sourceAgents = ts(path41.join(sourceAgentsRoot, "*.md")).sort();
|
|
29239
29365
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29240
29366
|
return sourceAgents.map((agentFile) => {
|
|
29241
|
-
const destination =
|
|
29367
|
+
const destination = path41.join(
|
|
29242
29368
|
agentsRoot,
|
|
29243
|
-
`${
|
|
29369
|
+
`${path41.basename(agentFile, ".md")}.agent.md`
|
|
29244
29370
|
);
|
|
29245
29371
|
const compiled = compileAgent(
|
|
29246
29372
|
agentFile,
|
|
@@ -29268,16 +29394,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29268
29394
|
});
|
|
29269
29395
|
}
|
|
29270
29396
|
function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29271
|
-
const sourceCommandsRoot =
|
|
29272
|
-
if (!
|
|
29397
|
+
const sourceCommandsRoot = path41.join(sourceRoot, config.source.commands);
|
|
29398
|
+
if (!fs41.existsSync(sourceCommandsRoot)) {
|
|
29273
29399
|
return [skippedMissingSource3("commands", sourceCommandsRoot)];
|
|
29274
29400
|
}
|
|
29275
|
-
const sourceCommands = ts(
|
|
29401
|
+
const sourceCommands = ts(path41.join(sourceCommandsRoot, "*.md")).sort();
|
|
29276
29402
|
const promptsRoot = resolveTargetPath(paths.prompts);
|
|
29277
29403
|
return sourceCommands.map((commandFile) => {
|
|
29278
|
-
const destination =
|
|
29404
|
+
const destination = path41.join(
|
|
29279
29405
|
promptsRoot,
|
|
29280
|
-
`${
|
|
29406
|
+
`${path41.basename(commandFile, ".md")}.prompt.md`
|
|
29281
29407
|
);
|
|
29282
29408
|
const compiled = compileCommandPrompt(commandFile);
|
|
29283
29409
|
if (options.dryRun) {
|
|
@@ -29301,7 +29427,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
|
|
|
29301
29427
|
});
|
|
29302
29428
|
}
|
|
29303
29429
|
function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
29304
|
-
const destination =
|
|
29430
|
+
const destination = path41.join(
|
|
29305
29431
|
resolveTargetPath(paths.hooks),
|
|
29306
29432
|
"tangyr-managed.json"
|
|
29307
29433
|
);
|
|
@@ -29364,10 +29490,10 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
29364
29490
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
29365
29491
|
const sourceLabel = mcpSourceLabel(config);
|
|
29366
29492
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
29367
|
-
if (!
|
|
29493
|
+
if (!fs41.existsSync(source)) {
|
|
29368
29494
|
return skippedMissingSource3("mcp", source);
|
|
29369
29495
|
}
|
|
29370
|
-
const sourceMcpJson = JSON.parse(
|
|
29496
|
+
const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
|
|
29371
29497
|
const compiled = compileMcp(
|
|
29372
29498
|
sourceMcpJson,
|
|
29373
29499
|
"copilot",
|
|
@@ -29389,6 +29515,36 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
29389
29515
|
logger
|
|
29390
29516
|
);
|
|
29391
29517
|
}
|
|
29518
|
+
function syncRules2(config, sourceRoot, rulesSlot, options, logger, manifest, scopePath) {
|
|
29519
|
+
const sourceRulesDir = path41.resolve(sourceRoot, config.source.rules);
|
|
29520
|
+
if (!fs41.existsSync(sourceRulesDir)) {
|
|
29521
|
+
return [skippedMissingSource3("rules", sourceRulesDir)];
|
|
29522
|
+
}
|
|
29523
|
+
const destinationRoot = resolveTargetPath(rulesSlot);
|
|
29524
|
+
return compileCopilotRules(sourceRulesDir).map((file) => {
|
|
29525
|
+
const destination = path41.join(destinationRoot, file.name);
|
|
29526
|
+
if (options.dryRun) {
|
|
29527
|
+
logger.info(`[dry-run] rules: compile -> ${destination}`);
|
|
29528
|
+
return {
|
|
29529
|
+
component: "rules",
|
|
29530
|
+
status: "dry-run",
|
|
29531
|
+
path: destination
|
|
29532
|
+
};
|
|
29533
|
+
}
|
|
29534
|
+
return writeCompiledArtifact2(
|
|
29535
|
+
"rules",
|
|
29536
|
+
destination,
|
|
29537
|
+
file.content,
|
|
29538
|
+
void 0,
|
|
29539
|
+
config,
|
|
29540
|
+
sourceRoot,
|
|
29541
|
+
options,
|
|
29542
|
+
logger,
|
|
29543
|
+
manifest,
|
|
29544
|
+
scopePath
|
|
29545
|
+
);
|
|
29546
|
+
});
|
|
29547
|
+
}
|
|
29392
29548
|
function writeCompiledArtifact2(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
|
|
29393
29549
|
if (!options.force && isCompiledCurrent2(destination, content, expectedHash)) {
|
|
29394
29550
|
return { component, status: "skipped-current", path: destination };
|
|
@@ -29400,19 +29556,19 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
|
|
|
29400
29556
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29401
29557
|
return { component, status: "conflict", path: destination };
|
|
29402
29558
|
}
|
|
29403
|
-
ensureDir(
|
|
29559
|
+
ensureDir(path41.dirname(destination));
|
|
29404
29560
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29405
29561
|
if (clearedLink !== null) {
|
|
29406
29562
|
logger.verbose(
|
|
29407
29563
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29408
29564
|
);
|
|
29409
29565
|
}
|
|
29410
|
-
|
|
29566
|
+
fs41.writeFileSync(destination, content);
|
|
29411
29567
|
return { component, status: "success", path: destination };
|
|
29412
29568
|
}
|
|
29413
29569
|
function isCompiledCurrent2(destination, expectedContent, _expectedHash) {
|
|
29414
29570
|
try {
|
|
29415
|
-
return
|
|
29571
|
+
return fs41.readFileSync(destination, "utf8") === expectedContent;
|
|
29416
29572
|
} catch {
|
|
29417
29573
|
return false;
|
|
29418
29574
|
}
|
|
@@ -29432,7 +29588,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
|
|
|
29432
29588
|
if (manifest && scopePath) {
|
|
29433
29589
|
backupFile(destination, manifest, scopePath);
|
|
29434
29590
|
writeManifest(scopePath, manifest);
|
|
29435
|
-
|
|
29591
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
29436
29592
|
} else {
|
|
29437
29593
|
const parked = parkConflictingPath(
|
|
29438
29594
|
destination,
|
|
@@ -29447,7 +29603,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
|
|
|
29447
29603
|
}
|
|
29448
29604
|
return true;
|
|
29449
29605
|
}
|
|
29450
|
-
|
|
29606
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
29451
29607
|
return true;
|
|
29452
29608
|
}
|
|
29453
29609
|
function shouldSkipComponent3(options, component) {
|
|
@@ -29456,12 +29612,12 @@ function shouldSkipComponent3(options, component) {
|
|
|
29456
29612
|
function cleanupLegacyAgents(paths, options, logger) {
|
|
29457
29613
|
const currentAgentsRoot = resolveTargetPath(paths.agents);
|
|
29458
29614
|
const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
|
|
29459
|
-
if (
|
|
29615
|
+
if (path41.resolve(currentAgentsRoot) === path41.resolve(legacyAgentsRoot)) {
|
|
29460
29616
|
return [];
|
|
29461
29617
|
}
|
|
29462
29618
|
const outcomes = [];
|
|
29463
29619
|
for (const filePath of ts(
|
|
29464
|
-
|
|
29620
|
+
path41.join(legacyAgentsRoot, "*.agent.md")
|
|
29465
29621
|
).sort()) {
|
|
29466
29622
|
if (!isCopilotManagedCompiledFile(filePath)) {
|
|
29467
29623
|
continue;
|
|
@@ -29471,14 +29627,14 @@ function cleanupLegacyAgents(paths, options, logger) {
|
|
|
29471
29627
|
outcomes.push({ component: "agents", status: "dry-run", path: filePath });
|
|
29472
29628
|
continue;
|
|
29473
29629
|
}
|
|
29474
|
-
|
|
29630
|
+
fs41.rmSync(filePath, { force: true });
|
|
29475
29631
|
outcomes.push({ component: "agents", status: "success", path: filePath });
|
|
29476
29632
|
}
|
|
29477
29633
|
return outcomes;
|
|
29478
29634
|
}
|
|
29479
29635
|
function isCopilotManagedCompiledFile(filePath) {
|
|
29480
29636
|
try {
|
|
29481
|
-
return extractProvenanceMarker(
|
|
29637
|
+
return extractProvenanceMarker(fs41.readFileSync(filePath, "utf8"))?.target === "copilot";
|
|
29482
29638
|
} catch {
|
|
29483
29639
|
return false;
|
|
29484
29640
|
}
|
|
@@ -29493,8 +29649,8 @@ function skippedMissingSource3(component, source) {
|
|
|
29493
29649
|
|
|
29494
29650
|
// src/adapters/cursor.ts
|
|
29495
29651
|
import crypto8 from "crypto";
|
|
29496
|
-
import
|
|
29497
|
-
import
|
|
29652
|
+
import fs42 from "fs";
|
|
29653
|
+
import path42 from "path";
|
|
29498
29654
|
function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29499
29655
|
const scope = options.scope ?? "global";
|
|
29500
29656
|
const profile = resolveTargetPaths({
|
|
@@ -29547,7 +29703,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
29547
29703
|
}
|
|
29548
29704
|
if (!shouldSkipComponent4(options, "rules")) {
|
|
29549
29705
|
outcomes.push(
|
|
29550
|
-
...
|
|
29706
|
+
...syncRules3(
|
|
29551
29707
|
config,
|
|
29552
29708
|
sourceRoot,
|
|
29553
29709
|
paths,
|
|
@@ -29562,7 +29718,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
29562
29718
|
}
|
|
29563
29719
|
if (!shouldSkipComponent4(options, "skills")) {
|
|
29564
29720
|
outcomes.push(
|
|
29565
|
-
syncSkills3(
|
|
29721
|
+
...syncSkills3(
|
|
29566
29722
|
config,
|
|
29567
29723
|
sourceRoot,
|
|
29568
29724
|
options,
|
|
@@ -29576,7 +29732,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
29576
29732
|
)
|
|
29577
29733
|
);
|
|
29578
29734
|
outcomes.push(
|
|
29579
|
-
syncSkills3(
|
|
29735
|
+
...syncSkills3(
|
|
29580
29736
|
config,
|
|
29581
29737
|
sourceRoot,
|
|
29582
29738
|
options,
|
|
@@ -29606,7 +29762,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
29606
29762
|
if (!shouldSkipComponent4(options, "hooks")) {
|
|
29607
29763
|
outcomes.push(
|
|
29608
29764
|
syncHookScriptsBridge({
|
|
29609
|
-
source:
|
|
29765
|
+
source: path42.resolve(sourceRoot, config.source.hooks),
|
|
29610
29766
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
29611
29767
|
config,
|
|
29612
29768
|
sourceRoot,
|
|
@@ -29671,7 +29827,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
|
|
|
29671
29827
|
const composed = composeCursorInstructions(config, sourceRoot, lossReport);
|
|
29672
29828
|
const marker = formatProvenanceMarker(
|
|
29673
29829
|
"markdown",
|
|
29674
|
-
|
|
29830
|
+
path42.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
29675
29831
|
hashString3(composed),
|
|
29676
29832
|
"cursor"
|
|
29677
29833
|
);
|
|
@@ -29697,7 +29853,7 @@ ${composed}
|
|
|
29697
29853
|
}
|
|
29698
29854
|
function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
29699
29855
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
29700
|
-
const baseContent =
|
|
29856
|
+
const baseContent = fs42.existsSync(source) ? fs42.readFileSync(source, "utf8").trim() : "";
|
|
29701
29857
|
const personaContent = extractPrimaryPersonaContent(
|
|
29702
29858
|
config,
|
|
29703
29859
|
sourceRoot,
|
|
@@ -29710,11 +29866,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
|
29710
29866
|
${personaContent}`.trim() : baseContent;
|
|
29711
29867
|
}
|
|
29712
29868
|
function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
29713
|
-
const agentsDir =
|
|
29714
|
-
if (!
|
|
29869
|
+
const agentsDir = path42.join(sourceRoot, config.source.agents);
|
|
29870
|
+
if (!fs42.existsSync(agentsDir)) {
|
|
29715
29871
|
return null;
|
|
29716
29872
|
}
|
|
29717
|
-
const agentFiles = ts(
|
|
29873
|
+
const agentFiles = ts(path42.join(agentsDir, "*.md")).sort();
|
|
29718
29874
|
if (agentFiles.length === 0) {
|
|
29719
29875
|
return null;
|
|
29720
29876
|
}
|
|
@@ -29737,7 +29893,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29737
29893
|
return null;
|
|
29738
29894
|
}
|
|
29739
29895
|
addLoss(lossReport, "cursor", "instructions", {
|
|
29740
|
-
source: `agents/${
|
|
29896
|
+
source: `agents/${path42.basename(primaryFile)}`,
|
|
29741
29897
|
fields: [
|
|
29742
29898
|
{
|
|
29743
29899
|
field: "persona",
|
|
@@ -29747,23 +29903,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29747
29903
|
"persona",
|
|
29748
29904
|
"instructions-shim"
|
|
29749
29905
|
),
|
|
29750
|
-
detail: `Primary persona from ${
|
|
29906
|
+
detail: `Primary persona from ${path42.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
|
|
29751
29907
|
}
|
|
29752
29908
|
]
|
|
29753
29909
|
});
|
|
29754
29910
|
return body.trim();
|
|
29755
29911
|
}
|
|
29756
29912
|
function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29757
|
-
const sourceAgentsRoot =
|
|
29758
|
-
if (!
|
|
29913
|
+
const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
|
|
29914
|
+
if (!fs42.existsSync(sourceAgentsRoot)) {
|
|
29759
29915
|
return [skippedMissingSource4("agents", sourceAgentsRoot)];
|
|
29760
29916
|
}
|
|
29761
|
-
const sourceAgents = ts(
|
|
29917
|
+
const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
|
|
29762
29918
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29763
29919
|
return sourceAgents.map((agentFile) => {
|
|
29764
|
-
const destination =
|
|
29920
|
+
const destination = path42.join(
|
|
29765
29921
|
agentsRoot,
|
|
29766
|
-
`${
|
|
29922
|
+
`${path42.basename(agentFile, ".md")}.md`
|
|
29767
29923
|
);
|
|
29768
29924
|
let compiled;
|
|
29769
29925
|
try {
|
|
@@ -29803,15 +29959,15 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29803
29959
|
);
|
|
29804
29960
|
});
|
|
29805
29961
|
}
|
|
29806
|
-
function
|
|
29807
|
-
const sourceRulesDir =
|
|
29808
|
-
if (!
|
|
29962
|
+
function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
29963
|
+
const sourceRulesDir = path42.join(sourceRoot, config.source.rules);
|
|
29964
|
+
if (!fs42.existsSync(sourceRulesDir)) {
|
|
29809
29965
|
return [skippedMissingSource4("rules", sourceRulesDir)];
|
|
29810
29966
|
}
|
|
29811
29967
|
const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
|
|
29812
29968
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
29813
29969
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
29814
|
-
const destination =
|
|
29970
|
+
const destination = path42.join(rulesDir, name);
|
|
29815
29971
|
if (options.dryRun) {
|
|
29816
29972
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
29817
29973
|
return {
|
|
@@ -29835,30 +29991,16 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
29835
29991
|
});
|
|
29836
29992
|
}
|
|
29837
29993
|
function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29838
|
-
const sourceCommandsRoot =
|
|
29839
|
-
if (!
|
|
29994
|
+
const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
|
|
29995
|
+
if (!fs42.existsSync(sourceCommandsRoot)) {
|
|
29840
29996
|
return [skippedMissingSource4("commands", sourceCommandsRoot)];
|
|
29841
29997
|
}
|
|
29842
|
-
const sourceCommands = ts(
|
|
29998
|
+
const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
|
|
29843
29999
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
29844
30000
|
return sourceCommands.map((commandFile) => {
|
|
29845
|
-
const baseName =
|
|
29846
|
-
const destination =
|
|
29847
|
-
const
|
|
29848
|
-
const relativeSource = `commands/${path41.basename(commandFile)}`;
|
|
29849
|
-
const marker = formatProvenanceMarker(
|
|
29850
|
-
"markdown",
|
|
29851
|
-
relativeSource,
|
|
29852
|
-
computeSourceHash(commandFile),
|
|
29853
|
-
"cursor"
|
|
29854
|
-
);
|
|
29855
|
-
const content = `${marker}
|
|
29856
|
-
---
|
|
29857
|
-
disable-model-invocation: true
|
|
29858
|
-
---
|
|
29859
|
-
|
|
29860
|
-
${commandContent.trim()}
|
|
29861
|
-
`;
|
|
30001
|
+
const baseName = path42.basename(commandFile, ".md");
|
|
30002
|
+
const destination = path42.join(skillsRoot, baseName, "SKILL.md");
|
|
30003
|
+
const { content } = compileCommandAsSkill(commandFile, "cursor");
|
|
29862
30004
|
if (options.dryRun) {
|
|
29863
30005
|
logger.info(
|
|
29864
30006
|
`[dry-run] commands: compile ${commandFile} -> ${destination}`
|
|
@@ -29883,39 +30025,23 @@ ${commandContent.trim()}
|
|
|
29883
30025
|
);
|
|
29884
30026
|
});
|
|
29885
30027
|
}
|
|
29886
|
-
function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath,
|
|
29887
|
-
|
|
29888
|
-
|
|
29889
|
-
|
|
29890
|
-
|
|
29891
|
-
|
|
29892
|
-
|
|
29893
|
-
logger
|
|
29894
|
-
|
|
29895
|
-
|
|
29896
|
-
|
|
29897
|
-
|
|
29898
|
-
|
|
29899
|
-
|
|
29900
|
-
|
|
29901
|
-
|
|
29902
|
-
|
|
29903
|
-
} else if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
29904
|
-
return { component, status: "conflict", path: destination };
|
|
29905
|
-
} else if (artifactClass === "managed-symlink") {
|
|
29906
|
-
fs41.unlinkSync(destination);
|
|
29907
|
-
}
|
|
29908
|
-
ensureDir(path41.dirname(destination));
|
|
29909
|
-
createRelativeSymlink(source, destination, "dir");
|
|
29910
|
-
logger.verbose(`Skills: created shared skills symlink ${destination}`);
|
|
29911
|
-
return { component, status: "success", path: destination };
|
|
29912
|
-
}
|
|
29913
|
-
if (fs41.existsSync(destination)) {
|
|
29914
|
-
return { component, status: "skipped-current", path: destination };
|
|
29915
|
-
}
|
|
29916
|
-
ensureDir(destination);
|
|
29917
|
-
logger.verbose(`Skills: ensured Cursor-local skills dir ${destination}`);
|
|
29918
|
-
return { component, status: "success", path: destination };
|
|
30028
|
+
function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, _component = "skills", destination = "", _asSymlink = false) {
|
|
30029
|
+
return syncSkillsSlot({
|
|
30030
|
+
config,
|
|
30031
|
+
sourceRoot,
|
|
30032
|
+
source: path42.resolve(sourceRoot, config.source.skills),
|
|
30033
|
+
destination,
|
|
30034
|
+
dryRun: options.dryRun,
|
|
30035
|
+
logger,
|
|
30036
|
+
onUnmanagedConflict: (conflictPath) => handleConflict4(
|
|
30037
|
+
conflictPath,
|
|
30038
|
+
config,
|
|
30039
|
+
options,
|
|
30040
|
+
logger,
|
|
30041
|
+
manifest,
|
|
30042
|
+
scopePath
|
|
30043
|
+
)
|
|
30044
|
+
});
|
|
29919
30045
|
}
|
|
29920
30046
|
function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
29921
30047
|
const scripts = hookScriptsDir(
|
|
@@ -29951,18 +30077,18 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
29951
30077
|
}
|
|
29952
30078
|
const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
|
|
29953
30079
|
`;
|
|
29954
|
-
ensureDir(
|
|
29955
|
-
|
|
30080
|
+
ensureDir(path42.dirname(destination));
|
|
30081
|
+
fs42.writeFileSync(destination, hooksFileContent);
|
|
29956
30082
|
return { component: "hooks", status: "success", path: destination };
|
|
29957
30083
|
}
|
|
29958
30084
|
function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
|
|
29959
30085
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
29960
30086
|
const sourceLabel = mcpSourceLabel(config);
|
|
29961
30087
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
29962
|
-
if (!
|
|
30088
|
+
if (!fs42.existsSync(source)) {
|
|
29963
30089
|
return skippedMissingSource4("mcp", source);
|
|
29964
30090
|
}
|
|
29965
|
-
const sourceMcpJson = JSON.parse(
|
|
30091
|
+
const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
|
|
29966
30092
|
const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
|
|
29967
30093
|
if (options.dryRun) {
|
|
29968
30094
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -30015,13 +30141,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
|
|
|
30015
30141
|
);
|
|
30016
30142
|
}
|
|
30017
30143
|
function syncProviderPin(config, sourceRoot, lossReport) {
|
|
30018
|
-
const agentsDir =
|
|
30019
|
-
if (!
|
|
30020
|
-
for (const agentFile of ts(
|
|
30144
|
+
const agentsDir = path42.join(sourceRoot, config.source.agents);
|
|
30145
|
+
if (!fs42.existsSync(agentsDir)) return;
|
|
30146
|
+
for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
|
|
30021
30147
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
30022
30148
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
30023
30149
|
if (hasCustomProvider) {
|
|
30024
|
-
const relativeSource = `agents/${
|
|
30150
|
+
const relativeSource = `agents/${path42.basename(agentFile)}`;
|
|
30025
30151
|
addLoss(lossReport, "cursor", "agents", {
|
|
30026
30152
|
source: relativeSource,
|
|
30027
30153
|
fields: [
|
|
@@ -30033,7 +30159,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
|
|
|
30033
30159
|
"provider",
|
|
30034
30160
|
"provider-not-representable"
|
|
30035
30161
|
),
|
|
30036
|
-
detail: `${
|
|
30162
|
+
detail: `${path42.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
30037
30163
|
}
|
|
30038
30164
|
]
|
|
30039
30165
|
});
|
|
@@ -30051,14 +30177,14 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
|
|
|
30051
30177
|
if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
30052
30178
|
return { component, status: "conflict", path: destination };
|
|
30053
30179
|
}
|
|
30054
|
-
ensureDir(
|
|
30180
|
+
ensureDir(path42.dirname(destination));
|
|
30055
30181
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30056
30182
|
if (clearedLink !== null) {
|
|
30057
30183
|
logger.verbose(
|
|
30058
30184
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30059
30185
|
);
|
|
30060
30186
|
}
|
|
30061
|
-
|
|
30187
|
+
fs42.writeFileSync(destination, content);
|
|
30062
30188
|
return { component, status: "success", path: destination };
|
|
30063
30189
|
}
|
|
30064
30190
|
function handleConflict4(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30076,7 +30202,7 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
|
|
|
30076
30202
|
if (manifest && scopePath) {
|
|
30077
30203
|
backupFile(destination, manifest, scopePath);
|
|
30078
30204
|
writeManifest(scopePath, manifest);
|
|
30079
|
-
|
|
30205
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
30080
30206
|
} else {
|
|
30081
30207
|
const parked = parkConflictingPath(
|
|
30082
30208
|
destination,
|
|
@@ -30091,12 +30217,12 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
|
|
|
30091
30217
|
}
|
|
30092
30218
|
return true;
|
|
30093
30219
|
}
|
|
30094
|
-
|
|
30220
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
30095
30221
|
return true;
|
|
30096
30222
|
}
|
|
30097
30223
|
function isCompiledCurrent3(destination, expectedContent, _expectedHash) {
|
|
30098
30224
|
try {
|
|
30099
|
-
return
|
|
30225
|
+
return fs42.readFileSync(destination, "utf8") === expectedContent;
|
|
30100
30226
|
} catch {
|
|
30101
30227
|
return false;
|
|
30102
30228
|
}
|
|
@@ -30111,21 +30237,14 @@ function skippedMissingSource4(component, source) {
|
|
|
30111
30237
|
function shouldSkipComponent4(options, component) {
|
|
30112
30238
|
return Boolean(options.component && options.component !== component);
|
|
30113
30239
|
}
|
|
30114
|
-
function isSymlinkTo5(linkPath, source) {
|
|
30115
|
-
try {
|
|
30116
|
-
return fs41.realpathSync(linkPath) === fs41.realpathSync(source);
|
|
30117
|
-
} catch {
|
|
30118
|
-
return false;
|
|
30119
|
-
}
|
|
30120
|
-
}
|
|
30121
30240
|
function hashString3(value) {
|
|
30122
30241
|
return `sha256:${crypto8.createHash("sha256").update(value).digest("hex")}`;
|
|
30123
30242
|
}
|
|
30124
30243
|
|
|
30125
30244
|
// src/adapters/cline.ts
|
|
30126
30245
|
import crypto9 from "crypto";
|
|
30127
|
-
import
|
|
30128
|
-
import
|
|
30246
|
+
import fs43 from "fs";
|
|
30247
|
+
import path43 from "path";
|
|
30129
30248
|
function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30130
30249
|
const scope = options.scope ?? "global";
|
|
30131
30250
|
const profile = resolveTargetPaths({
|
|
@@ -30172,7 +30291,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
30172
30291
|
}
|
|
30173
30292
|
if (!shouldSkipComponent5(options, "rules")) {
|
|
30174
30293
|
outcomes.push(
|
|
30175
|
-
...
|
|
30294
|
+
...syncRules4(
|
|
30176
30295
|
config,
|
|
30177
30296
|
sourceRoot,
|
|
30178
30297
|
paths,
|
|
@@ -30200,7 +30319,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
30200
30319
|
}
|
|
30201
30320
|
if (!shouldSkipComponent5(options, "skills")) {
|
|
30202
30321
|
outcomes.push(
|
|
30203
|
-
syncSkills4(
|
|
30322
|
+
...syncSkills4(
|
|
30204
30323
|
config,
|
|
30205
30324
|
sourceRoot,
|
|
30206
30325
|
paths,
|
|
@@ -30238,7 +30357,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
30238
30357
|
function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
|
|
30239
30358
|
if (scope === "global" || paths.instructions === null) {
|
|
30240
30359
|
addLoss(lossReport, "cline", "instructions", {
|
|
30241
|
-
source:
|
|
30360
|
+
source: path43.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30242
30361
|
fields: [
|
|
30243
30362
|
{
|
|
30244
30363
|
field: "instructions",
|
|
@@ -30260,10 +30379,10 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
|
|
|
30260
30379
|
}
|
|
30261
30380
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30262
30381
|
const destination = resolveTargetPath(paths.instructions);
|
|
30263
|
-
const baseContent =
|
|
30382
|
+
const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
|
|
30264
30383
|
const marker = formatProvenanceMarker(
|
|
30265
30384
|
"markdown",
|
|
30266
|
-
|
|
30385
|
+
path43.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30267
30386
|
hashString4(baseContent),
|
|
30268
30387
|
"cline"
|
|
30269
30388
|
);
|
|
@@ -30288,11 +30407,11 @@ ${baseContent}
|
|
|
30288
30407
|
);
|
|
30289
30408
|
}
|
|
30290
30409
|
function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
|
|
30291
|
-
const sourceAgentsRoot =
|
|
30292
|
-
if (!
|
|
30410
|
+
const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
|
|
30411
|
+
if (!fs43.existsSync(sourceAgentsRoot)) {
|
|
30293
30412
|
return [skippedMissingSource5("agents", sourceAgentsRoot)];
|
|
30294
30413
|
}
|
|
30295
|
-
const sourceAgents = ts(
|
|
30414
|
+
const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
|
|
30296
30415
|
return sourceAgents.map((agentFile) => {
|
|
30297
30416
|
compileAgent(agentFile, "cline", mappings, extensions, lossReport);
|
|
30298
30417
|
if (options.dryRun) {
|
|
@@ -30307,15 +30426,15 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
30307
30426
|
};
|
|
30308
30427
|
});
|
|
30309
30428
|
}
|
|
30310
|
-
function
|
|
30311
|
-
const sourceRulesDir =
|
|
30312
|
-
if (!
|
|
30429
|
+
function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
30430
|
+
const sourceRulesDir = path43.join(sourceRoot, config.source.rules);
|
|
30431
|
+
if (!fs43.existsSync(sourceRulesDir)) {
|
|
30313
30432
|
return [skippedMissingSource5("rules", sourceRulesDir)];
|
|
30314
30433
|
}
|
|
30315
30434
|
const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
|
|
30316
30435
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
30317
30436
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
30318
|
-
const destination =
|
|
30437
|
+
const destination = path43.join(rulesDir, name);
|
|
30319
30438
|
if (options.dryRun) {
|
|
30320
30439
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
30321
30440
|
return {
|
|
@@ -30339,17 +30458,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
30339
30458
|
});
|
|
30340
30459
|
}
|
|
30341
30460
|
function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30342
|
-
const sourceCommandsRoot =
|
|
30343
|
-
if (!
|
|
30461
|
+
const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
|
|
30462
|
+
if (!fs43.existsSync(sourceCommandsRoot)) {
|
|
30344
30463
|
return [skippedMissingSource5("commands", sourceCommandsRoot)];
|
|
30345
30464
|
}
|
|
30346
|
-
const sourceCommands = ts(
|
|
30465
|
+
const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
|
|
30347
30466
|
const workflowsRoot = resolveTargetPath(paths.workflows);
|
|
30348
30467
|
return sourceCommands.map((commandFile) => {
|
|
30349
|
-
const baseName =
|
|
30350
|
-
const destination =
|
|
30351
|
-
const commandContent =
|
|
30352
|
-
const relativeSource = `commands/${
|
|
30468
|
+
const baseName = path43.basename(commandFile);
|
|
30469
|
+
const destination = path43.join(workflowsRoot, baseName);
|
|
30470
|
+
const commandContent = fs43.readFileSync(commandFile, "utf8");
|
|
30471
|
+
const relativeSource = `commands/${path43.basename(commandFile)}`;
|
|
30353
30472
|
const marker = formatProvenanceMarker(
|
|
30354
30473
|
"markdown",
|
|
30355
30474
|
relativeSource,
|
|
@@ -30384,44 +30503,22 @@ ${commandContent.trim()}
|
|
|
30384
30503
|
});
|
|
30385
30504
|
}
|
|
30386
30505
|
function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30387
|
-
|
|
30388
|
-
|
|
30389
|
-
|
|
30390
|
-
|
|
30391
|
-
|
|
30392
|
-
|
|
30393
|
-
logger
|
|
30394
|
-
|
|
30395
|
-
|
|
30396
|
-
|
|
30397
|
-
|
|
30398
|
-
|
|
30399
|
-
|
|
30400
|
-
|
|
30401
|
-
|
|
30402
|
-
|
|
30403
|
-
}
|
|
30404
|
-
if (
|
|
30405
|
-
// A stale symlink from a superseded source root. Every other adapter
|
|
30406
|
-
// unlinks it here; this one did not, so classifyArtifact's `managed-stale`
|
|
30407
|
-
// matched no branch, fell through, and handed symlinkSync a path that
|
|
30408
|
-
// already existed. Measured: sync died with "EEXIST: file already exists,
|
|
30409
|
-
// symlink … -> ~/.cline/skills" and every component after skills went
|
|
30410
|
-
// unsynced.
|
|
30411
|
-
artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)
|
|
30412
|
-
) {
|
|
30413
|
-
fs42.unlinkSync(destination);
|
|
30414
|
-
} else if (artifactClass === "unmanaged-conflict") {
|
|
30415
|
-
if (!handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
30416
|
-
return { component: "skills", status: "conflict", path: destination };
|
|
30417
|
-
}
|
|
30418
|
-
} else if (artifactClass === "managed-symlink") {
|
|
30419
|
-
fs42.unlinkSync(destination);
|
|
30420
|
-
}
|
|
30421
|
-
ensureDir(path42.dirname(destination));
|
|
30422
|
-
createRelativeSymlink(source, destination, "dir");
|
|
30423
|
-
logger.verbose(`Skills: created Cline skills symlink ${destination}`);
|
|
30424
|
-
return { component: "skills", status: "success", path: destination };
|
|
30506
|
+
return syncSkillsSlot({
|
|
30507
|
+
config,
|
|
30508
|
+
sourceRoot,
|
|
30509
|
+
source: path43.resolve(sourceRoot, config.source.skills),
|
|
30510
|
+
destination: resolveTargetPath(paths.skills),
|
|
30511
|
+
dryRun: options.dryRun,
|
|
30512
|
+
logger,
|
|
30513
|
+
onUnmanagedConflict: (conflictPath) => handleConflict5(
|
|
30514
|
+
conflictPath,
|
|
30515
|
+
config,
|
|
30516
|
+
options,
|
|
30517
|
+
logger,
|
|
30518
|
+
manifest,
|
|
30519
|
+
scopePath
|
|
30520
|
+
)
|
|
30521
|
+
});
|
|
30425
30522
|
}
|
|
30426
30523
|
function syncHooks5(config, sourceRoot, mappings, options, lossReport, logger) {
|
|
30427
30524
|
const hooksSource = loadKitHooksSource(sourceRoot, config);
|
|
@@ -30442,10 +30539,10 @@ function syncMcp5(config, sourceRoot, paths, options, lossReport, logger, manife
|
|
|
30442
30539
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30443
30540
|
const sourceLabel = mcpSourceLabel(config);
|
|
30444
30541
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
30445
|
-
if (!
|
|
30542
|
+
if (!fs43.existsSync(source)) {
|
|
30446
30543
|
return skippedMissingSource5("mcp", source);
|
|
30447
30544
|
}
|
|
30448
|
-
const sourceMcpJson = JSON.parse(
|
|
30545
|
+
const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
|
|
30449
30546
|
const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
|
|
30450
30547
|
if (options.dryRun) {
|
|
30451
30548
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -30488,11 +30585,11 @@ function syncSettings2(lossReport) {
|
|
|
30488
30585
|
};
|
|
30489
30586
|
}
|
|
30490
30587
|
function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
30491
|
-
const agentsDir =
|
|
30492
|
-
if (!
|
|
30493
|
-
for (const agentFile of ts(
|
|
30588
|
+
const agentsDir = path43.join(sourceRoot, config.source.agents);
|
|
30589
|
+
if (!fs43.existsSync(agentsDir)) return;
|
|
30590
|
+
for (const agentFile of ts(path43.join(agentsDir, "*.md")).sort()) {
|
|
30494
30591
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
30495
|
-
const relativeSource = `agents/${
|
|
30592
|
+
const relativeSource = `agents/${path43.basename(agentFile)}`;
|
|
30496
30593
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
30497
30594
|
if (hasCustomProvider) {
|
|
30498
30595
|
addLoss(lossReport, "cline", "agents", {
|
|
@@ -30506,7 +30603,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30506
30603
|
"provider",
|
|
30507
30604
|
"provider-not-representable"
|
|
30508
30605
|
),
|
|
30509
|
-
detail: `${
|
|
30606
|
+
detail: `${path43.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
|
|
30510
30607
|
}
|
|
30511
30608
|
]
|
|
30512
30609
|
});
|
|
@@ -30524,7 +30621,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30524
30621
|
"model",
|
|
30525
30622
|
"model-not-representable"
|
|
30526
30623
|
),
|
|
30527
|
-
detail: `${
|
|
30624
|
+
detail: `${path43.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
|
|
30528
30625
|
}
|
|
30529
30626
|
]
|
|
30530
30627
|
});
|
|
@@ -30542,14 +30639,14 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
|
|
|
30542
30639
|
if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
30543
30640
|
return { component, status: "conflict", path: destination };
|
|
30544
30641
|
}
|
|
30545
|
-
ensureDir(
|
|
30642
|
+
ensureDir(path43.dirname(destination));
|
|
30546
30643
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30547
30644
|
if (clearedLink !== null) {
|
|
30548
30645
|
logger.verbose(
|
|
30549
30646
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30550
30647
|
);
|
|
30551
30648
|
}
|
|
30552
|
-
|
|
30649
|
+
fs43.writeFileSync(destination, content);
|
|
30553
30650
|
return { component, status: "success", path: destination };
|
|
30554
30651
|
}
|
|
30555
30652
|
function handleConflict5(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30567,7 +30664,7 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
|
|
|
30567
30664
|
if (manifest && scopePath) {
|
|
30568
30665
|
backupFile(destination, manifest, scopePath);
|
|
30569
30666
|
writeManifest(scopePath, manifest);
|
|
30570
|
-
|
|
30667
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30571
30668
|
} else {
|
|
30572
30669
|
const parked = parkConflictingPath(
|
|
30573
30670
|
destination,
|
|
@@ -30582,12 +30679,12 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
|
|
|
30582
30679
|
}
|
|
30583
30680
|
return true;
|
|
30584
30681
|
}
|
|
30585
|
-
|
|
30682
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30586
30683
|
return true;
|
|
30587
30684
|
}
|
|
30588
30685
|
function isCompiledCurrent4(destination, expectedContent, _expectedHash) {
|
|
30589
30686
|
try {
|
|
30590
|
-
return
|
|
30687
|
+
return fs43.readFileSync(destination, "utf8") === expectedContent;
|
|
30591
30688
|
} catch {
|
|
30592
30689
|
return false;
|
|
30593
30690
|
}
|
|
@@ -30602,23 +30699,16 @@ function skippedMissingSource5(component, source) {
|
|
|
30602
30699
|
function shouldSkipComponent5(options, component) {
|
|
30603
30700
|
return Boolean(options.component && options.component !== component);
|
|
30604
30701
|
}
|
|
30605
|
-
function isSymlinkTo6(linkPath, source) {
|
|
30606
|
-
try {
|
|
30607
|
-
return fs42.realpathSync(linkPath) === fs42.realpathSync(source);
|
|
30608
|
-
} catch {
|
|
30609
|
-
return false;
|
|
30610
|
-
}
|
|
30611
|
-
}
|
|
30612
30702
|
function hashString4(value) {
|
|
30613
30703
|
return `sha256:${crypto9.createHash("sha256").update(value).digest("hex")}`;
|
|
30614
30704
|
}
|
|
30615
30705
|
|
|
30616
30706
|
// src/adapters/opencode.ts
|
|
30617
30707
|
import crypto10 from "crypto";
|
|
30618
|
-
import
|
|
30708
|
+
import fs44 from "fs";
|
|
30619
30709
|
import os6 from "os";
|
|
30620
|
-
import
|
|
30621
|
-
var
|
|
30710
|
+
import path44 from "path";
|
|
30711
|
+
var import_yaml12 = __toESM(require_dist(), 1);
|
|
30622
30712
|
function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30623
30713
|
const scope = options.scope ?? "global";
|
|
30624
30714
|
const profile = resolveTargetPaths({
|
|
@@ -30635,7 +30725,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30635
30725
|
config_doc: profile.config_doc
|
|
30636
30726
|
};
|
|
30637
30727
|
const rules = compileRules(
|
|
30638
|
-
|
|
30728
|
+
path44.join(sourceRoot, config.source.rules),
|
|
30639
30729
|
"opencode",
|
|
30640
30730
|
mappings,
|
|
30641
30731
|
lossReport
|
|
@@ -30686,7 +30776,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30686
30776
|
}
|
|
30687
30777
|
if (!shouldSkipComponent6(options, "skills")) {
|
|
30688
30778
|
outcomes.push(
|
|
30689
|
-
syncSkills5(
|
|
30779
|
+
...syncSkills5(
|
|
30690
30780
|
config,
|
|
30691
30781
|
sourceRoot,
|
|
30692
30782
|
paths,
|
|
@@ -30699,7 +30789,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30699
30789
|
)
|
|
30700
30790
|
);
|
|
30701
30791
|
outcomes.push(
|
|
30702
|
-
syncSkills5(
|
|
30792
|
+
...syncSkills5(
|
|
30703
30793
|
config,
|
|
30704
30794
|
sourceRoot,
|
|
30705
30795
|
paths,
|
|
@@ -30739,14 +30829,14 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30739
30829
|
function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
30740
30830
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30741
30831
|
const destination = resolveTargetPath(paths.instructions);
|
|
30742
|
-
const baseContent =
|
|
30832
|
+
const baseContent = fs44.existsSync(source) ? fs44.readFileSync(source, "utf8").trim() : "";
|
|
30743
30833
|
const composed = agentsAppendix ? `${baseContent}
|
|
30744
30834
|
|
|
30745
30835
|
--- tangyr managed rules ---
|
|
30746
30836
|
${agentsAppendix}`.trim() : baseContent;
|
|
30747
30837
|
const marker = formatProvenanceMarker(
|
|
30748
30838
|
"markdown",
|
|
30749
|
-
|
|
30839
|
+
path44.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30750
30840
|
hashString5(composed),
|
|
30751
30841
|
"opencode"
|
|
30752
30842
|
);
|
|
@@ -30773,16 +30863,16 @@ ${composed}
|
|
|
30773
30863
|
);
|
|
30774
30864
|
}
|
|
30775
30865
|
function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30776
|
-
const sourceAgentsRoot =
|
|
30777
|
-
if (!
|
|
30866
|
+
const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
|
|
30867
|
+
if (!fs44.existsSync(sourceAgentsRoot)) {
|
|
30778
30868
|
return [skippedMissingSource6("agents", sourceAgentsRoot)];
|
|
30779
30869
|
}
|
|
30780
|
-
const sourceAgents = ts(
|
|
30870
|
+
const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
|
|
30781
30871
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
30782
30872
|
return sourceAgents.map((agentFile) => {
|
|
30783
|
-
const destination =
|
|
30873
|
+
const destination = path44.join(
|
|
30784
30874
|
agentsRoot,
|
|
30785
|
-
`${
|
|
30875
|
+
`${path44.basename(agentFile, ".md")}.md`
|
|
30786
30876
|
);
|
|
30787
30877
|
let compiled;
|
|
30788
30878
|
try {
|
|
@@ -30838,19 +30928,19 @@ function applyProviderModelBinding(compiled, mappings) {
|
|
|
30838
30928
|
const after = compiled.slice(fmEnd);
|
|
30839
30929
|
let fields;
|
|
30840
30930
|
try {
|
|
30841
|
-
fields = (0,
|
|
30931
|
+
fields = (0, import_yaml12.parse)(yamlBlock) ?? {};
|
|
30842
30932
|
} catch {
|
|
30843
30933
|
return compiled;
|
|
30844
30934
|
}
|
|
30845
30935
|
fields.model = modelValue;
|
|
30846
|
-
return `${before}${(0,
|
|
30936
|
+
return `${before}${(0, import_yaml12.stringify)(fields).trim()}${after}`;
|
|
30847
30937
|
}
|
|
30848
30938
|
function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30849
|
-
const sourceCommandsRoot =
|
|
30850
|
-
if (!
|
|
30939
|
+
const sourceCommandsRoot = path44.join(sourceRoot, config.source.commands);
|
|
30940
|
+
if (!fs44.existsSync(sourceCommandsRoot)) {
|
|
30851
30941
|
return [skippedMissingSource6("commands", sourceCommandsRoot)];
|
|
30852
30942
|
}
|
|
30853
|
-
const sourceCommands = ts(
|
|
30943
|
+
const sourceCommands = ts(path44.join(sourceCommandsRoot, "*.md")).sort();
|
|
30854
30944
|
const commandsRoot = resolveTargetPath(paths.commands);
|
|
30855
30945
|
return sourceCommands.map((commandFile) => {
|
|
30856
30946
|
const { data, body } = parseCommandFile(commandFile);
|
|
@@ -30864,7 +30954,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
|
|
|
30864
30954
|
if (typeof data.model === "string") {
|
|
30865
30955
|
frontmatter.model = data.model;
|
|
30866
30956
|
}
|
|
30867
|
-
const relativeSource = `commands/${
|
|
30957
|
+
const relativeSource = `commands/${path44.basename(commandFile)}`;
|
|
30868
30958
|
const marker = formatProvenanceMarker(
|
|
30869
30959
|
"markdown",
|
|
30870
30960
|
relativeSource,
|
|
@@ -30873,16 +30963,16 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
|
|
|
30873
30963
|
);
|
|
30874
30964
|
const content = Object.keys(frontmatter).length > 0 ? `${marker}
|
|
30875
30965
|
---
|
|
30876
|
-
${(0,
|
|
30966
|
+
${(0, import_yaml12.stringify)(frontmatter).trim()}
|
|
30877
30967
|
---
|
|
30878
30968
|
|
|
30879
30969
|
${body.trimEnd()}
|
|
30880
30970
|
` : `${marker}
|
|
30881
30971
|
${body.trimEnd()}
|
|
30882
30972
|
`;
|
|
30883
|
-
const destination =
|
|
30973
|
+
const destination = path44.join(
|
|
30884
30974
|
commandsRoot,
|
|
30885
|
-
`${
|
|
30975
|
+
`${path44.basename(commandFile, ".md")}.md`
|
|
30886
30976
|
);
|
|
30887
30977
|
if (options.dryRun) {
|
|
30888
30978
|
logger.info(
|
|
@@ -30908,42 +30998,35 @@ ${body.trimEnd()}
|
|
|
30908
30998
|
);
|
|
30909
30999
|
});
|
|
30910
31000
|
}
|
|
30911
|
-
function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath,
|
|
30912
|
-
|
|
30913
|
-
|
|
30914
|
-
|
|
30915
|
-
|
|
30916
|
-
|
|
30917
|
-
|
|
30918
|
-
|
|
30919
|
-
|
|
30920
|
-
|
|
30921
|
-
|
|
30922
|
-
|
|
30923
|
-
|
|
30924
|
-
|
|
30925
|
-
|
|
30926
|
-
|
|
30927
|
-
|
|
30928
|
-
} else if (artifactClass === "managed-symlink") {
|
|
30929
|
-
fs43.unlinkSync(destination);
|
|
30930
|
-
}
|
|
30931
|
-
ensureDir(path43.dirname(destination));
|
|
30932
|
-
createRelativeSymlink(source, destination, "dir");
|
|
30933
|
-
logger.verbose(`Skills: created skills path ${destination}`);
|
|
30934
|
-
return { component, status: "success", path: destination };
|
|
31001
|
+
function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, _component = "skills", destination = "") {
|
|
31002
|
+
return syncSkillsSlot({
|
|
31003
|
+
config,
|
|
31004
|
+
sourceRoot,
|
|
31005
|
+
source: path44.resolve(sourceRoot, config.source.skills),
|
|
31006
|
+
destination,
|
|
31007
|
+
dryRun: options.dryRun,
|
|
31008
|
+
logger,
|
|
31009
|
+
onUnmanagedConflict: (conflictPath) => handleConflict6(
|
|
31010
|
+
conflictPath,
|
|
31011
|
+
config,
|
|
31012
|
+
options,
|
|
31013
|
+
logger,
|
|
31014
|
+
manifest,
|
|
31015
|
+
scopePath
|
|
31016
|
+
)
|
|
31017
|
+
});
|
|
30935
31018
|
}
|
|
30936
31019
|
function syncMcp6(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
30937
31020
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30938
31021
|
const sourceLabel = mcpSourceLabel(config);
|
|
30939
31022
|
const destination = resolveTargetPath(paths.config_doc);
|
|
30940
|
-
if (!
|
|
31023
|
+
if (!fs44.existsSync(source)) {
|
|
30941
31024
|
if (!options.dryRun) {
|
|
30942
31025
|
syncConfigDoc(paths, {}, lossReport, {}, mappings);
|
|
30943
31026
|
}
|
|
30944
31027
|
return skippedMissingSource6("mcp", source);
|
|
30945
31028
|
}
|
|
30946
|
-
const sourceMcpJson = JSON.parse(
|
|
31029
|
+
const sourceMcpJson = JSON.parse(fs44.readFileSync(source, "utf8"));
|
|
30947
31030
|
const mcpJson = compileMcp(
|
|
30948
31031
|
sourceMcpJson,
|
|
30949
31032
|
"opencode",
|
|
@@ -31009,9 +31092,9 @@ function syncProviderBlock(mappings) {
|
|
|
31009
31092
|
function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
|
|
31010
31093
|
const destination = resolveTargetPath(paths.config_doc);
|
|
31011
31094
|
let existing = {};
|
|
31012
|
-
if (
|
|
31095
|
+
if (fs44.existsSync(destination)) {
|
|
31013
31096
|
try {
|
|
31014
|
-
existing = JSON.parse(
|
|
31097
|
+
existing = JSON.parse(fs44.readFileSync(destination, "utf8"));
|
|
31015
31098
|
} catch {
|
|
31016
31099
|
existing = {};
|
|
31017
31100
|
}
|
|
@@ -31036,8 +31119,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
|
|
|
31036
31119
|
};
|
|
31037
31120
|
}
|
|
31038
31121
|
}
|
|
31039
|
-
ensureDir(
|
|
31040
|
-
|
|
31122
|
+
ensureDir(path44.dirname(destination));
|
|
31123
|
+
fs44.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
31041
31124
|
`);
|
|
31042
31125
|
}
|
|
31043
31126
|
function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
|
|
@@ -31051,14 +31134,14 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
|
|
|
31051
31134
|
if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
31052
31135
|
return { component, status: "conflict", path: destination };
|
|
31053
31136
|
}
|
|
31054
|
-
ensureDir(
|
|
31137
|
+
ensureDir(path44.dirname(destination));
|
|
31055
31138
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
31056
31139
|
if (clearedLink !== null) {
|
|
31057
31140
|
logger.verbose(
|
|
31058
31141
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
31059
31142
|
);
|
|
31060
31143
|
}
|
|
31061
|
-
|
|
31144
|
+
fs44.writeFileSync(destination, content);
|
|
31062
31145
|
return { component, status: "success", path: destination };
|
|
31063
31146
|
}
|
|
31064
31147
|
function handleConflict6(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -31076,7 +31159,7 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
|
|
|
31076
31159
|
if (manifest && scopePath) {
|
|
31077
31160
|
backupFile(destination, manifest, scopePath);
|
|
31078
31161
|
writeManifest(scopePath, manifest);
|
|
31079
|
-
|
|
31162
|
+
fs44.rmSync(destination, { recursive: true, force: true });
|
|
31080
31163
|
} else {
|
|
31081
31164
|
const parked = parkConflictingPath(
|
|
31082
31165
|
destination,
|
|
@@ -31091,12 +31174,12 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
|
|
|
31091
31174
|
}
|
|
31092
31175
|
return true;
|
|
31093
31176
|
}
|
|
31094
|
-
|
|
31177
|
+
fs44.rmSync(destination, { recursive: true, force: true });
|
|
31095
31178
|
return true;
|
|
31096
31179
|
}
|
|
31097
31180
|
function isCompiledCurrent5(destination, expectedContent, _expectedHash) {
|
|
31098
31181
|
try {
|
|
31099
|
-
return
|
|
31182
|
+
return fs44.readFileSync(destination, "utf8") === expectedContent;
|
|
31100
31183
|
} catch {
|
|
31101
31184
|
return false;
|
|
31102
31185
|
}
|
|
@@ -31111,18 +31194,11 @@ function skippedMissingSource6(component, source) {
|
|
|
31111
31194
|
function shouldSkipComponent6(options, component) {
|
|
31112
31195
|
return Boolean(options.component && options.component !== component);
|
|
31113
31196
|
}
|
|
31114
|
-
function isSymlinkTo7(linkPath, source) {
|
|
31115
|
-
try {
|
|
31116
|
-
return fs43.realpathSync(linkPath) === fs43.realpathSync(source);
|
|
31117
|
-
} catch {
|
|
31118
|
-
return false;
|
|
31119
|
-
}
|
|
31120
|
-
}
|
|
31121
31197
|
function hashString5(value) {
|
|
31122
31198
|
return `sha256:${crypto10.createHash("sha256").update(value).digest("hex")}`;
|
|
31123
31199
|
}
|
|
31124
31200
|
function parseCommandFile(commandFile) {
|
|
31125
|
-
const content =
|
|
31201
|
+
const content = fs44.readFileSync(commandFile, "utf8");
|
|
31126
31202
|
if (!content.startsWith("---\n")) {
|
|
31127
31203
|
return { data: {}, body: content };
|
|
31128
31204
|
}
|
|
@@ -31131,7 +31207,7 @@ function parseCommandFile(commandFile) {
|
|
|
31131
31207
|
return { data: {}, body: content };
|
|
31132
31208
|
}
|
|
31133
31209
|
try {
|
|
31134
|
-
const data = (0,
|
|
31210
|
+
const data = (0, import_yaml12.parse)(content.slice(4, endIndex)) ?? {};
|
|
31135
31211
|
const body = content.slice(endIndex + "\n---".length).replace(/^\n/u, "");
|
|
31136
31212
|
return { data, body };
|
|
31137
31213
|
} catch {
|
|
@@ -31142,7 +31218,7 @@ function parseCommandFile(commandFile) {
|
|
|
31142
31218
|
// src/commands/install.ts
|
|
31143
31219
|
function isBackupablePath(targetPath) {
|
|
31144
31220
|
try {
|
|
31145
|
-
const lstat =
|
|
31221
|
+
const lstat = fs45.lstatSync(targetPath);
|
|
31146
31222
|
return lstat.isSymbolicLink() || lstat.isFile() || lstat.isDirectory();
|
|
31147
31223
|
} catch {
|
|
31148
31224
|
return false;
|
|
@@ -31179,7 +31255,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31179
31255
|
);
|
|
31180
31256
|
}
|
|
31181
31257
|
const kitName = resolvedKitName ?? config.kit;
|
|
31182
|
-
const kitPath = kitPathOverride ?? (options.kitPath ?
|
|
31258
|
+
const kitPath = kitPathOverride ?? (options.kitPath ? path45.resolve(options.kitPath) : config.kitPath);
|
|
31183
31259
|
if (!kitName && !kitPath) {
|
|
31184
31260
|
logger.error(
|
|
31185
31261
|
"No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
|
|
@@ -31284,8 +31360,8 @@ async function runInstallCommand(options, logger) {
|
|
|
31284
31360
|
config: options.config,
|
|
31285
31361
|
scope
|
|
31286
31362
|
});
|
|
31287
|
-
const skillsSource =
|
|
31288
|
-
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") &&
|
|
31363
|
+
const skillsSource = path45.resolve(kitInfo.path, config.source.skills);
|
|
31364
|
+
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path45.basename(f.path) === "skills";
|
|
31289
31365
|
const foreignSkillsSlots = new Set(
|
|
31290
31366
|
assessResult.findings.filter(
|
|
31291
31367
|
(f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
|
|
@@ -31323,7 +31399,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31323
31399
|
let instructionsLabel;
|
|
31324
31400
|
try {
|
|
31325
31401
|
const resolved = resolveInstructionsSource(kitInfo.path, config);
|
|
31326
|
-
instructionsLabel = resolved ?
|
|
31402
|
+
instructionsLabel = resolved ? path45.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
|
|
31327
31403
|
} catch (err) {
|
|
31328
31404
|
logger.error(
|
|
31329
31405
|
`[dry-run] ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -31351,7 +31427,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31351
31427
|
}
|
|
31352
31428
|
}
|
|
31353
31429
|
logger.info(
|
|
31354
|
-
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${
|
|
31430
|
+
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path45.join(scopePath, "manifest.json")}`
|
|
31355
31431
|
);
|
|
31356
31432
|
return;
|
|
31357
31433
|
}
|
|
@@ -31410,7 +31486,7 @@ ACCEPTED CONFLICTS (posture: ${posture}; ${replaceable.length} target(s)):`
|
|
|
31410
31486
|
logger.info(` - ${finding.path}`);
|
|
31411
31487
|
logger.info(` source: ${sources}`);
|
|
31412
31488
|
logger.info(
|
|
31413
|
-
` action: backup-and-replace${
|
|
31489
|
+
` action: backup-and-replace${fs45.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
|
|
31414
31490
|
);
|
|
31415
31491
|
logger.info(` backup: ${backupLocation}`);
|
|
31416
31492
|
continue;
|
|
@@ -31534,20 +31610,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
31534
31610
|
writeManifest(scopePath, manifest);
|
|
31535
31611
|
logger.info(`
|
|
31536
31612
|
Installation complete: ${installedCount} files installed.`);
|
|
31537
|
-
logger.info(`Manifest written to ${
|
|
31613
|
+
logger.info(`Manifest written to ${path45.join(scopePath, "manifest.json")}`);
|
|
31538
31614
|
logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
|
|
31539
31615
|
logger.info(`Scope: ${scope}`);
|
|
31540
31616
|
logger.info(`Tools: ${tools.join(", ")}`);
|
|
31541
31617
|
reportHookRejections(
|
|
31542
31618
|
installLossReport,
|
|
31543
31619
|
tools,
|
|
31544
|
-
|
|
31620
|
+
path45.resolve(kitInfo.path, "hooks"),
|
|
31545
31621
|
kitInfo.components.hooks.declared
|
|
31546
31622
|
);
|
|
31547
31623
|
const hooksConflict = reportHooksSourceConflict(
|
|
31548
31624
|
installLossReport,
|
|
31549
31625
|
tools,
|
|
31550
|
-
|
|
31626
|
+
path45.resolve(kitInfo.path, "hooks"),
|
|
31551
31627
|
kitInfo.components.hooks.declared
|
|
31552
31628
|
);
|
|
31553
31629
|
if (hooksConflict) {
|
|
@@ -31906,7 +31982,7 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
31906
31982
|
return 0;
|
|
31907
31983
|
}
|
|
31908
31984
|
try {
|
|
31909
|
-
const stat =
|
|
31985
|
+
const stat = fs45.lstatSync(destination);
|
|
31910
31986
|
if (stat.isFile() && !stat.isSymbolicLink()) {
|
|
31911
31987
|
logger.warn(
|
|
31912
31988
|
`${destination}: a regular file occupies the skills slot \u2014 skipping skills. Move or remove it, then re-run install.`
|
|
@@ -31934,17 +32010,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
31934
32010
|
manifest,
|
|
31935
32011
|
scopePath
|
|
31936
32012
|
);
|
|
31937
|
-
const skillsSource =
|
|
32013
|
+
const skillsSource = path45.resolve(kitInfo.path, config.source.skills);
|
|
31938
32014
|
let count = 0;
|
|
31939
32015
|
for (const outcome of outcomes) {
|
|
31940
32016
|
if (outcome.status !== "success" && outcome.status !== "skipped-current") {
|
|
31941
32017
|
continue;
|
|
31942
32018
|
}
|
|
31943
|
-
const skillName =
|
|
32019
|
+
const skillName = path45.basename(outcome.path);
|
|
31944
32020
|
addArtifactToManifest(manifest, {
|
|
31945
32021
|
relativePath: `claude-code/skills/${skillName}`,
|
|
31946
32022
|
path: outcome.path,
|
|
31947
|
-
hash: describeArtifactState(outcome.path) ?? `dir:${
|
|
32023
|
+
hash: describeArtifactState(outcome.path) ?? `dir:${path45.join(skillsSource, skillName)}`,
|
|
31948
32024
|
origin: "tangyr-managed"
|
|
31949
32025
|
});
|
|
31950
32026
|
count++;
|
|
@@ -31958,10 +32034,10 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
31958
32034
|
logger.verbose(` skipped (operator choice): ${placement.destination}`);
|
|
31959
32035
|
continue;
|
|
31960
32036
|
}
|
|
31961
|
-
const destDir =
|
|
31962
|
-
|
|
32037
|
+
const destDir = path45.dirname(placement.destination);
|
|
32038
|
+
fs45.mkdirSync(destDir, { recursive: true });
|
|
31963
32039
|
if (placement.type === "symlink") {
|
|
31964
|
-
if (
|
|
32040
|
+
if (fs45.existsSync(placement.destination) || isSymlink2(placement.destination)) {
|
|
31965
32041
|
removeManagedPath(placement.destination);
|
|
31966
32042
|
}
|
|
31967
32043
|
createRelativeSymlink(
|
|
@@ -31978,7 +32054,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
31978
32054
|
` symlink: ${placement.source} \u2192 ${placement.destination}`
|
|
31979
32055
|
);
|
|
31980
32056
|
} else {
|
|
31981
|
-
|
|
32057
|
+
fs45.copyFileSync(placement.source, placement.destination);
|
|
31982
32058
|
logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
|
|
31983
32059
|
}
|
|
31984
32060
|
addArtifactToManifest(manifest, {
|
|
@@ -32240,6 +32316,16 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32240
32316
|
}
|
|
32241
32317
|
throwUnrecognizedTarget(tool);
|
|
32242
32318
|
}
|
|
32319
|
+
const skillsSlotKey = skillsSubPathKey(
|
|
32320
|
+
tool,
|
|
32321
|
+
outcome.path,
|
|
32322
|
+
mappings,
|
|
32323
|
+
scope,
|
|
32324
|
+
projectRoot
|
|
32325
|
+
);
|
|
32326
|
+
if (skillsSlotKey) {
|
|
32327
|
+
return skillsSlotKey;
|
|
32328
|
+
}
|
|
32243
32329
|
if (tool === "cline") {
|
|
32244
32330
|
const profile2 = resolveTargetPaths({
|
|
32245
32331
|
scope,
|
|
@@ -32260,11 +32346,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32260
32346
|
if (outcome.path === mcpFile2) {
|
|
32261
32347
|
return "cline/mcp.json";
|
|
32262
32348
|
}
|
|
32263
|
-
if (outcome.path.startsWith(`${workflowsRoot}${
|
|
32264
|
-
return `cline/workflows/${
|
|
32349
|
+
if (outcome.path.startsWith(`${workflowsRoot}${path45.sep}`)) {
|
|
32350
|
+
return `cline/workflows/${path45.basename(outcome.path)}`;
|
|
32265
32351
|
}
|
|
32266
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32267
|
-
return `cline/rules/${
|
|
32352
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path45.sep}`)) {
|
|
32353
|
+
return `cline/rules/${path45.basename(outcome.path)}`;
|
|
32268
32354
|
}
|
|
32269
32355
|
return null;
|
|
32270
32356
|
}
|
|
@@ -32300,14 +32386,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32300
32386
|
if (outcome.path === permissionsFile) {
|
|
32301
32387
|
return "cursor/permissions.json";
|
|
32302
32388
|
}
|
|
32303
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32304
|
-
return `cursor/agents/${
|
|
32389
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
|
|
32390
|
+
return `cursor/agents/${path45.basename(outcome.path)}`;
|
|
32305
32391
|
}
|
|
32306
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32307
|
-
return `cursor/rules/${
|
|
32392
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path45.sep}`)) {
|
|
32393
|
+
return `cursor/rules/${path45.basename(outcome.path)}`;
|
|
32308
32394
|
}
|
|
32309
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
32310
|
-
const rel =
|
|
32395
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path45.sep}`)) {
|
|
32396
|
+
const rel = path45.relative(skillsRoot2, outcome.path);
|
|
32311
32397
|
return `cursor/skills/${rel}`;
|
|
32312
32398
|
}
|
|
32313
32399
|
return null;
|
|
@@ -32333,14 +32419,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32333
32419
|
if (outcome.path === skillsSharedRoot) {
|
|
32334
32420
|
return "opencode/skills_shared";
|
|
32335
32421
|
}
|
|
32336
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32337
|
-
return `opencode/agents/${
|
|
32422
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
|
|
32423
|
+
return `opencode/agents/${path45.basename(outcome.path)}`;
|
|
32338
32424
|
}
|
|
32339
|
-
if (outcome.path.startsWith(`${commandsRoot}${
|
|
32340
|
-
return `opencode/commands/${
|
|
32425
|
+
if (outcome.path.startsWith(`${commandsRoot}${path45.sep}`)) {
|
|
32426
|
+
return `opencode/commands/${path45.basename(outcome.path)}`;
|
|
32341
32427
|
}
|
|
32342
32428
|
if (outcome.path === configDocFile) {
|
|
32343
|
-
return `opencode/${
|
|
32429
|
+
return `opencode/${path45.basename(outcome.path)}`;
|
|
32344
32430
|
}
|
|
32345
32431
|
return null;
|
|
32346
32432
|
}
|
|
@@ -32357,26 +32443,29 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32357
32443
|
const hooksRoot = resolveTargetPath(copilot.hooks);
|
|
32358
32444
|
const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
|
|
32359
32445
|
const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
|
|
32360
|
-
if (outcome.path.startsWith(`${
|
|
32361
|
-
return `copilot/
|
|
32446
|
+
if (copilot.rules !== null && outcome.path.startsWith(`${resolveTargetPath(copilot.rules)}${path45.sep}`)) {
|
|
32447
|
+
return `copilot/rules/${path45.relative(resolveTargetPath(copilot.rules), outcome.path)}`;
|
|
32448
|
+
}
|
|
32449
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path45.sep}`)) {
|
|
32450
|
+
return `copilot/skills/${path45.relative(skillsRoot2, outcome.path)}`;
|
|
32362
32451
|
}
|
|
32363
32452
|
if (outcome.path === skillsRoot2) {
|
|
32364
32453
|
return "copilot/skills";
|
|
32365
32454
|
}
|
|
32366
32455
|
if (instructionsMirror !== null && outcome.path === instructionsMirror) {
|
|
32367
|
-
return `copilot/${
|
|
32456
|
+
return `copilot/${path45.basename(outcome.path)}`;
|
|
32368
32457
|
}
|
|
32369
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32370
|
-
return `copilot/agents/${
|
|
32458
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path45.sep}`)) {
|
|
32459
|
+
return `copilot/agents/${path45.basename(outcome.path)}`;
|
|
32371
32460
|
}
|
|
32372
|
-
if (outcome.path.startsWith(`${promptsRoot}${
|
|
32373
|
-
return `copilot/prompts/${
|
|
32461
|
+
if (outcome.path.startsWith(`${promptsRoot}${path45.sep}`)) {
|
|
32462
|
+
return `copilot/prompts/${path45.basename(outcome.path)}`;
|
|
32374
32463
|
}
|
|
32375
|
-
if (outcome.path.startsWith(`${hooksRoot}${
|
|
32376
|
-
return `copilot/hooks/${
|
|
32464
|
+
if (outcome.path.startsWith(`${hooksRoot}${path45.sep}`)) {
|
|
32465
|
+
return `copilot/hooks/${path45.basename(outcome.path)}`;
|
|
32377
32466
|
}
|
|
32378
32467
|
if (outcome.path === mcpFile2) {
|
|
32379
|
-
return `copilot/${
|
|
32468
|
+
return `copilot/${path45.basename(outcome.path)}`;
|
|
32380
32469
|
}
|
|
32381
32470
|
return null;
|
|
32382
32471
|
}
|
|
@@ -32393,17 +32482,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32393
32482
|
if (outcome.path === skillsRoot) {
|
|
32394
32483
|
return "codex/skills";
|
|
32395
32484
|
}
|
|
32396
|
-
if (outcome.path.startsWith(`${agentsRoot}${
|
|
32397
|
-
return `codex/agents/${
|
|
32485
|
+
if (outcome.path.startsWith(`${agentsRoot}${path45.sep}`)) {
|
|
32486
|
+
return `codex/agents/${path45.basename(outcome.path)}`;
|
|
32398
32487
|
}
|
|
32399
|
-
if (outcome.path.startsWith(`${rulesRoot}${
|
|
32400
|
-
return `codex/rules/${
|
|
32488
|
+
if (outcome.path.startsWith(`${rulesRoot}${path45.sep}`)) {
|
|
32489
|
+
return `codex/rules/${path45.basename(outcome.path)}`;
|
|
32401
32490
|
}
|
|
32402
32491
|
if (outcome.path === hooksFile) {
|
|
32403
|
-
return `codex/${
|
|
32492
|
+
return `codex/${path45.basename(outcome.path)}`;
|
|
32404
32493
|
}
|
|
32405
32494
|
if (outcome.path === mcpFile) {
|
|
32406
|
-
return `codex/${
|
|
32495
|
+
return `codex/${path45.basename(outcome.path)}`;
|
|
32407
32496
|
}
|
|
32408
32497
|
return null;
|
|
32409
32498
|
}
|
|
@@ -32472,8 +32561,8 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
|
|
|
32472
32561
|
rules: resolvedPaths.rules
|
|
32473
32562
|
};
|
|
32474
32563
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32475
|
-
const componentDir =
|
|
32476
|
-
if (
|
|
32564
|
+
const componentDir = path45.join(kitInfo.path, component);
|
|
32565
|
+
if (fs45.existsSync(componentDir) && fs45.statSync(componentDir).isDirectory()) {
|
|
32477
32566
|
placements.push({
|
|
32478
32567
|
source: componentDir,
|
|
32479
32568
|
destination: targetPath,
|
|
@@ -32503,8 +32592,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
|
|
|
32503
32592
|
rules: profile.rules
|
|
32504
32593
|
};
|
|
32505
32594
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32506
|
-
const componentDir =
|
|
32507
|
-
if (
|
|
32595
|
+
const componentDir = path45.join(kitInfo.path, component);
|
|
32596
|
+
if (fs45.existsSync(componentDir) && fs45.statSync(componentDir).isDirectory()) {
|
|
32508
32597
|
placements.push({
|
|
32509
32598
|
source: componentDir,
|
|
32510
32599
|
destination: targetPath,
|
|
@@ -32520,7 +32609,7 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32520
32609
|
const files = /* @__PURE__ */ new Map();
|
|
32521
32610
|
const entrypoint = resolveInstructionsSource(kitInfo.path, config);
|
|
32522
32611
|
if (entrypoint) {
|
|
32523
|
-
files.set(
|
|
32612
|
+
files.set(path45.basename(entrypoint.file), entrypoint.file);
|
|
32524
32613
|
}
|
|
32525
32614
|
for (const [component, reconciliation] of Object.entries(
|
|
32526
32615
|
kitInfo.components
|
|
@@ -32529,26 +32618,48 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32529
32618
|
const missingSet = new Set(reconciliation.missing);
|
|
32530
32619
|
for (const entry of reconciliation.declared) {
|
|
32531
32620
|
if (missingSet.has(entry)) continue;
|
|
32532
|
-
const relPath = isSkills ?
|
|
32533
|
-
files.set(relPath,
|
|
32621
|
+
const relPath = isSkills ? path45.join(component, entry) : path45.join(component, `${entry}.md`);
|
|
32622
|
+
files.set(relPath, path45.join(kitInfo.path, relPath));
|
|
32534
32623
|
}
|
|
32535
32624
|
}
|
|
32536
32625
|
return files;
|
|
32537
32626
|
}
|
|
32538
32627
|
function readLinkTarget(p) {
|
|
32539
32628
|
try {
|
|
32540
|
-
return
|
|
32629
|
+
return fs45.readlinkSync(p);
|
|
32541
32630
|
} catch {
|
|
32542
32631
|
return null;
|
|
32543
32632
|
}
|
|
32544
32633
|
}
|
|
32545
32634
|
function isSymlink2(p) {
|
|
32546
32635
|
try {
|
|
32547
|
-
return
|
|
32636
|
+
return fs45.lstatSync(p).isSymbolicLink();
|
|
32548
32637
|
} catch {
|
|
32549
32638
|
return false;
|
|
32550
32639
|
}
|
|
32551
32640
|
}
|
|
32641
|
+
function skillsSubPathKey(tool, outcomePath, mappings, scope, projectRoot) {
|
|
32642
|
+
const profile = resolveTargetPaths({
|
|
32643
|
+
scope,
|
|
32644
|
+
projectRoot,
|
|
32645
|
+
mappings: mappings.platformPaths
|
|
32646
|
+
})[tool];
|
|
32647
|
+
if (!profile) {
|
|
32648
|
+
return null;
|
|
32649
|
+
}
|
|
32650
|
+
for (const slot of [profile.skills, profile.skills_shared]) {
|
|
32651
|
+
if (typeof slot !== "string" || slot.length === 0) {
|
|
32652
|
+
continue;
|
|
32653
|
+
}
|
|
32654
|
+
const root = resolveTargetPath(slot);
|
|
32655
|
+
if (!outcomePath.startsWith(`${root}${path45.sep}`)) {
|
|
32656
|
+
continue;
|
|
32657
|
+
}
|
|
32658
|
+
const inside = path45.relative(root, outcomePath).split(path45.sep).join("/");
|
|
32659
|
+
return `${tool}/skills/${inside}`;
|
|
32660
|
+
}
|
|
32661
|
+
return null;
|
|
32662
|
+
}
|
|
32552
32663
|
|
|
32553
32664
|
// src/commands/kit.ts
|
|
32554
32665
|
async function runKitUpdateCommand(options, logger) {
|
|
@@ -32589,14 +32700,14 @@ async function runKitUpdateCommand(options, logger) {
|
|
|
32589
32700
|
}
|
|
32590
32701
|
|
|
32591
32702
|
// src/commands/list.ts
|
|
32592
|
-
import
|
|
32703
|
+
import path46 from "path";
|
|
32593
32704
|
function runListCommand(options, logger) {
|
|
32594
32705
|
let searchPaths = [];
|
|
32595
|
-
let directKitPath = options.kitPath ?
|
|
32706
|
+
let directKitPath = options.kitPath ? path46.resolve(options.kitPath) : void 0;
|
|
32596
32707
|
try {
|
|
32597
32708
|
const { config, configDir } = resolveConfig(options.config);
|
|
32598
32709
|
searchPaths = config.kitSearchPaths ?? [
|
|
32599
|
-
|
|
32710
|
+
path46.join(configDir, "operating-kits")
|
|
32600
32711
|
];
|
|
32601
32712
|
directKitPath = directKitPath ?? config.kitPath;
|
|
32602
32713
|
} catch (err) {
|
|
@@ -32671,7 +32782,7 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32671
32782
|
return kits;
|
|
32672
32783
|
}
|
|
32673
32784
|
const directKit = loadKit(directKitPath);
|
|
32674
|
-
if (kits.some((kit) =>
|
|
32785
|
+
if (kits.some((kit) => path46.resolve(kit.path) === directKit.path)) {
|
|
32675
32786
|
return kits;
|
|
32676
32787
|
}
|
|
32677
32788
|
return [...kits, directKit];
|
|
@@ -32679,8 +32790,8 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32679
32790
|
|
|
32680
32791
|
// src/commands/probe.ts
|
|
32681
32792
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
32682
|
-
import
|
|
32683
|
-
import
|
|
32793
|
+
import fs46 from "fs";
|
|
32794
|
+
import path47 from "path";
|
|
32684
32795
|
function runProbeCommand(options, logger) {
|
|
32685
32796
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32686
32797
|
options,
|
|
@@ -32708,7 +32819,7 @@ function runProbeCommand(options, logger) {
|
|
|
32708
32819
|
toProbeRow(
|
|
32709
32820
|
target,
|
|
32710
32821
|
key,
|
|
32711
|
-
scope === "project" ?
|
|
32822
|
+
scope === "project" ? path47.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
|
|
32712
32823
|
)
|
|
32713
32824
|
);
|
|
32714
32825
|
}
|
|
@@ -32730,7 +32841,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32730
32841
|
const resolved = resolveTargetPath(rawPath);
|
|
32731
32842
|
let accessible = false;
|
|
32732
32843
|
try {
|
|
32733
|
-
|
|
32844
|
+
fs46.accessSync(resolved);
|
|
32734
32845
|
accessible = true;
|
|
32735
32846
|
} catch {
|
|
32736
32847
|
accessible = false;
|
|
@@ -32739,7 +32850,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32739
32850
|
target,
|
|
32740
32851
|
key,
|
|
32741
32852
|
path: resolved,
|
|
32742
|
-
exists:
|
|
32853
|
+
exists: fs46.existsSync(resolved),
|
|
32743
32854
|
accessible
|
|
32744
32855
|
};
|
|
32745
32856
|
}
|
|
@@ -32757,7 +32868,7 @@ function codexRuntimeProbeRows() {
|
|
|
32757
32868
|
["binary_snap", "/snap/bin/codex"],
|
|
32758
32869
|
["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
|
|
32759
32870
|
]) {
|
|
32760
|
-
if (
|
|
32871
|
+
if (fs46.existsSync(candidatePath)) {
|
|
32761
32872
|
rows.push(toProbeRow("codex", key, candidatePath));
|
|
32762
32873
|
}
|
|
32763
32874
|
}
|
|
@@ -32773,8 +32884,8 @@ function commandProbeRows(target, key, command, args) {
|
|
|
32773
32884
|
|
|
32774
32885
|
// src/commands/status.ts
|
|
32775
32886
|
import crypto11 from "crypto";
|
|
32776
|
-
import
|
|
32777
|
-
import
|
|
32887
|
+
import fs47 from "fs";
|
|
32888
|
+
import path48 from "path";
|
|
32778
32889
|
function runStatusCommand(options, logger) {
|
|
32779
32890
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32780
32891
|
options,
|
|
@@ -32880,11 +32991,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
|
|
|
32880
32991
|
}
|
|
32881
32992
|
}
|
|
32882
32993
|
function sourceMarkdownFiles(sourceRoot, componentPath) {
|
|
32883
|
-
const root =
|
|
32884
|
-
if (!
|
|
32994
|
+
const root = path48.join(sourceRoot, componentPath);
|
|
32995
|
+
if (!fs47.existsSync(root)) {
|
|
32885
32996
|
return [];
|
|
32886
32997
|
}
|
|
32887
|
-
return ts(
|
|
32998
|
+
return ts(path48.join(root, "*.md")).sort();
|
|
32888
32999
|
}
|
|
32889
33000
|
function notRepresentableRow(component, detail) {
|
|
32890
33001
|
return {
|
|
@@ -32895,11 +33006,11 @@ function notRepresentableRow(component, detail) {
|
|
|
32895
33006
|
};
|
|
32896
33007
|
}
|
|
32897
33008
|
function readTargetJson(filePath) {
|
|
32898
|
-
if (!
|
|
33009
|
+
if (!fs47.existsSync(filePath)) {
|
|
32899
33010
|
return { kind: "missing" };
|
|
32900
33011
|
}
|
|
32901
33012
|
try {
|
|
32902
|
-
const parsed = JSON.parse(
|
|
33013
|
+
const parsed = JSON.parse(fs47.readFileSync(filePath, "utf8"));
|
|
32903
33014
|
return { kind: "object", value: isRecord(parsed) ? parsed : {} };
|
|
32904
33015
|
} catch (err) {
|
|
32905
33016
|
return {
|
|
@@ -32988,7 +33099,7 @@ function classifyInstructions(filePath, target, expectedHash, config, sourceRoot
|
|
|
32988
33099
|
}
|
|
32989
33100
|
function compiledMcpDocument(config, sourceRoot, target) {
|
|
32990
33101
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
32991
|
-
if (!
|
|
33102
|
+
if (!fs47.existsSync(source)) {
|
|
32992
33103
|
return {};
|
|
32993
33104
|
}
|
|
32994
33105
|
const compiled = compileMcp(
|
|
@@ -33001,7 +33112,7 @@ function compiledMcpDocument(config, sourceRoot, target) {
|
|
|
33001
33112
|
return isRecord(parsed) ? parsed : {};
|
|
33002
33113
|
}
|
|
33003
33114
|
function classifyMcpDocument(config, sourceRoot, target, filePath) {
|
|
33004
|
-
if (!
|
|
33115
|
+
if (!fs47.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
|
|
33005
33116
|
return notConfiguredRow("mcp", filePath);
|
|
33006
33117
|
}
|
|
33007
33118
|
return classifyJsonDocument(
|
|
@@ -33031,12 +33142,12 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
|
|
|
33031
33142
|
const rows = [];
|
|
33032
33143
|
const instructionsSource = instructionsSourcePath(sourceRoot, config);
|
|
33033
33144
|
const rules = compileRules(
|
|
33034
|
-
|
|
33145
|
+
path48.join(sourceRoot, config.source.rules),
|
|
33035
33146
|
"opencode",
|
|
33036
33147
|
mappings,
|
|
33037
33148
|
createLossReport()
|
|
33038
33149
|
);
|
|
33039
|
-
const baseInstructions =
|
|
33150
|
+
const baseInstructions = fs47.existsSync(instructionsSource) ? fs47.readFileSync(instructionsSource, "utf8").trim() : "";
|
|
33040
33151
|
const composedInstructions = rules.agentsAppendix ? `${baseInstructions}
|
|
33041
33152
|
|
|
33042
33153
|
--- tangyr managed rules ---
|
|
@@ -33058,10 +33169,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
33058
33169
|
)) {
|
|
33059
33170
|
rows.push(
|
|
33060
33171
|
classifyCompiledFile(
|
|
33061
|
-
`agents/${
|
|
33062
|
-
|
|
33172
|
+
`agents/${path48.basename(agentFile, ".md")}`,
|
|
33173
|
+
path48.join(
|
|
33063
33174
|
resolveTargetPath(paths.agents),
|
|
33064
|
-
`${
|
|
33175
|
+
`${path48.basename(agentFile, ".md")}.md`
|
|
33065
33176
|
),
|
|
33066
33177
|
"opencode",
|
|
33067
33178
|
computeSourceHash(agentFile),
|
|
@@ -33076,10 +33187,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
33076
33187
|
)) {
|
|
33077
33188
|
rows.push(
|
|
33078
33189
|
classifyCompiledFile(
|
|
33079
|
-
`commands/${
|
|
33080
|
-
|
|
33190
|
+
`commands/${path48.basename(commandFile, ".md")}`,
|
|
33191
|
+
path48.join(
|
|
33081
33192
|
resolveTargetPath(paths.commands),
|
|
33082
|
-
`${
|
|
33193
|
+
`${path48.basename(commandFile, ".md")}.md`
|
|
33083
33194
|
),
|
|
33084
33195
|
"opencode",
|
|
33085
33196
|
computeSourceHash(commandFile),
|
|
@@ -33161,10 +33272,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33161
33272
|
)) {
|
|
33162
33273
|
rows.push(
|
|
33163
33274
|
classifyCompiledFile(
|
|
33164
|
-
`agents/${
|
|
33165
|
-
|
|
33275
|
+
`agents/${path48.basename(agentFile, ".md")}`,
|
|
33276
|
+
path48.join(
|
|
33166
33277
|
resolveTargetPath(paths.agents),
|
|
33167
|
-
`${
|
|
33278
|
+
`${path48.basename(agentFile, ".md")}.md`
|
|
33168
33279
|
),
|
|
33169
33280
|
"cursor",
|
|
33170
33281
|
computeSourceHash(agentFile),
|
|
@@ -33181,7 +33292,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33181
33292
|
rows.push(
|
|
33182
33293
|
classifyCompiledFile(
|
|
33183
33294
|
`rules/${ruleFile.name}`,
|
|
33184
|
-
|
|
33295
|
+
path48.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
33185
33296
|
"cursor",
|
|
33186
33297
|
void 0,
|
|
33187
33298
|
config,
|
|
@@ -33195,11 +33306,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33195
33306
|
sourceRoot,
|
|
33196
33307
|
config.source.commands
|
|
33197
33308
|
)) {
|
|
33198
|
-
const baseName =
|
|
33309
|
+
const baseName = path48.basename(commandFile, ".md");
|
|
33199
33310
|
rows.push(
|
|
33200
33311
|
classifyCompiledFile(
|
|
33201
33312
|
`commands/${baseName}`,
|
|
33202
|
-
|
|
33313
|
+
path48.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
|
|
33203
33314
|
"cursor",
|
|
33204
33315
|
computeSourceHash(commandFile),
|
|
33205
33316
|
config,
|
|
@@ -33282,7 +33393,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33282
33393
|
rows.push(
|
|
33283
33394
|
classifyCompiledFile(
|
|
33284
33395
|
`rules/${ruleFile.name}`,
|
|
33285
|
-
|
|
33396
|
+
path48.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
33286
33397
|
"cline",
|
|
33287
33398
|
void 0,
|
|
33288
33399
|
config,
|
|
@@ -33298,10 +33409,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33298
33409
|
)) {
|
|
33299
33410
|
rows.push(
|
|
33300
33411
|
classifyCompiledFile(
|
|
33301
|
-
`commands/${
|
|
33302
|
-
|
|
33412
|
+
`commands/${path48.basename(commandFile, ".md")}`,
|
|
33413
|
+
path48.join(
|
|
33303
33414
|
resolveTargetPath(paths.workflows),
|
|
33304
|
-
|
|
33415
|
+
path48.basename(commandFile)
|
|
33305
33416
|
),
|
|
33306
33417
|
"cline",
|
|
33307
33418
|
computeSourceHash(commandFile),
|
|
@@ -33342,14 +33453,14 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33342
33453
|
return rows;
|
|
33343
33454
|
}
|
|
33344
33455
|
function compileRulesFiles(config, sourceRoot, target, mappings) {
|
|
33345
|
-
const rulesSource =
|
|
33346
|
-
if (!
|
|
33456
|
+
const rulesSource = path48.join(sourceRoot, config.source.rules);
|
|
33457
|
+
if (!fs47.existsSync(rulesSource)) {
|
|
33347
33458
|
return [];
|
|
33348
33459
|
}
|
|
33349
33460
|
return compileRules(rulesSource, target, mappings, createLossReport()).dotRulesFiles;
|
|
33350
33461
|
}
|
|
33351
33462
|
function classifyDirectoryPresence(component, dirPath) {
|
|
33352
|
-
const present =
|
|
33463
|
+
const present = fs47.existsSync(dirPath) && fs47.statSync(dirPath).isDirectory();
|
|
33353
33464
|
return {
|
|
33354
33465
|
component,
|
|
33355
33466
|
className: present ? "current" : "missing",
|
|
@@ -33368,7 +33479,7 @@ function slotsForScope2(scopeMap, scope, projectRoot) {
|
|
|
33368
33479
|
const root = projectRoot ?? process.cwd();
|
|
33369
33480
|
const resolved = {};
|
|
33370
33481
|
for (const [slot, value] of Object.entries(projectSlots)) {
|
|
33371
|
-
resolved[slot] = typeof value === "string" ?
|
|
33482
|
+
resolved[slot] = typeof value === "string" ? path48.resolve(root, value) : value;
|
|
33372
33483
|
}
|
|
33373
33484
|
return resolved;
|
|
33374
33485
|
}
|
|
@@ -33388,21 +33499,21 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33388
33499
|
rules: paths.rules
|
|
33389
33500
|
};
|
|
33390
33501
|
const rules = compileRules(
|
|
33391
|
-
|
|
33502
|
+
path48.join(sourceRoot, config.source.rules),
|
|
33392
33503
|
"codex",
|
|
33393
33504
|
mappings,
|
|
33394
33505
|
createLossReport()
|
|
33395
33506
|
);
|
|
33396
|
-
const instructionsSource =
|
|
33507
|
+
const instructionsSource = fs47.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
|
|
33397
33508
|
const composedInstructions = `${instructionsSource}
|
|
33398
33509
|
|
|
33399
33510
|
--- tangyr managed rules ---
|
|
33400
33511
|
${rules.agentsAppendix}`.trim();
|
|
33401
33512
|
const agentFiles = ts(
|
|
33402
|
-
|
|
33513
|
+
path48.join(sourceRoot, config.source.agents, "*.md")
|
|
33403
33514
|
).sort();
|
|
33404
33515
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33405
|
-
const mcpSource =
|
|
33516
|
+
const mcpSource = path48.join(sourceRoot, config.source.mcp);
|
|
33406
33517
|
const ruleRows = rules.dotRulesFiles.length === 0 ? [
|
|
33407
33518
|
{
|
|
33408
33519
|
component: "rules",
|
|
@@ -33413,7 +33524,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33413
33524
|
] : rules.dotRulesFiles.map(
|
|
33414
33525
|
(ruleFile) => classifyCompiledFile(
|
|
33415
33526
|
`rules/${ruleFile.name}`,
|
|
33416
|
-
|
|
33527
|
+
path48.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
|
|
33417
33528
|
"codex",
|
|
33418
33529
|
void 0,
|
|
33419
33530
|
config,
|
|
@@ -33431,10 +33542,10 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33431
33542
|
),
|
|
33432
33543
|
...agentFiles.map(
|
|
33433
33544
|
(agentFile) => classifyCompiledFile(
|
|
33434
|
-
`agents/${
|
|
33435
|
-
|
|
33545
|
+
`agents/${path48.basename(agentFile, ".md")}`,
|
|
33546
|
+
path48.join(
|
|
33436
33547
|
resolveTargetPath(codexPaths.agents),
|
|
33437
|
-
`${
|
|
33548
|
+
`${path48.basename(agentFile, ".md")}.toml`
|
|
33438
33549
|
),
|
|
33439
33550
|
"codex",
|
|
33440
33551
|
computeSourceHash(agentFile),
|
|
@@ -33462,7 +33573,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33462
33573
|
"hooks",
|
|
33463
33574
|
resolveTargetPath(codexPaths.hooksSharedFile)
|
|
33464
33575
|
),
|
|
33465
|
-
|
|
33576
|
+
fs47.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33466
33577
|
"mcp",
|
|
33467
33578
|
resolveTargetPath(codexPaths.mcpSharedFile),
|
|
33468
33579
|
"codex",
|
|
@@ -33528,20 +33639,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33528
33639
|
mcpSharedFile: paths.mcp_shared_file
|
|
33529
33640
|
};
|
|
33530
33641
|
const agentFiles = ts(
|
|
33531
|
-
|
|
33642
|
+
path48.join(sourceRoot, config.source.agents, "*.md")
|
|
33532
33643
|
).sort();
|
|
33533
33644
|
const commandFiles = ts(
|
|
33534
|
-
|
|
33645
|
+
path48.join(sourceRoot, config.source.commands, "*.md")
|
|
33535
33646
|
).sort();
|
|
33536
33647
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33537
|
-
const mcpSource =
|
|
33648
|
+
const mcpSource = path48.join(sourceRoot, config.source.mcp);
|
|
33538
33649
|
return [
|
|
33539
33650
|
...agentFiles.map(
|
|
33540
33651
|
(agentFile) => classifyCompiledFile(
|
|
33541
|
-
`agents/${
|
|
33542
|
-
|
|
33652
|
+
`agents/${path48.basename(agentFile, ".md")}`,
|
|
33653
|
+
path48.join(
|
|
33543
33654
|
resolveTargetPath(copilotPaths.agents),
|
|
33544
|
-
`${
|
|
33655
|
+
`${path48.basename(agentFile, ".md")}.agent.md`
|
|
33545
33656
|
),
|
|
33546
33657
|
"copilot",
|
|
33547
33658
|
computeSourceHash(agentFile),
|
|
@@ -33558,10 +33669,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33558
33669
|
),
|
|
33559
33670
|
...commandFiles.map(
|
|
33560
33671
|
(commandFile) => classifyCompiledFile(
|
|
33561
|
-
`commands/${
|
|
33562
|
-
|
|
33672
|
+
`commands/${path48.basename(commandFile, ".md")}`,
|
|
33673
|
+
path48.join(
|
|
33563
33674
|
resolveTargetPath(copilotPaths.prompts),
|
|
33564
|
-
`${
|
|
33675
|
+
`${path48.basename(commandFile, ".md")}.prompt.md`
|
|
33565
33676
|
),
|
|
33566
33677
|
"copilot",
|
|
33567
33678
|
computeSourceHash(commandFile),
|
|
@@ -33580,19 +33691,19 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33580
33691
|
sourceRoot
|
|
33581
33692
|
),
|
|
33582
33693
|
hooksPresent ? classifyCompiledHooksByProvenance(
|
|
33583
|
-
|
|
33694
|
+
path48.join(
|
|
33584
33695
|
resolveTargetPath(copilotPaths.hooks),
|
|
33585
33696
|
"tangyr-managed.json"
|
|
33586
33697
|
),
|
|
33587
33698
|
"copilot"
|
|
33588
33699
|
) : notConfiguredRow(
|
|
33589
33700
|
"hooks",
|
|
33590
|
-
|
|
33701
|
+
path48.join(
|
|
33591
33702
|
resolveTargetPath(copilotPaths.hooks),
|
|
33592
33703
|
"tangyr-managed.json"
|
|
33593
33704
|
)
|
|
33594
33705
|
),
|
|
33595
|
-
|
|
33706
|
+
fs47.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33596
33707
|
"mcp",
|
|
33597
33708
|
resolveTargetPath(copilotPaths.mcpSharedFile),
|
|
33598
33709
|
"copilot",
|
|
@@ -33612,7 +33723,7 @@ function notConfiguredRow(component, filePath) {
|
|
|
33612
33723
|
}
|
|
33613
33724
|
function classifyDirectArtifact(artifact, config, sourceRoot) {
|
|
33614
33725
|
const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
|
|
33615
|
-
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ?
|
|
33726
|
+
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path48.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
|
|
33616
33727
|
if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
|
|
33617
33728
|
const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
|
|
33618
33729
|
if (perSkill) {
|
|
@@ -33708,20 +33819,23 @@ function classifyClaudeCodeRows(sourceRoot, config, configDir, scope, projectRoo
|
|
|
33708
33819
|
function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
33709
33820
|
let entries;
|
|
33710
33821
|
try {
|
|
33711
|
-
const stat =
|
|
33822
|
+
const stat = fs47.lstatSync(slotPath);
|
|
33712
33823
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
33713
33824
|
return null;
|
|
33714
33825
|
}
|
|
33715
|
-
entries =
|
|
33826
|
+
entries = fs47.readdirSync(slotPath, { withFileTypes: true });
|
|
33716
33827
|
} catch {
|
|
33717
33828
|
return null;
|
|
33718
33829
|
}
|
|
33830
|
+
if (entries.length === 0) {
|
|
33831
|
+
return "managed-symlink";
|
|
33832
|
+
}
|
|
33719
33833
|
const links = entries.filter((entry) => entry.isSymbolicLink());
|
|
33720
33834
|
if (links.length === 0) {
|
|
33721
33835
|
return null;
|
|
33722
33836
|
}
|
|
33723
33837
|
const ours = links.filter(
|
|
33724
|
-
(entry) => isOurSymlink(
|
|
33838
|
+
(entry) => isOurSymlink(path48.join(slotPath, entry.name), sourceRoot)
|
|
33725
33839
|
);
|
|
33726
33840
|
if (ours.length === 0) {
|
|
33727
33841
|
return null;
|
|
@@ -33733,9 +33847,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
|
|
|
33733
33847
|
classifyHooks(settingsPath),
|
|
33734
33848
|
classifySettings(
|
|
33735
33849
|
settingsPath,
|
|
33736
|
-
|
|
33850
|
+
path48.resolve(sourceRoot, config.source.settings)
|
|
33737
33851
|
),
|
|
33738
|
-
classifyMcp(claudeJsonPath,
|
|
33852
|
+
classifyMcp(claudeJsonPath, path48.resolve(sourceRoot, config.source.mcp))
|
|
33739
33853
|
];
|
|
33740
33854
|
}
|
|
33741
33855
|
function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
|
|
@@ -33832,14 +33946,14 @@ function classifyMcp(filePath, sourcePath) {
|
|
|
33832
33946
|
}
|
|
33833
33947
|
function isSymlinkCurrent(linkPath, sourcePath) {
|
|
33834
33948
|
try {
|
|
33835
|
-
return
|
|
33949
|
+
return fs47.realpathSync(linkPath) === fs47.realpathSync(sourcePath);
|
|
33836
33950
|
} catch {
|
|
33837
33951
|
return false;
|
|
33838
33952
|
}
|
|
33839
33953
|
}
|
|
33840
33954
|
function isCompiledCurrent6(filePath, sourcePath) {
|
|
33841
33955
|
try {
|
|
33842
|
-
const marker = extractProvenanceMarker(
|
|
33956
|
+
const marker = extractProvenanceMarker(fs47.readFileSync(filePath, "utf8"));
|
|
33843
33957
|
return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
|
|
33844
33958
|
} catch {
|
|
33845
33959
|
return false;
|
|
@@ -33869,7 +33983,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
|
|
|
33869
33983
|
}
|
|
33870
33984
|
function readCompiledContent(filePath) {
|
|
33871
33985
|
try {
|
|
33872
|
-
return
|
|
33986
|
+
return fs47.readFileSync(filePath, "utf8");
|
|
33873
33987
|
} catch {
|
|
33874
33988
|
return null;
|
|
33875
33989
|
}
|
|
@@ -33900,8 +34014,8 @@ function hashString6(value) {
|
|
|
33900
34014
|
}
|
|
33901
34015
|
|
|
33902
34016
|
// src/commands/sync.ts
|
|
33903
|
-
import
|
|
33904
|
-
import
|
|
34017
|
+
import fs48 from "fs";
|
|
34018
|
+
import path49 from "path";
|
|
33905
34019
|
|
|
33906
34020
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
33907
34021
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -34571,13 +34685,13 @@ async function runSyncCommand(options, logger) {
|
|
|
34571
34685
|
reportHookRejections(
|
|
34572
34686
|
lossReport,
|
|
34573
34687
|
targets,
|
|
34574
|
-
|
|
34688
|
+
path49.resolve(kitInfo.path, "hooks"),
|
|
34575
34689
|
kitInfo.components.hooks.declared
|
|
34576
34690
|
);
|
|
34577
34691
|
const hooksConflict = reportHooksSourceConflict(
|
|
34578
34692
|
lossReport,
|
|
34579
34693
|
targets,
|
|
34580
|
-
|
|
34694
|
+
path49.resolve(kitInfo.path, "hooks"),
|
|
34581
34695
|
kitInfo.components.hooks.declared
|
|
34582
34696
|
);
|
|
34583
34697
|
if (hooksConflict) {
|
|
@@ -34780,8 +34894,8 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
|
|
|
34780
34894
|
}
|
|
34781
34895
|
}
|
|
34782
34896
|
function resolveKitFilePath(kitPath, relativePath) {
|
|
34783
|
-
const fullPath =
|
|
34784
|
-
return
|
|
34897
|
+
const fullPath = path49.join(kitPath, relativePath);
|
|
34898
|
+
return fs48.existsSync(fullPath) ? fullPath : null;
|
|
34785
34899
|
}
|
|
34786
34900
|
function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
|
|
34787
34901
|
if (removedSourcePaths.length === 0 || !mappings) {
|
|
@@ -34844,9 +34958,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34844
34958
|
}
|
|
34845
34959
|
if (relativePath.startsWith("agents/")) {
|
|
34846
34960
|
removeManagedCompiledArtifact2(
|
|
34847
|
-
|
|
34961
|
+
path49.join(
|
|
34848
34962
|
resolveTargetPath(paths.agents ?? ""),
|
|
34849
|
-
`${
|
|
34963
|
+
`${path49.parse(relativePath).name}.agent.md`
|
|
34850
34964
|
),
|
|
34851
34965
|
"copilot",
|
|
34852
34966
|
relativePath,
|
|
@@ -34856,9 +34970,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34856
34970
|
}
|
|
34857
34971
|
if (relativePath.startsWith("commands/")) {
|
|
34858
34972
|
removeManagedCompiledArtifact2(
|
|
34859
|
-
|
|
34973
|
+
path49.join(
|
|
34860
34974
|
resolveTargetPath(paths.prompts ?? ""),
|
|
34861
|
-
`${
|
|
34975
|
+
`${path49.parse(relativePath).name}.prompt.md`
|
|
34862
34976
|
),
|
|
34863
34977
|
"copilot",
|
|
34864
34978
|
relativePath,
|
|
@@ -34868,7 +34982,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34868
34982
|
}
|
|
34869
34983
|
if (relativePath.endsWith("hooks.json")) {
|
|
34870
34984
|
removeManagedCompiledArtifact2(
|
|
34871
|
-
|
|
34985
|
+
path49.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
|
|
34872
34986
|
"copilot",
|
|
34873
34987
|
relativePath,
|
|
34874
34988
|
logger
|
|
@@ -34898,9 +35012,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
34898
35012
|
}
|
|
34899
35013
|
if (relativePath.startsWith("agents/")) {
|
|
34900
35014
|
removeManagedCompiledArtifact2(
|
|
34901
|
-
|
|
35015
|
+
path49.join(
|
|
34902
35016
|
resolveTargetPath(paths.agents ?? ""),
|
|
34903
|
-
`${
|
|
35017
|
+
`${path49.parse(relativePath).name}.toml`
|
|
34904
35018
|
),
|
|
34905
35019
|
"codex",
|
|
34906
35020
|
relativePath,
|
|
@@ -34910,9 +35024,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
34910
35024
|
}
|
|
34911
35025
|
if (relativePath.startsWith("rules/")) {
|
|
34912
35026
|
removeManagedCompiledArtifact2(
|
|
34913
|
-
|
|
35027
|
+
path49.join(
|
|
34914
35028
|
resolveTargetPath(paths.rules ?? ""),
|
|
34915
|
-
`${
|
|
35029
|
+
`${path49.parse(relativePath).name}.rules`
|
|
34916
35030
|
),
|
|
34917
35031
|
"codex",
|
|
34918
35032
|
relativePath,
|
|
@@ -34951,9 +35065,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
34951
35065
|
}
|
|
34952
35066
|
if (relativePath.startsWith("agents/")) {
|
|
34953
35067
|
removeManagedCompiledArtifact2(
|
|
34954
|
-
|
|
35068
|
+
path49.join(
|
|
34955
35069
|
resolveTargetPath(paths.agents ?? ""),
|
|
34956
|
-
`${
|
|
35070
|
+
`${path49.parse(relativePath).name}.md`
|
|
34957
35071
|
),
|
|
34958
35072
|
"opencode",
|
|
34959
35073
|
relativePath,
|
|
@@ -34963,9 +35077,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
34963
35077
|
}
|
|
34964
35078
|
if (relativePath.startsWith("commands/")) {
|
|
34965
35079
|
removeManagedCompiledArtifact2(
|
|
34966
|
-
|
|
35080
|
+
path49.join(
|
|
34967
35081
|
resolveTargetPath(paths.commands ?? ""),
|
|
34968
|
-
`${
|
|
35082
|
+
`${path49.parse(relativePath).name}.md`
|
|
34969
35083
|
),
|
|
34970
35084
|
"opencode",
|
|
34971
35085
|
relativePath,
|
|
@@ -34997,9 +35111,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
34997
35111
|
}
|
|
34998
35112
|
if (relativePath.startsWith("agents/")) {
|
|
34999
35113
|
removeManagedCompiledArtifact2(
|
|
35000
|
-
|
|
35114
|
+
path49.join(
|
|
35001
35115
|
resolveTargetPath(paths.agents ?? ""),
|
|
35002
|
-
`${
|
|
35116
|
+
`${path49.parse(relativePath).name}.md`
|
|
35003
35117
|
),
|
|
35004
35118
|
"cursor",
|
|
35005
35119
|
relativePath,
|
|
@@ -35009,9 +35123,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
35009
35123
|
}
|
|
35010
35124
|
if (relativePath.startsWith("rules/")) {
|
|
35011
35125
|
removeManagedCompiledArtifact2(
|
|
35012
|
-
|
|
35126
|
+
path49.join(
|
|
35013
35127
|
resolveTargetPath(paths.rules ?? ""),
|
|
35014
|
-
`${
|
|
35128
|
+
`${path49.parse(relativePath).name}.mdc`
|
|
35015
35129
|
),
|
|
35016
35130
|
"cursor",
|
|
35017
35131
|
relativePath,
|
|
@@ -35021,9 +35135,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
35021
35135
|
}
|
|
35022
35136
|
if (relativePath.startsWith("commands/")) {
|
|
35023
35137
|
removeManagedCompiledArtifact2(
|
|
35024
|
-
|
|
35138
|
+
path49.join(
|
|
35025
35139
|
resolveTargetPath(paths.skills ?? ""),
|
|
35026
|
-
|
|
35140
|
+
path49.parse(relativePath).name,
|
|
35027
35141
|
"SKILL.md"
|
|
35028
35142
|
),
|
|
35029
35143
|
"cursor",
|
|
@@ -35067,9 +35181,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
35067
35181
|
}
|
|
35068
35182
|
if (relativePath.startsWith("rules/")) {
|
|
35069
35183
|
removeManagedCompiledArtifact2(
|
|
35070
|
-
|
|
35184
|
+
path49.join(
|
|
35071
35185
|
resolveTargetPath(paths.rules ?? ""),
|
|
35072
|
-
`${
|
|
35186
|
+
`${path49.parse(relativePath).name}.md`
|
|
35073
35187
|
),
|
|
35074
35188
|
"cline",
|
|
35075
35189
|
relativePath,
|
|
@@ -35079,9 +35193,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
35079
35193
|
}
|
|
35080
35194
|
if (relativePath.startsWith("commands/")) {
|
|
35081
35195
|
removeManagedCompiledArtifact2(
|
|
35082
|
-
|
|
35196
|
+
path49.join(
|
|
35083
35197
|
resolveTargetPath(paths.workflows ?? ""),
|
|
35084
|
-
|
|
35198
|
+
path49.basename(relativePath)
|
|
35085
35199
|
),
|
|
35086
35200
|
"cline",
|
|
35087
35201
|
relativePath,
|
|
@@ -35099,17 +35213,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
35099
35213
|
}
|
|
35100
35214
|
}
|
|
35101
35215
|
function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
|
|
35102
|
-
if (!
|
|
35216
|
+
if (!fs48.existsSync(artifactPath)) {
|
|
35103
35217
|
return;
|
|
35104
35218
|
}
|
|
35105
|
-
if (!
|
|
35219
|
+
if (!fs48.statSync(artifactPath).isFile()) {
|
|
35106
35220
|
return;
|
|
35107
35221
|
}
|
|
35108
|
-
const marker = extractProvenanceMarker(
|
|
35222
|
+
const marker = extractProvenanceMarker(fs48.readFileSync(artifactPath, "utf8"));
|
|
35109
35223
|
if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
|
|
35110
35224
|
return;
|
|
35111
35225
|
}
|
|
35112
|
-
|
|
35226
|
+
fs48.rmSync(artifactPath, { force: true });
|
|
35113
35227
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
35114
35228
|
}
|
|
35115
35229
|
function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
@@ -35140,10 +35254,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
|
|
|
35140
35254
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
35141
35255
|
}
|
|
35142
35256
|
function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
35143
|
-
if (!
|
|
35257
|
+
if (!fs48.existsSync(artifactPath)) {
|
|
35144
35258
|
return;
|
|
35145
35259
|
}
|
|
35146
|
-
const content =
|
|
35260
|
+
const content = fs48.readFileSync(artifactPath, "utf8");
|
|
35147
35261
|
const startMarker = "# tangyr: managed mcp start";
|
|
35148
35262
|
const endMarker = "# tangyr: managed mcp end";
|
|
35149
35263
|
const startIndex = content.indexOf(startMarker);
|
|
@@ -35160,19 +35274,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
|
35160
35274
|
const after = content.slice(endIndex + endMarker.length).trimStart();
|
|
35161
35275
|
const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
|
|
35162
35276
|
if (cleaned.length === 0) {
|
|
35163
|
-
|
|
35277
|
+
fs48.rmSync(artifactPath, { force: true });
|
|
35164
35278
|
} else {
|
|
35165
|
-
|
|
35279
|
+
fs48.writeFileSync(artifactPath, `${cleaned}
|
|
35166
35280
|
`);
|
|
35167
35281
|
}
|
|
35168
35282
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
35169
35283
|
}
|
|
35170
35284
|
function readJsonObject5(filePath) {
|
|
35171
|
-
if (!
|
|
35285
|
+
if (!fs48.existsSync(filePath)) {
|
|
35172
35286
|
return null;
|
|
35173
35287
|
}
|
|
35174
35288
|
try {
|
|
35175
|
-
const parsed = JSON.parse(
|
|
35289
|
+
const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
|
|
35176
35290
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
35177
35291
|
} catch {
|
|
35178
35292
|
return null;
|
|
@@ -35186,10 +35300,10 @@ function readJsonMetadata(value) {
|
|
|
35186
35300
|
}
|
|
35187
35301
|
function writeJsonOrRemove2(filePath, parsed) {
|
|
35188
35302
|
if (isEmptyJsonValue2(parsed)) {
|
|
35189
|
-
|
|
35303
|
+
fs48.rmSync(filePath, { force: true });
|
|
35190
35304
|
return;
|
|
35191
35305
|
}
|
|
35192
|
-
|
|
35306
|
+
fs48.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
35193
35307
|
`);
|
|
35194
35308
|
}
|
|
35195
35309
|
function isEmptyJsonValue2(value) {
|
|
@@ -35249,8 +35363,8 @@ function removeManagedHookEntries(value, expectedSource) {
|
|
|
35249
35363
|
}
|
|
35250
35364
|
|
|
35251
35365
|
// src/commands/validate.ts
|
|
35252
|
-
import
|
|
35253
|
-
import
|
|
35366
|
+
import fs49 from "fs";
|
|
35367
|
+
import path50 from "path";
|
|
35254
35368
|
var SUPPORTED_KIT_FORMATS2 = [1];
|
|
35255
35369
|
var SUPPORTED_DISCIPLINE_VERSIONS = [
|
|
35256
35370
|
"0.14.0",
|
|
@@ -35365,12 +35479,12 @@ function checkArchetype(kit) {
|
|
|
35365
35479
|
}
|
|
35366
35480
|
function checkHookScriptsExist(kit) {
|
|
35367
35481
|
const violations = [];
|
|
35368
|
-
const hooksDir =
|
|
35482
|
+
const hooksDir = path50.join(kit.path, "hooks");
|
|
35369
35483
|
const missingSet = new Set(kit.components.hooks.missing);
|
|
35370
35484
|
for (const name of kit.components.hooks.declared) {
|
|
35371
35485
|
if (missingSet.has(name)) continue;
|
|
35372
|
-
const declarationPath =
|
|
35373
|
-
if (!
|
|
35486
|
+
const declarationPath = path50.join(hooksDir, `${name}.md`);
|
|
35487
|
+
if (!fs49.existsSync(declarationPath)) continue;
|
|
35374
35488
|
let data;
|
|
35375
35489
|
try {
|
|
35376
35490
|
({ data } = parseMarkdownFrontmatter(declarationPath));
|
|
@@ -35380,8 +35494,8 @@ function checkHookScriptsExist(kit) {
|
|
|
35380
35494
|
if (typeof data.command === "string" && data.command.trim().length > 0) {
|
|
35381
35495
|
continue;
|
|
35382
35496
|
}
|
|
35383
|
-
const scriptPath =
|
|
35384
|
-
if (!
|
|
35497
|
+
const scriptPath = path50.join(hooksDir, "scripts", `${name}.ts`);
|
|
35498
|
+
if (!fs49.existsSync(scriptPath)) {
|
|
35385
35499
|
violations.push({
|
|
35386
35500
|
code: "hook-script-missing",
|
|
35387
35501
|
location: `hooks/scripts/${name}.ts`,
|
|
@@ -35394,10 +35508,10 @@ function checkHookScriptsExist(kit) {
|
|
|
35394
35508
|
function checkOptionalSourceDocuments(kit) {
|
|
35395
35509
|
const violations = [];
|
|
35396
35510
|
for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
|
|
35397
|
-
const filePath =
|
|
35398
|
-
if (!
|
|
35511
|
+
const filePath = path50.join(kit.path, name);
|
|
35512
|
+
if (!fs49.existsSync(filePath)) continue;
|
|
35399
35513
|
try {
|
|
35400
|
-
const parsed = JSON.parse(
|
|
35514
|
+
const parsed = JSON.parse(fs49.readFileSync(filePath, "utf8"));
|
|
35401
35515
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
35402
35516
|
violations.push({
|
|
35403
35517
|
code: "optional-source-malformed",
|
|
@@ -35419,10 +35533,10 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35419
35533
|
const notices = [];
|
|
35420
35534
|
const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
|
|
35421
35535
|
for (const name of kit.components.skills.declared) {
|
|
35422
|
-
const skillDir =
|
|
35536
|
+
const skillDir = path50.join(kit.path, "skills", name);
|
|
35423
35537
|
let entries;
|
|
35424
35538
|
try {
|
|
35425
|
-
entries =
|
|
35539
|
+
entries = fs49.readdirSync(skillDir, { withFileTypes: true });
|
|
35426
35540
|
} catch {
|
|
35427
35541
|
continue;
|
|
35428
35542
|
}
|
|
@@ -35440,7 +35554,7 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35440
35554
|
return notices;
|
|
35441
35555
|
}
|
|
35442
35556
|
function checkHooksSourceForm(kit) {
|
|
35443
|
-
const hooksDir =
|
|
35557
|
+
const hooksDir = path50.join(kit.path, "hooks");
|
|
35444
35558
|
const message = describeHooksSourceConflict(
|
|
35445
35559
|
hooksDir,
|
|
35446
35560
|
kit.components.hooks.declared
|
|
@@ -35452,12 +35566,12 @@ function checkHooksSourceForm(kit) {
|
|
|
35452
35566
|
} : null;
|
|
35453
35567
|
}
|
|
35454
35568
|
function checkHookDeclarations(kit) {
|
|
35455
|
-
const hooksDir =
|
|
35569
|
+
const hooksDir = path50.join(kit.path, "hooks");
|
|
35456
35570
|
return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
|
|
35457
35571
|
(r) => ({
|
|
35458
35572
|
code: "hook-declaration-invalid",
|
|
35459
|
-
location: `hooks/${
|
|
35460
|
-
message: `hooks: '${
|
|
35573
|
+
location: `hooks/${path50.basename(r.file)}`,
|
|
35574
|
+
message: `hooks: '${path50.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.`
|
|
35461
35575
|
})
|
|
35462
35576
|
);
|
|
35463
35577
|
}
|
|
@@ -35477,11 +35591,11 @@ function checkKitFormatSupported(kit) {
|
|
|
35477
35591
|
function checkEntrypointExists(kit) {
|
|
35478
35592
|
const declared = kit.entrypoint;
|
|
35479
35593
|
const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
|
|
35480
|
-
const entrypointPath =
|
|
35481
|
-
if (
|
|
35594
|
+
const entrypointPath = path50.join(kit.path, entrypoint);
|
|
35595
|
+
if (fs49.existsSync(entrypointPath)) {
|
|
35482
35596
|
return null;
|
|
35483
35597
|
}
|
|
35484
|
-
const legacyPresent = declared === void 0 &&
|
|
35598
|
+
const legacyPresent = declared === void 0 && fs49.existsSync(path50.join(kit.path, LEGACY_ENTRYPOINT));
|
|
35485
35599
|
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.`;
|
|
35486
35600
|
return {
|
|
35487
35601
|
code: "entrypoint-missing",
|
|
@@ -35540,9 +35654,9 @@ function checkComponentFrontmatter(kit) {
|
|
|
35540
35654
|
const missingSet = new Set(kit.components[cat].missing);
|
|
35541
35655
|
for (const name of kit.components[cat].declared) {
|
|
35542
35656
|
if (missingSet.has(name)) continue;
|
|
35543
|
-
const filePath = cat === "skills" ?
|
|
35544
|
-
if (!
|
|
35545
|
-
const relPath =
|
|
35657
|
+
const filePath = cat === "skills" ? path50.join(kit.path, cat, name, "SKILL.md") : path50.join(kit.path, cat, `${name}.md`);
|
|
35658
|
+
if (!fs49.existsSync(filePath)) continue;
|
|
35659
|
+
const relPath = path50.relative(kit.path, filePath);
|
|
35546
35660
|
try {
|
|
35547
35661
|
const { data } = parseMarkdownFrontmatter(filePath);
|
|
35548
35662
|
for (const field of requiredFields) {
|
|
@@ -35567,10 +35681,10 @@ function checkComponentFrontmatter(kit) {
|
|
|
35567
35681
|
}
|
|
35568
35682
|
function checkReservedRootNames(kit) {
|
|
35569
35683
|
const violations = [];
|
|
35570
|
-
if (!
|
|
35684
|
+
if (!fs49.existsSync(kit.path) || !fs49.statSync(kit.path).isDirectory()) {
|
|
35571
35685
|
return violations;
|
|
35572
35686
|
}
|
|
35573
|
-
const entries =
|
|
35687
|
+
const entries = fs49.readdirSync(kit.path, { withFileTypes: true });
|
|
35574
35688
|
for (const entry of entries) {
|
|
35575
35689
|
if (RESERVED_ROOT_NAMES.includes(entry.name)) {
|
|
35576
35690
|
violations.push({
|
|
@@ -35587,8 +35701,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35587
35701
|
const missingSet = new Set(kit.components.commands.missing);
|
|
35588
35702
|
for (const name of kit.components.commands.declared) {
|
|
35589
35703
|
if (missingSet.has(name)) continue;
|
|
35590
|
-
const filePath =
|
|
35591
|
-
if (!
|
|
35704
|
+
const filePath = path50.join(kit.path, "commands", `${name}.md`);
|
|
35705
|
+
if (!fs49.existsSync(filePath)) continue;
|
|
35592
35706
|
let data;
|
|
35593
35707
|
try {
|
|
35594
35708
|
({ data } = parseMarkdownFrontmatter(filePath));
|
|
@@ -35601,7 +35715,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35601
35715
|
if (!barred) {
|
|
35602
35716
|
violations.push({
|
|
35603
35717
|
code: "command-human-only-model-invocable",
|
|
35604
|
-
location:
|
|
35718
|
+
location: path50.relative(kit.path, filePath),
|
|
35605
35719
|
message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
|
|
35606
35720
|
});
|
|
35607
35721
|
}
|
|
@@ -35610,8 +35724,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35610
35724
|
}
|
|
35611
35725
|
|
|
35612
35726
|
// src/commands/verify.ts
|
|
35613
|
-
import
|
|
35614
|
-
import
|
|
35727
|
+
import fs50 from "fs";
|
|
35728
|
+
import path51 from "path";
|
|
35615
35729
|
function runVerifyCommand(options, logger) {
|
|
35616
35730
|
if (options.target && !isKnownTarget(options.target)) {
|
|
35617
35731
|
throwUnrecognizedTarget(options.target);
|
|
@@ -35792,8 +35906,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
|
|
|
35792
35906
|
if (!slotPath) {
|
|
35793
35907
|
continue;
|
|
35794
35908
|
}
|
|
35795
|
-
const fullPath = subPath ?
|
|
35796
|
-
if (!
|
|
35909
|
+
const fullPath = subPath ? path51.join(slotPath, subPath) : slotPath;
|
|
35910
|
+
if (!fs50.existsSync(fullPath)) {
|
|
35797
35911
|
failures.push(
|
|
35798
35912
|
`claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
|
|
35799
35913
|
);
|