@alessandroraffa/tangyr 0.20.1 → 0.21.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 +764 -627
- package/mappings/hook-events.yaml +89 -36
- package/mappings/platform-paths.yaml +8 -0
- 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 path47 = __require("path");
|
|
1376
|
+
var fs46 = __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 (fs46.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 = path47.resolve(baseDir, baseName);
|
|
2389
|
+
if (fs46.existsSync(localBin)) return localBin;
|
|
2390
|
+
if (sourceExt.includes(path47.extname(baseName))) return void 0;
|
|
2391
2391
|
const foundExt = sourceExt.find(
|
|
2392
|
-
(ext) =>
|
|
2392
|
+
(ext) => fs46.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 = fs46.realpathSync(this._scriptPath);
|
|
2405
2405
|
} catch {
|
|
2406
2406
|
resolvedScriptPath = this._scriptPath;
|
|
2407
2407
|
}
|
|
2408
|
-
executableDir =
|
|
2409
|
-
|
|
2408
|
+
executableDir = path47.resolve(
|
|
2409
|
+
path47.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 = path47.basename(
|
|
2417
2417
|
this._scriptPath,
|
|
2418
|
-
|
|
2418
|
+
path47.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(path47.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 = path47.basename(filename, path47.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(path48) {
|
|
3359
|
+
if (path48 === void 0) return this._executableDir;
|
|
3360
|
+
this._executableDir = path48;
|
|
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, path47) {
|
|
3717
|
+
const ctrl = callVisitor(key, node, visitor, path47);
|
|
3718
3718
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3719
|
-
replaceNode(key,
|
|
3720
|
-
return visit_(key, ctrl, visitor,
|
|
3719
|
+
replaceNode(key, path47, ctrl);
|
|
3720
|
+
return visit_(key, ctrl, visitor, path47);
|
|
3721
3721
|
}
|
|
3722
3722
|
if (typeof ctrl !== "symbol") {
|
|
3723
3723
|
if (identity.isCollection(node)) {
|
|
3724
|
-
|
|
3724
|
+
path47 = Object.freeze(path47.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, path47);
|
|
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
|
+
path47 = Object.freeze(path47.concat(node));
|
|
3738
|
+
const ck = visit_("key", node.key, visitor, path47);
|
|
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, path47);
|
|
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, path47) {
|
|
3765
|
+
const ctrl = await callVisitor(key, node, visitor, path47);
|
|
3766
3766
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3767
|
-
replaceNode(key,
|
|
3768
|
-
return visitAsync_(key, ctrl, visitor,
|
|
3767
|
+
replaceNode(key, path47, ctrl);
|
|
3768
|
+
return visitAsync_(key, ctrl, visitor, path47);
|
|
3769
3769
|
}
|
|
3770
3770
|
if (typeof ctrl !== "symbol") {
|
|
3771
3771
|
if (identity.isCollection(node)) {
|
|
3772
|
-
|
|
3772
|
+
path47 = Object.freeze(path47.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, path47);
|
|
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
|
+
path47 = Object.freeze(path47.concat(node));
|
|
3786
|
+
const ck = await visitAsync_("key", node.key, visitor, path47);
|
|
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, path47);
|
|
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, path47) {
|
|
3819
3819
|
if (typeof visitor === "function")
|
|
3820
|
-
return visitor(key, node,
|
|
3820
|
+
return visitor(key, node, path47);
|
|
3821
3821
|
if (identity.isMap(node))
|
|
3822
|
-
return visitor.Map?.(key, node,
|
|
3822
|
+
return visitor.Map?.(key, node, path47);
|
|
3823
3823
|
if (identity.isSeq(node))
|
|
3824
|
-
return visitor.Seq?.(key, node,
|
|
3824
|
+
return visitor.Seq?.(key, node, path47);
|
|
3825
3825
|
if (identity.isPair(node))
|
|
3826
|
-
return visitor.Pair?.(key, node,
|
|
3826
|
+
return visitor.Pair?.(key, node, path47);
|
|
3827
3827
|
if (identity.isScalar(node))
|
|
3828
|
-
return visitor.Scalar?.(key, node,
|
|
3828
|
+
return visitor.Scalar?.(key, node, path47);
|
|
3829
3829
|
if (identity.isAlias(node))
|
|
3830
|
-
return visitor.Alias?.(key, node,
|
|
3830
|
+
return visitor.Alias?.(key, node, path47);
|
|
3831
3831
|
return void 0;
|
|
3832
3832
|
}
|
|
3833
|
-
function replaceNode(key,
|
|
3834
|
-
const parent =
|
|
3833
|
+
function replaceNode(key, path47, node) {
|
|
3834
|
+
const parent = path47[path47.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, path47, value) {
|
|
4443
4443
|
let v2 = value;
|
|
4444
|
-
for (let i =
|
|
4445
|
-
const k2 =
|
|
4444
|
+
for (let i = path47.length - 1; i >= 0; --i) {
|
|
4445
|
+
const k2 = path47[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 = (path47) => path47 == null || typeof path47 === "object" && !!path47[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(path47, value) {
|
|
4495
|
+
if (isEmptyPath(path47))
|
|
4496
4496
|
this.add(value);
|
|
4497
4497
|
else {
|
|
4498
|
-
const [key, ...rest] =
|
|
4498
|
+
const [key, ...rest] = path47;
|
|
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(path47) {
|
|
4513
|
+
const [key, ...rest] = path47;
|
|
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(path47, keepScalar) {
|
|
4528
|
+
const [key, ...rest] = path47;
|
|
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(path47) {
|
|
4547
|
+
const [key, ...rest] = path47;
|
|
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(path47, value) {
|
|
4558
|
+
const [key, ...rest] = path47;
|
|
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(path47, value) {
|
|
7071
7071
|
if (assertCollection(this.contents))
|
|
7072
|
-
this.contents.addIn(
|
|
7072
|
+
this.contents.addIn(path47, 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(path47) {
|
|
7148
|
+
if (Collection.isEmptyPath(path47)) {
|
|
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(path47) : 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(path47, keepScalar) {
|
|
7170
|
+
if (Collection.isEmptyPath(path47))
|
|
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(path47, 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(path47) {
|
|
7184
|
+
if (Collection.isEmptyPath(path47))
|
|
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(path47) : 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(path47, value) {
|
|
7204
|
+
if (Collection.isEmptyPath(path47)) {
|
|
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(path47), value);
|
|
7208
7208
|
} else if (assertCollection(this.contents)) {
|
|
7209
|
-
this.contents.setIn(
|
|
7209
|
+
this.contents.setIn(path47, 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, path47) => {
|
|
9167
9167
|
let item = cst;
|
|
9168
|
-
for (const [field, index] of
|
|
9168
|
+
for (const [field, index] of path47) {
|
|
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, path47) => {
|
|
9178
|
+
const parent = visit.itemAtPath(cst, path47.slice(0, -1));
|
|
9179
|
+
const field = path47[path47.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(path47, item, visitor) {
|
|
9186
|
+
let ctrl = visitor(item, path47);
|
|
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(path47.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, path47);
|
|
9205
9205
|
}
|
|
9206
9206
|
}
|
|
9207
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
9207
|
+
return typeof ctrl === "function" ? ctrl(item, path47) : 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 fs46 = this.flowScalar(this.type);
|
|
10493
10493
|
if (atNextItem || it2.value) {
|
|
10494
|
-
map.items.push({ start, key:
|
|
10494
|
+
map.items.push({ start, key: fs46, sep: [] });
|
|
10495
10495
|
this.onKeyLine = true;
|
|
10496
10496
|
} else if (it2.sep) {
|
|
10497
|
-
this.stack.push(
|
|
10497
|
+
this.stack.push(fs46);
|
|
10498
10498
|
} else {
|
|
10499
|
-
Object.assign(it2, { key:
|
|
10499
|
+
Object.assign(it2, { key: fs46, 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 fs46 = this.flowScalar(this.type);
|
|
10628
10628
|
if (!it2 || it2.value)
|
|
10629
|
-
fc.items.push({ start: [], key:
|
|
10629
|
+
fc.items.push({ start: [], key: fs46, sep: [] });
|
|
10630
10630
|
else if (it2.sep)
|
|
10631
|
-
this.stack.push(
|
|
10631
|
+
this.stack.push(fs46);
|
|
10632
10632
|
else
|
|
10633
|
-
Object.assign(it2, { key:
|
|
10633
|
+
Object.assign(it2, { key: fs46, sep: [] });
|
|
10634
10634
|
return;
|
|
10635
10635
|
}
|
|
10636
10636
|
case "flow-map-end":
|
|
@@ -15724,7 +15724,8 @@ function resolveClaudeCodeProfile(scope, projectRoot, mappings) {
|
|
|
15724
15724
|
hooks_shared_file: r(slotMap, "hooks_shared_file"),
|
|
15725
15725
|
settings_shared_file: r(slotMap, "settings_shared_file"),
|
|
15726
15726
|
mcp_shared_file: r(slotMap, "mcp_shared_file"),
|
|
15727
|
-
hooks: r(slotMap, "hooks")
|
|
15727
|
+
hooks: r(slotMap, "hooks"),
|
|
15728
|
+
hook_scripts: r(slotMap, "hook_scripts")
|
|
15728
15729
|
};
|
|
15729
15730
|
}
|
|
15730
15731
|
function resolveCopilotProfile(scope, projectRoot, mappings) {
|
|
@@ -15741,6 +15742,7 @@ function resolveCopilotProfile(scope, projectRoot, mappings) {
|
|
|
15741
15742
|
skills: r(slotMap, "skills"),
|
|
15742
15743
|
prompts: r(slotMap, "prompts"),
|
|
15743
15744
|
hooks: r(slotMap, "hooks"),
|
|
15745
|
+
hook_scripts: r(slotMap, "hook_scripts"),
|
|
15744
15746
|
mcp_shared_file: r(slotMap, "mcp_shared_file"),
|
|
15745
15747
|
instructions
|
|
15746
15748
|
};
|
|
@@ -15759,6 +15761,7 @@ function resolveCodexProfile(scope, projectRoot, mappings) {
|
|
|
15759
15761
|
rules: r(slotMap, "rules"),
|
|
15760
15762
|
skills: r(slotMap, "skills"),
|
|
15761
15763
|
hooks_shared_file: r(slotMap, "hooks_shared_file"),
|
|
15764
|
+
hook_scripts: r(slotMap, "hook_scripts"),
|
|
15762
15765
|
mcp_shared_file: r(slotMap, "mcp_shared_file")
|
|
15763
15766
|
};
|
|
15764
15767
|
}
|
|
@@ -15794,6 +15797,7 @@ function resolveCursorProfile(scope, projectRoot, mappings) {
|
|
|
15794
15797
|
skills: r(slotMap, "skills"),
|
|
15795
15798
|
skills_shared: r(slotMap, "skills_shared"),
|
|
15796
15799
|
hooks_file: r(slotMap, "hooks_file"),
|
|
15800
|
+
hook_scripts: r(slotMap, "hook_scripts"),
|
|
15797
15801
|
mcp_file: r(slotMap, "mcp_file"),
|
|
15798
15802
|
permissions_file: r(slotMap, "permissions_file")
|
|
15799
15803
|
};
|
|
@@ -15863,7 +15867,8 @@ function resolveClaudeCodeProfileForRoot(root, mappings) {
|
|
|
15863
15867
|
hooks_shared_file: r(slotMap, "hooks_shared_file"),
|
|
15864
15868
|
settings_shared_file: r(slotMap, "settings_shared_file"),
|
|
15865
15869
|
mcp_shared_file: r(slotMap, "mcp_shared_file"),
|
|
15866
|
-
hooks: r(slotMap, "hooks")
|
|
15870
|
+
hooks: r(slotMap, "hooks"),
|
|
15871
|
+
hook_scripts: r(slotMap, "hook_scripts")
|
|
15867
15872
|
};
|
|
15868
15873
|
const defaultRoot = defaultProfile.agents !== void 0 ? path8.dirname(defaultProfile.agents) : path8.resolve(expandHome(DEFAULT_CLAUDE_ROOT_RAW));
|
|
15869
15874
|
if (root === defaultRoot) {
|
|
@@ -21130,9 +21135,6 @@ var lossSeverityByEntryType = {
|
|
|
21130
21135
|
// which. Error severity, because the CLI cannot tell an author which half
|
|
21131
21136
|
// of their kit it is ignoring without them deciding first.
|
|
21132
21137
|
"hook-source-ambiguous": "error",
|
|
21133
|
-
// A warning, not an error: the hooks that do reach the target are correct,
|
|
21134
|
-
// and the remedy is a choice about scope rather than a defect in the kit.
|
|
21135
|
-
"hook-script-path-unresolved": "warning",
|
|
21136
21138
|
"hook-as-plugin": "error",
|
|
21137
21139
|
"instructions-shim": "info",
|
|
21138
21140
|
"permission-coarsening": "error",
|
|
@@ -21250,7 +21252,9 @@ function parseHookDeclaration(filePath) {
|
|
|
21250
21252
|
}
|
|
21251
21253
|
var GLOBAL_HOOK_SCRIPTS_DIR = "~/.agents/hooks/scripts";
|
|
21252
21254
|
function synthesizedHookCommand(name, scriptsDir = GLOBAL_HOOK_SCRIPTS_DIR) {
|
|
21253
|
-
|
|
21255
|
+
const script = `${scriptsDir}/${name}.ts`;
|
|
21256
|
+
const needsQuoting = (/\s/u.test(script) || script.includes("$")) && !script.startsWith("~");
|
|
21257
|
+
return `npx tsx ${needsQuoting ? `"${script}"` : script}`;
|
|
21254
21258
|
}
|
|
21255
21259
|
function resolveHookCommand(declaration, scriptsDir) {
|
|
21256
21260
|
return declaration.command ?? synthesizedHookCommand(declaration.name, scriptsDir);
|
|
@@ -21486,32 +21490,6 @@ function reportHooksSourceConflict(report, targets, hooksDir, hookNames) {
|
|
|
21486
21490
|
}
|
|
21487
21491
|
return message;
|
|
21488
21492
|
}
|
|
21489
|
-
function reportProjectScopeScriptPath(report, targets, hooksDir, hookNames) {
|
|
21490
|
-
const affected = targets.filter((t) => t !== "claude-code");
|
|
21491
|
-
if (affected.length === 0) {
|
|
21492
|
-
return [];
|
|
21493
|
-
}
|
|
21494
|
-
const synthesized = loadHookDeclarations(hooksDir, hookNames).filter(
|
|
21495
|
-
(d) => d.command === void 0
|
|
21496
|
-
);
|
|
21497
|
-
if (synthesized.length === 0) {
|
|
21498
|
-
return [];
|
|
21499
|
-
}
|
|
21500
|
-
for (const target of affected) {
|
|
21501
|
-
addLoss(report, target, "hooks", {
|
|
21502
|
-
source: `${path20.basename(hooksDir)}/`,
|
|
21503
|
-
fields: [
|
|
21504
|
-
{
|
|
21505
|
-
field: "command",
|
|
21506
|
-
action: "hook-script-path-unresolved",
|
|
21507
|
-
severity: "warning",
|
|
21508
|
-
detail: `The ${synthesized.length} hook${synthesized.length === 1 ? "" : "s"} that take the synthesized command name '${GLOBAL_HOOK_SCRIPTS_DIR}/<name>.ts', which a project-scope install does not write. Only the claude-code adapter delivers hook scripts into a project, and only its own commands are resolved against the project. To fix, choose one: install this kit at global scope, where the path is correct; install claude-code alongside ${target} so the scripts reach the project, and give each hook an explicit 'command' pointing at them; or give each hook a 'command' of its own. Until then these hooks do not run under ${target}.`
|
|
21509
|
-
}
|
|
21510
|
-
]
|
|
21511
|
-
});
|
|
21512
|
-
}
|
|
21513
|
-
return affected;
|
|
21514
|
-
}
|
|
21515
21493
|
|
|
21516
21494
|
// src/core/remove.ts
|
|
21517
21495
|
import fs23 from "fs";
|
|
@@ -24311,8 +24289,8 @@ function toConflictPolicy2(value) {
|
|
|
24311
24289
|
}
|
|
24312
24290
|
|
|
24313
24291
|
// src/commands/install.ts
|
|
24314
|
-
import
|
|
24315
|
-
import
|
|
24292
|
+
import fs39 from "fs";
|
|
24293
|
+
import path39 from "path";
|
|
24316
24294
|
|
|
24317
24295
|
// src/core/channel-state.ts
|
|
24318
24296
|
import fs30 from "fs";
|
|
@@ -25221,8 +25199,8 @@ function sleep(ms2) {
|
|
|
25221
25199
|
// src/adapters/codex.ts
|
|
25222
25200
|
var TOML3 = __toESM(require_toml(), 1);
|
|
25223
25201
|
import crypto5 from "crypto";
|
|
25224
|
-
import
|
|
25225
|
-
import
|
|
25202
|
+
import fs34 from "fs";
|
|
25203
|
+
import path33 from "path";
|
|
25226
25204
|
|
|
25227
25205
|
// src/compiler/agents.ts
|
|
25228
25206
|
var TOML = __toESM(require_toml(), 1);
|
|
@@ -25668,6 +25646,16 @@ function compileCursorHooks(sourceHooksJson, mappings, lossReport, sourceLabel)
|
|
|
25668
25646
|
}
|
|
25669
25647
|
hooks[mapping.target_event] = { command: extracted.command };
|
|
25670
25648
|
translated += 1;
|
|
25649
|
+
if (extracted.remaining.length > 0) {
|
|
25650
|
+
addHookLoss(
|
|
25651
|
+
lossReport,
|
|
25652
|
+
"cursor",
|
|
25653
|
+
sourceEvent,
|
|
25654
|
+
sourceLabel,
|
|
25655
|
+
"error",
|
|
25656
|
+
`${sourceEvent}: the source registers ${extracted.remaining.length + 1} hooks on this event and Cursor's entry holds one command. Only '${extracted.command}' was written; ${extracted.remaining.map((c) => `'${c}'`).join(", ")} ${extracted.remaining.length === 1 ? "does" : "do"} not run under Cursor. To fix: give this event a single entry point that dispatches to the others, or accept the loss knowingly.`
|
|
25657
|
+
);
|
|
25658
|
+
}
|
|
25671
25659
|
if (extracted.matcher) {
|
|
25672
25660
|
addInformational(
|
|
25673
25661
|
lossReport,
|
|
@@ -25835,20 +25823,30 @@ function compileCopilotHooks(sourceHooksJson, mappings, lossReport, sourceLabel)
|
|
|
25835
25823
|
}
|
|
25836
25824
|
function extractHookCommand(payload) {
|
|
25837
25825
|
const entries = Array.isArray(payload) ? payload : [payload];
|
|
25826
|
+
const found = [];
|
|
25838
25827
|
for (const entry of entries) {
|
|
25839
25828
|
if (!isRecord(entry)) continue;
|
|
25840
25829
|
const matcher = typeof entry.matcher === "string" && entry.matcher ? { matcher: entry.matcher } : {};
|
|
25841
25830
|
if (typeof entry.command === "string" && entry.command) {
|
|
25842
|
-
|
|
25831
|
+
found.push({ command: entry.command, ...matcher });
|
|
25832
|
+
continue;
|
|
25843
25833
|
}
|
|
25844
25834
|
const inner = Array.isArray(entry.hooks) ? entry.hooks : [];
|
|
25845
25835
|
for (const hook of inner) {
|
|
25846
25836
|
if (isRecord(hook) && typeof hook.command === "string" && hook.command) {
|
|
25847
|
-
|
|
25837
|
+
found.push({ command: hook.command, ...matcher });
|
|
25848
25838
|
}
|
|
25849
25839
|
}
|
|
25850
25840
|
}
|
|
25851
|
-
|
|
25841
|
+
if (found.length === 0) {
|
|
25842
|
+
return { command: "", remaining: [] };
|
|
25843
|
+
}
|
|
25844
|
+
const [first, ...rest] = found;
|
|
25845
|
+
return {
|
|
25846
|
+
command: first.command,
|
|
25847
|
+
...first.matcher !== void 0 ? { matcher: first.matcher } : {},
|
|
25848
|
+
remaining: rest.map((r) => r.command)
|
|
25849
|
+
};
|
|
25852
25850
|
}
|
|
25853
25851
|
function normalizeHookEventRule(value, target, sourceEvent) {
|
|
25854
25852
|
if (typeof value === "string") {
|
|
@@ -25929,6 +25927,78 @@ function addHookLoss(lossReport, target, eventName, sourceLabel, severity, reaso
|
|
|
25929
25927
|
});
|
|
25930
25928
|
}
|
|
25931
25929
|
|
|
25930
|
+
// src/core/hook-scripts.ts
|
|
25931
|
+
import path30 from "path";
|
|
25932
|
+
function hookScriptsDir(bridge, target) {
|
|
25933
|
+
const globalBridge = resolveTargetPath("~/.agents/hooks");
|
|
25934
|
+
if (path30.resolve(bridge) === path30.resolve(globalBridge)) {
|
|
25935
|
+
return { prefix: GLOBAL_HOOK_SCRIPTS_DIR, machineLocal: false };
|
|
25936
|
+
}
|
|
25937
|
+
const relative = path30.relative(process.cwd(), bridge);
|
|
25938
|
+
const insideProject = !relative.startsWith("..") && !path30.isAbsolute(relative) && relative !== "";
|
|
25939
|
+
const variable = PROJECT_DIR_VARIABLE[target];
|
|
25940
|
+
if (insideProject && variable) {
|
|
25941
|
+
const posix = path30.posix.join(
|
|
25942
|
+
relative.split(path30.sep).join("/"),
|
|
25943
|
+
"scripts"
|
|
25944
|
+
);
|
|
25945
|
+
return { prefix: `$${variable.slice(1)}/${posix}`, machineLocal: false };
|
|
25946
|
+
}
|
|
25947
|
+
return { prefix: path30.join(bridge, "scripts"), machineLocal: true };
|
|
25948
|
+
}
|
|
25949
|
+
var PROJECT_DIR_VARIABLE = {
|
|
25950
|
+
"claude-code": "$CLAUDE_PROJECT_DIR"
|
|
25951
|
+
};
|
|
25952
|
+
function machineLocalScriptPathNotice(target, prefix) {
|
|
25953
|
+
return `The hook commands compiled for ${target} name '${prefix}', an absolute path. ${target} publishes no project-directory variable a command could use instead \u2014 measured, not assumed \u2014 and a bare relative path would resolve against whatever directory the harness runs the hook from. The compiled file is therefore correct on this machine and not on another: re-run 'tangyr sync' after cloning, and prefer keeping it out of version control.`;
|
|
25954
|
+
}
|
|
25955
|
+
|
|
25956
|
+
// src/adapters/hook-scripts-bridge.ts
|
|
25957
|
+
import fs32 from "fs";
|
|
25958
|
+
import path31 from "path";
|
|
25959
|
+
function syncHookScriptsBridge(args) {
|
|
25960
|
+
const { source, destination, config, sourceRoot, options, logger } = args;
|
|
25961
|
+
if (!fs32.existsSync(source)) {
|
|
25962
|
+
return {
|
|
25963
|
+
component: "hooks",
|
|
25964
|
+
status: "skipped",
|
|
25965
|
+
path: `${source}: source not configured`
|
|
25966
|
+
};
|
|
25967
|
+
}
|
|
25968
|
+
if (options.dryRun) {
|
|
25969
|
+
logger.info(`[dry-run] hooks: symlink ${source} -> ${destination}`);
|
|
25970
|
+
return { component: "hooks", status: "dry-run", path: destination };
|
|
25971
|
+
}
|
|
25972
|
+
const artifactClass = classifyArtifact(destination, config, sourceRoot);
|
|
25973
|
+
if (artifactClass === "managed-symlink" && isSymlinkTo(destination, source)) {
|
|
25974
|
+
return { component: "hooks", status: "skipped-current", path: destination };
|
|
25975
|
+
}
|
|
25976
|
+
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
25977
|
+
fs32.unlinkSync(destination);
|
|
25978
|
+
} else if (artifactClass === "unmanaged-conflict" && !args.onConflict()) {
|
|
25979
|
+
return { component: "hooks", status: "conflict", path: destination };
|
|
25980
|
+
} else if (artifactClass === "managed-symlink") {
|
|
25981
|
+
fs32.unlinkSync(destination);
|
|
25982
|
+
}
|
|
25983
|
+
ensureDir(path31.dirname(destination));
|
|
25984
|
+
createRelativeSymlink(source, destination, "dir");
|
|
25985
|
+
if (args.manifest && args.scopePath) {
|
|
25986
|
+
addArtifactToManifest(args.manifest, {
|
|
25987
|
+
relativePath: path31.relative(args.scopePath, destination),
|
|
25988
|
+
hash: `dir:${source}`,
|
|
25989
|
+
origin: "tangyr-managed"
|
|
25990
|
+
});
|
|
25991
|
+
}
|
|
25992
|
+
return { component: "hooks", status: "success", path: destination };
|
|
25993
|
+
}
|
|
25994
|
+
function isSymlinkTo(linkPath, source) {
|
|
25995
|
+
try {
|
|
25996
|
+
return fs32.realpathSync(linkPath) === fs32.realpathSync(source);
|
|
25997
|
+
} catch {
|
|
25998
|
+
return false;
|
|
25999
|
+
}
|
|
26000
|
+
}
|
|
26001
|
+
|
|
25932
26002
|
// src/compiler/mcp.ts
|
|
25933
26003
|
var TOML2 = __toESM(require_toml(), 1);
|
|
25934
26004
|
import crypto4 from "crypto";
|
|
@@ -26208,9 +26278,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
|
|
|
26208
26278
|
}
|
|
26209
26279
|
|
|
26210
26280
|
// src/compiler/rules.ts
|
|
26211
|
-
import
|
|
26281
|
+
import path32 from "path";
|
|
26212
26282
|
var import_yaml9 = __toESM(require_dist(), 1);
|
|
26213
|
-
import
|
|
26283
|
+
import fs33 from "fs";
|
|
26214
26284
|
function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
26215
26285
|
if (target === "copilot") {
|
|
26216
26286
|
addLoss(lossReport, "copilot", "rules", {
|
|
@@ -26247,13 +26317,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
|
26247
26317
|
}
|
|
26248
26318
|
const appendixParts = [];
|
|
26249
26319
|
const dotRulesFiles = [];
|
|
26250
|
-
for (const ruleFile of ts(
|
|
26320
|
+
for (const ruleFile of ts(path32.join(sourceRulesDir, "*.md")).sort()) {
|
|
26251
26321
|
const parsed = parseRule(ruleFile);
|
|
26252
|
-
const name =
|
|
26322
|
+
const name = path32.basename(ruleFile, ".md");
|
|
26253
26323
|
if (parsed.mode === "exec-policy") {
|
|
26254
26324
|
dotRulesFiles.push({
|
|
26255
26325
|
name: `${name}.rules`,
|
|
26256
|
-
content: `${formatProvenanceMarker("toml", `rules/${
|
|
26326
|
+
content: `${formatProvenanceMarker("toml", `rules/${path32.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
|
|
26257
26327
|
${parsed.body}`
|
|
26258
26328
|
});
|
|
26259
26329
|
continue;
|
|
@@ -26262,7 +26332,7 @@ ${parsed.body}`
|
|
|
26262
26332
|
|
|
26263
26333
|
${parsed.body.trim()}`);
|
|
26264
26334
|
addLoss(lossReport, "codex", "rules", {
|
|
26265
|
-
source: `rules/${
|
|
26335
|
+
source: `rules/${path32.basename(ruleFile)}`,
|
|
26266
26336
|
fields: [
|
|
26267
26337
|
{
|
|
26268
26338
|
field: "mode",
|
|
@@ -26272,7 +26342,7 @@ ${parsed.body.trim()}`);
|
|
|
26272
26342
|
"mode",
|
|
26273
26343
|
"rule-as-instruction"
|
|
26274
26344
|
),
|
|
26275
|
-
detail: `${
|
|
26345
|
+
detail: `${path32.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
|
|
26276
26346
|
}
|
|
26277
26347
|
]
|
|
26278
26348
|
});
|
|
@@ -26280,7 +26350,7 @@ ${parsed.body.trim()}`);
|
|
|
26280
26350
|
return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
|
|
26281
26351
|
}
|
|
26282
26352
|
function parseRule(ruleFile) {
|
|
26283
|
-
const content =
|
|
26353
|
+
const content = fs33.readFileSync(ruleFile, "utf8");
|
|
26284
26354
|
if (!content.startsWith("---\n")) {
|
|
26285
26355
|
return { mode: "guidance", body: content };
|
|
26286
26356
|
}
|
|
@@ -26304,14 +26374,14 @@ function isRuleMode(value) {
|
|
|
26304
26374
|
}
|
|
26305
26375
|
function compileOpenCodeRules(sourceRulesDir, lossReport) {
|
|
26306
26376
|
const appendixParts = [];
|
|
26307
|
-
for (const ruleFile of ts(
|
|
26377
|
+
for (const ruleFile of ts(path32.join(sourceRulesDir, "*.md")).sort()) {
|
|
26308
26378
|
const parsed = parseRule(ruleFile);
|
|
26309
|
-
const name =
|
|
26379
|
+
const name = path32.basename(ruleFile, ".md");
|
|
26310
26380
|
appendixParts.push(`## ${name}
|
|
26311
26381
|
|
|
26312
26382
|
${parsed.body.trim()}`);
|
|
26313
26383
|
addLoss(lossReport, "opencode", "rules", {
|
|
26314
|
-
source: `rules/${
|
|
26384
|
+
source: `rules/${path32.basename(ruleFile)}`,
|
|
26315
26385
|
fields: [
|
|
26316
26386
|
{
|
|
26317
26387
|
field: "rule",
|
|
@@ -26321,7 +26391,7 @@ ${parsed.body.trim()}`);
|
|
|
26321
26391
|
"rule",
|
|
26322
26392
|
"rule-path-scoping"
|
|
26323
26393
|
),
|
|
26324
|
-
detail: `${
|
|
26394
|
+
detail: `${path32.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
|
|
26325
26395
|
}
|
|
26326
26396
|
]
|
|
26327
26397
|
});
|
|
@@ -26330,9 +26400,9 @@ ${parsed.body.trim()}`);
|
|
|
26330
26400
|
}
|
|
26331
26401
|
function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
26332
26402
|
const dotRulesFiles = [];
|
|
26333
|
-
for (const ruleFile of ts(
|
|
26334
|
-
const content =
|
|
26335
|
-
const name =
|
|
26403
|
+
for (const ruleFile of ts(path32.join(sourceRulesDir, "*.md")).sort()) {
|
|
26404
|
+
const content = fs33.readFileSync(ruleFile, "utf8");
|
|
26405
|
+
const name = path32.basename(ruleFile, ".md");
|
|
26336
26406
|
let frontmatterData = {};
|
|
26337
26407
|
let body = content;
|
|
26338
26408
|
if (content.startsWith("---\n")) {
|
|
@@ -26361,7 +26431,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
|
26361
26431
|
}
|
|
26362
26432
|
const marker = formatProvenanceMarker(
|
|
26363
26433
|
"markdown",
|
|
26364
|
-
`rules/${
|
|
26434
|
+
`rules/${path32.basename(ruleFile)}`,
|
|
26365
26435
|
computeSourceHash(ruleFile),
|
|
26366
26436
|
"cursor"
|
|
26367
26437
|
);
|
|
@@ -26377,9 +26447,9 @@ ${body}`;
|
|
|
26377
26447
|
}
|
|
26378
26448
|
function compileClineRules(sourceRulesDir, lossReport) {
|
|
26379
26449
|
const dotRulesFiles = [];
|
|
26380
|
-
for (const ruleFile of ts(
|
|
26381
|
-
const content =
|
|
26382
|
-
const name =
|
|
26450
|
+
for (const ruleFile of ts(path32.join(sourceRulesDir, "*.md")).sort()) {
|
|
26451
|
+
const content = fs33.readFileSync(ruleFile, "utf8");
|
|
26452
|
+
const name = path32.basename(ruleFile, ".md");
|
|
26383
26453
|
let frontmatterData = {};
|
|
26384
26454
|
let body = content;
|
|
26385
26455
|
if (content.startsWith("---\n")) {
|
|
@@ -26396,13 +26466,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
26396
26466
|
}
|
|
26397
26467
|
const marker = formatProvenanceMarker(
|
|
26398
26468
|
"markdown",
|
|
26399
|
-
`rules/${
|
|
26469
|
+
`rules/${path32.basename(ruleFile)}`,
|
|
26400
26470
|
computeSourceHash(ruleFile),
|
|
26401
26471
|
"cline"
|
|
26402
26472
|
);
|
|
26403
26473
|
if (frontmatterData.mode === "exec-policy") {
|
|
26404
26474
|
addLoss(lossReport, "cline", "rules", {
|
|
26405
|
-
source: `rules/${
|
|
26475
|
+
source: `rules/${path32.basename(ruleFile)}`,
|
|
26406
26476
|
fields: [
|
|
26407
26477
|
{
|
|
26408
26478
|
field: "mode",
|
|
@@ -26412,7 +26482,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
26412
26482
|
"mode",
|
|
26413
26483
|
"rule-mode-downgrade"
|
|
26414
26484
|
),
|
|
26415
|
-
detail: `${
|
|
26485
|
+
detail: `${path32.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
|
|
26416
26486
|
}
|
|
26417
26487
|
]
|
|
26418
26488
|
});
|
|
@@ -26453,11 +26523,12 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
26453
26523
|
agents: profile.agents,
|
|
26454
26524
|
skills: profile.skills,
|
|
26455
26525
|
hooks_shared_file: profile.hooks_shared_file,
|
|
26526
|
+
hook_scripts: profile.hook_scripts,
|
|
26456
26527
|
mcp_shared_file: profile.mcp_shared_file,
|
|
26457
26528
|
rules: profile.rules
|
|
26458
26529
|
};
|
|
26459
26530
|
const rules = compileRules(
|
|
26460
|
-
|
|
26531
|
+
path33.join(sourceRoot, config.source.rules),
|
|
26461
26532
|
"codex",
|
|
26462
26533
|
mappings,
|
|
26463
26534
|
lossReport
|
|
@@ -26521,6 +26592,26 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
26521
26592
|
);
|
|
26522
26593
|
}
|
|
26523
26594
|
if (!shouldSkipComponent(options, "hooks")) {
|
|
26595
|
+
outcomes.push(
|
|
26596
|
+
syncHookScriptsBridge({
|
|
26597
|
+
source: path33.resolve(sourceRoot, config.source.hooks),
|
|
26598
|
+
destination: resolveTargetPath(paths.hook_scripts),
|
|
26599
|
+
config,
|
|
26600
|
+
sourceRoot,
|
|
26601
|
+
options,
|
|
26602
|
+
logger,
|
|
26603
|
+
onConflict: () => handleConflict(
|
|
26604
|
+
resolveTargetPath(paths.hook_scripts),
|
|
26605
|
+
config,
|
|
26606
|
+
options,
|
|
26607
|
+
logger,
|
|
26608
|
+
manifest,
|
|
26609
|
+
scopePath
|
|
26610
|
+
),
|
|
26611
|
+
manifest,
|
|
26612
|
+
scopePath
|
|
26613
|
+
})
|
|
26614
|
+
);
|
|
26524
26615
|
outcomes.push(
|
|
26525
26616
|
syncHooks(
|
|
26526
26617
|
config,
|
|
@@ -26602,9 +26693,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
26602
26693
|
function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
|
|
26603
26694
|
const cp = mappings.modelTiers.custom_provider;
|
|
26604
26695
|
if (!cp) return "";
|
|
26605
|
-
const agentsDir =
|
|
26606
|
-
if (!
|
|
26607
|
-
const agentFiles = ts(
|
|
26696
|
+
const agentsDir = path33.join(sourceRoot, config.source.agents);
|
|
26697
|
+
if (!fs34.existsSync(agentsDir)) return "";
|
|
26698
|
+
const agentFiles = ts(path33.join(agentsDir, "*.md")).sort();
|
|
26608
26699
|
const hasProviderAgent = agentFiles.some((agentFile) => {
|
|
26609
26700
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
26610
26701
|
return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
@@ -26669,7 +26760,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
26669
26760
|
}
|
|
26670
26761
|
];
|
|
26671
26762
|
for (const ruleFile of rules.dotRulesFiles) {
|
|
26672
|
-
const destination =
|
|
26763
|
+
const destination = path33.join(rulesRoot, ruleFile.name);
|
|
26673
26764
|
if (options.dryRun) {
|
|
26674
26765
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
26675
26766
|
outcomes.push({
|
|
@@ -26697,15 +26788,15 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
26697
26788
|
return outcomes;
|
|
26698
26789
|
}
|
|
26699
26790
|
function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
26700
|
-
const source =
|
|
26791
|
+
const source = path33.join(sourceRoot, config.source.instructions);
|
|
26701
26792
|
const destination = resolveTargetPath(paths.instructions);
|
|
26702
|
-
const composed = `${
|
|
26793
|
+
const composed = `${fs34.readFileSync(source, "utf8").trim()}
|
|
26703
26794
|
|
|
26704
26795
|
--- tangyr managed rules ---
|
|
26705
26796
|
${agentsAppendix}`.trim();
|
|
26706
26797
|
const marker = formatProvenanceMarker(
|
|
26707
26798
|
"markdown",
|
|
26708
|
-
|
|
26799
|
+
path33.basename(config.source.instructions),
|
|
26709
26800
|
hashString(composed),
|
|
26710
26801
|
"codex"
|
|
26711
26802
|
);
|
|
@@ -26732,9 +26823,9 @@ ${composed}
|
|
|
26732
26823
|
);
|
|
26733
26824
|
}
|
|
26734
26825
|
function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
26735
|
-
const source =
|
|
26826
|
+
const source = path33.resolve(sourceRoot, config.source.skills);
|
|
26736
26827
|
const destination = resolveTargetPath(paths.skills);
|
|
26737
|
-
if (!
|
|
26828
|
+
if (!fs34.existsSync(source)) {
|
|
26738
26829
|
return skippedMissingSource("skills", source);
|
|
26739
26830
|
}
|
|
26740
26831
|
if (options.dryRun) {
|
|
@@ -26742,7 +26833,7 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
26742
26833
|
return { component: "skills", status: "dry-run", path: destination };
|
|
26743
26834
|
}
|
|
26744
26835
|
const artifactClass = classifyArtifact(destination, config, sourceRoot);
|
|
26745
|
-
if (artifactClass === "managed-symlink" &&
|
|
26836
|
+
if (artifactClass === "managed-symlink" && isSymlinkTo2(destination, source)) {
|
|
26746
26837
|
return {
|
|
26747
26838
|
component: "skills",
|
|
26748
26839
|
status: "skipped-current",
|
|
@@ -26750,29 +26841,29 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
26750
26841
|
};
|
|
26751
26842
|
}
|
|
26752
26843
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
26753
|
-
|
|
26844
|
+
fs34.unlinkSync(destination);
|
|
26754
26845
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
26755
26846
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
|
|
26756
26847
|
return { component: "skills", status: "conflict", path: destination };
|
|
26757
26848
|
} else if (artifactClass === "managed-symlink") {
|
|
26758
|
-
|
|
26849
|
+
fs34.unlinkSync(destination);
|
|
26759
26850
|
}
|
|
26760
|
-
ensureDir(
|
|
26851
|
+
ensureDir(path33.dirname(destination));
|
|
26761
26852
|
createRelativeSymlink(source, destination, "dir");
|
|
26762
26853
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
26763
26854
|
return { component: "skills", status: "success", path: destination };
|
|
26764
26855
|
}
|
|
26765
26856
|
function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
26766
|
-
const sourceAgentsRoot =
|
|
26767
|
-
if (!
|
|
26857
|
+
const sourceAgentsRoot = path33.join(sourceRoot, config.source.agents);
|
|
26858
|
+
if (!fs34.existsSync(sourceAgentsRoot)) {
|
|
26768
26859
|
return [skippedMissingSource("agents", sourceAgentsRoot)];
|
|
26769
26860
|
}
|
|
26770
|
-
const sourceAgents = ts(
|
|
26861
|
+
const sourceAgents = ts(path33.join(sourceAgentsRoot, "*.md")).sort();
|
|
26771
26862
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
26772
26863
|
return sourceAgents.map((agentFile) => {
|
|
26773
|
-
const destination =
|
|
26864
|
+
const destination = path33.join(
|
|
26774
26865
|
agentsRoot,
|
|
26775
|
-
`${
|
|
26866
|
+
`${path33.basename(agentFile, ".md")}.toml`
|
|
26776
26867
|
);
|
|
26777
26868
|
const compiled = compileAgent(
|
|
26778
26869
|
agentFile,
|
|
@@ -26806,7 +26897,21 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
|
|
|
26806
26897
|
logger.warn(message);
|
|
26807
26898
|
return { component: "hooks", status: "skipped", path: message };
|
|
26808
26899
|
}
|
|
26809
|
-
const
|
|
26900
|
+
const scripts = hookScriptsDir(
|
|
26901
|
+
resolveTargetPath(paths.hook_scripts),
|
|
26902
|
+
"codex"
|
|
26903
|
+
);
|
|
26904
|
+
const hooksSource = loadKitHooksSource(sourceRoot, config, scripts.prefix);
|
|
26905
|
+
if (scripts.machineLocal) {
|
|
26906
|
+
addInformational(
|
|
26907
|
+
lossReport,
|
|
26908
|
+
"codex",
|
|
26909
|
+
"hooks",
|
|
26910
|
+
hooksSourceLabel(sourceRoot, config),
|
|
26911
|
+
"warning",
|
|
26912
|
+
machineLocalScriptPathNotice("codex", scripts.prefix)
|
|
26913
|
+
);
|
|
26914
|
+
}
|
|
26810
26915
|
if (!hooksSource) {
|
|
26811
26916
|
return skippedMissingSource(
|
|
26812
26917
|
"hooks",
|
|
@@ -26835,7 +26940,7 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
|
|
|
26835
26940
|
destination,
|
|
26836
26941
|
hostHooks,
|
|
26837
26942
|
stringifyJson2,
|
|
26838
|
-
!
|
|
26943
|
+
!fs34.existsSync(destination),
|
|
26839
26944
|
logger
|
|
26840
26945
|
);
|
|
26841
26946
|
return {
|
|
@@ -26848,7 +26953,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
|
|
|
26848
26953
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
26849
26954
|
const sourceLabel = mcpSourceLabel(config);
|
|
26850
26955
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
26851
|
-
if (!
|
|
26956
|
+
if (!fs34.existsSync(source)) {
|
|
26852
26957
|
if (providerToml && !options.dryRun) {
|
|
26853
26958
|
const changed2 = writeTomlManagedSection(
|
|
26854
26959
|
destination,
|
|
@@ -26863,7 +26968,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
|
|
|
26863
26968
|
}
|
|
26864
26969
|
return skippedMissingSource("mcp", source);
|
|
26865
26970
|
}
|
|
26866
|
-
const sourceMcpJson = JSON.parse(
|
|
26971
|
+
const sourceMcpJson = JSON.parse(fs34.readFileSync(source, "utf8"));
|
|
26867
26972
|
const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
|
|
26868
26973
|
const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
|
|
26869
26974
|
if (options.dryRun) {
|
|
@@ -26885,12 +26990,12 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
|
|
|
26885
26990
|
if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
|
|
26886
26991
|
return { component, status: "conflict", path: destination };
|
|
26887
26992
|
}
|
|
26888
|
-
ensureDir(
|
|
26889
|
-
|
|
26993
|
+
ensureDir(path33.dirname(destination));
|
|
26994
|
+
fs34.writeFileSync(destination, content);
|
|
26890
26995
|
return { component, status: "success", path: destination };
|
|
26891
26996
|
}
|
|
26892
26997
|
function writeTomlManagedSection(destination, managedContent, logger) {
|
|
26893
|
-
const current =
|
|
26998
|
+
const current = fs34.existsSync(destination) ? fs34.readFileSync(destination, "utf8") : "";
|
|
26894
26999
|
const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
|
|
26895
27000
|
if (isFirstWrite) {
|
|
26896
27001
|
logger.warn(
|
|
@@ -26906,8 +27011,8 @@ ${managedMcpEnd}
|
|
|
26906
27011
|
if (current === next.trimStart()) {
|
|
26907
27012
|
return false;
|
|
26908
27013
|
}
|
|
26909
|
-
ensureDir(
|
|
26910
|
-
|
|
27014
|
+
ensureDir(path33.dirname(destination));
|
|
27015
|
+
fs34.writeFileSync(destination, next.trimStart());
|
|
26911
27016
|
return true;
|
|
26912
27017
|
}
|
|
26913
27018
|
function removeManagedTomlSection(content) {
|
|
@@ -26934,16 +27039,16 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
|
|
|
26934
27039
|
backupFile(destination, manifest);
|
|
26935
27040
|
writeManifest(scopePath, manifest);
|
|
26936
27041
|
} else {
|
|
26937
|
-
|
|
27042
|
+
fs34.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
26938
27043
|
}
|
|
26939
27044
|
return true;
|
|
26940
27045
|
}
|
|
26941
|
-
|
|
27046
|
+
fs34.rmSync(destination, { recursive: true, force: true });
|
|
26942
27047
|
return true;
|
|
26943
27048
|
}
|
|
26944
27049
|
function isCompiledCurrent(destination, expectedContent, expectedHash) {
|
|
26945
27050
|
try {
|
|
26946
|
-
const current =
|
|
27051
|
+
const current = fs34.readFileSync(destination, "utf8");
|
|
26947
27052
|
const marker = extractProvenanceMarker(current);
|
|
26948
27053
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "codex" && current === expectedContent : current === expectedContent;
|
|
26949
27054
|
} catch {
|
|
@@ -26960,18 +27065,18 @@ function skippedMissingSource(component, source) {
|
|
|
26960
27065
|
function shouldSkipComponent(options, component) {
|
|
26961
27066
|
return Boolean(options.component && options.component !== component);
|
|
26962
27067
|
}
|
|
26963
|
-
function
|
|
27068
|
+
function isSymlinkTo2(linkPath, source) {
|
|
26964
27069
|
try {
|
|
26965
|
-
return
|
|
27070
|
+
return fs34.realpathSync(linkPath) === fs34.realpathSync(source);
|
|
26966
27071
|
} catch {
|
|
26967
27072
|
return false;
|
|
26968
27073
|
}
|
|
26969
27074
|
}
|
|
26970
27075
|
function readJsonObject3(filePath) {
|
|
26971
|
-
if (!
|
|
27076
|
+
if (!fs34.existsSync(filePath)) {
|
|
26972
27077
|
return {};
|
|
26973
27078
|
}
|
|
26974
|
-
const parsed = JSON.parse(
|
|
27079
|
+
const parsed = JSON.parse(fs34.readFileSync(filePath, "utf8"));
|
|
26975
27080
|
return isRecord4(parsed) ? parsed : {};
|
|
26976
27081
|
}
|
|
26977
27082
|
function stringifyJson2(value) {
|
|
@@ -26987,16 +27092,16 @@ function hashString(value) {
|
|
|
26987
27092
|
|
|
26988
27093
|
// src/adapters/copilot.ts
|
|
26989
27094
|
import crypto6 from "crypto";
|
|
26990
|
-
import
|
|
26991
|
-
import
|
|
27095
|
+
import fs35 from "fs";
|
|
27096
|
+
import path35 from "path";
|
|
26992
27097
|
|
|
26993
27098
|
// src/compiler/commands.ts
|
|
26994
27099
|
var import_yaml10 = __toESM(require_dist(), 1);
|
|
26995
|
-
import
|
|
27100
|
+
import path34 from "path";
|
|
26996
27101
|
function compileCommandPrompt(sourceFile) {
|
|
26997
27102
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
26998
|
-
const relativeSource = `commands/${
|
|
26999
|
-
const fields = promptFrontmatter(data,
|
|
27103
|
+
const relativeSource = `commands/${path34.basename(sourceFile)}`;
|
|
27104
|
+
const fields = promptFrontmatter(data, path34.basename(sourceFile, ".md"));
|
|
27000
27105
|
const marker = formatProvenanceMarker(
|
|
27001
27106
|
"markdown",
|
|
27002
27107
|
relativeSource,
|
|
@@ -27048,6 +27153,7 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
27048
27153
|
skills: profile.skills,
|
|
27049
27154
|
prompts: profile.prompts,
|
|
27050
27155
|
hooks: profile.hooks,
|
|
27156
|
+
hook_scripts: profile.hook_scripts,
|
|
27051
27157
|
mcp_shared_file: profile.mcp_shared_file
|
|
27052
27158
|
};
|
|
27053
27159
|
const outcomes = [];
|
|
@@ -27108,6 +27214,26 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
27108
27214
|
);
|
|
27109
27215
|
}
|
|
27110
27216
|
if (!shouldSkipComponent2(options, "hooks")) {
|
|
27217
|
+
outcomes.push(
|
|
27218
|
+
syncHookScriptsBridge({
|
|
27219
|
+
source: path35.resolve(sourceRoot, config.source.hooks),
|
|
27220
|
+
destination: resolveTargetPath(paths.hook_scripts),
|
|
27221
|
+
config,
|
|
27222
|
+
sourceRoot,
|
|
27223
|
+
options,
|
|
27224
|
+
logger,
|
|
27225
|
+
onConflict: () => handleConflict2(
|
|
27226
|
+
resolveTargetPath(paths.hook_scripts),
|
|
27227
|
+
config,
|
|
27228
|
+
options,
|
|
27229
|
+
logger,
|
|
27230
|
+
manifest,
|
|
27231
|
+
scopePath
|
|
27232
|
+
),
|
|
27233
|
+
manifest,
|
|
27234
|
+
scopePath
|
|
27235
|
+
})
|
|
27236
|
+
);
|
|
27111
27237
|
outcomes.push(
|
|
27112
27238
|
syncHooks2(
|
|
27113
27239
|
config,
|
|
@@ -27171,13 +27297,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
27171
27297
|
}
|
|
27172
27298
|
function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
|
|
27173
27299
|
if (!mappings.modelTiers.custom_provider) return;
|
|
27174
|
-
const agentsDir =
|
|
27175
|
-
if (!
|
|
27176
|
-
for (const agentFile of ts(
|
|
27300
|
+
const agentsDir = path35.join(sourceRoot, config.source.agents);
|
|
27301
|
+
if (!fs35.existsSync(agentsDir)) return;
|
|
27302
|
+
for (const agentFile of ts(path35.join(agentsDir, "*.md")).sort()) {
|
|
27177
27303
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
27178
27304
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
27179
27305
|
if (hasProvider) {
|
|
27180
|
-
const basename =
|
|
27306
|
+
const basename = path35.basename(agentFile);
|
|
27181
27307
|
addLoss(lossReport, "copilot", "agents", {
|
|
27182
27308
|
source: `agents/${basename}`,
|
|
27183
27309
|
fields: [
|
|
@@ -27202,23 +27328,23 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
|
|
|
27202
27328
|
logger.verbose(message);
|
|
27203
27329
|
return [{ component: "instructions", status: "skipped", path: message }];
|
|
27204
27330
|
}
|
|
27205
|
-
const source =
|
|
27206
|
-
if (!
|
|
27331
|
+
const source = path35.resolve(sourceRoot, config.source.instructions);
|
|
27332
|
+
if (!fs35.existsSync(source)) {
|
|
27207
27333
|
return [skippedMissingSource2("instructions", source)];
|
|
27208
27334
|
}
|
|
27209
|
-
const rawContent =
|
|
27335
|
+
const rawContent = fs35.readFileSync(source, "utf8");
|
|
27210
27336
|
const contentHash = hashString2(rawContent);
|
|
27211
27337
|
const marker = formatProvenanceMarker(
|
|
27212
27338
|
"markdown",
|
|
27213
|
-
|
|
27339
|
+
path35.basename(config.source.instructions),
|
|
27214
27340
|
contentHash,
|
|
27215
27341
|
"copilot"
|
|
27216
27342
|
);
|
|
27217
27343
|
const composedContent = `${marker}
|
|
27218
27344
|
${rawContent}`;
|
|
27219
27345
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
27220
|
-
const agentsMdDest =
|
|
27221
|
-
const mirrorDest =
|
|
27346
|
+
const agentsMdDest = path35.resolve(projectRoot, "AGENTS.md");
|
|
27347
|
+
const mirrorDest = path35.resolve(
|
|
27222
27348
|
projectRoot,
|
|
27223
27349
|
".github",
|
|
27224
27350
|
"copilot-instructions.md"
|
|
@@ -27272,17 +27398,17 @@ function writeInstructionsFile(component, destination, content, contentHash, con
|
|
|
27272
27398
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
27273
27399
|
return { component, status: "conflict", path: destination };
|
|
27274
27400
|
}
|
|
27275
|
-
ensureDir(
|
|
27276
|
-
|
|
27401
|
+
ensureDir(path35.dirname(destination));
|
|
27402
|
+
fs35.writeFileSync(destination, content);
|
|
27277
27403
|
return { component, status: "success", path: destination };
|
|
27278
27404
|
}
|
|
27279
27405
|
function hashString2(value) {
|
|
27280
27406
|
return `sha256:${crypto6.createHash("sha256").update(value).digest("hex")}`;
|
|
27281
27407
|
}
|
|
27282
27408
|
function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
27283
|
-
const source =
|
|
27409
|
+
const source = path35.resolve(sourceRoot, config.source.skills);
|
|
27284
27410
|
const destination = resolveTargetPath(paths.skills);
|
|
27285
|
-
if (!
|
|
27411
|
+
if (!fs35.existsSync(source)) {
|
|
27286
27412
|
return skippedMissingSource2("skills", source);
|
|
27287
27413
|
}
|
|
27288
27414
|
if (options.dryRun) {
|
|
@@ -27290,7 +27416,7 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
27290
27416
|
return { component: "skills", status: "dry-run", path: destination };
|
|
27291
27417
|
}
|
|
27292
27418
|
const artifactClass = classifyArtifact(destination, config, sourceRoot);
|
|
27293
|
-
if (artifactClass === "managed-symlink" &&
|
|
27419
|
+
if (artifactClass === "managed-symlink" && isSymlinkTo3(destination, source)) {
|
|
27294
27420
|
return {
|
|
27295
27421
|
component: "skills",
|
|
27296
27422
|
status: "skipped-current",
|
|
@@ -27298,27 +27424,27 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
27298
27424
|
};
|
|
27299
27425
|
}
|
|
27300
27426
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
27301
|
-
|
|
27427
|
+
fs35.unlinkSync(destination);
|
|
27302
27428
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
27303
27429
|
return { component: "skills", status: "conflict", path: destination };
|
|
27304
27430
|
} else if (artifactClass === "managed-symlink") {
|
|
27305
|
-
|
|
27431
|
+
fs35.unlinkSync(destination);
|
|
27306
27432
|
}
|
|
27307
|
-
ensureDir(
|
|
27433
|
+
ensureDir(path35.dirname(destination));
|
|
27308
27434
|
createRelativeSymlink(source, destination, "dir");
|
|
27309
27435
|
return { component: "skills", status: "success", path: destination };
|
|
27310
27436
|
}
|
|
27311
27437
|
function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
27312
|
-
const sourceAgentsRoot =
|
|
27313
|
-
if (!
|
|
27438
|
+
const sourceAgentsRoot = path35.join(sourceRoot, config.source.agents);
|
|
27439
|
+
if (!fs35.existsSync(sourceAgentsRoot)) {
|
|
27314
27440
|
return [skippedMissingSource2("agents", sourceAgentsRoot)];
|
|
27315
27441
|
}
|
|
27316
|
-
const sourceAgents = ts(
|
|
27442
|
+
const sourceAgents = ts(path35.join(sourceAgentsRoot, "*.md")).sort();
|
|
27317
27443
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
27318
27444
|
return sourceAgents.map((agentFile) => {
|
|
27319
|
-
const destination =
|
|
27445
|
+
const destination = path35.join(
|
|
27320
27446
|
agentsRoot,
|
|
27321
|
-
`${
|
|
27447
|
+
`${path35.basename(agentFile, ".md")}.agent.md`
|
|
27322
27448
|
);
|
|
27323
27449
|
const compiled = compileAgent(
|
|
27324
27450
|
agentFile,
|
|
@@ -27346,16 +27472,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
27346
27472
|
});
|
|
27347
27473
|
}
|
|
27348
27474
|
function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
27349
|
-
const sourceCommandsRoot =
|
|
27350
|
-
if (!
|
|
27475
|
+
const sourceCommandsRoot = path35.join(sourceRoot, config.source.commands);
|
|
27476
|
+
if (!fs35.existsSync(sourceCommandsRoot)) {
|
|
27351
27477
|
return [skippedMissingSource2("commands", sourceCommandsRoot)];
|
|
27352
27478
|
}
|
|
27353
|
-
const sourceCommands = ts(
|
|
27479
|
+
const sourceCommands = ts(path35.join(sourceCommandsRoot, "*.md")).sort();
|
|
27354
27480
|
const promptsRoot = resolveTargetPath(paths.prompts);
|
|
27355
27481
|
return sourceCommands.map((commandFile) => {
|
|
27356
|
-
const destination =
|
|
27482
|
+
const destination = path35.join(
|
|
27357
27483
|
promptsRoot,
|
|
27358
|
-
`${
|
|
27484
|
+
`${path35.basename(commandFile, ".md")}.prompt.md`
|
|
27359
27485
|
);
|
|
27360
27486
|
const compiled = compileCommandPrompt(commandFile);
|
|
27361
27487
|
if (options.dryRun) {
|
|
@@ -27379,11 +27505,25 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
|
|
|
27379
27505
|
});
|
|
27380
27506
|
}
|
|
27381
27507
|
function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
27382
|
-
const destination =
|
|
27508
|
+
const destination = path35.join(
|
|
27383
27509
|
resolveTargetPath(paths.hooks),
|
|
27384
27510
|
"tangyr-managed.json"
|
|
27385
27511
|
);
|
|
27386
|
-
const
|
|
27512
|
+
const scripts = hookScriptsDir(
|
|
27513
|
+
resolveTargetPath(paths.hook_scripts),
|
|
27514
|
+
"copilot"
|
|
27515
|
+
);
|
|
27516
|
+
const hooksSource = loadKitHooksSource(sourceRoot, config, scripts.prefix);
|
|
27517
|
+
if (scripts.machineLocal) {
|
|
27518
|
+
addInformational(
|
|
27519
|
+
lossReport,
|
|
27520
|
+
"copilot",
|
|
27521
|
+
"hooks",
|
|
27522
|
+
hooksSourceLabel(sourceRoot, config),
|
|
27523
|
+
"warning",
|
|
27524
|
+
machineLocalScriptPathNotice("copilot", scripts.prefix)
|
|
27525
|
+
);
|
|
27526
|
+
}
|
|
27387
27527
|
if (!hooksSource) {
|
|
27388
27528
|
return skippedMissingSource2(
|
|
27389
27529
|
"hooks",
|
|
@@ -27427,10 +27567,10 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
27427
27567
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
27428
27568
|
const sourceLabel = mcpSourceLabel(config);
|
|
27429
27569
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
27430
|
-
if (!
|
|
27570
|
+
if (!fs35.existsSync(source)) {
|
|
27431
27571
|
return skippedMissingSource2("mcp", source);
|
|
27432
27572
|
}
|
|
27433
|
-
const sourceMcpJson = JSON.parse(
|
|
27573
|
+
const sourceMcpJson = JSON.parse(fs35.readFileSync(source, "utf8"));
|
|
27434
27574
|
const compiled = compileMcp(
|
|
27435
27575
|
sourceMcpJson,
|
|
27436
27576
|
"copilot",
|
|
@@ -27460,13 +27600,13 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
|
|
|
27460
27600
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
27461
27601
|
return { component, status: "conflict", path: destination };
|
|
27462
27602
|
}
|
|
27463
|
-
ensureDir(
|
|
27464
|
-
|
|
27603
|
+
ensureDir(path35.dirname(destination));
|
|
27604
|
+
fs35.writeFileSync(destination, content);
|
|
27465
27605
|
return { component, status: "success", path: destination };
|
|
27466
27606
|
}
|
|
27467
27607
|
function isCompiledCurrent2(destination, expectedContent, expectedHash) {
|
|
27468
27608
|
try {
|
|
27469
|
-
const current =
|
|
27609
|
+
const current = fs35.readFileSync(destination, "utf8");
|
|
27470
27610
|
const marker = extractProvenanceMarker(current);
|
|
27471
27611
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "copilot" && current === expectedContent : current === expectedContent;
|
|
27472
27612
|
} catch {
|
|
@@ -27489,11 +27629,11 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
|
|
|
27489
27629
|
backupFile(destination, manifest);
|
|
27490
27630
|
writeManifest(scopePath, manifest);
|
|
27491
27631
|
} else {
|
|
27492
|
-
|
|
27632
|
+
fs35.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
27493
27633
|
}
|
|
27494
27634
|
return true;
|
|
27495
27635
|
}
|
|
27496
|
-
|
|
27636
|
+
fs35.rmSync(destination, { recursive: true, force: true });
|
|
27497
27637
|
return true;
|
|
27498
27638
|
}
|
|
27499
27639
|
function shouldSkipComponent2(options, component) {
|
|
@@ -27502,12 +27642,12 @@ function shouldSkipComponent2(options, component) {
|
|
|
27502
27642
|
function cleanupLegacyAgents(paths, options, logger) {
|
|
27503
27643
|
const currentAgentsRoot = resolveTargetPath(paths.agents);
|
|
27504
27644
|
const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
|
|
27505
|
-
if (
|
|
27645
|
+
if (path35.resolve(currentAgentsRoot) === path35.resolve(legacyAgentsRoot)) {
|
|
27506
27646
|
return [];
|
|
27507
27647
|
}
|
|
27508
27648
|
const outcomes = [];
|
|
27509
27649
|
for (const filePath of ts(
|
|
27510
|
-
|
|
27650
|
+
path35.join(legacyAgentsRoot, "*.agent.md")
|
|
27511
27651
|
).sort()) {
|
|
27512
27652
|
if (!isCopilotManagedCompiledFile(filePath)) {
|
|
27513
27653
|
continue;
|
|
@@ -27517,14 +27657,14 @@ function cleanupLegacyAgents(paths, options, logger) {
|
|
|
27517
27657
|
outcomes.push({ component: "agents", status: "dry-run", path: filePath });
|
|
27518
27658
|
continue;
|
|
27519
27659
|
}
|
|
27520
|
-
|
|
27660
|
+
fs35.rmSync(filePath, { force: true });
|
|
27521
27661
|
outcomes.push({ component: "agents", status: "success", path: filePath });
|
|
27522
27662
|
}
|
|
27523
27663
|
return outcomes;
|
|
27524
27664
|
}
|
|
27525
27665
|
function isCopilotManagedCompiledFile(filePath) {
|
|
27526
27666
|
try {
|
|
27527
|
-
return extractProvenanceMarker(
|
|
27667
|
+
return extractProvenanceMarker(fs35.readFileSync(filePath, "utf8"))?.target === "copilot";
|
|
27528
27668
|
} catch {
|
|
27529
27669
|
return false;
|
|
27530
27670
|
}
|
|
@@ -27536,9 +27676,9 @@ function skippedMissingSource2(component, source) {
|
|
|
27536
27676
|
path: `${source}: source not configured`
|
|
27537
27677
|
};
|
|
27538
27678
|
}
|
|
27539
|
-
function
|
|
27679
|
+
function isSymlinkTo3(linkPath, source) {
|
|
27540
27680
|
try {
|
|
27541
|
-
return
|
|
27681
|
+
return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
|
|
27542
27682
|
} catch {
|
|
27543
27683
|
return false;
|
|
27544
27684
|
}
|
|
@@ -27546,8 +27686,8 @@ function isSymlinkTo2(linkPath, source) {
|
|
|
27546
27686
|
|
|
27547
27687
|
// src/adapters/cursor.ts
|
|
27548
27688
|
import crypto7 from "crypto";
|
|
27549
|
-
import
|
|
27550
|
-
import
|
|
27689
|
+
import fs36 from "fs";
|
|
27690
|
+
import path36 from "path";
|
|
27551
27691
|
function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
27552
27692
|
const scope = options.scope ?? "global";
|
|
27553
27693
|
const profile = resolveTargetPaths({
|
|
@@ -27562,6 +27702,7 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
27562
27702
|
skills: profile.skills,
|
|
27563
27703
|
skills_shared: profile.skills_shared,
|
|
27564
27704
|
hooks_file: profile.hooks_file,
|
|
27705
|
+
hook_scripts: profile.hook_scripts,
|
|
27565
27706
|
mcp_file: profile.mcp_file,
|
|
27566
27707
|
permissions_file: profile.permissions_file
|
|
27567
27708
|
};
|
|
@@ -27656,6 +27797,26 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
27656
27797
|
);
|
|
27657
27798
|
}
|
|
27658
27799
|
if (!shouldSkipComponent3(options, "hooks")) {
|
|
27800
|
+
outcomes.push(
|
|
27801
|
+
syncHookScriptsBridge({
|
|
27802
|
+
source: path36.resolve(sourceRoot, config.source.hooks),
|
|
27803
|
+
destination: resolveTargetPath(paths.hook_scripts),
|
|
27804
|
+
config,
|
|
27805
|
+
sourceRoot,
|
|
27806
|
+
options,
|
|
27807
|
+
logger,
|
|
27808
|
+
onConflict: () => handleConflict3(
|
|
27809
|
+
resolveTargetPath(paths.hook_scripts),
|
|
27810
|
+
config,
|
|
27811
|
+
options,
|
|
27812
|
+
logger,
|
|
27813
|
+
manifest,
|
|
27814
|
+
scopePath
|
|
27815
|
+
),
|
|
27816
|
+
manifest,
|
|
27817
|
+
scopePath
|
|
27818
|
+
})
|
|
27819
|
+
);
|
|
27659
27820
|
outcomes.push(
|
|
27660
27821
|
syncHooks3(
|
|
27661
27822
|
config,
|
|
@@ -27698,9 +27859,9 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
27698
27859
|
return { target: "cursor", outcomes };
|
|
27699
27860
|
}
|
|
27700
27861
|
function syncInstructions2(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
|
|
27701
|
-
const source =
|
|
27862
|
+
const source = path36.join(sourceRoot, config.source.instructions);
|
|
27702
27863
|
const destination = resolveTargetPath(paths.instructions);
|
|
27703
|
-
const baseContent =
|
|
27864
|
+
const baseContent = fs36.existsSync(source) ? fs36.readFileSync(source, "utf8").trim() : "";
|
|
27704
27865
|
const personaContent = extractPrimaryPersonaContent(
|
|
27705
27866
|
config,
|
|
27706
27867
|
sourceRoot,
|
|
@@ -27713,7 +27874,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
|
|
|
27713
27874
|
${personaContent}`.trim() : baseContent;
|
|
27714
27875
|
const marker = formatProvenanceMarker(
|
|
27715
27876
|
"markdown",
|
|
27716
|
-
|
|
27877
|
+
path36.basename(config.source.instructions),
|
|
27717
27878
|
hashString3(composed),
|
|
27718
27879
|
"cursor"
|
|
27719
27880
|
);
|
|
@@ -27738,11 +27899,11 @@ ${composed}
|
|
|
27738
27899
|
);
|
|
27739
27900
|
}
|
|
27740
27901
|
function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
27741
|
-
const agentsDir =
|
|
27742
|
-
if (!
|
|
27902
|
+
const agentsDir = path36.join(sourceRoot, config.source.agents);
|
|
27903
|
+
if (!fs36.existsSync(agentsDir)) {
|
|
27743
27904
|
return null;
|
|
27744
27905
|
}
|
|
27745
|
-
const agentFiles = ts(
|
|
27906
|
+
const agentFiles = ts(path36.join(agentsDir, "*.md")).sort();
|
|
27746
27907
|
if (agentFiles.length === 0) {
|
|
27747
27908
|
return null;
|
|
27748
27909
|
}
|
|
@@ -27765,7 +27926,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
27765
27926
|
return null;
|
|
27766
27927
|
}
|
|
27767
27928
|
addLoss(lossReport, "cursor", "instructions", {
|
|
27768
|
-
source: `agents/${
|
|
27929
|
+
source: `agents/${path36.basename(primaryFile)}`,
|
|
27769
27930
|
fields: [
|
|
27770
27931
|
{
|
|
27771
27932
|
field: "persona",
|
|
@@ -27775,23 +27936,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
27775
27936
|
"persona",
|
|
27776
27937
|
"instructions-shim"
|
|
27777
27938
|
),
|
|
27778
|
-
detail: `Primary persona from ${
|
|
27939
|
+
detail: `Primary persona from ${path36.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
|
|
27779
27940
|
}
|
|
27780
27941
|
]
|
|
27781
27942
|
});
|
|
27782
27943
|
return body.trim();
|
|
27783
27944
|
}
|
|
27784
27945
|
function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
27785
|
-
const sourceAgentsRoot =
|
|
27786
|
-
if (!
|
|
27946
|
+
const sourceAgentsRoot = path36.join(sourceRoot, config.source.agents);
|
|
27947
|
+
if (!fs36.existsSync(sourceAgentsRoot)) {
|
|
27787
27948
|
return [skippedMissingSource3("agents", sourceAgentsRoot)];
|
|
27788
27949
|
}
|
|
27789
|
-
const sourceAgents = ts(
|
|
27950
|
+
const sourceAgents = ts(path36.join(sourceAgentsRoot, "*.md")).sort();
|
|
27790
27951
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
27791
27952
|
return sourceAgents.map((agentFile) => {
|
|
27792
|
-
const destination =
|
|
27953
|
+
const destination = path36.join(
|
|
27793
27954
|
agentsRoot,
|
|
27794
|
-
`${
|
|
27955
|
+
`${path36.basename(agentFile, ".md")}.md`
|
|
27795
27956
|
);
|
|
27796
27957
|
let compiled;
|
|
27797
27958
|
try {
|
|
@@ -27832,14 +27993,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
27832
27993
|
});
|
|
27833
27994
|
}
|
|
27834
27995
|
function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
27835
|
-
const sourceRulesDir =
|
|
27836
|
-
if (!
|
|
27996
|
+
const sourceRulesDir = path36.join(sourceRoot, config.source.rules);
|
|
27997
|
+
if (!fs36.existsSync(sourceRulesDir)) {
|
|
27837
27998
|
return [skippedMissingSource3("rules", sourceRulesDir)];
|
|
27838
27999
|
}
|
|
27839
28000
|
const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
|
|
27840
28001
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
27841
28002
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
27842
|
-
const destination =
|
|
28003
|
+
const destination = path36.join(rulesDir, name);
|
|
27843
28004
|
if (options.dryRun) {
|
|
27844
28005
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
27845
28006
|
return {
|
|
@@ -27863,17 +28024,17 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
27863
28024
|
});
|
|
27864
28025
|
}
|
|
27865
28026
|
function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
27866
|
-
const sourceCommandsRoot =
|
|
27867
|
-
if (!
|
|
28027
|
+
const sourceCommandsRoot = path36.join(sourceRoot, config.source.commands);
|
|
28028
|
+
if (!fs36.existsSync(sourceCommandsRoot)) {
|
|
27868
28029
|
return [skippedMissingSource3("commands", sourceCommandsRoot)];
|
|
27869
28030
|
}
|
|
27870
|
-
const sourceCommands = ts(
|
|
28031
|
+
const sourceCommands = ts(path36.join(sourceCommandsRoot, "*.md")).sort();
|
|
27871
28032
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
27872
28033
|
return sourceCommands.map((commandFile) => {
|
|
27873
|
-
const baseName =
|
|
27874
|
-
const destination =
|
|
27875
|
-
const commandContent =
|
|
27876
|
-
const relativeSource = `commands/${
|
|
28034
|
+
const baseName = path36.basename(commandFile, ".md");
|
|
28035
|
+
const destination = path36.join(skillsRoot, baseName, "SKILL.md");
|
|
28036
|
+
const commandContent = fs36.readFileSync(commandFile, "utf8");
|
|
28037
|
+
const relativeSource = `commands/${path36.basename(commandFile)}`;
|
|
27877
28038
|
const marker = formatProvenanceMarker(
|
|
27878
28039
|
"markdown",
|
|
27879
28040
|
relativeSource,
|
|
@@ -27912,8 +28073,8 @@ ${commandContent.trim()}
|
|
|
27912
28073
|
});
|
|
27913
28074
|
}
|
|
27914
28075
|
function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
|
|
27915
|
-
const source =
|
|
27916
|
-
if (!
|
|
28076
|
+
const source = path36.resolve(sourceRoot, config.source.skills);
|
|
28077
|
+
if (!fs36.existsSync(source)) {
|
|
27917
28078
|
return skippedMissingSource3(component, source);
|
|
27918
28079
|
}
|
|
27919
28080
|
if (options.dryRun) {
|
|
@@ -27923,22 +28084,22 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
|
|
|
27923
28084
|
}
|
|
27924
28085
|
if (asSymlink) {
|
|
27925
28086
|
const artifactClass = classifyArtifact(destination, config, sourceRoot);
|
|
27926
|
-
if (artifactClass === "managed-symlink" &&
|
|
28087
|
+
if (artifactClass === "managed-symlink" && isSymlinkTo4(destination, source)) {
|
|
27927
28088
|
return { component, status: "skipped-current", path: destination };
|
|
27928
28089
|
}
|
|
27929
28090
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
27930
|
-
|
|
28091
|
+
fs36.unlinkSync(destination);
|
|
27931
28092
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
27932
28093
|
return { component, status: "conflict", path: destination };
|
|
27933
28094
|
} else if (artifactClass === "managed-symlink") {
|
|
27934
|
-
|
|
28095
|
+
fs36.unlinkSync(destination);
|
|
27935
28096
|
}
|
|
27936
|
-
ensureDir(
|
|
28097
|
+
ensureDir(path36.dirname(destination));
|
|
27937
28098
|
createRelativeSymlink(source, destination, "dir");
|
|
27938
28099
|
logger.verbose(`Skills: created shared skills symlink ${destination}`);
|
|
27939
28100
|
return { component, status: "success", path: destination };
|
|
27940
28101
|
}
|
|
27941
|
-
if (
|
|
28102
|
+
if (fs36.existsSync(destination)) {
|
|
27942
28103
|
return { component, status: "skipped-current", path: destination };
|
|
27943
28104
|
}
|
|
27944
28105
|
ensureDir(destination);
|
|
@@ -27946,7 +28107,21 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
|
|
|
27946
28107
|
return { component, status: "success", path: destination };
|
|
27947
28108
|
}
|
|
27948
28109
|
function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
27949
|
-
const
|
|
28110
|
+
const scripts = hookScriptsDir(
|
|
28111
|
+
resolveTargetPath(paths.hook_scripts),
|
|
28112
|
+
"cursor"
|
|
28113
|
+
);
|
|
28114
|
+
const hooksSource = loadKitHooksSource(sourceRoot, config, scripts.prefix);
|
|
28115
|
+
if (scripts.machineLocal) {
|
|
28116
|
+
addInformational(
|
|
28117
|
+
lossReport,
|
|
28118
|
+
"cursor",
|
|
28119
|
+
"hooks",
|
|
28120
|
+
hooksSourceLabel(sourceRoot, config),
|
|
28121
|
+
"warning",
|
|
28122
|
+
machineLocalScriptPathNotice("cursor", scripts.prefix)
|
|
28123
|
+
);
|
|
28124
|
+
}
|
|
27950
28125
|
const source = hooksSource?.path ?? resolveHooksSourceDir(sourceRoot, config);
|
|
27951
28126
|
const sourceLabel = hooksSource?.label ?? hooksSourceLabel(sourceRoot, config);
|
|
27952
28127
|
const destination = resolveTargetPath(paths.hooks_file);
|
|
@@ -27964,18 +28139,18 @@ function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
27964
28139
|
}
|
|
27965
28140
|
const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
|
|
27966
28141
|
`;
|
|
27967
|
-
ensureDir(
|
|
27968
|
-
|
|
28142
|
+
ensureDir(path36.dirname(destination));
|
|
28143
|
+
fs36.writeFileSync(destination, hooksFileContent);
|
|
27969
28144
|
return { component: "hooks", status: "success", path: destination };
|
|
27970
28145
|
}
|
|
27971
28146
|
function syncMcp3(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
|
|
27972
28147
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
27973
28148
|
const sourceLabel = mcpSourceLabel(config);
|
|
27974
28149
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
27975
|
-
if (!
|
|
28150
|
+
if (!fs36.existsSync(source)) {
|
|
27976
28151
|
return skippedMissingSource3("mcp", source);
|
|
27977
28152
|
}
|
|
27978
|
-
const sourceMcpJson = JSON.parse(
|
|
28153
|
+
const sourceMcpJson = JSON.parse(fs36.readFileSync(source, "utf8"));
|
|
27979
28154
|
const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
|
|
27980
28155
|
if (options.dryRun) {
|
|
27981
28156
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -28026,13 +28201,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
|
|
|
28026
28201
|
);
|
|
28027
28202
|
}
|
|
28028
28203
|
function syncProviderPin(config, sourceRoot, lossReport) {
|
|
28029
|
-
const agentsDir =
|
|
28030
|
-
if (!
|
|
28031
|
-
for (const agentFile of ts(
|
|
28204
|
+
const agentsDir = path36.join(sourceRoot, config.source.agents);
|
|
28205
|
+
if (!fs36.existsSync(agentsDir)) return;
|
|
28206
|
+
for (const agentFile of ts(path36.join(agentsDir, "*.md")).sort()) {
|
|
28032
28207
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28033
28208
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
28034
28209
|
if (hasCustomProvider) {
|
|
28035
|
-
const relativeSource = `agents/${
|
|
28210
|
+
const relativeSource = `agents/${path36.basename(agentFile)}`;
|
|
28036
28211
|
addLoss(lossReport, "cursor", "agents", {
|
|
28037
28212
|
source: relativeSource,
|
|
28038
28213
|
fields: [
|
|
@@ -28044,7 +28219,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
|
|
|
28044
28219
|
"provider",
|
|
28045
28220
|
"provider-not-representable"
|
|
28046
28221
|
),
|
|
28047
|
-
detail: `${
|
|
28222
|
+
detail: `${path36.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
28048
28223
|
}
|
|
28049
28224
|
]
|
|
28050
28225
|
});
|
|
@@ -28059,8 +28234,8 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
|
|
|
28059
28234
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
28060
28235
|
return { component, status: "conflict", path: destination };
|
|
28061
28236
|
}
|
|
28062
|
-
ensureDir(
|
|
28063
|
-
|
|
28237
|
+
ensureDir(path36.dirname(destination));
|
|
28238
|
+
fs36.writeFileSync(destination, content);
|
|
28064
28239
|
return { component, status: "success", path: destination };
|
|
28065
28240
|
}
|
|
28066
28241
|
function handleConflict3(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -28079,16 +28254,16 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
|
|
|
28079
28254
|
backupFile(destination, manifest);
|
|
28080
28255
|
writeManifest(scopePath, manifest);
|
|
28081
28256
|
} else {
|
|
28082
|
-
|
|
28257
|
+
fs36.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
28083
28258
|
}
|
|
28084
28259
|
return true;
|
|
28085
28260
|
}
|
|
28086
|
-
|
|
28261
|
+
fs36.rmSync(destination, { recursive: true, force: true });
|
|
28087
28262
|
return true;
|
|
28088
28263
|
}
|
|
28089
28264
|
function isCompiledCurrent3(destination, expectedContent, expectedHash) {
|
|
28090
28265
|
try {
|
|
28091
|
-
const current =
|
|
28266
|
+
const current = fs36.readFileSync(destination, "utf8");
|
|
28092
28267
|
const marker = extractProvenanceMarker(current);
|
|
28093
28268
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cursor" && current === expectedContent : current === expectedContent;
|
|
28094
28269
|
} catch {
|
|
@@ -28105,9 +28280,9 @@ function skippedMissingSource3(component, source) {
|
|
|
28105
28280
|
function shouldSkipComponent3(options, component) {
|
|
28106
28281
|
return Boolean(options.component && options.component !== component);
|
|
28107
28282
|
}
|
|
28108
|
-
function
|
|
28283
|
+
function isSymlinkTo4(linkPath, source) {
|
|
28109
28284
|
try {
|
|
28110
|
-
return
|
|
28285
|
+
return fs36.realpathSync(linkPath) === fs36.realpathSync(source);
|
|
28111
28286
|
} catch {
|
|
28112
28287
|
return false;
|
|
28113
28288
|
}
|
|
@@ -28118,8 +28293,8 @@ function hashString3(value) {
|
|
|
28118
28293
|
|
|
28119
28294
|
// src/adapters/cline.ts
|
|
28120
28295
|
import crypto8 from "crypto";
|
|
28121
|
-
import
|
|
28122
|
-
import
|
|
28296
|
+
import fs37 from "fs";
|
|
28297
|
+
import path37 from "path";
|
|
28123
28298
|
function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
28124
28299
|
const scope = options.scope ?? "global";
|
|
28125
28300
|
const profile = resolveTargetPaths({
|
|
@@ -28232,7 +28407,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
28232
28407
|
function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
|
|
28233
28408
|
if (scope === "global" || paths.instructions === null) {
|
|
28234
28409
|
addLoss(lossReport, "cline", "instructions", {
|
|
28235
|
-
source:
|
|
28410
|
+
source: path37.basename(config.source.instructions),
|
|
28236
28411
|
fields: [
|
|
28237
28412
|
{
|
|
28238
28413
|
field: "instructions",
|
|
@@ -28252,12 +28427,12 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
|
|
|
28252
28427
|
path: "cline/global/instructions: no committable global path"
|
|
28253
28428
|
};
|
|
28254
28429
|
}
|
|
28255
|
-
const source =
|
|
28430
|
+
const source = path37.join(sourceRoot, config.source.instructions);
|
|
28256
28431
|
const destination = resolveTargetPath(paths.instructions);
|
|
28257
|
-
const baseContent =
|
|
28432
|
+
const baseContent = fs37.existsSync(source) ? fs37.readFileSync(source, "utf8").trim() : "";
|
|
28258
28433
|
const marker = formatProvenanceMarker(
|
|
28259
28434
|
"markdown",
|
|
28260
|
-
|
|
28435
|
+
path37.basename(config.source.instructions),
|
|
28261
28436
|
hashString4(baseContent),
|
|
28262
28437
|
"cline"
|
|
28263
28438
|
);
|
|
@@ -28282,11 +28457,11 @@ ${baseContent}
|
|
|
28282
28457
|
);
|
|
28283
28458
|
}
|
|
28284
28459
|
function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
|
|
28285
|
-
const sourceAgentsRoot =
|
|
28286
|
-
if (!
|
|
28460
|
+
const sourceAgentsRoot = path37.join(sourceRoot, config.source.agents);
|
|
28461
|
+
if (!fs37.existsSync(sourceAgentsRoot)) {
|
|
28287
28462
|
return [skippedMissingSource4("agents", sourceAgentsRoot)];
|
|
28288
28463
|
}
|
|
28289
|
-
const sourceAgents = ts(
|
|
28464
|
+
const sourceAgents = ts(path37.join(sourceAgentsRoot, "*.md")).sort();
|
|
28290
28465
|
return sourceAgents.map((agentFile) => {
|
|
28291
28466
|
compileAgent(agentFile, "cline", mappings, extensions, lossReport);
|
|
28292
28467
|
if (options.dryRun) {
|
|
@@ -28302,14 +28477,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
28302
28477
|
});
|
|
28303
28478
|
}
|
|
28304
28479
|
function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
28305
|
-
const sourceRulesDir =
|
|
28306
|
-
if (!
|
|
28480
|
+
const sourceRulesDir = path37.join(sourceRoot, config.source.rules);
|
|
28481
|
+
if (!fs37.existsSync(sourceRulesDir)) {
|
|
28307
28482
|
return [skippedMissingSource4("rules", sourceRulesDir)];
|
|
28308
28483
|
}
|
|
28309
28484
|
const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
|
|
28310
28485
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
28311
28486
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
28312
|
-
const destination =
|
|
28487
|
+
const destination = path37.join(rulesDir, name);
|
|
28313
28488
|
if (options.dryRun) {
|
|
28314
28489
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
28315
28490
|
return {
|
|
@@ -28333,17 +28508,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
28333
28508
|
});
|
|
28334
28509
|
}
|
|
28335
28510
|
function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
28336
|
-
const sourceCommandsRoot =
|
|
28337
|
-
if (!
|
|
28511
|
+
const sourceCommandsRoot = path37.join(sourceRoot, config.source.commands);
|
|
28512
|
+
if (!fs37.existsSync(sourceCommandsRoot)) {
|
|
28338
28513
|
return [skippedMissingSource4("commands", sourceCommandsRoot)];
|
|
28339
28514
|
}
|
|
28340
|
-
const sourceCommands = ts(
|
|
28515
|
+
const sourceCommands = ts(path37.join(sourceCommandsRoot, "*.md")).sort();
|
|
28341
28516
|
const workflowsRoot = resolveTargetPath(paths.workflows);
|
|
28342
28517
|
return sourceCommands.map((commandFile) => {
|
|
28343
|
-
const baseName =
|
|
28344
|
-
const destination =
|
|
28345
|
-
const commandContent =
|
|
28346
|
-
const relativeSource = `commands/${
|
|
28518
|
+
const baseName = path37.basename(commandFile);
|
|
28519
|
+
const destination = path37.join(workflowsRoot, baseName);
|
|
28520
|
+
const commandContent = fs37.readFileSync(commandFile, "utf8");
|
|
28521
|
+
const relativeSource = `commands/${path37.basename(commandFile)}`;
|
|
28347
28522
|
const marker = formatProvenanceMarker(
|
|
28348
28523
|
"markdown",
|
|
28349
28524
|
relativeSource,
|
|
@@ -28378,9 +28553,9 @@ ${commandContent.trim()}
|
|
|
28378
28553
|
});
|
|
28379
28554
|
}
|
|
28380
28555
|
function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
28381
|
-
const source =
|
|
28556
|
+
const source = path37.resolve(sourceRoot, config.source.skills);
|
|
28382
28557
|
const destination = resolveTargetPath(paths.skills);
|
|
28383
|
-
if (!
|
|
28558
|
+
if (!fs37.existsSync(source)) {
|
|
28384
28559
|
return skippedMissingSource4("skills", source);
|
|
28385
28560
|
}
|
|
28386
28561
|
if (options.dryRun) {
|
|
@@ -28388,7 +28563,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
28388
28563
|
return { component: "skills", status: "dry-run", path: destination };
|
|
28389
28564
|
}
|
|
28390
28565
|
const artifactClass = classifyArtifact(destination, config, sourceRoot);
|
|
28391
|
-
if (artifactClass === "managed-symlink" &&
|
|
28566
|
+
if (artifactClass === "managed-symlink" && isSymlinkTo5(destination, source)) {
|
|
28392
28567
|
return {
|
|
28393
28568
|
component: "skills",
|
|
28394
28569
|
status: "skipped-current",
|
|
@@ -28400,9 +28575,9 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
28400
28575
|
return { component: "skills", status: "conflict", path: destination };
|
|
28401
28576
|
}
|
|
28402
28577
|
} else if (artifactClass === "managed-symlink") {
|
|
28403
|
-
|
|
28578
|
+
fs37.unlinkSync(destination);
|
|
28404
28579
|
}
|
|
28405
|
-
ensureDir(
|
|
28580
|
+
ensureDir(path37.dirname(destination));
|
|
28406
28581
|
createRelativeSymlink(source, destination, "dir");
|
|
28407
28582
|
logger.verbose(`Skills: created Cline skills symlink ${destination}`);
|
|
28408
28583
|
return { component: "skills", status: "success", path: destination };
|
|
@@ -28426,10 +28601,10 @@ function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manife
|
|
|
28426
28601
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
28427
28602
|
const sourceLabel = mcpSourceLabel(config);
|
|
28428
28603
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
28429
|
-
if (!
|
|
28604
|
+
if (!fs37.existsSync(source)) {
|
|
28430
28605
|
return skippedMissingSource4("mcp", source);
|
|
28431
28606
|
}
|
|
28432
|
-
const sourceMcpJson = JSON.parse(
|
|
28607
|
+
const sourceMcpJson = JSON.parse(fs37.readFileSync(source, "utf8"));
|
|
28433
28608
|
const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
|
|
28434
28609
|
if (options.dryRun) {
|
|
28435
28610
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -28472,11 +28647,11 @@ function syncSettings(lossReport) {
|
|
|
28472
28647
|
};
|
|
28473
28648
|
}
|
|
28474
28649
|
function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
28475
|
-
const agentsDir =
|
|
28476
|
-
if (!
|
|
28477
|
-
for (const agentFile of ts(
|
|
28650
|
+
const agentsDir = path37.join(sourceRoot, config.source.agents);
|
|
28651
|
+
if (!fs37.existsSync(agentsDir)) return;
|
|
28652
|
+
for (const agentFile of ts(path37.join(agentsDir, "*.md")).sort()) {
|
|
28478
28653
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
28479
|
-
const relativeSource = `agents/${
|
|
28654
|
+
const relativeSource = `agents/${path37.basename(agentFile)}`;
|
|
28480
28655
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
28481
28656
|
if (hasCustomProvider) {
|
|
28482
28657
|
addLoss(lossReport, "cline", "agents", {
|
|
@@ -28490,7 +28665,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
28490
28665
|
"provider",
|
|
28491
28666
|
"provider-not-representable"
|
|
28492
28667
|
),
|
|
28493
|
-
detail: `${
|
|
28668
|
+
detail: `${path37.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
|
|
28494
28669
|
}
|
|
28495
28670
|
]
|
|
28496
28671
|
});
|
|
@@ -28508,7 +28683,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
28508
28683
|
"model",
|
|
28509
28684
|
"model-not-representable"
|
|
28510
28685
|
),
|
|
28511
|
-
detail: `${
|
|
28686
|
+
detail: `${path37.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
|
|
28512
28687
|
}
|
|
28513
28688
|
]
|
|
28514
28689
|
});
|
|
@@ -28523,8 +28698,8 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
|
|
|
28523
28698
|
if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
28524
28699
|
return { component, status: "conflict", path: destination };
|
|
28525
28700
|
}
|
|
28526
|
-
ensureDir(
|
|
28527
|
-
|
|
28701
|
+
ensureDir(path37.dirname(destination));
|
|
28702
|
+
fs37.writeFileSync(destination, content);
|
|
28528
28703
|
return { component, status: "success", path: destination };
|
|
28529
28704
|
}
|
|
28530
28705
|
function handleConflict4(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -28543,16 +28718,16 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
|
|
|
28543
28718
|
backupFile(destination, manifest);
|
|
28544
28719
|
writeManifest(scopePath, manifest);
|
|
28545
28720
|
} else {
|
|
28546
|
-
|
|
28721
|
+
fs37.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
28547
28722
|
}
|
|
28548
28723
|
return true;
|
|
28549
28724
|
}
|
|
28550
|
-
|
|
28725
|
+
fs37.rmSync(destination, { recursive: true, force: true });
|
|
28551
28726
|
return true;
|
|
28552
28727
|
}
|
|
28553
28728
|
function isCompiledCurrent4(destination, expectedContent, expectedHash) {
|
|
28554
28729
|
try {
|
|
28555
|
-
const current =
|
|
28730
|
+
const current = fs37.readFileSync(destination, "utf8");
|
|
28556
28731
|
const marker = extractProvenanceMarker(current);
|
|
28557
28732
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cline" && current === expectedContent : current === expectedContent;
|
|
28558
28733
|
} catch {
|
|
@@ -28569,9 +28744,9 @@ function skippedMissingSource4(component, source) {
|
|
|
28569
28744
|
function shouldSkipComponent4(options, component) {
|
|
28570
28745
|
return Boolean(options.component && options.component !== component);
|
|
28571
28746
|
}
|
|
28572
|
-
function
|
|
28747
|
+
function isSymlinkTo5(linkPath, source) {
|
|
28573
28748
|
try {
|
|
28574
|
-
return
|
|
28749
|
+
return fs37.realpathSync(linkPath) === fs37.realpathSync(source);
|
|
28575
28750
|
} catch {
|
|
28576
28751
|
return false;
|
|
28577
28752
|
}
|
|
@@ -28582,9 +28757,9 @@ function hashString4(value) {
|
|
|
28582
28757
|
|
|
28583
28758
|
// src/adapters/opencode.ts
|
|
28584
28759
|
import crypto9 from "crypto";
|
|
28585
|
-
import
|
|
28760
|
+
import fs38 from "fs";
|
|
28586
28761
|
import os6 from "os";
|
|
28587
|
-
import
|
|
28762
|
+
import path38 from "path";
|
|
28588
28763
|
var import_yaml11 = __toESM(require_dist(), 1);
|
|
28589
28764
|
function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
28590
28765
|
const scope = options.scope ?? "global";
|
|
@@ -28602,7 +28777,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
28602
28777
|
config_doc: profile.config_doc
|
|
28603
28778
|
};
|
|
28604
28779
|
const rules = compileRules(
|
|
28605
|
-
|
|
28780
|
+
path38.join(sourceRoot, config.source.rules),
|
|
28606
28781
|
"opencode",
|
|
28607
28782
|
mappings,
|
|
28608
28783
|
lossReport
|
|
@@ -28704,16 +28879,16 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
28704
28879
|
return { target: "opencode", outcomes };
|
|
28705
28880
|
}
|
|
28706
28881
|
function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
28707
|
-
const source =
|
|
28882
|
+
const source = path38.join(sourceRoot, config.source.instructions);
|
|
28708
28883
|
const destination = resolveTargetPath(paths.instructions);
|
|
28709
|
-
const baseContent =
|
|
28884
|
+
const baseContent = fs38.existsSync(source) ? fs38.readFileSync(source, "utf8").trim() : "";
|
|
28710
28885
|
const composed = agentsAppendix ? `${baseContent}
|
|
28711
28886
|
|
|
28712
28887
|
--- tangyr managed rules ---
|
|
28713
28888
|
${agentsAppendix}`.trim() : baseContent;
|
|
28714
28889
|
const marker = formatProvenanceMarker(
|
|
28715
28890
|
"markdown",
|
|
28716
|
-
|
|
28891
|
+
path38.basename(config.source.instructions),
|
|
28717
28892
|
hashString5(composed),
|
|
28718
28893
|
"opencode"
|
|
28719
28894
|
);
|
|
@@ -28740,16 +28915,16 @@ ${composed}
|
|
|
28740
28915
|
);
|
|
28741
28916
|
}
|
|
28742
28917
|
function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
28743
|
-
const sourceAgentsRoot =
|
|
28744
|
-
if (!
|
|
28918
|
+
const sourceAgentsRoot = path38.join(sourceRoot, config.source.agents);
|
|
28919
|
+
if (!fs38.existsSync(sourceAgentsRoot)) {
|
|
28745
28920
|
return [skippedMissingSource5("agents", sourceAgentsRoot)];
|
|
28746
28921
|
}
|
|
28747
|
-
const sourceAgents = ts(
|
|
28922
|
+
const sourceAgents = ts(path38.join(sourceAgentsRoot, "*.md")).sort();
|
|
28748
28923
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
28749
28924
|
return sourceAgents.map((agentFile) => {
|
|
28750
|
-
const destination =
|
|
28925
|
+
const destination = path38.join(
|
|
28751
28926
|
agentsRoot,
|
|
28752
|
-
`${
|
|
28927
|
+
`${path38.basename(agentFile, ".md")}.md`
|
|
28753
28928
|
);
|
|
28754
28929
|
let compiled;
|
|
28755
28930
|
try {
|
|
@@ -28813,11 +28988,11 @@ function applyProviderModelBinding(compiled, mappings) {
|
|
|
28813
28988
|
return `${before}${(0, import_yaml11.stringify)(fields).trim()}${after}`;
|
|
28814
28989
|
}
|
|
28815
28990
|
function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
28816
|
-
const sourceCommandsRoot =
|
|
28817
|
-
if (!
|
|
28991
|
+
const sourceCommandsRoot = path38.join(sourceRoot, config.source.commands);
|
|
28992
|
+
if (!fs38.existsSync(sourceCommandsRoot)) {
|
|
28818
28993
|
return [skippedMissingSource5("commands", sourceCommandsRoot)];
|
|
28819
28994
|
}
|
|
28820
|
-
const sourceCommands = ts(
|
|
28995
|
+
const sourceCommands = ts(path38.join(sourceCommandsRoot, "*.md")).sort();
|
|
28821
28996
|
const commandsRoot = resolveTargetPath(paths.commands);
|
|
28822
28997
|
return sourceCommands.map((commandFile) => {
|
|
28823
28998
|
const { data, body } = parseCommandFile(commandFile);
|
|
@@ -28831,7 +29006,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
|
|
|
28831
29006
|
if (typeof data.model === "string") {
|
|
28832
29007
|
frontmatter.model = data.model;
|
|
28833
29008
|
}
|
|
28834
|
-
const relativeSource = `commands/${
|
|
29009
|
+
const relativeSource = `commands/${path38.basename(commandFile)}`;
|
|
28835
29010
|
const marker = formatProvenanceMarker(
|
|
28836
29011
|
"markdown",
|
|
28837
29012
|
relativeSource,
|
|
@@ -28847,9 +29022,9 @@ ${body.trimEnd()}
|
|
|
28847
29022
|
` : `${marker}
|
|
28848
29023
|
${body.trimEnd()}
|
|
28849
29024
|
`;
|
|
28850
|
-
const destination =
|
|
29025
|
+
const destination = path38.join(
|
|
28851
29026
|
commandsRoot,
|
|
28852
|
-
`${
|
|
29027
|
+
`${path38.basename(commandFile, ".md")}.md`
|
|
28853
29028
|
);
|
|
28854
29029
|
if (options.dryRun) {
|
|
28855
29030
|
logger.info(
|
|
@@ -28876,8 +29051,8 @@ ${body.trimEnd()}
|
|
|
28876
29051
|
});
|
|
28877
29052
|
}
|
|
28878
29053
|
function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
|
|
28879
|
-
const source =
|
|
28880
|
-
if (!
|
|
29054
|
+
const source = path38.resolve(sourceRoot, config.source.skills);
|
|
29055
|
+
if (!fs38.existsSync(source)) {
|
|
28881
29056
|
return skippedMissingSource5(component, source);
|
|
28882
29057
|
}
|
|
28883
29058
|
if (options.dryRun) {
|
|
@@ -28885,17 +29060,17 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
|
|
|
28885
29060
|
return { component, status: "dry-run", path: destination };
|
|
28886
29061
|
}
|
|
28887
29062
|
const artifactClass = classifyArtifact(destination, config, sourceRoot);
|
|
28888
|
-
if (artifactClass === "managed-symlink" &&
|
|
29063
|
+
if (artifactClass === "managed-symlink" && isSymlinkTo6(destination, source)) {
|
|
28889
29064
|
return { component, status: "skipped-current", path: destination };
|
|
28890
29065
|
}
|
|
28891
29066
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
28892
|
-
|
|
29067
|
+
fs38.unlinkSync(destination);
|
|
28893
29068
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
28894
29069
|
return { component, status: "conflict", path: destination };
|
|
28895
29070
|
} else if (artifactClass === "managed-symlink") {
|
|
28896
|
-
|
|
29071
|
+
fs38.unlinkSync(destination);
|
|
28897
29072
|
}
|
|
28898
|
-
ensureDir(
|
|
29073
|
+
ensureDir(path38.dirname(destination));
|
|
28899
29074
|
createRelativeSymlink(source, destination, "dir");
|
|
28900
29075
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
28901
29076
|
return { component, status: "success", path: destination };
|
|
@@ -28904,13 +29079,13 @@ function syncMcp5(config, sourceRoot, paths, mappings, options, lossReport, logg
|
|
|
28904
29079
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
28905
29080
|
const sourceLabel = mcpSourceLabel(config);
|
|
28906
29081
|
const destination = resolveTargetPath(paths.config_doc);
|
|
28907
|
-
if (!
|
|
29082
|
+
if (!fs38.existsSync(source)) {
|
|
28908
29083
|
if (!options.dryRun) {
|
|
28909
29084
|
syncConfigDoc(paths, {}, lossReport, {}, mappings);
|
|
28910
29085
|
}
|
|
28911
29086
|
return skippedMissingSource5("mcp", source);
|
|
28912
29087
|
}
|
|
28913
|
-
const sourceMcpJson = JSON.parse(
|
|
29088
|
+
const sourceMcpJson = JSON.parse(fs38.readFileSync(source, "utf8"));
|
|
28914
29089
|
const mcpJson = compileMcp(
|
|
28915
29090
|
sourceMcpJson,
|
|
28916
29091
|
"opencode",
|
|
@@ -28976,9 +29151,9 @@ function syncProviderBlock(mappings) {
|
|
|
28976
29151
|
function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
|
|
28977
29152
|
const destination = resolveTargetPath(paths.config_doc);
|
|
28978
29153
|
let existing = {};
|
|
28979
|
-
if (
|
|
29154
|
+
if (fs38.existsSync(destination)) {
|
|
28980
29155
|
try {
|
|
28981
|
-
existing = JSON.parse(
|
|
29156
|
+
existing = JSON.parse(fs38.readFileSync(destination, "utf8"));
|
|
28982
29157
|
} catch {
|
|
28983
29158
|
existing = {};
|
|
28984
29159
|
}
|
|
@@ -29003,8 +29178,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
|
|
|
29003
29178
|
};
|
|
29004
29179
|
}
|
|
29005
29180
|
}
|
|
29006
|
-
ensureDir(
|
|
29007
|
-
|
|
29181
|
+
ensureDir(path38.dirname(destination));
|
|
29182
|
+
fs38.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
29008
29183
|
`);
|
|
29009
29184
|
}
|
|
29010
29185
|
function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
|
|
@@ -29015,8 +29190,8 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
|
|
|
29015
29190
|
if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
29016
29191
|
return { component, status: "conflict", path: destination };
|
|
29017
29192
|
}
|
|
29018
|
-
ensureDir(
|
|
29019
|
-
|
|
29193
|
+
ensureDir(path38.dirname(destination));
|
|
29194
|
+
fs38.writeFileSync(destination, content);
|
|
29020
29195
|
return { component, status: "success", path: destination };
|
|
29021
29196
|
}
|
|
29022
29197
|
function handleConflict5(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -29035,16 +29210,16 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
|
|
|
29035
29210
|
backupFile(destination, manifest);
|
|
29036
29211
|
writeManifest(scopePath, manifest);
|
|
29037
29212
|
} else {
|
|
29038
|
-
|
|
29213
|
+
fs38.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
29039
29214
|
}
|
|
29040
29215
|
return true;
|
|
29041
29216
|
}
|
|
29042
|
-
|
|
29217
|
+
fs38.rmSync(destination, { recursive: true, force: true });
|
|
29043
29218
|
return true;
|
|
29044
29219
|
}
|
|
29045
29220
|
function isCompiledCurrent5(destination, expectedContent, expectedHash) {
|
|
29046
29221
|
try {
|
|
29047
|
-
const current =
|
|
29222
|
+
const current = fs38.readFileSync(destination, "utf8");
|
|
29048
29223
|
const marker = extractProvenanceMarker(current);
|
|
29049
29224
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "opencode" && current === expectedContent : current === expectedContent;
|
|
29050
29225
|
} catch {
|
|
@@ -29061,9 +29236,9 @@ function skippedMissingSource5(component, source) {
|
|
|
29061
29236
|
function shouldSkipComponent5(options, component) {
|
|
29062
29237
|
return Boolean(options.component && options.component !== component);
|
|
29063
29238
|
}
|
|
29064
|
-
function
|
|
29239
|
+
function isSymlinkTo6(linkPath, source) {
|
|
29065
29240
|
try {
|
|
29066
|
-
return
|
|
29241
|
+
return fs38.realpathSync(linkPath) === fs38.realpathSync(source);
|
|
29067
29242
|
} catch {
|
|
29068
29243
|
return false;
|
|
29069
29244
|
}
|
|
@@ -29072,7 +29247,7 @@ function hashString5(value) {
|
|
|
29072
29247
|
return `sha256:${crypto9.createHash("sha256").update(value).digest("hex")}`;
|
|
29073
29248
|
}
|
|
29074
29249
|
function parseCommandFile(commandFile) {
|
|
29075
|
-
const content =
|
|
29250
|
+
const content = fs38.readFileSync(commandFile, "utf8");
|
|
29076
29251
|
if (!content.startsWith("---\n")) {
|
|
29077
29252
|
return { data: {}, body: content };
|
|
29078
29253
|
}
|
|
@@ -29092,10 +29267,10 @@ function parseCommandFile(commandFile) {
|
|
|
29092
29267
|
// src/commands/install.ts
|
|
29093
29268
|
function isBackupableFile(targetPath) {
|
|
29094
29269
|
try {
|
|
29095
|
-
const lstat =
|
|
29270
|
+
const lstat = fs39.lstatSync(targetPath);
|
|
29096
29271
|
if (lstat.isDirectory()) return false;
|
|
29097
29272
|
if (lstat.isSymbolicLink()) {
|
|
29098
|
-
const stat =
|
|
29273
|
+
const stat = fs39.statSync(targetPath);
|
|
29099
29274
|
return stat.isFile();
|
|
29100
29275
|
}
|
|
29101
29276
|
return lstat.isFile();
|
|
@@ -29105,10 +29280,10 @@ function isBackupableFile(targetPath) {
|
|
|
29105
29280
|
}
|
|
29106
29281
|
function backupConflictingTarget(targetPath, scopePath) {
|
|
29107
29282
|
const ts2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/gu, "").replace("T", "T").replace(/\.\d+Z$/u, "Z");
|
|
29108
|
-
const relativeToRoot =
|
|
29109
|
-
const backupPath =
|
|
29110
|
-
|
|
29111
|
-
|
|
29283
|
+
const relativeToRoot = path39.relative("/", targetPath).replace(/^\.\.\/+/gu, "");
|
|
29284
|
+
const backupPath = path39.join(scopePath, "backups", ts2, relativeToRoot);
|
|
29285
|
+
fs39.mkdirSync(path39.dirname(backupPath), { recursive: true });
|
|
29286
|
+
fs39.copyFileSync(targetPath, backupPath);
|
|
29112
29287
|
return backupPath;
|
|
29113
29288
|
}
|
|
29114
29289
|
async function runInstallCommand(options, logger) {
|
|
@@ -29137,7 +29312,7 @@ async function runInstallCommand(options, logger) {
|
|
|
29137
29312
|
);
|
|
29138
29313
|
}
|
|
29139
29314
|
const kitName = resolvedKitName ?? config.kit;
|
|
29140
|
-
const kitPath = kitPathOverride ?? (options.kitPath ?
|
|
29315
|
+
const kitPath = kitPathOverride ?? (options.kitPath ? path39.resolve(options.kitPath) : config.kitPath);
|
|
29141
29316
|
if (!kitName && !kitPath) {
|
|
29142
29317
|
logger.error(
|
|
29143
29318
|
"No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
|
|
@@ -29282,7 +29457,7 @@ ACCEPTED CONFLICTS (backup-and-replace applied to ${conflictingFindings.length}
|
|
|
29282
29457
|
logger.info(` source: ${finding.tool}`);
|
|
29283
29458
|
logger.info(` action: backup-and-replace`);
|
|
29284
29459
|
logger.info(` backup: ${backupLocation}`);
|
|
29285
|
-
} else if (
|
|
29460
|
+
} else if (fs39.existsSync(finding.path)) {
|
|
29286
29461
|
logger.info(` - ${finding.path}`);
|
|
29287
29462
|
logger.info(` source: ${finding.tool}`);
|
|
29288
29463
|
logger.info(
|
|
@@ -29393,33 +29568,25 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
29393
29568
|
writeManifest(scopePath, manifest);
|
|
29394
29569
|
logger.info(`
|
|
29395
29570
|
Installation complete: ${installedCount} files installed.`);
|
|
29396
|
-
logger.info(`Manifest written to ${
|
|
29571
|
+
logger.info(`Manifest written to ${path39.join(scopePath, "manifest.json")}`);
|
|
29397
29572
|
logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
|
|
29398
29573
|
logger.info(`Scope: ${scope}`);
|
|
29399
29574
|
logger.info(`Tools: ${tools.join(", ")}`);
|
|
29400
29575
|
reportHookRejections(
|
|
29401
29576
|
installLossReport,
|
|
29402
29577
|
tools,
|
|
29403
|
-
|
|
29578
|
+
path39.resolve(kitInfo.path, "hooks"),
|
|
29404
29579
|
kitInfo.components.hooks.declared
|
|
29405
29580
|
);
|
|
29406
29581
|
const hooksConflict = reportHooksSourceConflict(
|
|
29407
29582
|
installLossReport,
|
|
29408
29583
|
tools,
|
|
29409
|
-
|
|
29584
|
+
path39.resolve(kitInfo.path, "hooks"),
|
|
29410
29585
|
kitInfo.components.hooks.declared
|
|
29411
29586
|
);
|
|
29412
29587
|
if (hooksConflict) {
|
|
29413
29588
|
logger.warn(hooksConflict);
|
|
29414
29589
|
}
|
|
29415
|
-
if (scope === "project") {
|
|
29416
|
-
reportProjectScopeScriptPath(
|
|
29417
|
-
installLossReport,
|
|
29418
|
-
tools,
|
|
29419
|
-
path37.resolve(kitInfo.path, "hooks"),
|
|
29420
|
-
kitInfo.components.hooks.declared
|
|
29421
|
-
);
|
|
29422
|
-
}
|
|
29423
29590
|
writeLossReport(options.lossReport, installLossReport);
|
|
29424
29591
|
exitOnErrorSeverityLoss(installLossReport, logger, {
|
|
29425
29592
|
ignoreErrors: options.ignoreErrors ?? false
|
|
@@ -29559,13 +29726,13 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
29559
29726
|
logger.verbose(` skipped (operator choice): ${placement.destination}`);
|
|
29560
29727
|
continue;
|
|
29561
29728
|
}
|
|
29562
|
-
const destDir =
|
|
29563
|
-
|
|
29729
|
+
const destDir = path39.dirname(placement.destination);
|
|
29730
|
+
fs39.mkdirSync(destDir, { recursive: true });
|
|
29564
29731
|
if (placement.type === "symlink") {
|
|
29565
|
-
if (
|
|
29732
|
+
if (fs39.existsSync(placement.destination) || isSymlink2(placement.destination)) {
|
|
29566
29733
|
removeManagedPath(placement.destination);
|
|
29567
29734
|
}
|
|
29568
|
-
|
|
29735
|
+
fs39.symlinkSync(
|
|
29569
29736
|
placement.source,
|
|
29570
29737
|
placement.destination,
|
|
29571
29738
|
placement.isDir ? "dir" : "file"
|
|
@@ -29574,12 +29741,12 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
29574
29741
|
` symlink: ${placement.source} \u2192 ${placement.destination}`
|
|
29575
29742
|
);
|
|
29576
29743
|
} else {
|
|
29577
|
-
|
|
29744
|
+
fs39.copyFileSync(placement.source, placement.destination);
|
|
29578
29745
|
logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
|
|
29579
29746
|
}
|
|
29580
29747
|
addArtifactToManifest(manifest, {
|
|
29581
29748
|
relativePath: placement.manifestKey,
|
|
29582
|
-
hash:
|
|
29749
|
+
hash: fs39.statSync(placement.source).isDirectory() ? `dir:${placement.source}` : computeSourceHash(placement.source),
|
|
29583
29750
|
origin: "tangyr-managed"
|
|
29584
29751
|
});
|
|
29585
29752
|
count++;
|
|
@@ -29826,11 +29993,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
29826
29993
|
if (outcome.path === mcpFile2) {
|
|
29827
29994
|
return "cline/mcp.json";
|
|
29828
29995
|
}
|
|
29829
|
-
if (outcome.path.startsWith(`${workflowsRoot}${
|
|
29830
|
-
return `cline/workflows/${
|
|
29996
|
+
if (outcome.path.startsWith(`${workflowsRoot}${path39.sep}`)) {
|
|
29997
|
+
return `cline/workflows/${path39.basename(outcome.path)}`;
|
|
29831
29998
|
}
|
|
29832
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
29833
|
-
return `cline/rules/${
|
|
29999
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path39.sep}`)) {
|
|
30000
|
+
return `cline/rules/${path39.basename(outcome.path)}`;
|
|
29834
30001
|
}
|
|
29835
30002
|
return null;
|
|
29836
30003
|
}
|
|
@@ -29866,14 +30033,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
29866
30033
|
if (outcome.path === permissionsFile) {
|
|
29867
30034
|
return "cursor/permissions.json";
|
|
29868
30035
|
}
|
|
29869
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
29870
|
-
return `cursor/agents/${
|
|
30036
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path39.sep}`)) {
|
|
30037
|
+
return `cursor/agents/${path39.basename(outcome.path)}`;
|
|
29871
30038
|
}
|
|
29872
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
29873
|
-
return `cursor/rules/${
|
|
30039
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path39.sep}`)) {
|
|
30040
|
+
return `cursor/rules/${path39.basename(outcome.path)}`;
|
|
29874
30041
|
}
|
|
29875
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
29876
|
-
const rel =
|
|
30042
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path39.sep}`)) {
|
|
30043
|
+
const rel = path39.relative(skillsRoot2, outcome.path);
|
|
29877
30044
|
return `cursor/skills/${rel}`;
|
|
29878
30045
|
}
|
|
29879
30046
|
return null;
|
|
@@ -29899,14 +30066,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
29899
30066
|
if (outcome.path === skillsSharedRoot) {
|
|
29900
30067
|
return "opencode/skills_shared";
|
|
29901
30068
|
}
|
|
29902
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
29903
|
-
return `opencode/agents/${
|
|
30069
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path39.sep}`)) {
|
|
30070
|
+
return `opencode/agents/${path39.basename(outcome.path)}`;
|
|
29904
30071
|
}
|
|
29905
|
-
if (outcome.path.startsWith(`${commandsRoot}${
|
|
29906
|
-
return `opencode/commands/${
|
|
30072
|
+
if (outcome.path.startsWith(`${commandsRoot}${path39.sep}`)) {
|
|
30073
|
+
return `opencode/commands/${path39.basename(outcome.path)}`;
|
|
29907
30074
|
}
|
|
29908
30075
|
if (outcome.path === configDocFile) {
|
|
29909
|
-
return `opencode/${
|
|
30076
|
+
return `opencode/${path39.basename(outcome.path)}`;
|
|
29910
30077
|
}
|
|
29911
30078
|
return null;
|
|
29912
30079
|
}
|
|
@@ -29920,17 +30087,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
29920
30087
|
if (outcome.path === skillsRoot2) {
|
|
29921
30088
|
return "copilot/skills";
|
|
29922
30089
|
}
|
|
29923
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
29924
|
-
return `copilot/agents/${
|
|
30090
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path39.sep}`)) {
|
|
30091
|
+
return `copilot/agents/${path39.basename(outcome.path)}`;
|
|
29925
30092
|
}
|
|
29926
|
-
if (outcome.path.startsWith(`${promptsRoot}${
|
|
29927
|
-
return `copilot/prompts/${
|
|
30093
|
+
if (outcome.path.startsWith(`${promptsRoot}${path39.sep}`)) {
|
|
30094
|
+
return `copilot/prompts/${path39.basename(outcome.path)}`;
|
|
29928
30095
|
}
|
|
29929
|
-
if (outcome.path.startsWith(`${hooksRoot}${
|
|
29930
|
-
return `copilot/hooks/${
|
|
30096
|
+
if (outcome.path.startsWith(`${hooksRoot}${path39.sep}`)) {
|
|
30097
|
+
return `copilot/hooks/${path39.basename(outcome.path)}`;
|
|
29931
30098
|
}
|
|
29932
30099
|
if (outcome.path === mcpFile2) {
|
|
29933
|
-
return `copilot/${
|
|
30100
|
+
return `copilot/${path39.basename(outcome.path)}`;
|
|
29934
30101
|
}
|
|
29935
30102
|
return null;
|
|
29936
30103
|
}
|
|
@@ -29946,17 +30113,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
29946
30113
|
if (outcome.path === skillsRoot) {
|
|
29947
30114
|
return "codex/skills";
|
|
29948
30115
|
}
|
|
29949
|
-
if (outcome.path.startsWith(`${agentsRoot}${
|
|
29950
|
-
return `codex/agents/${
|
|
30116
|
+
if (outcome.path.startsWith(`${agentsRoot}${path39.sep}`)) {
|
|
30117
|
+
return `codex/agents/${path39.basename(outcome.path)}`;
|
|
29951
30118
|
}
|
|
29952
|
-
if (outcome.path.startsWith(`${rulesRoot}${
|
|
29953
|
-
return `codex/rules/${
|
|
30119
|
+
if (outcome.path.startsWith(`${rulesRoot}${path39.sep}`)) {
|
|
30120
|
+
return `codex/rules/${path39.basename(outcome.path)}`;
|
|
29954
30121
|
}
|
|
29955
30122
|
if (outcome.path === hooksFile) {
|
|
29956
|
-
return `codex/${
|
|
30123
|
+
return `codex/${path39.basename(outcome.path)}`;
|
|
29957
30124
|
}
|
|
29958
30125
|
if (outcome.path === mcpFile) {
|
|
29959
|
-
return `codex/${
|
|
30126
|
+
return `codex/${path39.basename(outcome.path)}`;
|
|
29960
30127
|
}
|
|
29961
30128
|
return null;
|
|
29962
30129
|
}
|
|
@@ -30008,8 +30175,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
|
|
|
30008
30175
|
rules: resolvedPaths.rules
|
|
30009
30176
|
};
|
|
30010
30177
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
30011
|
-
const componentDir =
|
|
30012
|
-
if (
|
|
30178
|
+
const componentDir = path39.join(kitInfo.path, component);
|
|
30179
|
+
if (fs39.existsSync(componentDir) && fs39.statSync(componentDir).isDirectory()) {
|
|
30013
30180
|
placements.push({
|
|
30014
30181
|
source: componentDir,
|
|
30015
30182
|
destination: targetPath,
|
|
@@ -30040,8 +30207,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
|
|
|
30040
30207
|
rules: profile.rules
|
|
30041
30208
|
};
|
|
30042
30209
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
30043
|
-
const componentDir =
|
|
30044
|
-
if (
|
|
30210
|
+
const componentDir = path39.join(kitInfo.path, component);
|
|
30211
|
+
if (fs39.existsSync(componentDir) && fs39.statSync(componentDir).isDirectory()) {
|
|
30045
30212
|
placements.push({
|
|
30046
30213
|
source: componentDir,
|
|
30047
30214
|
destination: targetPath,
|
|
@@ -30066,15 +30233,15 @@ function collectAllFiles(kitInfo) {
|
|
|
30066
30233
|
const missingSet = new Set(reconciliation.missing);
|
|
30067
30234
|
for (const entry of reconciliation.declared) {
|
|
30068
30235
|
if (missingSet.has(entry)) continue;
|
|
30069
|
-
const relPath = isSkills ?
|
|
30070
|
-
files.set(relPath,
|
|
30236
|
+
const relPath = isSkills ? path39.join(component, entry) : path39.join(component, `${entry}.md`);
|
|
30237
|
+
files.set(relPath, path39.join(kitInfo.path, relPath));
|
|
30071
30238
|
}
|
|
30072
30239
|
}
|
|
30073
30240
|
return files;
|
|
30074
30241
|
}
|
|
30075
30242
|
function isSymlink2(p) {
|
|
30076
30243
|
try {
|
|
30077
|
-
return
|
|
30244
|
+
return fs39.lstatSync(p).isSymbolicLink();
|
|
30078
30245
|
} catch {
|
|
30079
30246
|
return false;
|
|
30080
30247
|
}
|
|
@@ -30119,14 +30286,14 @@ async function runKitUpdateCommand(options, logger) {
|
|
|
30119
30286
|
}
|
|
30120
30287
|
|
|
30121
30288
|
// src/commands/list.ts
|
|
30122
|
-
import
|
|
30289
|
+
import path40 from "path";
|
|
30123
30290
|
function runListCommand(options, logger) {
|
|
30124
30291
|
let searchPaths = [];
|
|
30125
|
-
let directKitPath = options.kitPath ?
|
|
30292
|
+
let directKitPath = options.kitPath ? path40.resolve(options.kitPath) : void 0;
|
|
30126
30293
|
try {
|
|
30127
30294
|
const { config, configDir } = resolveConfig(options.config);
|
|
30128
30295
|
searchPaths = config.kitSearchPaths ?? [
|
|
30129
|
-
|
|
30296
|
+
path40.join(configDir, "operating-kits")
|
|
30130
30297
|
];
|
|
30131
30298
|
directKitPath = directKitPath ?? config.kitPath;
|
|
30132
30299
|
} catch (err) {
|
|
@@ -30201,7 +30368,7 @@ function withDirectKit(kits, directKitPath) {
|
|
|
30201
30368
|
return kits;
|
|
30202
30369
|
}
|
|
30203
30370
|
const directKit = loadKit(directKitPath);
|
|
30204
|
-
if (kits.some((kit) =>
|
|
30371
|
+
if (kits.some((kit) => path40.resolve(kit.path) === directKit.path)) {
|
|
30205
30372
|
return kits;
|
|
30206
30373
|
}
|
|
30207
30374
|
return [...kits, directKit];
|
|
@@ -30209,15 +30376,15 @@ function withDirectKit(kits, directKitPath) {
|
|
|
30209
30376
|
|
|
30210
30377
|
// src/commands/probe.ts
|
|
30211
30378
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
30212
|
-
import
|
|
30213
|
-
import
|
|
30379
|
+
import fs40 from "fs";
|
|
30380
|
+
import path41 from "path";
|
|
30214
30381
|
function runProbeCommand(options, logger) {
|
|
30215
30382
|
const { config, configDir, sourceRoot } = resolveRuntime(
|
|
30216
30383
|
options,
|
|
30217
30384
|
import.meta.url
|
|
30218
30385
|
);
|
|
30219
30386
|
const platformPaths = readYamlObject(
|
|
30220
|
-
|
|
30387
|
+
path41.join(
|
|
30221
30388
|
resolveConfiguredPath(config.mappings, configDir, sourceRoot, "mappings"),
|
|
30222
30389
|
"platform-paths.yaml"
|
|
30223
30390
|
)
|
|
@@ -30253,7 +30420,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
30253
30420
|
const resolved = resolveTargetPath(rawPath);
|
|
30254
30421
|
let accessible = false;
|
|
30255
30422
|
try {
|
|
30256
|
-
|
|
30423
|
+
fs40.accessSync(resolved);
|
|
30257
30424
|
accessible = true;
|
|
30258
30425
|
} catch {
|
|
30259
30426
|
accessible = false;
|
|
@@ -30262,7 +30429,7 @@ function toProbeRow(target, key, rawPath) {
|
|
|
30262
30429
|
target,
|
|
30263
30430
|
key,
|
|
30264
30431
|
path: resolved,
|
|
30265
|
-
exists:
|
|
30432
|
+
exists: fs40.existsSync(resolved),
|
|
30266
30433
|
accessible
|
|
30267
30434
|
};
|
|
30268
30435
|
}
|
|
@@ -30280,7 +30447,7 @@ function codexRuntimeProbeRows() {
|
|
|
30280
30447
|
["binary_snap", "/snap/bin/codex"],
|
|
30281
30448
|
["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
|
|
30282
30449
|
]) {
|
|
30283
|
-
if (
|
|
30450
|
+
if (fs40.existsSync(candidatePath)) {
|
|
30284
30451
|
rows.push(toProbeRow("codex", key, candidatePath));
|
|
30285
30452
|
}
|
|
30286
30453
|
}
|
|
@@ -30296,8 +30463,8 @@ function commandProbeRows(target, key, command, args) {
|
|
|
30296
30463
|
|
|
30297
30464
|
// src/commands/status.ts
|
|
30298
30465
|
import crypto10 from "crypto";
|
|
30299
|
-
import
|
|
30300
|
-
import
|
|
30466
|
+
import fs41 from "fs";
|
|
30467
|
+
import path42 from "path";
|
|
30301
30468
|
function runStatusCommand(options, logger) {
|
|
30302
30469
|
const { config, configDir, sourceRoot } = resolveRuntime(
|
|
30303
30470
|
options,
|
|
@@ -30376,21 +30543,21 @@ function classifyCodexFiles(config, sourceRoot, configDir) {
|
|
|
30376
30543
|
rules: paths.rules
|
|
30377
30544
|
};
|
|
30378
30545
|
const rules = compileRules(
|
|
30379
|
-
|
|
30546
|
+
path42.join(sourceRoot, config.source.rules),
|
|
30380
30547
|
"codex",
|
|
30381
30548
|
mappings,
|
|
30382
30549
|
createLossReport()
|
|
30383
30550
|
);
|
|
30384
|
-
const instructionsSource =
|
|
30551
|
+
const instructionsSource = fs41.readFileSync(path42.join(sourceRoot, config.source.instructions), "utf8").trim();
|
|
30385
30552
|
const composedInstructions = `${instructionsSource}
|
|
30386
30553
|
|
|
30387
30554
|
--- tangyr managed rules ---
|
|
30388
30555
|
${rules.agentsAppendix}`.trim();
|
|
30389
30556
|
const agentFiles = ts(
|
|
30390
|
-
|
|
30557
|
+
path42.join(sourceRoot, config.source.agents, "*.md")
|
|
30391
30558
|
).sort();
|
|
30392
|
-
const hooksSource =
|
|
30393
|
-
const mcpSource =
|
|
30559
|
+
const hooksSource = path42.join(sourceRoot, config.source.hooks, "hooks.json");
|
|
30560
|
+
const mcpSource = path42.join(sourceRoot, config.source.mcp);
|
|
30394
30561
|
const ruleRows = rules.dotRulesFiles.length === 0 ? [
|
|
30395
30562
|
{
|
|
30396
30563
|
component: "rules",
|
|
@@ -30401,7 +30568,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
30401
30568
|
] : rules.dotRulesFiles.map(
|
|
30402
30569
|
(ruleFile) => classifyCompiledFile(
|
|
30403
30570
|
`rules/${ruleFile.name}`,
|
|
30404
|
-
|
|
30571
|
+
path42.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
|
|
30405
30572
|
"codex",
|
|
30406
30573
|
void 0,
|
|
30407
30574
|
config,
|
|
@@ -30419,10 +30586,10 @@ ${rules.agentsAppendix}`.trim();
|
|
|
30419
30586
|
),
|
|
30420
30587
|
...agentFiles.map(
|
|
30421
30588
|
(agentFile) => classifyCompiledFile(
|
|
30422
|
-
`agents/${
|
|
30423
|
-
|
|
30589
|
+
`agents/${path42.basename(agentFile, ".md")}`,
|
|
30590
|
+
path42.join(
|
|
30424
30591
|
resolveTargetPath(codexPaths.agents),
|
|
30425
|
-
`${
|
|
30592
|
+
`${path42.basename(agentFile, ".md")}.toml`
|
|
30426
30593
|
),
|
|
30427
30594
|
"codex",
|
|
30428
30595
|
computeSourceHash(agentFile),
|
|
@@ -30446,11 +30613,11 @@ ${rules.agentsAppendix}`.trim();
|
|
|
30446
30613
|
config,
|
|
30447
30614
|
sourceRoot
|
|
30448
30615
|
),
|
|
30449
|
-
|
|
30616
|
+
fs41.existsSync(hooksSource) ? classifyCodexHooksFile(resolveTargetPath(codexPaths.hooksSharedFile)) : notConfiguredRow(
|
|
30450
30617
|
"hooks",
|
|
30451
30618
|
resolveTargetPath(codexPaths.hooksSharedFile)
|
|
30452
30619
|
),
|
|
30453
|
-
|
|
30620
|
+
fs41.existsSync(mcpSource) ? classifyCompiledFile(
|
|
30454
30621
|
"mcp",
|
|
30455
30622
|
resolveTargetPath(codexPaths.mcpSharedFile),
|
|
30456
30623
|
"codex",
|
|
@@ -30470,7 +30637,7 @@ function classifyCodexHooksFile(filePath) {
|
|
|
30470
30637
|
conformant: true
|
|
30471
30638
|
};
|
|
30472
30639
|
}
|
|
30473
|
-
if (!
|
|
30640
|
+
if (!fs41.existsSync(filePath)) {
|
|
30474
30641
|
return {
|
|
30475
30642
|
component: "hooks",
|
|
30476
30643
|
className: "missing",
|
|
@@ -30502,20 +30669,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
|
|
|
30502
30669
|
mcpSharedFile: paths.mcp_shared_file
|
|
30503
30670
|
};
|
|
30504
30671
|
const agentFiles = ts(
|
|
30505
|
-
|
|
30672
|
+
path42.join(sourceRoot, config.source.agents, "*.md")
|
|
30506
30673
|
).sort();
|
|
30507
30674
|
const commandFiles = ts(
|
|
30508
|
-
|
|
30675
|
+
path42.join(sourceRoot, config.source.commands, "*.md")
|
|
30509
30676
|
).sort();
|
|
30510
|
-
const hooksSource =
|
|
30511
|
-
const mcpSource =
|
|
30677
|
+
const hooksSource = path42.join(sourceRoot, config.source.hooks, "hooks.json");
|
|
30678
|
+
const mcpSource = path42.join(sourceRoot, config.source.mcp);
|
|
30512
30679
|
return [
|
|
30513
30680
|
...agentFiles.map(
|
|
30514
30681
|
(agentFile) => classifyCompiledFile(
|
|
30515
|
-
`agents/${
|
|
30516
|
-
|
|
30682
|
+
`agents/${path42.basename(agentFile, ".md")}`,
|
|
30683
|
+
path42.join(
|
|
30517
30684
|
resolveTargetPath(copilotPaths.agents),
|
|
30518
|
-
`${
|
|
30685
|
+
`${path42.basename(agentFile, ".md")}.agent.md`
|
|
30519
30686
|
),
|
|
30520
30687
|
"copilot",
|
|
30521
30688
|
computeSourceHash(agentFile),
|
|
@@ -30532,10 +30699,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
|
|
|
30532
30699
|
),
|
|
30533
30700
|
...commandFiles.map(
|
|
30534
30701
|
(commandFile) => classifyCompiledFile(
|
|
30535
|
-
`commands/${
|
|
30536
|
-
|
|
30702
|
+
`commands/${path42.basename(commandFile, ".md")}`,
|
|
30703
|
+
path42.join(
|
|
30537
30704
|
resolveTargetPath(copilotPaths.prompts),
|
|
30538
|
-
`${
|
|
30705
|
+
`${path42.basename(commandFile, ".md")}.prompt.md`
|
|
30539
30706
|
),
|
|
30540
30707
|
"copilot",
|
|
30541
30708
|
computeSourceHash(commandFile),
|
|
@@ -30553,9 +30720,9 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
|
|
|
30553
30720
|
config,
|
|
30554
30721
|
sourceRoot
|
|
30555
30722
|
),
|
|
30556
|
-
|
|
30723
|
+
fs41.existsSync(hooksSource) ? classifyCompiledFile(
|
|
30557
30724
|
"hooks",
|
|
30558
|
-
|
|
30725
|
+
path42.join(
|
|
30559
30726
|
resolveTargetPath(copilotPaths.hooks),
|
|
30560
30727
|
"tangyr-managed.json"
|
|
30561
30728
|
),
|
|
@@ -30565,12 +30732,12 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
|
|
|
30565
30732
|
sourceRoot
|
|
30566
30733
|
) : notConfiguredRow(
|
|
30567
30734
|
"hooks",
|
|
30568
|
-
|
|
30735
|
+
path42.join(
|
|
30569
30736
|
resolveTargetPath(copilotPaths.hooks),
|
|
30570
30737
|
"tangyr-managed.json"
|
|
30571
30738
|
)
|
|
30572
30739
|
),
|
|
30573
|
-
|
|
30740
|
+
fs41.existsSync(mcpSource) ? classifyCompiledFile(
|
|
30574
30741
|
"mcp",
|
|
30575
30742
|
resolveTargetPath(copilotPaths.mcpSharedFile),
|
|
30576
30743
|
"copilot",
|
|
@@ -30590,7 +30757,7 @@ function notConfiguredRow(component, filePath) {
|
|
|
30590
30757
|
}
|
|
30591
30758
|
function classifyDirectArtifact(artifact, config, sourceRoot) {
|
|
30592
30759
|
const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
|
|
30593
|
-
const sourcePath = artifact.sourceKey ?
|
|
30760
|
+
const sourcePath = artifact.sourceKey ? path42.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
|
|
30594
30761
|
if (artifactClass === "managed-symlink" && sourcePath && !isSymlinkCurrent(artifact.path, sourcePath)) {
|
|
30595
30762
|
return {
|
|
30596
30763
|
component: artifact.component,
|
|
@@ -30679,9 +30846,9 @@ function classifyClaudeSharedFiles(config, sourceRoot) {
|
|
|
30679
30846
|
classifyHooks(settingsPath),
|
|
30680
30847
|
classifySettings(
|
|
30681
30848
|
settingsPath,
|
|
30682
|
-
|
|
30849
|
+
path42.resolve(sourceRoot, config.source.settings)
|
|
30683
30850
|
),
|
|
30684
|
-
classifyMcp(claudeJsonPath,
|
|
30851
|
+
classifyMcp(claudeJsonPath, path42.resolve(sourceRoot, config.source.mcp))
|
|
30685
30852
|
];
|
|
30686
30853
|
}
|
|
30687
30854
|
function classifyHooks(filePath) {
|
|
@@ -30745,14 +30912,14 @@ function classifyMcp(filePath, sourcePath) {
|
|
|
30745
30912
|
}
|
|
30746
30913
|
function isSymlinkCurrent(linkPath, sourcePath) {
|
|
30747
30914
|
try {
|
|
30748
|
-
return
|
|
30915
|
+
return fs41.realpathSync(linkPath) === fs41.realpathSync(sourcePath);
|
|
30749
30916
|
} catch {
|
|
30750
30917
|
return false;
|
|
30751
30918
|
}
|
|
30752
30919
|
}
|
|
30753
30920
|
function isCompiledCurrent6(filePath, sourcePath) {
|
|
30754
30921
|
try {
|
|
30755
|
-
const marker = extractProvenanceMarker(
|
|
30922
|
+
const marker = extractProvenanceMarker(fs41.readFileSync(filePath, "utf8"));
|
|
30756
30923
|
return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
|
|
30757
30924
|
} catch {
|
|
30758
30925
|
return false;
|
|
@@ -30782,7 +30949,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
|
|
|
30782
30949
|
}
|
|
30783
30950
|
function readCompiledContent(filePath) {
|
|
30784
30951
|
try {
|
|
30785
|
-
return
|
|
30952
|
+
return fs41.readFileSync(filePath, "utf8");
|
|
30786
30953
|
} catch {
|
|
30787
30954
|
return null;
|
|
30788
30955
|
}
|
|
@@ -30813,8 +30980,8 @@ function hashString6(value) {
|
|
|
30813
30980
|
}
|
|
30814
30981
|
|
|
30815
30982
|
// src/commands/sync.ts
|
|
30816
|
-
import
|
|
30817
|
-
import
|
|
30983
|
+
import fs43 from "fs";
|
|
30984
|
+
import path44 from "path";
|
|
30818
30985
|
|
|
30819
30986
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
30820
30987
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -31312,8 +31479,8 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
31312
31479
|
var source_default = chalk;
|
|
31313
31480
|
|
|
31314
31481
|
// src/adapters/claude-code.ts
|
|
31315
|
-
import
|
|
31316
|
-
import
|
|
31482
|
+
import fs42 from "fs";
|
|
31483
|
+
import path43 from "path";
|
|
31317
31484
|
|
|
31318
31485
|
// src/core/shim.ts
|
|
31319
31486
|
import crypto11 from "crypto";
|
|
@@ -31387,7 +31554,8 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
31387
31554
|
hooks_shared_file: resolveTargetPath("~/.claude/settings.json"),
|
|
31388
31555
|
settings_shared_file: resolveTargetPath("~/.claude/settings.json"),
|
|
31389
31556
|
mcp_shared_file: resolveTargetPath("~/.claude.json"),
|
|
31390
|
-
hooks: resolveTargetPath("~/.agents/hooks")
|
|
31557
|
+
hooks: resolveTargetPath("~/.agents/hooks"),
|
|
31558
|
+
hook_scripts: resolveTargetPath("~/.agents/hooks")
|
|
31391
31559
|
};
|
|
31392
31560
|
}
|
|
31393
31561
|
const directComponents = buildDirectComponents(profile);
|
|
@@ -31423,7 +31591,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
31423
31591
|
}
|
|
31424
31592
|
if (!shouldSkipComponent6(options, "instructions") && manifest && scopePath) {
|
|
31425
31593
|
const shimPath = profile.instructions_shim;
|
|
31426
|
-
const agentsMdPath =
|
|
31594
|
+
const agentsMdPath = path43.resolve(sourceRoot, config.source.instructions);
|
|
31427
31595
|
if (!options.dryRun) {
|
|
31428
31596
|
applyClaudeCodeShimUpgrade(
|
|
31429
31597
|
shimPath,
|
|
@@ -31440,15 +31608,24 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
31440
31608
|
}
|
|
31441
31609
|
if (!shouldSkipComponent6(options, "hooks")) {
|
|
31442
31610
|
outcomes.push(
|
|
31443
|
-
syncHookScriptsBridge(
|
|
31611
|
+
syncHookScriptsBridge({
|
|
31612
|
+
source: path43.resolve(sourceRoot, config.source.hooks),
|
|
31613
|
+
destination: profile.hook_scripts,
|
|
31444
31614
|
config,
|
|
31445
31615
|
sourceRoot,
|
|
31446
31616
|
options,
|
|
31447
31617
|
logger,
|
|
31448
|
-
|
|
31618
|
+
onConflict: () => handleConflict6(
|
|
31619
|
+
profile.hook_scripts,
|
|
31620
|
+
config,
|
|
31621
|
+
options,
|
|
31622
|
+
logger,
|
|
31623
|
+
manifest,
|
|
31624
|
+
scopePath
|
|
31625
|
+
),
|
|
31449
31626
|
manifest,
|
|
31450
31627
|
scopePath
|
|
31451
|
-
)
|
|
31628
|
+
})
|
|
31452
31629
|
);
|
|
31453
31630
|
outcomes.push(
|
|
31454
31631
|
syncHooks6(
|
|
@@ -31457,7 +31634,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
31457
31634
|
options,
|
|
31458
31635
|
logger,
|
|
31459
31636
|
profile.hooks_shared_file,
|
|
31460
|
-
profile.
|
|
31637
|
+
profile.hook_scripts
|
|
31461
31638
|
)
|
|
31462
31639
|
);
|
|
31463
31640
|
}
|
|
@@ -31484,13 +31661,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
31484
31661
|
}
|
|
31485
31662
|
function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
|
|
31486
31663
|
if (!mappings.modelTiers.custom_provider) return;
|
|
31487
|
-
const agentsDir =
|
|
31488
|
-
if (!
|
|
31489
|
-
for (const agentFile of ts(
|
|
31664
|
+
const agentsDir = path43.join(sourceRoot, config.source.agents);
|
|
31665
|
+
if (!fs42.existsSync(agentsDir)) return;
|
|
31666
|
+
for (const agentFile of ts(path43.join(agentsDir, "*.md")).sort()) {
|
|
31490
31667
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
31491
31668
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
31492
31669
|
if (hasProvider) {
|
|
31493
|
-
const basename =
|
|
31670
|
+
const basename = path43.basename(agentFile);
|
|
31494
31671
|
addLoss(lossReport, "claude-code", "agents", {
|
|
31495
31672
|
source: `agents/${basename}`,
|
|
31496
31673
|
fields: [
|
|
@@ -31515,19 +31692,19 @@ function shouldSkipComponent6(options, component) {
|
|
|
31515
31692
|
function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath, logger) {
|
|
31516
31693
|
const expectedBodyHash = shimBodyHash();
|
|
31517
31694
|
const shimContent = buildAgentsMdShim(shimPath, agentsMdPath, "claude-code");
|
|
31518
|
-
if (!
|
|
31695
|
+
if (!fs42.existsSync(shimPath)) {
|
|
31519
31696
|
manifest.artifacts.push({
|
|
31520
|
-
relativePath:
|
|
31697
|
+
relativePath: path43.relative(scopePath, shimPath),
|
|
31521
31698
|
hash: expectedBodyHash,
|
|
31522
31699
|
origin: "tangyr-managed"
|
|
31523
31700
|
});
|
|
31524
31701
|
writeManifest(scopePath, manifest);
|
|
31525
|
-
|
|
31526
|
-
|
|
31702
|
+
fs42.mkdirSync(path43.dirname(shimPath), { recursive: true });
|
|
31703
|
+
fs42.writeFileSync(shimPath, shimContent);
|
|
31527
31704
|
logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
|
|
31528
31705
|
return;
|
|
31529
31706
|
}
|
|
31530
|
-
const existing =
|
|
31707
|
+
const existing = fs42.readFileSync(shimPath, "utf8");
|
|
31531
31708
|
const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
|
|
31532
31709
|
const marker = extractProvenanceMarker(firstNonEmptyLine);
|
|
31533
31710
|
if (marker !== null && marker.hash === expectedBodyHash) {
|
|
@@ -31538,21 +31715,21 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
31538
31715
|
}
|
|
31539
31716
|
backupFile(shimPath, manifest);
|
|
31540
31717
|
writeManifest(scopePath, manifest);
|
|
31541
|
-
|
|
31718
|
+
fs42.writeFileSync(shimPath, shimContent);
|
|
31542
31719
|
manifest.artifacts.push({
|
|
31543
|
-
relativePath:
|
|
31720
|
+
relativePath: path43.relative(scopePath, shimPath),
|
|
31544
31721
|
hash: expectedBodyHash,
|
|
31545
31722
|
origin: "tangyr-managed"
|
|
31546
31723
|
});
|
|
31547
31724
|
logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
|
|
31548
31725
|
}
|
|
31549
31726
|
function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
|
|
31550
|
-
const source =
|
|
31727
|
+
const source = path43.resolve(
|
|
31551
31728
|
sourceRoot,
|
|
31552
31729
|
config.source[directComponent.sourceKey]
|
|
31553
31730
|
);
|
|
31554
31731
|
const destination = directComponent.destination;
|
|
31555
|
-
if (!
|
|
31732
|
+
if (!fs42.existsSync(source)) {
|
|
31556
31733
|
return skippedMissingSource6(directComponent.component, source);
|
|
31557
31734
|
}
|
|
31558
31735
|
if (options.dryRun) {
|
|
@@ -31566,7 +31743,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
31566
31743
|
};
|
|
31567
31744
|
}
|
|
31568
31745
|
const artifactClass = classifyArtifact(destination, config, sourceRoot);
|
|
31569
|
-
if (artifactClass === "managed-symlink" &&
|
|
31746
|
+
if (artifactClass === "managed-symlink" && isSymlinkTo7(destination, source)) {
|
|
31570
31747
|
return {
|
|
31571
31748
|
component: directComponent.component,
|
|
31572
31749
|
status: "skipped-current",
|
|
@@ -31574,7 +31751,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
31574
31751
|
};
|
|
31575
31752
|
}
|
|
31576
31753
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
31577
|
-
|
|
31754
|
+
fs42.unlinkSync(destination);
|
|
31578
31755
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
31579
31756
|
return {
|
|
31580
31757
|
component: directComponent.component,
|
|
@@ -31582,9 +31759,9 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
31582
31759
|
path: destination
|
|
31583
31760
|
};
|
|
31584
31761
|
} else if (artifactClass === "managed-symlink") {
|
|
31585
|
-
|
|
31762
|
+
fs42.unlinkSync(destination);
|
|
31586
31763
|
}
|
|
31587
|
-
ensureDir(
|
|
31764
|
+
ensureDir(path43.dirname(destination));
|
|
31588
31765
|
createRelativeSymlink(source, destination, directComponent.type, {
|
|
31589
31766
|
logger,
|
|
31590
31767
|
provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
|
|
@@ -31601,8 +31778,8 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
31601
31778
|
};
|
|
31602
31779
|
}
|
|
31603
31780
|
function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination, manifest, scopePath) {
|
|
31604
|
-
const source =
|
|
31605
|
-
if (!
|
|
31781
|
+
const source = path43.resolve(sourceRoot, config.source.skills);
|
|
31782
|
+
if (!fs42.existsSync(source)) {
|
|
31606
31783
|
return [skippedMissingSource6("skills", source)];
|
|
31607
31784
|
}
|
|
31608
31785
|
const declaredNames = resolveKitSkillNames(sourceRoot);
|
|
@@ -31612,7 +31789,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
31612
31789
|
if (isLegacyWholesaleSymlink) {
|
|
31613
31790
|
for (const name of foreignSkillNames(source, declaredNames)) {
|
|
31614
31791
|
logger.info(
|
|
31615
|
-
`[dry-run] skills: migrate foreign skill ${
|
|
31792
|
+
`[dry-run] skills: migrate foreign skill ${path43.join(source, name)} -> ${path43.join(destination, name)}`
|
|
31616
31793
|
);
|
|
31617
31794
|
}
|
|
31618
31795
|
logger.info(
|
|
@@ -31620,9 +31797,9 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
31620
31797
|
);
|
|
31621
31798
|
}
|
|
31622
31799
|
for (const name of declaredNames ?? listSkillDirNames(source)) {
|
|
31623
|
-
const skillDestination =
|
|
31800
|
+
const skillDestination = path43.join(destination, name);
|
|
31624
31801
|
logger.info(
|
|
31625
|
-
`[dry-run] skills: symlink ${
|
|
31802
|
+
`[dry-run] skills: symlink ${path43.join(source, name)} -> ${skillDestination}`
|
|
31626
31803
|
);
|
|
31627
31804
|
outcomes2.push({
|
|
31628
31805
|
component: "skills",
|
|
@@ -31655,13 +31832,13 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
31655
31832
|
return outcomes;
|
|
31656
31833
|
}
|
|
31657
31834
|
function syncSingleSkill(config, sourceRoot, options, logger, source, destination, name, manifest, scopePath) {
|
|
31658
|
-
const skillSource =
|
|
31659
|
-
const skillDestination =
|
|
31660
|
-
if (!
|
|
31835
|
+
const skillSource = path43.join(source, name);
|
|
31836
|
+
const skillDestination = path43.join(destination, name);
|
|
31837
|
+
if (!fs42.existsSync(skillSource)) {
|
|
31661
31838
|
return skippedMissingSource6("skills", skillSource);
|
|
31662
31839
|
}
|
|
31663
31840
|
const artifactClass = classifyArtifact(skillDestination, config, sourceRoot);
|
|
31664
|
-
if (artifactClass === "managed-symlink" &&
|
|
31841
|
+
if (artifactClass === "managed-symlink" && isSymlinkTo7(skillDestination, skillSource)) {
|
|
31665
31842
|
return {
|
|
31666
31843
|
component: "skills",
|
|
31667
31844
|
status: "skipped-current",
|
|
@@ -31669,7 +31846,7 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
|
|
|
31669
31846
|
};
|
|
31670
31847
|
}
|
|
31671
31848
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
|
|
31672
|
-
|
|
31849
|
+
fs42.unlinkSync(skillDestination);
|
|
31673
31850
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict6(
|
|
31674
31851
|
skillDestination,
|
|
31675
31852
|
config,
|
|
@@ -31680,25 +31857,25 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
|
|
|
31680
31857
|
)) {
|
|
31681
31858
|
return { component: "skills", status: "conflict", path: skillDestination };
|
|
31682
31859
|
} else if (artifactClass === "managed-symlink") {
|
|
31683
|
-
|
|
31860
|
+
fs42.unlinkSync(skillDestination);
|
|
31684
31861
|
}
|
|
31685
31862
|
createRelativeSymlink(skillSource, skillDestination, "dir");
|
|
31686
31863
|
return { component: "skills", status: "success", path: skillDestination };
|
|
31687
31864
|
}
|
|
31688
31865
|
function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
|
|
31689
31866
|
const foreignNames = foreignSkillNames(source, declaredNames);
|
|
31690
|
-
|
|
31867
|
+
fs42.unlinkSync(destination);
|
|
31691
31868
|
ensureDir(destination);
|
|
31692
31869
|
for (const name of foreignNames) {
|
|
31693
|
-
const from =
|
|
31694
|
-
const to =
|
|
31695
|
-
if (
|
|
31870
|
+
const from = path43.join(source, name);
|
|
31871
|
+
const to = path43.join(destination, name);
|
|
31872
|
+
if (fs42.existsSync(to)) {
|
|
31696
31873
|
logger.warn(
|
|
31697
31874
|
`skills migration: ${to} already exists \u2014 skipping ${from} to avoid overwrite. Nothing in the kit was changed.`
|
|
31698
31875
|
);
|
|
31699
31876
|
continue;
|
|
31700
31877
|
}
|
|
31701
|
-
|
|
31878
|
+
fs42.cpSync(from, to, { recursive: true, verbatimSymlinks: true });
|
|
31702
31879
|
logger.warn(
|
|
31703
31880
|
`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.`
|
|
31704
31881
|
);
|
|
@@ -31712,50 +31889,18 @@ function foreignSkillNames(source, declaredNames) {
|
|
|
31712
31889
|
return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
|
|
31713
31890
|
}
|
|
31714
31891
|
function listSkillDirNames(dir) {
|
|
31715
|
-
if (!
|
|
31892
|
+
if (!fs42.existsSync(dir)) {
|
|
31716
31893
|
return [];
|
|
31717
31894
|
}
|
|
31718
|
-
return
|
|
31895
|
+
return fs42.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
31719
31896
|
}
|
|
31720
31897
|
function isSymlinkPath(filePath) {
|
|
31721
31898
|
try {
|
|
31722
|
-
return
|
|
31899
|
+
return fs42.lstatSync(filePath).isSymbolicLink();
|
|
31723
31900
|
} catch {
|
|
31724
31901
|
return false;
|
|
31725
31902
|
}
|
|
31726
31903
|
}
|
|
31727
|
-
function syncHookScriptsBridge(config, sourceRoot, options, logger, destination, manifest, scopePath) {
|
|
31728
|
-
const source = path41.resolve(sourceRoot, config.source.hooks);
|
|
31729
|
-
if (!fs41.existsSync(source)) {
|
|
31730
|
-
return skippedMissingSource6("hooks", source);
|
|
31731
|
-
}
|
|
31732
|
-
if (options.dryRun) {
|
|
31733
|
-
logger.info(`[dry-run] hooks: symlink ${source} -> ${destination}`);
|
|
31734
|
-
return { component: "hooks", status: "dry-run", path: destination };
|
|
31735
|
-
}
|
|
31736
|
-
const artifactClass = classifyArtifact(destination, config, sourceRoot);
|
|
31737
|
-
if (artifactClass === "managed-symlink" && isSymlinkTo6(destination, source)) {
|
|
31738
|
-
return { component: "hooks", status: "skipped-current", path: destination };
|
|
31739
|
-
}
|
|
31740
|
-
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
31741
|
-
fs41.unlinkSync(destination);
|
|
31742
|
-
} else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
31743
|
-
return { component: "hooks", status: "conflict", path: destination };
|
|
31744
|
-
} else if (artifactClass === "managed-symlink") {
|
|
31745
|
-
fs41.unlinkSync(destination);
|
|
31746
|
-
}
|
|
31747
|
-
ensureDir(path41.dirname(destination));
|
|
31748
|
-
createRelativeSymlink(source, destination, "dir");
|
|
31749
|
-
return { component: "hooks", status: "success", path: destination };
|
|
31750
|
-
}
|
|
31751
|
-
function hookScriptsDir(scriptsBridge) {
|
|
31752
|
-
const globalBridge = resolveTargetPath("~/.agents/hooks");
|
|
31753
|
-
if (path41.resolve(scriptsBridge) === path41.resolve(globalBridge)) {
|
|
31754
|
-
return GLOBAL_HOOK_SCRIPTS_DIR;
|
|
31755
|
-
}
|
|
31756
|
-
const relative = path41.relative(process.cwd(), scriptsBridge);
|
|
31757
|
-
return relative.startsWith("..") || path41.isAbsolute(relative) ? path41.join(scriptsBridge, "scripts") : `"$CLAUDE_PROJECT_DIR"/${path41.posix.join(relative.split(path41.sep).join("/"), "scripts")}`;
|
|
31758
|
-
}
|
|
31759
31904
|
function syncHooks6(config, sourceRoot, options, logger, destination, scriptsBridge) {
|
|
31760
31905
|
const hooksDir = resolveHooksSourceDir(sourceRoot, config);
|
|
31761
31906
|
if (!hooksSourceExists(sourceRoot, config)) {
|
|
@@ -31769,14 +31914,14 @@ function syncHooks6(config, sourceRoot, options, logger, destination, scriptsBri
|
|
|
31769
31914
|
const sourceHooks = loadSourceHooks(
|
|
31770
31915
|
hooksDir,
|
|
31771
31916
|
resolveKitHookNames(sourceRoot),
|
|
31772
|
-
hookScriptsDir(scriptsBridge)
|
|
31917
|
+
hookScriptsDir(scriptsBridge, "claude-code").prefix
|
|
31773
31918
|
);
|
|
31774
31919
|
settings.hooks = markManaged(sourceHooks.hooks ?? {});
|
|
31775
31920
|
const changed = writeSharedFile(
|
|
31776
31921
|
destination,
|
|
31777
31922
|
settings,
|
|
31778
31923
|
stringifyJson3,
|
|
31779
|
-
!
|
|
31924
|
+
!fs42.existsSync(destination),
|
|
31780
31925
|
logger
|
|
31781
31926
|
);
|
|
31782
31927
|
return {
|
|
@@ -31786,8 +31931,8 @@ function syncHooks6(config, sourceRoot, options, logger, destination, scriptsBri
|
|
|
31786
31931
|
};
|
|
31787
31932
|
}
|
|
31788
31933
|
function syncMcp6(config, sourceRoot, options, logger, destination) {
|
|
31789
|
-
const source =
|
|
31790
|
-
if (!
|
|
31934
|
+
const source = path43.resolve(sourceRoot, config.source.mcp);
|
|
31935
|
+
if (!fs42.existsSync(source)) {
|
|
31791
31936
|
return skippedMissingSource6("mcp", source);
|
|
31792
31937
|
}
|
|
31793
31938
|
if (options.dryRun) {
|
|
@@ -31812,7 +31957,7 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
|
|
|
31812
31957
|
destination,
|
|
31813
31958
|
hostConfig,
|
|
31814
31959
|
stringifyJson3,
|
|
31815
|
-
!
|
|
31960
|
+
!fs42.existsSync(destination),
|
|
31816
31961
|
logger
|
|
31817
31962
|
);
|
|
31818
31963
|
return {
|
|
@@ -31822,8 +31967,8 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
|
|
|
31822
31967
|
};
|
|
31823
31968
|
}
|
|
31824
31969
|
function syncSettings2(config, sourceRoot, options, logger, destination) {
|
|
31825
|
-
const source =
|
|
31826
|
-
if (!
|
|
31970
|
+
const source = path43.resolve(sourceRoot, config.source.settings);
|
|
31971
|
+
if (!fs42.existsSync(source)) {
|
|
31827
31972
|
return skippedMissingSource6("settings", source);
|
|
31828
31973
|
}
|
|
31829
31974
|
if (options.dryRun) {
|
|
@@ -31841,7 +31986,7 @@ function syncSettings2(config, sourceRoot, options, logger, destination) {
|
|
|
31841
31986
|
destination,
|
|
31842
31987
|
settings,
|
|
31843
31988
|
stringifyJson3,
|
|
31844
|
-
!
|
|
31989
|
+
!fs42.existsSync(destination),
|
|
31845
31990
|
logger
|
|
31846
31991
|
);
|
|
31847
31992
|
return {
|
|
@@ -31866,11 +32011,11 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
|
|
|
31866
32011
|
backupFile(destination, manifest);
|
|
31867
32012
|
writeManifest(scopePath, manifest);
|
|
31868
32013
|
} else {
|
|
31869
|
-
|
|
32014
|
+
fs42.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
31870
32015
|
}
|
|
31871
32016
|
return true;
|
|
31872
32017
|
}
|
|
31873
|
-
|
|
32018
|
+
fs42.rmSync(destination, { recursive: true, force: true });
|
|
31874
32019
|
return true;
|
|
31875
32020
|
}
|
|
31876
32021
|
function skippedMissingSource6(component, source) {
|
|
@@ -31880,18 +32025,18 @@ function skippedMissingSource6(component, source) {
|
|
|
31880
32025
|
path: `${source}: source not configured`
|
|
31881
32026
|
};
|
|
31882
32027
|
}
|
|
31883
|
-
function
|
|
32028
|
+
function isSymlinkTo7(linkPath, source) {
|
|
31884
32029
|
try {
|
|
31885
|
-
return
|
|
32030
|
+
return fs42.realpathSync(linkPath) === fs42.realpathSync(source);
|
|
31886
32031
|
} catch {
|
|
31887
32032
|
return false;
|
|
31888
32033
|
}
|
|
31889
32034
|
}
|
|
31890
32035
|
function readJsonObject4(filePath) {
|
|
31891
|
-
if (!
|
|
32036
|
+
if (!fs42.existsSync(filePath)) {
|
|
31892
32037
|
return {};
|
|
31893
32038
|
}
|
|
31894
|
-
const parsed = JSON.parse(
|
|
32039
|
+
const parsed = JSON.parse(fs42.readFileSync(filePath, "utf8"));
|
|
31895
32040
|
return isRecord5(parsed) ? parsed : {};
|
|
31896
32041
|
}
|
|
31897
32042
|
function markManaged(value) {
|
|
@@ -32091,26 +32236,18 @@ async function runSyncCommand(options, logger) {
|
|
|
32091
32236
|
reportHookRejections(
|
|
32092
32237
|
lossReport,
|
|
32093
32238
|
targets,
|
|
32094
|
-
|
|
32239
|
+
path44.resolve(kitInfo.path, "hooks"),
|
|
32095
32240
|
kitInfo.components.hooks.declared
|
|
32096
32241
|
);
|
|
32097
32242
|
const hooksConflict = reportHooksSourceConflict(
|
|
32098
32243
|
lossReport,
|
|
32099
32244
|
targets,
|
|
32100
|
-
|
|
32245
|
+
path44.resolve(kitInfo.path, "hooks"),
|
|
32101
32246
|
kitInfo.components.hooks.declared
|
|
32102
32247
|
);
|
|
32103
32248
|
if (hooksConflict) {
|
|
32104
32249
|
logger.warn(hooksConflict);
|
|
32105
32250
|
}
|
|
32106
|
-
if (syncOptions.scope === "project") {
|
|
32107
|
-
reportProjectScopeScriptPath(
|
|
32108
|
-
lossReport,
|
|
32109
|
-
targets,
|
|
32110
|
-
path42.resolve(kitInfo.path, "hooks"),
|
|
32111
|
-
kitInfo.components.hooks.declared
|
|
32112
|
-
);
|
|
32113
|
-
}
|
|
32114
32251
|
}
|
|
32115
32252
|
writeLossReport(options.lossReport, lossReport);
|
|
32116
32253
|
printOutcomeTable(results);
|
|
@@ -32216,8 +32353,8 @@ function updateManifest(kitInfo, kitSync) {
|
|
|
32216
32353
|
writeManifest(kitSync.scopePath, kitSync.manifest);
|
|
32217
32354
|
}
|
|
32218
32355
|
function resolveKitFilePath(kitPath, relativePath) {
|
|
32219
|
-
const fullPath =
|
|
32220
|
-
return
|
|
32356
|
+
const fullPath = path44.join(kitPath, relativePath);
|
|
32357
|
+
return fs43.existsSync(fullPath) ? fullPath : null;
|
|
32221
32358
|
}
|
|
32222
32359
|
function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
|
|
32223
32360
|
if (removedSourcePaths.length === 0 || !mappings) {
|
|
@@ -32280,9 +32417,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
32280
32417
|
}
|
|
32281
32418
|
if (relativePath.startsWith("agents/")) {
|
|
32282
32419
|
removeManagedCompiledArtifact2(
|
|
32283
|
-
|
|
32420
|
+
path44.join(
|
|
32284
32421
|
resolveTargetPath(paths.agents ?? ""),
|
|
32285
|
-
`${
|
|
32422
|
+
`${path44.parse(relativePath).name}.agent.md`
|
|
32286
32423
|
),
|
|
32287
32424
|
"copilot",
|
|
32288
32425
|
relativePath,
|
|
@@ -32292,9 +32429,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
32292
32429
|
}
|
|
32293
32430
|
if (relativePath.startsWith("commands/")) {
|
|
32294
32431
|
removeManagedCompiledArtifact2(
|
|
32295
|
-
|
|
32432
|
+
path44.join(
|
|
32296
32433
|
resolveTargetPath(paths.prompts ?? ""),
|
|
32297
|
-
`${
|
|
32434
|
+
`${path44.parse(relativePath).name}.prompt.md`
|
|
32298
32435
|
),
|
|
32299
32436
|
"copilot",
|
|
32300
32437
|
relativePath,
|
|
@@ -32304,7 +32441,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
32304
32441
|
}
|
|
32305
32442
|
if (relativePath.endsWith("hooks.json")) {
|
|
32306
32443
|
removeManagedCompiledArtifact2(
|
|
32307
|
-
|
|
32444
|
+
path44.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
|
|
32308
32445
|
"copilot",
|
|
32309
32446
|
relativePath,
|
|
32310
32447
|
logger
|
|
@@ -32334,9 +32471,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
32334
32471
|
}
|
|
32335
32472
|
if (relativePath.startsWith("agents/")) {
|
|
32336
32473
|
removeManagedCompiledArtifact2(
|
|
32337
|
-
|
|
32474
|
+
path44.join(
|
|
32338
32475
|
resolveTargetPath(paths.agents ?? ""),
|
|
32339
|
-
`${
|
|
32476
|
+
`${path44.parse(relativePath).name}.toml`
|
|
32340
32477
|
),
|
|
32341
32478
|
"codex",
|
|
32342
32479
|
relativePath,
|
|
@@ -32346,9 +32483,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
32346
32483
|
}
|
|
32347
32484
|
if (relativePath.startsWith("rules/")) {
|
|
32348
32485
|
removeManagedCompiledArtifact2(
|
|
32349
|
-
|
|
32486
|
+
path44.join(
|
|
32350
32487
|
resolveTargetPath(paths.rules ?? ""),
|
|
32351
|
-
`${
|
|
32488
|
+
`${path44.parse(relativePath).name}.rules`
|
|
32352
32489
|
),
|
|
32353
32490
|
"codex",
|
|
32354
32491
|
relativePath,
|
|
@@ -32387,9 +32524,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
32387
32524
|
}
|
|
32388
32525
|
if (relativePath.startsWith("agents/")) {
|
|
32389
32526
|
removeManagedCompiledArtifact2(
|
|
32390
|
-
|
|
32527
|
+
path44.join(
|
|
32391
32528
|
resolveTargetPath(paths.agents ?? ""),
|
|
32392
|
-
`${
|
|
32529
|
+
`${path44.parse(relativePath).name}.md`
|
|
32393
32530
|
),
|
|
32394
32531
|
"opencode",
|
|
32395
32532
|
relativePath,
|
|
@@ -32399,9 +32536,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
32399
32536
|
}
|
|
32400
32537
|
if (relativePath.startsWith("commands/")) {
|
|
32401
32538
|
removeManagedCompiledArtifact2(
|
|
32402
|
-
|
|
32539
|
+
path44.join(
|
|
32403
32540
|
resolveTargetPath(paths.commands ?? ""),
|
|
32404
|
-
`${
|
|
32541
|
+
`${path44.parse(relativePath).name}.md`
|
|
32405
32542
|
),
|
|
32406
32543
|
"opencode",
|
|
32407
32544
|
relativePath,
|
|
@@ -32433,9 +32570,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
32433
32570
|
}
|
|
32434
32571
|
if (relativePath.startsWith("agents/")) {
|
|
32435
32572
|
removeManagedCompiledArtifact2(
|
|
32436
|
-
|
|
32573
|
+
path44.join(
|
|
32437
32574
|
resolveTargetPath(paths.agents ?? ""),
|
|
32438
|
-
`${
|
|
32575
|
+
`${path44.parse(relativePath).name}.md`
|
|
32439
32576
|
),
|
|
32440
32577
|
"cursor",
|
|
32441
32578
|
relativePath,
|
|
@@ -32445,9 +32582,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
32445
32582
|
}
|
|
32446
32583
|
if (relativePath.startsWith("rules/")) {
|
|
32447
32584
|
removeManagedCompiledArtifact2(
|
|
32448
|
-
|
|
32585
|
+
path44.join(
|
|
32449
32586
|
resolveTargetPath(paths.rules ?? ""),
|
|
32450
|
-
`${
|
|
32587
|
+
`${path44.parse(relativePath).name}.mdc`
|
|
32451
32588
|
),
|
|
32452
32589
|
"cursor",
|
|
32453
32590
|
relativePath,
|
|
@@ -32457,9 +32594,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
32457
32594
|
}
|
|
32458
32595
|
if (relativePath.startsWith("commands/")) {
|
|
32459
32596
|
removeManagedCompiledArtifact2(
|
|
32460
|
-
|
|
32597
|
+
path44.join(
|
|
32461
32598
|
resolveTargetPath(paths.skills ?? ""),
|
|
32462
|
-
|
|
32599
|
+
path44.parse(relativePath).name,
|
|
32463
32600
|
"SKILL.md"
|
|
32464
32601
|
),
|
|
32465
32602
|
"cursor",
|
|
@@ -32503,9 +32640,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
32503
32640
|
}
|
|
32504
32641
|
if (relativePath.startsWith("rules/")) {
|
|
32505
32642
|
removeManagedCompiledArtifact2(
|
|
32506
|
-
|
|
32643
|
+
path44.join(
|
|
32507
32644
|
resolveTargetPath(paths.rules ?? ""),
|
|
32508
|
-
`${
|
|
32645
|
+
`${path44.parse(relativePath).name}.md`
|
|
32509
32646
|
),
|
|
32510
32647
|
"cline",
|
|
32511
32648
|
relativePath,
|
|
@@ -32515,9 +32652,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
32515
32652
|
}
|
|
32516
32653
|
if (relativePath.startsWith("commands/")) {
|
|
32517
32654
|
removeManagedCompiledArtifact2(
|
|
32518
|
-
|
|
32655
|
+
path44.join(
|
|
32519
32656
|
resolveTargetPath(paths.workflows ?? ""),
|
|
32520
|
-
|
|
32657
|
+
path44.basename(relativePath)
|
|
32521
32658
|
),
|
|
32522
32659
|
"cline",
|
|
32523
32660
|
relativePath,
|
|
@@ -32535,17 +32672,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
32535
32672
|
}
|
|
32536
32673
|
}
|
|
32537
32674
|
function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
|
|
32538
|
-
if (!
|
|
32675
|
+
if (!fs43.existsSync(artifactPath)) {
|
|
32539
32676
|
return;
|
|
32540
32677
|
}
|
|
32541
|
-
if (!
|
|
32678
|
+
if (!fs43.statSync(artifactPath).isFile()) {
|
|
32542
32679
|
return;
|
|
32543
32680
|
}
|
|
32544
|
-
const marker = extractProvenanceMarker(
|
|
32681
|
+
const marker = extractProvenanceMarker(fs43.readFileSync(artifactPath, "utf8"));
|
|
32545
32682
|
if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
|
|
32546
32683
|
return;
|
|
32547
32684
|
}
|
|
32548
|
-
|
|
32685
|
+
fs43.rmSync(artifactPath, { force: true });
|
|
32549
32686
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
32550
32687
|
}
|
|
32551
32688
|
function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
@@ -32576,10 +32713,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
|
|
|
32576
32713
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
32577
32714
|
}
|
|
32578
32715
|
function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
32579
|
-
if (!
|
|
32716
|
+
if (!fs43.existsSync(artifactPath)) {
|
|
32580
32717
|
return;
|
|
32581
32718
|
}
|
|
32582
|
-
const content =
|
|
32719
|
+
const content = fs43.readFileSync(artifactPath, "utf8");
|
|
32583
32720
|
const startMarker = "# tangyr: managed mcp start";
|
|
32584
32721
|
const endMarker = "# tangyr: managed mcp end";
|
|
32585
32722
|
const startIndex = content.indexOf(startMarker);
|
|
@@ -32596,19 +32733,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
|
32596
32733
|
const after = content.slice(endIndex + endMarker.length).trimStart();
|
|
32597
32734
|
const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
|
|
32598
32735
|
if (cleaned.length === 0) {
|
|
32599
|
-
|
|
32736
|
+
fs43.rmSync(artifactPath, { force: true });
|
|
32600
32737
|
} else {
|
|
32601
|
-
|
|
32738
|
+
fs43.writeFileSync(artifactPath, `${cleaned}
|
|
32602
32739
|
`);
|
|
32603
32740
|
}
|
|
32604
32741
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
32605
32742
|
}
|
|
32606
32743
|
function readJsonObject5(filePath) {
|
|
32607
|
-
if (!
|
|
32744
|
+
if (!fs43.existsSync(filePath)) {
|
|
32608
32745
|
return null;
|
|
32609
32746
|
}
|
|
32610
32747
|
try {
|
|
32611
|
-
const parsed = JSON.parse(
|
|
32748
|
+
const parsed = JSON.parse(fs43.readFileSync(filePath, "utf8"));
|
|
32612
32749
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
32613
32750
|
} catch {
|
|
32614
32751
|
return null;
|
|
@@ -32622,10 +32759,10 @@ function readJsonMetadata(value) {
|
|
|
32622
32759
|
}
|
|
32623
32760
|
function writeJsonOrRemove2(filePath, parsed) {
|
|
32624
32761
|
if (isEmptyJsonValue2(parsed)) {
|
|
32625
|
-
|
|
32762
|
+
fs43.rmSync(filePath, { force: true });
|
|
32626
32763
|
return;
|
|
32627
32764
|
}
|
|
32628
|
-
|
|
32765
|
+
fs43.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
32629
32766
|
`);
|
|
32630
32767
|
}
|
|
32631
32768
|
function isEmptyJsonValue2(value) {
|
|
@@ -32685,8 +32822,8 @@ function removeManagedHookEntries(value, expectedSource) {
|
|
|
32685
32822
|
}
|
|
32686
32823
|
|
|
32687
32824
|
// src/commands/validate.ts
|
|
32688
|
-
import
|
|
32689
|
-
import
|
|
32825
|
+
import fs44 from "fs";
|
|
32826
|
+
import path45 from "path";
|
|
32690
32827
|
var SUPPORTED_KIT_FORMATS2 = [1];
|
|
32691
32828
|
var SUPPORTED_DISCIPLINE_VERSIONS = [
|
|
32692
32829
|
"0.14.0",
|
|
@@ -32780,10 +32917,10 @@ function checkSkillSubfolderNames(kit) {
|
|
|
32780
32917
|
const notices = [];
|
|
32781
32918
|
const canonical = new Set(CANONICAL_SKILL_SUBFOLDERS);
|
|
32782
32919
|
for (const name of kit.components.skills.declared) {
|
|
32783
|
-
const skillDir =
|
|
32920
|
+
const skillDir = path45.join(kit.path, "skills", name);
|
|
32784
32921
|
let entries;
|
|
32785
32922
|
try {
|
|
32786
|
-
entries =
|
|
32923
|
+
entries = fs44.readdirSync(skillDir, { withFileTypes: true });
|
|
32787
32924
|
} catch {
|
|
32788
32925
|
continue;
|
|
32789
32926
|
}
|
|
@@ -32801,7 +32938,7 @@ function checkSkillSubfolderNames(kit) {
|
|
|
32801
32938
|
return notices;
|
|
32802
32939
|
}
|
|
32803
32940
|
function checkHooksSourceForm(kit) {
|
|
32804
|
-
const hooksDir =
|
|
32941
|
+
const hooksDir = path45.join(kit.path, "hooks");
|
|
32805
32942
|
const message = describeHooksSourceConflict(
|
|
32806
32943
|
hooksDir,
|
|
32807
32944
|
kit.components.hooks.declared
|
|
@@ -32813,12 +32950,12 @@ function checkHooksSourceForm(kit) {
|
|
|
32813
32950
|
} : null;
|
|
32814
32951
|
}
|
|
32815
32952
|
function checkHookDeclarations(kit) {
|
|
32816
|
-
const hooksDir =
|
|
32953
|
+
const hooksDir = path45.join(kit.path, "hooks");
|
|
32817
32954
|
return collectHookRejections(hooksDir, kit.components.hooks.declared).map(
|
|
32818
32955
|
(r) => ({
|
|
32819
32956
|
code: "hook-declaration-invalid",
|
|
32820
|
-
location: `hooks/${
|
|
32821
|
-
message: `hooks: '${
|
|
32957
|
+
location: `hooks/${path45.basename(r.file)}`,
|
|
32958
|
+
message: `hooks: '${path45.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.`
|
|
32822
32959
|
})
|
|
32823
32960
|
);
|
|
32824
32961
|
}
|
|
@@ -32838,11 +32975,11 @@ function checkKitFormatSupported(kit) {
|
|
|
32838
32975
|
function checkEntrypointExists(kit) {
|
|
32839
32976
|
const declared = kit.entrypoint;
|
|
32840
32977
|
const entrypoint = declared ?? DEFAULT_ENTRYPOINT;
|
|
32841
|
-
const entrypointPath =
|
|
32842
|
-
if (
|
|
32978
|
+
const entrypointPath = path45.join(kit.path, entrypoint);
|
|
32979
|
+
if (fs44.existsSync(entrypointPath)) {
|
|
32843
32980
|
return null;
|
|
32844
32981
|
}
|
|
32845
|
-
const legacyPresent = declared === void 0 &&
|
|
32982
|
+
const legacyPresent = declared === void 0 && fs44.existsSync(path45.join(kit.path, LEGACY_ENTRYPOINT));
|
|
32846
32983
|
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.`;
|
|
32847
32984
|
return {
|
|
32848
32985
|
code: "entrypoint-missing",
|
|
@@ -32898,9 +33035,9 @@ function checkComponentFrontmatter(kit) {
|
|
|
32898
33035
|
const missingSet = new Set(kit.components[cat].missing);
|
|
32899
33036
|
for (const name of kit.components[cat].declared) {
|
|
32900
33037
|
if (missingSet.has(name)) continue;
|
|
32901
|
-
const filePath = cat === "skills" ?
|
|
32902
|
-
if (!
|
|
32903
|
-
const relPath =
|
|
33038
|
+
const filePath = cat === "skills" ? path45.join(kit.path, cat, name, "SKILL.md") : path45.join(kit.path, cat, `${name}.md`);
|
|
33039
|
+
if (!fs44.existsSync(filePath)) continue;
|
|
33040
|
+
const relPath = path45.relative(kit.path, filePath);
|
|
32904
33041
|
try {
|
|
32905
33042
|
const { data } = parseMarkdownFrontmatter(filePath);
|
|
32906
33043
|
for (const field of requiredFields) {
|
|
@@ -32925,10 +33062,10 @@ function checkComponentFrontmatter(kit) {
|
|
|
32925
33062
|
}
|
|
32926
33063
|
function checkReservedRootNames(kit) {
|
|
32927
33064
|
const violations = [];
|
|
32928
|
-
if (!
|
|
33065
|
+
if (!fs44.existsSync(kit.path) || !fs44.statSync(kit.path).isDirectory()) {
|
|
32929
33066
|
return violations;
|
|
32930
33067
|
}
|
|
32931
|
-
const entries =
|
|
33068
|
+
const entries = fs44.readdirSync(kit.path, { withFileTypes: true });
|
|
32932
33069
|
for (const entry of entries) {
|
|
32933
33070
|
if (RESERVED_ROOT_NAMES.includes(entry.name)) {
|
|
32934
33071
|
violations.push({
|
|
@@ -32945,8 +33082,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
32945
33082
|
const missingSet = new Set(kit.components.commands.missing);
|
|
32946
33083
|
for (const name of kit.components.commands.declared) {
|
|
32947
33084
|
if (missingSet.has(name)) continue;
|
|
32948
|
-
const filePath =
|
|
32949
|
-
if (!
|
|
33085
|
+
const filePath = path45.join(kit.path, "commands", `${name}.md`);
|
|
33086
|
+
if (!fs44.existsSync(filePath)) continue;
|
|
32950
33087
|
let data;
|
|
32951
33088
|
try {
|
|
32952
33089
|
({ data } = parseMarkdownFrontmatter(filePath));
|
|
@@ -32959,7 +33096,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
32959
33096
|
if (!barred) {
|
|
32960
33097
|
violations.push({
|
|
32961
33098
|
code: "command-human-only-model-invocable",
|
|
32962
|
-
location:
|
|
33099
|
+
location: path45.relative(kit.path, filePath),
|
|
32963
33100
|
message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
|
|
32964
33101
|
});
|
|
32965
33102
|
}
|
|
@@ -32968,8 +33105,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
32968
33105
|
}
|
|
32969
33106
|
|
|
32970
33107
|
// src/commands/verify.ts
|
|
32971
|
-
import
|
|
32972
|
-
import
|
|
33108
|
+
import fs45 from "fs";
|
|
33109
|
+
import path46 from "path";
|
|
32973
33110
|
function runVerifyCommand(options, logger) {
|
|
32974
33111
|
const { config, configDir, sourceRoot, kitInfo } = resolveRuntime(
|
|
32975
33112
|
options,
|
|
@@ -33060,8 +33197,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
|
|
|
33060
33197
|
if (!slotPath) {
|
|
33061
33198
|
continue;
|
|
33062
33199
|
}
|
|
33063
|
-
const fullPath = subPath ?
|
|
33064
|
-
if (!
|
|
33200
|
+
const fullPath = subPath ? path46.join(slotPath, subPath) : slotPath;
|
|
33201
|
+
if (!fs45.existsSync(fullPath)) {
|
|
33065
33202
|
failures.push(
|
|
33066
33203
|
`claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
|
|
33067
33204
|
);
|