@alessandroraffa/tangyr 4.1.0 → 4.2.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 +940 -639
- package/mappings/platform-paths.yaml +9 -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 path53 = __require("path");
|
|
1376
|
+
var fs52 = __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 (fs52.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 = path53.resolve(baseDir, baseName);
|
|
2389
|
+
if (fs52.existsSync(localBin)) return localBin;
|
|
2390
|
+
if (sourceExt.includes(path53.extname(baseName))) return void 0;
|
|
2391
2391
|
const foundExt = sourceExt.find(
|
|
2392
|
-
(ext) =>
|
|
2392
|
+
(ext) => fs52.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 = fs52.realpathSync(this._scriptPath);
|
|
2405
2405
|
} catch {
|
|
2406
2406
|
resolvedScriptPath = this._scriptPath;
|
|
2407
2407
|
}
|
|
2408
|
-
executableDir =
|
|
2409
|
-
|
|
2408
|
+
executableDir = path53.resolve(
|
|
2409
|
+
path53.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 = path53.basename(
|
|
2417
2417
|
this._scriptPath,
|
|
2418
|
-
|
|
2418
|
+
path53.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(path53.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 = path53.basename(filename, path53.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(path54) {
|
|
3359
|
+
if (path54 === void 0) return this._executableDir;
|
|
3360
|
+
this._executableDir = path54;
|
|
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, path53) {
|
|
3717
|
+
const ctrl = callVisitor(key, node, visitor, path53);
|
|
3718
3718
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3719
|
-
replaceNode(key,
|
|
3720
|
-
return visit_(key, ctrl, visitor,
|
|
3719
|
+
replaceNode(key, path53, ctrl);
|
|
3720
|
+
return visit_(key, ctrl, visitor, path53);
|
|
3721
3721
|
}
|
|
3722
3722
|
if (typeof ctrl !== "symbol") {
|
|
3723
3723
|
if (identity.isCollection(node)) {
|
|
3724
|
-
|
|
3724
|
+
path53 = Object.freeze(path53.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, path53);
|
|
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
|
+
path53 = Object.freeze(path53.concat(node));
|
|
3738
|
+
const ck = visit_("key", node.key, visitor, path53);
|
|
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, path53);
|
|
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, path53) {
|
|
3765
|
+
const ctrl = await callVisitor(key, node, visitor, path53);
|
|
3766
3766
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3767
|
-
replaceNode(key,
|
|
3768
|
-
return visitAsync_(key, ctrl, visitor,
|
|
3767
|
+
replaceNode(key, path53, ctrl);
|
|
3768
|
+
return visitAsync_(key, ctrl, visitor, path53);
|
|
3769
3769
|
}
|
|
3770
3770
|
if (typeof ctrl !== "symbol") {
|
|
3771
3771
|
if (identity.isCollection(node)) {
|
|
3772
|
-
|
|
3772
|
+
path53 = Object.freeze(path53.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, path53);
|
|
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
|
+
path53 = Object.freeze(path53.concat(node));
|
|
3786
|
+
const ck = await visitAsync_("key", node.key, visitor, path53);
|
|
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, path53);
|
|
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, path53) {
|
|
3819
3819
|
if (typeof visitor === "function")
|
|
3820
|
-
return visitor(key, node,
|
|
3820
|
+
return visitor(key, node, path53);
|
|
3821
3821
|
if (identity.isMap(node))
|
|
3822
|
-
return visitor.Map?.(key, node,
|
|
3822
|
+
return visitor.Map?.(key, node, path53);
|
|
3823
3823
|
if (identity.isSeq(node))
|
|
3824
|
-
return visitor.Seq?.(key, node,
|
|
3824
|
+
return visitor.Seq?.(key, node, path53);
|
|
3825
3825
|
if (identity.isPair(node))
|
|
3826
|
-
return visitor.Pair?.(key, node,
|
|
3826
|
+
return visitor.Pair?.(key, node, path53);
|
|
3827
3827
|
if (identity.isScalar(node))
|
|
3828
|
-
return visitor.Scalar?.(key, node,
|
|
3828
|
+
return visitor.Scalar?.(key, node, path53);
|
|
3829
3829
|
if (identity.isAlias(node))
|
|
3830
|
-
return visitor.Alias?.(key, node,
|
|
3830
|
+
return visitor.Alias?.(key, node, path53);
|
|
3831
3831
|
return void 0;
|
|
3832
3832
|
}
|
|
3833
|
-
function replaceNode(key,
|
|
3834
|
-
const parent =
|
|
3833
|
+
function replaceNode(key, path53, node) {
|
|
3834
|
+
const parent = path53[path53.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, path53, value) {
|
|
4443
4443
|
let v2 = value;
|
|
4444
|
-
for (let i =
|
|
4445
|
-
const k2 =
|
|
4444
|
+
for (let i = path53.length - 1; i >= 0; --i) {
|
|
4445
|
+
const k2 = path53[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 = (path53) => path53 == null || typeof path53 === "object" && !!path53[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(path53, value) {
|
|
4495
|
+
if (isEmptyPath(path53))
|
|
4496
4496
|
this.add(value);
|
|
4497
4497
|
else {
|
|
4498
|
-
const [key, ...rest] =
|
|
4498
|
+
const [key, ...rest] = path53;
|
|
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(path53) {
|
|
4513
|
+
const [key, ...rest] = path53;
|
|
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(path53, keepScalar) {
|
|
4528
|
+
const [key, ...rest] = path53;
|
|
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(path53) {
|
|
4547
|
+
const [key, ...rest] = path53;
|
|
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(path53, value) {
|
|
4558
|
+
const [key, ...rest] = path53;
|
|
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(path53, value) {
|
|
7071
7071
|
if (assertCollection(this.contents))
|
|
7072
|
-
this.contents.addIn(
|
|
7072
|
+
this.contents.addIn(path53, 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(path53) {
|
|
7148
|
+
if (Collection.isEmptyPath(path53)) {
|
|
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(path53) : 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(path53, keepScalar) {
|
|
7170
|
+
if (Collection.isEmptyPath(path53))
|
|
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(path53, 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(path53) {
|
|
7184
|
+
if (Collection.isEmptyPath(path53))
|
|
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(path53) : 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(path53, value) {
|
|
7204
|
+
if (Collection.isEmptyPath(path53)) {
|
|
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(path53), value);
|
|
7208
7208
|
} else if (assertCollection(this.contents)) {
|
|
7209
|
-
this.contents.setIn(
|
|
7209
|
+
this.contents.setIn(path53, 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, path53) => {
|
|
9167
9167
|
let item = cst;
|
|
9168
|
-
for (const [field, index] of
|
|
9168
|
+
for (const [field, index] of path53) {
|
|
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, path53) => {
|
|
9178
|
+
const parent = visit.itemAtPath(cst, path53.slice(0, -1));
|
|
9179
|
+
const field = path53[path53.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(path53, item, visitor) {
|
|
9186
|
+
let ctrl = visitor(item, path53);
|
|
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(path53.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, path53);
|
|
9205
9205
|
}
|
|
9206
9206
|
}
|
|
9207
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
9207
|
+
return typeof ctrl === "function" ? ctrl(item, path53) : 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 fs52 = this.flowScalar(this.type);
|
|
10493
10493
|
if (atNextItem || it2.value) {
|
|
10494
|
-
map.items.push({ start, key:
|
|
10494
|
+
map.items.push({ start, key: fs52, sep: [] });
|
|
10495
10495
|
this.onKeyLine = true;
|
|
10496
10496
|
} else if (it2.sep) {
|
|
10497
|
-
this.stack.push(
|
|
10497
|
+
this.stack.push(fs52);
|
|
10498
10498
|
} else {
|
|
10499
|
-
Object.assign(it2, { key:
|
|
10499
|
+
Object.assign(it2, { key: fs52, 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 fs52 = this.flowScalar(this.type);
|
|
10628
10628
|
if (!it2 || it2.value)
|
|
10629
|
-
fc.items.push({ start: [], key:
|
|
10629
|
+
fc.items.push({ start: [], key: fs52, sep: [] });
|
|
10630
10630
|
else if (it2.sep)
|
|
10631
|
-
this.stack.push(
|
|
10631
|
+
this.stack.push(fs52);
|
|
10632
10632
|
else
|
|
10633
|
-
Object.assign(it2, { key:
|
|
10633
|
+
Object.assign(it2, { key: fs52, sep: [] });
|
|
10634
10634
|
return;
|
|
10635
10635
|
}
|
|
10636
10636
|
case "flow-map-end":
|
|
@@ -21991,7 +21991,7 @@ function reportHooksSourceConflict(report, targets, hooksDir, hookNames) {
|
|
|
21991
21991
|
|
|
21992
21992
|
// src/adapters/hook-scripts-bridge.ts
|
|
21993
21993
|
import fs25 from "fs";
|
|
21994
|
-
import
|
|
21994
|
+
import path23 from "path";
|
|
21995
21995
|
|
|
21996
21996
|
// src/utils/fs.ts
|
|
21997
21997
|
import fs23 from "fs";
|
|
@@ -22121,8 +22121,62 @@ function compareArtifactState(recorded, artifactPath) {
|
|
|
22121
22121
|
return current === recorded ? "current" : "modified";
|
|
22122
22122
|
}
|
|
22123
22123
|
|
|
22124
|
+
// src/core/shared-artifacts.ts
|
|
22125
|
+
import path22 from "path";
|
|
22126
|
+
var SHARED_NAMESPACE = "shared";
|
|
22127
|
+
var SHARED_INSTRUCTIONS_KEY = `${SHARED_NAMESPACE}/AGENTS.md`;
|
|
22128
|
+
var SHARED_INSTRUCTIONS_FILE = "AGENTS.md";
|
|
22129
|
+
var SHARED_HOOK_SCRIPTS_KEY = `${SHARED_NAMESPACE}/hook_scripts`;
|
|
22130
|
+
function sharedArtifactKey(destination, scope, projectRoot) {
|
|
22131
|
+
if (scope !== "project") {
|
|
22132
|
+
return null;
|
|
22133
|
+
}
|
|
22134
|
+
const root = projectRoot ?? process.cwd();
|
|
22135
|
+
const shared = path22.resolve(root, SHARED_INSTRUCTIONS_FILE);
|
|
22136
|
+
return path22.resolve(destination) === shared ? SHARED_INSTRUCTIONS_KEY : null;
|
|
22137
|
+
}
|
|
22138
|
+
function resolveSharedArtifactKey(key, scope, projectRoot) {
|
|
22139
|
+
if (key !== SHARED_INSTRUCTIONS_KEY || scope !== "project") {
|
|
22140
|
+
return null;
|
|
22141
|
+
}
|
|
22142
|
+
return path22.join(projectRoot ?? process.cwd(), SHARED_INSTRUCTIONS_FILE);
|
|
22143
|
+
}
|
|
22144
|
+
var SHARED_SKILLS_PREFIX = `${SHARED_NAMESPACE}/skills`;
|
|
22145
|
+
function sharedKeyForDestination(destination, scope, projectRoot, platformPaths) {
|
|
22146
|
+
const instructions = sharedArtifactKey(destination, scope, projectRoot);
|
|
22147
|
+
if (instructions) {
|
|
22148
|
+
return instructions;
|
|
22149
|
+
}
|
|
22150
|
+
const resolved = path22.resolve(destination);
|
|
22151
|
+
let profiles;
|
|
22152
|
+
try {
|
|
22153
|
+
profiles = resolveTargetPaths({
|
|
22154
|
+
scope,
|
|
22155
|
+
projectRoot,
|
|
22156
|
+
mappings: platformPaths
|
|
22157
|
+
});
|
|
22158
|
+
} catch {
|
|
22159
|
+
return null;
|
|
22160
|
+
}
|
|
22161
|
+
if (resolved === path22.resolve(profiles.codex.hook_scripts)) {
|
|
22162
|
+
return SHARED_HOOK_SCRIPTS_KEY;
|
|
22163
|
+
}
|
|
22164
|
+
const skillsRoot = path22.resolve(profiles.opencode.skills_shared);
|
|
22165
|
+
if (resolved.startsWith(`${skillsRoot}${path22.sep}`)) {
|
|
22166
|
+
const inside = path22.relative(skillsRoot, resolved).split(path22.sep).join("/");
|
|
22167
|
+
return `${SHARED_SKILLS_PREFIX}/${inside}`;
|
|
22168
|
+
}
|
|
22169
|
+
return null;
|
|
22170
|
+
}
|
|
22171
|
+
function resolveSharedSkillsKey(key, sharedSkillsRoot) {
|
|
22172
|
+
if (!key.startsWith(`${SHARED_SKILLS_PREFIX}/`) || !sharedSkillsRoot) {
|
|
22173
|
+
return null;
|
|
22174
|
+
}
|
|
22175
|
+
const inside = key.slice(SHARED_SKILLS_PREFIX.length + 1);
|
|
22176
|
+
return path22.join(sharedSkillsRoot, ...inside.split("/"));
|
|
22177
|
+
}
|
|
22178
|
+
|
|
22124
22179
|
// src/adapters/hook-scripts-bridge.ts
|
|
22125
|
-
var SHARED_HOOK_SCRIPTS_KEY = "shared/hook_scripts";
|
|
22126
22180
|
function syncHookScriptsBridge(args) {
|
|
22127
22181
|
const { source, destination, config, sourceRoot, options, logger } = args;
|
|
22128
22182
|
if (!fs25.existsSync(source)) {
|
|
@@ -22147,7 +22201,7 @@ function syncHookScriptsBridge(args) {
|
|
|
22147
22201
|
} else if (artifactClass === "managed-symlink") {
|
|
22148
22202
|
fs25.unlinkSync(destination);
|
|
22149
22203
|
}
|
|
22150
|
-
ensureDir(
|
|
22204
|
+
ensureDir(path23.dirname(destination));
|
|
22151
22205
|
createRelativeSymlink(source, destination, "dir");
|
|
22152
22206
|
if (args.manifest) {
|
|
22153
22207
|
const state = describeArtifactState(destination);
|
|
@@ -22176,26 +22230,6 @@ function isSymlinkTo(linkPath, source) {
|
|
|
22176
22230
|
}
|
|
22177
22231
|
}
|
|
22178
22232
|
|
|
22179
|
-
// src/core/shared-artifacts.ts
|
|
22180
|
-
import path23 from "path";
|
|
22181
|
-
var SHARED_NAMESPACE = "shared";
|
|
22182
|
-
var SHARED_INSTRUCTIONS_KEY = `${SHARED_NAMESPACE}/AGENTS.md`;
|
|
22183
|
-
var SHARED_INSTRUCTIONS_FILE = "AGENTS.md";
|
|
22184
|
-
function sharedArtifactKey(destination, scope, projectRoot) {
|
|
22185
|
-
if (scope !== "project") {
|
|
22186
|
-
return null;
|
|
22187
|
-
}
|
|
22188
|
-
const root = projectRoot ?? process.cwd();
|
|
22189
|
-
const shared = path23.resolve(root, SHARED_INSTRUCTIONS_FILE);
|
|
22190
|
-
return path23.resolve(destination) === shared ? SHARED_INSTRUCTIONS_KEY : null;
|
|
22191
|
-
}
|
|
22192
|
-
function resolveSharedArtifactKey(key, scope, projectRoot) {
|
|
22193
|
-
if (key !== SHARED_INSTRUCTIONS_KEY || scope !== "project") {
|
|
22194
|
-
return null;
|
|
22195
|
-
}
|
|
22196
|
-
return path23.join(projectRoot ?? process.cwd(), SHARED_INSTRUCTIONS_FILE);
|
|
22197
|
-
}
|
|
22198
|
-
|
|
22199
22233
|
// src/core/remove.ts
|
|
22200
22234
|
import fs26 from "fs";
|
|
22201
22235
|
function removeManagedPath(managedPath) {
|
|
@@ -22316,6 +22350,7 @@ async function runUninstallCommand(options, logger) {
|
|
|
22316
22350
|
const claudeRoots = scope === "global" && selectedTools.has("claude-code") ? resolveClaudeRootsForUninstall(manifest, runtime) : [];
|
|
22317
22351
|
let removedCount = 0;
|
|
22318
22352
|
const removedParentDirs = /* @__PURE__ */ new Set();
|
|
22353
|
+
const keptSurfaces = [];
|
|
22319
22354
|
for (const file of useManifestPathRemoval ? manifestArtifacts : []) {
|
|
22320
22355
|
if (isMergeSurfaceKey(file.relativePath)) {
|
|
22321
22356
|
const surfacePath = file.path ?? resolveManifestKeyToPath(
|
|
@@ -22327,6 +22362,9 @@ async function runUninstallCommand(options, logger) {
|
|
|
22327
22362
|
if (surfacePath && stripTangyrFromMergeSurface(surfacePath, logger)) {
|
|
22328
22363
|
removedParentDirs.add(path24.dirname(surfacePath));
|
|
22329
22364
|
removedCount++;
|
|
22365
|
+
if (fs27.existsSync(surfacePath)) {
|
|
22366
|
+
keptSurfaces.push(surfacePath);
|
|
22367
|
+
}
|
|
22330
22368
|
} else {
|
|
22331
22369
|
logger.verbose(
|
|
22332
22370
|
` left in place (merge surface, nothing of ours in it): ${surfacePath ?? file.relativePath}`
|
|
@@ -22429,10 +22467,6 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
|
|
|
22429
22467
|
logger.verbose(` removed manifest: ${manifestPath}`);
|
|
22430
22468
|
}
|
|
22431
22469
|
pruneEmptyDirs(path24.join(scopePath, "backups"), logger);
|
|
22432
|
-
const pruneBoundary = path24.dirname(scopePath);
|
|
22433
|
-
for (const dir of removedParentDirs) {
|
|
22434
|
-
pruneEmptyAncestors(dir, pruneBoundary, logger);
|
|
22435
|
-
}
|
|
22436
22470
|
try {
|
|
22437
22471
|
const remaining = fs27.readdirSync(scopePath);
|
|
22438
22472
|
if (remaining.length === 0) {
|
|
@@ -22455,6 +22489,22 @@ ${String(kept.length)} later backup(s) were NOT restored: the earliest copy of e
|
|
|
22455
22489
|
} else {
|
|
22456
22490
|
logger.verbose(" no manifest to update after partial residue cleanup");
|
|
22457
22491
|
}
|
|
22492
|
+
const pruneBoundary = path24.dirname(scopePath);
|
|
22493
|
+
for (const dir of removedParentDirs) {
|
|
22494
|
+
pruneEmptyAncestors(dir, pruneBoundary, logger);
|
|
22495
|
+
}
|
|
22496
|
+
if (keptSurfaces.length > 0) {
|
|
22497
|
+
logger.warn(
|
|
22498
|
+
`
|
|
22499
|
+
${String(keptSurfaces.length)} shared file(s) kept, with Tangyr's own block removed from each:`
|
|
22500
|
+
);
|
|
22501
|
+
for (const surface of keptSurfaces) {
|
|
22502
|
+
logger.warn(` ${surface}`);
|
|
22503
|
+
}
|
|
22504
|
+
logger.warn(
|
|
22505
|
+
" What remains in them was not written with a marker of ours, so it is left rather than guessed at. Delete what you no longer want."
|
|
22506
|
+
);
|
|
22507
|
+
}
|
|
22458
22508
|
logger.info(`
|
|
22459
22509
|
Uninstallation complete: ${removedCount} file(s) removed.`);
|
|
22460
22510
|
}
|
|
@@ -22470,6 +22520,13 @@ function resolveManifestKeyToPath(key, scope, runtime, projectRootOverride) {
|
|
|
22470
22520
|
if (component === "hook_scripts") {
|
|
22471
22521
|
return resolveSharedHookScriptsPath(runtime, scope, projectRoot);
|
|
22472
22522
|
}
|
|
22523
|
+
const sharedSkill = resolveSharedSkillsKey(
|
|
22524
|
+
key,
|
|
22525
|
+
resolveSharedSkillsPath(runtime, scope, projectRoot)
|
|
22526
|
+
);
|
|
22527
|
+
if (sharedSkill) {
|
|
22528
|
+
return sharedSkill;
|
|
22529
|
+
}
|
|
22473
22530
|
return resolveSharedArtifactKey(key, scope, projectRoot);
|
|
22474
22531
|
}
|
|
22475
22532
|
if (tool === "claude-code") {
|
|
@@ -23867,6 +23924,27 @@ function resolveSharedHookScriptsPath(runtime, scope, projectRoot) {
|
|
|
23867
23924
|
}
|
|
23868
23925
|
return resolveTargetPath("~/.agents/hooks");
|
|
23869
23926
|
}
|
|
23927
|
+
function resolveSharedSkillsPath(runtime, scope, projectRoot) {
|
|
23928
|
+
if (runtime) {
|
|
23929
|
+
try {
|
|
23930
|
+
const mappings = loadMappings(
|
|
23931
|
+
runtime.sourceRoot,
|
|
23932
|
+
runtime.config,
|
|
23933
|
+
runtime.configDir
|
|
23934
|
+
);
|
|
23935
|
+
return resolveTargetPaths({
|
|
23936
|
+
scope,
|
|
23937
|
+
projectRoot,
|
|
23938
|
+
mappings: mappings.platformPaths
|
|
23939
|
+
}).opencode.skills_shared;
|
|
23940
|
+
} catch {
|
|
23941
|
+
}
|
|
23942
|
+
}
|
|
23943
|
+
if (scope === "project") {
|
|
23944
|
+
return path24.join(projectRoot ?? process.cwd(), ".agents", "skills");
|
|
23945
|
+
}
|
|
23946
|
+
return resolveTargetPath("~/.agents/skills");
|
|
23947
|
+
}
|
|
23870
23948
|
function resolveOpenCodePaths(runtime, scope = "global", projectRoot) {
|
|
23871
23949
|
if (runtime) {
|
|
23872
23950
|
try {
|
|
@@ -25223,8 +25301,8 @@ function toConflictPolicy2(value) {
|
|
|
25223
25301
|
}
|
|
25224
25302
|
|
|
25225
25303
|
// src/commands/install.ts
|
|
25226
|
-
import
|
|
25227
|
-
import
|
|
25304
|
+
import fs46 from "fs";
|
|
25305
|
+
import path46 from "path";
|
|
25228
25306
|
|
|
25229
25307
|
// src/core/channel-state.ts
|
|
25230
25308
|
import fs32 from "fs";
|
|
@@ -26171,12 +26249,15 @@ function findContestedInstructions(instructionsByTarget) {
|
|
|
26171
26249
|
}
|
|
26172
26250
|
return contested;
|
|
26173
26251
|
}
|
|
26174
|
-
function reportContestedInstructions(instructionsByTarget, kitDeclaresRules, logger) {
|
|
26252
|
+
function reportContestedInstructions(instructionsByTarget, kitDeclaresRules, logger, missingByTarget) {
|
|
26175
26253
|
if (!kitDeclaresRules) {
|
|
26176
26254
|
return;
|
|
26177
26255
|
}
|
|
26178
26256
|
for (const contested of findContestedInstructions(instructionsByTarget)) {
|
|
26179
|
-
|
|
26257
|
+
const losers = missingByTarget ? contested.losers.filter(
|
|
26258
|
+
(target) => (missingByTarget.get(target)?.length ?? 0) > 0
|
|
26259
|
+
) : contested.losers;
|
|
26260
|
+
if (losers.length === 0) {
|
|
26180
26261
|
continue;
|
|
26181
26262
|
}
|
|
26182
26263
|
logger.warn(
|
|
@@ -26186,7 +26267,7 @@ ${contested.destination} is the instructions file for ${contested.claimants.join
|
|
|
26186
26267
|
if (contested.survivor) {
|
|
26187
26268
|
logger.warn(` The content on disk is ${contested.survivor}'s.`);
|
|
26188
26269
|
}
|
|
26189
|
-
for (const target of
|
|
26270
|
+
for (const target of losers) {
|
|
26190
26271
|
logger.warn(
|
|
26191
26272
|
` ${target} does NOT get its rules: ${FOLDS_RULES_INTO_INSTRUCTIONS[target]}, and that content is overwritten here.`
|
|
26192
26273
|
);
|
|
@@ -26209,12 +26290,141 @@ function instructionsByActiveTarget(tools, scope, projectRoot, mappings) {
|
|
|
26209
26290
|
byTarget.set(tool, instructions);
|
|
26210
26291
|
}
|
|
26211
26292
|
}
|
|
26293
|
+
if (scope === "project" && projectRoot && tools.includes("copilot")) {
|
|
26294
|
+
byTarget.set("copilot", path31.join(projectRoot, "AGENTS.md"));
|
|
26295
|
+
}
|
|
26212
26296
|
return byTarget;
|
|
26213
26297
|
}
|
|
26214
26298
|
|
|
26299
|
+
// src/core/rules-coverage.ts
|
|
26300
|
+
import fs35 from "fs";
|
|
26301
|
+
import path32 from "path";
|
|
26302
|
+
function readingSurfaces(profile) {
|
|
26303
|
+
const record = profile;
|
|
26304
|
+
return {
|
|
26305
|
+
slot: typeof record?.rules === "string" ? record.rules : null,
|
|
26306
|
+
instructions: typeof record?.instructions === "string" ? record.instructions : null
|
|
26307
|
+
};
|
|
26308
|
+
}
|
|
26309
|
+
function inRulesSlot(slot, rule) {
|
|
26310
|
+
let entries;
|
|
26311
|
+
try {
|
|
26312
|
+
entries = fs35.readdirSync(slot);
|
|
26313
|
+
} catch {
|
|
26314
|
+
return false;
|
|
26315
|
+
}
|
|
26316
|
+
return entries.some(
|
|
26317
|
+
(entry) => entry === rule || entry.startsWith(`${rule}.`)
|
|
26318
|
+
);
|
|
26319
|
+
}
|
|
26320
|
+
function inInstructions(instructions, rule) {
|
|
26321
|
+
let content;
|
|
26322
|
+
try {
|
|
26323
|
+
content = fs35.readFileSync(instructions, "utf8");
|
|
26324
|
+
} catch {
|
|
26325
|
+
return false;
|
|
26326
|
+
}
|
|
26327
|
+
return content.split("\n").some((line) => line.trim() === `## ${rule}`);
|
|
26328
|
+
}
|
|
26329
|
+
function recordedRulesLoss(lossReport, target) {
|
|
26330
|
+
const entries = lossReport.targets[target]?.rules ?? [];
|
|
26331
|
+
for (const artifact of entries) {
|
|
26332
|
+
for (const field of artifact.fields) {
|
|
26333
|
+
if (field.detail.length > 0) {
|
|
26334
|
+
return field.detail;
|
|
26335
|
+
}
|
|
26336
|
+
}
|
|
26337
|
+
}
|
|
26338
|
+
return null;
|
|
26339
|
+
}
|
|
26340
|
+
function measureRulesCoverage(tools, declaredRules, scope, projectRoot, mappings, lossReport, instructionsByTarget) {
|
|
26341
|
+
const resolved = resolveTargetPaths({
|
|
26342
|
+
scope,
|
|
26343
|
+
projectRoot,
|
|
26344
|
+
mappings: mappings.platformPaths
|
|
26345
|
+
});
|
|
26346
|
+
const contestedByPath = new Map(
|
|
26347
|
+
findContestedInstructions(instructionsByTarget).map((contested) => [
|
|
26348
|
+
contested.destination,
|
|
26349
|
+
contested
|
|
26350
|
+
])
|
|
26351
|
+
);
|
|
26352
|
+
return tools.map((target) => {
|
|
26353
|
+
const surfaces = readingSurfaces(resolved[target]);
|
|
26354
|
+
const missing = declaredRules.filter((rule) => {
|
|
26355
|
+
if (surfaces.slot && inRulesSlot(surfaces.slot, rule)) {
|
|
26356
|
+
return false;
|
|
26357
|
+
}
|
|
26358
|
+
return !(surfaces.instructions && inInstructions(surfaces.instructions, rule));
|
|
26359
|
+
});
|
|
26360
|
+
return {
|
|
26361
|
+
target,
|
|
26362
|
+
missing,
|
|
26363
|
+
declared: declaredRules.length,
|
|
26364
|
+
reason: missing.length === 0 ? null : explain(target, surfaces, contestedByPath, lossReport, projectRoot)
|
|
26365
|
+
};
|
|
26366
|
+
});
|
|
26367
|
+
}
|
|
26368
|
+
function explain(target, surfaces, contestedByPath, lossReport, projectRoot) {
|
|
26369
|
+
if (surfaces.instructions) {
|
|
26370
|
+
const contested = contestedByPath.get(path32.resolve(surfaces.instructions));
|
|
26371
|
+
if (contested && contested.survivor !== null && contested.survivor !== target) {
|
|
26372
|
+
return `its rules are folded into ${display(surfaces.instructions, projectRoot)}, which ${contested.survivor} wrote last`;
|
|
26373
|
+
}
|
|
26374
|
+
}
|
|
26375
|
+
const recorded = recordedRulesLoss(lossReport, target);
|
|
26376
|
+
if (recorded) {
|
|
26377
|
+
return recorded;
|
|
26378
|
+
}
|
|
26379
|
+
if (!surfaces.slot) {
|
|
26380
|
+
return "it has no rules surface in this scope";
|
|
26381
|
+
}
|
|
26382
|
+
return `not in ${display(surfaces.slot, projectRoot)}, nor folded into the instructions file`;
|
|
26383
|
+
}
|
|
26384
|
+
function display(target, projectRoot) {
|
|
26385
|
+
if (!projectRoot) {
|
|
26386
|
+
return target;
|
|
26387
|
+
}
|
|
26388
|
+
const relative = path32.relative(projectRoot, target);
|
|
26389
|
+
return relative.startsWith("..") ? target : relative;
|
|
26390
|
+
}
|
|
26391
|
+
function reportRulesCoverage(coverage, logger) {
|
|
26392
|
+
if (coverage.length === 0 || coverage[0].declared === 0) {
|
|
26393
|
+
return;
|
|
26394
|
+
}
|
|
26395
|
+
const complete = coverage.every((entry) => entry.missing.length === 0);
|
|
26396
|
+
const say = complete ? (line) => {
|
|
26397
|
+
logger.verbose(line);
|
|
26398
|
+
} : (line) => {
|
|
26399
|
+
logger.warn(line);
|
|
26400
|
+
};
|
|
26401
|
+
const declared = coverage[0].declared;
|
|
26402
|
+
const width = Math.max(...coverage.map((entry) => entry.target.length));
|
|
26403
|
+
say(
|
|
26404
|
+
`
|
|
26405
|
+
Rules reaching each target (${String(declared)} declared, measured on disk):`
|
|
26406
|
+
);
|
|
26407
|
+
for (const entry of coverage) {
|
|
26408
|
+
const delivered = declared - entry.missing.length;
|
|
26409
|
+
const counts = `${String(delivered)}/${String(declared)}`;
|
|
26410
|
+
const head = ` ${entry.target.padEnd(width)} ${counts}`;
|
|
26411
|
+
if (entry.missing.length === 0) {
|
|
26412
|
+
say(head);
|
|
26413
|
+
continue;
|
|
26414
|
+
}
|
|
26415
|
+
say(`${head} missing: ${entry.missing.join(", ")}`);
|
|
26416
|
+
if (entry.reason) {
|
|
26417
|
+
say(` ${" ".repeat(width)} ${entry.reason}`);
|
|
26418
|
+
}
|
|
26419
|
+
}
|
|
26420
|
+
}
|
|
26421
|
+
function missingRulesByTarget(coverage) {
|
|
26422
|
+
return new Map(coverage.map((entry) => [entry.target, entry.missing]));
|
|
26423
|
+
}
|
|
26424
|
+
|
|
26215
26425
|
// src/adapters/claude-code.ts
|
|
26216
|
-
import
|
|
26217
|
-
import
|
|
26426
|
+
import fs38 from "fs";
|
|
26427
|
+
import path36 from "path";
|
|
26218
26428
|
|
|
26219
26429
|
// src/core/shim.ts
|
|
26220
26430
|
import crypto4 from "crypto";
|
|
@@ -26236,8 +26446,8 @@ ${SHIM_BODY}`;
|
|
|
26236
26446
|
}
|
|
26237
26447
|
|
|
26238
26448
|
// src/core/skills-slot.ts
|
|
26239
|
-
import
|
|
26240
|
-
import
|
|
26449
|
+
import fs36 from "fs";
|
|
26450
|
+
import path33 from "path";
|
|
26241
26451
|
function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
|
|
26242
26452
|
if (!isSymlinkPath(destination)) {
|
|
26243
26453
|
return false;
|
|
@@ -26250,7 +26460,7 @@ function isForeignSkillsSlotSymlink(destination, config, sourceRoot, source) {
|
|
|
26250
26460
|
}
|
|
26251
26461
|
function syncSkillsSlot(sync) {
|
|
26252
26462
|
const { source, destination, logger } = sync;
|
|
26253
|
-
if (!
|
|
26463
|
+
if (!fs36.existsSync(source)) {
|
|
26254
26464
|
return [
|
|
26255
26465
|
{
|
|
26256
26466
|
component: "skills",
|
|
@@ -26278,7 +26488,7 @@ function syncSkillsSlot(sync) {
|
|
|
26278
26488
|
if (isLegacyWholesaleSymlink) {
|
|
26279
26489
|
for (const name of foreignSkillNames(source, declaredNames)) {
|
|
26280
26490
|
logger.info(
|
|
26281
|
-
`[dry-run] skills: migrate foreign skill ${
|
|
26491
|
+
`[dry-run] skills: migrate foreign skill ${path33.join(source, name)} -> ${path33.join(destination, name)}`
|
|
26282
26492
|
);
|
|
26283
26493
|
}
|
|
26284
26494
|
logger.info(
|
|
@@ -26286,9 +26496,9 @@ function syncSkillsSlot(sync) {
|
|
|
26286
26496
|
);
|
|
26287
26497
|
}
|
|
26288
26498
|
for (const name of declaredNames ?? listSkillDirNames(source)) {
|
|
26289
|
-
const skillDestination =
|
|
26499
|
+
const skillDestination = path33.join(destination, name);
|
|
26290
26500
|
logger.info(
|
|
26291
|
-
`[dry-run] skills: symlink ${
|
|
26501
|
+
`[dry-run] skills: symlink ${path33.join(source, name)} -> ${skillDestination}`
|
|
26292
26502
|
);
|
|
26293
26503
|
outcomes2.push({
|
|
26294
26504
|
component: "skills",
|
|
@@ -26315,9 +26525,9 @@ function syncSkillsSlot(sync) {
|
|
|
26315
26525
|
}
|
|
26316
26526
|
function syncSingleSkill(sync, name) {
|
|
26317
26527
|
const { config, sourceRoot, source, destination } = sync;
|
|
26318
|
-
const skillSource =
|
|
26319
|
-
const skillDestination =
|
|
26320
|
-
if (!
|
|
26528
|
+
const skillSource = path33.join(source, name);
|
|
26529
|
+
const skillDestination = path33.join(destination, name);
|
|
26530
|
+
if (!fs36.existsSync(skillSource)) {
|
|
26321
26531
|
return {
|
|
26322
26532
|
component: "skills",
|
|
26323
26533
|
status: "skipped",
|
|
@@ -26333,29 +26543,29 @@ function syncSingleSkill(sync, name) {
|
|
|
26333
26543
|
};
|
|
26334
26544
|
}
|
|
26335
26545
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
|
|
26336
|
-
|
|
26546
|
+
fs36.unlinkSync(skillDestination);
|
|
26337
26547
|
} else if (artifactClass === "unmanaged-conflict" && !sync.onUnmanagedConflict(skillDestination)) {
|
|
26338
26548
|
return { component: "skills", status: "conflict", path: skillDestination };
|
|
26339
26549
|
} else if (artifactClass === "managed-symlink") {
|
|
26340
|
-
|
|
26550
|
+
fs36.unlinkSync(skillDestination);
|
|
26341
26551
|
}
|
|
26342
26552
|
createRelativeSymlink(skillSource, skillDestination, "dir");
|
|
26343
26553
|
return { component: "skills", status: "success", path: skillDestination };
|
|
26344
26554
|
}
|
|
26345
26555
|
function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
|
|
26346
26556
|
const foreignNames = foreignSkillNames(source, declaredNames);
|
|
26347
|
-
|
|
26557
|
+
fs36.unlinkSync(destination);
|
|
26348
26558
|
ensureDir(destination);
|
|
26349
26559
|
for (const name of foreignNames) {
|
|
26350
|
-
const from =
|
|
26351
|
-
const to =
|
|
26352
|
-
if (
|
|
26560
|
+
const from = path33.join(source, name);
|
|
26561
|
+
const to = path33.join(destination, name);
|
|
26562
|
+
if (fs36.existsSync(to)) {
|
|
26353
26563
|
logger.warn(
|
|
26354
26564
|
`skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
|
|
26355
26565
|
);
|
|
26356
26566
|
continue;
|
|
26357
26567
|
}
|
|
26358
|
-
|
|
26568
|
+
fs36.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
|
|
26359
26569
|
logger.warn(
|
|
26360
26570
|
`skills migration: '${name}' is present under the kit's skills/ but is not declared in its manifest. Copied ${from} -> ${to} so the harness can read it. The original is left in the kit deliberately: this command does not modify a kit. Remove ${from} yourself if it does not belong there, or declare it in tangyr-kit.yaml if it does.`
|
|
26361
26571
|
);
|
|
@@ -26369,44 +26579,44 @@ function foreignSkillNames(source, declaredNames) {
|
|
|
26369
26579
|
return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
|
|
26370
26580
|
}
|
|
26371
26581
|
function listSkillDirNames(dir) {
|
|
26372
|
-
if (!
|
|
26582
|
+
if (!fs36.existsSync(dir)) {
|
|
26373
26583
|
return [];
|
|
26374
26584
|
}
|
|
26375
|
-
return
|
|
26585
|
+
return fs36.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
26376
26586
|
}
|
|
26377
26587
|
function isSymlinkPath(filePath) {
|
|
26378
26588
|
try {
|
|
26379
|
-
return
|
|
26589
|
+
return fs36.lstatSync(filePath).isSymbolicLink();
|
|
26380
26590
|
} catch {
|
|
26381
26591
|
return false;
|
|
26382
26592
|
}
|
|
26383
26593
|
}
|
|
26384
26594
|
function isSymlinkTo2(linkPath, source) {
|
|
26385
26595
|
try {
|
|
26386
|
-
return
|
|
26596
|
+
return fs36.realpathSync(linkPath) === fs36.realpathSync(source);
|
|
26387
26597
|
} catch {
|
|
26388
26598
|
return false;
|
|
26389
26599
|
}
|
|
26390
26600
|
}
|
|
26391
26601
|
|
|
26392
26602
|
// src/core/hook-scripts.ts
|
|
26393
|
-
import
|
|
26603
|
+
import path34 from "path";
|
|
26394
26604
|
function hookScriptsDir(bridge, target, projectRoot) {
|
|
26395
26605
|
const globalBridge = resolveTargetPath("~/.agents/hooks");
|
|
26396
|
-
if (
|
|
26606
|
+
if (path34.resolve(bridge) === path34.resolve(globalBridge)) {
|
|
26397
26607
|
return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
|
|
26398
26608
|
}
|
|
26399
|
-
const relative =
|
|
26400
|
-
const insideProject = !relative.startsWith("..") && !
|
|
26609
|
+
const relative = path34.relative(projectRoot ?? process.cwd(), bridge);
|
|
26610
|
+
const insideProject = !relative.startsWith("..") && !path34.isAbsolute(relative) && relative !== "";
|
|
26401
26611
|
const variable = PROJECT_DIR_VARIABLE[target];
|
|
26402
26612
|
if (insideProject && variable) {
|
|
26403
|
-
const posix =
|
|
26404
|
-
relative.split(
|
|
26613
|
+
const posix = path34.posix.join(
|
|
26614
|
+
relative.split(path34.sep).join("/"),
|
|
26405
26615
|
"scripts"
|
|
26406
26616
|
);
|
|
26407
26617
|
return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
|
|
26408
26618
|
}
|
|
26409
|
-
return { prefix:
|
|
26619
|
+
return { prefix: path34.join(bridge, "scripts"), machineLocal: true };
|
|
26410
26620
|
}
|
|
26411
26621
|
var PROJECT_DIR_VARIABLE = {
|
|
26412
26622
|
"claude-code": "$CLAUDE_PROJECT_DIR"
|
|
@@ -26416,19 +26626,19 @@ function machineLocalScriptPathNotice(target, prefix) {
|
|
|
26416
26626
|
}
|
|
26417
26627
|
|
|
26418
26628
|
// src/core/instructions-source.ts
|
|
26419
|
-
import
|
|
26420
|
-
import
|
|
26629
|
+
import fs37 from "fs";
|
|
26630
|
+
import path35 from "path";
|
|
26421
26631
|
var PORTABLE_INSTRUCTIONS_NAME = "AGENTS.md";
|
|
26422
26632
|
var InstructionsSourceMissingError = class extends Error {
|
|
26423
26633
|
constructor(kitRoot, expected, declaredBy) {
|
|
26424
26634
|
super(
|
|
26425
|
-
`${
|
|
26635
|
+
`${path35.join(kitRoot, expected)}: instructions source not found (declared by ${declaredBy}). To fix: create that file, or point '${declaredBy}' at the file this kit actually carries. With neither declaration, the kit's ${DEFAULT_ENTRYPOINT} or ${PORTABLE_INSTRUCTIONS_NAME} is used.`
|
|
26426
26636
|
);
|
|
26427
26637
|
this.name = "InstructionsSourceMissingError";
|
|
26428
26638
|
}
|
|
26429
26639
|
};
|
|
26430
26640
|
function normalizeLabel(kitRoot, file) {
|
|
26431
|
-
return
|
|
26641
|
+
return path35.relative(kitRoot, file).split(path35.sep).join("/");
|
|
26432
26642
|
}
|
|
26433
26643
|
function isExplicitOverride(configured) {
|
|
26434
26644
|
const normalize = (value) => value.replace(/\\/gu, "/").replace(/^\.\//u, "");
|
|
@@ -26437,8 +26647,8 @@ function isExplicitOverride(configured) {
|
|
|
26437
26647
|
function resolveInstructionsSource(kitRoot, config) {
|
|
26438
26648
|
const configured = config.source.instructions;
|
|
26439
26649
|
if (isExplicitOverride(configured)) {
|
|
26440
|
-
const file =
|
|
26441
|
-
if (!
|
|
26650
|
+
const file = path35.resolve(kitRoot, configured);
|
|
26651
|
+
if (!fs37.existsSync(file)) {
|
|
26442
26652
|
throw new InstructionsSourceMissingError(
|
|
26443
26653
|
kitRoot,
|
|
26444
26654
|
configured,
|
|
@@ -26453,8 +26663,8 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26453
26663
|
}
|
|
26454
26664
|
const declared = resolveKitEntrypointName(kitRoot);
|
|
26455
26665
|
if (declared !== void 0) {
|
|
26456
|
-
const file =
|
|
26457
|
-
if (!
|
|
26666
|
+
const file = path35.resolve(kitRoot, declared);
|
|
26667
|
+
if (!fs37.existsSync(file)) {
|
|
26458
26668
|
throw new InstructionsSourceMissingError(
|
|
26459
26669
|
kitRoot,
|
|
26460
26670
|
declared,
|
|
@@ -26468,13 +26678,13 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26468
26678
|
};
|
|
26469
26679
|
}
|
|
26470
26680
|
for (const name of [DEFAULT_ENTRYPOINT, PORTABLE_INSTRUCTIONS_NAME]) {
|
|
26471
|
-
const file =
|
|
26472
|
-
if (
|
|
26681
|
+
const file = path35.resolve(kitRoot, name);
|
|
26682
|
+
if (fs37.existsSync(file)) {
|
|
26473
26683
|
return { file, label: name, origin: "convention" };
|
|
26474
26684
|
}
|
|
26475
26685
|
}
|
|
26476
|
-
const legacy =
|
|
26477
|
-
if (
|
|
26686
|
+
const legacy = path35.resolve(kitRoot, LEGACY_ENTRYPOINT);
|
|
26687
|
+
if (fs37.existsSync(legacy)) {
|
|
26478
26688
|
return {
|
|
26479
26689
|
file: legacy,
|
|
26480
26690
|
label: LEGACY_ENTRYPOINT,
|
|
@@ -26486,7 +26696,7 @@ function resolveInstructionsSource(kitRoot, config) {
|
|
|
26486
26696
|
}
|
|
26487
26697
|
function instructionsSourcePath(kitRoot, config) {
|
|
26488
26698
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
26489
|
-
return resolved ? resolved.file :
|
|
26699
|
+
return resolved ? resolved.file : path35.resolve(kitRoot, config.source.instructions);
|
|
26490
26700
|
}
|
|
26491
26701
|
function instructionsSourceLabel(kitRoot, config) {
|
|
26492
26702
|
const resolved = resolveInstructionsSource(kitRoot, config);
|
|
@@ -26607,7 +26817,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
26607
26817
|
if (!shouldSkipComponent(options, "hooks")) {
|
|
26608
26818
|
outcomes.push(
|
|
26609
26819
|
syncHookScriptsBridge({
|
|
26610
|
-
source:
|
|
26820
|
+
source: path36.resolve(sourceRoot, config.source.hooks),
|
|
26611
26821
|
destination: profile.hook_scripts,
|
|
26612
26822
|
config,
|
|
26613
26823
|
sourceRoot,
|
|
@@ -26659,13 +26869,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
26659
26869
|
}
|
|
26660
26870
|
function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
|
|
26661
26871
|
if (!mappings.modelTiers.custom_provider) return;
|
|
26662
|
-
const agentsDir =
|
|
26663
|
-
if (!
|
|
26664
|
-
for (const agentFile of ts(
|
|
26872
|
+
const agentsDir = path36.join(sourceRoot, config.source.agents);
|
|
26873
|
+
if (!fs38.existsSync(agentsDir)) return;
|
|
26874
|
+
for (const agentFile of ts(path36.join(agentsDir, "*.md")).sort()) {
|
|
26665
26875
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
26666
26876
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
26667
26877
|
if (hasProvider) {
|
|
26668
|
-
const basename =
|
|
26878
|
+
const basename = path36.basename(agentFile);
|
|
26669
26879
|
addLoss(lossReport, "claude-code", "agents", {
|
|
26670
26880
|
source: `agents/${basename}`,
|
|
26671
26881
|
fields: [
|
|
@@ -26690,7 +26900,7 @@ function shouldSkipComponent(options, component) {
|
|
|
26690
26900
|
var SHIM_MANIFEST_KEY = "claude-code/instructions_shim";
|
|
26691
26901
|
function lstatOrNull(p) {
|
|
26692
26902
|
try {
|
|
26693
|
-
return
|
|
26903
|
+
return fs38.lstatSync(p);
|
|
26694
26904
|
} catch {
|
|
26695
26905
|
return null;
|
|
26696
26906
|
}
|
|
@@ -26702,12 +26912,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26702
26912
|
if (shimLink?.isSymbolicLink()) {
|
|
26703
26913
|
backupFile(shimPath, manifest, scopePath);
|
|
26704
26914
|
writeManifest(scopePath, manifest);
|
|
26705
|
-
|
|
26915
|
+
fs38.unlinkSync(shimPath);
|
|
26706
26916
|
logger?.verbose(
|
|
26707
26917
|
`instructions-shim: replaced an unmanaged symlink at ${shimPath}`
|
|
26708
26918
|
);
|
|
26709
26919
|
}
|
|
26710
|
-
if (!
|
|
26920
|
+
if (!fs38.existsSync(shimPath)) {
|
|
26711
26921
|
addArtifactToManifest(manifest, {
|
|
26712
26922
|
relativePath: SHIM_MANIFEST_KEY,
|
|
26713
26923
|
path: shimPath,
|
|
@@ -26715,12 +26925,12 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26715
26925
|
origin: "tangyr-managed"
|
|
26716
26926
|
});
|
|
26717
26927
|
writeManifest(scopePath, manifest);
|
|
26718
|
-
|
|
26719
|
-
|
|
26928
|
+
fs38.mkdirSync(path36.dirname(shimPath), { recursive: true });
|
|
26929
|
+
fs38.writeFileSync(shimPath, shimContent);
|
|
26720
26930
|
logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
|
|
26721
26931
|
return;
|
|
26722
26932
|
}
|
|
26723
|
-
const existing =
|
|
26933
|
+
const existing = fs38.readFileSync(shimPath, "utf8");
|
|
26724
26934
|
const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
|
|
26725
26935
|
const marker = extractProvenanceMarker(firstNonEmptyLine);
|
|
26726
26936
|
if (marker !== null && marker.hash === expectedBodyHash) {
|
|
@@ -26737,7 +26947,7 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26737
26947
|
}
|
|
26738
26948
|
backupFile(shimPath, manifest, scopePath);
|
|
26739
26949
|
writeManifest(scopePath, manifest);
|
|
26740
|
-
|
|
26950
|
+
fs38.writeFileSync(shimPath, shimContent);
|
|
26741
26951
|
addArtifactToManifest(manifest, {
|
|
26742
26952
|
relativePath: SHIM_MANIFEST_KEY,
|
|
26743
26953
|
path: shimPath,
|
|
@@ -26747,10 +26957,10 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
26747
26957
|
logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
|
|
26748
26958
|
}
|
|
26749
26959
|
function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
|
|
26750
|
-
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) :
|
|
26960
|
+
const source = directComponent.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : path36.resolve(sourceRoot, config.source[directComponent.sourceKey]);
|
|
26751
26961
|
const sourceLabel = directComponent.sourceKey === "instructions" ? instructionsSourceLabel(sourceRoot, config) : config.source[directComponent.sourceKey];
|
|
26752
26962
|
const destination = directComponent.destination;
|
|
26753
|
-
if (!
|
|
26963
|
+
if (!fs38.existsSync(source)) {
|
|
26754
26964
|
return skippedMissingSource(directComponent.component, source);
|
|
26755
26965
|
}
|
|
26756
26966
|
if (options.dryRun) {
|
|
@@ -26772,7 +26982,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
26772
26982
|
};
|
|
26773
26983
|
}
|
|
26774
26984
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
26775
|
-
|
|
26985
|
+
fs38.unlinkSync(destination);
|
|
26776
26986
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
|
|
26777
26987
|
return {
|
|
26778
26988
|
component: directComponent.component,
|
|
@@ -26780,11 +26990,11 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
26780
26990
|
path: destination
|
|
26781
26991
|
};
|
|
26782
26992
|
} else if (artifactClass === "managed-symlink") {
|
|
26783
|
-
|
|
26993
|
+
fs38.unlinkSync(destination);
|
|
26784
26994
|
} else if (artifactClass === "managed-compiled") {
|
|
26785
|
-
|
|
26995
|
+
fs38.unlinkSync(destination);
|
|
26786
26996
|
}
|
|
26787
|
-
ensureDir(
|
|
26997
|
+
ensureDir(path36.dirname(destination));
|
|
26788
26998
|
createRelativeSymlink(source, destination, directComponent.type, {
|
|
26789
26999
|
logger,
|
|
26790
27000
|
provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
|
|
@@ -26804,7 +27014,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
26804
27014
|
return syncSkillsSlot({
|
|
26805
27015
|
config,
|
|
26806
27016
|
sourceRoot,
|
|
26807
|
-
source:
|
|
27017
|
+
source: path36.resolve(sourceRoot, config.source.skills),
|
|
26808
27018
|
destination,
|
|
26809
27019
|
dryRun: options.dryRun,
|
|
26810
27020
|
logger,
|
|
@@ -26838,7 +27048,7 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
|
|
|
26838
27048
|
destination,
|
|
26839
27049
|
settings,
|
|
26840
27050
|
stringifyJson2,
|
|
26841
|
-
!
|
|
27051
|
+
!fs38.existsSync(destination),
|
|
26842
27052
|
logger
|
|
26843
27053
|
);
|
|
26844
27054
|
return {
|
|
@@ -26848,8 +27058,8 @@ function syncHooks(config, sourceRoot, options, logger, destination, scriptsBrid
|
|
|
26848
27058
|
};
|
|
26849
27059
|
}
|
|
26850
27060
|
function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
26851
|
-
const source =
|
|
26852
|
-
if (!
|
|
27061
|
+
const source = path36.resolve(sourceRoot, config.source.mcp);
|
|
27062
|
+
if (!fs38.existsSync(source)) {
|
|
26853
27063
|
return skippedMissingSource("mcp", source);
|
|
26854
27064
|
}
|
|
26855
27065
|
if (options.dryRun) {
|
|
@@ -26874,7 +27084,7 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
|
26874
27084
|
destination,
|
|
26875
27085
|
hostConfig,
|
|
26876
27086
|
stringifyJson2,
|
|
26877
|
-
!
|
|
27087
|
+
!fs38.existsSync(destination),
|
|
26878
27088
|
logger
|
|
26879
27089
|
);
|
|
26880
27090
|
return {
|
|
@@ -26884,8 +27094,8 @@ function syncMcp(config, sourceRoot, options, logger, destination) {
|
|
|
26884
27094
|
};
|
|
26885
27095
|
}
|
|
26886
27096
|
function syncSettings(config, sourceRoot, options, logger, destination) {
|
|
26887
|
-
const source =
|
|
26888
|
-
if (!
|
|
27097
|
+
const source = path36.resolve(sourceRoot, config.source.settings);
|
|
27098
|
+
if (!fs38.existsSync(source)) {
|
|
26889
27099
|
return skippedMissingSource("settings", source);
|
|
26890
27100
|
}
|
|
26891
27101
|
if (options.dryRun) {
|
|
@@ -26903,7 +27113,7 @@ function syncSettings(config, sourceRoot, options, logger, destination) {
|
|
|
26903
27113
|
destination,
|
|
26904
27114
|
settings,
|
|
26905
27115
|
stringifyJson2,
|
|
26906
|
-
!
|
|
27116
|
+
!fs38.existsSync(destination),
|
|
26907
27117
|
logger
|
|
26908
27118
|
);
|
|
26909
27119
|
return {
|
|
@@ -26927,7 +27137,7 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
|
|
|
26927
27137
|
if (manifest && scopePath) {
|
|
26928
27138
|
backupFile(destination, manifest, scopePath);
|
|
26929
27139
|
writeManifest(scopePath, manifest);
|
|
26930
|
-
|
|
27140
|
+
fs38.rmSync(destination, { recursive: true, force: true });
|
|
26931
27141
|
} else {
|
|
26932
27142
|
const parked = parkConflictingPath(
|
|
26933
27143
|
destination,
|
|
@@ -26942,7 +27152,7 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
|
|
|
26942
27152
|
}
|
|
26943
27153
|
return true;
|
|
26944
27154
|
}
|
|
26945
|
-
|
|
27155
|
+
fs38.rmSync(destination, { recursive: true, force: true });
|
|
26946
27156
|
return true;
|
|
26947
27157
|
}
|
|
26948
27158
|
function skippedMissingSource(component, source) {
|
|
@@ -26954,16 +27164,16 @@ function skippedMissingSource(component, source) {
|
|
|
26954
27164
|
}
|
|
26955
27165
|
function isSymlinkTo3(linkPath, source) {
|
|
26956
27166
|
try {
|
|
26957
|
-
return
|
|
27167
|
+
return fs38.realpathSync(linkPath) === fs38.realpathSync(source);
|
|
26958
27168
|
} catch {
|
|
26959
27169
|
return false;
|
|
26960
27170
|
}
|
|
26961
27171
|
}
|
|
26962
27172
|
function readJsonObject3(filePath) {
|
|
26963
|
-
if (!
|
|
27173
|
+
if (!fs38.existsSync(filePath)) {
|
|
26964
27174
|
return {};
|
|
26965
27175
|
}
|
|
26966
|
-
const parsed = JSON.parse(
|
|
27176
|
+
const parsed = JSON.parse(fs38.readFileSync(filePath, "utf8"));
|
|
26967
27177
|
return isRecord3(parsed) ? parsed : {};
|
|
26968
27178
|
}
|
|
26969
27179
|
function markManaged(value) {
|
|
@@ -26990,13 +27200,13 @@ function isRecord3(value) {
|
|
|
26990
27200
|
// src/adapters/codex.ts
|
|
26991
27201
|
var TOML3 = __toESM(require_toml(), 1);
|
|
26992
27202
|
import crypto6 from "crypto";
|
|
26993
|
-
import
|
|
26994
|
-
import
|
|
27203
|
+
import fs41 from "fs";
|
|
27204
|
+
import path40 from "path";
|
|
26995
27205
|
|
|
26996
27206
|
// src/compiler/agents.ts
|
|
26997
27207
|
var TOML = __toESM(require_toml(), 1);
|
|
26998
27208
|
var import_yaml8 = __toESM(require_dist(), 1);
|
|
26999
|
-
import
|
|
27209
|
+
import path37 from "path";
|
|
27000
27210
|
var writeCapabilityClasses = /* @__PURE__ */ new Set(["filesystem-write", "shell-execution"]);
|
|
27001
27211
|
var copilotToolAliasesByClass = {
|
|
27002
27212
|
delegation: "agent",
|
|
@@ -27008,7 +27218,7 @@ var copilotToolAliasesByClass = {
|
|
|
27008
27218
|
};
|
|
27009
27219
|
function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
27010
27220
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
27011
|
-
const relativeSource = `agents/${
|
|
27221
|
+
const relativeSource = `agents/${path37.basename(sourceFile)}`;
|
|
27012
27222
|
if (target === "opencode") {
|
|
27013
27223
|
return compileOpenCodeAgent(
|
|
27014
27224
|
sourceFile,
|
|
@@ -27049,7 +27259,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
|
27049
27259
|
mappings,
|
|
27050
27260
|
lossReport
|
|
27051
27261
|
);
|
|
27052
|
-
const overlayKey = `agents/${
|
|
27262
|
+
const overlayKey = `agents/${path37.basename(sourceFile, ".md")}.${target}.yaml`;
|
|
27053
27263
|
const targetFields = {
|
|
27054
27264
|
...translated.fields,
|
|
27055
27265
|
...extensions[overlayKey] ?? {}
|
|
@@ -27083,7 +27293,7 @@ ${TOML.stringify({
|
|
|
27083
27293
|
function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
27084
27294
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
27085
27295
|
throw new Error(
|
|
27086
|
-
`${
|
|
27296
|
+
`${path37.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
|
|
27087
27297
|
);
|
|
27088
27298
|
}
|
|
27089
27299
|
const frontmatter = {
|
|
@@ -27137,7 +27347,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
|
|
|
27137
27347
|
"permission",
|
|
27138
27348
|
"permission-coarsening"
|
|
27139
27349
|
),
|
|
27140
|
-
detail: `${
|
|
27350
|
+
detail: `${path37.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
|
|
27141
27351
|
}
|
|
27142
27352
|
]
|
|
27143
27353
|
});
|
|
@@ -27162,7 +27372,7 @@ ${(0, import_yaml8.stringify)(frontmatter).trim()}
|
|
|
27162
27372
|
function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
27163
27373
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
27164
27374
|
throw new Error(
|
|
27165
|
-
`${
|
|
27375
|
+
`${path37.basename(sourceFile)}: Cursor agent requires a non-empty description field`
|
|
27166
27376
|
);
|
|
27167
27377
|
}
|
|
27168
27378
|
const frontmatter = {
|
|
@@ -27199,7 +27409,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
27199
27409
|
"permission",
|
|
27200
27410
|
"permission-coarsening"
|
|
27201
27411
|
),
|
|
27202
|
-
detail: `${
|
|
27412
|
+
detail: `${path37.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
|
|
27203
27413
|
}
|
|
27204
27414
|
]
|
|
27205
27415
|
});
|
|
@@ -27218,7 +27428,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
27218
27428
|
"provider",
|
|
27219
27429
|
"provider-not-representable"
|
|
27220
27430
|
),
|
|
27221
|
-
detail: `${
|
|
27431
|
+
detail: `${path37.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
27222
27432
|
}
|
|
27223
27433
|
]
|
|
27224
27434
|
});
|
|
@@ -27250,7 +27460,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
|
|
|
27250
27460
|
"persona",
|
|
27251
27461
|
"persona-not-representable"
|
|
27252
27462
|
),
|
|
27253
|
-
detail: `${
|
|
27463
|
+
detail: `${path37.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
|
|
27254
27464
|
}
|
|
27255
27465
|
]
|
|
27256
27466
|
});
|
|
@@ -27298,7 +27508,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27298
27508
|
field,
|
|
27299
27509
|
"model-not-representable"
|
|
27300
27510
|
),
|
|
27301
|
-
detail: `${
|
|
27511
|
+
detail: `${path37.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
|
|
27302
27512
|
});
|
|
27303
27513
|
return;
|
|
27304
27514
|
}
|
|
@@ -27316,9 +27526,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27316
27526
|
lossReport,
|
|
27317
27527
|
target,
|
|
27318
27528
|
"agents",
|
|
27319
|
-
`agents/${
|
|
27529
|
+
`agents/${path37.basename(sourceFile)}`,
|
|
27320
27530
|
"info",
|
|
27321
|
-
`${
|
|
27531
|
+
`${path37.basename(sourceFile)}: ${field} is delivered through another managed surface.`
|
|
27322
27532
|
);
|
|
27323
27533
|
return;
|
|
27324
27534
|
}
|
|
@@ -27327,7 +27537,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
27327
27537
|
field,
|
|
27328
27538
|
action: entryType,
|
|
27329
27539
|
severity: resolveLossSeverity("agent-field", field, entryType),
|
|
27330
|
-
detail: `${
|
|
27540
|
+
detail: `${path37.basename(sourceFile)}: ${field} has no emitted field for this target.`
|
|
27331
27541
|
});
|
|
27332
27542
|
}
|
|
27333
27543
|
function mapToolsToCapabilities(value, mappings) {
|
|
@@ -27791,13 +28001,13 @@ function addHookLoss(lossReport, target, eventName, sourceLabel, severity, reaso
|
|
|
27791
28001
|
|
|
27792
28002
|
// src/compiler/command-as-skill.ts
|
|
27793
28003
|
var import_yaml9 = __toESM(require_dist(), 1);
|
|
27794
|
-
import
|
|
27795
|
-
import
|
|
28004
|
+
import fs39 from "fs";
|
|
28005
|
+
import path38 from "path";
|
|
27796
28006
|
var CARRIED_OVER = ["argument-hint", "agent", "launch"];
|
|
27797
28007
|
function compileCommandAsSkill(commandFile, target) {
|
|
27798
|
-
const name =
|
|
28008
|
+
const name = path38.basename(commandFile, ".md");
|
|
27799
28009
|
const { data, body } = parseMarkdownFrontmatter(commandFile);
|
|
27800
|
-
const relativeSource = `commands/${
|
|
28010
|
+
const relativeSource = `commands/${path38.basename(commandFile)}`;
|
|
27801
28011
|
const description = typeof data.description === "string" && data.description.trim().length > 0 ? data.description.trim() : `The ${name} command.`;
|
|
27802
28012
|
const frontmatter = { name, description };
|
|
27803
28013
|
for (const key of CARRIED_OVER) {
|
|
@@ -27820,11 +28030,11 @@ ${body.trim()}
|
|
|
27820
28030
|
return { name, content, relativeSource };
|
|
27821
28031
|
}
|
|
27822
28032
|
function compileCommandsAsSkills(commandsRoot, target) {
|
|
27823
|
-
if (!
|
|
28033
|
+
if (!fs39.existsSync(commandsRoot)) {
|
|
27824
28034
|
return [];
|
|
27825
28035
|
}
|
|
27826
|
-
return
|
|
27827
|
-
(entry) => compileCommandAsSkill(
|
|
28036
|
+
return fs39.readdirSync(commandsRoot).filter((entry) => entry.endsWith(".md")).sort().map(
|
|
28037
|
+
(entry) => compileCommandAsSkill(path38.join(commandsRoot, entry), target)
|
|
27828
28038
|
);
|
|
27829
28039
|
}
|
|
27830
28040
|
|
|
@@ -28107,9 +28317,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
|
|
|
28107
28317
|
}
|
|
28108
28318
|
|
|
28109
28319
|
// src/compiler/rules.ts
|
|
28110
|
-
import
|
|
28320
|
+
import path39 from "path";
|
|
28111
28321
|
var import_yaml10 = __toESM(require_dist(), 1);
|
|
28112
|
-
import
|
|
28322
|
+
import fs40 from "fs";
|
|
28113
28323
|
function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
28114
28324
|
if (target === "copilot") {
|
|
28115
28325
|
addLoss(lossReport, "copilot", "rules", {
|
|
@@ -28146,13 +28356,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
|
28146
28356
|
}
|
|
28147
28357
|
const appendixParts = [];
|
|
28148
28358
|
const dotRulesFiles = [];
|
|
28149
|
-
for (const ruleFile of ts(
|
|
28359
|
+
for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
|
|
28150
28360
|
const parsed = parseRule(ruleFile);
|
|
28151
|
-
const name =
|
|
28361
|
+
const name = path39.basename(ruleFile, ".md");
|
|
28152
28362
|
if (parsed.mode === "exec-policy") {
|
|
28153
28363
|
dotRulesFiles.push({
|
|
28154
28364
|
name: `${name}.rules`,
|
|
28155
|
-
content: `${formatProvenanceMarker("toml", `rules/${
|
|
28365
|
+
content: `${formatProvenanceMarker("toml", `rules/${path39.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
|
|
28156
28366
|
${parsed.body}`
|
|
28157
28367
|
});
|
|
28158
28368
|
continue;
|
|
@@ -28161,7 +28371,7 @@ ${parsed.body}`
|
|
|
28161
28371
|
|
|
28162
28372
|
${parsed.body.trim()}`);
|
|
28163
28373
|
addLoss(lossReport, "codex", "rules", {
|
|
28164
|
-
source: `rules/${
|
|
28374
|
+
source: `rules/${path39.basename(ruleFile)}`,
|
|
28165
28375
|
fields: [
|
|
28166
28376
|
{
|
|
28167
28377
|
field: "mode",
|
|
@@ -28171,7 +28381,7 @@ ${parsed.body.trim()}`);
|
|
|
28171
28381
|
"mode",
|
|
28172
28382
|
"rule-as-instruction"
|
|
28173
28383
|
),
|
|
28174
|
-
detail: `${
|
|
28384
|
+
detail: `${path39.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
|
|
28175
28385
|
}
|
|
28176
28386
|
]
|
|
28177
28387
|
});
|
|
@@ -28179,7 +28389,7 @@ ${parsed.body.trim()}`);
|
|
|
28179
28389
|
return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
|
|
28180
28390
|
}
|
|
28181
28391
|
function parseRule(ruleFile) {
|
|
28182
|
-
const content =
|
|
28392
|
+
const content = fs40.readFileSync(ruleFile, "utf8");
|
|
28183
28393
|
if (!content.startsWith("---\n")) {
|
|
28184
28394
|
return { mode: "guidance", body: content };
|
|
28185
28395
|
}
|
|
@@ -28203,14 +28413,14 @@ function isRuleMode(value) {
|
|
|
28203
28413
|
}
|
|
28204
28414
|
function compileOpenCodeRules(sourceRulesDir, lossReport) {
|
|
28205
28415
|
const appendixParts = [];
|
|
28206
|
-
for (const ruleFile of ts(
|
|
28416
|
+
for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
|
|
28207
28417
|
const parsed = parseRule(ruleFile);
|
|
28208
|
-
const name =
|
|
28418
|
+
const name = path39.basename(ruleFile, ".md");
|
|
28209
28419
|
appendixParts.push(`## ${name}
|
|
28210
28420
|
|
|
28211
28421
|
${parsed.body.trim()}`);
|
|
28212
28422
|
addLoss(lossReport, "opencode", "rules", {
|
|
28213
|
-
source: `rules/${
|
|
28423
|
+
source: `rules/${path39.basename(ruleFile)}`,
|
|
28214
28424
|
fields: [
|
|
28215
28425
|
{
|
|
28216
28426
|
field: "rule",
|
|
@@ -28220,7 +28430,7 @@ ${parsed.body.trim()}`);
|
|
|
28220
28430
|
"rule",
|
|
28221
28431
|
"rule-path-scoping"
|
|
28222
28432
|
),
|
|
28223
|
-
detail: `${
|
|
28433
|
+
detail: `${path39.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
|
|
28224
28434
|
}
|
|
28225
28435
|
]
|
|
28226
28436
|
});
|
|
@@ -28229,9 +28439,9 @@ ${parsed.body.trim()}`);
|
|
|
28229
28439
|
}
|
|
28230
28440
|
function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
28231
28441
|
const dotRulesFiles = [];
|
|
28232
|
-
for (const ruleFile of ts(
|
|
28233
|
-
const content =
|
|
28234
|
-
const name =
|
|
28442
|
+
for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
|
|
28443
|
+
const content = fs40.readFileSync(ruleFile, "utf8");
|
|
28444
|
+
const name = path39.basename(ruleFile, ".md");
|
|
28235
28445
|
let frontmatterData = {};
|
|
28236
28446
|
let body = content;
|
|
28237
28447
|
if (content.startsWith("---\n")) {
|
|
@@ -28260,7 +28470,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
|
28260
28470
|
}
|
|
28261
28471
|
const marker = formatProvenanceMarker(
|
|
28262
28472
|
"markdown",
|
|
28263
|
-
`rules/${
|
|
28473
|
+
`rules/${path39.basename(ruleFile)}`,
|
|
28264
28474
|
computeSourceHash(ruleFile),
|
|
28265
28475
|
"cursor"
|
|
28266
28476
|
);
|
|
@@ -28276,9 +28486,9 @@ ${body}`;
|
|
|
28276
28486
|
}
|
|
28277
28487
|
function compileClineRules(sourceRulesDir, lossReport) {
|
|
28278
28488
|
const dotRulesFiles = [];
|
|
28279
|
-
for (const ruleFile of ts(
|
|
28280
|
-
const content =
|
|
28281
|
-
const name =
|
|
28489
|
+
for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
|
|
28490
|
+
const content = fs40.readFileSync(ruleFile, "utf8");
|
|
28491
|
+
const name = path39.basename(ruleFile, ".md");
|
|
28282
28492
|
let frontmatterData = {};
|
|
28283
28493
|
let body = content;
|
|
28284
28494
|
if (content.startsWith("---\n")) {
|
|
@@ -28295,13 +28505,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28295
28505
|
}
|
|
28296
28506
|
const marker = formatProvenanceMarker(
|
|
28297
28507
|
"markdown",
|
|
28298
|
-
`rules/${
|
|
28508
|
+
`rules/${path39.basename(ruleFile)}`,
|
|
28299
28509
|
computeSourceHash(ruleFile),
|
|
28300
28510
|
"cline"
|
|
28301
28511
|
);
|
|
28302
28512
|
if (frontmatterData.mode === "exec-policy") {
|
|
28303
28513
|
addLoss(lossReport, "cline", "rules", {
|
|
28304
|
-
source: `rules/${
|
|
28514
|
+
source: `rules/${path39.basename(ruleFile)}`,
|
|
28305
28515
|
fields: [
|
|
28306
28516
|
{
|
|
28307
28517
|
field: "mode",
|
|
@@ -28311,7 +28521,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
28311
28521
|
"mode",
|
|
28312
28522
|
"rule-mode-downgrade"
|
|
28313
28523
|
),
|
|
28314
|
-
detail: `${
|
|
28524
|
+
detail: `${path39.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
|
|
28315
28525
|
}
|
|
28316
28526
|
]
|
|
28317
28527
|
});
|
|
@@ -28331,12 +28541,12 @@ ${frontmatterYaml}${body}`;
|
|
|
28331
28541
|
return { agentsAppendix: "", dotRulesFiles };
|
|
28332
28542
|
}
|
|
28333
28543
|
function compileCopilotRules(sourceRulesDir) {
|
|
28334
|
-
if (!
|
|
28544
|
+
if (!fs40.existsSync(sourceRulesDir)) {
|
|
28335
28545
|
return [];
|
|
28336
28546
|
}
|
|
28337
28547
|
const files = [];
|
|
28338
|
-
for (const ruleFile of ts(
|
|
28339
|
-
const name =
|
|
28548
|
+
for (const ruleFile of ts(path39.join(sourceRulesDir, "*.md")).sort()) {
|
|
28549
|
+
const name = path39.basename(ruleFile, ".md");
|
|
28340
28550
|
const { data } = parseMarkdownFrontmatter(ruleFile);
|
|
28341
28551
|
const { body } = parseRule(ruleFile);
|
|
28342
28552
|
const declared = data.paths;
|
|
@@ -28345,7 +28555,7 @@ function compileCopilotRules(sourceRulesDir) {
|
|
|
28345
28555
|
"---",
|
|
28346
28556
|
`applyTo: ${JSON.stringify(applyTo)}`,
|
|
28347
28557
|
"x-tangyr:",
|
|
28348
|
-
` source: rules/${
|
|
28558
|
+
` source: rules/${path39.basename(ruleFile)}`,
|
|
28349
28559
|
` hash: ${computeSourceHash(ruleFile)}`,
|
|
28350
28560
|
" target: copilot",
|
|
28351
28561
|
"---"
|
|
@@ -28382,7 +28592,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28382
28592
|
rules: profile.rules
|
|
28383
28593
|
};
|
|
28384
28594
|
const rules = compileRules(
|
|
28385
|
-
|
|
28595
|
+
path40.join(sourceRoot, config.source.rules),
|
|
28386
28596
|
"codex",
|
|
28387
28597
|
mappings,
|
|
28388
28598
|
lossReport
|
|
@@ -28462,7 +28672,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28462
28672
|
if (!shouldSkipComponent2(options, "hooks")) {
|
|
28463
28673
|
outcomes.push(
|
|
28464
28674
|
syncHookScriptsBridge({
|
|
28465
|
-
source:
|
|
28675
|
+
source: path40.resolve(sourceRoot, config.source.hooks),
|
|
28466
28676
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
28467
28677
|
config,
|
|
28468
28678
|
sourceRoot,
|
|
@@ -28561,9 +28771,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28561
28771
|
function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
|
|
28562
28772
|
const cp = mappings.modelTiers.custom_provider;
|
|
28563
28773
|
if (!cp) return "";
|
|
28564
|
-
const agentsDir =
|
|
28565
|
-
if (!
|
|
28566
|
-
const agentFiles = ts(
|
|
28774
|
+
const agentsDir = path40.join(sourceRoot, config.source.agents);
|
|
28775
|
+
if (!fs41.existsSync(agentsDir)) return "";
|
|
28776
|
+
const agentFiles = ts(path40.join(agentsDir, "*.md")).sort();
|
|
28567
28777
|
const hasProviderAgent = agentFiles.some((agentFile) => {
|
|
28568
28778
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28569
28779
|
return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
@@ -28628,7 +28838,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28628
28838
|
}
|
|
28629
28839
|
];
|
|
28630
28840
|
for (const ruleFile of rules.dotRulesFiles) {
|
|
28631
|
-
const destination =
|
|
28841
|
+
const destination = path40.join(rulesRoot, ruleFile.name);
|
|
28632
28842
|
if (options.dryRun) {
|
|
28633
28843
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
28634
28844
|
outcomes.push({
|
|
@@ -28658,16 +28868,16 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
28658
28868
|
function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
28659
28869
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
28660
28870
|
const destination = resolveTargetPath(paths.instructions);
|
|
28661
|
-
if (!
|
|
28871
|
+
if (!fs41.existsSync(source)) {
|
|
28662
28872
|
return skippedMissingSource2("instructions", source);
|
|
28663
28873
|
}
|
|
28664
|
-
const composed = `${
|
|
28874
|
+
const composed = `${fs41.readFileSync(source, "utf8").trim()}
|
|
28665
28875
|
|
|
28666
28876
|
--- tangyr managed rules ---
|
|
28667
28877
|
${agentsAppendix}`.trim();
|
|
28668
28878
|
const marker = formatProvenanceMarker(
|
|
28669
28879
|
"markdown",
|
|
28670
|
-
|
|
28880
|
+
path40.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
28671
28881
|
hashString(composed),
|
|
28672
28882
|
"codex"
|
|
28673
28883
|
);
|
|
@@ -28697,7 +28907,7 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
28697
28907
|
return syncSkillsSlot({
|
|
28698
28908
|
config,
|
|
28699
28909
|
sourceRoot,
|
|
28700
|
-
source:
|
|
28910
|
+
source: path40.resolve(sourceRoot, config.source.skills),
|
|
28701
28911
|
destination: resolveTargetPath(paths.skills),
|
|
28702
28912
|
dryRun: options.dryRun,
|
|
28703
28913
|
logger,
|
|
@@ -28712,13 +28922,13 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
28712
28922
|
});
|
|
28713
28923
|
}
|
|
28714
28924
|
function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, logger, manifest, scopePath) {
|
|
28715
|
-
const commandsRoot =
|
|
28716
|
-
if (!
|
|
28925
|
+
const commandsRoot = path40.resolve(sourceRoot, config.source.commands);
|
|
28926
|
+
if (!fs41.existsSync(commandsRoot)) {
|
|
28717
28927
|
return [skippedMissingSource2("commands", commandsRoot)];
|
|
28718
28928
|
}
|
|
28719
28929
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
28720
28930
|
return compileCommandsAsSkills(commandsRoot, "codex").map((skill) => {
|
|
28721
|
-
const destination =
|
|
28931
|
+
const destination = path40.join(skillsRoot, skill.name, "SKILL.md");
|
|
28722
28932
|
if (options.dryRun) {
|
|
28723
28933
|
logger.info(
|
|
28724
28934
|
`[dry-run] commands: compile ${skill.relativeSource} -> ${destination}`
|
|
@@ -28744,16 +28954,16 @@ function syncCommandsAsSkills(config, sourceRoot, paths, options, _lossReport, l
|
|
|
28744
28954
|
});
|
|
28745
28955
|
}
|
|
28746
28956
|
function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
28747
|
-
const sourceAgentsRoot =
|
|
28748
|
-
if (!
|
|
28957
|
+
const sourceAgentsRoot = path40.join(sourceRoot, config.source.agents);
|
|
28958
|
+
if (!fs41.existsSync(sourceAgentsRoot)) {
|
|
28749
28959
|
return [skippedMissingSource2("agents", sourceAgentsRoot)];
|
|
28750
28960
|
}
|
|
28751
|
-
const sourceAgents = ts(
|
|
28961
|
+
const sourceAgents = ts(path40.join(sourceAgentsRoot, "*.md")).sort();
|
|
28752
28962
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
28753
28963
|
return sourceAgents.map((agentFile) => {
|
|
28754
|
-
const destination =
|
|
28964
|
+
const destination = path40.join(
|
|
28755
28965
|
agentsRoot,
|
|
28756
|
-
`${
|
|
28966
|
+
`${path40.basename(agentFile, ".md")}.toml`
|
|
28757
28967
|
);
|
|
28758
28968
|
const compiled = compileAgent(
|
|
28759
28969
|
agentFile,
|
|
@@ -28831,7 +29041,7 @@ function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
28831
29041
|
destination,
|
|
28832
29042
|
hostHooks,
|
|
28833
29043
|
stringifyJson3,
|
|
28834
|
-
!
|
|
29044
|
+
!fs41.existsSync(destination),
|
|
28835
29045
|
logger
|
|
28836
29046
|
);
|
|
28837
29047
|
return {
|
|
@@ -28844,7 +29054,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28844
29054
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
28845
29055
|
const sourceLabel = mcpSourceLabel(config);
|
|
28846
29056
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
28847
|
-
if (!
|
|
29057
|
+
if (!fs41.existsSync(source)) {
|
|
28848
29058
|
if (providerToml && !options.dryRun) {
|
|
28849
29059
|
const changed2 = writeTomlManagedSection(
|
|
28850
29060
|
destination,
|
|
@@ -28859,7 +29069,7 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger, provid
|
|
|
28859
29069
|
}
|
|
28860
29070
|
return skippedMissingSource2("mcp", source);
|
|
28861
29071
|
}
|
|
28862
|
-
const sourceMcpJson = JSON.parse(
|
|
29072
|
+
const sourceMcpJson = JSON.parse(fs41.readFileSync(source, "utf8"));
|
|
28863
29073
|
const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
|
|
28864
29074
|
const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
|
|
28865
29075
|
if (options.dryRun) {
|
|
@@ -28884,18 +29094,18 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
|
|
|
28884
29094
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
28885
29095
|
return { component, status: "conflict", path: destination };
|
|
28886
29096
|
}
|
|
28887
|
-
ensureDir(
|
|
29097
|
+
ensureDir(path40.dirname(destination));
|
|
28888
29098
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
28889
29099
|
if (clearedLink !== null) {
|
|
28890
29100
|
logger.verbose(
|
|
28891
29101
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
28892
29102
|
);
|
|
28893
29103
|
}
|
|
28894
|
-
|
|
29104
|
+
fs41.writeFileSync(destination, content);
|
|
28895
29105
|
return { component, status: "success", path: destination };
|
|
28896
29106
|
}
|
|
28897
29107
|
function writeTomlManagedSection(destination, managedContent, logger) {
|
|
28898
|
-
const current =
|
|
29108
|
+
const current = fs41.existsSync(destination) ? fs41.readFileSync(destination, "utf8") : "";
|
|
28899
29109
|
const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
|
|
28900
29110
|
if (isFirstWrite) {
|
|
28901
29111
|
logger.warn(
|
|
@@ -28911,8 +29121,8 @@ ${managedMcpEnd}
|
|
|
28911
29121
|
if (current === next.trimStart()) {
|
|
28912
29122
|
return false;
|
|
28913
29123
|
}
|
|
28914
|
-
ensureDir(
|
|
28915
|
-
|
|
29124
|
+
ensureDir(path40.dirname(destination));
|
|
29125
|
+
fs41.writeFileSync(destination, next.trimStart());
|
|
28916
29126
|
return true;
|
|
28917
29127
|
}
|
|
28918
29128
|
function removeManagedTomlSection(content) {
|
|
@@ -28938,7 +29148,7 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
|
|
|
28938
29148
|
if (manifest && scopePath) {
|
|
28939
29149
|
backupFile(destination, manifest, scopePath);
|
|
28940
29150
|
writeManifest(scopePath, manifest);
|
|
28941
|
-
|
|
29151
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
28942
29152
|
} else {
|
|
28943
29153
|
const parked = parkConflictingPath(
|
|
28944
29154
|
destination,
|
|
@@ -28953,12 +29163,12 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
|
|
|
28953
29163
|
}
|
|
28954
29164
|
return true;
|
|
28955
29165
|
}
|
|
28956
|
-
|
|
29166
|
+
fs41.rmSync(destination, { recursive: true, force: true });
|
|
28957
29167
|
return true;
|
|
28958
29168
|
}
|
|
28959
29169
|
function isCompiledCurrent(destination, expectedContent, _expectedHash) {
|
|
28960
29170
|
try {
|
|
28961
|
-
return
|
|
29171
|
+
return fs41.readFileSync(destination, "utf8") === expectedContent;
|
|
28962
29172
|
} catch {
|
|
28963
29173
|
return false;
|
|
28964
29174
|
}
|
|
@@ -28974,10 +29184,10 @@ function shouldSkipComponent2(options, component) {
|
|
|
28974
29184
|
return Boolean(options.component && options.component !== component);
|
|
28975
29185
|
}
|
|
28976
29186
|
function readJsonObject4(filePath) {
|
|
28977
|
-
if (!
|
|
29187
|
+
if (!fs41.existsSync(filePath)) {
|
|
28978
29188
|
return {};
|
|
28979
29189
|
}
|
|
28980
|
-
const parsed = JSON.parse(
|
|
29190
|
+
const parsed = JSON.parse(fs41.readFileSync(filePath, "utf8"));
|
|
28981
29191
|
return isRecord5(parsed) ? parsed : {};
|
|
28982
29192
|
}
|
|
28983
29193
|
function stringifyJson3(value) {
|
|
@@ -28993,16 +29203,16 @@ function hashString(value) {
|
|
|
28993
29203
|
|
|
28994
29204
|
// src/adapters/copilot.ts
|
|
28995
29205
|
import crypto7 from "crypto";
|
|
28996
|
-
import
|
|
28997
|
-
import
|
|
29206
|
+
import fs42 from "fs";
|
|
29207
|
+
import path42 from "path";
|
|
28998
29208
|
|
|
28999
29209
|
// src/compiler/commands.ts
|
|
29000
29210
|
var import_yaml11 = __toESM(require_dist(), 1);
|
|
29001
|
-
import
|
|
29211
|
+
import path41 from "path";
|
|
29002
29212
|
function compileCommandPrompt(sourceFile) {
|
|
29003
29213
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
29004
|
-
const relativeSource = `commands/${
|
|
29005
|
-
const fields = promptFrontmatter(data,
|
|
29214
|
+
const relativeSource = `commands/${path41.basename(sourceFile)}`;
|
|
29215
|
+
const fields = promptFrontmatter(data, path41.basename(sourceFile, ".md"));
|
|
29006
29216
|
const marker = formatProvenanceMarker(
|
|
29007
29217
|
"markdown",
|
|
29008
29218
|
relativeSource,
|
|
@@ -29143,7 +29353,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
29143
29353
|
if (!shouldSkipComponent3(options, "hooks")) {
|
|
29144
29354
|
outcomes.push(
|
|
29145
29355
|
syncHookScriptsBridge({
|
|
29146
|
-
source:
|
|
29356
|
+
source: path42.resolve(sourceRoot, config.source.hooks),
|
|
29147
29357
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
29148
29358
|
config,
|
|
29149
29359
|
sourceRoot,
|
|
@@ -29224,13 +29434,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
29224
29434
|
}
|
|
29225
29435
|
function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
|
|
29226
29436
|
if (!mappings.modelTiers.custom_provider) return;
|
|
29227
|
-
const agentsDir =
|
|
29228
|
-
if (!
|
|
29229
|
-
for (const agentFile of ts(
|
|
29437
|
+
const agentsDir = path42.join(sourceRoot, config.source.agents);
|
|
29438
|
+
if (!fs42.existsSync(agentsDir)) return;
|
|
29439
|
+
for (const agentFile of ts(path42.join(agentsDir, "*.md")).sort()) {
|
|
29230
29440
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
29231
29441
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
29232
29442
|
if (hasProvider) {
|
|
29233
|
-
const basename =
|
|
29443
|
+
const basename = path42.basename(agentFile);
|
|
29234
29444
|
addLoss(lossReport, "copilot", "agents", {
|
|
29235
29445
|
source: `agents/${basename}`,
|
|
29236
29446
|
fields: [
|
|
@@ -29256,22 +29466,22 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
|
|
|
29256
29466
|
return [{ component: "instructions", status: "skipped", path: message }];
|
|
29257
29467
|
}
|
|
29258
29468
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
29259
|
-
if (!
|
|
29469
|
+
if (!fs42.existsSync(source)) {
|
|
29260
29470
|
return [skippedMissingSource3("instructions", source)];
|
|
29261
29471
|
}
|
|
29262
|
-
const rawContent =
|
|
29472
|
+
const rawContent = fs42.readFileSync(source, "utf8");
|
|
29263
29473
|
const contentHash = hashString2(rawContent);
|
|
29264
29474
|
const marker = formatProvenanceMarker(
|
|
29265
29475
|
"markdown",
|
|
29266
|
-
|
|
29476
|
+
path42.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
29267
29477
|
contentHash,
|
|
29268
29478
|
"copilot"
|
|
29269
29479
|
);
|
|
29270
29480
|
const composedContent = `${marker}
|
|
29271
29481
|
${rawContent}`;
|
|
29272
29482
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
29273
|
-
const agentsMdDest =
|
|
29274
|
-
const mirrorDest =
|
|
29483
|
+
const agentsMdDest = path42.resolve(projectRoot, "AGENTS.md");
|
|
29484
|
+
const mirrorDest = path42.resolve(
|
|
29275
29485
|
projectRoot,
|
|
29276
29486
|
".github",
|
|
29277
29487
|
"copilot-instructions.md"
|
|
@@ -29325,14 +29535,14 @@ function writeInstructionsFile(component, destination, content, contentHash, con
|
|
|
29325
29535
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29326
29536
|
return { component, status: "conflict", path: destination };
|
|
29327
29537
|
}
|
|
29328
|
-
ensureDir(
|
|
29538
|
+
ensureDir(path42.dirname(destination));
|
|
29329
29539
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29330
29540
|
if (clearedLink !== null) {
|
|
29331
29541
|
logger.verbose(
|
|
29332
29542
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29333
29543
|
);
|
|
29334
29544
|
}
|
|
29335
|
-
|
|
29545
|
+
fs42.writeFileSync(destination, content);
|
|
29336
29546
|
return { component, status: "success", path: destination };
|
|
29337
29547
|
}
|
|
29338
29548
|
function hashString2(value) {
|
|
@@ -29342,7 +29552,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29342
29552
|
return syncSkillsSlot({
|
|
29343
29553
|
config,
|
|
29344
29554
|
sourceRoot,
|
|
29345
|
-
source:
|
|
29555
|
+
source: path42.resolve(sourceRoot, config.source.skills),
|
|
29346
29556
|
destination: resolveTargetPath(paths.skills),
|
|
29347
29557
|
dryRun: options.dryRun,
|
|
29348
29558
|
logger,
|
|
@@ -29357,16 +29567,16 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
29357
29567
|
});
|
|
29358
29568
|
}
|
|
29359
29569
|
function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29360
|
-
const sourceAgentsRoot =
|
|
29361
|
-
if (!
|
|
29570
|
+
const sourceAgentsRoot = path42.join(sourceRoot, config.source.agents);
|
|
29571
|
+
if (!fs42.existsSync(sourceAgentsRoot)) {
|
|
29362
29572
|
return [skippedMissingSource3("agents", sourceAgentsRoot)];
|
|
29363
29573
|
}
|
|
29364
|
-
const sourceAgents = ts(
|
|
29574
|
+
const sourceAgents = ts(path42.join(sourceAgentsRoot, "*.md")).sort();
|
|
29365
29575
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29366
29576
|
return sourceAgents.map((agentFile) => {
|
|
29367
|
-
const destination =
|
|
29577
|
+
const destination = path42.join(
|
|
29368
29578
|
agentsRoot,
|
|
29369
|
-
`${
|
|
29579
|
+
`${path42.basename(agentFile, ".md")}.agent.md`
|
|
29370
29580
|
);
|
|
29371
29581
|
const compiled = compileAgent(
|
|
29372
29582
|
agentFile,
|
|
@@ -29394,16 +29604,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29394
29604
|
});
|
|
29395
29605
|
}
|
|
29396
29606
|
function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29397
|
-
const sourceCommandsRoot =
|
|
29398
|
-
if (!
|
|
29607
|
+
const sourceCommandsRoot = path42.join(sourceRoot, config.source.commands);
|
|
29608
|
+
if (!fs42.existsSync(sourceCommandsRoot)) {
|
|
29399
29609
|
return [skippedMissingSource3("commands", sourceCommandsRoot)];
|
|
29400
29610
|
}
|
|
29401
|
-
const sourceCommands = ts(
|
|
29611
|
+
const sourceCommands = ts(path42.join(sourceCommandsRoot, "*.md")).sort();
|
|
29402
29612
|
const promptsRoot = resolveTargetPath(paths.prompts);
|
|
29403
29613
|
return sourceCommands.map((commandFile) => {
|
|
29404
|
-
const destination =
|
|
29614
|
+
const destination = path42.join(
|
|
29405
29615
|
promptsRoot,
|
|
29406
|
-
`${
|
|
29616
|
+
`${path42.basename(commandFile, ".md")}.prompt.md`
|
|
29407
29617
|
);
|
|
29408
29618
|
const compiled = compileCommandPrompt(commandFile);
|
|
29409
29619
|
if (options.dryRun) {
|
|
@@ -29427,7 +29637,7 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
|
|
|
29427
29637
|
});
|
|
29428
29638
|
}
|
|
29429
29639
|
function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
29430
|
-
const destination =
|
|
29640
|
+
const destination = path42.join(
|
|
29431
29641
|
resolveTargetPath(paths.hooks),
|
|
29432
29642
|
"tangyr-managed.json"
|
|
29433
29643
|
);
|
|
@@ -29490,10 +29700,10 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
29490
29700
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
29491
29701
|
const sourceLabel = mcpSourceLabel(config);
|
|
29492
29702
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
29493
|
-
if (!
|
|
29703
|
+
if (!fs42.existsSync(source)) {
|
|
29494
29704
|
return skippedMissingSource3("mcp", source);
|
|
29495
29705
|
}
|
|
29496
|
-
const sourceMcpJson = JSON.parse(
|
|
29706
|
+
const sourceMcpJson = JSON.parse(fs42.readFileSync(source, "utf8"));
|
|
29497
29707
|
const compiled = compileMcp(
|
|
29498
29708
|
sourceMcpJson,
|
|
29499
29709
|
"copilot",
|
|
@@ -29516,13 +29726,13 @@ function syncMcp3(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
29516
29726
|
);
|
|
29517
29727
|
}
|
|
29518
29728
|
function syncRules2(config, sourceRoot, rulesSlot, options, logger, manifest, scopePath) {
|
|
29519
|
-
const sourceRulesDir =
|
|
29520
|
-
if (!
|
|
29729
|
+
const sourceRulesDir = path42.resolve(sourceRoot, config.source.rules);
|
|
29730
|
+
if (!fs42.existsSync(sourceRulesDir)) {
|
|
29521
29731
|
return [skippedMissingSource3("rules", sourceRulesDir)];
|
|
29522
29732
|
}
|
|
29523
29733
|
const destinationRoot = resolveTargetPath(rulesSlot);
|
|
29524
29734
|
return compileCopilotRules(sourceRulesDir).map((file) => {
|
|
29525
|
-
const destination =
|
|
29735
|
+
const destination = path42.join(destinationRoot, file.name);
|
|
29526
29736
|
if (options.dryRun) {
|
|
29527
29737
|
logger.info(`[dry-run] rules: compile -> ${destination}`);
|
|
29528
29738
|
return {
|
|
@@ -29556,19 +29766,19 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
|
|
|
29556
29766
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
29557
29767
|
return { component, status: "conflict", path: destination };
|
|
29558
29768
|
}
|
|
29559
|
-
ensureDir(
|
|
29769
|
+
ensureDir(path42.dirname(destination));
|
|
29560
29770
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
29561
29771
|
if (clearedLink !== null) {
|
|
29562
29772
|
logger.verbose(
|
|
29563
29773
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
29564
29774
|
);
|
|
29565
29775
|
}
|
|
29566
|
-
|
|
29776
|
+
fs42.writeFileSync(destination, content);
|
|
29567
29777
|
return { component, status: "success", path: destination };
|
|
29568
29778
|
}
|
|
29569
29779
|
function isCompiledCurrent2(destination, expectedContent, _expectedHash) {
|
|
29570
29780
|
try {
|
|
29571
|
-
return
|
|
29781
|
+
return fs42.readFileSync(destination, "utf8") === expectedContent;
|
|
29572
29782
|
} catch {
|
|
29573
29783
|
return false;
|
|
29574
29784
|
}
|
|
@@ -29588,7 +29798,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
|
|
|
29588
29798
|
if (manifest && scopePath) {
|
|
29589
29799
|
backupFile(destination, manifest, scopePath);
|
|
29590
29800
|
writeManifest(scopePath, manifest);
|
|
29591
|
-
|
|
29801
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
29592
29802
|
} else {
|
|
29593
29803
|
const parked = parkConflictingPath(
|
|
29594
29804
|
destination,
|
|
@@ -29603,7 +29813,7 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
|
|
|
29603
29813
|
}
|
|
29604
29814
|
return true;
|
|
29605
29815
|
}
|
|
29606
|
-
|
|
29816
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
29607
29817
|
return true;
|
|
29608
29818
|
}
|
|
29609
29819
|
function shouldSkipComponent3(options, component) {
|
|
@@ -29612,12 +29822,12 @@ function shouldSkipComponent3(options, component) {
|
|
|
29612
29822
|
function cleanupLegacyAgents(paths, options, logger) {
|
|
29613
29823
|
const currentAgentsRoot = resolveTargetPath(paths.agents);
|
|
29614
29824
|
const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
|
|
29615
|
-
if (
|
|
29825
|
+
if (path42.resolve(currentAgentsRoot) === path42.resolve(legacyAgentsRoot)) {
|
|
29616
29826
|
return [];
|
|
29617
29827
|
}
|
|
29618
29828
|
const outcomes = [];
|
|
29619
29829
|
for (const filePath of ts(
|
|
29620
|
-
|
|
29830
|
+
path42.join(legacyAgentsRoot, "*.agent.md")
|
|
29621
29831
|
).sort()) {
|
|
29622
29832
|
if (!isCopilotManagedCompiledFile(filePath)) {
|
|
29623
29833
|
continue;
|
|
@@ -29627,14 +29837,14 @@ function cleanupLegacyAgents(paths, options, logger) {
|
|
|
29627
29837
|
outcomes.push({ component: "agents", status: "dry-run", path: filePath });
|
|
29628
29838
|
continue;
|
|
29629
29839
|
}
|
|
29630
|
-
|
|
29840
|
+
fs42.rmSync(filePath, { force: true });
|
|
29631
29841
|
outcomes.push({ component: "agents", status: "success", path: filePath });
|
|
29632
29842
|
}
|
|
29633
29843
|
return outcomes;
|
|
29634
29844
|
}
|
|
29635
29845
|
function isCopilotManagedCompiledFile(filePath) {
|
|
29636
29846
|
try {
|
|
29637
|
-
return extractProvenanceMarker(
|
|
29847
|
+
return extractProvenanceMarker(fs42.readFileSync(filePath, "utf8"))?.target === "copilot";
|
|
29638
29848
|
} catch {
|
|
29639
29849
|
return false;
|
|
29640
29850
|
}
|
|
@@ -29649,8 +29859,8 @@ function skippedMissingSource3(component, source) {
|
|
|
29649
29859
|
|
|
29650
29860
|
// src/adapters/cursor.ts
|
|
29651
29861
|
import crypto8 from "crypto";
|
|
29652
|
-
import
|
|
29653
|
-
import
|
|
29862
|
+
import fs43 from "fs";
|
|
29863
|
+
import path43 from "path";
|
|
29654
29864
|
function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29655
29865
|
const scope = options.scope ?? "global";
|
|
29656
29866
|
const profile = resolveTargetPaths({
|
|
@@ -29762,7 +29972,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
29762
29972
|
if (!shouldSkipComponent4(options, "hooks")) {
|
|
29763
29973
|
outcomes.push(
|
|
29764
29974
|
syncHookScriptsBridge({
|
|
29765
|
-
source:
|
|
29975
|
+
source: path43.resolve(sourceRoot, config.source.hooks),
|
|
29766
29976
|
destination: resolveTargetPath(paths.hook_scripts),
|
|
29767
29977
|
config,
|
|
29768
29978
|
sourceRoot,
|
|
@@ -29827,7 +30037,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
|
|
|
29827
30037
|
const composed = composeCursorInstructions(config, sourceRoot, lossReport);
|
|
29828
30038
|
const marker = formatProvenanceMarker(
|
|
29829
30039
|
"markdown",
|
|
29830
|
-
|
|
30040
|
+
path43.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
29831
30041
|
hashString3(composed),
|
|
29832
30042
|
"cursor"
|
|
29833
30043
|
);
|
|
@@ -29853,7 +30063,7 @@ ${composed}
|
|
|
29853
30063
|
}
|
|
29854
30064
|
function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
29855
30065
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
29856
|
-
const baseContent =
|
|
30066
|
+
const baseContent = fs43.existsSync(source) ? fs43.readFileSync(source, "utf8").trim() : "";
|
|
29857
30067
|
const personaContent = extractPrimaryPersonaContent(
|
|
29858
30068
|
config,
|
|
29859
30069
|
sourceRoot,
|
|
@@ -29866,11 +30076,11 @@ function composeCursorInstructions(config, sourceRoot, lossReport) {
|
|
|
29866
30076
|
${personaContent}`.trim() : baseContent;
|
|
29867
30077
|
}
|
|
29868
30078
|
function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
29869
|
-
const agentsDir =
|
|
29870
|
-
if (!
|
|
30079
|
+
const agentsDir = path43.join(sourceRoot, config.source.agents);
|
|
30080
|
+
if (!fs43.existsSync(agentsDir)) {
|
|
29871
30081
|
return null;
|
|
29872
30082
|
}
|
|
29873
|
-
const agentFiles = ts(
|
|
30083
|
+
const agentFiles = ts(path43.join(agentsDir, "*.md")).sort();
|
|
29874
30084
|
if (agentFiles.length === 0) {
|
|
29875
30085
|
return null;
|
|
29876
30086
|
}
|
|
@@ -29893,7 +30103,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29893
30103
|
return null;
|
|
29894
30104
|
}
|
|
29895
30105
|
addLoss(lossReport, "cursor", "instructions", {
|
|
29896
|
-
source: `agents/${
|
|
30106
|
+
source: `agents/${path43.basename(primaryFile)}`,
|
|
29897
30107
|
fields: [
|
|
29898
30108
|
{
|
|
29899
30109
|
field: "persona",
|
|
@@ -29903,23 +30113,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
29903
30113
|
"persona",
|
|
29904
30114
|
"instructions-shim"
|
|
29905
30115
|
),
|
|
29906
|
-
detail: `Primary persona from ${
|
|
30116
|
+
detail: `Primary persona from ${path43.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
|
|
29907
30117
|
}
|
|
29908
30118
|
]
|
|
29909
30119
|
});
|
|
29910
30120
|
return body.trim();
|
|
29911
30121
|
}
|
|
29912
30122
|
function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
29913
|
-
const sourceAgentsRoot =
|
|
29914
|
-
if (!
|
|
30123
|
+
const sourceAgentsRoot = path43.join(sourceRoot, config.source.agents);
|
|
30124
|
+
if (!fs43.existsSync(sourceAgentsRoot)) {
|
|
29915
30125
|
return [skippedMissingSource4("agents", sourceAgentsRoot)];
|
|
29916
30126
|
}
|
|
29917
|
-
const sourceAgents = ts(
|
|
30127
|
+
const sourceAgents = ts(path43.join(sourceAgentsRoot, "*.md")).sort();
|
|
29918
30128
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
29919
30129
|
return sourceAgents.map((agentFile) => {
|
|
29920
|
-
const destination =
|
|
30130
|
+
const destination = path43.join(
|
|
29921
30131
|
agentsRoot,
|
|
29922
|
-
`${
|
|
30132
|
+
`${path43.basename(agentFile, ".md")}.md`
|
|
29923
30133
|
);
|
|
29924
30134
|
let compiled;
|
|
29925
30135
|
try {
|
|
@@ -29960,14 +30170,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
29960
30170
|
});
|
|
29961
30171
|
}
|
|
29962
30172
|
function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
29963
|
-
const sourceRulesDir =
|
|
29964
|
-
if (!
|
|
30173
|
+
const sourceRulesDir = path43.join(sourceRoot, config.source.rules);
|
|
30174
|
+
if (!fs43.existsSync(sourceRulesDir)) {
|
|
29965
30175
|
return [skippedMissingSource4("rules", sourceRulesDir)];
|
|
29966
30176
|
}
|
|
29967
30177
|
const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
|
|
29968
30178
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
29969
30179
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
29970
|
-
const destination =
|
|
30180
|
+
const destination = path43.join(rulesDir, name);
|
|
29971
30181
|
if (options.dryRun) {
|
|
29972
30182
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
29973
30183
|
return {
|
|
@@ -29991,15 +30201,15 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
29991
30201
|
});
|
|
29992
30202
|
}
|
|
29993
30203
|
function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
29994
|
-
const sourceCommandsRoot =
|
|
29995
|
-
if (!
|
|
30204
|
+
const sourceCommandsRoot = path43.join(sourceRoot, config.source.commands);
|
|
30205
|
+
if (!fs43.existsSync(sourceCommandsRoot)) {
|
|
29996
30206
|
return [skippedMissingSource4("commands", sourceCommandsRoot)];
|
|
29997
30207
|
}
|
|
29998
|
-
const sourceCommands = ts(
|
|
30208
|
+
const sourceCommands = ts(path43.join(sourceCommandsRoot, "*.md")).sort();
|
|
29999
30209
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
30000
30210
|
return sourceCommands.map((commandFile) => {
|
|
30001
|
-
const baseName =
|
|
30002
|
-
const destination =
|
|
30211
|
+
const baseName = path43.basename(commandFile, ".md");
|
|
30212
|
+
const destination = path43.join(skillsRoot, baseName, "SKILL.md");
|
|
30003
30213
|
const { content } = compileCommandAsSkill(commandFile, "cursor");
|
|
30004
30214
|
if (options.dryRun) {
|
|
30005
30215
|
logger.info(
|
|
@@ -30029,7 +30239,7 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, _
|
|
|
30029
30239
|
return syncSkillsSlot({
|
|
30030
30240
|
config,
|
|
30031
30241
|
sourceRoot,
|
|
30032
|
-
source:
|
|
30242
|
+
source: path43.resolve(sourceRoot, config.source.skills),
|
|
30033
30243
|
destination,
|
|
30034
30244
|
dryRun: options.dryRun,
|
|
30035
30245
|
logger,
|
|
@@ -30077,18 +30287,18 @@ function syncHooks4(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
30077
30287
|
}
|
|
30078
30288
|
const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
|
|
30079
30289
|
`;
|
|
30080
|
-
ensureDir(
|
|
30081
|
-
|
|
30290
|
+
ensureDir(path43.dirname(destination));
|
|
30291
|
+
fs43.writeFileSync(destination, hooksFileContent);
|
|
30082
30292
|
return { component: "hooks", status: "success", path: destination };
|
|
30083
30293
|
}
|
|
30084
30294
|
function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
|
|
30085
30295
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30086
30296
|
const sourceLabel = mcpSourceLabel(config);
|
|
30087
30297
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
30088
|
-
if (!
|
|
30298
|
+
if (!fs43.existsSync(source)) {
|
|
30089
30299
|
return skippedMissingSource4("mcp", source);
|
|
30090
30300
|
}
|
|
30091
|
-
const sourceMcpJson = JSON.parse(
|
|
30301
|
+
const sourceMcpJson = JSON.parse(fs43.readFileSync(source, "utf8"));
|
|
30092
30302
|
const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
|
|
30093
30303
|
if (options.dryRun) {
|
|
30094
30304
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -30141,13 +30351,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
|
|
|
30141
30351
|
);
|
|
30142
30352
|
}
|
|
30143
30353
|
function syncProviderPin(config, sourceRoot, lossReport) {
|
|
30144
|
-
const agentsDir =
|
|
30145
|
-
if (!
|
|
30146
|
-
for (const agentFile of ts(
|
|
30354
|
+
const agentsDir = path43.join(sourceRoot, config.source.agents);
|
|
30355
|
+
if (!fs43.existsSync(agentsDir)) return;
|
|
30356
|
+
for (const agentFile of ts(path43.join(agentsDir, "*.md")).sort()) {
|
|
30147
30357
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
30148
30358
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
30149
30359
|
if (hasCustomProvider) {
|
|
30150
|
-
const relativeSource = `agents/${
|
|
30360
|
+
const relativeSource = `agents/${path43.basename(agentFile)}`;
|
|
30151
30361
|
addLoss(lossReport, "cursor", "agents", {
|
|
30152
30362
|
source: relativeSource,
|
|
30153
30363
|
fields: [
|
|
@@ -30159,7 +30369,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
|
|
|
30159
30369
|
"provider",
|
|
30160
30370
|
"provider-not-representable"
|
|
30161
30371
|
),
|
|
30162
|
-
detail: `${
|
|
30372
|
+
detail: `${path43.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
30163
30373
|
}
|
|
30164
30374
|
]
|
|
30165
30375
|
});
|
|
@@ -30177,14 +30387,14 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
|
|
|
30177
30387
|
if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
30178
30388
|
return { component, status: "conflict", path: destination };
|
|
30179
30389
|
}
|
|
30180
|
-
ensureDir(
|
|
30390
|
+
ensureDir(path43.dirname(destination));
|
|
30181
30391
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30182
30392
|
if (clearedLink !== null) {
|
|
30183
30393
|
logger.verbose(
|
|
30184
30394
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30185
30395
|
);
|
|
30186
30396
|
}
|
|
30187
|
-
|
|
30397
|
+
fs43.writeFileSync(destination, content);
|
|
30188
30398
|
return { component, status: "success", path: destination };
|
|
30189
30399
|
}
|
|
30190
30400
|
function handleConflict4(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30202,7 +30412,7 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
|
|
|
30202
30412
|
if (manifest && scopePath) {
|
|
30203
30413
|
backupFile(destination, manifest, scopePath);
|
|
30204
30414
|
writeManifest(scopePath, manifest);
|
|
30205
|
-
|
|
30415
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30206
30416
|
} else {
|
|
30207
30417
|
const parked = parkConflictingPath(
|
|
30208
30418
|
destination,
|
|
@@ -30217,12 +30427,12 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
|
|
|
30217
30427
|
}
|
|
30218
30428
|
return true;
|
|
30219
30429
|
}
|
|
30220
|
-
|
|
30430
|
+
fs43.rmSync(destination, { recursive: true, force: true });
|
|
30221
30431
|
return true;
|
|
30222
30432
|
}
|
|
30223
30433
|
function isCompiledCurrent3(destination, expectedContent, _expectedHash) {
|
|
30224
30434
|
try {
|
|
30225
|
-
return
|
|
30435
|
+
return fs43.readFileSync(destination, "utf8") === expectedContent;
|
|
30226
30436
|
} catch {
|
|
30227
30437
|
return false;
|
|
30228
30438
|
}
|
|
@@ -30243,8 +30453,8 @@ function hashString3(value) {
|
|
|
30243
30453
|
|
|
30244
30454
|
// src/adapters/cline.ts
|
|
30245
30455
|
import crypto9 from "crypto";
|
|
30246
|
-
import
|
|
30247
|
-
import
|
|
30456
|
+
import fs44 from "fs";
|
|
30457
|
+
import path44 from "path";
|
|
30248
30458
|
function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30249
30459
|
const scope = options.scope ?? "global";
|
|
30250
30460
|
const profile = resolveTargetPaths({
|
|
@@ -30357,7 +30567,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
30357
30567
|
function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
|
|
30358
30568
|
if (scope === "global" || paths.instructions === null) {
|
|
30359
30569
|
addLoss(lossReport, "cline", "instructions", {
|
|
30360
|
-
source:
|
|
30570
|
+
source: path44.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30361
30571
|
fields: [
|
|
30362
30572
|
{
|
|
30363
30573
|
field: "instructions",
|
|
@@ -30379,10 +30589,10 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
|
|
|
30379
30589
|
}
|
|
30380
30590
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30381
30591
|
const destination = resolveTargetPath(paths.instructions);
|
|
30382
|
-
const baseContent =
|
|
30592
|
+
const baseContent = fs44.existsSync(source) ? fs44.readFileSync(source, "utf8").trim() : "";
|
|
30383
30593
|
const marker = formatProvenanceMarker(
|
|
30384
30594
|
"markdown",
|
|
30385
|
-
|
|
30595
|
+
path44.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30386
30596
|
hashString4(baseContent),
|
|
30387
30597
|
"cline"
|
|
30388
30598
|
);
|
|
@@ -30407,11 +30617,11 @@ ${baseContent}
|
|
|
30407
30617
|
);
|
|
30408
30618
|
}
|
|
30409
30619
|
function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
|
|
30410
|
-
const sourceAgentsRoot =
|
|
30411
|
-
if (!
|
|
30620
|
+
const sourceAgentsRoot = path44.join(sourceRoot, config.source.agents);
|
|
30621
|
+
if (!fs44.existsSync(sourceAgentsRoot)) {
|
|
30412
30622
|
return [skippedMissingSource5("agents", sourceAgentsRoot)];
|
|
30413
30623
|
}
|
|
30414
|
-
const sourceAgents = ts(
|
|
30624
|
+
const sourceAgents = ts(path44.join(sourceAgentsRoot, "*.md")).sort();
|
|
30415
30625
|
return sourceAgents.map((agentFile) => {
|
|
30416
30626
|
compileAgent(agentFile, "cline", mappings, extensions, lossReport);
|
|
30417
30627
|
if (options.dryRun) {
|
|
@@ -30427,14 +30637,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
30427
30637
|
});
|
|
30428
30638
|
}
|
|
30429
30639
|
function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
30430
|
-
const sourceRulesDir =
|
|
30431
|
-
if (!
|
|
30640
|
+
const sourceRulesDir = path44.join(sourceRoot, config.source.rules);
|
|
30641
|
+
if (!fs44.existsSync(sourceRulesDir)) {
|
|
30432
30642
|
return [skippedMissingSource5("rules", sourceRulesDir)];
|
|
30433
30643
|
}
|
|
30434
30644
|
const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
|
|
30435
30645
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
30436
30646
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
30437
|
-
const destination =
|
|
30647
|
+
const destination = path44.join(rulesDir, name);
|
|
30438
30648
|
if (options.dryRun) {
|
|
30439
30649
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
30440
30650
|
return {
|
|
@@ -30458,17 +30668,17 @@ function syncRules4(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
30458
30668
|
});
|
|
30459
30669
|
}
|
|
30460
30670
|
function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30461
|
-
const sourceCommandsRoot =
|
|
30462
|
-
if (!
|
|
30671
|
+
const sourceCommandsRoot = path44.join(sourceRoot, config.source.commands);
|
|
30672
|
+
if (!fs44.existsSync(sourceCommandsRoot)) {
|
|
30463
30673
|
return [skippedMissingSource5("commands", sourceCommandsRoot)];
|
|
30464
30674
|
}
|
|
30465
|
-
const sourceCommands = ts(
|
|
30675
|
+
const sourceCommands = ts(path44.join(sourceCommandsRoot, "*.md")).sort();
|
|
30466
30676
|
const workflowsRoot = resolveTargetPath(paths.workflows);
|
|
30467
30677
|
return sourceCommands.map((commandFile) => {
|
|
30468
|
-
const baseName =
|
|
30469
|
-
const destination =
|
|
30470
|
-
const commandContent =
|
|
30471
|
-
const relativeSource = `commands/${
|
|
30678
|
+
const baseName = path44.basename(commandFile);
|
|
30679
|
+
const destination = path44.join(workflowsRoot, baseName);
|
|
30680
|
+
const commandContent = fs44.readFileSync(commandFile, "utf8");
|
|
30681
|
+
const relativeSource = `commands/${path44.basename(commandFile)}`;
|
|
30472
30682
|
const marker = formatProvenanceMarker(
|
|
30473
30683
|
"markdown",
|
|
30474
30684
|
relativeSource,
|
|
@@ -30506,7 +30716,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
30506
30716
|
return syncSkillsSlot({
|
|
30507
30717
|
config,
|
|
30508
30718
|
sourceRoot,
|
|
30509
|
-
source:
|
|
30719
|
+
source: path44.resolve(sourceRoot, config.source.skills),
|
|
30510
30720
|
destination: resolveTargetPath(paths.skills),
|
|
30511
30721
|
dryRun: options.dryRun,
|
|
30512
30722
|
logger,
|
|
@@ -30539,10 +30749,10 @@ function syncMcp5(config, sourceRoot, paths, options, lossReport, logger, manife
|
|
|
30539
30749
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
30540
30750
|
const sourceLabel = mcpSourceLabel(config);
|
|
30541
30751
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
30542
|
-
if (!
|
|
30752
|
+
if (!fs44.existsSync(source)) {
|
|
30543
30753
|
return skippedMissingSource5("mcp", source);
|
|
30544
30754
|
}
|
|
30545
|
-
const sourceMcpJson = JSON.parse(
|
|
30755
|
+
const sourceMcpJson = JSON.parse(fs44.readFileSync(source, "utf8"));
|
|
30546
30756
|
const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
|
|
30547
30757
|
if (options.dryRun) {
|
|
30548
30758
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -30585,11 +30795,11 @@ function syncSettings2(lossReport) {
|
|
|
30585
30795
|
};
|
|
30586
30796
|
}
|
|
30587
30797
|
function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
30588
|
-
const agentsDir =
|
|
30589
|
-
if (!
|
|
30590
|
-
for (const agentFile of ts(
|
|
30798
|
+
const agentsDir = path44.join(sourceRoot, config.source.agents);
|
|
30799
|
+
if (!fs44.existsSync(agentsDir)) return;
|
|
30800
|
+
for (const agentFile of ts(path44.join(agentsDir, "*.md")).sort()) {
|
|
30591
30801
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
30592
|
-
const relativeSource = `agents/${
|
|
30802
|
+
const relativeSource = `agents/${path44.basename(agentFile)}`;
|
|
30593
30803
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
30594
30804
|
if (hasCustomProvider) {
|
|
30595
30805
|
addLoss(lossReport, "cline", "agents", {
|
|
@@ -30603,7 +30813,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30603
30813
|
"provider",
|
|
30604
30814
|
"provider-not-representable"
|
|
30605
30815
|
),
|
|
30606
|
-
detail: `${
|
|
30816
|
+
detail: `${path44.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
|
|
30607
30817
|
}
|
|
30608
30818
|
]
|
|
30609
30819
|
});
|
|
@@ -30621,7 +30831,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
30621
30831
|
"model",
|
|
30622
30832
|
"model-not-representable"
|
|
30623
30833
|
),
|
|
30624
|
-
detail: `${
|
|
30834
|
+
detail: `${path44.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
|
|
30625
30835
|
}
|
|
30626
30836
|
]
|
|
30627
30837
|
});
|
|
@@ -30639,14 +30849,14 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
|
|
|
30639
30849
|
if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
30640
30850
|
return { component, status: "conflict", path: destination };
|
|
30641
30851
|
}
|
|
30642
|
-
ensureDir(
|
|
30852
|
+
ensureDir(path44.dirname(destination));
|
|
30643
30853
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
30644
30854
|
if (clearedLink !== null) {
|
|
30645
30855
|
logger.verbose(
|
|
30646
30856
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
30647
30857
|
);
|
|
30648
30858
|
}
|
|
30649
|
-
|
|
30859
|
+
fs44.writeFileSync(destination, content);
|
|
30650
30860
|
return { component, status: "success", path: destination };
|
|
30651
30861
|
}
|
|
30652
30862
|
function handleConflict5(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -30664,7 +30874,7 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
|
|
|
30664
30874
|
if (manifest && scopePath) {
|
|
30665
30875
|
backupFile(destination, manifest, scopePath);
|
|
30666
30876
|
writeManifest(scopePath, manifest);
|
|
30667
|
-
|
|
30877
|
+
fs44.rmSync(destination, { recursive: true, force: true });
|
|
30668
30878
|
} else {
|
|
30669
30879
|
const parked = parkConflictingPath(
|
|
30670
30880
|
destination,
|
|
@@ -30679,12 +30889,12 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
|
|
|
30679
30889
|
}
|
|
30680
30890
|
return true;
|
|
30681
30891
|
}
|
|
30682
|
-
|
|
30892
|
+
fs44.rmSync(destination, { recursive: true, force: true });
|
|
30683
30893
|
return true;
|
|
30684
30894
|
}
|
|
30685
30895
|
function isCompiledCurrent4(destination, expectedContent, _expectedHash) {
|
|
30686
30896
|
try {
|
|
30687
|
-
return
|
|
30897
|
+
return fs44.readFileSync(destination, "utf8") === expectedContent;
|
|
30688
30898
|
} catch {
|
|
30689
30899
|
return false;
|
|
30690
30900
|
}
|
|
@@ -30705,9 +30915,9 @@ function hashString4(value) {
|
|
|
30705
30915
|
|
|
30706
30916
|
// src/adapters/opencode.ts
|
|
30707
30917
|
import crypto10 from "crypto";
|
|
30708
|
-
import
|
|
30918
|
+
import fs45 from "fs";
|
|
30709
30919
|
import os6 from "os";
|
|
30710
|
-
import
|
|
30920
|
+
import path45 from "path";
|
|
30711
30921
|
var import_yaml12 = __toESM(require_dist(), 1);
|
|
30712
30922
|
function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30713
30923
|
const scope = options.scope ?? "global";
|
|
@@ -30725,7 +30935,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30725
30935
|
config_doc: profile.config_doc
|
|
30726
30936
|
};
|
|
30727
30937
|
const rules = compileRules(
|
|
30728
|
-
|
|
30938
|
+
path45.join(sourceRoot, config.source.rules),
|
|
30729
30939
|
"opencode",
|
|
30730
30940
|
mappings,
|
|
30731
30941
|
lossReport
|
|
@@ -30733,7 +30943,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30733
30943
|
const outcomes = [];
|
|
30734
30944
|
if (!shouldSkipComponent6(options, "instructions")) {
|
|
30735
30945
|
outcomes.push(
|
|
30736
|
-
syncInstructions4(
|
|
30946
|
+
...syncInstructions4(
|
|
30737
30947
|
config,
|
|
30738
30948
|
sourceRoot,
|
|
30739
30949
|
paths,
|
|
@@ -30829,14 +31039,14 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
30829
31039
|
function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
30830
31040
|
const source = instructionsSourcePath(sourceRoot, config);
|
|
30831
31041
|
const destination = resolveTargetPath(paths.instructions);
|
|
30832
|
-
const baseContent =
|
|
31042
|
+
const baseContent = fs45.existsSync(source) ? fs45.readFileSync(source, "utf8").trim() : "";
|
|
30833
31043
|
const composed = agentsAppendix ? `${baseContent}
|
|
30834
31044
|
|
|
30835
31045
|
--- tangyr managed rules ---
|
|
30836
31046
|
${agentsAppendix}`.trim() : baseContent;
|
|
30837
31047
|
const marker = formatProvenanceMarker(
|
|
30838
31048
|
"markdown",
|
|
30839
|
-
|
|
31049
|
+
path45.basename(instructionsSourceLabel(sourceRoot, config)),
|
|
30840
31050
|
hashString5(composed),
|
|
30841
31051
|
"opencode"
|
|
30842
31052
|
);
|
|
@@ -30847,9 +31057,11 @@ ${composed}
|
|
|
30847
31057
|
logger.info(
|
|
30848
31058
|
`[dry-run] instructions: generate ${source} + rules appendix -> ${destination}`
|
|
30849
31059
|
);
|
|
30850
|
-
return
|
|
31060
|
+
return [
|
|
31061
|
+
{ component: "instructions", status: "dry-run", path: destination }
|
|
31062
|
+
];
|
|
30851
31063
|
}
|
|
30852
|
-
|
|
31064
|
+
const written = writeCompiledArtifact5(
|
|
30853
31065
|
"instructions",
|
|
30854
31066
|
destination,
|
|
30855
31067
|
content,
|
|
@@ -30861,18 +31073,60 @@ ${composed}
|
|
|
30861
31073
|
manifest,
|
|
30862
31074
|
scopePath
|
|
30863
31075
|
);
|
|
31076
|
+
const declared = declareInstructions(paths);
|
|
31077
|
+
return declared === null ? [written] : [
|
|
31078
|
+
written,
|
|
31079
|
+
{ component: "instructions", status: "success", path: declared }
|
|
31080
|
+
];
|
|
31081
|
+
}
|
|
31082
|
+
function declaredInstructionsPath(paths) {
|
|
31083
|
+
const configDir = path45.dirname(resolveTargetPath(paths.config_doc));
|
|
31084
|
+
const instructions = resolveTargetPath(paths.instructions);
|
|
31085
|
+
const relative = path45.relative(configDir, instructions);
|
|
31086
|
+
if (relative === "AGENTS.md" || relative.startsWith("..")) {
|
|
31087
|
+
return null;
|
|
31088
|
+
}
|
|
31089
|
+
return relative.split(path45.sep).join("/");
|
|
31090
|
+
}
|
|
31091
|
+
function withDeclaredInstructions(existing, reference) {
|
|
31092
|
+
const listed = Array.isArray(existing) ? existing.filter((entry) => typeof entry === "string") : [];
|
|
31093
|
+
return listed.includes(reference) ? listed : [...listed, reference];
|
|
31094
|
+
}
|
|
31095
|
+
function declareInstructions(paths) {
|
|
31096
|
+
const reference = declaredInstructionsPath(paths);
|
|
31097
|
+
if (reference === null) {
|
|
31098
|
+
return null;
|
|
31099
|
+
}
|
|
31100
|
+
const destination = resolveTargetPath(paths.config_doc);
|
|
31101
|
+
let existing = {};
|
|
31102
|
+
if (fs45.existsSync(destination)) {
|
|
31103
|
+
try {
|
|
31104
|
+
existing = JSON.parse(fs45.readFileSync(destination, "utf8"));
|
|
31105
|
+
} catch {
|
|
31106
|
+
existing = {};
|
|
31107
|
+
}
|
|
31108
|
+
}
|
|
31109
|
+
const config = {
|
|
31110
|
+
$schema: "https://opencode.ai/config.json",
|
|
31111
|
+
...existing,
|
|
31112
|
+
instructions: withDeclaredInstructions(existing.instructions, reference)
|
|
31113
|
+
};
|
|
31114
|
+
ensureDir(path45.dirname(destination));
|
|
31115
|
+
fs45.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
31116
|
+
`);
|
|
31117
|
+
return destination;
|
|
30864
31118
|
}
|
|
30865
31119
|
function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
30866
|
-
const sourceAgentsRoot =
|
|
30867
|
-
if (!
|
|
31120
|
+
const sourceAgentsRoot = path45.join(sourceRoot, config.source.agents);
|
|
31121
|
+
if (!fs45.existsSync(sourceAgentsRoot)) {
|
|
30868
31122
|
return [skippedMissingSource6("agents", sourceAgentsRoot)];
|
|
30869
31123
|
}
|
|
30870
|
-
const sourceAgents = ts(
|
|
31124
|
+
const sourceAgents = ts(path45.join(sourceAgentsRoot, "*.md")).sort();
|
|
30871
31125
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
30872
31126
|
return sourceAgents.map((agentFile) => {
|
|
30873
|
-
const destination =
|
|
31127
|
+
const destination = path45.join(
|
|
30874
31128
|
agentsRoot,
|
|
30875
|
-
`${
|
|
31129
|
+
`${path45.basename(agentFile, ".md")}.md`
|
|
30876
31130
|
);
|
|
30877
31131
|
let compiled;
|
|
30878
31132
|
try {
|
|
@@ -30936,11 +31190,11 @@ function applyProviderModelBinding(compiled, mappings) {
|
|
|
30936
31190
|
return `${before}${(0, import_yaml12.stringify)(fields).trim()}${after}`;
|
|
30937
31191
|
}
|
|
30938
31192
|
function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
30939
|
-
const sourceCommandsRoot =
|
|
30940
|
-
if (!
|
|
31193
|
+
const sourceCommandsRoot = path45.join(sourceRoot, config.source.commands);
|
|
31194
|
+
if (!fs45.existsSync(sourceCommandsRoot)) {
|
|
30941
31195
|
return [skippedMissingSource6("commands", sourceCommandsRoot)];
|
|
30942
31196
|
}
|
|
30943
|
-
const sourceCommands = ts(
|
|
31197
|
+
const sourceCommands = ts(path45.join(sourceCommandsRoot, "*.md")).sort();
|
|
30944
31198
|
const commandsRoot = resolveTargetPath(paths.commands);
|
|
30945
31199
|
return sourceCommands.map((commandFile) => {
|
|
30946
31200
|
const { data, body } = parseCommandFile(commandFile);
|
|
@@ -30954,7 +31208,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
|
|
|
30954
31208
|
if (typeof data.model === "string") {
|
|
30955
31209
|
frontmatter.model = data.model;
|
|
30956
31210
|
}
|
|
30957
|
-
const relativeSource = `commands/${
|
|
31211
|
+
const relativeSource = `commands/${path45.basename(commandFile)}`;
|
|
30958
31212
|
const marker = formatProvenanceMarker(
|
|
30959
31213
|
"markdown",
|
|
30960
31214
|
relativeSource,
|
|
@@ -30970,9 +31224,9 @@ ${body.trimEnd()}
|
|
|
30970
31224
|
` : `${marker}
|
|
30971
31225
|
${body.trimEnd()}
|
|
30972
31226
|
`;
|
|
30973
|
-
const destination =
|
|
31227
|
+
const destination = path45.join(
|
|
30974
31228
|
commandsRoot,
|
|
30975
|
-
`${
|
|
31229
|
+
`${path45.basename(commandFile, ".md")}.md`
|
|
30976
31230
|
);
|
|
30977
31231
|
if (options.dryRun) {
|
|
30978
31232
|
logger.info(
|
|
@@ -31002,7 +31256,7 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
|
|
|
31002
31256
|
return syncSkillsSlot({
|
|
31003
31257
|
config,
|
|
31004
31258
|
sourceRoot,
|
|
31005
|
-
source:
|
|
31259
|
+
source: path45.resolve(sourceRoot, config.source.skills),
|
|
31006
31260
|
destination,
|
|
31007
31261
|
dryRun: options.dryRun,
|
|
31008
31262
|
logger,
|
|
@@ -31020,13 +31274,13 @@ function syncMcp6(config, sourceRoot, paths, mappings, options, lossReport, logg
|
|
|
31020
31274
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
31021
31275
|
const sourceLabel = mcpSourceLabel(config);
|
|
31022
31276
|
const destination = resolveTargetPath(paths.config_doc);
|
|
31023
|
-
if (!
|
|
31277
|
+
if (!fs45.existsSync(source)) {
|
|
31024
31278
|
if (!options.dryRun) {
|
|
31025
31279
|
syncConfigDoc(paths, {}, lossReport, {}, mappings);
|
|
31026
31280
|
}
|
|
31027
31281
|
return skippedMissingSource6("mcp", source);
|
|
31028
31282
|
}
|
|
31029
|
-
const sourceMcpJson = JSON.parse(
|
|
31283
|
+
const sourceMcpJson = JSON.parse(fs45.readFileSync(source, "utf8"));
|
|
31030
31284
|
const mcpJson = compileMcp(
|
|
31031
31285
|
sourceMcpJson,
|
|
31032
31286
|
"opencode",
|
|
@@ -31092,9 +31346,9 @@ function syncProviderBlock(mappings) {
|
|
|
31092
31346
|
function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
|
|
31093
31347
|
const destination = resolveTargetPath(paths.config_doc);
|
|
31094
31348
|
let existing = {};
|
|
31095
|
-
if (
|
|
31349
|
+
if (fs45.existsSync(destination)) {
|
|
31096
31350
|
try {
|
|
31097
|
-
existing = JSON.parse(
|
|
31351
|
+
existing = JSON.parse(fs45.readFileSync(destination, "utf8"));
|
|
31098
31352
|
} catch {
|
|
31099
31353
|
existing = {};
|
|
31100
31354
|
}
|
|
@@ -31107,6 +31361,13 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
|
|
|
31107
31361
|
...mcpEntries
|
|
31108
31362
|
}
|
|
31109
31363
|
};
|
|
31364
|
+
const instructionsRef = declaredInstructionsPath(paths);
|
|
31365
|
+
if (instructionsRef !== null) {
|
|
31366
|
+
config.instructions = withDeclaredInstructions(
|
|
31367
|
+
existing.instructions,
|
|
31368
|
+
instructionsRef
|
|
31369
|
+
);
|
|
31370
|
+
}
|
|
31110
31371
|
if (Object.keys(permissionMap).length > 0) {
|
|
31111
31372
|
config.permission = permissionMap;
|
|
31112
31373
|
}
|
|
@@ -31119,8 +31380,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
|
|
|
31119
31380
|
};
|
|
31120
31381
|
}
|
|
31121
31382
|
}
|
|
31122
|
-
ensureDir(
|
|
31123
|
-
|
|
31383
|
+
ensureDir(path45.dirname(destination));
|
|
31384
|
+
fs45.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
31124
31385
|
`);
|
|
31125
31386
|
}
|
|
31126
31387
|
function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
|
|
@@ -31134,14 +31395,14 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
|
|
|
31134
31395
|
if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
31135
31396
|
return { component, status: "conflict", path: destination };
|
|
31136
31397
|
}
|
|
31137
|
-
ensureDir(
|
|
31398
|
+
ensureDir(path45.dirname(destination));
|
|
31138
31399
|
const clearedLink = clearSymlinkAtDestination(destination);
|
|
31139
31400
|
if (clearedLink !== null) {
|
|
31140
31401
|
logger.verbose(
|
|
31141
31402
|
` ${destination}: replaced a symlink to ${clearedLink} with generated content`
|
|
31142
31403
|
);
|
|
31143
31404
|
}
|
|
31144
|
-
|
|
31405
|
+
fs45.writeFileSync(destination, content);
|
|
31145
31406
|
return { component, status: "success", path: destination };
|
|
31146
31407
|
}
|
|
31147
31408
|
function handleConflict6(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -31159,7 +31420,7 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
|
|
|
31159
31420
|
if (manifest && scopePath) {
|
|
31160
31421
|
backupFile(destination, manifest, scopePath);
|
|
31161
31422
|
writeManifest(scopePath, manifest);
|
|
31162
|
-
|
|
31423
|
+
fs45.rmSync(destination, { recursive: true, force: true });
|
|
31163
31424
|
} else {
|
|
31164
31425
|
const parked = parkConflictingPath(
|
|
31165
31426
|
destination,
|
|
@@ -31174,12 +31435,12 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
|
|
|
31174
31435
|
}
|
|
31175
31436
|
return true;
|
|
31176
31437
|
}
|
|
31177
|
-
|
|
31438
|
+
fs45.rmSync(destination, { recursive: true, force: true });
|
|
31178
31439
|
return true;
|
|
31179
31440
|
}
|
|
31180
31441
|
function isCompiledCurrent5(destination, expectedContent, _expectedHash) {
|
|
31181
31442
|
try {
|
|
31182
|
-
return
|
|
31443
|
+
return fs45.readFileSync(destination, "utf8") === expectedContent;
|
|
31183
31444
|
} catch {
|
|
31184
31445
|
return false;
|
|
31185
31446
|
}
|
|
@@ -31198,7 +31459,7 @@ function hashString5(value) {
|
|
|
31198
31459
|
return `sha256:${crypto10.createHash("sha256").update(value).digest("hex")}`;
|
|
31199
31460
|
}
|
|
31200
31461
|
function parseCommandFile(commandFile) {
|
|
31201
|
-
const content =
|
|
31462
|
+
const content = fs45.readFileSync(commandFile, "utf8");
|
|
31202
31463
|
if (!content.startsWith("---\n")) {
|
|
31203
31464
|
return { data: {}, body: content };
|
|
31204
31465
|
}
|
|
@@ -31218,7 +31479,7 @@ function parseCommandFile(commandFile) {
|
|
|
31218
31479
|
// src/commands/install.ts
|
|
31219
31480
|
function isBackupablePath(targetPath) {
|
|
31220
31481
|
try {
|
|
31221
|
-
const lstat =
|
|
31482
|
+
const lstat = fs46.lstatSync(targetPath);
|
|
31222
31483
|
return lstat.isSymbolicLink() || lstat.isFile() || lstat.isDirectory();
|
|
31223
31484
|
} catch {
|
|
31224
31485
|
return false;
|
|
@@ -31255,7 +31516,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31255
31516
|
);
|
|
31256
31517
|
}
|
|
31257
31518
|
const kitName = resolvedKitName ?? config.kit;
|
|
31258
|
-
const kitPath = kitPathOverride ?? (options.kitPath ?
|
|
31519
|
+
const kitPath = kitPathOverride ?? (options.kitPath ? path46.resolve(options.kitPath) : config.kitPath);
|
|
31259
31520
|
if (!kitName && !kitPath) {
|
|
31260
31521
|
logger.error(
|
|
31261
31522
|
"No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
|
|
@@ -31360,8 +31621,8 @@ async function runInstallCommand(options, logger) {
|
|
|
31360
31621
|
config: options.config,
|
|
31361
31622
|
scope
|
|
31362
31623
|
});
|
|
31363
|
-
const skillsSource =
|
|
31364
|
-
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") &&
|
|
31624
|
+
const skillsSource = path46.resolve(kitInfo.path, config.source.skills);
|
|
31625
|
+
const isPerSkillSkillsSlot = (f) => (f.tool === "claude-code" || f.tool === "copilot") && path46.basename(f.path) === "skills";
|
|
31365
31626
|
const foreignSkillsSlots = new Set(
|
|
31366
31627
|
assessResult.findings.filter(
|
|
31367
31628
|
(f) => isPerSkillSkillsSlot(f) && isForeignSkillsSlotSymlink(
|
|
@@ -31399,7 +31660,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31399
31660
|
let instructionsLabel;
|
|
31400
31661
|
try {
|
|
31401
31662
|
const resolved = resolveInstructionsSource(kitInfo.path, config);
|
|
31402
|
-
instructionsLabel = resolved ?
|
|
31663
|
+
instructionsLabel = resolved ? path46.relative(kitInfo.path, resolved.file) : "(none \u2014 no instructions file resolves in this kit)";
|
|
31403
31664
|
} catch (err) {
|
|
31404
31665
|
logger.error(
|
|
31405
31666
|
`[dry-run] ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -31427,7 +31688,7 @@ async function runInstallCommand(options, logger) {
|
|
|
31427
31688
|
}
|
|
31428
31689
|
}
|
|
31429
31690
|
logger.info(
|
|
31430
|
-
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${
|
|
31691
|
+
`[dry-run] Total: ${plannedTotal} destination(s); manifest at ${path46.join(scopePath, "manifest.json")}`
|
|
31431
31692
|
);
|
|
31432
31693
|
return;
|
|
31433
31694
|
}
|
|
@@ -31486,7 +31747,7 @@ ACCEPTED CONFLICTS (posture: ${posture}; ${replaceable.length} target(s)):`
|
|
|
31486
31747
|
logger.info(` - ${finding.path}`);
|
|
31487
31748
|
logger.info(` source: ${sources}`);
|
|
31488
31749
|
logger.info(
|
|
31489
|
-
` action: backup-and-replace${
|
|
31750
|
+
` action: backup-and-replace${fs46.lstatSync(finding.path).isDirectory() ? " (directory)" : ""}`
|
|
31490
31751
|
);
|
|
31491
31752
|
logger.info(` backup: ${backupLocation}`);
|
|
31492
31753
|
continue;
|
|
@@ -31594,11 +31855,28 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
31594
31855
|
installLossReport
|
|
31595
31856
|
);
|
|
31596
31857
|
}
|
|
31858
|
+
const instructionsByTarget = instructionsByActiveTarget(
|
|
31859
|
+
tools,
|
|
31860
|
+
scope,
|
|
31861
|
+
projectRoot,
|
|
31862
|
+
mappings
|
|
31863
|
+
);
|
|
31864
|
+
const rulesCoverage = measureRulesCoverage(
|
|
31865
|
+
tools,
|
|
31866
|
+
kitInfo.components.rules?.declared ?? [],
|
|
31867
|
+
scope,
|
|
31868
|
+
projectRoot,
|
|
31869
|
+
mappings,
|
|
31870
|
+
installLossReport,
|
|
31871
|
+
instructionsByTarget
|
|
31872
|
+
);
|
|
31597
31873
|
reportContestedInstructions(
|
|
31598
|
-
|
|
31874
|
+
instructionsByTarget,
|
|
31599
31875
|
(kitInfo.components.rules?.declared.length ?? 0) > 0,
|
|
31600
|
-
logger
|
|
31876
|
+
logger,
|
|
31877
|
+
missingRulesByTarget(rulesCoverage)
|
|
31601
31878
|
);
|
|
31879
|
+
reportRulesCoverage(rulesCoverage, logger);
|
|
31602
31880
|
for (const [relativePath, sourcePath] of collectAllFiles(kitInfo, config)) {
|
|
31603
31881
|
addFileToManifest(manifest, {
|
|
31604
31882
|
relativePath,
|
|
@@ -31610,20 +31888,20 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
31610
31888
|
writeManifest(scopePath, manifest);
|
|
31611
31889
|
logger.info(`
|
|
31612
31890
|
Installation complete: ${installedCount} files installed.`);
|
|
31613
|
-
logger.info(`Manifest written to ${
|
|
31891
|
+
logger.info(`Manifest written to ${path46.join(scopePath, "manifest.json")}`);
|
|
31614
31892
|
logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
|
|
31615
31893
|
logger.info(`Scope: ${scope}`);
|
|
31616
31894
|
logger.info(`Tools: ${tools.join(", ")}`);
|
|
31617
31895
|
reportHookRejections(
|
|
31618
31896
|
installLossReport,
|
|
31619
31897
|
tools,
|
|
31620
|
-
|
|
31898
|
+
path46.resolve(kitInfo.path, "hooks"),
|
|
31621
31899
|
kitInfo.components.hooks.declared
|
|
31622
31900
|
);
|
|
31623
31901
|
const hooksConflict = reportHooksSourceConflict(
|
|
31624
31902
|
installLossReport,
|
|
31625
31903
|
tools,
|
|
31626
|
-
|
|
31904
|
+
path46.resolve(kitInfo.path, "hooks"),
|
|
31627
31905
|
kitInfo.components.hooks.declared
|
|
31628
31906
|
);
|
|
31629
31907
|
if (hooksConflict) {
|
|
@@ -31929,7 +32207,8 @@ function installClaudeCodeAdapterSlots(args) {
|
|
|
31929
32207
|
profile,
|
|
31930
32208
|
outcome,
|
|
31931
32209
|
scope,
|
|
31932
|
-
projectRoot
|
|
32210
|
+
projectRoot,
|
|
32211
|
+
mappings
|
|
31933
32212
|
);
|
|
31934
32213
|
if (!key) {
|
|
31935
32214
|
continue;
|
|
@@ -31954,8 +32233,13 @@ function installClaudeCodeAdapterSlots(args) {
|
|
|
31954
32233
|
}
|
|
31955
32234
|
return count;
|
|
31956
32235
|
}
|
|
31957
|
-
function claudeCodeOutcomeToManifestKey(profile, outcome, scope, projectRoot) {
|
|
31958
|
-
const shared =
|
|
32236
|
+
function claudeCodeOutcomeToManifestKey(profile, outcome, scope, projectRoot, mappings) {
|
|
32237
|
+
const shared = sharedKeyForDestination(
|
|
32238
|
+
outcome.path,
|
|
32239
|
+
scope,
|
|
32240
|
+
projectRoot,
|
|
32241
|
+
mappings.platformPaths
|
|
32242
|
+
);
|
|
31959
32243
|
if (shared) {
|
|
31960
32244
|
return shared;
|
|
31961
32245
|
}
|
|
@@ -31982,7 +32266,7 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
31982
32266
|
return 0;
|
|
31983
32267
|
}
|
|
31984
32268
|
try {
|
|
31985
|
-
const stat =
|
|
32269
|
+
const stat = fs46.lstatSync(destination);
|
|
31986
32270
|
if (stat.isFile() && !stat.isSymbolicLink()) {
|
|
31987
32271
|
logger.warn(
|
|
31988
32272
|
`${destination}: a regular file occupies the skills slot \u2014 skipping skills. Move or remove it, then re-run install.`
|
|
@@ -32010,17 +32294,17 @@ function installClaudeCodeSkills(config, kitInfo, manifest, options, logger, sco
|
|
|
32010
32294
|
manifest,
|
|
32011
32295
|
scopePath
|
|
32012
32296
|
);
|
|
32013
|
-
const skillsSource =
|
|
32297
|
+
const skillsSource = path46.resolve(kitInfo.path, config.source.skills);
|
|
32014
32298
|
let count = 0;
|
|
32015
32299
|
for (const outcome of outcomes) {
|
|
32016
32300
|
if (outcome.status !== "success" && outcome.status !== "skipped-current") {
|
|
32017
32301
|
continue;
|
|
32018
32302
|
}
|
|
32019
|
-
const skillName =
|
|
32303
|
+
const skillName = path46.basename(outcome.path);
|
|
32020
32304
|
addArtifactToManifest(manifest, {
|
|
32021
32305
|
relativePath: `claude-code/skills/${skillName}`,
|
|
32022
32306
|
path: outcome.path,
|
|
32023
|
-
hash: describeArtifactState(outcome.path) ?? `dir:${
|
|
32307
|
+
hash: describeArtifactState(outcome.path) ?? `dir:${path46.join(skillsSource, skillName)}`,
|
|
32024
32308
|
origin: "tangyr-managed"
|
|
32025
32309
|
});
|
|
32026
32310
|
count++;
|
|
@@ -32034,10 +32318,10 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
32034
32318
|
logger.verbose(` skipped (operator choice): ${placement.destination}`);
|
|
32035
32319
|
continue;
|
|
32036
32320
|
}
|
|
32037
|
-
const destDir =
|
|
32038
|
-
|
|
32321
|
+
const destDir = path46.dirname(placement.destination);
|
|
32322
|
+
fs46.mkdirSync(destDir, { recursive: true });
|
|
32039
32323
|
if (placement.type === "symlink") {
|
|
32040
|
-
if (
|
|
32324
|
+
if (fs46.existsSync(placement.destination) || isSymlink2(placement.destination)) {
|
|
32041
32325
|
removeManagedPath(placement.destination);
|
|
32042
32326
|
}
|
|
32043
32327
|
createRelativeSymlink(
|
|
@@ -32054,7 +32338,7 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
32054
32338
|
` symlink: ${placement.source} \u2192 ${placement.destination}`
|
|
32055
32339
|
);
|
|
32056
32340
|
} else {
|
|
32057
|
-
|
|
32341
|
+
fs46.copyFileSync(placement.source, placement.destination);
|
|
32058
32342
|
logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
|
|
32059
32343
|
}
|
|
32060
32344
|
addArtifactToManifest(manifest, {
|
|
@@ -32304,7 +32588,12 @@ function countInstalledArtifacts(outcomes) {
|
|
|
32304
32588
|
).length;
|
|
32305
32589
|
}
|
|
32306
32590
|
function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", projectRoot) {
|
|
32307
|
-
const shared =
|
|
32591
|
+
const shared = sharedKeyForDestination(
|
|
32592
|
+
outcome.path,
|
|
32593
|
+
scope,
|
|
32594
|
+
projectRoot,
|
|
32595
|
+
mappings.platformPaths
|
|
32596
|
+
);
|
|
32308
32597
|
if (shared) {
|
|
32309
32598
|
return shared;
|
|
32310
32599
|
}
|
|
@@ -32346,11 +32635,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32346
32635
|
if (outcome.path === mcpFile2) {
|
|
32347
32636
|
return "cline/mcp.json";
|
|
32348
32637
|
}
|
|
32349
|
-
if (outcome.path.startsWith(`${workflowsRoot}${
|
|
32350
|
-
return `cline/workflows/${
|
|
32638
|
+
if (outcome.path.startsWith(`${workflowsRoot}${path46.sep}`)) {
|
|
32639
|
+
return `cline/workflows/${path46.basename(outcome.path)}`;
|
|
32351
32640
|
}
|
|
32352
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32353
|
-
return `cline/rules/${
|
|
32641
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path46.sep}`)) {
|
|
32642
|
+
return `cline/rules/${path46.basename(outcome.path)}`;
|
|
32354
32643
|
}
|
|
32355
32644
|
return null;
|
|
32356
32645
|
}
|
|
@@ -32386,14 +32675,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32386
32675
|
if (outcome.path === permissionsFile) {
|
|
32387
32676
|
return "cursor/permissions.json";
|
|
32388
32677
|
}
|
|
32389
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32390
|
-
return `cursor/agents/${
|
|
32678
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path46.sep}`)) {
|
|
32679
|
+
return `cursor/agents/${path46.basename(outcome.path)}`;
|
|
32391
32680
|
}
|
|
32392
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
32393
|
-
return `cursor/rules/${
|
|
32681
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path46.sep}`)) {
|
|
32682
|
+
return `cursor/rules/${path46.basename(outcome.path)}`;
|
|
32394
32683
|
}
|
|
32395
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
32396
|
-
const rel =
|
|
32684
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path46.sep}`)) {
|
|
32685
|
+
const rel = path46.relative(skillsRoot2, outcome.path);
|
|
32397
32686
|
return `cursor/skills/${rel}`;
|
|
32398
32687
|
}
|
|
32399
32688
|
return null;
|
|
@@ -32419,14 +32708,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32419
32708
|
if (outcome.path === skillsSharedRoot) {
|
|
32420
32709
|
return "opencode/skills_shared";
|
|
32421
32710
|
}
|
|
32422
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32423
|
-
return `opencode/agents/${
|
|
32711
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path46.sep}`)) {
|
|
32712
|
+
return `opencode/agents/${path46.basename(outcome.path)}`;
|
|
32424
32713
|
}
|
|
32425
|
-
if (outcome.path.startsWith(`${commandsRoot}${
|
|
32426
|
-
return `opencode/commands/${
|
|
32714
|
+
if (outcome.path.startsWith(`${commandsRoot}${path46.sep}`)) {
|
|
32715
|
+
return `opencode/commands/${path46.basename(outcome.path)}`;
|
|
32427
32716
|
}
|
|
32428
32717
|
if (outcome.path === configDocFile) {
|
|
32429
|
-
return `opencode/${
|
|
32718
|
+
return `opencode/${path46.basename(outcome.path)}`;
|
|
32430
32719
|
}
|
|
32431
32720
|
return null;
|
|
32432
32721
|
}
|
|
@@ -32443,29 +32732,29 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32443
32732
|
const hooksRoot = resolveTargetPath(copilot.hooks);
|
|
32444
32733
|
const mcpFile2 = resolveTargetPath(copilot.mcp_shared_file);
|
|
32445
32734
|
const instructionsMirror = copilot.instructions !== null ? resolveTargetPath(copilot.instructions) : null;
|
|
32446
|
-
if (copilot.rules !== null && outcome.path.startsWith(`${resolveTargetPath(copilot.rules)}${
|
|
32447
|
-
return `copilot/rules/${
|
|
32735
|
+
if (copilot.rules !== null && outcome.path.startsWith(`${resolveTargetPath(copilot.rules)}${path46.sep}`)) {
|
|
32736
|
+
return `copilot/rules/${path46.relative(resolveTargetPath(copilot.rules), outcome.path)}`;
|
|
32448
32737
|
}
|
|
32449
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
32450
|
-
return `copilot/skills/${
|
|
32738
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path46.sep}`)) {
|
|
32739
|
+
return `copilot/skills/${path46.relative(skillsRoot2, outcome.path)}`;
|
|
32451
32740
|
}
|
|
32452
32741
|
if (outcome.path === skillsRoot2) {
|
|
32453
32742
|
return "copilot/skills";
|
|
32454
32743
|
}
|
|
32455
32744
|
if (instructionsMirror !== null && outcome.path === instructionsMirror) {
|
|
32456
|
-
return `copilot/${
|
|
32745
|
+
return `copilot/${path46.basename(outcome.path)}`;
|
|
32457
32746
|
}
|
|
32458
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
32459
|
-
return `copilot/agents/${
|
|
32747
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path46.sep}`)) {
|
|
32748
|
+
return `copilot/agents/${path46.basename(outcome.path)}`;
|
|
32460
32749
|
}
|
|
32461
|
-
if (outcome.path.startsWith(`${promptsRoot}${
|
|
32462
|
-
return `copilot/prompts/${
|
|
32750
|
+
if (outcome.path.startsWith(`${promptsRoot}${path46.sep}`)) {
|
|
32751
|
+
return `copilot/prompts/${path46.basename(outcome.path)}`;
|
|
32463
32752
|
}
|
|
32464
|
-
if (outcome.path.startsWith(`${hooksRoot}${
|
|
32465
|
-
return `copilot/hooks/${
|
|
32753
|
+
if (outcome.path.startsWith(`${hooksRoot}${path46.sep}`)) {
|
|
32754
|
+
return `copilot/hooks/${path46.basename(outcome.path)}`;
|
|
32466
32755
|
}
|
|
32467
32756
|
if (outcome.path === mcpFile2) {
|
|
32468
|
-
return `copilot/${
|
|
32757
|
+
return `copilot/${path46.basename(outcome.path)}`;
|
|
32469
32758
|
}
|
|
32470
32759
|
return null;
|
|
32471
32760
|
}
|
|
@@ -32482,17 +32771,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
32482
32771
|
if (outcome.path === skillsRoot) {
|
|
32483
32772
|
return "codex/skills";
|
|
32484
32773
|
}
|
|
32485
|
-
if (outcome.path.startsWith(`${agentsRoot}${
|
|
32486
|
-
return `codex/agents/${
|
|
32774
|
+
if (outcome.path.startsWith(`${agentsRoot}${path46.sep}`)) {
|
|
32775
|
+
return `codex/agents/${path46.basename(outcome.path)}`;
|
|
32487
32776
|
}
|
|
32488
|
-
if (outcome.path.startsWith(`${rulesRoot}${
|
|
32489
|
-
return `codex/rules/${
|
|
32777
|
+
if (outcome.path.startsWith(`${rulesRoot}${path46.sep}`)) {
|
|
32778
|
+
return `codex/rules/${path46.basename(outcome.path)}`;
|
|
32490
32779
|
}
|
|
32491
32780
|
if (outcome.path === hooksFile) {
|
|
32492
|
-
return `codex/${
|
|
32781
|
+
return `codex/${path46.basename(outcome.path)}`;
|
|
32493
32782
|
}
|
|
32494
32783
|
if (outcome.path === mcpFile) {
|
|
32495
|
-
return `codex/${
|
|
32784
|
+
return `codex/${path46.basename(outcome.path)}`;
|
|
32496
32785
|
}
|
|
32497
32786
|
return null;
|
|
32498
32787
|
}
|
|
@@ -32561,8 +32850,8 @@ function getClaudeCodePlacements(kitInfo, config, scope = "global", projectRoot,
|
|
|
32561
32850
|
rules: resolvedPaths.rules
|
|
32562
32851
|
};
|
|
32563
32852
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32564
|
-
const componentDir =
|
|
32565
|
-
if (
|
|
32853
|
+
const componentDir = path46.join(kitInfo.path, component);
|
|
32854
|
+
if (fs46.existsSync(componentDir) && fs46.statSync(componentDir).isDirectory()) {
|
|
32566
32855
|
placements.push({
|
|
32567
32856
|
source: componentDir,
|
|
32568
32857
|
destination: targetPath,
|
|
@@ -32592,8 +32881,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile, config) {
|
|
|
32592
32881
|
rules: profile.rules
|
|
32593
32882
|
};
|
|
32594
32883
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
32595
|
-
const componentDir =
|
|
32596
|
-
if (
|
|
32884
|
+
const componentDir = path46.join(kitInfo.path, component);
|
|
32885
|
+
if (fs46.existsSync(componentDir) && fs46.statSync(componentDir).isDirectory()) {
|
|
32597
32886
|
placements.push({
|
|
32598
32887
|
source: componentDir,
|
|
32599
32888
|
destination: targetPath,
|
|
@@ -32609,7 +32898,7 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32609
32898
|
const files = /* @__PURE__ */ new Map();
|
|
32610
32899
|
const entrypoint = resolveInstructionsSource(kitInfo.path, config);
|
|
32611
32900
|
if (entrypoint) {
|
|
32612
|
-
files.set(
|
|
32901
|
+
files.set(path46.basename(entrypoint.file), entrypoint.file);
|
|
32613
32902
|
}
|
|
32614
32903
|
for (const [component, reconciliation] of Object.entries(
|
|
32615
32904
|
kitInfo.components
|
|
@@ -32618,22 +32907,22 @@ function collectAllFiles(kitInfo, config) {
|
|
|
32618
32907
|
const missingSet = new Set(reconciliation.missing);
|
|
32619
32908
|
for (const entry of reconciliation.declared) {
|
|
32620
32909
|
if (missingSet.has(entry)) continue;
|
|
32621
|
-
const relPath = isSkills ?
|
|
32622
|
-
files.set(relPath,
|
|
32910
|
+
const relPath = isSkills ? path46.join(component, entry) : path46.join(component, `${entry}.md`);
|
|
32911
|
+
files.set(relPath, path46.join(kitInfo.path, relPath));
|
|
32623
32912
|
}
|
|
32624
32913
|
}
|
|
32625
32914
|
return files;
|
|
32626
32915
|
}
|
|
32627
32916
|
function readLinkTarget(p) {
|
|
32628
32917
|
try {
|
|
32629
|
-
return
|
|
32918
|
+
return fs46.readlinkSync(p);
|
|
32630
32919
|
} catch {
|
|
32631
32920
|
return null;
|
|
32632
32921
|
}
|
|
32633
32922
|
}
|
|
32634
32923
|
function isSymlink2(p) {
|
|
32635
32924
|
try {
|
|
32636
|
-
return
|
|
32925
|
+
return fs46.lstatSync(p).isSymbolicLink();
|
|
32637
32926
|
} catch {
|
|
32638
32927
|
return false;
|
|
32639
32928
|
}
|
|
@@ -32652,10 +32941,10 @@ function skillsSubPathKey(tool, outcomePath, mappings, scope, projectRoot) {
|
|
|
32652
32941
|
continue;
|
|
32653
32942
|
}
|
|
32654
32943
|
const root = resolveTargetPath(slot);
|
|
32655
|
-
if (!outcomePath.startsWith(`${root}${
|
|
32944
|
+
if (!outcomePath.startsWith(`${root}${path46.sep}`)) {
|
|
32656
32945
|
continue;
|
|
32657
32946
|
}
|
|
32658
|
-
const inside =
|
|
32947
|
+
const inside = path46.relative(root, outcomePath).split(path46.sep).join("/");
|
|
32659
32948
|
return `${tool}/skills/${inside}`;
|
|
32660
32949
|
}
|
|
32661
32950
|
return null;
|
|
@@ -32700,14 +32989,14 @@ async function runKitUpdateCommand(options, logger) {
|
|
|
32700
32989
|
}
|
|
32701
32990
|
|
|
32702
32991
|
// src/commands/list.ts
|
|
32703
|
-
import
|
|
32992
|
+
import path47 from "path";
|
|
32704
32993
|
function runListCommand(options, logger) {
|
|
32705
32994
|
let searchPaths = [];
|
|
32706
|
-
let directKitPath = options.kitPath ?
|
|
32995
|
+
let directKitPath = options.kitPath ? path47.resolve(options.kitPath) : void 0;
|
|
32707
32996
|
try {
|
|
32708
32997
|
const { config, configDir } = resolveConfig(options.config);
|
|
32709
32998
|
searchPaths = config.kitSearchPaths ?? [
|
|
32710
|
-
|
|
32999
|
+
path47.join(configDir, "operating-kits")
|
|
32711
33000
|
];
|
|
32712
33001
|
directKitPath = directKitPath ?? config.kitPath;
|
|
32713
33002
|
} catch (err) {
|
|
@@ -32782,7 +33071,7 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32782
33071
|
return kits;
|
|
32783
33072
|
}
|
|
32784
33073
|
const directKit = loadKit(directKitPath);
|
|
32785
|
-
if (kits.some((kit) =>
|
|
33074
|
+
if (kits.some((kit) => path47.resolve(kit.path) === directKit.path)) {
|
|
32786
33075
|
return kits;
|
|
32787
33076
|
}
|
|
32788
33077
|
return [...kits, directKit];
|
|
@@ -32790,8 +33079,8 @@ function withDirectKit(kits, directKitPath) {
|
|
|
32790
33079
|
|
|
32791
33080
|
// src/commands/probe.ts
|
|
32792
33081
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
32793
|
-
import
|
|
32794
|
-
import
|
|
33082
|
+
import fs47 from "fs";
|
|
33083
|
+
import path48 from "path";
|
|
32795
33084
|
function runProbeCommand(options, logger) {
|
|
32796
33085
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32797
33086
|
options,
|
|
@@ -32819,7 +33108,7 @@ function runProbeCommand(options, logger) {
|
|
|
32819
33108
|
toProbeRow(
|
|
32820
33109
|
target,
|
|
32821
33110
|
key,
|
|
32822
|
-
scope === "project" ?
|
|
33111
|
+
scope === "project" ? path48.resolve(projectRoot ?? process.cwd(), rawPath) : rawPath
|
|
32823
33112
|
)
|
|
32824
33113
|
);
|
|
32825
33114
|
}
|
|
@@ -32841,7 +33130,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32841
33130
|
const resolved = resolveTargetPath(rawPath);
|
|
32842
33131
|
let accessible = false;
|
|
32843
33132
|
try {
|
|
32844
|
-
|
|
33133
|
+
fs47.accessSync(resolved);
|
|
32845
33134
|
accessible = true;
|
|
32846
33135
|
} catch {
|
|
32847
33136
|
accessible = false;
|
|
@@ -32850,7 +33139,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
32850
33139
|
target,
|
|
32851
33140
|
key,
|
|
32852
33141
|
path: resolved,
|
|
32853
|
-
exists:
|
|
33142
|
+
exists: fs47.existsSync(resolved),
|
|
32854
33143
|
accessible
|
|
32855
33144
|
};
|
|
32856
33145
|
}
|
|
@@ -32868,7 +33157,7 @@ function codexRuntimeProbeRows() {
|
|
|
32868
33157
|
["binary_snap", "/snap/bin/codex"],
|
|
32869
33158
|
["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
|
|
32870
33159
|
]) {
|
|
32871
|
-
if (
|
|
33160
|
+
if (fs47.existsSync(candidatePath)) {
|
|
32872
33161
|
rows.push(toProbeRow("codex", key, candidatePath));
|
|
32873
33162
|
}
|
|
32874
33163
|
}
|
|
@@ -32884,8 +33173,8 @@ function commandProbeRows(target, key, command, args) {
|
|
|
32884
33173
|
|
|
32885
33174
|
// src/commands/status.ts
|
|
32886
33175
|
import crypto11 from "crypto";
|
|
32887
|
-
import
|
|
32888
|
-
import
|
|
33176
|
+
import fs48 from "fs";
|
|
33177
|
+
import path49 from "path";
|
|
32889
33178
|
function runStatusCommand(options, logger) {
|
|
32890
33179
|
const { config, configDir, configSource, sourceRoot } = resolveRuntime(
|
|
32891
33180
|
options,
|
|
@@ -32991,11 +33280,11 @@ function classifyTargetRows(target, config, sourceRoot, configDir, scope, projec
|
|
|
32991
33280
|
}
|
|
32992
33281
|
}
|
|
32993
33282
|
function sourceMarkdownFiles(sourceRoot, componentPath) {
|
|
32994
|
-
const root =
|
|
32995
|
-
if (!
|
|
33283
|
+
const root = path49.join(sourceRoot, componentPath);
|
|
33284
|
+
if (!fs48.existsSync(root)) {
|
|
32996
33285
|
return [];
|
|
32997
33286
|
}
|
|
32998
|
-
return ts(
|
|
33287
|
+
return ts(path49.join(root, "*.md")).sort();
|
|
32999
33288
|
}
|
|
33000
33289
|
function notRepresentableRow(component, detail) {
|
|
33001
33290
|
return {
|
|
@@ -33006,11 +33295,11 @@ function notRepresentableRow(component, detail) {
|
|
|
33006
33295
|
};
|
|
33007
33296
|
}
|
|
33008
33297
|
function readTargetJson(filePath) {
|
|
33009
|
-
if (!
|
|
33298
|
+
if (!fs48.existsSync(filePath)) {
|
|
33010
33299
|
return { kind: "missing" };
|
|
33011
33300
|
}
|
|
33012
33301
|
try {
|
|
33013
|
-
const parsed = JSON.parse(
|
|
33302
|
+
const parsed = JSON.parse(fs48.readFileSync(filePath, "utf8"));
|
|
33014
33303
|
return { kind: "object", value: isRecord(parsed) ? parsed : {} };
|
|
33015
33304
|
} catch (err) {
|
|
33016
33305
|
return {
|
|
@@ -33099,7 +33388,7 @@ function classifyInstructions(filePath, target, expectedHash, config, sourceRoot
|
|
|
33099
33388
|
}
|
|
33100
33389
|
function compiledMcpDocument(config, sourceRoot, target) {
|
|
33101
33390
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
33102
|
-
if (!
|
|
33391
|
+
if (!fs48.existsSync(source)) {
|
|
33103
33392
|
return {};
|
|
33104
33393
|
}
|
|
33105
33394
|
const compiled = compileMcp(
|
|
@@ -33112,7 +33401,7 @@ function compiledMcpDocument(config, sourceRoot, target) {
|
|
|
33112
33401
|
return isRecord(parsed) ? parsed : {};
|
|
33113
33402
|
}
|
|
33114
33403
|
function classifyMcpDocument(config, sourceRoot, target, filePath) {
|
|
33115
|
-
if (!
|
|
33404
|
+
if (!fs48.existsSync(resolveMcpSourceFile(sourceRoot, config))) {
|
|
33116
33405
|
return notConfiguredRow("mcp", filePath);
|
|
33117
33406
|
}
|
|
33118
33407
|
return classifyJsonDocument(
|
|
@@ -33142,12 +33431,12 @@ function classifyOpenCodeFiles(config, sourceRoot, configDir, scope, projectRoot
|
|
|
33142
33431
|
const rows = [];
|
|
33143
33432
|
const instructionsSource = instructionsSourcePath(sourceRoot, config);
|
|
33144
33433
|
const rules = compileRules(
|
|
33145
|
-
|
|
33434
|
+
path49.join(sourceRoot, config.source.rules),
|
|
33146
33435
|
"opencode",
|
|
33147
33436
|
mappings,
|
|
33148
33437
|
createLossReport()
|
|
33149
33438
|
);
|
|
33150
|
-
const baseInstructions =
|
|
33439
|
+
const baseInstructions = fs48.existsSync(instructionsSource) ? fs48.readFileSync(instructionsSource, "utf8").trim() : "";
|
|
33151
33440
|
const composedInstructions = rules.agentsAppendix ? `${baseInstructions}
|
|
33152
33441
|
|
|
33153
33442
|
--- tangyr managed rules ---
|
|
@@ -33169,10 +33458,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
33169
33458
|
)) {
|
|
33170
33459
|
rows.push(
|
|
33171
33460
|
classifyCompiledFile(
|
|
33172
|
-
`agents/${
|
|
33173
|
-
|
|
33461
|
+
`agents/${path49.basename(agentFile, ".md")}`,
|
|
33462
|
+
path49.join(
|
|
33174
33463
|
resolveTargetPath(paths.agents),
|
|
33175
|
-
`${
|
|
33464
|
+
`${path49.basename(agentFile, ".md")}.md`
|
|
33176
33465
|
),
|
|
33177
33466
|
"opencode",
|
|
33178
33467
|
computeSourceHash(agentFile),
|
|
@@ -33187,10 +33476,10 @@ ${rules.agentsAppendix}`.trim() : baseInstructions;
|
|
|
33187
33476
|
)) {
|
|
33188
33477
|
rows.push(
|
|
33189
33478
|
classifyCompiledFile(
|
|
33190
|
-
`commands/${
|
|
33191
|
-
|
|
33479
|
+
`commands/${path49.basename(commandFile, ".md")}`,
|
|
33480
|
+
path49.join(
|
|
33192
33481
|
resolveTargetPath(paths.commands),
|
|
33193
|
-
`${
|
|
33482
|
+
`${path49.basename(commandFile, ".md")}.md`
|
|
33194
33483
|
),
|
|
33195
33484
|
"opencode",
|
|
33196
33485
|
computeSourceHash(commandFile),
|
|
@@ -33272,10 +33561,10 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33272
33561
|
)) {
|
|
33273
33562
|
rows.push(
|
|
33274
33563
|
classifyCompiledFile(
|
|
33275
|
-
`agents/${
|
|
33276
|
-
|
|
33564
|
+
`agents/${path49.basename(agentFile, ".md")}`,
|
|
33565
|
+
path49.join(
|
|
33277
33566
|
resolveTargetPath(paths.agents),
|
|
33278
|
-
`${
|
|
33567
|
+
`${path49.basename(agentFile, ".md")}.md`
|
|
33279
33568
|
),
|
|
33280
33569
|
"cursor",
|
|
33281
33570
|
computeSourceHash(agentFile),
|
|
@@ -33292,7 +33581,7 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33292
33581
|
rows.push(
|
|
33293
33582
|
classifyCompiledFile(
|
|
33294
33583
|
`rules/${ruleFile.name}`,
|
|
33295
|
-
|
|
33584
|
+
path49.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
33296
33585
|
"cursor",
|
|
33297
33586
|
void 0,
|
|
33298
33587
|
config,
|
|
@@ -33306,11 +33595,11 @@ function classifyCursorFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33306
33595
|
sourceRoot,
|
|
33307
33596
|
config.source.commands
|
|
33308
33597
|
)) {
|
|
33309
|
-
const baseName =
|
|
33598
|
+
const baseName = path49.basename(commandFile, ".md");
|
|
33310
33599
|
rows.push(
|
|
33311
33600
|
classifyCompiledFile(
|
|
33312
33601
|
`commands/${baseName}`,
|
|
33313
|
-
|
|
33602
|
+
path49.join(resolveTargetPath(paths.skills), baseName, "SKILL.md"),
|
|
33314
33603
|
"cursor",
|
|
33315
33604
|
computeSourceHash(commandFile),
|
|
33316
33605
|
config,
|
|
@@ -33393,7 +33682,7 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33393
33682
|
rows.push(
|
|
33394
33683
|
classifyCompiledFile(
|
|
33395
33684
|
`rules/${ruleFile.name}`,
|
|
33396
|
-
|
|
33685
|
+
path49.join(resolveTargetPath(paths.rules), ruleFile.name),
|
|
33397
33686
|
"cline",
|
|
33398
33687
|
void 0,
|
|
33399
33688
|
config,
|
|
@@ -33409,10 +33698,10 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33409
33698
|
)) {
|
|
33410
33699
|
rows.push(
|
|
33411
33700
|
classifyCompiledFile(
|
|
33412
|
-
`commands/${
|
|
33413
|
-
|
|
33701
|
+
`commands/${path49.basename(commandFile, ".md")}`,
|
|
33702
|
+
path49.join(
|
|
33414
33703
|
resolveTargetPath(paths.workflows),
|
|
33415
|
-
|
|
33704
|
+
path49.basename(commandFile)
|
|
33416
33705
|
),
|
|
33417
33706
|
"cline",
|
|
33418
33707
|
computeSourceHash(commandFile),
|
|
@@ -33453,14 +33742,14 @@ function classifyClineFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33453
33742
|
return rows;
|
|
33454
33743
|
}
|
|
33455
33744
|
function compileRulesFiles(config, sourceRoot, target, mappings) {
|
|
33456
|
-
const rulesSource =
|
|
33457
|
-
if (!
|
|
33745
|
+
const rulesSource = path49.join(sourceRoot, config.source.rules);
|
|
33746
|
+
if (!fs48.existsSync(rulesSource)) {
|
|
33458
33747
|
return [];
|
|
33459
33748
|
}
|
|
33460
33749
|
return compileRules(rulesSource, target, mappings, createLossReport()).dotRulesFiles;
|
|
33461
33750
|
}
|
|
33462
33751
|
function classifyDirectoryPresence(component, dirPath) {
|
|
33463
|
-
const present =
|
|
33752
|
+
const present = fs48.existsSync(dirPath) && fs48.statSync(dirPath).isDirectory();
|
|
33464
33753
|
return {
|
|
33465
33754
|
component,
|
|
33466
33755
|
className: present ? "current" : "missing",
|
|
@@ -33479,7 +33768,7 @@ function slotsForScope2(scopeMap, scope, projectRoot) {
|
|
|
33479
33768
|
const root = projectRoot ?? process.cwd();
|
|
33480
33769
|
const resolved = {};
|
|
33481
33770
|
for (const [slot, value] of Object.entries(projectSlots)) {
|
|
33482
|
-
resolved[slot] = typeof value === "string" ?
|
|
33771
|
+
resolved[slot] = typeof value === "string" ? path49.resolve(root, value) : value;
|
|
33483
33772
|
}
|
|
33484
33773
|
return resolved;
|
|
33485
33774
|
}
|
|
@@ -33499,21 +33788,21 @@ function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
|
33499
33788
|
rules: paths.rules
|
|
33500
33789
|
};
|
|
33501
33790
|
const rules = compileRules(
|
|
33502
|
-
|
|
33791
|
+
path49.join(sourceRoot, config.source.rules),
|
|
33503
33792
|
"codex",
|
|
33504
33793
|
mappings,
|
|
33505
33794
|
createLossReport()
|
|
33506
33795
|
);
|
|
33507
|
-
const instructionsSource =
|
|
33796
|
+
const instructionsSource = fs48.readFileSync(instructionsSourcePath(sourceRoot, config), "utf8").trim();
|
|
33508
33797
|
const composedInstructions = `${instructionsSource}
|
|
33509
33798
|
|
|
33510
33799
|
--- tangyr managed rules ---
|
|
33511
33800
|
${rules.agentsAppendix}`.trim();
|
|
33512
33801
|
const agentFiles = ts(
|
|
33513
|
-
|
|
33802
|
+
path49.join(sourceRoot, config.source.agents, "*.md")
|
|
33514
33803
|
).sort();
|
|
33515
33804
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33516
|
-
const mcpSource =
|
|
33805
|
+
const mcpSource = path49.join(sourceRoot, config.source.mcp);
|
|
33517
33806
|
const ruleRows = rules.dotRulesFiles.length === 0 ? [
|
|
33518
33807
|
{
|
|
33519
33808
|
component: "rules",
|
|
@@ -33524,7 +33813,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33524
33813
|
] : rules.dotRulesFiles.map(
|
|
33525
33814
|
(ruleFile) => classifyCompiledFile(
|
|
33526
33815
|
`rules/${ruleFile.name}`,
|
|
33527
|
-
|
|
33816
|
+
path49.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
|
|
33528
33817
|
"codex",
|
|
33529
33818
|
void 0,
|
|
33530
33819
|
config,
|
|
@@ -33542,10 +33831,10 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33542
33831
|
),
|
|
33543
33832
|
...agentFiles.map(
|
|
33544
33833
|
(agentFile) => classifyCompiledFile(
|
|
33545
|
-
`agents/${
|
|
33546
|
-
|
|
33834
|
+
`agents/${path49.basename(agentFile, ".md")}`,
|
|
33835
|
+
path49.join(
|
|
33547
33836
|
resolveTargetPath(codexPaths.agents),
|
|
33548
|
-
`${
|
|
33837
|
+
`${path49.basename(agentFile, ".md")}.toml`
|
|
33549
33838
|
),
|
|
33550
33839
|
"codex",
|
|
33551
33840
|
computeSourceHash(agentFile),
|
|
@@ -33573,7 +33862,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
33573
33862
|
"hooks",
|
|
33574
33863
|
resolveTargetPath(codexPaths.hooksSharedFile)
|
|
33575
33864
|
),
|
|
33576
|
-
|
|
33865
|
+
fs48.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33577
33866
|
"mcp",
|
|
33578
33867
|
resolveTargetPath(codexPaths.mcpSharedFile),
|
|
33579
33868
|
"codex",
|
|
@@ -33639,20 +33928,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33639
33928
|
mcpSharedFile: paths.mcp_shared_file
|
|
33640
33929
|
};
|
|
33641
33930
|
const agentFiles = ts(
|
|
33642
|
-
|
|
33931
|
+
path49.join(sourceRoot, config.source.agents, "*.md")
|
|
33643
33932
|
).sort();
|
|
33644
33933
|
const commandFiles = ts(
|
|
33645
|
-
|
|
33934
|
+
path49.join(sourceRoot, config.source.commands, "*.md")
|
|
33646
33935
|
).sort();
|
|
33647
33936
|
const hooksPresent = hooksSourceExists(sourceRoot, config);
|
|
33648
|
-
const mcpSource =
|
|
33937
|
+
const mcpSource = path49.join(sourceRoot, config.source.mcp);
|
|
33649
33938
|
return [
|
|
33650
33939
|
...agentFiles.map(
|
|
33651
33940
|
(agentFile) => classifyCompiledFile(
|
|
33652
|
-
`agents/${
|
|
33653
|
-
|
|
33941
|
+
`agents/${path49.basename(agentFile, ".md")}`,
|
|
33942
|
+
path49.join(
|
|
33654
33943
|
resolveTargetPath(copilotPaths.agents),
|
|
33655
|
-
`${
|
|
33944
|
+
`${path49.basename(agentFile, ".md")}.agent.md`
|
|
33656
33945
|
),
|
|
33657
33946
|
"copilot",
|
|
33658
33947
|
computeSourceHash(agentFile),
|
|
@@ -33669,10 +33958,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33669
33958
|
),
|
|
33670
33959
|
...commandFiles.map(
|
|
33671
33960
|
(commandFile) => classifyCompiledFile(
|
|
33672
|
-
`commands/${
|
|
33673
|
-
|
|
33961
|
+
`commands/${path49.basename(commandFile, ".md")}`,
|
|
33962
|
+
path49.join(
|
|
33674
33963
|
resolveTargetPath(copilotPaths.prompts),
|
|
33675
|
-
`${
|
|
33964
|
+
`${path49.basename(commandFile, ".md")}.prompt.md`
|
|
33676
33965
|
),
|
|
33677
33966
|
"copilot",
|
|
33678
33967
|
computeSourceHash(commandFile),
|
|
@@ -33691,19 +33980,19 @@ function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot)
|
|
|
33691
33980
|
sourceRoot
|
|
33692
33981
|
),
|
|
33693
33982
|
hooksPresent ? classifyCompiledHooksByProvenance(
|
|
33694
|
-
|
|
33983
|
+
path49.join(
|
|
33695
33984
|
resolveTargetPath(copilotPaths.hooks),
|
|
33696
33985
|
"tangyr-managed.json"
|
|
33697
33986
|
),
|
|
33698
33987
|
"copilot"
|
|
33699
33988
|
) : notConfiguredRow(
|
|
33700
33989
|
"hooks",
|
|
33701
|
-
|
|
33990
|
+
path49.join(
|
|
33702
33991
|
resolveTargetPath(copilotPaths.hooks),
|
|
33703
33992
|
"tangyr-managed.json"
|
|
33704
33993
|
)
|
|
33705
33994
|
),
|
|
33706
|
-
|
|
33995
|
+
fs48.existsSync(mcpSource) ? classifyCompiledFile(
|
|
33707
33996
|
"mcp",
|
|
33708
33997
|
resolveTargetPath(copilotPaths.mcpSharedFile),
|
|
33709
33998
|
"copilot",
|
|
@@ -33723,7 +34012,7 @@ function notConfiguredRow(component, filePath) {
|
|
|
33723
34012
|
}
|
|
33724
34013
|
function classifyDirectArtifact(artifact, config, sourceRoot) {
|
|
33725
34014
|
const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
|
|
33726
|
-
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ?
|
|
34015
|
+
const sourcePath = artifact.sourceKey === "instructions" ? instructionsSourcePath(sourceRoot, config) : artifact.sourceKey ? path49.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
|
|
33727
34016
|
if (artifact.sourceKey === "skills" && artifactClass === "unmanaged-conflict") {
|
|
33728
34017
|
const perSkill = classifyPerSkillSlot(artifact.path, sourceRoot);
|
|
33729
34018
|
if (perSkill) {
|
|
@@ -33819,11 +34108,11 @@ function classifyClaudeCodeRows(sourceRoot, config, configDir, scope, projectRoo
|
|
|
33819
34108
|
function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
33820
34109
|
let entries;
|
|
33821
34110
|
try {
|
|
33822
|
-
const stat =
|
|
34111
|
+
const stat = fs48.lstatSync(slotPath);
|
|
33823
34112
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
33824
34113
|
return null;
|
|
33825
34114
|
}
|
|
33826
|
-
entries =
|
|
34115
|
+
entries = fs48.readdirSync(slotPath, { withFileTypes: true });
|
|
33827
34116
|
} catch {
|
|
33828
34117
|
return null;
|
|
33829
34118
|
}
|
|
@@ -33835,7 +34124,7 @@ function classifyPerSkillSlot(slotPath, sourceRoot) {
|
|
|
33835
34124
|
return null;
|
|
33836
34125
|
}
|
|
33837
34126
|
const ours = links.filter(
|
|
33838
|
-
(entry) => isOurSymlink(
|
|
34127
|
+
(entry) => isOurSymlink(path49.join(slotPath, entry.name), sourceRoot)
|
|
33839
34128
|
);
|
|
33840
34129
|
if (ours.length === 0) {
|
|
33841
34130
|
return null;
|
|
@@ -33847,9 +34136,9 @@ function classifyClaudeSharedFiles(config, sourceRoot, settingsPath, claudeJsonP
|
|
|
33847
34136
|
classifyHooks(settingsPath),
|
|
33848
34137
|
classifySettings(
|
|
33849
34138
|
settingsPath,
|
|
33850
|
-
|
|
34139
|
+
path49.resolve(sourceRoot, config.source.settings)
|
|
33851
34140
|
),
|
|
33852
|
-
classifyMcp(claudeJsonPath,
|
|
34141
|
+
classifyMcp(claudeJsonPath, path49.resolve(sourceRoot, config.source.mcp))
|
|
33853
34142
|
];
|
|
33854
34143
|
}
|
|
33855
34144
|
function claudeSharedFileRows(config, sourceRoot, configDir, scope, projectRoot) {
|
|
@@ -33946,14 +34235,14 @@ function classifyMcp(filePath, sourcePath) {
|
|
|
33946
34235
|
}
|
|
33947
34236
|
function isSymlinkCurrent(linkPath, sourcePath) {
|
|
33948
34237
|
try {
|
|
33949
|
-
return
|
|
34238
|
+
return fs48.realpathSync(linkPath) === fs48.realpathSync(sourcePath);
|
|
33950
34239
|
} catch {
|
|
33951
34240
|
return false;
|
|
33952
34241
|
}
|
|
33953
34242
|
}
|
|
33954
34243
|
function isCompiledCurrent6(filePath, sourcePath) {
|
|
33955
34244
|
try {
|
|
33956
|
-
const marker = extractProvenanceMarker(
|
|
34245
|
+
const marker = extractProvenanceMarker(fs48.readFileSync(filePath, "utf8"));
|
|
33957
34246
|
return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
|
|
33958
34247
|
} catch {
|
|
33959
34248
|
return false;
|
|
@@ -33983,7 +34272,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
|
|
|
33983
34272
|
}
|
|
33984
34273
|
function readCompiledContent(filePath) {
|
|
33985
34274
|
try {
|
|
33986
|
-
return
|
|
34275
|
+
return fs48.readFileSync(filePath, "utf8");
|
|
33987
34276
|
} catch {
|
|
33988
34277
|
return null;
|
|
33989
34278
|
}
|
|
@@ -34014,8 +34303,8 @@ function hashString6(value) {
|
|
|
34014
34303
|
}
|
|
34015
34304
|
|
|
34016
34305
|
// src/commands/sync.ts
|
|
34017
|
-
import
|
|
34018
|
-
import
|
|
34306
|
+
import fs49 from "fs";
|
|
34307
|
+
import path50 from "path";
|
|
34019
34308
|
|
|
34020
34309
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
34021
34310
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -34685,29 +34974,41 @@ async function runSyncCommand(options, logger) {
|
|
|
34685
34974
|
reportHookRejections(
|
|
34686
34975
|
lossReport,
|
|
34687
34976
|
targets,
|
|
34688
|
-
|
|
34977
|
+
path50.resolve(kitInfo.path, "hooks"),
|
|
34689
34978
|
kitInfo.components.hooks.declared
|
|
34690
34979
|
);
|
|
34691
34980
|
const hooksConflict = reportHooksSourceConflict(
|
|
34692
34981
|
lossReport,
|
|
34693
34982
|
targets,
|
|
34694
|
-
|
|
34983
|
+
path50.resolve(kitInfo.path, "hooks"),
|
|
34695
34984
|
kitInfo.components.hooks.declared
|
|
34696
34985
|
);
|
|
34697
34986
|
if (hooksConflict) {
|
|
34698
34987
|
logger.warn(hooksConflict);
|
|
34699
34988
|
}
|
|
34700
34989
|
if (allMappings) {
|
|
34990
|
+
const instructionsByTarget = instructionsByActiveTarget(
|
|
34991
|
+
targets,
|
|
34992
|
+
syncOptions.scope,
|
|
34993
|
+
syncOptions.projectRoot,
|
|
34994
|
+
allMappings
|
|
34995
|
+
);
|
|
34996
|
+
const rulesCoverage = measureRulesCoverage(
|
|
34997
|
+
targets,
|
|
34998
|
+
kitInfo.components.rules.declared,
|
|
34999
|
+
syncOptions.scope,
|
|
35000
|
+
syncOptions.projectRoot,
|
|
35001
|
+
allMappings,
|
|
35002
|
+
lossReport,
|
|
35003
|
+
instructionsByTarget
|
|
35004
|
+
);
|
|
34701
35005
|
reportContestedInstructions(
|
|
34702
|
-
|
|
34703
|
-
targets,
|
|
34704
|
-
syncOptions.scope,
|
|
34705
|
-
syncOptions.projectRoot,
|
|
34706
|
-
allMappings
|
|
34707
|
-
),
|
|
35006
|
+
instructionsByTarget,
|
|
34708
35007
|
kitInfo.components.rules.declared.length > 0,
|
|
34709
|
-
logger
|
|
35008
|
+
logger,
|
|
35009
|
+
missingRulesByTarget(rulesCoverage)
|
|
34710
35010
|
);
|
|
35011
|
+
reportRulesCoverage(rulesCoverage, logger);
|
|
34711
35012
|
}
|
|
34712
35013
|
}
|
|
34713
35014
|
writeLossReport(options.lossReport, lossReport);
|
|
@@ -34894,8 +35195,8 @@ function reconcileSyncedArtifacts(manifest, results, mappings, scope, projectRoo
|
|
|
34894
35195
|
}
|
|
34895
35196
|
}
|
|
34896
35197
|
function resolveKitFilePath(kitPath, relativePath) {
|
|
34897
|
-
const fullPath =
|
|
34898
|
-
return
|
|
35198
|
+
const fullPath = path50.join(kitPath, relativePath);
|
|
35199
|
+
return fs49.existsSync(fullPath) ? fullPath : null;
|
|
34899
35200
|
}
|
|
34900
35201
|
function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
|
|
34901
35202
|
if (removedSourcePaths.length === 0 || !mappings) {
|
|
@@ -34958,9 +35259,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34958
35259
|
}
|
|
34959
35260
|
if (relativePath.startsWith("agents/")) {
|
|
34960
35261
|
removeManagedCompiledArtifact2(
|
|
34961
|
-
|
|
35262
|
+
path50.join(
|
|
34962
35263
|
resolveTargetPath(paths.agents ?? ""),
|
|
34963
|
-
`${
|
|
35264
|
+
`${path50.parse(relativePath).name}.agent.md`
|
|
34964
35265
|
),
|
|
34965
35266
|
"copilot",
|
|
34966
35267
|
relativePath,
|
|
@@ -34970,9 +35271,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34970
35271
|
}
|
|
34971
35272
|
if (relativePath.startsWith("commands/")) {
|
|
34972
35273
|
removeManagedCompiledArtifact2(
|
|
34973
|
-
|
|
35274
|
+
path50.join(
|
|
34974
35275
|
resolveTargetPath(paths.prompts ?? ""),
|
|
34975
|
-
`${
|
|
35276
|
+
`${path50.parse(relativePath).name}.prompt.md`
|
|
34976
35277
|
),
|
|
34977
35278
|
"copilot",
|
|
34978
35279
|
relativePath,
|
|
@@ -34982,7 +35283,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
34982
35283
|
}
|
|
34983
35284
|
if (relativePath.endsWith("hooks.json")) {
|
|
34984
35285
|
removeManagedCompiledArtifact2(
|
|
34985
|
-
|
|
35286
|
+
path50.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
|
|
34986
35287
|
"copilot",
|
|
34987
35288
|
relativePath,
|
|
34988
35289
|
logger
|
|
@@ -35012,9 +35313,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
35012
35313
|
}
|
|
35013
35314
|
if (relativePath.startsWith("agents/")) {
|
|
35014
35315
|
removeManagedCompiledArtifact2(
|
|
35015
|
-
|
|
35316
|
+
path50.join(
|
|
35016
35317
|
resolveTargetPath(paths.agents ?? ""),
|
|
35017
|
-
`${
|
|
35318
|
+
`${path50.parse(relativePath).name}.toml`
|
|
35018
35319
|
),
|
|
35019
35320
|
"codex",
|
|
35020
35321
|
relativePath,
|
|
@@ -35024,9 +35325,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
35024
35325
|
}
|
|
35025
35326
|
if (relativePath.startsWith("rules/")) {
|
|
35026
35327
|
removeManagedCompiledArtifact2(
|
|
35027
|
-
|
|
35328
|
+
path50.join(
|
|
35028
35329
|
resolveTargetPath(paths.rules ?? ""),
|
|
35029
|
-
`${
|
|
35330
|
+
`${path50.parse(relativePath).name}.rules`
|
|
35030
35331
|
),
|
|
35031
35332
|
"codex",
|
|
35032
35333
|
relativePath,
|
|
@@ -35065,9 +35366,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
35065
35366
|
}
|
|
35066
35367
|
if (relativePath.startsWith("agents/")) {
|
|
35067
35368
|
removeManagedCompiledArtifact2(
|
|
35068
|
-
|
|
35369
|
+
path50.join(
|
|
35069
35370
|
resolveTargetPath(paths.agents ?? ""),
|
|
35070
|
-
`${
|
|
35371
|
+
`${path50.parse(relativePath).name}.md`
|
|
35071
35372
|
),
|
|
35072
35373
|
"opencode",
|
|
35073
35374
|
relativePath,
|
|
@@ -35077,9 +35378,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
35077
35378
|
}
|
|
35078
35379
|
if (relativePath.startsWith("commands/")) {
|
|
35079
35380
|
removeManagedCompiledArtifact2(
|
|
35080
|
-
|
|
35381
|
+
path50.join(
|
|
35081
35382
|
resolveTargetPath(paths.commands ?? ""),
|
|
35082
|
-
`${
|
|
35383
|
+
`${path50.parse(relativePath).name}.md`
|
|
35083
35384
|
),
|
|
35084
35385
|
"opencode",
|
|
35085
35386
|
relativePath,
|
|
@@ -35111,9 +35412,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
35111
35412
|
}
|
|
35112
35413
|
if (relativePath.startsWith("agents/")) {
|
|
35113
35414
|
removeManagedCompiledArtifact2(
|
|
35114
|
-
|
|
35415
|
+
path50.join(
|
|
35115
35416
|
resolveTargetPath(paths.agents ?? ""),
|
|
35116
|
-
`${
|
|
35417
|
+
`${path50.parse(relativePath).name}.md`
|
|
35117
35418
|
),
|
|
35118
35419
|
"cursor",
|
|
35119
35420
|
relativePath,
|
|
@@ -35123,9 +35424,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
35123
35424
|
}
|
|
35124
35425
|
if (relativePath.startsWith("rules/")) {
|
|
35125
35426
|
removeManagedCompiledArtifact2(
|
|
35126
|
-
|
|
35427
|
+
path50.join(
|
|
35127
35428
|
resolveTargetPath(paths.rules ?? ""),
|
|
35128
|
-
`${
|
|
35429
|
+
`${path50.parse(relativePath).name}.mdc`
|
|
35129
35430
|
),
|
|
35130
35431
|
"cursor",
|
|
35131
35432
|
relativePath,
|
|
@@ -35135,9 +35436,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
35135
35436
|
}
|
|
35136
35437
|
if (relativePath.startsWith("commands/")) {
|
|
35137
35438
|
removeManagedCompiledArtifact2(
|
|
35138
|
-
|
|
35439
|
+
path50.join(
|
|
35139
35440
|
resolveTargetPath(paths.skills ?? ""),
|
|
35140
|
-
|
|
35441
|
+
path50.parse(relativePath).name,
|
|
35141
35442
|
"SKILL.md"
|
|
35142
35443
|
),
|
|
35143
35444
|
"cursor",
|
|
@@ -35181,9 +35482,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
35181
35482
|
}
|
|
35182
35483
|
if (relativePath.startsWith("rules/")) {
|
|
35183
35484
|
removeManagedCompiledArtifact2(
|
|
35184
|
-
|
|
35485
|
+
path50.join(
|
|
35185
35486
|
resolveTargetPath(paths.rules ?? ""),
|
|
35186
|
-
`${
|
|
35487
|
+
`${path50.parse(relativePath).name}.md`
|
|
35187
35488
|
),
|
|
35188
35489
|
"cline",
|
|
35189
35490
|
relativePath,
|
|
@@ -35193,9 +35494,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
35193
35494
|
}
|
|
35194
35495
|
if (relativePath.startsWith("commands/")) {
|
|
35195
35496
|
removeManagedCompiledArtifact2(
|
|
35196
|
-
|
|
35497
|
+
path50.join(
|
|
35197
35498
|
resolveTargetPath(paths.workflows ?? ""),
|
|
35198
|
-
|
|
35499
|
+
path50.basename(relativePath)
|
|
35199
35500
|
),
|
|
35200
35501
|
"cline",
|
|
35201
35502
|
relativePath,
|
|
@@ -35213,17 +35514,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
35213
35514
|
}
|
|
35214
35515
|
}
|
|
35215
35516
|
function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
|
|
35216
|
-
if (!
|
|
35517
|
+
if (!fs49.existsSync(artifactPath)) {
|
|
35217
35518
|
return;
|
|
35218
35519
|
}
|
|
35219
|
-
if (!
|
|
35520
|
+
if (!fs49.statSync(artifactPath).isFile()) {
|
|
35220
35521
|
return;
|
|
35221
35522
|
}
|
|
35222
|
-
const marker = extractProvenanceMarker(
|
|
35523
|
+
const marker = extractProvenanceMarker(fs49.readFileSync(artifactPath, "utf8"));
|
|
35223
35524
|
if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
|
|
35224
35525
|
return;
|
|
35225
35526
|
}
|
|
35226
|
-
|
|
35527
|
+
fs49.rmSync(artifactPath, { force: true });
|
|
35227
35528
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
35228
35529
|
}
|
|
35229
35530
|
function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
@@ -35254,10 +35555,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
|
|
|
35254
35555
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
35255
35556
|
}
|
|
35256
35557
|
function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
35257
|
-
if (!
|
|
35558
|
+
if (!fs49.existsSync(artifactPath)) {
|
|
35258
35559
|
return;
|
|
35259
35560
|
}
|
|
35260
|
-
const content =
|
|
35561
|
+
const content = fs49.readFileSync(artifactPath, "utf8");
|
|
35261
35562
|
const startMarker = "# tangyr: managed mcp start";
|
|
35262
35563
|
const endMarker = "# tangyr: managed mcp end";
|
|
35263
35564
|
const startIndex = content.indexOf(startMarker);
|
|
@@ -35274,19 +35575,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
|
35274
35575
|
const after = content.slice(endIndex + endMarker.length).trimStart();
|
|
35275
35576
|
const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
|
|
35276
35577
|
if (cleaned.length === 0) {
|
|
35277
|
-
|
|
35578
|
+
fs49.rmSync(artifactPath, { force: true });
|
|
35278
35579
|
} else {
|
|
35279
|
-
|
|
35580
|
+
fs49.writeFileSync(artifactPath, `${cleaned}
|
|
35280
35581
|
`);
|
|
35281
35582
|
}
|
|
35282
35583
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
35283
35584
|
}
|
|
35284
35585
|
function readJsonObject5(filePath) {
|
|
35285
|
-
if (!
|
|
35586
|
+
if (!fs49.existsSync(filePath)) {
|
|
35286
35587
|
return null;
|
|
35287
35588
|
}
|
|
35288
35589
|
try {
|
|
35289
|
-
const parsed = JSON.parse(
|
|
35590
|
+
const parsed = JSON.parse(fs49.readFileSync(filePath, "utf8"));
|
|
35290
35591
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
35291
35592
|
} catch {
|
|
35292
35593
|
return null;
|
|
@@ -35300,10 +35601,10 @@ function readJsonMetadata(value) {
|
|
|
35300
35601
|
}
|
|
35301
35602
|
function writeJsonOrRemove2(filePath, parsed) {
|
|
35302
35603
|
if (isEmptyJsonValue2(parsed)) {
|
|
35303
|
-
|
|
35604
|
+
fs49.rmSync(filePath, { force: true });
|
|
35304
35605
|
return;
|
|
35305
35606
|
}
|
|
35306
|
-
|
|
35607
|
+
fs49.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
35307
35608
|
`);
|
|
35308
35609
|
}
|
|
35309
35610
|
function isEmptyJsonValue2(value) {
|
|
@@ -35363,8 +35664,8 @@ function removeManagedHookEntries(value, expectedSource) {
|
|
|
35363
35664
|
}
|
|
35364
35665
|
|
|
35365
35666
|
// src/commands/validate.ts
|
|
35366
|
-
import
|
|
35367
|
-
import
|
|
35667
|
+
import fs50 from "fs";
|
|
35668
|
+
import path51 from "path";
|
|
35368
35669
|
var SUPPORTED_KIT_FORMATS2 = [1];
|
|
35369
35670
|
var SUPPORTED_DISCIPLINE_VERSIONS = [
|
|
35370
35671
|
"0.14.0",
|
|
@@ -35479,12 +35780,12 @@ function checkArchetype(kit) {
|
|
|
35479
35780
|
}
|
|
35480
35781
|
function checkHookScriptsExist(kit) {
|
|
35481
35782
|
const violations = [];
|
|
35482
|
-
const hooksDir =
|
|
35783
|
+
const hooksDir = path51.join(kit.path, "hooks");
|
|
35483
35784
|
const missingSet = new Set(kit.components.hooks.missing);
|
|
35484
35785
|
for (const name of kit.components.hooks.declared) {
|
|
35485
35786
|
if (missingSet.has(name)) continue;
|
|
35486
|
-
const declarationPath =
|
|
35487
|
-
if (!
|
|
35787
|
+
const declarationPath = path51.join(hooksDir, `${name}.md`);
|
|
35788
|
+
if (!fs50.existsSync(declarationPath)) continue;
|
|
35488
35789
|
let data;
|
|
35489
35790
|
try {
|
|
35490
35791
|
({ data } = parseMarkdownFrontmatter(declarationPath));
|
|
@@ -35494,8 +35795,8 @@ function checkHookScriptsExist(kit) {
|
|
|
35494
35795
|
if (typeof data.command === "string" && data.command.trim().length > 0) {
|
|
35495
35796
|
continue;
|
|
35496
35797
|
}
|
|
35497
|
-
const scriptPath =
|
|
35498
|
-
if (!
|
|
35798
|
+
const scriptPath = path51.join(hooksDir, "scripts", `${name}.ts`);
|
|
35799
|
+
if (!fs50.existsSync(scriptPath)) {
|
|
35499
35800
|
violations.push({
|
|
35500
35801
|
code: "hook-script-missing",
|
|
35501
35802
|
location: `hooks/scripts/${name}.ts`,
|
|
@@ -35508,10 +35809,10 @@ function checkHookScriptsExist(kit) {
|
|
|
35508
35809
|
function checkOptionalSourceDocuments(kit) {
|
|
35509
35810
|
const violations = [];
|
|
35510
35811
|
for (const name of [".mcp.json", "settings.json", ".lsp.json"]) {
|
|
35511
|
-
const filePath =
|
|
35512
|
-
if (!
|
|
35812
|
+
const filePath = path51.join(kit.path, name);
|
|
35813
|
+
if (!fs50.existsSync(filePath)) continue;
|
|
35513
35814
|
try {
|
|
35514
|
-
const parsed = JSON.parse(
|
|
35815
|
+
const parsed = JSON.parse(fs50.readFileSync(filePath, "utf8"));
|
|
35515
35816
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
35516
35817
|
violations.push({
|
|
35517
35818
|
code: "optional-source-malformed",
|
|
@@ -35533,10 +35834,10 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35533
35834
|
const notices = [];
|
|
35534
35835
|
const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
|
|
35535
35836
|
for (const name of kit.components.skills.declared) {
|
|
35536
|
-
const skillDir =
|
|
35837
|
+
const skillDir = path51.join(kit.path, "skills", name);
|
|
35537
35838
|
let entries;
|
|
35538
35839
|
try {
|
|
35539
|
-
entries =
|
|
35840
|
+
entries = fs50.readdirSync(skillDir, { withFileTypes: true });
|
|
35540
35841
|
} catch {
|
|
35541
35842
|
continue;
|
|
35542
35843
|
}
|
|
@@ -35554,7 +35855,7 @@ function checkSkillSubfolderNames(kit) {
|
|
|
35554
35855
|
return notices;
|
|
35555
35856
|
}
|
|
35556
35857
|
function checkHooksSourceForm(kit) {
|
|
35557
|
-
const hooksDir =
|
|
35858
|
+
const hooksDir = path51.join(kit.path, "hooks");
|
|
35558
35859
|
const message = describeHooksSourceConflict(
|
|
35559
35860
|
hooksDir,
|
|
35560
35861
|
kit.components.hooks.declared
|
|
@@ -35566,12 +35867,12 @@ function checkHooksSourceForm(kit) {
|
|
|
35566
35867
|
} : null;
|
|
35567
35868
|
}
|
|
35568
35869
|
function checkHookDeclarations(kit) {
|
|
35569
|
-
const hooksDir =
|
|
35870
|
+
const hooksDir = path51.join(kit.path, "hooks");
|
|
35570
35871
|
return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
|
|
35571
35872
|
(r) => ({
|
|
35572
35873
|
code: "hook-declaration-invalid",
|
|
35573
|
-
location: `hooks/${
|
|
35574
|
-
message: `hooks: '${
|
|
35874
|
+
location: `hooks/${path51.basename(r.file)}`,
|
|
35875
|
+
message: `hooks: '${path51.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.`
|
|
35575
35876
|
})
|
|
35576
35877
|
);
|
|
35577
35878
|
}
|
|
@@ -35591,11 +35892,11 @@ function checkKitFormatSupported(kit) {
|
|
|
35591
35892
|
function checkEntrypointExists(kit) {
|
|
35592
35893
|
const declared = kit.entrypoint;
|
|
35593
35894
|
const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
|
|
35594
|
-
const entrypointPath =
|
|
35595
|
-
if (
|
|
35895
|
+
const entrypointPath = path51.join(kit.path, entrypoint);
|
|
35896
|
+
if (fs50.existsSync(entrypointPath)) {
|
|
35596
35897
|
return null;
|
|
35597
35898
|
}
|
|
35598
|
-
const legacyPresent = declared === void 0 &&
|
|
35899
|
+
const legacyPresent = declared === void 0 && fs50.existsSync(path51.join(kit.path, LEGACY_ENTRYPOINT));
|
|
35599
35900
|
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.`;
|
|
35600
35901
|
return {
|
|
35601
35902
|
code: "entrypoint-missing",
|
|
@@ -35654,9 +35955,9 @@ function checkComponentFrontmatter(kit) {
|
|
|
35654
35955
|
const missingSet = new Set(kit.components[cat].missing);
|
|
35655
35956
|
for (const name of kit.components[cat].declared) {
|
|
35656
35957
|
if (missingSet.has(name)) continue;
|
|
35657
|
-
const filePath = cat === "skills" ?
|
|
35658
|
-
if (!
|
|
35659
|
-
const relPath =
|
|
35958
|
+
const filePath = cat === "skills" ? path51.join(kit.path, cat, name, "SKILL.md") : path51.join(kit.path, cat, `${name}.md`);
|
|
35959
|
+
if (!fs50.existsSync(filePath)) continue;
|
|
35960
|
+
const relPath = path51.relative(kit.path, filePath);
|
|
35660
35961
|
try {
|
|
35661
35962
|
const { data } = parseMarkdownFrontmatter(filePath);
|
|
35662
35963
|
for (const field of requiredFields) {
|
|
@@ -35681,10 +35982,10 @@ function checkComponentFrontmatter(kit) {
|
|
|
35681
35982
|
}
|
|
35682
35983
|
function checkReservedRootNames(kit) {
|
|
35683
35984
|
const violations = [];
|
|
35684
|
-
if (!
|
|
35985
|
+
if (!fs50.existsSync(kit.path) || !fs50.statSync(kit.path).isDirectory()) {
|
|
35685
35986
|
return violations;
|
|
35686
35987
|
}
|
|
35687
|
-
const entries =
|
|
35988
|
+
const entries = fs50.readdirSync(kit.path, { withFileTypes: true });
|
|
35688
35989
|
for (const entry of entries) {
|
|
35689
35990
|
if (RESERVED_ROOT_NAMES.includes(entry.name)) {
|
|
35690
35991
|
violations.push({
|
|
@@ -35701,8 +36002,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35701
36002
|
const missingSet = new Set(kit.components.commands.missing);
|
|
35702
36003
|
for (const name of kit.components.commands.declared) {
|
|
35703
36004
|
if (missingSet.has(name)) continue;
|
|
35704
|
-
const filePath =
|
|
35705
|
-
if (!
|
|
36005
|
+
const filePath = path51.join(kit.path, "commands", `${name}.md`);
|
|
36006
|
+
if (!fs50.existsSync(filePath)) continue;
|
|
35706
36007
|
let data;
|
|
35707
36008
|
try {
|
|
35708
36009
|
({ data } = parseMarkdownFrontmatter(filePath));
|
|
@@ -35715,7 +36016,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35715
36016
|
if (!barred) {
|
|
35716
36017
|
violations.push({
|
|
35717
36018
|
code: "command-human-only-model-invocable",
|
|
35718
|
-
location:
|
|
36019
|
+
location: path51.relative(kit.path, filePath),
|
|
35719
36020
|
message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
|
|
35720
36021
|
});
|
|
35721
36022
|
}
|
|
@@ -35724,8 +36025,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
35724
36025
|
}
|
|
35725
36026
|
|
|
35726
36027
|
// src/commands/verify.ts
|
|
35727
|
-
import
|
|
35728
|
-
import
|
|
36028
|
+
import fs51 from "fs";
|
|
36029
|
+
import path52 from "path";
|
|
35729
36030
|
function runVerifyCommand(options, logger) {
|
|
35730
36031
|
if (options.target && !isKnownTarget(options.target)) {
|
|
35731
36032
|
throwUnrecognizedTarget(options.target);
|
|
@@ -35906,8 +36207,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
|
|
|
35906
36207
|
if (!slotPath) {
|
|
35907
36208
|
continue;
|
|
35908
36209
|
}
|
|
35909
|
-
const fullPath = subPath ?
|
|
35910
|
-
if (!
|
|
36210
|
+
const fullPath = subPath ? path52.join(slotPath, subPath) : slotPath;
|
|
36211
|
+
if (!fs51.existsSync(fullPath)) {
|
|
35911
36212
|
failures.push(
|
|
35912
36213
|
`claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
|
|
35913
36214
|
);
|