@alessandroraffa/tangyr 0.13.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +710 -577
- 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 path45 = __require("path");
|
|
1376
|
+
var fs44 = __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 (fs44.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 = path45.resolve(baseDir, baseName);
|
|
2389
|
+
if (fs44.existsSync(localBin)) return localBin;
|
|
2390
|
+
if (sourceExt.includes(path45.extname(baseName))) return void 0;
|
|
2391
2391
|
const foundExt = sourceExt.find(
|
|
2392
|
-
(ext) =>
|
|
2392
|
+
(ext) => fs44.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 = fs44.realpathSync(this._scriptPath);
|
|
2405
2405
|
} catch {
|
|
2406
2406
|
resolvedScriptPath = this._scriptPath;
|
|
2407
2407
|
}
|
|
2408
|
-
executableDir =
|
|
2409
|
-
|
|
2408
|
+
executableDir = path45.resolve(
|
|
2409
|
+
path45.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 = path45.basename(
|
|
2417
2417
|
this._scriptPath,
|
|
2418
|
-
|
|
2418
|
+
path45.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(path45.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 = path45.basename(filename, path45.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(path46) {
|
|
3359
|
+
if (path46 === void 0) return this._executableDir;
|
|
3360
|
+
this._executableDir = path46;
|
|
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, path45) {
|
|
3717
|
+
const ctrl = callVisitor(key, node, visitor, path45);
|
|
3718
3718
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3719
|
-
replaceNode(key,
|
|
3720
|
-
return visit_(key, ctrl, visitor,
|
|
3719
|
+
replaceNode(key, path45, ctrl);
|
|
3720
|
+
return visit_(key, ctrl, visitor, path45);
|
|
3721
3721
|
}
|
|
3722
3722
|
if (typeof ctrl !== "symbol") {
|
|
3723
3723
|
if (identity.isCollection(node)) {
|
|
3724
|
-
|
|
3724
|
+
path45 = Object.freeze(path45.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, path45);
|
|
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
|
+
path45 = Object.freeze(path45.concat(node));
|
|
3738
|
+
const ck = visit_("key", node.key, visitor, path45);
|
|
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, path45);
|
|
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, path45) {
|
|
3765
|
+
const ctrl = await callVisitor(key, node, visitor, path45);
|
|
3766
3766
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
3767
|
-
replaceNode(key,
|
|
3768
|
-
return visitAsync_(key, ctrl, visitor,
|
|
3767
|
+
replaceNode(key, path45, ctrl);
|
|
3768
|
+
return visitAsync_(key, ctrl, visitor, path45);
|
|
3769
3769
|
}
|
|
3770
3770
|
if (typeof ctrl !== "symbol") {
|
|
3771
3771
|
if (identity.isCollection(node)) {
|
|
3772
|
-
|
|
3772
|
+
path45 = Object.freeze(path45.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, path45);
|
|
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
|
+
path45 = Object.freeze(path45.concat(node));
|
|
3786
|
+
const ck = await visitAsync_("key", node.key, visitor, path45);
|
|
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, path45);
|
|
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, path45) {
|
|
3819
3819
|
if (typeof visitor === "function")
|
|
3820
|
-
return visitor(key, node,
|
|
3820
|
+
return visitor(key, node, path45);
|
|
3821
3821
|
if (identity.isMap(node))
|
|
3822
|
-
return visitor.Map?.(key, node,
|
|
3822
|
+
return visitor.Map?.(key, node, path45);
|
|
3823
3823
|
if (identity.isSeq(node))
|
|
3824
|
-
return visitor.Seq?.(key, node,
|
|
3824
|
+
return visitor.Seq?.(key, node, path45);
|
|
3825
3825
|
if (identity.isPair(node))
|
|
3826
|
-
return visitor.Pair?.(key, node,
|
|
3826
|
+
return visitor.Pair?.(key, node, path45);
|
|
3827
3827
|
if (identity.isScalar(node))
|
|
3828
|
-
return visitor.Scalar?.(key, node,
|
|
3828
|
+
return visitor.Scalar?.(key, node, path45);
|
|
3829
3829
|
if (identity.isAlias(node))
|
|
3830
|
-
return visitor.Alias?.(key, node,
|
|
3830
|
+
return visitor.Alias?.(key, node, path45);
|
|
3831
3831
|
return void 0;
|
|
3832
3832
|
}
|
|
3833
|
-
function replaceNode(key,
|
|
3834
|
-
const parent =
|
|
3833
|
+
function replaceNode(key, path45, node) {
|
|
3834
|
+
const parent = path45[path45.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, path45, value) {
|
|
4443
4443
|
let v2 = value;
|
|
4444
|
-
for (let i =
|
|
4445
|
-
const k2 =
|
|
4444
|
+
for (let i = path45.length - 1; i >= 0; --i) {
|
|
4445
|
+
const k2 = path45[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 = (path45) => path45 == null || typeof path45 === "object" && !!path45[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(path45, value) {
|
|
4495
|
+
if (isEmptyPath(path45))
|
|
4496
4496
|
this.add(value);
|
|
4497
4497
|
else {
|
|
4498
|
-
const [key, ...rest] =
|
|
4498
|
+
const [key, ...rest] = path45;
|
|
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(path45) {
|
|
4513
|
+
const [key, ...rest] = path45;
|
|
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(path45, keepScalar) {
|
|
4528
|
+
const [key, ...rest] = path45;
|
|
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(path45) {
|
|
4547
|
+
const [key, ...rest] = path45;
|
|
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(path45, value) {
|
|
4558
|
+
const [key, ...rest] = path45;
|
|
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(path45, value) {
|
|
7071
7071
|
if (assertCollection(this.contents))
|
|
7072
|
-
this.contents.addIn(
|
|
7072
|
+
this.contents.addIn(path45, 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(path45) {
|
|
7148
|
+
if (Collection.isEmptyPath(path45)) {
|
|
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(path45) : 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(path45, keepScalar) {
|
|
7170
|
+
if (Collection.isEmptyPath(path45))
|
|
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(path45, 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(path45) {
|
|
7184
|
+
if (Collection.isEmptyPath(path45))
|
|
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(path45) : 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(path45, value) {
|
|
7204
|
+
if (Collection.isEmptyPath(path45)) {
|
|
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(path45), value);
|
|
7208
7208
|
} else if (assertCollection(this.contents)) {
|
|
7209
|
-
this.contents.setIn(
|
|
7209
|
+
this.contents.setIn(path45, 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, path45) => {
|
|
9167
9167
|
let item = cst;
|
|
9168
|
-
for (const [field, index] of
|
|
9168
|
+
for (const [field, index] of path45) {
|
|
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, path45) => {
|
|
9178
|
+
const parent = visit.itemAtPath(cst, path45.slice(0, -1));
|
|
9179
|
+
const field = path45[path45.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(path45, item, visitor) {
|
|
9186
|
+
let ctrl = visitor(item, path45);
|
|
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(path45.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, path45);
|
|
9205
9205
|
}
|
|
9206
9206
|
}
|
|
9207
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
9207
|
+
return typeof ctrl === "function" ? ctrl(item, path45) : 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 fs44 = this.flowScalar(this.type);
|
|
10493
10493
|
if (atNextItem || it2.value) {
|
|
10494
|
-
map.items.push({ start, key:
|
|
10494
|
+
map.items.push({ start, key: fs44, sep: [] });
|
|
10495
10495
|
this.onKeyLine = true;
|
|
10496
10496
|
} else if (it2.sep) {
|
|
10497
|
-
this.stack.push(
|
|
10497
|
+
this.stack.push(fs44);
|
|
10498
10498
|
} else {
|
|
10499
|
-
Object.assign(it2, { key:
|
|
10499
|
+
Object.assign(it2, { key: fs44, 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 fs44 = this.flowScalar(this.type);
|
|
10628
10628
|
if (!it2 || it2.value)
|
|
10629
|
-
fc.items.push({ start: [], key:
|
|
10629
|
+
fc.items.push({ start: [], key: fs44, sep: [] });
|
|
10630
10630
|
else if (it2.sep)
|
|
10631
|
-
this.stack.push(
|
|
10631
|
+
this.stack.push(fs44);
|
|
10632
10632
|
else
|
|
10633
|
-
Object.assign(it2, { key:
|
|
10633
|
+
Object.assign(it2, { key: fs44, sep: [] });
|
|
10634
10634
|
return;
|
|
10635
10635
|
}
|
|
10636
10636
|
case "flow-map-end":
|
|
@@ -23113,15 +23113,20 @@ function toConflictPolicy2(value) {
|
|
|
23113
23113
|
}
|
|
23114
23114
|
|
|
23115
23115
|
// src/commands/install.ts
|
|
23116
|
-
import
|
|
23117
|
-
import
|
|
23116
|
+
import fs36 from "fs";
|
|
23117
|
+
import path36 from "path";
|
|
23118
23118
|
|
|
23119
23119
|
// src/core/materialize.ts
|
|
23120
|
-
import
|
|
23121
|
-
import
|
|
23120
|
+
import fs29 from "fs";
|
|
23121
|
+
import path27 from "path";
|
|
23122
23122
|
|
|
23123
23123
|
// src/core/integrity.ts
|
|
23124
23124
|
import crypto3 from "crypto";
|
|
23125
|
+
|
|
23126
|
+
// src/core/bundle.ts
|
|
23127
|
+
var DENY_LIST_TYPE = "tangyr.deny-list.v2";
|
|
23128
|
+
|
|
23129
|
+
// src/core/integrity.ts
|
|
23125
23130
|
function canonicalize(value) {
|
|
23126
23131
|
if (Array.isArray(value)) {
|
|
23127
23132
|
return value.map(canonicalize);
|
|
@@ -23237,21 +23242,139 @@ function verifyBundle(bundle, keys, expectedIdentity, now) {
|
|
|
23237
23242
|
verifyIdentity(bundle.manifest, expectedIdentity);
|
|
23238
23243
|
}
|
|
23239
23244
|
function verifyDenyList(denyList, keys, now) {
|
|
23240
|
-
|
|
23241
|
-
(
|
|
23242
|
-
|
|
23243
|
-
|
|
23245
|
+
if (denyList === null || typeof denyList !== "object") {
|
|
23246
|
+
throw new IntegrityError(DENY_LIST_MALFORMED);
|
|
23247
|
+
}
|
|
23248
|
+
const actualKeys = Object.keys(denyList).sort();
|
|
23249
|
+
const expectedKeys = [
|
|
23250
|
+
"entries",
|
|
23251
|
+
"expiresAt",
|
|
23252
|
+
"issuedAt",
|
|
23253
|
+
"keyId",
|
|
23254
|
+
"sequence",
|
|
23255
|
+
"signature",
|
|
23256
|
+
"type"
|
|
23257
|
+
];
|
|
23258
|
+
if (actualKeys.length !== expectedKeys.length || actualKeys.some((key, index) => key !== expectedKeys[index])) {
|
|
23244
23259
|
throw new IntegrityError(
|
|
23245
|
-
|
|
23260
|
+
`${DENY_LIST_MALFORMED} Expected exactly [${expectedKeys.join(", ")}], got [${actualKeys.join(", ")}].`
|
|
23246
23261
|
);
|
|
23247
23262
|
}
|
|
23248
23263
|
const list = denyList;
|
|
23249
|
-
const
|
|
23250
|
-
|
|
23251
|
-
|
|
23264
|
+
const shapeOk = list.type === DENY_LIST_TYPE && typeof list.keyId === "string" && typeof list.signature === "string" && list.signature.length > 0 && Number.isSafeInteger(list.sequence) && list.sequence >= 0 && typeof list.issuedAt === "string" && typeof list.expiresAt === "string" && Array.isArray(list.entries) && list.entries.every((entry) => typeof entry === "string");
|
|
23265
|
+
if (!shapeOk) {
|
|
23266
|
+
throw new IntegrityError(DENY_LIST_MALFORMED);
|
|
23267
|
+
}
|
|
23268
|
+
const { signature, ...signed } = list;
|
|
23269
|
+
verifySignedPayload(
|
|
23270
|
+
canonicalJsonBytes(signed),
|
|
23271
|
+
signature,
|
|
23272
|
+
list.keyId,
|
|
23273
|
+
keys,
|
|
23274
|
+
now
|
|
23275
|
+
);
|
|
23276
|
+
assertFreshnessWindow(list.issuedAt, list.expiresAt, now);
|
|
23277
|
+
return list;
|
|
23278
|
+
}
|
|
23279
|
+
var DENY_LIST_MALFORMED = "Revocation deny-list response is malformed, unsigned, or corrupted \u2014 treated as an integrity failure, never as an absent deny-list (REQ-INT-009).";
|
|
23280
|
+
function assertFreshnessWindow(issuedAt, expiresAt, now) {
|
|
23281
|
+
const utcDesignatorPattern = /Z|[+-]\d{2}:\d{2}$/;
|
|
23282
|
+
if (!utcDesignatorPattern.test(issuedAt) || !utcDesignatorPattern.test(expiresAt)) {
|
|
23283
|
+
throw new IntegrityError(
|
|
23284
|
+
`Signed document has a timezone-ambiguous validity window (issuedAt "${issuedAt}", expiresAt "${expiresAt}") \u2014 an explicit UTC designator ("Z") or numeric offset is required.`
|
|
23285
|
+
);
|
|
23286
|
+
}
|
|
23287
|
+
const issued = new Date(issuedAt);
|
|
23288
|
+
const expires = new Date(expiresAt);
|
|
23289
|
+
if (Number.isNaN(issued.getTime()) || Number.isNaN(expires.getTime())) {
|
|
23290
|
+
throw new IntegrityError(
|
|
23291
|
+
`Signed document has an unparseable validity window (issuedAt "${issuedAt}", expiresAt "${expiresAt}").`
|
|
23292
|
+
);
|
|
23293
|
+
}
|
|
23294
|
+
if (expires.getTime() < issued.getTime()) {
|
|
23295
|
+
throw new IntegrityError(
|
|
23296
|
+
`Signed document expires (${expiresAt}) before it was issued (${issuedAt}) \u2014 refusing.`
|
|
23297
|
+
);
|
|
23298
|
+
}
|
|
23299
|
+
if (now.getTime() > expires.getTime()) {
|
|
23300
|
+
throw new IntegrityError(
|
|
23301
|
+
`Signed document expired at ${expiresAt} (now ${now.toISOString()}). An expired revocation deny-list is not evidence that nothing is revoked \u2014 the publisher must re-sign and republish it.`
|
|
23302
|
+
);
|
|
23303
|
+
}
|
|
23304
|
+
if (now.getTime() < issued.getTime()) {
|
|
23305
|
+
throw new IntegrityError(
|
|
23306
|
+
`Signed document is not yet valid: issued at ${issuedAt}, now ${now.toISOString()}. Check the local clock.`
|
|
23307
|
+
);
|
|
23308
|
+
}
|
|
23309
|
+
}
|
|
23310
|
+
|
|
23311
|
+
// src/core/revocation-state.ts
|
|
23312
|
+
import fs28 from "fs";
|
|
23313
|
+
import path26 from "path";
|
|
23314
|
+
var REVOCATION_STATE_FILENAME = ".tangyr-revocation.json";
|
|
23315
|
+
function stateFilePath(cacheRoot) {
|
|
23316
|
+
return path26.join(cacheRoot, REVOCATION_STATE_FILENAME);
|
|
23317
|
+
}
|
|
23318
|
+
function readState(cacheRoot) {
|
|
23319
|
+
const filePath = stateFilePath(cacheRoot);
|
|
23320
|
+
let raw;
|
|
23321
|
+
try {
|
|
23322
|
+
raw = fs28.readFileSync(filePath, "utf8");
|
|
23323
|
+
} catch (err) {
|
|
23324
|
+
if (err.code === "ENOENT") {
|
|
23325
|
+
return { state: {} };
|
|
23326
|
+
}
|
|
23327
|
+
return {
|
|
23328
|
+
state: {},
|
|
23329
|
+
warning: `Could not read ${filePath} (${err.message}); the deny-list replay guard starts from nothing for this run.`
|
|
23330
|
+
};
|
|
23331
|
+
}
|
|
23332
|
+
let parsed;
|
|
23333
|
+
try {
|
|
23334
|
+
parsed = JSON.parse(raw);
|
|
23335
|
+
} catch {
|
|
23336
|
+
return {
|
|
23337
|
+
state: {},
|
|
23338
|
+
warning: `${filePath} is not valid JSON; the deny-list replay guard starts from nothing for this run.`
|
|
23339
|
+
};
|
|
23340
|
+
}
|
|
23341
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
23342
|
+
return {
|
|
23343
|
+
state: {},
|
|
23344
|
+
warning: `${filePath} does not contain an object; the deny-list replay guard starts from nothing for this run.`
|
|
23345
|
+
};
|
|
23346
|
+
}
|
|
23347
|
+
return { state: parsed };
|
|
23348
|
+
}
|
|
23349
|
+
function readRevocationSequence(cacheRoot, originUrl) {
|
|
23350
|
+
const { state, warning } = readState(cacheRoot);
|
|
23351
|
+
const record = state[originUrl];
|
|
23352
|
+
const sequence = record !== void 0 && Number.isSafeInteger(record.sequence) ? record.sequence : void 0;
|
|
23353
|
+
return warning === void 0 ? { sequence } : { sequence, warning };
|
|
23354
|
+
}
|
|
23355
|
+
function writeRevocationSequence(cacheRoot, originUrl, sequence, now) {
|
|
23356
|
+
const { state } = readState(cacheRoot);
|
|
23357
|
+
const existing = state[originUrl]?.sequence;
|
|
23358
|
+
if (existing !== void 0 && existing >= sequence) {
|
|
23359
|
+
return;
|
|
23360
|
+
}
|
|
23361
|
+
state[originUrl] = { sequence, seenAt: now.toISOString() };
|
|
23362
|
+
const filePath = stateFilePath(cacheRoot);
|
|
23363
|
+
fs28.mkdirSync(path26.dirname(filePath), { recursive: true, mode: 448 });
|
|
23364
|
+
const tempPath = `${filePath}.${process.pid}.tmp`;
|
|
23365
|
+
fs28.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
|
|
23366
|
+
`, {
|
|
23367
|
+
mode: 384
|
|
23252
23368
|
});
|
|
23253
|
-
|
|
23254
|
-
|
|
23369
|
+
fs28.renameSync(tempPath, filePath);
|
|
23370
|
+
}
|
|
23371
|
+
function assertSequenceNotReplayed(params) {
|
|
23372
|
+
const { originUrl, seen, incoming } = params;
|
|
23373
|
+
if (seen !== void 0 && incoming < seen) {
|
|
23374
|
+
throw new IntegrityError(
|
|
23375
|
+
`Revocation deny-list from ${originUrl} carries sequence ${incoming}, behind the highest already accepted (${seen}). That is a replay of a superseded deny-list, which would silently un-revoke a kit \u2014 refusing (REQ-INT-009).`
|
|
23376
|
+
);
|
|
23377
|
+
}
|
|
23255
23378
|
}
|
|
23256
23379
|
|
|
23257
23380
|
// src/core/materialize.ts
|
|
@@ -23365,7 +23488,7 @@ async function assertReferenceNotRevoked(params) {
|
|
|
23365
23488
|
sleep: sleep2
|
|
23366
23489
|
} = params;
|
|
23367
23490
|
const credentials = resolveCredentialNonInteractive();
|
|
23368
|
-
const
|
|
23491
|
+
const denyList = await withBoundedRetry(
|
|
23369
23492
|
async () => {
|
|
23370
23493
|
const controller = new AbortController();
|
|
23371
23494
|
const response = await transport.fetchObjectStream(
|
|
@@ -23402,11 +23525,21 @@ async function assertReferenceNotRevoked(params) {
|
|
|
23402
23525
|
sleep2,
|
|
23403
23526
|
logger
|
|
23404
23527
|
);
|
|
23528
|
+
const seen = readRevocationSequence(cacheRoot, originUrl);
|
|
23529
|
+
if (seen.warning) {
|
|
23530
|
+
logger.warn(seen.warning);
|
|
23531
|
+
}
|
|
23532
|
+
assertSequenceNotReplayed({
|
|
23533
|
+
originUrl,
|
|
23534
|
+
seen: seen.sequence,
|
|
23535
|
+
incoming: denyList.sequence
|
|
23536
|
+
});
|
|
23537
|
+
writeRevocationSequence(cacheRoot, originUrl, denyList.sequence, now);
|
|
23405
23538
|
const key = `${reference.name}@${reference.version}`;
|
|
23406
|
-
if (
|
|
23539
|
+
if (denyList.entries.includes(key)) {
|
|
23407
23540
|
const entryDir = cacheEntryPath(cacheRoot, reference);
|
|
23408
|
-
if (
|
|
23409
|
-
|
|
23541
|
+
if (fs29.existsSync(entryDir)) {
|
|
23542
|
+
fs29.rmSync(entryDir, { recursive: true, force: true });
|
|
23410
23543
|
}
|
|
23411
23544
|
throw new IntegrityError(
|
|
23412
23545
|
`"${key}" is present on the signed revocation deny-list \u2014 refusing to materialize or install; any existing cache entry has been invalidated (REQ-INT-009).`
|
|
@@ -23453,7 +23586,7 @@ function assertFileWithinCeiling(entryPath, byteLength) {
|
|
|
23453
23586
|
}
|
|
23454
23587
|
var WINDOWS_DRIVE_ABSOLUTE = /^[a-zA-Z]:[\\/]/u;
|
|
23455
23588
|
function sanitizeBundleFilePath(entryPath, stagingDir) {
|
|
23456
|
-
if (
|
|
23589
|
+
if (path27.isAbsolute(entryPath) || WINDOWS_DRIVE_ABSOLUTE.test(entryPath)) {
|
|
23457
23590
|
throw new IntegrityError(
|
|
23458
23591
|
`Bundle file path "${entryPath}" is absolute \u2014 every file inside a bundle must use a relative path (REQ-INT-004).`
|
|
23459
23592
|
);
|
|
@@ -23469,13 +23602,13 @@ function sanitizeBundleFilePath(entryPath, stagingDir) {
|
|
|
23469
23602
|
`Bundle file path "${entryPath}" contains a ".." segment \u2014 directory traversal is rejected (REQ-INT-004).`
|
|
23470
23603
|
);
|
|
23471
23604
|
}
|
|
23472
|
-
const resolved =
|
|
23605
|
+
const resolved = path27.resolve(stagingDir, entryPath);
|
|
23473
23606
|
if (resolved === stagingDir) {
|
|
23474
23607
|
throw new IntegrityError(
|
|
23475
23608
|
`Bundle file path "${entryPath}" resolves to the staging directory itself \u2014 every entry must be a file inside it (REQ-INT-004).`
|
|
23476
23609
|
);
|
|
23477
23610
|
}
|
|
23478
|
-
if (!resolved.startsWith(stagingDir +
|
|
23611
|
+
if (!resolved.startsWith(stagingDir + path27.sep)) {
|
|
23479
23612
|
throw new IntegrityError(
|
|
23480
23613
|
`Bundle file path "${entryPath}" escapes the staging directory \u2014 refusing to write (REQ-INT-004).`
|
|
23481
23614
|
);
|
|
@@ -23527,10 +23660,10 @@ function verifyBundleFileHashes(bundle) {
|
|
|
23527
23660
|
function writeStagedFiles(stagingDir, decoded) {
|
|
23528
23661
|
for (const [rawPath, bytes] of decoded) {
|
|
23529
23662
|
const target = sanitizeBundleFilePath(rawPath, stagingDir);
|
|
23530
|
-
|
|
23663
|
+
fs29.mkdirSync(path27.dirname(target), { recursive: true, mode: 448 });
|
|
23531
23664
|
let existingStat;
|
|
23532
23665
|
try {
|
|
23533
|
-
existingStat =
|
|
23666
|
+
existingStat = fs29.lstatSync(target);
|
|
23534
23667
|
} catch (error) {
|
|
23535
23668
|
if (error.code !== "ENOENT") {
|
|
23536
23669
|
throw error;
|
|
@@ -23541,7 +23674,7 @@ function writeStagedFiles(stagingDir, decoded) {
|
|
|
23541
23674
|
`Refusing to write "${rawPath}" \u2014 a symbolic link already exists at the target path.`
|
|
23542
23675
|
);
|
|
23543
23676
|
}
|
|
23544
|
-
|
|
23677
|
+
fs29.writeFileSync(target, bytes, { mode: 384, flag: "wx" });
|
|
23545
23678
|
}
|
|
23546
23679
|
}
|
|
23547
23680
|
function verifyWarmCacheEntry(entryDir, reference, keys, now) {
|
|
@@ -23607,14 +23740,14 @@ async function materializeRemoteKit(params) {
|
|
|
23607
23740
|
writeStagedFiles(stagingDir, decoded);
|
|
23608
23741
|
writeBundleDocument(stagingDir, bundle);
|
|
23609
23742
|
writeCompletionMarker(stagingDir, reference);
|
|
23610
|
-
if (replace &&
|
|
23611
|
-
|
|
23743
|
+
if (replace && fs29.existsSync(entryDir)) {
|
|
23744
|
+
fs29.rmSync(entryDir, { recursive: true, force: true });
|
|
23612
23745
|
}
|
|
23613
23746
|
publishCacheEntry(stagingDir, entryDir);
|
|
23614
23747
|
return entryDir;
|
|
23615
23748
|
} catch (error) {
|
|
23616
23749
|
if (stagingDir !== void 0) {
|
|
23617
|
-
|
|
23750
|
+
fs29.rmSync(stagingDir, { recursive: true, force: true });
|
|
23618
23751
|
}
|
|
23619
23752
|
throw error;
|
|
23620
23753
|
}
|
|
@@ -23822,13 +23955,13 @@ function sleep(ms2) {
|
|
|
23822
23955
|
// src/adapters/codex.ts
|
|
23823
23956
|
var TOML3 = __toESM(require_toml(), 1);
|
|
23824
23957
|
import crypto5 from "crypto";
|
|
23825
|
-
import
|
|
23826
|
-
import
|
|
23958
|
+
import fs31 from "fs";
|
|
23959
|
+
import path30 from "path";
|
|
23827
23960
|
|
|
23828
23961
|
// src/compiler/agents.ts
|
|
23829
23962
|
var TOML = __toESM(require_toml(), 1);
|
|
23830
23963
|
var import_yaml7 = __toESM(require_dist(), 1);
|
|
23831
|
-
import
|
|
23964
|
+
import path28 from "path";
|
|
23832
23965
|
|
|
23833
23966
|
// src/compiler/loss-report.ts
|
|
23834
23967
|
function createLossReport() {
|
|
@@ -23892,7 +24025,7 @@ var copilotToolAliasesByClass = {
|
|
|
23892
24025
|
};
|
|
23893
24026
|
function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
23894
24027
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
23895
|
-
const relativeSource = `agents/${
|
|
24028
|
+
const relativeSource = `agents/${path28.basename(sourceFile)}`;
|
|
23896
24029
|
if (target === "opencode") {
|
|
23897
24030
|
return compileOpenCodeAgent(
|
|
23898
24031
|
sourceFile,
|
|
@@ -23933,7 +24066,7 @@ function compileAgent(sourceFile, target, mappings, extensions, lossReport) {
|
|
|
23933
24066
|
mappings,
|
|
23934
24067
|
lossReport
|
|
23935
24068
|
);
|
|
23936
|
-
const overlayKey = `agents/${
|
|
24069
|
+
const overlayKey = `agents/${path28.basename(sourceFile, ".md")}.${target}.yaml`;
|
|
23937
24070
|
const targetFields = {
|
|
23938
24071
|
...translated.fields,
|
|
23939
24072
|
...extensions[overlayKey] ?? {}
|
|
@@ -23967,7 +24100,7 @@ ${TOML.stringify({
|
|
|
23967
24100
|
function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
23968
24101
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
23969
24102
|
throw new Error(
|
|
23970
|
-
`${
|
|
24103
|
+
`${path28.basename(sourceFile)}: OpenCode agent requires a non-empty description field`
|
|
23971
24104
|
);
|
|
23972
24105
|
}
|
|
23973
24106
|
const frontmatter = {
|
|
@@ -24021,7 +24154,7 @@ function compileOpenCodeAgent(sourceFile, data, body, relativeSource, lossReport
|
|
|
24021
24154
|
"permission",
|
|
24022
24155
|
"permission-coarsening"
|
|
24023
24156
|
),
|
|
24024
|
-
detail: `${
|
|
24157
|
+
detail: `${path28.basename(sourceFile)}: per-tool permission '${tool}' mapped to coarse allow|deny action`
|
|
24025
24158
|
}
|
|
24026
24159
|
]
|
|
24027
24160
|
});
|
|
@@ -24046,7 +24179,7 @@ ${(0, import_yaml7.stringify)(frontmatter).trim()}
|
|
|
24046
24179
|
function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport) {
|
|
24047
24180
|
if (typeof data.description !== "string" || data.description.trim() === "") {
|
|
24048
24181
|
throw new Error(
|
|
24049
|
-
`${
|
|
24182
|
+
`${path28.basename(sourceFile)}: Cursor agent requires a non-empty description field`
|
|
24050
24183
|
);
|
|
24051
24184
|
}
|
|
24052
24185
|
const frontmatter = {
|
|
@@ -24083,7 +24216,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
24083
24216
|
"permission",
|
|
24084
24217
|
"permission-coarsening"
|
|
24085
24218
|
),
|
|
24086
|
-
detail: `${
|
|
24219
|
+
detail: `${path28.basename(sourceFile)}: per-agent tool allow set coarsened to readonly=${readonly} boolean (Cursor only exposes readonly control)`
|
|
24087
24220
|
}
|
|
24088
24221
|
]
|
|
24089
24222
|
});
|
|
@@ -24102,7 +24235,7 @@ function compileCursorAgent(sourceFile, data, body, relativeSource, lossReport)
|
|
|
24102
24235
|
"provider",
|
|
24103
24236
|
"provider-not-representable"
|
|
24104
24237
|
),
|
|
24105
|
-
detail: `${
|
|
24238
|
+
detail: `${path28.basename(sourceFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
24106
24239
|
}
|
|
24107
24240
|
]
|
|
24108
24241
|
});
|
|
@@ -24134,7 +24267,7 @@ function compileClineAgent(sourceFile, _data, _body, relativeSource, lossReport)
|
|
|
24134
24267
|
"persona",
|
|
24135
24268
|
"persona-not-representable"
|
|
24136
24269
|
),
|
|
24137
|
-
detail: `${
|
|
24270
|
+
detail: `${path28.basename(sourceFile)}: Cline has no committable per-agent persona file for the VSCode extension target; configure the agent through Cline Settings \u2192 Agent.`
|
|
24138
24271
|
}
|
|
24139
24272
|
]
|
|
24140
24273
|
});
|
|
@@ -24182,7 +24315,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
24182
24315
|
field,
|
|
24183
24316
|
"model-not-representable"
|
|
24184
24317
|
),
|
|
24185
|
-
detail: `${
|
|
24318
|
+
detail: `${path28.basename(sourceFile)}: model tier '${String(value)}' has no stable Copilot model literal; omitted so VS Code uses the selected model.`
|
|
24186
24319
|
});
|
|
24187
24320
|
return;
|
|
24188
24321
|
}
|
|
@@ -24200,9 +24333,9 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
24200
24333
|
lossReport,
|
|
24201
24334
|
target,
|
|
24202
24335
|
"agents",
|
|
24203
|
-
`agents/${
|
|
24336
|
+
`agents/${path28.basename(sourceFile)}`,
|
|
24204
24337
|
"info",
|
|
24205
|
-
`${
|
|
24338
|
+
`${path28.basename(sourceFile)}: ${field} is delivered through another managed surface.`
|
|
24206
24339
|
);
|
|
24207
24340
|
return;
|
|
24208
24341
|
}
|
|
@@ -24211,7 +24344,7 @@ function applyFieldAction(sourceFile, field, value, action, target, mappings, tr
|
|
|
24211
24344
|
field,
|
|
24212
24345
|
action: entryType,
|
|
24213
24346
|
severity: resolveLossSeverity("agent-field", field, entryType),
|
|
24214
|
-
detail: `${
|
|
24347
|
+
detail: `${path28.basename(sourceFile)}: ${field} has no emitted field for this target.`
|
|
24215
24348
|
});
|
|
24216
24349
|
}
|
|
24217
24350
|
function mapToolsToCapabilities(value, mappings) {
|
|
@@ -24808,9 +24941,9 @@ function compileOpenCodeMcp(sourceMcpJson, lossReport, sourceLabel) {
|
|
|
24808
24941
|
}
|
|
24809
24942
|
|
|
24810
24943
|
// src/compiler/rules.ts
|
|
24811
|
-
import
|
|
24944
|
+
import path29 from "path";
|
|
24812
24945
|
var import_yaml8 = __toESM(require_dist(), 1);
|
|
24813
|
-
import
|
|
24946
|
+
import fs30 from "fs";
|
|
24814
24947
|
function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
24815
24948
|
if (target === "copilot") {
|
|
24816
24949
|
addLoss(lossReport, "copilot", "rules", {
|
|
@@ -24847,13 +24980,13 @@ function compileRules(sourceRulesDir, target, _mappings, lossReport) {
|
|
|
24847
24980
|
}
|
|
24848
24981
|
const appendixParts = [];
|
|
24849
24982
|
const dotRulesFiles = [];
|
|
24850
|
-
for (const ruleFile of ts(
|
|
24983
|
+
for (const ruleFile of ts(path29.join(sourceRulesDir, "*.md")).sort()) {
|
|
24851
24984
|
const parsed = parseRule(ruleFile);
|
|
24852
|
-
const name =
|
|
24985
|
+
const name = path29.basename(ruleFile, ".md");
|
|
24853
24986
|
if (parsed.mode === "exec-policy") {
|
|
24854
24987
|
dotRulesFiles.push({
|
|
24855
24988
|
name: `${name}.rules`,
|
|
24856
|
-
content: `${formatProvenanceMarker("toml", `rules/${
|
|
24989
|
+
content: `${formatProvenanceMarker("toml", `rules/${path29.basename(ruleFile)}`, computeSourceHash(ruleFile), "codex")}
|
|
24857
24990
|
${parsed.body}`
|
|
24858
24991
|
});
|
|
24859
24992
|
continue;
|
|
@@ -24862,7 +24995,7 @@ ${parsed.body}`
|
|
|
24862
24995
|
|
|
24863
24996
|
${parsed.body.trim()}`);
|
|
24864
24997
|
addLoss(lossReport, "codex", "rules", {
|
|
24865
|
-
source: `rules/${
|
|
24998
|
+
source: `rules/${path29.basename(ruleFile)}`,
|
|
24866
24999
|
fields: [
|
|
24867
25000
|
{
|
|
24868
25001
|
field: "mode",
|
|
@@ -24872,7 +25005,7 @@ ${parsed.body.trim()}`);
|
|
|
24872
25005
|
"mode",
|
|
24873
25006
|
"rule-as-instruction"
|
|
24874
25007
|
),
|
|
24875
|
-
detail: `${
|
|
25008
|
+
detail: `${path29.basename(ruleFile)} is appended to the managed Codex instructions file as guidance.`
|
|
24876
25009
|
}
|
|
24877
25010
|
]
|
|
24878
25011
|
});
|
|
@@ -24880,7 +25013,7 @@ ${parsed.body.trim()}`);
|
|
|
24880
25013
|
return { agentsAppendix: appendixParts.join("\n\n"), dotRulesFiles };
|
|
24881
25014
|
}
|
|
24882
25015
|
function parseRule(ruleFile) {
|
|
24883
|
-
const content =
|
|
25016
|
+
const content = fs30.readFileSync(ruleFile, "utf8");
|
|
24884
25017
|
if (!content.startsWith("---\n")) {
|
|
24885
25018
|
return { mode: "guidance", body: content };
|
|
24886
25019
|
}
|
|
@@ -24904,14 +25037,14 @@ function isRuleMode(value) {
|
|
|
24904
25037
|
}
|
|
24905
25038
|
function compileOpenCodeRules(sourceRulesDir, lossReport) {
|
|
24906
25039
|
const appendixParts = [];
|
|
24907
|
-
for (const ruleFile of ts(
|
|
25040
|
+
for (const ruleFile of ts(path29.join(sourceRulesDir, "*.md")).sort()) {
|
|
24908
25041
|
const parsed = parseRule(ruleFile);
|
|
24909
|
-
const name =
|
|
25042
|
+
const name = path29.basename(ruleFile, ".md");
|
|
24910
25043
|
appendixParts.push(`## ${name}
|
|
24911
25044
|
|
|
24912
25045
|
${parsed.body.trim()}`);
|
|
24913
25046
|
addLoss(lossReport, "opencode", "rules", {
|
|
24914
|
-
source: `rules/${
|
|
25047
|
+
source: `rules/${path29.basename(ruleFile)}`,
|
|
24915
25048
|
fields: [
|
|
24916
25049
|
{
|
|
24917
25050
|
field: "rule",
|
|
@@ -24921,7 +25054,7 @@ ${parsed.body.trim()}`);
|
|
|
24921
25054
|
"rule",
|
|
24922
25055
|
"rule-path-scoping"
|
|
24923
25056
|
),
|
|
24924
|
-
detail: `${
|
|
25057
|
+
detail: `${path29.basename(ruleFile)}: OpenCode has no per-agent rule scoping \u2014 rule appended to AGENTS.md instructions`
|
|
24925
25058
|
}
|
|
24926
25059
|
]
|
|
24927
25060
|
});
|
|
@@ -24930,9 +25063,9 @@ ${parsed.body.trim()}`);
|
|
|
24930
25063
|
}
|
|
24931
25064
|
function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
24932
25065
|
const dotRulesFiles = [];
|
|
24933
|
-
for (const ruleFile of ts(
|
|
24934
|
-
const content =
|
|
24935
|
-
const name =
|
|
25066
|
+
for (const ruleFile of ts(path29.join(sourceRulesDir, "*.md")).sort()) {
|
|
25067
|
+
const content = fs30.readFileSync(ruleFile, "utf8");
|
|
25068
|
+
const name = path29.basename(ruleFile, ".md");
|
|
24936
25069
|
let frontmatterData = {};
|
|
24937
25070
|
let body = content;
|
|
24938
25071
|
if (content.startsWith("---\n")) {
|
|
@@ -24961,7 +25094,7 @@ function compileCursorRules(sourceRulesDir, _lossReport) {
|
|
|
24961
25094
|
}
|
|
24962
25095
|
const marker = formatProvenanceMarker(
|
|
24963
25096
|
"markdown",
|
|
24964
|
-
`rules/${
|
|
25097
|
+
`rules/${path29.basename(ruleFile)}`,
|
|
24965
25098
|
computeSourceHash(ruleFile),
|
|
24966
25099
|
"cursor"
|
|
24967
25100
|
);
|
|
@@ -24977,9 +25110,9 @@ ${body}`;
|
|
|
24977
25110
|
}
|
|
24978
25111
|
function compileClineRules(sourceRulesDir, lossReport) {
|
|
24979
25112
|
const dotRulesFiles = [];
|
|
24980
|
-
for (const ruleFile of ts(
|
|
24981
|
-
const content =
|
|
24982
|
-
const name =
|
|
25113
|
+
for (const ruleFile of ts(path29.join(sourceRulesDir, "*.md")).sort()) {
|
|
25114
|
+
const content = fs30.readFileSync(ruleFile, "utf8");
|
|
25115
|
+
const name = path29.basename(ruleFile, ".md");
|
|
24983
25116
|
let frontmatterData = {};
|
|
24984
25117
|
let body = content;
|
|
24985
25118
|
if (content.startsWith("---\n")) {
|
|
@@ -24996,13 +25129,13 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
24996
25129
|
}
|
|
24997
25130
|
const marker = formatProvenanceMarker(
|
|
24998
25131
|
"markdown",
|
|
24999
|
-
`rules/${
|
|
25132
|
+
`rules/${path29.basename(ruleFile)}`,
|
|
25000
25133
|
computeSourceHash(ruleFile),
|
|
25001
25134
|
"cline"
|
|
25002
25135
|
);
|
|
25003
25136
|
if (frontmatterData.mode === "exec-policy") {
|
|
25004
25137
|
addLoss(lossReport, "cline", "rules", {
|
|
25005
|
-
source: `rules/${
|
|
25138
|
+
source: `rules/${path29.basename(ruleFile)}`,
|
|
25006
25139
|
fields: [
|
|
25007
25140
|
{
|
|
25008
25141
|
field: "mode",
|
|
@@ -25012,7 +25145,7 @@ function compileClineRules(sourceRulesDir, lossReport) {
|
|
|
25012
25145
|
"mode",
|
|
25013
25146
|
"rule-mode-downgrade"
|
|
25014
25147
|
),
|
|
25015
|
-
detail: `${
|
|
25148
|
+
detail: `${path29.basename(ruleFile)}: Cline rules have no exec-policy mode; rule emitted as guidance.`
|
|
25016
25149
|
}
|
|
25017
25150
|
]
|
|
25018
25151
|
});
|
|
@@ -25057,7 +25190,7 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
25057
25190
|
rules: profile.rules
|
|
25058
25191
|
};
|
|
25059
25192
|
const rules = compileRules(
|
|
25060
|
-
|
|
25193
|
+
path30.join(sourceRoot, config.source.rules),
|
|
25061
25194
|
"codex",
|
|
25062
25195
|
mappings,
|
|
25063
25196
|
lossReport
|
|
@@ -25202,9 +25335,9 @@ function syncCodex(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
25202
25335
|
function buildProviderTomlSection(config, sourceRoot, mappings, scope, lossReport) {
|
|
25203
25336
|
const cp = mappings.modelTiers.custom_provider;
|
|
25204
25337
|
if (!cp) return "";
|
|
25205
|
-
const agentsDir =
|
|
25206
|
-
if (!
|
|
25207
|
-
const agentFiles = ts(
|
|
25338
|
+
const agentsDir = path30.join(sourceRoot, config.source.agents);
|
|
25339
|
+
if (!fs31.existsSync(agentsDir)) return "";
|
|
25340
|
+
const agentFiles = ts(path30.join(agentsDir, "*.md")).sort();
|
|
25208
25341
|
const hasProviderAgent = agentFiles.some((agentFile) => {
|
|
25209
25342
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
25210
25343
|
return typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
@@ -25269,7 +25402,7 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
25269
25402
|
}
|
|
25270
25403
|
];
|
|
25271
25404
|
for (const ruleFile of rules.dotRulesFiles) {
|
|
25272
|
-
const destination =
|
|
25405
|
+
const destination = path30.join(rulesRoot, ruleFile.name);
|
|
25273
25406
|
if (options.dryRun) {
|
|
25274
25407
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
25275
25408
|
outcomes.push({
|
|
@@ -25297,15 +25430,15 @@ function syncRules(config, sourceRoot, paths, rules, options, logger, manifest,
|
|
|
25297
25430
|
return outcomes;
|
|
25298
25431
|
}
|
|
25299
25432
|
function syncInstructions(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
25300
|
-
const source =
|
|
25433
|
+
const source = path30.join(sourceRoot, config.source.instructions);
|
|
25301
25434
|
const destination = resolveTargetPath(paths.instructions);
|
|
25302
|
-
const composed = `${
|
|
25435
|
+
const composed = `${fs31.readFileSync(source, "utf8").trim()}
|
|
25303
25436
|
|
|
25304
25437
|
--- tangyr managed rules ---
|
|
25305
25438
|
${agentsAppendix}`.trim();
|
|
25306
25439
|
const marker = formatProvenanceMarker(
|
|
25307
25440
|
"markdown",
|
|
25308
|
-
|
|
25441
|
+
path30.basename(config.source.instructions),
|
|
25309
25442
|
hashString(composed),
|
|
25310
25443
|
"codex"
|
|
25311
25444
|
);
|
|
@@ -25332,9 +25465,9 @@ ${composed}
|
|
|
25332
25465
|
);
|
|
25333
25466
|
}
|
|
25334
25467
|
function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
25335
|
-
const source =
|
|
25468
|
+
const source = path30.resolve(sourceRoot, config.source.skills);
|
|
25336
25469
|
const destination = resolveTargetPath(paths.skills);
|
|
25337
|
-
if (!
|
|
25470
|
+
if (!fs31.existsSync(source)) {
|
|
25338
25471
|
return skippedMissingSource("skills", source);
|
|
25339
25472
|
}
|
|
25340
25473
|
if (options.dryRun) {
|
|
@@ -25350,29 +25483,29 @@ function syncSkills(config, sourceRoot, paths, options, logger, manifest, scopeP
|
|
|
25350
25483
|
};
|
|
25351
25484
|
}
|
|
25352
25485
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
25353
|
-
|
|
25486
|
+
fs31.unlinkSync(destination);
|
|
25354
25487
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
25355
25488
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
|
|
25356
25489
|
return { component: "skills", status: "conflict", path: destination };
|
|
25357
25490
|
} else if (artifactClass === "managed-symlink") {
|
|
25358
|
-
|
|
25491
|
+
fs31.unlinkSync(destination);
|
|
25359
25492
|
}
|
|
25360
|
-
ensureDir(
|
|
25493
|
+
ensureDir(path30.dirname(destination));
|
|
25361
25494
|
createRelativeSymlink(source, destination, "dir");
|
|
25362
25495
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
25363
25496
|
return { component: "skills", status: "success", path: destination };
|
|
25364
25497
|
}
|
|
25365
25498
|
function syncAgents(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
25366
|
-
const sourceAgentsRoot =
|
|
25367
|
-
if (!
|
|
25499
|
+
const sourceAgentsRoot = path30.join(sourceRoot, config.source.agents);
|
|
25500
|
+
if (!fs31.existsSync(sourceAgentsRoot)) {
|
|
25368
25501
|
return [skippedMissingSource("agents", sourceAgentsRoot)];
|
|
25369
25502
|
}
|
|
25370
|
-
const sourceAgents = ts(
|
|
25503
|
+
const sourceAgents = ts(path30.join(sourceAgentsRoot, "*.md")).sort();
|
|
25371
25504
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
25372
25505
|
return sourceAgents.map((agentFile) => {
|
|
25373
|
-
const destination =
|
|
25506
|
+
const destination = path30.join(
|
|
25374
25507
|
agentsRoot,
|
|
25375
|
-
`${
|
|
25508
|
+
`${path30.basename(agentFile, ".md")}.toml`
|
|
25376
25509
|
);
|
|
25377
25510
|
const compiled = compileAgent(
|
|
25378
25511
|
agentFile,
|
|
@@ -25408,10 +25541,10 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
|
|
|
25408
25541
|
}
|
|
25409
25542
|
const source = resolveHooksSourceFile(sourceRoot, config);
|
|
25410
25543
|
const sourceLabel = hooksSourceLabel(config);
|
|
25411
|
-
if (!
|
|
25544
|
+
if (!fs31.existsSync(source)) {
|
|
25412
25545
|
return skippedMissingSource("hooks", source);
|
|
25413
25546
|
}
|
|
25414
|
-
const sourceHooksJson = JSON.parse(
|
|
25547
|
+
const sourceHooksJson = JSON.parse(fs31.readFileSync(source, "utf8"));
|
|
25415
25548
|
const compiled = compileHooks(
|
|
25416
25549
|
sourceHooksJson,
|
|
25417
25550
|
"codex",
|
|
@@ -25433,7 +25566,7 @@ function syncHooks(config, sourceRoot, paths, mappings, options, lossReport, log
|
|
|
25433
25566
|
destination,
|
|
25434
25567
|
hostHooks,
|
|
25435
25568
|
stringifyJson2,
|
|
25436
|
-
!
|
|
25569
|
+
!fs31.existsSync(destination),
|
|
25437
25570
|
logger
|
|
25438
25571
|
);
|
|
25439
25572
|
return {
|
|
@@ -25446,7 +25579,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
|
|
|
25446
25579
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
25447
25580
|
const sourceLabel = mcpSourceLabel(config);
|
|
25448
25581
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
25449
|
-
if (!
|
|
25582
|
+
if (!fs31.existsSync(source)) {
|
|
25450
25583
|
if (providerToml && !options.dryRun) {
|
|
25451
25584
|
const changed2 = writeTomlManagedSection(
|
|
25452
25585
|
destination,
|
|
@@ -25461,7 +25594,7 @@ function syncMcp(config, sourceRoot, paths, options, lossReport, logger, provide
|
|
|
25461
25594
|
}
|
|
25462
25595
|
return skippedMissingSource("mcp", source);
|
|
25463
25596
|
}
|
|
25464
|
-
const sourceMcpJson = JSON.parse(
|
|
25597
|
+
const sourceMcpJson = JSON.parse(fs31.readFileSync(source, "utf8"));
|
|
25465
25598
|
const compiled = compileMcp(sourceMcpJson, "codex", lossReport, sourceLabel);
|
|
25466
25599
|
const managedContent = providerToml ? `${compiled.trimEnd()}${providerToml}` : compiled;
|
|
25467
25600
|
if (options.dryRun) {
|
|
@@ -25483,12 +25616,12 @@ function writeCompiledArtifact(component, destination, content, expectedHash, co
|
|
|
25483
25616
|
if (artifactClass === "unmanaged-conflict" && !handleConflict(destination, config, options, logger, manifest, scopePath)) {
|
|
25484
25617
|
return { component, status: "conflict", path: destination };
|
|
25485
25618
|
}
|
|
25486
|
-
ensureDir(
|
|
25487
|
-
|
|
25619
|
+
ensureDir(path30.dirname(destination));
|
|
25620
|
+
fs31.writeFileSync(destination, content);
|
|
25488
25621
|
return { component, status: "success", path: destination };
|
|
25489
25622
|
}
|
|
25490
25623
|
function writeTomlManagedSection(destination, managedContent, logger) {
|
|
25491
|
-
const current =
|
|
25624
|
+
const current = fs31.existsSync(destination) ? fs31.readFileSync(destination, "utf8") : "";
|
|
25492
25625
|
const isFirstWrite = current.length > 0 && !current.includes(managedMcpStart);
|
|
25493
25626
|
if (isFirstWrite) {
|
|
25494
25627
|
logger.warn(
|
|
@@ -25504,8 +25637,8 @@ ${managedMcpEnd}
|
|
|
25504
25637
|
if (current === next.trimStart()) {
|
|
25505
25638
|
return false;
|
|
25506
25639
|
}
|
|
25507
|
-
ensureDir(
|
|
25508
|
-
|
|
25640
|
+
ensureDir(path30.dirname(destination));
|
|
25641
|
+
fs31.writeFileSync(destination, next.trimStart());
|
|
25509
25642
|
return true;
|
|
25510
25643
|
}
|
|
25511
25644
|
function removeManagedTomlSection(content) {
|
|
@@ -25532,16 +25665,16 @@ function handleConflict(destination, config, options, logger, manifest, scopePat
|
|
|
25532
25665
|
backupFile(destination, manifest);
|
|
25533
25666
|
writeManifest(scopePath, manifest);
|
|
25534
25667
|
} else {
|
|
25535
|
-
|
|
25668
|
+
fs31.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
25536
25669
|
}
|
|
25537
25670
|
return true;
|
|
25538
25671
|
}
|
|
25539
|
-
|
|
25672
|
+
fs31.rmSync(destination, { recursive: true, force: true });
|
|
25540
25673
|
return true;
|
|
25541
25674
|
}
|
|
25542
25675
|
function isCompiledCurrent(destination, expectedContent, expectedHash) {
|
|
25543
25676
|
try {
|
|
25544
|
-
const current =
|
|
25677
|
+
const current = fs31.readFileSync(destination, "utf8");
|
|
25545
25678
|
const marker = extractProvenanceMarker(current);
|
|
25546
25679
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "codex" && current === expectedContent : current === expectedContent;
|
|
25547
25680
|
} catch {
|
|
@@ -25560,16 +25693,16 @@ function shouldSkipComponent(options, component) {
|
|
|
25560
25693
|
}
|
|
25561
25694
|
function isSymlinkTo(linkPath, source) {
|
|
25562
25695
|
try {
|
|
25563
|
-
return
|
|
25696
|
+
return fs31.realpathSync(linkPath) === fs31.realpathSync(source);
|
|
25564
25697
|
} catch {
|
|
25565
25698
|
return false;
|
|
25566
25699
|
}
|
|
25567
25700
|
}
|
|
25568
25701
|
function readJsonObject3(filePath) {
|
|
25569
|
-
if (!
|
|
25702
|
+
if (!fs31.existsSync(filePath)) {
|
|
25570
25703
|
return {};
|
|
25571
25704
|
}
|
|
25572
|
-
const parsed = JSON.parse(
|
|
25705
|
+
const parsed = JSON.parse(fs31.readFileSync(filePath, "utf8"));
|
|
25573
25706
|
return isRecord4(parsed) ? parsed : {};
|
|
25574
25707
|
}
|
|
25575
25708
|
function stringifyJson2(value) {
|
|
@@ -25585,16 +25718,16 @@ function hashString(value) {
|
|
|
25585
25718
|
|
|
25586
25719
|
// src/adapters/copilot.ts
|
|
25587
25720
|
import crypto6 from "crypto";
|
|
25588
|
-
import
|
|
25589
|
-
import
|
|
25721
|
+
import fs32 from "fs";
|
|
25722
|
+
import path32 from "path";
|
|
25590
25723
|
|
|
25591
25724
|
// src/compiler/commands.ts
|
|
25592
25725
|
var import_yaml9 = __toESM(require_dist(), 1);
|
|
25593
|
-
import
|
|
25726
|
+
import path31 from "path";
|
|
25594
25727
|
function compileCommandPrompt(sourceFile) {
|
|
25595
25728
|
const { data, body } = parseMarkdownFrontmatter(sourceFile);
|
|
25596
|
-
const relativeSource = `commands/${
|
|
25597
|
-
const fields = promptFrontmatter(data,
|
|
25729
|
+
const relativeSource = `commands/${path31.basename(sourceFile)}`;
|
|
25730
|
+
const fields = promptFrontmatter(data, path31.basename(sourceFile, ".md"));
|
|
25598
25731
|
const marker = formatProvenanceMarker(
|
|
25599
25732
|
"markdown",
|
|
25600
25733
|
relativeSource,
|
|
@@ -25769,13 +25902,13 @@ function syncCopilot(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
25769
25902
|
}
|
|
25770
25903
|
function syncProviderLoss(config, sourceRoot, mappings, lossReport) {
|
|
25771
25904
|
if (!mappings.modelTiers.custom_provider) return;
|
|
25772
|
-
const agentsDir =
|
|
25773
|
-
if (!
|
|
25774
|
-
for (const agentFile of ts(
|
|
25905
|
+
const agentsDir = path32.join(sourceRoot, config.source.agents);
|
|
25906
|
+
if (!fs32.existsSync(agentsDir)) return;
|
|
25907
|
+
for (const agentFile of ts(path32.join(agentsDir, "*.md")).sort()) {
|
|
25775
25908
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
25776
25909
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
25777
25910
|
if (hasProvider) {
|
|
25778
|
-
const basename =
|
|
25911
|
+
const basename = path32.basename(agentFile);
|
|
25779
25912
|
addLoss(lossReport, "copilot", "agents", {
|
|
25780
25913
|
source: `agents/${basename}`,
|
|
25781
25914
|
fields: [
|
|
@@ -25800,23 +25933,23 @@ function syncCopilotInstructions(config, sourceRoot, options, lossReport, logger
|
|
|
25800
25933
|
logger.verbose(message);
|
|
25801
25934
|
return [{ component: "instructions", status: "skipped", path: message }];
|
|
25802
25935
|
}
|
|
25803
|
-
const source =
|
|
25804
|
-
if (!
|
|
25936
|
+
const source = path32.resolve(sourceRoot, config.source.instructions);
|
|
25937
|
+
if (!fs32.existsSync(source)) {
|
|
25805
25938
|
return [skippedMissingSource2("instructions", source)];
|
|
25806
25939
|
}
|
|
25807
|
-
const rawContent =
|
|
25940
|
+
const rawContent = fs32.readFileSync(source, "utf8");
|
|
25808
25941
|
const contentHash = hashString2(rawContent);
|
|
25809
25942
|
const marker = formatProvenanceMarker(
|
|
25810
25943
|
"markdown",
|
|
25811
|
-
|
|
25944
|
+
path32.basename(config.source.instructions),
|
|
25812
25945
|
contentHash,
|
|
25813
25946
|
"copilot"
|
|
25814
25947
|
);
|
|
25815
25948
|
const composedContent = `${marker}
|
|
25816
25949
|
${rawContent}`;
|
|
25817
25950
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
25818
|
-
const agentsMdDest =
|
|
25819
|
-
const mirrorDest =
|
|
25951
|
+
const agentsMdDest = path32.resolve(projectRoot, "AGENTS.md");
|
|
25952
|
+
const mirrorDest = path32.resolve(
|
|
25820
25953
|
projectRoot,
|
|
25821
25954
|
".github",
|
|
25822
25955
|
"copilot-instructions.md"
|
|
@@ -25870,17 +26003,17 @@ function writeInstructionsFile(component, destination, content, contentHash, con
|
|
|
25870
26003
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
25871
26004
|
return { component, status: "conflict", path: destination };
|
|
25872
26005
|
}
|
|
25873
|
-
ensureDir(
|
|
25874
|
-
|
|
26006
|
+
ensureDir(path32.dirname(destination));
|
|
26007
|
+
fs32.writeFileSync(destination, content);
|
|
25875
26008
|
return { component, status: "success", path: destination };
|
|
25876
26009
|
}
|
|
25877
26010
|
function hashString2(value) {
|
|
25878
26011
|
return `sha256:${crypto6.createHash("sha256").update(value).digest("hex")}`;
|
|
25879
26012
|
}
|
|
25880
26013
|
function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
25881
|
-
const source =
|
|
26014
|
+
const source = path32.resolve(sourceRoot, config.source.skills);
|
|
25882
26015
|
const destination = resolveTargetPath(paths.skills);
|
|
25883
|
-
if (!
|
|
26016
|
+
if (!fs32.existsSync(source)) {
|
|
25884
26017
|
return skippedMissingSource2("skills", source);
|
|
25885
26018
|
}
|
|
25886
26019
|
if (options.dryRun) {
|
|
@@ -25896,27 +26029,27 @@ function syncSkills2(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
25896
26029
|
};
|
|
25897
26030
|
}
|
|
25898
26031
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
25899
|
-
|
|
26032
|
+
fs32.unlinkSync(destination);
|
|
25900
26033
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
25901
26034
|
return { component: "skills", status: "conflict", path: destination };
|
|
25902
26035
|
} else if (artifactClass === "managed-symlink") {
|
|
25903
|
-
|
|
26036
|
+
fs32.unlinkSync(destination);
|
|
25904
26037
|
}
|
|
25905
|
-
ensureDir(
|
|
26038
|
+
ensureDir(path32.dirname(destination));
|
|
25906
26039
|
createRelativeSymlink(source, destination, "dir");
|
|
25907
26040
|
return { component: "skills", status: "success", path: destination };
|
|
25908
26041
|
}
|
|
25909
26042
|
function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
25910
|
-
const sourceAgentsRoot =
|
|
25911
|
-
if (!
|
|
26043
|
+
const sourceAgentsRoot = path32.join(sourceRoot, config.source.agents);
|
|
26044
|
+
if (!fs32.existsSync(sourceAgentsRoot)) {
|
|
25912
26045
|
return [skippedMissingSource2("agents", sourceAgentsRoot)];
|
|
25913
26046
|
}
|
|
25914
|
-
const sourceAgents = ts(
|
|
26047
|
+
const sourceAgents = ts(path32.join(sourceAgentsRoot, "*.md")).sort();
|
|
25915
26048
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
25916
26049
|
return sourceAgents.map((agentFile) => {
|
|
25917
|
-
const destination =
|
|
26050
|
+
const destination = path32.join(
|
|
25918
26051
|
agentsRoot,
|
|
25919
|
-
`${
|
|
26052
|
+
`${path32.basename(agentFile, ".md")}.agent.md`
|
|
25920
26053
|
);
|
|
25921
26054
|
const compiled = compileAgent(
|
|
25922
26055
|
agentFile,
|
|
@@ -25944,16 +26077,16 @@ function syncAgents2(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
25944
26077
|
});
|
|
25945
26078
|
}
|
|
25946
26079
|
function syncCommands(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
25947
|
-
const sourceCommandsRoot =
|
|
25948
|
-
if (!
|
|
26080
|
+
const sourceCommandsRoot = path32.join(sourceRoot, config.source.commands);
|
|
26081
|
+
if (!fs32.existsSync(sourceCommandsRoot)) {
|
|
25949
26082
|
return [skippedMissingSource2("commands", sourceCommandsRoot)];
|
|
25950
26083
|
}
|
|
25951
|
-
const sourceCommands = ts(
|
|
26084
|
+
const sourceCommands = ts(path32.join(sourceCommandsRoot, "*.md")).sort();
|
|
25952
26085
|
const promptsRoot = resolveTargetPath(paths.prompts);
|
|
25953
26086
|
return sourceCommands.map((commandFile) => {
|
|
25954
|
-
const destination =
|
|
26087
|
+
const destination = path32.join(
|
|
25955
26088
|
promptsRoot,
|
|
25956
|
-
`${
|
|
26089
|
+
`${path32.basename(commandFile, ".md")}.prompt.md`
|
|
25957
26090
|
);
|
|
25958
26091
|
const compiled = compileCommandPrompt(commandFile);
|
|
25959
26092
|
if (options.dryRun) {
|
|
@@ -25979,14 +26112,14 @@ function syncCommands(config, sourceRoot, paths, options, logger, manifest, scop
|
|
|
25979
26112
|
function syncHooks2(config, sourceRoot, paths, mappings, options, lossReport, logger) {
|
|
25980
26113
|
const source = resolveHooksSourceFile(sourceRoot, config);
|
|
25981
26114
|
const sourceLabel = hooksSourceLabel(config);
|
|
25982
|
-
const destination =
|
|
26115
|
+
const destination = path32.join(
|
|
25983
26116
|
resolveTargetPath(paths.hooks),
|
|
25984
26117
|
"tangyr-managed.json"
|
|
25985
26118
|
);
|
|
25986
|
-
if (!
|
|
26119
|
+
if (!fs32.existsSync(source)) {
|
|
25987
26120
|
return skippedMissingSource2("hooks", source);
|
|
25988
26121
|
}
|
|
25989
|
-
const sourceHooksJson = JSON.parse(
|
|
26122
|
+
const sourceHooksJson = JSON.parse(fs32.readFileSync(source, "utf8"));
|
|
25990
26123
|
const compiled = compileHooks(
|
|
25991
26124
|
sourceHooksJson,
|
|
25992
26125
|
"copilot",
|
|
@@ -26023,10 +26156,10 @@ function syncMcp2(config, sourceRoot, paths, options, lossReport, logger) {
|
|
|
26023
26156
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
26024
26157
|
const sourceLabel = mcpSourceLabel(config);
|
|
26025
26158
|
const destination = resolveTargetPath(paths.mcp_shared_file);
|
|
26026
|
-
if (!
|
|
26159
|
+
if (!fs32.existsSync(source)) {
|
|
26027
26160
|
return skippedMissingSource2("mcp", source);
|
|
26028
26161
|
}
|
|
26029
|
-
const sourceMcpJson = JSON.parse(
|
|
26162
|
+
const sourceMcpJson = JSON.parse(fs32.readFileSync(source, "utf8"));
|
|
26030
26163
|
const compiled = compileMcp(
|
|
26031
26164
|
sourceMcpJson,
|
|
26032
26165
|
"copilot",
|
|
@@ -26056,13 +26189,13 @@ function writeCompiledArtifact2(component, destination, content, expectedHash, c
|
|
|
26056
26189
|
if (artifactClass === "unmanaged-conflict" && !handleConflict2(destination, config, options, logger, manifest, scopePath)) {
|
|
26057
26190
|
return { component, status: "conflict", path: destination };
|
|
26058
26191
|
}
|
|
26059
|
-
ensureDir(
|
|
26060
|
-
|
|
26192
|
+
ensureDir(path32.dirname(destination));
|
|
26193
|
+
fs32.writeFileSync(destination, content);
|
|
26061
26194
|
return { component, status: "success", path: destination };
|
|
26062
26195
|
}
|
|
26063
26196
|
function isCompiledCurrent2(destination, expectedContent, expectedHash) {
|
|
26064
26197
|
try {
|
|
26065
|
-
const current =
|
|
26198
|
+
const current = fs32.readFileSync(destination, "utf8");
|
|
26066
26199
|
const marker = extractProvenanceMarker(current);
|
|
26067
26200
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "copilot" && current === expectedContent : current === expectedContent;
|
|
26068
26201
|
} catch {
|
|
@@ -26085,11 +26218,11 @@ function handleConflict2(destination, config, options, logger, manifest, scopePa
|
|
|
26085
26218
|
backupFile(destination, manifest);
|
|
26086
26219
|
writeManifest(scopePath, manifest);
|
|
26087
26220
|
} else {
|
|
26088
|
-
|
|
26221
|
+
fs32.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
26089
26222
|
}
|
|
26090
26223
|
return true;
|
|
26091
26224
|
}
|
|
26092
|
-
|
|
26225
|
+
fs32.rmSync(destination, { recursive: true, force: true });
|
|
26093
26226
|
return true;
|
|
26094
26227
|
}
|
|
26095
26228
|
function shouldSkipComponent2(options, component) {
|
|
@@ -26098,12 +26231,12 @@ function shouldSkipComponent2(options, component) {
|
|
|
26098
26231
|
function cleanupLegacyAgents(paths, options, logger) {
|
|
26099
26232
|
const currentAgentsRoot = resolveTargetPath(paths.agents);
|
|
26100
26233
|
const legacyAgentsRoot = resolveTargetPath(legacyCopilotAgentsPath);
|
|
26101
|
-
if (
|
|
26234
|
+
if (path32.resolve(currentAgentsRoot) === path32.resolve(legacyAgentsRoot)) {
|
|
26102
26235
|
return [];
|
|
26103
26236
|
}
|
|
26104
26237
|
const outcomes = [];
|
|
26105
26238
|
for (const filePath of ts(
|
|
26106
|
-
|
|
26239
|
+
path32.join(legacyAgentsRoot, "*.agent.md")
|
|
26107
26240
|
).sort()) {
|
|
26108
26241
|
if (!isCopilotManagedCompiledFile(filePath)) {
|
|
26109
26242
|
continue;
|
|
@@ -26113,14 +26246,14 @@ function cleanupLegacyAgents(paths, options, logger) {
|
|
|
26113
26246
|
outcomes.push({ component: "agents", status: "dry-run", path: filePath });
|
|
26114
26247
|
continue;
|
|
26115
26248
|
}
|
|
26116
|
-
|
|
26249
|
+
fs32.rmSync(filePath, { force: true });
|
|
26117
26250
|
outcomes.push({ component: "agents", status: "success", path: filePath });
|
|
26118
26251
|
}
|
|
26119
26252
|
return outcomes;
|
|
26120
26253
|
}
|
|
26121
26254
|
function isCopilotManagedCompiledFile(filePath) {
|
|
26122
26255
|
try {
|
|
26123
|
-
return extractProvenanceMarker(
|
|
26256
|
+
return extractProvenanceMarker(fs32.readFileSync(filePath, "utf8"))?.target === "copilot";
|
|
26124
26257
|
} catch {
|
|
26125
26258
|
return false;
|
|
26126
26259
|
}
|
|
@@ -26134,7 +26267,7 @@ function skippedMissingSource2(component, source) {
|
|
|
26134
26267
|
}
|
|
26135
26268
|
function isSymlinkTo2(linkPath, source) {
|
|
26136
26269
|
try {
|
|
26137
|
-
return
|
|
26270
|
+
return fs32.realpathSync(linkPath) === fs32.realpathSync(source);
|
|
26138
26271
|
} catch {
|
|
26139
26272
|
return false;
|
|
26140
26273
|
}
|
|
@@ -26142,8 +26275,8 @@ function isSymlinkTo2(linkPath, source) {
|
|
|
26142
26275
|
|
|
26143
26276
|
// src/adapters/cursor.ts
|
|
26144
26277
|
import crypto7 from "crypto";
|
|
26145
|
-
import
|
|
26146
|
-
import
|
|
26278
|
+
import fs33 from "fs";
|
|
26279
|
+
import path33 from "path";
|
|
26147
26280
|
function syncCursor(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
26148
26281
|
const scope = options.scope ?? "global";
|
|
26149
26282
|
const profile = resolveTargetPaths({
|
|
@@ -26294,9 +26427,9 @@ function syncCursor(config, sourceRoot, mappings, extensions, options, lossRepor
|
|
|
26294
26427
|
return { target: "cursor", outcomes };
|
|
26295
26428
|
}
|
|
26296
26429
|
function syncInstructions2(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
|
|
26297
|
-
const source =
|
|
26430
|
+
const source = path33.join(sourceRoot, config.source.instructions);
|
|
26298
26431
|
const destination = resolveTargetPath(paths.instructions);
|
|
26299
|
-
const baseContent =
|
|
26432
|
+
const baseContent = fs33.existsSync(source) ? fs33.readFileSync(source, "utf8").trim() : "";
|
|
26300
26433
|
const personaContent = extractPrimaryPersonaContent(
|
|
26301
26434
|
config,
|
|
26302
26435
|
sourceRoot,
|
|
@@ -26309,7 +26442,7 @@ function syncInstructions2(config, sourceRoot, paths, options, lossReport, logge
|
|
|
26309
26442
|
${personaContent}`.trim() : baseContent;
|
|
26310
26443
|
const marker = formatProvenanceMarker(
|
|
26311
26444
|
"markdown",
|
|
26312
|
-
|
|
26445
|
+
path33.basename(config.source.instructions),
|
|
26313
26446
|
hashString3(composed),
|
|
26314
26447
|
"cursor"
|
|
26315
26448
|
);
|
|
@@ -26334,11 +26467,11 @@ ${composed}
|
|
|
26334
26467
|
);
|
|
26335
26468
|
}
|
|
26336
26469
|
function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
26337
|
-
const agentsDir =
|
|
26338
|
-
if (!
|
|
26470
|
+
const agentsDir = path33.join(sourceRoot, config.source.agents);
|
|
26471
|
+
if (!fs33.existsSync(agentsDir)) {
|
|
26339
26472
|
return null;
|
|
26340
26473
|
}
|
|
26341
|
-
const agentFiles = ts(
|
|
26474
|
+
const agentFiles = ts(path33.join(agentsDir, "*.md")).sort();
|
|
26342
26475
|
if (agentFiles.length === 0) {
|
|
26343
26476
|
return null;
|
|
26344
26477
|
}
|
|
@@ -26361,7 +26494,7 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
26361
26494
|
return null;
|
|
26362
26495
|
}
|
|
26363
26496
|
addLoss(lossReport, "cursor", "instructions", {
|
|
26364
|
-
source: `agents/${
|
|
26497
|
+
source: `agents/${path33.basename(primaryFile)}`,
|
|
26365
26498
|
fields: [
|
|
26366
26499
|
{
|
|
26367
26500
|
field: "persona",
|
|
@@ -26371,23 +26504,23 @@ function extractPrimaryPersonaContent(config, sourceRoot, lossReport) {
|
|
|
26371
26504
|
"persona",
|
|
26372
26505
|
"instructions-shim"
|
|
26373
26506
|
),
|
|
26374
|
-
detail: `Primary persona from ${
|
|
26507
|
+
detail: `Primary persona from ${path33.basename(primaryFile)} folded into AGENTS.md (Cursor has no custom modes surface)`
|
|
26375
26508
|
}
|
|
26376
26509
|
]
|
|
26377
26510
|
});
|
|
26378
26511
|
return body.trim();
|
|
26379
26512
|
}
|
|
26380
26513
|
function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
26381
|
-
const sourceAgentsRoot =
|
|
26382
|
-
if (!
|
|
26514
|
+
const sourceAgentsRoot = path33.join(sourceRoot, config.source.agents);
|
|
26515
|
+
if (!fs33.existsSync(sourceAgentsRoot)) {
|
|
26383
26516
|
return [skippedMissingSource3("agents", sourceAgentsRoot)];
|
|
26384
26517
|
}
|
|
26385
|
-
const sourceAgents = ts(
|
|
26518
|
+
const sourceAgents = ts(path33.join(sourceAgentsRoot, "*.md")).sort();
|
|
26386
26519
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
26387
26520
|
return sourceAgents.map((agentFile) => {
|
|
26388
|
-
const destination =
|
|
26521
|
+
const destination = path33.join(
|
|
26389
26522
|
agentsRoot,
|
|
26390
|
-
`${
|
|
26523
|
+
`${path33.basename(agentFile, ".md")}.md`
|
|
26391
26524
|
);
|
|
26392
26525
|
let compiled;
|
|
26393
26526
|
try {
|
|
@@ -26428,14 +26561,14 @@ function syncAgents3(config, sourceRoot, paths, mappings, extensions, options, l
|
|
|
26428
26561
|
});
|
|
26429
26562
|
}
|
|
26430
26563
|
function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
26431
|
-
const sourceRulesDir =
|
|
26432
|
-
if (!
|
|
26564
|
+
const sourceRulesDir = path33.join(sourceRoot, config.source.rules);
|
|
26565
|
+
if (!fs33.existsSync(sourceRulesDir)) {
|
|
26433
26566
|
return [skippedMissingSource3("rules", sourceRulesDir)];
|
|
26434
26567
|
}
|
|
26435
26568
|
const compiled = compileRules(sourceRulesDir, "cursor", mappings, lossReport);
|
|
26436
26569
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
26437
26570
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
26438
|
-
const destination =
|
|
26571
|
+
const destination = path33.join(rulesDir, name);
|
|
26439
26572
|
if (options.dryRun) {
|
|
26440
26573
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
26441
26574
|
return {
|
|
@@ -26459,17 +26592,17 @@ function syncRules2(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
26459
26592
|
});
|
|
26460
26593
|
}
|
|
26461
26594
|
function syncCommands2(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
26462
|
-
const sourceCommandsRoot =
|
|
26463
|
-
if (!
|
|
26595
|
+
const sourceCommandsRoot = path33.join(sourceRoot, config.source.commands);
|
|
26596
|
+
if (!fs33.existsSync(sourceCommandsRoot)) {
|
|
26464
26597
|
return [skippedMissingSource3("commands", sourceCommandsRoot)];
|
|
26465
26598
|
}
|
|
26466
|
-
const sourceCommands = ts(
|
|
26599
|
+
const sourceCommands = ts(path33.join(sourceCommandsRoot, "*.md")).sort();
|
|
26467
26600
|
const skillsRoot = resolveTargetPath(paths.skills);
|
|
26468
26601
|
return sourceCommands.map((commandFile) => {
|
|
26469
|
-
const baseName =
|
|
26470
|
-
const destination =
|
|
26471
|
-
const commandContent =
|
|
26472
|
-
const relativeSource = `commands/${
|
|
26602
|
+
const baseName = path33.basename(commandFile, ".md");
|
|
26603
|
+
const destination = path33.join(skillsRoot, baseName, "SKILL.md");
|
|
26604
|
+
const commandContent = fs33.readFileSync(commandFile, "utf8");
|
|
26605
|
+
const relativeSource = `commands/${path33.basename(commandFile)}`;
|
|
26473
26606
|
const marker = formatProvenanceMarker(
|
|
26474
26607
|
"markdown",
|
|
26475
26608
|
relativeSource,
|
|
@@ -26508,8 +26641,8 @@ ${commandContent.trim()}
|
|
|
26508
26641
|
});
|
|
26509
26642
|
}
|
|
26510
26643
|
function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, component = "skills", destination = "", asSymlink = false) {
|
|
26511
|
-
const source =
|
|
26512
|
-
if (!
|
|
26644
|
+
const source = path33.resolve(sourceRoot, config.source.skills);
|
|
26645
|
+
if (!fs33.existsSync(source)) {
|
|
26513
26646
|
return skippedMissingSource3(component, source);
|
|
26514
26647
|
}
|
|
26515
26648
|
if (options.dryRun) {
|
|
@@ -26523,18 +26656,18 @@ function syncSkills3(config, sourceRoot, options, logger, manifest, scopePath, c
|
|
|
26523
26656
|
return { component, status: "skipped-current", path: destination };
|
|
26524
26657
|
}
|
|
26525
26658
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
26526
|
-
|
|
26659
|
+
fs33.unlinkSync(destination);
|
|
26527
26660
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
26528
26661
|
return { component, status: "conflict", path: destination };
|
|
26529
26662
|
} else if (artifactClass === "managed-symlink") {
|
|
26530
|
-
|
|
26663
|
+
fs33.unlinkSync(destination);
|
|
26531
26664
|
}
|
|
26532
|
-
ensureDir(
|
|
26665
|
+
ensureDir(path33.dirname(destination));
|
|
26533
26666
|
createRelativeSymlink(source, destination, "dir");
|
|
26534
26667
|
logger.verbose(`Skills: created shared skills symlink ${destination}`);
|
|
26535
26668
|
return { component, status: "success", path: destination };
|
|
26536
26669
|
}
|
|
26537
|
-
if (
|
|
26670
|
+
if (fs33.existsSync(destination)) {
|
|
26538
26671
|
return { component, status: "skipped-current", path: destination };
|
|
26539
26672
|
}
|
|
26540
26673
|
ensureDir(destination);
|
|
@@ -26545,7 +26678,7 @@ function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
26545
26678
|
const source = resolveHooksSourceFile(sourceRoot, config);
|
|
26546
26679
|
const sourceLabel = hooksSourceLabel(config);
|
|
26547
26680
|
const destination = resolveTargetPath(paths.hooks_file);
|
|
26548
|
-
const sourceHooksJson =
|
|
26681
|
+
const sourceHooksJson = fs33.existsSync(source) ? JSON.parse(fs33.readFileSync(source, "utf8")) : { hooks: {} };
|
|
26549
26682
|
const compiled = compileHooks(
|
|
26550
26683
|
sourceHooksJson,
|
|
26551
26684
|
"cursor",
|
|
@@ -26559,18 +26692,18 @@ function syncHooks3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
26559
26692
|
}
|
|
26560
26693
|
const hooksFileContent = `${JSON.stringify({ version: 1, hooks: compiled.payload }, null, 2)}
|
|
26561
26694
|
`;
|
|
26562
|
-
ensureDir(
|
|
26563
|
-
|
|
26695
|
+
ensureDir(path33.dirname(destination));
|
|
26696
|
+
fs33.writeFileSync(destination, hooksFileContent);
|
|
26564
26697
|
return { component: "hooks", status: "success", path: destination };
|
|
26565
26698
|
}
|
|
26566
26699
|
function syncMcp3(config, sourceRoot, paths, options, lossReport, logger, manifest, scopePath) {
|
|
26567
26700
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
26568
26701
|
const sourceLabel = mcpSourceLabel(config);
|
|
26569
26702
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
26570
|
-
if (!
|
|
26703
|
+
if (!fs33.existsSync(source)) {
|
|
26571
26704
|
return skippedMissingSource3("mcp", source);
|
|
26572
26705
|
}
|
|
26573
|
-
const sourceMcpJson = JSON.parse(
|
|
26706
|
+
const sourceMcpJson = JSON.parse(fs33.readFileSync(source, "utf8"));
|
|
26574
26707
|
const mcpJson = compileMcp(sourceMcpJson, "cursor", lossReport, sourceLabel);
|
|
26575
26708
|
if (options.dryRun) {
|
|
26576
26709
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -26621,13 +26754,13 @@ function syncPermissions(config, paths, options, _lossReport, logger, manifest,
|
|
|
26621
26754
|
);
|
|
26622
26755
|
}
|
|
26623
26756
|
function syncProviderPin(config, sourceRoot, lossReport) {
|
|
26624
|
-
const agentsDir =
|
|
26625
|
-
if (!
|
|
26626
|
-
for (const agentFile of ts(
|
|
26757
|
+
const agentsDir = path33.join(sourceRoot, config.source.agents);
|
|
26758
|
+
if (!fs33.existsSync(agentsDir)) return;
|
|
26759
|
+
for (const agentFile of ts(path33.join(agentsDir, "*.md")).sort()) {
|
|
26627
26760
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
26628
26761
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
26629
26762
|
if (hasCustomProvider) {
|
|
26630
|
-
const relativeSource = `agents/${
|
|
26763
|
+
const relativeSource = `agents/${path33.basename(agentFile)}`;
|
|
26631
26764
|
addLoss(lossReport, "cursor", "agents", {
|
|
26632
26765
|
source: relativeSource,
|
|
26633
26766
|
fields: [
|
|
@@ -26639,7 +26772,7 @@ function syncProviderPin(config, sourceRoot, lossReport) {
|
|
|
26639
26772
|
"provider",
|
|
26640
26773
|
"provider-not-representable"
|
|
26641
26774
|
),
|
|
26642
|
-
detail: `${
|
|
26775
|
+
detail: `${path33.basename(agentFile)}: custom provider cannot be expressed in Cursor subagent frontmatter \u2014 configure manually via Cursor settings`
|
|
26643
26776
|
}
|
|
26644
26777
|
]
|
|
26645
26778
|
});
|
|
@@ -26654,8 +26787,8 @@ function writeCompiledArtifact3(component, destination, content, expectedHash, c
|
|
|
26654
26787
|
if (artifactClass === "unmanaged-conflict" && !handleConflict3(destination, config, options, logger, manifest, scopePath)) {
|
|
26655
26788
|
return { component, status: "conflict", path: destination };
|
|
26656
26789
|
}
|
|
26657
|
-
ensureDir(
|
|
26658
|
-
|
|
26790
|
+
ensureDir(path33.dirname(destination));
|
|
26791
|
+
fs33.writeFileSync(destination, content);
|
|
26659
26792
|
return { component, status: "success", path: destination };
|
|
26660
26793
|
}
|
|
26661
26794
|
function handleConflict3(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -26674,16 +26807,16 @@ function handleConflict3(destination, config, options, logger, manifest, scopePa
|
|
|
26674
26807
|
backupFile(destination, manifest);
|
|
26675
26808
|
writeManifest(scopePath, manifest);
|
|
26676
26809
|
} else {
|
|
26677
|
-
|
|
26810
|
+
fs33.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
26678
26811
|
}
|
|
26679
26812
|
return true;
|
|
26680
26813
|
}
|
|
26681
|
-
|
|
26814
|
+
fs33.rmSync(destination, { recursive: true, force: true });
|
|
26682
26815
|
return true;
|
|
26683
26816
|
}
|
|
26684
26817
|
function isCompiledCurrent3(destination, expectedContent, expectedHash) {
|
|
26685
26818
|
try {
|
|
26686
|
-
const current =
|
|
26819
|
+
const current = fs33.readFileSync(destination, "utf8");
|
|
26687
26820
|
const marker = extractProvenanceMarker(current);
|
|
26688
26821
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cursor" && current === expectedContent : current === expectedContent;
|
|
26689
26822
|
} catch {
|
|
@@ -26702,7 +26835,7 @@ function shouldSkipComponent3(options, component) {
|
|
|
26702
26835
|
}
|
|
26703
26836
|
function isSymlinkTo3(linkPath, source) {
|
|
26704
26837
|
try {
|
|
26705
|
-
return
|
|
26838
|
+
return fs33.realpathSync(linkPath) === fs33.realpathSync(source);
|
|
26706
26839
|
} catch {
|
|
26707
26840
|
return false;
|
|
26708
26841
|
}
|
|
@@ -26713,8 +26846,8 @@ function hashString3(value) {
|
|
|
26713
26846
|
|
|
26714
26847
|
// src/adapters/cline.ts
|
|
26715
26848
|
import crypto8 from "crypto";
|
|
26716
|
-
import
|
|
26717
|
-
import
|
|
26849
|
+
import fs34 from "fs";
|
|
26850
|
+
import path34 from "path";
|
|
26718
26851
|
function syncCline(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
26719
26852
|
const scope = options.scope ?? "global";
|
|
26720
26853
|
const profile = resolveTargetPaths({
|
|
@@ -26827,7 +26960,7 @@ function syncCline(config, sourceRoot, mappings, extensions, options, lossReport
|
|
|
26827
26960
|
function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport, logger, manifest, scopePath) {
|
|
26828
26961
|
if (scope === "global" || paths.instructions === null) {
|
|
26829
26962
|
addLoss(lossReport, "cline", "instructions", {
|
|
26830
|
-
source:
|
|
26963
|
+
source: path34.basename(config.source.instructions),
|
|
26831
26964
|
fields: [
|
|
26832
26965
|
{
|
|
26833
26966
|
field: "instructions",
|
|
@@ -26847,12 +26980,12 @@ function syncInstructions3(config, sourceRoot, paths, scope, options, lossReport
|
|
|
26847
26980
|
path: "cline/global/instructions: no committable global path"
|
|
26848
26981
|
};
|
|
26849
26982
|
}
|
|
26850
|
-
const source =
|
|
26983
|
+
const source = path34.join(sourceRoot, config.source.instructions);
|
|
26851
26984
|
const destination = resolveTargetPath(paths.instructions);
|
|
26852
|
-
const baseContent =
|
|
26985
|
+
const baseContent = fs34.existsSync(source) ? fs34.readFileSync(source, "utf8").trim() : "";
|
|
26853
26986
|
const marker = formatProvenanceMarker(
|
|
26854
26987
|
"markdown",
|
|
26855
|
-
|
|
26988
|
+
path34.basename(config.source.instructions),
|
|
26856
26989
|
hashString4(baseContent),
|
|
26857
26990
|
"cline"
|
|
26858
26991
|
);
|
|
@@ -26877,11 +27010,11 @@ ${baseContent}
|
|
|
26877
27010
|
);
|
|
26878
27011
|
}
|
|
26879
27012
|
function syncAgents4(config, sourceRoot, mappings, extensions, options, lossReport, logger) {
|
|
26880
|
-
const sourceAgentsRoot =
|
|
26881
|
-
if (!
|
|
27013
|
+
const sourceAgentsRoot = path34.join(sourceRoot, config.source.agents);
|
|
27014
|
+
if (!fs34.existsSync(sourceAgentsRoot)) {
|
|
26882
27015
|
return [skippedMissingSource4("agents", sourceAgentsRoot)];
|
|
26883
27016
|
}
|
|
26884
|
-
const sourceAgents = ts(
|
|
27017
|
+
const sourceAgents = ts(path34.join(sourceAgentsRoot, "*.md")).sort();
|
|
26885
27018
|
return sourceAgents.map((agentFile) => {
|
|
26886
27019
|
compileAgent(agentFile, "cline", mappings, extensions, lossReport);
|
|
26887
27020
|
if (options.dryRun) {
|
|
@@ -26897,14 +27030,14 @@ function syncAgents4(config, sourceRoot, mappings, extensions, options, lossRepo
|
|
|
26897
27030
|
});
|
|
26898
27031
|
}
|
|
26899
27032
|
function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, logger, manifest, scopePath) {
|
|
26900
|
-
const sourceRulesDir =
|
|
26901
|
-
if (!
|
|
27033
|
+
const sourceRulesDir = path34.join(sourceRoot, config.source.rules);
|
|
27034
|
+
if (!fs34.existsSync(sourceRulesDir)) {
|
|
26902
27035
|
return [skippedMissingSource4("rules", sourceRulesDir)];
|
|
26903
27036
|
}
|
|
26904
27037
|
const compiled = compileRules(sourceRulesDir, "cline", mappings, lossReport);
|
|
26905
27038
|
const rulesDir = resolveTargetPath(paths.rules);
|
|
26906
27039
|
return compiled.dotRulesFiles.map(({ name, content }) => {
|
|
26907
|
-
const destination =
|
|
27040
|
+
const destination = path34.join(rulesDir, name);
|
|
26908
27041
|
if (options.dryRun) {
|
|
26909
27042
|
logger.info(`[dry-run] rules: write ${destination}`);
|
|
26910
27043
|
return {
|
|
@@ -26928,17 +27061,17 @@ function syncRules3(config, sourceRoot, paths, mappings, options, lossReport, lo
|
|
|
26928
27061
|
});
|
|
26929
27062
|
}
|
|
26930
27063
|
function syncCommands3(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
26931
|
-
const sourceCommandsRoot =
|
|
26932
|
-
if (!
|
|
27064
|
+
const sourceCommandsRoot = path34.join(sourceRoot, config.source.commands);
|
|
27065
|
+
if (!fs34.existsSync(sourceCommandsRoot)) {
|
|
26933
27066
|
return [skippedMissingSource4("commands", sourceCommandsRoot)];
|
|
26934
27067
|
}
|
|
26935
|
-
const sourceCommands = ts(
|
|
27068
|
+
const sourceCommands = ts(path34.join(sourceCommandsRoot, "*.md")).sort();
|
|
26936
27069
|
const workflowsRoot = resolveTargetPath(paths.workflows);
|
|
26937
27070
|
return sourceCommands.map((commandFile) => {
|
|
26938
|
-
const baseName =
|
|
26939
|
-
const destination =
|
|
26940
|
-
const commandContent =
|
|
26941
|
-
const relativeSource = `commands/${
|
|
27071
|
+
const baseName = path34.basename(commandFile);
|
|
27072
|
+
const destination = path34.join(workflowsRoot, baseName);
|
|
27073
|
+
const commandContent = fs34.readFileSync(commandFile, "utf8");
|
|
27074
|
+
const relativeSource = `commands/${path34.basename(commandFile)}`;
|
|
26942
27075
|
const marker = formatProvenanceMarker(
|
|
26943
27076
|
"markdown",
|
|
26944
27077
|
relativeSource,
|
|
@@ -26973,9 +27106,9 @@ ${commandContent.trim()}
|
|
|
26973
27106
|
});
|
|
26974
27107
|
}
|
|
26975
27108
|
function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
26976
|
-
const source =
|
|
27109
|
+
const source = path34.resolve(sourceRoot, config.source.skills);
|
|
26977
27110
|
const destination = resolveTargetPath(paths.skills);
|
|
26978
|
-
if (!
|
|
27111
|
+
if (!fs34.existsSync(source)) {
|
|
26979
27112
|
return skippedMissingSource4("skills", source);
|
|
26980
27113
|
}
|
|
26981
27114
|
if (options.dryRun) {
|
|
@@ -26995,9 +27128,9 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
26995
27128
|
return { component: "skills", status: "conflict", path: destination };
|
|
26996
27129
|
}
|
|
26997
27130
|
} else if (artifactClass === "managed-symlink") {
|
|
26998
|
-
|
|
27131
|
+
fs34.unlinkSync(destination);
|
|
26999
27132
|
}
|
|
27000
|
-
ensureDir(
|
|
27133
|
+
ensureDir(path34.dirname(destination));
|
|
27001
27134
|
createRelativeSymlink(source, destination, "dir");
|
|
27002
27135
|
logger.verbose(`Skills: created Cline skills symlink ${destination}`);
|
|
27003
27136
|
return { component: "skills", status: "success", path: destination };
|
|
@@ -27005,7 +27138,7 @@ function syncSkills4(config, sourceRoot, paths, options, logger, manifest, scope
|
|
|
27005
27138
|
function syncHooks4(config, sourceRoot, mappings, options, lossReport, logger) {
|
|
27006
27139
|
const source = resolveHooksSourceFile(sourceRoot, config);
|
|
27007
27140
|
const sourceLabel = hooksSourceLabel(config);
|
|
27008
|
-
const sourceHooksJson =
|
|
27141
|
+
const sourceHooksJson = fs34.existsSync(source) ? JSON.parse(fs34.readFileSync(source, "utf8")) : { hooks: {} };
|
|
27009
27142
|
compileHooks(sourceHooksJson, "cline", mappings, lossReport, sourceLabel);
|
|
27010
27143
|
if (options.dryRun) {
|
|
27011
27144
|
logger.info(`[dry-run] hooks: record hook-as-plugin loss for ${source}`);
|
|
@@ -27020,10 +27153,10 @@ function syncMcp4(config, sourceRoot, paths, options, lossReport, logger, manife
|
|
|
27020
27153
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
27021
27154
|
const sourceLabel = mcpSourceLabel(config);
|
|
27022
27155
|
const destination = resolveTargetPath(paths.mcp_file);
|
|
27023
|
-
if (!
|
|
27156
|
+
if (!fs34.existsSync(source)) {
|
|
27024
27157
|
return skippedMissingSource4("mcp", source);
|
|
27025
27158
|
}
|
|
27026
|
-
const sourceMcpJson = JSON.parse(
|
|
27159
|
+
const sourceMcpJson = JSON.parse(fs34.readFileSync(source, "utf8"));
|
|
27027
27160
|
const mcpJson = compileMcp(sourceMcpJson, "cline", lossReport, sourceLabel);
|
|
27028
27161
|
if (options.dryRun) {
|
|
27029
27162
|
logger.info(`[dry-run] mcp: compile ${source} -> ${destination}`);
|
|
@@ -27066,11 +27199,11 @@ function syncSettings(lossReport) {
|
|
|
27066
27199
|
};
|
|
27067
27200
|
}
|
|
27068
27201
|
function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
27069
|
-
const agentsDir =
|
|
27070
|
-
if (!
|
|
27071
|
-
for (const agentFile of ts(
|
|
27202
|
+
const agentsDir = path34.join(sourceRoot, config.source.agents);
|
|
27203
|
+
if (!fs34.existsSync(agentsDir)) return;
|
|
27204
|
+
for (const agentFile of ts(path34.join(agentsDir, "*.md")).sort()) {
|
|
27072
27205
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
27073
|
-
const relativeSource = `agents/${
|
|
27206
|
+
const relativeSource = `agents/${path34.basename(agentFile)}`;
|
|
27074
27207
|
const hasCustomProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
27075
27208
|
if (hasCustomProvider) {
|
|
27076
27209
|
addLoss(lossReport, "cline", "agents", {
|
|
@@ -27084,7 +27217,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
27084
27217
|
"provider",
|
|
27085
27218
|
"provider-not-representable"
|
|
27086
27219
|
),
|
|
27087
|
-
detail: `${
|
|
27220
|
+
detail: `${path34.basename(agentFile)}: Cline provider is interface-only (Settings \u2192 API Provider); configure manually.`
|
|
27088
27221
|
}
|
|
27089
27222
|
]
|
|
27090
27223
|
});
|
|
@@ -27102,7 +27235,7 @@ function syncProviderAndModel(config, sourceRoot, lossReport) {
|
|
|
27102
27235
|
"model",
|
|
27103
27236
|
"model-not-representable"
|
|
27104
27237
|
),
|
|
27105
|
-
detail: `${
|
|
27238
|
+
detail: `${path34.basename(agentFile)}: Cline model pin is interface-only (Settings \u2192 Model); configure manually.`
|
|
27106
27239
|
}
|
|
27107
27240
|
]
|
|
27108
27241
|
});
|
|
@@ -27117,8 +27250,8 @@ function writeCompiledArtifact4(component, destination, content, expectedHash, c
|
|
|
27117
27250
|
if (artifactClass === "unmanaged-conflict" && !handleConflict4(destination, config, options, logger, manifest, scopePath)) {
|
|
27118
27251
|
return { component, status: "conflict", path: destination };
|
|
27119
27252
|
}
|
|
27120
|
-
ensureDir(
|
|
27121
|
-
|
|
27253
|
+
ensureDir(path34.dirname(destination));
|
|
27254
|
+
fs34.writeFileSync(destination, content);
|
|
27122
27255
|
return { component, status: "success", path: destination };
|
|
27123
27256
|
}
|
|
27124
27257
|
function handleConflict4(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -27137,16 +27270,16 @@ function handleConflict4(destination, config, options, logger, manifest, scopePa
|
|
|
27137
27270
|
backupFile(destination, manifest);
|
|
27138
27271
|
writeManifest(scopePath, manifest);
|
|
27139
27272
|
} else {
|
|
27140
|
-
|
|
27273
|
+
fs34.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
27141
27274
|
}
|
|
27142
27275
|
return true;
|
|
27143
27276
|
}
|
|
27144
|
-
|
|
27277
|
+
fs34.rmSync(destination, { recursive: true, force: true });
|
|
27145
27278
|
return true;
|
|
27146
27279
|
}
|
|
27147
27280
|
function isCompiledCurrent4(destination, expectedContent, expectedHash) {
|
|
27148
27281
|
try {
|
|
27149
|
-
const current =
|
|
27282
|
+
const current = fs34.readFileSync(destination, "utf8");
|
|
27150
27283
|
const marker = extractProvenanceMarker(current);
|
|
27151
27284
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "cline" && current === expectedContent : current === expectedContent;
|
|
27152
27285
|
} catch {
|
|
@@ -27165,7 +27298,7 @@ function shouldSkipComponent4(options, component) {
|
|
|
27165
27298
|
}
|
|
27166
27299
|
function isSymlinkTo4(linkPath, source) {
|
|
27167
27300
|
try {
|
|
27168
|
-
return
|
|
27301
|
+
return fs34.realpathSync(linkPath) === fs34.realpathSync(source);
|
|
27169
27302
|
} catch {
|
|
27170
27303
|
return false;
|
|
27171
27304
|
}
|
|
@@ -27176,9 +27309,9 @@ function hashString4(value) {
|
|
|
27176
27309
|
|
|
27177
27310
|
// src/adapters/opencode.ts
|
|
27178
27311
|
import crypto9 from "crypto";
|
|
27179
|
-
import
|
|
27312
|
+
import fs35 from "fs";
|
|
27180
27313
|
import os6 from "os";
|
|
27181
|
-
import
|
|
27314
|
+
import path35 from "path";
|
|
27182
27315
|
var import_yaml10 = __toESM(require_dist(), 1);
|
|
27183
27316
|
function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
27184
27317
|
const scope = options.scope ?? "global";
|
|
@@ -27196,7 +27329,7 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
27196
27329
|
config_doc: profile.config_doc
|
|
27197
27330
|
};
|
|
27198
27331
|
const rules = compileRules(
|
|
27199
|
-
|
|
27332
|
+
path35.join(sourceRoot, config.source.rules),
|
|
27200
27333
|
"opencode",
|
|
27201
27334
|
mappings,
|
|
27202
27335
|
lossReport
|
|
@@ -27298,16 +27431,16 @@ function syncOpenCode(config, sourceRoot, mappings, extensions, options, lossRep
|
|
|
27298
27431
|
return { target: "opencode", outcomes };
|
|
27299
27432
|
}
|
|
27300
27433
|
function syncInstructions4(config, sourceRoot, paths, agentsAppendix, options, logger, manifest, scopePath) {
|
|
27301
|
-
const source =
|
|
27434
|
+
const source = path35.join(sourceRoot, config.source.instructions);
|
|
27302
27435
|
const destination = resolveTargetPath(paths.instructions);
|
|
27303
|
-
const baseContent =
|
|
27436
|
+
const baseContent = fs35.existsSync(source) ? fs35.readFileSync(source, "utf8").trim() : "";
|
|
27304
27437
|
const composed = agentsAppendix ? `${baseContent}
|
|
27305
27438
|
|
|
27306
27439
|
--- tangyr managed rules ---
|
|
27307
27440
|
${agentsAppendix}`.trim() : baseContent;
|
|
27308
27441
|
const marker = formatProvenanceMarker(
|
|
27309
27442
|
"markdown",
|
|
27310
|
-
|
|
27443
|
+
path35.basename(config.source.instructions),
|
|
27311
27444
|
hashString5(composed),
|
|
27312
27445
|
"opencode"
|
|
27313
27446
|
);
|
|
@@ -27334,16 +27467,16 @@ ${composed}
|
|
|
27334
27467
|
);
|
|
27335
27468
|
}
|
|
27336
27469
|
function syncAgents5(config, sourceRoot, paths, mappings, extensions, options, lossReport, logger, manifest, scopePath) {
|
|
27337
|
-
const sourceAgentsRoot =
|
|
27338
|
-
if (!
|
|
27470
|
+
const sourceAgentsRoot = path35.join(sourceRoot, config.source.agents);
|
|
27471
|
+
if (!fs35.existsSync(sourceAgentsRoot)) {
|
|
27339
27472
|
return [skippedMissingSource5("agents", sourceAgentsRoot)];
|
|
27340
27473
|
}
|
|
27341
|
-
const sourceAgents = ts(
|
|
27474
|
+
const sourceAgents = ts(path35.join(sourceAgentsRoot, "*.md")).sort();
|
|
27342
27475
|
const agentsRoot = resolveTargetPath(paths.agents);
|
|
27343
27476
|
return sourceAgents.map((agentFile) => {
|
|
27344
|
-
const destination =
|
|
27477
|
+
const destination = path35.join(
|
|
27345
27478
|
agentsRoot,
|
|
27346
|
-
`${
|
|
27479
|
+
`${path35.basename(agentFile, ".md")}.md`
|
|
27347
27480
|
);
|
|
27348
27481
|
let compiled;
|
|
27349
27482
|
try {
|
|
@@ -27407,11 +27540,11 @@ function applyProviderModelBinding(compiled, mappings) {
|
|
|
27407
27540
|
return `${before}${(0, import_yaml10.stringify)(fields).trim()}${after}`;
|
|
27408
27541
|
}
|
|
27409
27542
|
function syncCommands4(config, sourceRoot, paths, options, logger, manifest, scopePath) {
|
|
27410
|
-
const sourceCommandsRoot =
|
|
27411
|
-
if (!
|
|
27543
|
+
const sourceCommandsRoot = path35.join(sourceRoot, config.source.commands);
|
|
27544
|
+
if (!fs35.existsSync(sourceCommandsRoot)) {
|
|
27412
27545
|
return [skippedMissingSource5("commands", sourceCommandsRoot)];
|
|
27413
27546
|
}
|
|
27414
|
-
const sourceCommands = ts(
|
|
27547
|
+
const sourceCommands = ts(path35.join(sourceCommandsRoot, "*.md")).sort();
|
|
27415
27548
|
const commandsRoot = resolveTargetPath(paths.commands);
|
|
27416
27549
|
return sourceCommands.map((commandFile) => {
|
|
27417
27550
|
const { data, body } = parseCommandFile(commandFile);
|
|
@@ -27425,7 +27558,7 @@ function syncCommands4(config, sourceRoot, paths, options, logger, manifest, sco
|
|
|
27425
27558
|
if (typeof data.model === "string") {
|
|
27426
27559
|
frontmatter.model = data.model;
|
|
27427
27560
|
}
|
|
27428
|
-
const relativeSource = `commands/${
|
|
27561
|
+
const relativeSource = `commands/${path35.basename(commandFile)}`;
|
|
27429
27562
|
const marker = formatProvenanceMarker(
|
|
27430
27563
|
"markdown",
|
|
27431
27564
|
relativeSource,
|
|
@@ -27441,9 +27574,9 @@ ${body.trimEnd()}
|
|
|
27441
27574
|
` : `${marker}
|
|
27442
27575
|
${body.trimEnd()}
|
|
27443
27576
|
`;
|
|
27444
|
-
const destination =
|
|
27577
|
+
const destination = path35.join(
|
|
27445
27578
|
commandsRoot,
|
|
27446
|
-
`${
|
|
27579
|
+
`${path35.basename(commandFile, ".md")}.md`
|
|
27447
27580
|
);
|
|
27448
27581
|
if (options.dryRun) {
|
|
27449
27582
|
logger.info(
|
|
@@ -27470,8 +27603,8 @@ ${body.trimEnd()}
|
|
|
27470
27603
|
});
|
|
27471
27604
|
}
|
|
27472
27605
|
function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scopePath, component = "skills", destination = "") {
|
|
27473
|
-
const source =
|
|
27474
|
-
if (!
|
|
27606
|
+
const source = path35.resolve(sourceRoot, config.source.skills);
|
|
27607
|
+
if (!fs35.existsSync(source)) {
|
|
27475
27608
|
return skippedMissingSource5(component, source);
|
|
27476
27609
|
}
|
|
27477
27610
|
if (options.dryRun) {
|
|
@@ -27483,13 +27616,13 @@ function syncSkills5(config, sourceRoot, _paths, options, logger, manifest, scop
|
|
|
27483
27616
|
return { component, status: "skipped-current", path: destination };
|
|
27484
27617
|
}
|
|
27485
27618
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
27486
|
-
|
|
27619
|
+
fs35.unlinkSync(destination);
|
|
27487
27620
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
27488
27621
|
return { component, status: "conflict", path: destination };
|
|
27489
27622
|
} else if (artifactClass === "managed-symlink") {
|
|
27490
|
-
|
|
27623
|
+
fs35.unlinkSync(destination);
|
|
27491
27624
|
}
|
|
27492
|
-
ensureDir(
|
|
27625
|
+
ensureDir(path35.dirname(destination));
|
|
27493
27626
|
createRelativeSymlink(source, destination, "dir");
|
|
27494
27627
|
logger.verbose(`Skills: created skills path ${destination}`);
|
|
27495
27628
|
return { component, status: "success", path: destination };
|
|
@@ -27498,13 +27631,13 @@ function syncMcp5(config, sourceRoot, paths, mappings, options, lossReport, logg
|
|
|
27498
27631
|
const source = resolveMcpSourceFile(sourceRoot, config);
|
|
27499
27632
|
const sourceLabel = mcpSourceLabel(config);
|
|
27500
27633
|
const destination = resolveTargetPath(paths.config_doc);
|
|
27501
|
-
if (!
|
|
27634
|
+
if (!fs35.existsSync(source)) {
|
|
27502
27635
|
if (!options.dryRun) {
|
|
27503
27636
|
syncConfigDoc(paths, {}, lossReport, {}, mappings);
|
|
27504
27637
|
}
|
|
27505
27638
|
return skippedMissingSource5("mcp", source);
|
|
27506
27639
|
}
|
|
27507
|
-
const sourceMcpJson = JSON.parse(
|
|
27640
|
+
const sourceMcpJson = JSON.parse(fs35.readFileSync(source, "utf8"));
|
|
27508
27641
|
const mcpJson = compileMcp(
|
|
27509
27642
|
sourceMcpJson,
|
|
27510
27643
|
"opencode",
|
|
@@ -27535,7 +27668,7 @@ function syncPermissions2(config, _sourceRoot, paths, options, lossReport, logge
|
|
|
27535
27668
|
function syncHooks5(config, sourceRoot, mappings, options, lossReport) {
|
|
27536
27669
|
const source = resolveHooksSourceFile(sourceRoot, config);
|
|
27537
27670
|
const sourceLabel = hooksSourceLabel(config);
|
|
27538
|
-
const sourceHooksJson =
|
|
27671
|
+
const sourceHooksJson = fs35.existsSync(source) ? JSON.parse(fs35.readFileSync(source, "utf8")) : { hooks: {} };
|
|
27539
27672
|
compileHooks(sourceHooksJson, "opencode", mappings, lossReport, sourceLabel);
|
|
27540
27673
|
const message = "hooks: Skip \u2014 OpenCode exposes hooks only as plugin code (hook-as-plugin loss recorded)";
|
|
27541
27674
|
return { component: "hooks", status: "skipped", path: message };
|
|
@@ -27569,9 +27702,9 @@ function syncProviderBlock(mappings) {
|
|
|
27569
27702
|
function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings) {
|
|
27570
27703
|
const destination = resolveTargetPath(paths.config_doc);
|
|
27571
27704
|
let existing = {};
|
|
27572
|
-
if (
|
|
27705
|
+
if (fs35.existsSync(destination)) {
|
|
27573
27706
|
try {
|
|
27574
|
-
existing = JSON.parse(
|
|
27707
|
+
existing = JSON.parse(fs35.readFileSync(destination, "utf8"));
|
|
27575
27708
|
} catch {
|
|
27576
27709
|
existing = {};
|
|
27577
27710
|
}
|
|
@@ -27596,8 +27729,8 @@ function syncConfigDoc(paths, mcpEntries, _lossReport, permissionMap, mappings)
|
|
|
27596
27729
|
};
|
|
27597
27730
|
}
|
|
27598
27731
|
}
|
|
27599
|
-
ensureDir(
|
|
27600
|
-
|
|
27732
|
+
ensureDir(path35.dirname(destination));
|
|
27733
|
+
fs35.writeFileSync(destination, `${JSON.stringify(config, null, 2)}
|
|
27601
27734
|
`);
|
|
27602
27735
|
}
|
|
27603
27736
|
function writeCompiledArtifact5(component, destination, content, expectedHash, config, sourceRoot, options, logger, manifest, scopePath) {
|
|
@@ -27608,8 +27741,8 @@ function writeCompiledArtifact5(component, destination, content, expectedHash, c
|
|
|
27608
27741
|
if (artifactClass === "unmanaged-conflict" && !handleConflict5(destination, config, options, logger, manifest, scopePath)) {
|
|
27609
27742
|
return { component, status: "conflict", path: destination };
|
|
27610
27743
|
}
|
|
27611
|
-
ensureDir(
|
|
27612
|
-
|
|
27744
|
+
ensureDir(path35.dirname(destination));
|
|
27745
|
+
fs35.writeFileSync(destination, content);
|
|
27613
27746
|
return { component, status: "success", path: destination };
|
|
27614
27747
|
}
|
|
27615
27748
|
function handleConflict5(destination, config, options, logger, manifest, scopePath) {
|
|
@@ -27628,16 +27761,16 @@ function handleConflict5(destination, config, options, logger, manifest, scopePa
|
|
|
27628
27761
|
backupFile(destination, manifest);
|
|
27629
27762
|
writeManifest(scopePath, manifest);
|
|
27630
27763
|
} else {
|
|
27631
|
-
|
|
27764
|
+
fs35.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
27632
27765
|
}
|
|
27633
27766
|
return true;
|
|
27634
27767
|
}
|
|
27635
|
-
|
|
27768
|
+
fs35.rmSync(destination, { recursive: true, force: true });
|
|
27636
27769
|
return true;
|
|
27637
27770
|
}
|
|
27638
27771
|
function isCompiledCurrent5(destination, expectedContent, expectedHash) {
|
|
27639
27772
|
try {
|
|
27640
|
-
const current =
|
|
27773
|
+
const current = fs35.readFileSync(destination, "utf8");
|
|
27641
27774
|
const marker = extractProvenanceMarker(current);
|
|
27642
27775
|
return expectedHash ? marker?.hash === expectedHash && marker.target === "opencode" && current === expectedContent : current === expectedContent;
|
|
27643
27776
|
} catch {
|
|
@@ -27656,7 +27789,7 @@ function shouldSkipComponent5(options, component) {
|
|
|
27656
27789
|
}
|
|
27657
27790
|
function isSymlinkTo5(linkPath, source) {
|
|
27658
27791
|
try {
|
|
27659
|
-
return
|
|
27792
|
+
return fs35.realpathSync(linkPath) === fs35.realpathSync(source);
|
|
27660
27793
|
} catch {
|
|
27661
27794
|
return false;
|
|
27662
27795
|
}
|
|
@@ -27665,7 +27798,7 @@ function hashString5(value) {
|
|
|
27665
27798
|
return `sha256:${crypto9.createHash("sha256").update(value).digest("hex")}`;
|
|
27666
27799
|
}
|
|
27667
27800
|
function parseCommandFile(commandFile) {
|
|
27668
|
-
const content =
|
|
27801
|
+
const content = fs35.readFileSync(commandFile, "utf8");
|
|
27669
27802
|
if (!content.startsWith("---\n")) {
|
|
27670
27803
|
return { data: {}, body: content };
|
|
27671
27804
|
}
|
|
@@ -27685,10 +27818,10 @@ function parseCommandFile(commandFile) {
|
|
|
27685
27818
|
// src/commands/install.ts
|
|
27686
27819
|
function isBackupableFile(targetPath) {
|
|
27687
27820
|
try {
|
|
27688
|
-
const lstat =
|
|
27821
|
+
const lstat = fs36.lstatSync(targetPath);
|
|
27689
27822
|
if (lstat.isDirectory()) return false;
|
|
27690
27823
|
if (lstat.isSymbolicLink()) {
|
|
27691
|
-
const stat =
|
|
27824
|
+
const stat = fs36.statSync(targetPath);
|
|
27692
27825
|
return stat.isFile();
|
|
27693
27826
|
}
|
|
27694
27827
|
return lstat.isFile();
|
|
@@ -27698,10 +27831,10 @@ function isBackupableFile(targetPath) {
|
|
|
27698
27831
|
}
|
|
27699
27832
|
function backupConflictingTarget(targetPath, scopePath) {
|
|
27700
27833
|
const ts2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/gu, "").replace("T", "T").replace(/\.\d+Z$/u, "Z");
|
|
27701
|
-
const relativeToRoot =
|
|
27702
|
-
const backupPath =
|
|
27703
|
-
|
|
27704
|
-
|
|
27834
|
+
const relativeToRoot = path36.relative("/", targetPath).replace(/^\.\.\/+/gu, "");
|
|
27835
|
+
const backupPath = path36.join(scopePath, "backups", ts2, relativeToRoot);
|
|
27836
|
+
fs36.mkdirSync(path36.dirname(backupPath), { recursive: true });
|
|
27837
|
+
fs36.copyFileSync(targetPath, backupPath);
|
|
27705
27838
|
return backupPath;
|
|
27706
27839
|
}
|
|
27707
27840
|
async function runInstallCommand(options, logger) {
|
|
@@ -27730,7 +27863,7 @@ async function runInstallCommand(options, logger) {
|
|
|
27730
27863
|
);
|
|
27731
27864
|
}
|
|
27732
27865
|
const kitName = resolvedKitName ?? config.kit;
|
|
27733
|
-
const kitPath = kitPathOverride ?? (options.kitPath ?
|
|
27866
|
+
const kitPath = kitPathOverride ?? (options.kitPath ? path36.resolve(options.kitPath) : config.kitPath);
|
|
27734
27867
|
if (!kitName && !kitPath) {
|
|
27735
27868
|
logger.error(
|
|
27736
27869
|
"No kit specified. Use --kit <name>, --kit-path <path>, or set 'kit'/'kitPath' in tangyr.config.yaml."
|
|
@@ -27871,7 +28004,7 @@ ACCEPTED CONFLICTS (backup-and-replace applied to ${conflictingFindings.length}
|
|
|
27871
28004
|
logger.info(` source: ${finding.tool}`);
|
|
27872
28005
|
logger.info(` action: backup-and-replace`);
|
|
27873
28006
|
logger.info(` backup: ${backupLocation}`);
|
|
27874
|
-
} else if (
|
|
28007
|
+
} else if (fs36.existsSync(finding.path)) {
|
|
27875
28008
|
logger.info(` - ${finding.path}`);
|
|
27876
28009
|
logger.info(` source: ${finding.tool}`);
|
|
27877
28010
|
logger.info(
|
|
@@ -27982,7 +28115,7 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
27982
28115
|
writeManifest(scopePath, manifest);
|
|
27983
28116
|
logger.info(`
|
|
27984
28117
|
Installation complete: ${installedCount} files installed.`);
|
|
27985
|
-
logger.info(`Manifest written to ${
|
|
28118
|
+
logger.info(`Manifest written to ${path36.join(scopePath, "manifest.json")}`);
|
|
27986
28119
|
logger.info(`Kit: ${kitInfo.name} (archetype: ${kitInfo.archetype})`);
|
|
27987
28120
|
logger.info(`Scope: ${scope}`);
|
|
27988
28121
|
logger.info(`Tools: ${tools.join(", ")}`);
|
|
@@ -28124,13 +28257,13 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
28124
28257
|
logger.verbose(` skipped (operator choice): ${placement.destination}`);
|
|
28125
28258
|
continue;
|
|
28126
28259
|
}
|
|
28127
|
-
const destDir =
|
|
28128
|
-
|
|
28260
|
+
const destDir = path36.dirname(placement.destination);
|
|
28261
|
+
fs36.mkdirSync(destDir, { recursive: true });
|
|
28129
28262
|
if (placement.type === "symlink") {
|
|
28130
|
-
if (
|
|
28263
|
+
if (fs36.existsSync(placement.destination) || isSymlink2(placement.destination)) {
|
|
28131
28264
|
removeManagedPath(placement.destination);
|
|
28132
28265
|
}
|
|
28133
|
-
|
|
28266
|
+
fs36.symlinkSync(
|
|
28134
28267
|
placement.source,
|
|
28135
28268
|
placement.destination,
|
|
28136
28269
|
placement.isDir ? "dir" : "file"
|
|
@@ -28139,12 +28272,12 @@ function applyClaudeCodePlacements(placements, manifest, skippedTargetPaths, log
|
|
|
28139
28272
|
` symlink: ${placement.source} \u2192 ${placement.destination}`
|
|
28140
28273
|
);
|
|
28141
28274
|
} else {
|
|
28142
|
-
|
|
28275
|
+
fs36.copyFileSync(placement.source, placement.destination);
|
|
28143
28276
|
logger.verbose(` copy: ${placement.source} \u2192 ${placement.destination}`);
|
|
28144
28277
|
}
|
|
28145
28278
|
addArtifactToManifest(manifest, {
|
|
28146
28279
|
relativePath: placement.manifestKey,
|
|
28147
|
-
hash:
|
|
28280
|
+
hash: fs36.statSync(placement.source).isDirectory() ? `dir:${placement.source}` : computeSourceHash(placement.source),
|
|
28148
28281
|
origin: "tangyr-managed"
|
|
28149
28282
|
});
|
|
28150
28283
|
count++;
|
|
@@ -28391,11 +28524,11 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
28391
28524
|
if (outcome.path === mcpFile2) {
|
|
28392
28525
|
return "cline/mcp.json";
|
|
28393
28526
|
}
|
|
28394
|
-
if (outcome.path.startsWith(`${workflowsRoot}${
|
|
28395
|
-
return `cline/workflows/${
|
|
28527
|
+
if (outcome.path.startsWith(`${workflowsRoot}${path36.sep}`)) {
|
|
28528
|
+
return `cline/workflows/${path36.basename(outcome.path)}`;
|
|
28396
28529
|
}
|
|
28397
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
28398
|
-
return `cline/rules/${
|
|
28530
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path36.sep}`)) {
|
|
28531
|
+
return `cline/rules/${path36.basename(outcome.path)}`;
|
|
28399
28532
|
}
|
|
28400
28533
|
return null;
|
|
28401
28534
|
}
|
|
@@ -28431,14 +28564,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
28431
28564
|
if (outcome.path === permissionsFile) {
|
|
28432
28565
|
return "cursor/permissions.json";
|
|
28433
28566
|
}
|
|
28434
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
28435
|
-
return `cursor/agents/${
|
|
28567
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path36.sep}`)) {
|
|
28568
|
+
return `cursor/agents/${path36.basename(outcome.path)}`;
|
|
28436
28569
|
}
|
|
28437
|
-
if (outcome.path.startsWith(`${rulesRoot2}${
|
|
28438
|
-
return `cursor/rules/${
|
|
28570
|
+
if (outcome.path.startsWith(`${rulesRoot2}${path36.sep}`)) {
|
|
28571
|
+
return `cursor/rules/${path36.basename(outcome.path)}`;
|
|
28439
28572
|
}
|
|
28440
|
-
if (outcome.path.startsWith(`${skillsRoot2}${
|
|
28441
|
-
const rel =
|
|
28573
|
+
if (outcome.path.startsWith(`${skillsRoot2}${path36.sep}`)) {
|
|
28574
|
+
const rel = path36.relative(skillsRoot2, outcome.path);
|
|
28442
28575
|
return `cursor/skills/${rel}`;
|
|
28443
28576
|
}
|
|
28444
28577
|
return null;
|
|
@@ -28464,14 +28597,14 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
28464
28597
|
if (outcome.path === skillsSharedRoot) {
|
|
28465
28598
|
return "opencode/skills_shared";
|
|
28466
28599
|
}
|
|
28467
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
28468
|
-
return `opencode/agents/${
|
|
28600
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path36.sep}`)) {
|
|
28601
|
+
return `opencode/agents/${path36.basename(outcome.path)}`;
|
|
28469
28602
|
}
|
|
28470
|
-
if (outcome.path.startsWith(`${commandsRoot}${
|
|
28471
|
-
return `opencode/commands/${
|
|
28603
|
+
if (outcome.path.startsWith(`${commandsRoot}${path36.sep}`)) {
|
|
28604
|
+
return `opencode/commands/${path36.basename(outcome.path)}`;
|
|
28472
28605
|
}
|
|
28473
28606
|
if (outcome.path === configDocFile) {
|
|
28474
|
-
return `opencode/${
|
|
28607
|
+
return `opencode/${path36.basename(outcome.path)}`;
|
|
28475
28608
|
}
|
|
28476
28609
|
return null;
|
|
28477
28610
|
}
|
|
@@ -28485,17 +28618,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
28485
28618
|
if (outcome.path === skillsRoot2) {
|
|
28486
28619
|
return "copilot/skills";
|
|
28487
28620
|
}
|
|
28488
|
-
if (outcome.path.startsWith(`${agentsRoot2}${
|
|
28489
|
-
return `copilot/agents/${
|
|
28621
|
+
if (outcome.path.startsWith(`${agentsRoot2}${path36.sep}`)) {
|
|
28622
|
+
return `copilot/agents/${path36.basename(outcome.path)}`;
|
|
28490
28623
|
}
|
|
28491
|
-
if (outcome.path.startsWith(`${promptsRoot}${
|
|
28492
|
-
return `copilot/prompts/${
|
|
28624
|
+
if (outcome.path.startsWith(`${promptsRoot}${path36.sep}`)) {
|
|
28625
|
+
return `copilot/prompts/${path36.basename(outcome.path)}`;
|
|
28493
28626
|
}
|
|
28494
|
-
if (outcome.path.startsWith(`${hooksRoot}${
|
|
28495
|
-
return `copilot/hooks/${
|
|
28627
|
+
if (outcome.path.startsWith(`${hooksRoot}${path36.sep}`)) {
|
|
28628
|
+
return `copilot/hooks/${path36.basename(outcome.path)}`;
|
|
28496
28629
|
}
|
|
28497
28630
|
if (outcome.path === mcpFile2) {
|
|
28498
|
-
return `copilot/${
|
|
28631
|
+
return `copilot/${path36.basename(outcome.path)}`;
|
|
28499
28632
|
}
|
|
28500
28633
|
return null;
|
|
28501
28634
|
}
|
|
@@ -28511,17 +28644,17 @@ function syncOutcomeToManifestKey(tool, outcome, mappings, scope = "global", pro
|
|
|
28511
28644
|
if (outcome.path === skillsRoot) {
|
|
28512
28645
|
return "codex/skills";
|
|
28513
28646
|
}
|
|
28514
|
-
if (outcome.path.startsWith(`${agentsRoot}${
|
|
28515
|
-
return `codex/agents/${
|
|
28647
|
+
if (outcome.path.startsWith(`${agentsRoot}${path36.sep}`)) {
|
|
28648
|
+
return `codex/agents/${path36.basename(outcome.path)}`;
|
|
28516
28649
|
}
|
|
28517
|
-
if (outcome.path.startsWith(`${rulesRoot}${
|
|
28518
|
-
return `codex/rules/${
|
|
28650
|
+
if (outcome.path.startsWith(`${rulesRoot}${path36.sep}`)) {
|
|
28651
|
+
return `codex/rules/${path36.basename(outcome.path)}`;
|
|
28519
28652
|
}
|
|
28520
28653
|
if (outcome.path === hooksFile) {
|
|
28521
|
-
return `codex/${
|
|
28654
|
+
return `codex/${path36.basename(outcome.path)}`;
|
|
28522
28655
|
}
|
|
28523
28656
|
if (outcome.path === mcpFile) {
|
|
28524
|
-
return `codex/${
|
|
28657
|
+
return `codex/${path36.basename(outcome.path)}`;
|
|
28525
28658
|
}
|
|
28526
28659
|
return null;
|
|
28527
28660
|
}
|
|
@@ -28556,8 +28689,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
|
|
|
28556
28689
|
};
|
|
28557
28690
|
}
|
|
28558
28691
|
const placements = [];
|
|
28559
|
-
const claudeMd =
|
|
28560
|
-
if (
|
|
28692
|
+
const claudeMd = path36.join(kitInfo.path, "CLAUDE.md");
|
|
28693
|
+
if (fs36.existsSync(claudeMd)) {
|
|
28561
28694
|
placements.push({
|
|
28562
28695
|
source: claudeMd,
|
|
28563
28696
|
destination: resolvedPaths.instructions,
|
|
@@ -28573,8 +28706,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
|
|
|
28573
28706
|
rules: resolvedPaths.rules
|
|
28574
28707
|
};
|
|
28575
28708
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
28576
|
-
const componentDir =
|
|
28577
|
-
if (
|
|
28709
|
+
const componentDir = path36.join(kitInfo.path, component);
|
|
28710
|
+
if (fs36.existsSync(componentDir) && fs36.statSync(componentDir).isDirectory()) {
|
|
28578
28711
|
placements.push({
|
|
28579
28712
|
source: componentDir,
|
|
28580
28713
|
destination: targetPath,
|
|
@@ -28588,8 +28721,8 @@ function getClaudeCodePlacements(kitInfo, scope = "global", projectRoot, mapping
|
|
|
28588
28721
|
}
|
|
28589
28722
|
function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
|
|
28590
28723
|
const placements = [];
|
|
28591
|
-
const claudeMd =
|
|
28592
|
-
if (
|
|
28724
|
+
const claudeMd = path36.join(kitInfo.path, "CLAUDE.md");
|
|
28725
|
+
if (fs36.existsSync(claudeMd)) {
|
|
28593
28726
|
placements.push({
|
|
28594
28727
|
source: claudeMd,
|
|
28595
28728
|
destination: profile.instructions,
|
|
@@ -28605,8 +28738,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
|
|
|
28605
28738
|
rules: profile.rules
|
|
28606
28739
|
};
|
|
28607
28740
|
for (const [component, targetPath] of Object.entries(componentDirMap)) {
|
|
28608
|
-
const componentDir =
|
|
28609
|
-
if (
|
|
28741
|
+
const componentDir = path36.join(kitInfo.path, component);
|
|
28742
|
+
if (fs36.existsSync(componentDir) && fs36.statSync(componentDir).isDirectory()) {
|
|
28610
28743
|
placements.push({
|
|
28611
28744
|
source: componentDir,
|
|
28612
28745
|
destination: targetPath,
|
|
@@ -28620,8 +28753,8 @@ function getClaudeCodePlacementsFromProfile(kitInfo, profile) {
|
|
|
28620
28753
|
}
|
|
28621
28754
|
function collectAllFiles(kitInfo) {
|
|
28622
28755
|
const files = /* @__PURE__ */ new Map();
|
|
28623
|
-
const claudeMd =
|
|
28624
|
-
if (
|
|
28756
|
+
const claudeMd = path36.join(kitInfo.path, "CLAUDE.md");
|
|
28757
|
+
if (fs36.existsSync(claudeMd)) {
|
|
28625
28758
|
files.set("CLAUDE.md", claudeMd);
|
|
28626
28759
|
}
|
|
28627
28760
|
for (const [component, reconciliation] of Object.entries(
|
|
@@ -28631,15 +28764,15 @@ function collectAllFiles(kitInfo) {
|
|
|
28631
28764
|
const missingSet = new Set(reconciliation.missing);
|
|
28632
28765
|
for (const entry of reconciliation.declared) {
|
|
28633
28766
|
if (missingSet.has(entry)) continue;
|
|
28634
|
-
const relPath = isSkills ?
|
|
28635
|
-
files.set(relPath,
|
|
28767
|
+
const relPath = isSkills ? path36.join(component, entry) : path36.join(component, `${entry}.md`);
|
|
28768
|
+
files.set(relPath, path36.join(kitInfo.path, relPath));
|
|
28636
28769
|
}
|
|
28637
28770
|
}
|
|
28638
28771
|
return files;
|
|
28639
28772
|
}
|
|
28640
28773
|
function isSymlink2(p) {
|
|
28641
28774
|
try {
|
|
28642
|
-
return
|
|
28775
|
+
return fs36.lstatSync(p).isSymbolicLink();
|
|
28643
28776
|
} catch {
|
|
28644
28777
|
return false;
|
|
28645
28778
|
}
|
|
@@ -28684,14 +28817,14 @@ async function runKitUpdateCommand(options, logger) {
|
|
|
28684
28817
|
}
|
|
28685
28818
|
|
|
28686
28819
|
// src/commands/list.ts
|
|
28687
|
-
import
|
|
28820
|
+
import path37 from "path";
|
|
28688
28821
|
function runListCommand(options, logger) {
|
|
28689
28822
|
let searchPaths = [];
|
|
28690
|
-
let directKitPath = options.kitPath ?
|
|
28823
|
+
let directKitPath = options.kitPath ? path37.resolve(options.kitPath) : void 0;
|
|
28691
28824
|
try {
|
|
28692
28825
|
const { config, configDir } = resolveConfig(options.config);
|
|
28693
28826
|
searchPaths = config.kitSearchPaths ?? [
|
|
28694
|
-
|
|
28827
|
+
path37.join(configDir, "operating-kits")
|
|
28695
28828
|
];
|
|
28696
28829
|
directKitPath = directKitPath ?? config.kitPath;
|
|
28697
28830
|
} catch (err) {
|
|
@@ -28766,7 +28899,7 @@ function withDirectKit(kits, directKitPath) {
|
|
|
28766
28899
|
return kits;
|
|
28767
28900
|
}
|
|
28768
28901
|
const directKit = loadKit(directKitPath);
|
|
28769
|
-
if (kits.some((kit) =>
|
|
28902
|
+
if (kits.some((kit) => path37.resolve(kit.path) === directKit.path)) {
|
|
28770
28903
|
return kits;
|
|
28771
28904
|
}
|
|
28772
28905
|
return [...kits, directKit];
|
|
@@ -28774,12 +28907,12 @@ function withDirectKit(kits, directKitPath) {
|
|
|
28774
28907
|
|
|
28775
28908
|
// src/commands/probe.ts
|
|
28776
28909
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
28777
|
-
import
|
|
28778
|
-
import
|
|
28910
|
+
import fs37 from "fs";
|
|
28911
|
+
import path38 from "path";
|
|
28779
28912
|
function runProbeCommand(options, logger) {
|
|
28780
28913
|
const { config, configDir, sourceRoot } = resolveRuntime(options, import.meta.url);
|
|
28781
28914
|
const platformPaths = readYamlObject(
|
|
28782
|
-
|
|
28915
|
+
path38.join(
|
|
28783
28916
|
resolveConfiguredPath(config.mappings, configDir, sourceRoot, "mappings"),
|
|
28784
28917
|
"platform-paths.yaml"
|
|
28785
28918
|
)
|
|
@@ -28813,12 +28946,12 @@ function toProbeRow(target, key, rawPath) {
|
|
|
28813
28946
|
const resolved = resolveTargetPath(rawPath);
|
|
28814
28947
|
let accessible = false;
|
|
28815
28948
|
try {
|
|
28816
|
-
|
|
28949
|
+
fs37.accessSync(resolved);
|
|
28817
28950
|
accessible = true;
|
|
28818
28951
|
} catch {
|
|
28819
28952
|
accessible = false;
|
|
28820
28953
|
}
|
|
28821
|
-
return { target, key, path: resolved, exists:
|
|
28954
|
+
return { target, key, path: resolved, exists: fs37.existsSync(resolved), accessible };
|
|
28822
28955
|
}
|
|
28823
28956
|
function codexRuntimeProbeRows() {
|
|
28824
28957
|
const rows = commandProbeRows("codex", "binary", process.platform === "win32" ? "where.exe" : "which", ["codex"]);
|
|
@@ -28829,7 +28962,7 @@ function codexRuntimeProbeRows() {
|
|
|
28829
28962
|
["binary_snap", "/snap/bin/codex"],
|
|
28830
28963
|
["binary_flatpak", "/var/lib/flatpak/exports/bin/codex"]
|
|
28831
28964
|
]) {
|
|
28832
|
-
if (
|
|
28965
|
+
if (fs37.existsSync(candidatePath)) {
|
|
28833
28966
|
rows.push(toProbeRow("codex", key, candidatePath));
|
|
28834
28967
|
}
|
|
28835
28968
|
}
|
|
@@ -28845,8 +28978,8 @@ function commandProbeRows(target, key, command, args) {
|
|
|
28845
28978
|
|
|
28846
28979
|
// src/commands/status.ts
|
|
28847
28980
|
import crypto10 from "crypto";
|
|
28848
|
-
import
|
|
28849
|
-
import
|
|
28981
|
+
import fs38 from "fs";
|
|
28982
|
+
import path39 from "path";
|
|
28850
28983
|
function runStatusCommand(options, logger) {
|
|
28851
28984
|
const { config, configDir, sourceRoot } = resolveRuntime(
|
|
28852
28985
|
options,
|
|
@@ -28925,21 +29058,21 @@ function classifyCodexFiles(config, sourceRoot, configDir) {
|
|
|
28925
29058
|
rules: paths.rules
|
|
28926
29059
|
};
|
|
28927
29060
|
const rules = compileRules(
|
|
28928
|
-
|
|
29061
|
+
path39.join(sourceRoot, config.source.rules),
|
|
28929
29062
|
"codex",
|
|
28930
29063
|
mappings,
|
|
28931
29064
|
createLossReport()
|
|
28932
29065
|
);
|
|
28933
|
-
const instructionsSource =
|
|
29066
|
+
const instructionsSource = fs38.readFileSync(path39.join(sourceRoot, config.source.instructions), "utf8").trim();
|
|
28934
29067
|
const composedInstructions = `${instructionsSource}
|
|
28935
29068
|
|
|
28936
29069
|
--- tangyr managed rules ---
|
|
28937
29070
|
${rules.agentsAppendix}`.trim();
|
|
28938
29071
|
const agentFiles = ts(
|
|
28939
|
-
|
|
29072
|
+
path39.join(sourceRoot, config.source.agents, "*.md")
|
|
28940
29073
|
).sort();
|
|
28941
|
-
const hooksSource =
|
|
28942
|
-
const mcpSource =
|
|
29074
|
+
const hooksSource = path39.join(sourceRoot, config.source.hooks, "hooks.json");
|
|
29075
|
+
const mcpSource = path39.join(sourceRoot, config.source.mcp);
|
|
28943
29076
|
const ruleRows = rules.dotRulesFiles.length === 0 ? [
|
|
28944
29077
|
{
|
|
28945
29078
|
component: "rules",
|
|
@@ -28950,7 +29083,7 @@ ${rules.agentsAppendix}`.trim();
|
|
|
28950
29083
|
] : rules.dotRulesFiles.map(
|
|
28951
29084
|
(ruleFile) => classifyCompiledFile(
|
|
28952
29085
|
`rules/${ruleFile.name}`,
|
|
28953
|
-
|
|
29086
|
+
path39.join(resolveTargetPath(codexPaths.rules), ruleFile.name),
|
|
28954
29087
|
"codex",
|
|
28955
29088
|
void 0,
|
|
28956
29089
|
config,
|
|
@@ -28968,10 +29101,10 @@ ${rules.agentsAppendix}`.trim();
|
|
|
28968
29101
|
),
|
|
28969
29102
|
...agentFiles.map(
|
|
28970
29103
|
(agentFile) => classifyCompiledFile(
|
|
28971
|
-
`agents/${
|
|
28972
|
-
|
|
29104
|
+
`agents/${path39.basename(agentFile, ".md")}`,
|
|
29105
|
+
path39.join(
|
|
28973
29106
|
resolveTargetPath(codexPaths.agents),
|
|
28974
|
-
`${
|
|
29107
|
+
`${path39.basename(agentFile, ".md")}.toml`
|
|
28975
29108
|
),
|
|
28976
29109
|
"codex",
|
|
28977
29110
|
computeSourceHash(agentFile),
|
|
@@ -28995,11 +29128,11 @@ ${rules.agentsAppendix}`.trim();
|
|
|
28995
29128
|
config,
|
|
28996
29129
|
sourceRoot
|
|
28997
29130
|
),
|
|
28998
|
-
|
|
29131
|
+
fs38.existsSync(hooksSource) ? classifyCodexHooksFile(resolveTargetPath(codexPaths.hooksSharedFile)) : notConfiguredRow(
|
|
28999
29132
|
"hooks",
|
|
29000
29133
|
resolveTargetPath(codexPaths.hooksSharedFile)
|
|
29001
29134
|
),
|
|
29002
|
-
|
|
29135
|
+
fs38.existsSync(mcpSource) ? classifyCompiledFile(
|
|
29003
29136
|
"mcp",
|
|
29004
29137
|
resolveTargetPath(codexPaths.mcpSharedFile),
|
|
29005
29138
|
"codex",
|
|
@@ -29019,7 +29152,7 @@ function classifyCodexHooksFile(filePath) {
|
|
|
29019
29152
|
conformant: true
|
|
29020
29153
|
};
|
|
29021
29154
|
}
|
|
29022
|
-
if (!
|
|
29155
|
+
if (!fs38.existsSync(filePath)) {
|
|
29023
29156
|
return {
|
|
29024
29157
|
component: "hooks",
|
|
29025
29158
|
className: "missing",
|
|
@@ -29051,20 +29184,20 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
|
|
|
29051
29184
|
mcpSharedFile: paths.mcp_shared_file
|
|
29052
29185
|
};
|
|
29053
29186
|
const agentFiles = ts(
|
|
29054
|
-
|
|
29187
|
+
path39.join(sourceRoot, config.source.agents, "*.md")
|
|
29055
29188
|
).sort();
|
|
29056
29189
|
const commandFiles = ts(
|
|
29057
|
-
|
|
29190
|
+
path39.join(sourceRoot, config.source.commands, "*.md")
|
|
29058
29191
|
).sort();
|
|
29059
|
-
const hooksSource =
|
|
29060
|
-
const mcpSource =
|
|
29192
|
+
const hooksSource = path39.join(sourceRoot, config.source.hooks, "hooks.json");
|
|
29193
|
+
const mcpSource = path39.join(sourceRoot, config.source.mcp);
|
|
29061
29194
|
return [
|
|
29062
29195
|
...agentFiles.map(
|
|
29063
29196
|
(agentFile) => classifyCompiledFile(
|
|
29064
|
-
`agents/${
|
|
29065
|
-
|
|
29197
|
+
`agents/${path39.basename(agentFile, ".md")}`,
|
|
29198
|
+
path39.join(
|
|
29066
29199
|
resolveTargetPath(copilotPaths.agents),
|
|
29067
|
-
`${
|
|
29200
|
+
`${path39.basename(agentFile, ".md")}.agent.md`
|
|
29068
29201
|
),
|
|
29069
29202
|
"copilot",
|
|
29070
29203
|
computeSourceHash(agentFile),
|
|
@@ -29081,10 +29214,10 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
|
|
|
29081
29214
|
),
|
|
29082
29215
|
...commandFiles.map(
|
|
29083
29216
|
(commandFile) => classifyCompiledFile(
|
|
29084
|
-
`commands/${
|
|
29085
|
-
|
|
29217
|
+
`commands/${path39.basename(commandFile, ".md")}`,
|
|
29218
|
+
path39.join(
|
|
29086
29219
|
resolveTargetPath(copilotPaths.prompts),
|
|
29087
|
-
`${
|
|
29220
|
+
`${path39.basename(commandFile, ".md")}.prompt.md`
|
|
29088
29221
|
),
|
|
29089
29222
|
"copilot",
|
|
29090
29223
|
computeSourceHash(commandFile),
|
|
@@ -29102,9 +29235,9 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
|
|
|
29102
29235
|
config,
|
|
29103
29236
|
sourceRoot
|
|
29104
29237
|
),
|
|
29105
|
-
|
|
29238
|
+
fs38.existsSync(hooksSource) ? classifyCompiledFile(
|
|
29106
29239
|
"hooks",
|
|
29107
|
-
|
|
29240
|
+
path39.join(
|
|
29108
29241
|
resolveTargetPath(copilotPaths.hooks),
|
|
29109
29242
|
"tangyr-managed.json"
|
|
29110
29243
|
),
|
|
@@ -29114,12 +29247,12 @@ function classifyCopilotFiles(config, sourceRoot, configDir) {
|
|
|
29114
29247
|
sourceRoot
|
|
29115
29248
|
) : notConfiguredRow(
|
|
29116
29249
|
"hooks",
|
|
29117
|
-
|
|
29250
|
+
path39.join(
|
|
29118
29251
|
resolveTargetPath(copilotPaths.hooks),
|
|
29119
29252
|
"tangyr-managed.json"
|
|
29120
29253
|
)
|
|
29121
29254
|
),
|
|
29122
|
-
|
|
29255
|
+
fs38.existsSync(mcpSource) ? classifyCompiledFile(
|
|
29123
29256
|
"mcp",
|
|
29124
29257
|
resolveTargetPath(copilotPaths.mcpSharedFile),
|
|
29125
29258
|
"copilot",
|
|
@@ -29139,7 +29272,7 @@ function notConfiguredRow(component, filePath) {
|
|
|
29139
29272
|
}
|
|
29140
29273
|
function classifyDirectArtifact(artifact, config, sourceRoot) {
|
|
29141
29274
|
const artifactClass = classifyArtifact(artifact.path, config, sourceRoot);
|
|
29142
|
-
const sourcePath = artifact.sourceKey ?
|
|
29275
|
+
const sourcePath = artifact.sourceKey ? path39.resolve(sourceRoot, config.source[artifact.sourceKey]) : void 0;
|
|
29143
29276
|
if (artifactClass === "managed-symlink" && sourcePath && !isSymlinkCurrent(artifact.path, sourcePath)) {
|
|
29144
29277
|
return {
|
|
29145
29278
|
component: artifact.component,
|
|
@@ -29228,9 +29361,9 @@ function classifyClaudeSharedFiles(config, sourceRoot) {
|
|
|
29228
29361
|
classifyHooks(settingsPath),
|
|
29229
29362
|
classifySettings(
|
|
29230
29363
|
settingsPath,
|
|
29231
|
-
|
|
29364
|
+
path39.resolve(sourceRoot, config.source.settings)
|
|
29232
29365
|
),
|
|
29233
|
-
classifyMcp(claudeJsonPath,
|
|
29366
|
+
classifyMcp(claudeJsonPath, path39.resolve(sourceRoot, config.source.mcp))
|
|
29234
29367
|
];
|
|
29235
29368
|
}
|
|
29236
29369
|
function classifyHooks(filePath) {
|
|
@@ -29294,14 +29427,14 @@ function classifyMcp(filePath, sourcePath) {
|
|
|
29294
29427
|
}
|
|
29295
29428
|
function isSymlinkCurrent(linkPath, sourcePath) {
|
|
29296
29429
|
try {
|
|
29297
|
-
return
|
|
29430
|
+
return fs38.realpathSync(linkPath) === fs38.realpathSync(sourcePath);
|
|
29298
29431
|
} catch {
|
|
29299
29432
|
return false;
|
|
29300
29433
|
}
|
|
29301
29434
|
}
|
|
29302
29435
|
function isCompiledCurrent6(filePath, sourcePath) {
|
|
29303
29436
|
try {
|
|
29304
|
-
const marker = extractProvenanceMarker(
|
|
29437
|
+
const marker = extractProvenanceMarker(fs38.readFileSync(filePath, "utf8"));
|
|
29305
29438
|
return marker?.hash === computeSourceHash(sourcePath) && marker.target === "claude-code";
|
|
29306
29439
|
} catch {
|
|
29307
29440
|
return false;
|
|
@@ -29331,7 +29464,7 @@ function classifyCompiledFile(component, filePath, target, expectedHash, config,
|
|
|
29331
29464
|
}
|
|
29332
29465
|
function readCompiledContent(filePath) {
|
|
29333
29466
|
try {
|
|
29334
|
-
return
|
|
29467
|
+
return fs38.readFileSync(filePath, "utf8");
|
|
29335
29468
|
} catch {
|
|
29336
29469
|
return null;
|
|
29337
29470
|
}
|
|
@@ -29362,8 +29495,8 @@ function hashString6(value) {
|
|
|
29362
29495
|
}
|
|
29363
29496
|
|
|
29364
29497
|
// src/commands/sync.ts
|
|
29365
|
-
import
|
|
29366
|
-
import
|
|
29498
|
+
import fs41 from "fs";
|
|
29499
|
+
import path42 from "path";
|
|
29367
29500
|
|
|
29368
29501
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
29369
29502
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -29861,8 +29994,8 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
29861
29994
|
var source_default = chalk;
|
|
29862
29995
|
|
|
29863
29996
|
// src/adapters/claude-code.ts
|
|
29864
|
-
import
|
|
29865
|
-
import
|
|
29997
|
+
import fs40 from "fs";
|
|
29998
|
+
import path41 from "path";
|
|
29866
29999
|
|
|
29867
30000
|
// src/core/shim.ts
|
|
29868
30001
|
import crypto11 from "crypto";
|
|
@@ -29879,12 +30012,12 @@ ${SHIM_BODY}`;
|
|
|
29879
30012
|
|
|
29880
30013
|
// src/compiler/hook-components.ts
|
|
29881
30014
|
var import_yaml11 = __toESM(require_dist(), 1);
|
|
29882
|
-
import
|
|
29883
|
-
import
|
|
30015
|
+
import fs39 from "fs";
|
|
30016
|
+
import path40 from "path";
|
|
29884
30017
|
function parseHookDeclaration(filePath) {
|
|
29885
30018
|
let raw;
|
|
29886
30019
|
try {
|
|
29887
|
-
raw =
|
|
30020
|
+
raw = fs39.readFileSync(filePath, "utf8");
|
|
29888
30021
|
} catch {
|
|
29889
30022
|
return null;
|
|
29890
30023
|
}
|
|
@@ -29967,9 +30100,9 @@ function synthesizeHooksJson(declarations) {
|
|
|
29967
30100
|
return { hooks };
|
|
29968
30101
|
}
|
|
29969
30102
|
function loadSourceHooks(hooksDir, hookNames) {
|
|
29970
|
-
const hooksJsonPath =
|
|
29971
|
-
if (
|
|
29972
|
-
const raw =
|
|
30103
|
+
const hooksJsonPath = path40.join(hooksDir, "hooks.json");
|
|
30104
|
+
if (fs39.existsSync(hooksJsonPath)) {
|
|
30105
|
+
const raw = fs39.readFileSync(hooksJsonPath, "utf8");
|
|
29973
30106
|
return JSON.parse(raw);
|
|
29974
30107
|
}
|
|
29975
30108
|
const declarations = loadHookDeclarations(hooksDir, hookNames);
|
|
@@ -29980,14 +30113,14 @@ function loadHookDeclarations(hooksDir, hookNames) {
|
|
|
29980
30113
|
if (hookNames && hookNames.length > 0) {
|
|
29981
30114
|
names = hookNames;
|
|
29982
30115
|
} else {
|
|
29983
|
-
if (!
|
|
30116
|
+
if (!fs39.existsSync(hooksDir) || !fs39.statSync(hooksDir).isDirectory()) {
|
|
29984
30117
|
return [];
|
|
29985
30118
|
}
|
|
29986
|
-
names =
|
|
30119
|
+
names = fs39.readdirSync(hooksDir).filter((f) => f.endsWith(".md") && !f.startsWith(".")).map((f) => f.slice(0, -3)).sort();
|
|
29987
30120
|
}
|
|
29988
30121
|
const declarations = [];
|
|
29989
30122
|
for (const name of names) {
|
|
29990
|
-
const filePath =
|
|
30123
|
+
const filePath = path40.join(hooksDir, `${name}.md`);
|
|
29991
30124
|
const decl = parseHookDeclaration(filePath);
|
|
29992
30125
|
if (decl) {
|
|
29993
30126
|
declarations.push(decl);
|
|
@@ -30111,7 +30244,7 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
30111
30244
|
}
|
|
30112
30245
|
if (!shouldSkipComponent6(options, "instructions") && manifest && scopePath) {
|
|
30113
30246
|
const shimPath = profile.instructions_shim;
|
|
30114
|
-
const agentsMdPath =
|
|
30247
|
+
const agentsMdPath = path41.resolve(sourceRoot, config.source.instructions);
|
|
30115
30248
|
if (!options.dryRun) {
|
|
30116
30249
|
applyClaudeCodeShimUpgrade(
|
|
30117
30250
|
shimPath,
|
|
@@ -30165,13 +30298,13 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
|
|
|
30165
30298
|
}
|
|
30166
30299
|
function syncProviderLoss2(config, sourceRoot, mappings, lossReport) {
|
|
30167
30300
|
if (!mappings.modelTiers.custom_provider) return;
|
|
30168
|
-
const agentsDir =
|
|
30169
|
-
if (!
|
|
30170
|
-
for (const agentFile of ts(
|
|
30301
|
+
const agentsDir = path41.join(sourceRoot, config.source.agents);
|
|
30302
|
+
if (!fs40.existsSync(agentsDir)) return;
|
|
30303
|
+
for (const agentFile of ts(path41.join(agentsDir, "*.md")).sort()) {
|
|
30171
30304
|
const { data } = parseMarkdownFrontmatter(agentFile);
|
|
30172
30305
|
const hasProvider = typeof data.provider === "string" || typeof data.provider === "object" && data.provider !== null && Object.keys(data.provider).length > 0;
|
|
30173
30306
|
if (hasProvider) {
|
|
30174
|
-
const basename =
|
|
30307
|
+
const basename = path41.basename(agentFile);
|
|
30175
30308
|
addLoss(lossReport, "claude-code", "agents", {
|
|
30176
30309
|
source: `agents/${basename}`,
|
|
30177
30310
|
fields: [
|
|
@@ -30196,19 +30329,19 @@ function shouldSkipComponent6(options, component) {
|
|
|
30196
30329
|
function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath, logger) {
|
|
30197
30330
|
const expectedBodyHash = shimBodyHash();
|
|
30198
30331
|
const shimContent = buildAgentsMdShim(shimPath, agentsMdPath, "claude-code");
|
|
30199
|
-
if (!
|
|
30332
|
+
if (!fs40.existsSync(shimPath)) {
|
|
30200
30333
|
manifest.artifacts.push({
|
|
30201
|
-
relativePath:
|
|
30334
|
+
relativePath: path41.relative(scopePath, shimPath),
|
|
30202
30335
|
hash: expectedBodyHash,
|
|
30203
30336
|
origin: "tangyr-managed"
|
|
30204
30337
|
});
|
|
30205
30338
|
writeManifest(scopePath, manifest);
|
|
30206
|
-
|
|
30207
|
-
|
|
30339
|
+
fs40.mkdirSync(path41.dirname(shimPath), { recursive: true });
|
|
30340
|
+
fs40.writeFileSync(shimPath, shimContent);
|
|
30208
30341
|
logger?.verbose(`instructions-shim: wrote @AGENTS.md shim -> ${shimPath}`);
|
|
30209
30342
|
return;
|
|
30210
30343
|
}
|
|
30211
|
-
const existing =
|
|
30344
|
+
const existing = fs40.readFileSync(shimPath, "utf8");
|
|
30212
30345
|
const firstNonEmptyLine = existing.split("\n").find((l) => l.trim().length > 0) ?? "";
|
|
30213
30346
|
const marker = extractProvenanceMarker(firstNonEmptyLine);
|
|
30214
30347
|
if (marker !== null && marker.hash === expectedBodyHash) {
|
|
@@ -30219,21 +30352,21 @@ function applyClaudeCodeShimUpgrade(shimPath, agentsMdPath, manifest, scopePath,
|
|
|
30219
30352
|
}
|
|
30220
30353
|
backupFile(shimPath, manifest);
|
|
30221
30354
|
writeManifest(scopePath, manifest);
|
|
30222
|
-
|
|
30355
|
+
fs40.writeFileSync(shimPath, shimContent);
|
|
30223
30356
|
manifest.artifacts.push({
|
|
30224
|
-
relativePath:
|
|
30357
|
+
relativePath: path41.relative(scopePath, shimPath),
|
|
30225
30358
|
hash: expectedBodyHash,
|
|
30226
30359
|
origin: "tangyr-managed"
|
|
30227
30360
|
});
|
|
30228
30361
|
logger?.verbose(`instructions-shim: backed up and replaced -> ${shimPath}`);
|
|
30229
30362
|
}
|
|
30230
30363
|
function syncDirectComponent(config, sourceRoot, options, logger, directComponent, manifest, scopePath) {
|
|
30231
|
-
const source =
|
|
30364
|
+
const source = path41.resolve(
|
|
30232
30365
|
sourceRoot,
|
|
30233
30366
|
config.source[directComponent.sourceKey]
|
|
30234
30367
|
);
|
|
30235
30368
|
const destination = directComponent.destination;
|
|
30236
|
-
if (!
|
|
30369
|
+
if (!fs40.existsSync(source)) {
|
|
30237
30370
|
return skippedMissingSource6(directComponent.component, source);
|
|
30238
30371
|
}
|
|
30239
30372
|
if (options.dryRun) {
|
|
@@ -30255,7 +30388,7 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
30255
30388
|
};
|
|
30256
30389
|
}
|
|
30257
30390
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
30258
|
-
|
|
30391
|
+
fs40.unlinkSync(destination);
|
|
30259
30392
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
30260
30393
|
return {
|
|
30261
30394
|
component: directComponent.component,
|
|
@@ -30263,9 +30396,9 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
30263
30396
|
path: destination
|
|
30264
30397
|
};
|
|
30265
30398
|
} else if (artifactClass === "managed-symlink") {
|
|
30266
|
-
|
|
30399
|
+
fs40.unlinkSync(destination);
|
|
30267
30400
|
}
|
|
30268
|
-
ensureDir(
|
|
30401
|
+
ensureDir(path41.dirname(destination));
|
|
30269
30402
|
createRelativeSymlink(source, destination, directComponent.type, {
|
|
30270
30403
|
logger,
|
|
30271
30404
|
provenanceMarker: directComponent.type === "file" ? formatProvenanceMarker(
|
|
@@ -30282,8 +30415,8 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
|
|
|
30282
30415
|
};
|
|
30283
30416
|
}
|
|
30284
30417
|
function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination, manifest, scopePath) {
|
|
30285
|
-
const source =
|
|
30286
|
-
if (!
|
|
30418
|
+
const source = path41.resolve(sourceRoot, config.source.skills);
|
|
30419
|
+
if (!fs40.existsSync(source)) {
|
|
30287
30420
|
return [skippedMissingSource6("skills", source)];
|
|
30288
30421
|
}
|
|
30289
30422
|
const declaredNames = resolveKitSkillNames(sourceRoot);
|
|
@@ -30293,7 +30426,7 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
30293
30426
|
if (isLegacyWholesaleSymlink) {
|
|
30294
30427
|
for (const name of foreignSkillNames(source, declaredNames)) {
|
|
30295
30428
|
logger.info(
|
|
30296
|
-
`[dry-run] skills: migrate foreign skill ${
|
|
30429
|
+
`[dry-run] skills: migrate foreign skill ${path41.join(source, name)} -> ${path41.join(destination, name)}`
|
|
30297
30430
|
);
|
|
30298
30431
|
}
|
|
30299
30432
|
logger.info(
|
|
@@ -30301,9 +30434,9 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
30301
30434
|
);
|
|
30302
30435
|
}
|
|
30303
30436
|
for (const name of declaredNames ?? listSkillDirNames(source)) {
|
|
30304
|
-
const skillDestination =
|
|
30437
|
+
const skillDestination = path41.join(destination, name);
|
|
30305
30438
|
logger.info(
|
|
30306
|
-
`[dry-run] skills: symlink ${
|
|
30439
|
+
`[dry-run] skills: symlink ${path41.join(source, name)} -> ${skillDestination}`
|
|
30307
30440
|
);
|
|
30308
30441
|
outcomes2.push({
|
|
30309
30442
|
component: "skills",
|
|
@@ -30336,9 +30469,9 @@ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination,
|
|
|
30336
30469
|
return outcomes;
|
|
30337
30470
|
}
|
|
30338
30471
|
function syncSingleSkill(config, sourceRoot, options, logger, source, destination, name, manifest, scopePath) {
|
|
30339
|
-
const skillSource =
|
|
30340
|
-
const skillDestination =
|
|
30341
|
-
if (!
|
|
30472
|
+
const skillSource = path41.join(source, name);
|
|
30473
|
+
const skillDestination = path41.join(destination, name);
|
|
30474
|
+
if (!fs40.existsSync(skillSource)) {
|
|
30342
30475
|
return skippedMissingSource6("skills", skillSource);
|
|
30343
30476
|
}
|
|
30344
30477
|
const artifactClass = classifyArtifact(skillDestination, config, sourceRoot);
|
|
@@ -30350,7 +30483,7 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
|
|
|
30350
30483
|
};
|
|
30351
30484
|
}
|
|
30352
30485
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
|
|
30353
|
-
|
|
30486
|
+
fs40.unlinkSync(skillDestination);
|
|
30354
30487
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict6(
|
|
30355
30488
|
skillDestination,
|
|
30356
30489
|
config,
|
|
@@ -30361,25 +30494,25 @@ function syncSingleSkill(config, sourceRoot, options, logger, source, destinatio
|
|
|
30361
30494
|
)) {
|
|
30362
30495
|
return { component: "skills", status: "conflict", path: skillDestination };
|
|
30363
30496
|
} else if (artifactClass === "managed-symlink") {
|
|
30364
|
-
|
|
30497
|
+
fs40.unlinkSync(skillDestination);
|
|
30365
30498
|
}
|
|
30366
30499
|
createRelativeSymlink(skillSource, skillDestination, "dir");
|
|
30367
30500
|
return { component: "skills", status: "success", path: skillDestination };
|
|
30368
30501
|
}
|
|
30369
30502
|
function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
|
|
30370
30503
|
const foreignNames = foreignSkillNames(source, declaredNames);
|
|
30371
|
-
|
|
30504
|
+
fs40.unlinkSync(destination);
|
|
30372
30505
|
ensureDir(destination);
|
|
30373
30506
|
for (const name of foreignNames) {
|
|
30374
|
-
const from =
|
|
30375
|
-
const to =
|
|
30376
|
-
if (
|
|
30507
|
+
const from = path41.join(source, name);
|
|
30508
|
+
const to = path41.join(destination, name);
|
|
30509
|
+
if (fs40.existsSync(to)) {
|
|
30377
30510
|
logger.warn(
|
|
30378
30511
|
`skills migration: ${to} already exists \u2014 skipping move of ${from} to avoid overwrite`
|
|
30379
30512
|
);
|
|
30380
30513
|
continue;
|
|
30381
30514
|
}
|
|
30382
|
-
|
|
30515
|
+
fs40.renameSync(from, to);
|
|
30383
30516
|
logger.info(`skills migration: moved ${from} -> ${to}`);
|
|
30384
30517
|
}
|
|
30385
30518
|
}
|
|
@@ -30391,21 +30524,21 @@ function foreignSkillNames(source, declaredNames) {
|
|
|
30391
30524
|
return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
|
|
30392
30525
|
}
|
|
30393
30526
|
function listSkillDirNames(dir) {
|
|
30394
|
-
if (!
|
|
30527
|
+
if (!fs40.existsSync(dir)) {
|
|
30395
30528
|
return [];
|
|
30396
30529
|
}
|
|
30397
|
-
return
|
|
30530
|
+
return fs40.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
30398
30531
|
}
|
|
30399
30532
|
function isSymlinkPath(filePath) {
|
|
30400
30533
|
try {
|
|
30401
|
-
return
|
|
30534
|
+
return fs40.lstatSync(filePath).isSymbolicLink();
|
|
30402
30535
|
} catch {
|
|
30403
30536
|
return false;
|
|
30404
30537
|
}
|
|
30405
30538
|
}
|
|
30406
30539
|
function syncHookScriptsBridge(config, sourceRoot, options, logger, destination, manifest, scopePath) {
|
|
30407
|
-
const source =
|
|
30408
|
-
if (!
|
|
30540
|
+
const source = path41.resolve(sourceRoot, config.source.hooks);
|
|
30541
|
+
if (!fs40.existsSync(source)) {
|
|
30409
30542
|
return skippedMissingSource6("hooks", source);
|
|
30410
30543
|
}
|
|
30411
30544
|
if (options.dryRun) {
|
|
@@ -30417,13 +30550,13 @@ function syncHookScriptsBridge(config, sourceRoot, options, logger, destination,
|
|
|
30417
30550
|
return { component: "hooks", status: "skipped-current", path: destination };
|
|
30418
30551
|
}
|
|
30419
30552
|
if (artifactClass === "managed-stale" && isOurStaleSymlink(destination, /* @__PURE__ */ new Set([destination]), config)) {
|
|
30420
|
-
|
|
30553
|
+
fs40.unlinkSync(destination);
|
|
30421
30554
|
} else if (artifactClass === "unmanaged-conflict" && !handleConflict6(destination, config, options, logger, manifest, scopePath)) {
|
|
30422
30555
|
return { component: "hooks", status: "conflict", path: destination };
|
|
30423
30556
|
} else if (artifactClass === "managed-symlink") {
|
|
30424
|
-
|
|
30557
|
+
fs40.unlinkSync(destination);
|
|
30425
30558
|
}
|
|
30426
|
-
ensureDir(
|
|
30559
|
+
ensureDir(path41.dirname(destination));
|
|
30427
30560
|
createRelativeSymlink(source, destination, "dir");
|
|
30428
30561
|
return { component: "hooks", status: "success", path: destination };
|
|
30429
30562
|
}
|
|
@@ -30446,7 +30579,7 @@ function syncHooks6(config, sourceRoot, options, logger, destination) {
|
|
|
30446
30579
|
destination,
|
|
30447
30580
|
settings,
|
|
30448
30581
|
stringifyJson3,
|
|
30449
|
-
!
|
|
30582
|
+
!fs40.existsSync(destination),
|
|
30450
30583
|
logger
|
|
30451
30584
|
);
|
|
30452
30585
|
return {
|
|
@@ -30456,8 +30589,8 @@ function syncHooks6(config, sourceRoot, options, logger, destination) {
|
|
|
30456
30589
|
};
|
|
30457
30590
|
}
|
|
30458
30591
|
function syncMcp6(config, sourceRoot, options, logger, destination) {
|
|
30459
|
-
const source =
|
|
30460
|
-
if (!
|
|
30592
|
+
const source = path41.resolve(sourceRoot, config.source.mcp);
|
|
30593
|
+
if (!fs40.existsSync(source)) {
|
|
30461
30594
|
return skippedMissingSource6("mcp", source);
|
|
30462
30595
|
}
|
|
30463
30596
|
if (options.dryRun) {
|
|
@@ -30482,7 +30615,7 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
|
|
|
30482
30615
|
destination,
|
|
30483
30616
|
hostConfig,
|
|
30484
30617
|
stringifyJson3,
|
|
30485
|
-
!
|
|
30618
|
+
!fs40.existsSync(destination),
|
|
30486
30619
|
logger
|
|
30487
30620
|
);
|
|
30488
30621
|
return {
|
|
@@ -30492,8 +30625,8 @@ function syncMcp6(config, sourceRoot, options, logger, destination) {
|
|
|
30492
30625
|
};
|
|
30493
30626
|
}
|
|
30494
30627
|
function syncSettings2(config, sourceRoot, options, logger, destination) {
|
|
30495
|
-
const source =
|
|
30496
|
-
if (!
|
|
30628
|
+
const source = path41.resolve(sourceRoot, config.source.settings);
|
|
30629
|
+
if (!fs40.existsSync(source)) {
|
|
30497
30630
|
return skippedMissingSource6("settings", source);
|
|
30498
30631
|
}
|
|
30499
30632
|
if (options.dryRun) {
|
|
@@ -30511,7 +30644,7 @@ function syncSettings2(config, sourceRoot, options, logger, destination) {
|
|
|
30511
30644
|
destination,
|
|
30512
30645
|
settings,
|
|
30513
30646
|
stringifyJson3,
|
|
30514
|
-
!
|
|
30647
|
+
!fs40.existsSync(destination),
|
|
30515
30648
|
logger
|
|
30516
30649
|
);
|
|
30517
30650
|
return {
|
|
@@ -30536,11 +30669,11 @@ function handleConflict6(destination, config, options, logger, manifest, scopePa
|
|
|
30536
30669
|
backupFile(destination, manifest);
|
|
30537
30670
|
writeManifest(scopePath, manifest);
|
|
30538
30671
|
} else {
|
|
30539
|
-
|
|
30672
|
+
fs40.renameSync(destination, `${destination}.bak.${Date.now()}`);
|
|
30540
30673
|
}
|
|
30541
30674
|
return true;
|
|
30542
30675
|
}
|
|
30543
|
-
|
|
30676
|
+
fs40.rmSync(destination, { recursive: true, force: true });
|
|
30544
30677
|
return true;
|
|
30545
30678
|
}
|
|
30546
30679
|
function skippedMissingSource6(component, source) {
|
|
@@ -30552,16 +30685,16 @@ function skippedMissingSource6(component, source) {
|
|
|
30552
30685
|
}
|
|
30553
30686
|
function isSymlinkTo6(linkPath, source) {
|
|
30554
30687
|
try {
|
|
30555
|
-
return
|
|
30688
|
+
return fs40.realpathSync(linkPath) === fs40.realpathSync(source);
|
|
30556
30689
|
} catch {
|
|
30557
30690
|
return false;
|
|
30558
30691
|
}
|
|
30559
30692
|
}
|
|
30560
30693
|
function readJsonObject4(filePath) {
|
|
30561
|
-
if (!
|
|
30694
|
+
if (!fs40.existsSync(filePath)) {
|
|
30562
30695
|
return {};
|
|
30563
30696
|
}
|
|
30564
|
-
const parsed = JSON.parse(
|
|
30697
|
+
const parsed = JSON.parse(fs40.readFileSync(filePath, "utf8"));
|
|
30565
30698
|
return isRecord5(parsed) ? parsed : {};
|
|
30566
30699
|
}
|
|
30567
30700
|
function markManaged(value) {
|
|
@@ -30827,7 +30960,7 @@ function writeLossReport(filePath, report) {
|
|
|
30827
30960
|
if (!filePath) {
|
|
30828
30961
|
return;
|
|
30829
30962
|
}
|
|
30830
|
-
|
|
30963
|
+
fs41.writeFileSync(filePath, `${JSON.stringify(report, null, 2)}
|
|
30831
30964
|
`);
|
|
30832
30965
|
}
|
|
30833
30966
|
function prepareKitManifest(scope, projectRoot, kitInfo) {
|
|
@@ -30868,8 +31001,8 @@ function updateManifest(kitInfo, kitSync) {
|
|
|
30868
31001
|
writeManifest(kitSync.scopePath, kitSync.manifest);
|
|
30869
31002
|
}
|
|
30870
31003
|
function resolveKitFilePath(kitPath, relativePath) {
|
|
30871
|
-
const fullPath =
|
|
30872
|
-
return
|
|
31004
|
+
const fullPath = path42.join(kitPath, relativePath);
|
|
31005
|
+
return fs41.existsSync(fullPath) ? fullPath : null;
|
|
30873
31006
|
}
|
|
30874
31007
|
function cleanupRemovedManagedArtifacts(config, mappings, targets, options, removedSourcePaths, logger) {
|
|
30875
31008
|
if (removedSourcePaths.length === 0 || !mappings) {
|
|
@@ -30930,9 +31063,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
30930
31063
|
}
|
|
30931
31064
|
if (relativePath.startsWith("agents/")) {
|
|
30932
31065
|
removeManagedCompiledArtifact2(
|
|
30933
|
-
|
|
31066
|
+
path42.join(
|
|
30934
31067
|
resolveTargetPath(paths.agents ?? ""),
|
|
30935
|
-
`${
|
|
31068
|
+
`${path42.parse(relativePath).name}.agent.md`
|
|
30936
31069
|
),
|
|
30937
31070
|
"copilot",
|
|
30938
31071
|
relativePath,
|
|
@@ -30942,9 +31075,9 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
30942
31075
|
}
|
|
30943
31076
|
if (relativePath.startsWith("commands/")) {
|
|
30944
31077
|
removeManagedCompiledArtifact2(
|
|
30945
|
-
|
|
31078
|
+
path42.join(
|
|
30946
31079
|
resolveTargetPath(paths.prompts ?? ""),
|
|
30947
|
-
`${
|
|
31080
|
+
`${path42.parse(relativePath).name}.prompt.md`
|
|
30948
31081
|
),
|
|
30949
31082
|
"copilot",
|
|
30950
31083
|
relativePath,
|
|
@@ -30954,7 +31087,7 @@ function cleanupRemovedCopilotArtifact(relativePath, paths, logger) {
|
|
|
30954
31087
|
}
|
|
30955
31088
|
if (relativePath.endsWith("hooks.json")) {
|
|
30956
31089
|
removeManagedCompiledArtifact2(
|
|
30957
|
-
|
|
31090
|
+
path42.join(resolveTargetPath(paths.hooks ?? ""), "tangyr-managed.json"),
|
|
30958
31091
|
"copilot",
|
|
30959
31092
|
relativePath,
|
|
30960
31093
|
logger
|
|
@@ -30984,9 +31117,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
30984
31117
|
}
|
|
30985
31118
|
if (relativePath.startsWith("agents/")) {
|
|
30986
31119
|
removeManagedCompiledArtifact2(
|
|
30987
|
-
|
|
31120
|
+
path42.join(
|
|
30988
31121
|
resolveTargetPath(paths.agents ?? ""),
|
|
30989
|
-
`${
|
|
31122
|
+
`${path42.parse(relativePath).name}.toml`
|
|
30990
31123
|
),
|
|
30991
31124
|
"codex",
|
|
30992
31125
|
relativePath,
|
|
@@ -30996,9 +31129,9 @@ function cleanupRemovedCodexArtifact(relativePath, paths, logger) {
|
|
|
30996
31129
|
}
|
|
30997
31130
|
if (relativePath.startsWith("rules/")) {
|
|
30998
31131
|
removeManagedCompiledArtifact2(
|
|
30999
|
-
|
|
31132
|
+
path42.join(
|
|
31000
31133
|
resolveTargetPath(paths.rules ?? ""),
|
|
31001
|
-
`${
|
|
31134
|
+
`${path42.parse(relativePath).name}.rules`
|
|
31002
31135
|
),
|
|
31003
31136
|
"codex",
|
|
31004
31137
|
relativePath,
|
|
@@ -31037,9 +31170,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
31037
31170
|
}
|
|
31038
31171
|
if (relativePath.startsWith("agents/")) {
|
|
31039
31172
|
removeManagedCompiledArtifact2(
|
|
31040
|
-
|
|
31173
|
+
path42.join(
|
|
31041
31174
|
resolveTargetPath(paths.agents ?? ""),
|
|
31042
|
-
`${
|
|
31175
|
+
`${path42.parse(relativePath).name}.md`
|
|
31043
31176
|
),
|
|
31044
31177
|
"opencode",
|
|
31045
31178
|
relativePath,
|
|
@@ -31049,9 +31182,9 @@ function cleanupRemovedOpenCodeArtifact(relativePath, paths, logger) {
|
|
|
31049
31182
|
}
|
|
31050
31183
|
if (relativePath.startsWith("commands/")) {
|
|
31051
31184
|
removeManagedCompiledArtifact2(
|
|
31052
|
-
|
|
31185
|
+
path42.join(
|
|
31053
31186
|
resolveTargetPath(paths.commands ?? ""),
|
|
31054
|
-
`${
|
|
31187
|
+
`${path42.parse(relativePath).name}.md`
|
|
31055
31188
|
),
|
|
31056
31189
|
"opencode",
|
|
31057
31190
|
relativePath,
|
|
@@ -31083,9 +31216,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
31083
31216
|
}
|
|
31084
31217
|
if (relativePath.startsWith("agents/")) {
|
|
31085
31218
|
removeManagedCompiledArtifact2(
|
|
31086
|
-
|
|
31219
|
+
path42.join(
|
|
31087
31220
|
resolveTargetPath(paths.agents ?? ""),
|
|
31088
|
-
`${
|
|
31221
|
+
`${path42.parse(relativePath).name}.md`
|
|
31089
31222
|
),
|
|
31090
31223
|
"cursor",
|
|
31091
31224
|
relativePath,
|
|
@@ -31095,9 +31228,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
31095
31228
|
}
|
|
31096
31229
|
if (relativePath.startsWith("rules/")) {
|
|
31097
31230
|
removeManagedCompiledArtifact2(
|
|
31098
|
-
|
|
31231
|
+
path42.join(
|
|
31099
31232
|
resolveTargetPath(paths.rules ?? ""),
|
|
31100
|
-
`${
|
|
31233
|
+
`${path42.parse(relativePath).name}.mdc`
|
|
31101
31234
|
),
|
|
31102
31235
|
"cursor",
|
|
31103
31236
|
relativePath,
|
|
@@ -31107,9 +31240,9 @@ function cleanupRemovedCursorArtifact(relativePath, paths, logger) {
|
|
|
31107
31240
|
}
|
|
31108
31241
|
if (relativePath.startsWith("commands/")) {
|
|
31109
31242
|
removeManagedCompiledArtifact2(
|
|
31110
|
-
|
|
31243
|
+
path42.join(
|
|
31111
31244
|
resolveTargetPath(paths.skills ?? ""),
|
|
31112
|
-
|
|
31245
|
+
path42.parse(relativePath).name,
|
|
31113
31246
|
"SKILL.md"
|
|
31114
31247
|
),
|
|
31115
31248
|
"cursor",
|
|
@@ -31153,9 +31286,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
31153
31286
|
}
|
|
31154
31287
|
if (relativePath.startsWith("rules/")) {
|
|
31155
31288
|
removeManagedCompiledArtifact2(
|
|
31156
|
-
|
|
31289
|
+
path42.join(
|
|
31157
31290
|
resolveTargetPath(paths.rules ?? ""),
|
|
31158
|
-
`${
|
|
31291
|
+
`${path42.parse(relativePath).name}.md`
|
|
31159
31292
|
),
|
|
31160
31293
|
"cline",
|
|
31161
31294
|
relativePath,
|
|
@@ -31165,9 +31298,9 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
31165
31298
|
}
|
|
31166
31299
|
if (relativePath.startsWith("commands/")) {
|
|
31167
31300
|
removeManagedCompiledArtifact2(
|
|
31168
|
-
|
|
31301
|
+
path42.join(
|
|
31169
31302
|
resolveTargetPath(paths.workflows ?? ""),
|
|
31170
|
-
|
|
31303
|
+
path42.basename(relativePath)
|
|
31171
31304
|
),
|
|
31172
31305
|
"cline",
|
|
31173
31306
|
relativePath,
|
|
@@ -31185,17 +31318,17 @@ function cleanupRemovedClineArtifact(relativePath, paths, logger) {
|
|
|
31185
31318
|
}
|
|
31186
31319
|
}
|
|
31187
31320
|
function removeManagedCompiledArtifact2(artifactPath, expectedTarget, expectedSource, logger) {
|
|
31188
|
-
if (!
|
|
31321
|
+
if (!fs41.existsSync(artifactPath)) {
|
|
31189
31322
|
return;
|
|
31190
31323
|
}
|
|
31191
|
-
if (!
|
|
31324
|
+
if (!fs41.statSync(artifactPath).isFile()) {
|
|
31192
31325
|
return;
|
|
31193
31326
|
}
|
|
31194
|
-
const marker = extractProvenanceMarker(
|
|
31327
|
+
const marker = extractProvenanceMarker(fs41.readFileSync(artifactPath, "utf8"));
|
|
31195
31328
|
if (marker?.source !== expectedSource || marker.target !== expectedTarget) {
|
|
31196
31329
|
return;
|
|
31197
31330
|
}
|
|
31198
|
-
|
|
31331
|
+
fs41.rmSync(artifactPath, { force: true });
|
|
31199
31332
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
31200
31333
|
}
|
|
31201
31334
|
function removeManagedCopilotMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
@@ -31226,10 +31359,10 @@ function removeManagedCodexHooksArtifact2(artifactPath, expectedSource, logger)
|
|
|
31226
31359
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
31227
31360
|
}
|
|
31228
31361
|
function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
31229
|
-
if (!
|
|
31362
|
+
if (!fs41.existsSync(artifactPath)) {
|
|
31230
31363
|
return;
|
|
31231
31364
|
}
|
|
31232
|
-
const content =
|
|
31365
|
+
const content = fs41.readFileSync(artifactPath, "utf8");
|
|
31233
31366
|
const startMarker = "# tangyr: managed mcp start";
|
|
31234
31367
|
const endMarker = "# tangyr: managed mcp end";
|
|
31235
31368
|
const startIndex = content.indexOf(startMarker);
|
|
@@ -31246,19 +31379,19 @@ function removeManagedCodexMcpArtifact2(artifactPath, expectedSource, logger) {
|
|
|
31246
31379
|
const after = content.slice(endIndex + endMarker.length).trimStart();
|
|
31247
31380
|
const cleaned = [before, after].filter((entry) => entry.length > 0).join("\n\n");
|
|
31248
31381
|
if (cleaned.length === 0) {
|
|
31249
|
-
|
|
31382
|
+
fs41.rmSync(artifactPath, { force: true });
|
|
31250
31383
|
} else {
|
|
31251
|
-
|
|
31384
|
+
fs41.writeFileSync(artifactPath, `${cleaned}
|
|
31252
31385
|
`);
|
|
31253
31386
|
}
|
|
31254
31387
|
logger.verbose(` removed stale target artifact: ${artifactPath}`);
|
|
31255
31388
|
}
|
|
31256
31389
|
function readJsonObject5(filePath) {
|
|
31257
|
-
if (!
|
|
31390
|
+
if (!fs41.existsSync(filePath)) {
|
|
31258
31391
|
return null;
|
|
31259
31392
|
}
|
|
31260
31393
|
try {
|
|
31261
|
-
const parsed = JSON.parse(
|
|
31394
|
+
const parsed = JSON.parse(fs41.readFileSync(filePath, "utf8"));
|
|
31262
31395
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
31263
31396
|
} catch {
|
|
31264
31397
|
return null;
|
|
@@ -31272,10 +31405,10 @@ function readJsonMetadata(value) {
|
|
|
31272
31405
|
}
|
|
31273
31406
|
function writeJsonOrRemove2(filePath, parsed) {
|
|
31274
31407
|
if (isEmptyJsonValue2(parsed)) {
|
|
31275
|
-
|
|
31408
|
+
fs41.rmSync(filePath, { force: true });
|
|
31276
31409
|
return;
|
|
31277
31410
|
}
|
|
31278
|
-
|
|
31411
|
+
fs41.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
31279
31412
|
`);
|
|
31280
31413
|
}
|
|
31281
31414
|
function isEmptyJsonValue2(value) {
|
|
@@ -31335,8 +31468,8 @@ function removeManagedHookEntries(value, expectedSource) {
|
|
|
31335
31468
|
}
|
|
31336
31469
|
|
|
31337
31470
|
// src/commands/validate.ts
|
|
31338
|
-
import
|
|
31339
|
-
import
|
|
31471
|
+
import fs42 from "fs";
|
|
31472
|
+
import path43 from "path";
|
|
31340
31473
|
var SUPPORTED_KIT_FORMATS2 = [1];
|
|
31341
31474
|
var SUPPORTED_DISCIPLINE_VERSIONS = [
|
|
31342
31475
|
"0.14.0",
|
|
@@ -31420,8 +31553,8 @@ function checkKitFormatSupported(kit) {
|
|
|
31420
31553
|
}
|
|
31421
31554
|
function checkEntrypointExists(kit) {
|
|
31422
31555
|
const entrypoint = "CLAUDE.md";
|
|
31423
|
-
const entrypointPath =
|
|
31424
|
-
if (!
|
|
31556
|
+
const entrypointPath = path43.join(kit.path, entrypoint);
|
|
31557
|
+
if (!fs42.existsSync(entrypointPath)) {
|
|
31425
31558
|
return {
|
|
31426
31559
|
code: "entrypoint-missing",
|
|
31427
31560
|
location: entrypoint,
|
|
@@ -31478,9 +31611,9 @@ function checkComponentFrontmatter(kit) {
|
|
|
31478
31611
|
const missingSet = new Set(kit.components[cat].missing);
|
|
31479
31612
|
for (const name of kit.components[cat].declared) {
|
|
31480
31613
|
if (missingSet.has(name)) continue;
|
|
31481
|
-
const filePath = cat === "skills" ?
|
|
31482
|
-
if (!
|
|
31483
|
-
const relPath =
|
|
31614
|
+
const filePath = cat === "skills" ? path43.join(kit.path, cat, name, "SKILL.md") : path43.join(kit.path, cat, `${name}.md`);
|
|
31615
|
+
if (!fs42.existsSync(filePath)) continue;
|
|
31616
|
+
const relPath = path43.relative(kit.path, filePath);
|
|
31484
31617
|
try {
|
|
31485
31618
|
const { data } = parseMarkdownFrontmatter(filePath);
|
|
31486
31619
|
for (const field of requiredFields) {
|
|
@@ -31505,10 +31638,10 @@ function checkComponentFrontmatter(kit) {
|
|
|
31505
31638
|
}
|
|
31506
31639
|
function checkReservedRootNames(kit) {
|
|
31507
31640
|
const violations = [];
|
|
31508
|
-
if (!
|
|
31641
|
+
if (!fs42.existsSync(kit.path) || !fs42.statSync(kit.path).isDirectory()) {
|
|
31509
31642
|
return violations;
|
|
31510
31643
|
}
|
|
31511
|
-
const entries =
|
|
31644
|
+
const entries = fs42.readdirSync(kit.path, { withFileTypes: true });
|
|
31512
31645
|
for (const entry of entries) {
|
|
31513
31646
|
if (RESERVED_ROOT_NAMES.includes(entry.name)) {
|
|
31514
31647
|
violations.push({
|
|
@@ -31525,8 +31658,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
31525
31658
|
const missingSet = new Set(kit.components.commands.missing);
|
|
31526
31659
|
for (const name of kit.components.commands.declared) {
|
|
31527
31660
|
if (missingSet.has(name)) continue;
|
|
31528
|
-
const filePath =
|
|
31529
|
-
if (!
|
|
31661
|
+
const filePath = path43.join(kit.path, "commands", `${name}.md`);
|
|
31662
|
+
if (!fs42.existsSync(filePath)) continue;
|
|
31530
31663
|
let data;
|
|
31531
31664
|
try {
|
|
31532
31665
|
({ data } = parseMarkdownFrontmatter(filePath));
|
|
@@ -31539,7 +31672,7 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
31539
31672
|
if (!barred) {
|
|
31540
31673
|
violations.push({
|
|
31541
31674
|
code: "command-human-only-model-invocable",
|
|
31542
|
-
location:
|
|
31675
|
+
location: path43.relative(kit.path, filePath),
|
|
31543
31676
|
message: "commands: 'launch: human-only' requires 'disable-model-invocation: true' so the model cannot start the command; only a Human-typed launch may"
|
|
31544
31677
|
});
|
|
31545
31678
|
}
|
|
@@ -31548,8 +31681,8 @@ function checkHumanOnlyCommandInvocation(kit) {
|
|
|
31548
31681
|
}
|
|
31549
31682
|
|
|
31550
31683
|
// src/commands/verify.ts
|
|
31551
|
-
import
|
|
31552
|
-
import
|
|
31684
|
+
import fs43 from "fs";
|
|
31685
|
+
import path44 from "path";
|
|
31553
31686
|
function runVerifyCommand(options, logger) {
|
|
31554
31687
|
const { config, configDir, sourceRoot, kitInfo } = resolveRuntime(
|
|
31555
31688
|
options,
|
|
@@ -31640,8 +31773,8 @@ function verifyClaudeCodeGlobalRoots(roots, manifestKeys, mappings) {
|
|
|
31640
31773
|
if (!slotPath) {
|
|
31641
31774
|
continue;
|
|
31642
31775
|
}
|
|
31643
|
-
const fullPath = subPath ?
|
|
31644
|
-
if (!
|
|
31776
|
+
const fullPath = subPath ? path44.join(slotPath, subPath) : slotPath;
|
|
31777
|
+
if (!fs43.existsSync(fullPath)) {
|
|
31645
31778
|
failures.push(
|
|
31646
31779
|
`claude-code/${slot}${subPath ? `/${subPath}` : ""} missing in root ${root}: ${fullPath}`
|
|
31647
31780
|
);
|