rulesync 8.6.0 → 8.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ILMHM7BF.js → chunk-QGQQJNZD.js} +460 -464
- package/dist/cli/index.cjs +2474 -864
- package/dist/cli/index.js +1831 -211
- package/dist/index.cjs +457 -464
- package/dist/index.js +1 -1
- package/package.json +3 -2
package/dist/cli/index.cjs
CHANGED
|
@@ -3079,7 +3079,7 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
3079
3079
|
};
|
|
3080
3080
|
|
|
3081
3081
|
// src/features/hooks/hooks-processor.ts
|
|
3082
|
-
var
|
|
3082
|
+
var import_mini18 = require("zod/mini");
|
|
3083
3083
|
|
|
3084
3084
|
// src/types/hooks.ts
|
|
3085
3085
|
var import_mini15 = require("zod/mini");
|
|
@@ -3383,22 +3383,34 @@ function canonicalToToolHooks({
|
|
|
3383
3383
|
`matcher "${matcherKey}" on "${eventName}" hook will be ignored \u2014 this event does not support matchers`
|
|
3384
3384
|
);
|
|
3385
3385
|
}
|
|
3386
|
-
const hooks =
|
|
3386
|
+
const hooks = [];
|
|
3387
|
+
for (const def of defs) {
|
|
3388
|
+
const hookType = def.type ?? "command";
|
|
3389
|
+
if (converterConfig.supportedHookTypes && !converterConfig.supportedHookTypes.has(hookType)) {
|
|
3390
|
+
continue;
|
|
3391
|
+
}
|
|
3387
3392
|
const commandText = def.command;
|
|
3388
3393
|
const trimmedCommand = typeof commandText === "string" ? commandText.trimStart() : void 0;
|
|
3389
|
-
const shouldPrefix = typeof trimmedCommand === "string" && !trimmedCommand.startsWith("$") && (!converterConfig.prefixDotRelativeCommandsOnly || trimmedCommand.startsWith("."));
|
|
3394
|
+
const shouldPrefix = converterConfig.projectDirVar !== "" && typeof trimmedCommand === "string" && !trimmedCommand.startsWith("$") && (!converterConfig.prefixDotRelativeCommandsOnly || trimmedCommand.startsWith("."));
|
|
3390
3395
|
const command = shouldPrefix && typeof trimmedCommand === "string" ? `${converterConfig.projectDirVar}/${trimmedCommand.replace(/^\.\//, "")}` : def.command;
|
|
3391
|
-
|
|
3392
|
-
type:
|
|
3396
|
+
hooks.push({
|
|
3397
|
+
type: hookType,
|
|
3393
3398
|
...command !== void 0 && command !== null && { command },
|
|
3394
3399
|
...def.timeout !== void 0 && def.timeout !== null && { timeout: def.timeout },
|
|
3395
|
-
...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt }
|
|
3396
|
-
|
|
3397
|
-
|
|
3400
|
+
...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt },
|
|
3401
|
+
...converterConfig.passthroughFields?.includes("name") && def.name !== void 0 && def.name !== null && { name: def.name },
|
|
3402
|
+
...converterConfig.passthroughFields?.includes("description") && def.description !== void 0 && def.description !== null && { description: def.description }
|
|
3403
|
+
});
|
|
3404
|
+
}
|
|
3405
|
+
if (hooks.length === 0) {
|
|
3406
|
+
continue;
|
|
3407
|
+
}
|
|
3398
3408
|
const includeMatcher = matcherKey && !isNoMatcherEvent;
|
|
3399
3409
|
entries.push(includeMatcher ? { matcher: matcherKey, hooks } : { hooks });
|
|
3400
3410
|
}
|
|
3401
|
-
|
|
3411
|
+
if (entries.length > 0) {
|
|
3412
|
+
result[toolEventName] = entries;
|
|
3413
|
+
}
|
|
3402
3414
|
}
|
|
3403
3415
|
return result;
|
|
3404
3416
|
}
|
|
@@ -3419,7 +3431,7 @@ function toolHooksToCanonical({
|
|
|
3419
3431
|
const hookDefs = rawEntry.hooks ?? [];
|
|
3420
3432
|
for (const h of hookDefs) {
|
|
3421
3433
|
const cmd = typeof h.command === "string" ? h.command : void 0;
|
|
3422
|
-
const command = typeof cmd === "string" && cmd.includes(`${converterConfig.projectDirVar}/`) ? cmd.replace(
|
|
3434
|
+
const command = converterConfig.projectDirVar !== "" && typeof cmd === "string" && cmd.includes(`${converterConfig.projectDirVar}/`) ? cmd.replace(
|
|
3423
3435
|
new RegExp(
|
|
3424
3436
|
`^${converterConfig.projectDirVar.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\/?`
|
|
3425
3437
|
),
|
|
@@ -3433,6 +3445,8 @@ function toolHooksToCanonical({
|
|
|
3433
3445
|
...command !== void 0 && command !== null && { command },
|
|
3434
3446
|
...timeout !== void 0 && timeout !== null && { timeout },
|
|
3435
3447
|
...prompt !== void 0 && prompt !== null && { prompt },
|
|
3448
|
+
...converterConfig.passthroughFields?.includes("name") && typeof h.name === "string" && { name: h.name },
|
|
3449
|
+
...converterConfig.passthroughFields?.includes("description") && typeof h.description === "string" && { description: h.description },
|
|
3436
3450
|
...rawEntry.matcher !== void 0 && rawEntry.matcher !== null && rawEntry.matcher !== "" && { matcher: rawEntry.matcher }
|
|
3437
3451
|
});
|
|
3438
3452
|
}
|
|
@@ -3531,6 +3545,9 @@ var ToolHooks = class extends ToolFile {
|
|
|
3531
3545
|
static forDeletion(_params) {
|
|
3532
3546
|
throw new Error("Please implement this method in the subclass.");
|
|
3533
3547
|
}
|
|
3548
|
+
static async getAuxiliaryFiles(_params) {
|
|
3549
|
+
return [];
|
|
3550
|
+
}
|
|
3534
3551
|
};
|
|
3535
3552
|
|
|
3536
3553
|
// src/features/hooks/claudecode-hooks.ts
|
|
@@ -3652,89 +3669,28 @@ var ClaudecodeHooks = class _ClaudecodeHooks extends ToolHooks {
|
|
|
3652
3669
|
// src/features/hooks/codexcli-hooks.ts
|
|
3653
3670
|
var import_node_path24 = require("path");
|
|
3654
3671
|
var smolToml2 = __toESM(require("smol-toml"), 1);
|
|
3655
|
-
var
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
}
|
|
3664
|
-
const effectiveHooks = {
|
|
3665
|
-
...sharedHooks,
|
|
3666
|
-
...config.codexcli?.hooks
|
|
3667
|
-
};
|
|
3668
|
-
const codex = {};
|
|
3669
|
-
for (const [eventName, definitions] of Object.entries(effectiveHooks)) {
|
|
3670
|
-
const codexEventName = CANONICAL_TO_CODEXCLI_EVENT_NAMES[eventName] ?? eventName;
|
|
3671
|
-
const byMatcher = /* @__PURE__ */ new Map();
|
|
3672
|
-
for (const def of definitions) {
|
|
3673
|
-
const key = def.matcher ?? "";
|
|
3674
|
-
const list = byMatcher.get(key);
|
|
3675
|
-
if (list) list.push(def);
|
|
3676
|
-
else byMatcher.set(key, [def]);
|
|
3677
|
-
}
|
|
3678
|
-
const entries = [];
|
|
3679
|
-
for (const [matcherKey, defs] of byMatcher) {
|
|
3680
|
-
const commandDefs = defs.filter((def) => !def.type || def.type === "command");
|
|
3681
|
-
if (commandDefs.length === 0) continue;
|
|
3682
|
-
const hooks = commandDefs.map((def) => ({
|
|
3683
|
-
type: "command",
|
|
3684
|
-
...def.command !== void 0 && def.command !== null && { command: def.command },
|
|
3685
|
-
...def.timeout !== void 0 && def.timeout !== null && { timeout: def.timeout }
|
|
3686
|
-
}));
|
|
3687
|
-
entries.push(matcherKey ? { matcher: matcherKey, hooks } : { hooks });
|
|
3688
|
-
}
|
|
3689
|
-
if (entries.length > 0) {
|
|
3690
|
-
codex[codexEventName] = entries;
|
|
3691
|
-
}
|
|
3692
|
-
}
|
|
3693
|
-
return codex;
|
|
3694
|
-
}
|
|
3695
|
-
var CodexHookEntrySchema = import_mini16.z.looseObject({
|
|
3696
|
-
type: import_mini16.z.optional(import_mini16.z.string()),
|
|
3697
|
-
command: import_mini16.z.optional(import_mini16.z.string()),
|
|
3698
|
-
timeout: import_mini16.z.optional(import_mini16.z.number())
|
|
3699
|
-
});
|
|
3700
|
-
var CodexMatcherEntrySchema = import_mini16.z.looseObject({
|
|
3701
|
-
matcher: import_mini16.z.optional(import_mini16.z.string()),
|
|
3702
|
-
hooks: import_mini16.z.optional(import_mini16.z.array(CodexHookEntrySchema))
|
|
3703
|
-
});
|
|
3704
|
-
function codexcliHooksToCanonical(codexHooks) {
|
|
3705
|
-
if (codexHooks === null || codexHooks === void 0 || typeof codexHooks !== "object") {
|
|
3706
|
-
return {};
|
|
3707
|
-
}
|
|
3708
|
-
const canonical = {};
|
|
3709
|
-
for (const [codexEventName, matcherEntries] of Object.entries(codexHooks)) {
|
|
3710
|
-
const eventName = CODEXCLI_TO_CANONICAL_EVENT_NAMES[codexEventName] ?? codexEventName;
|
|
3711
|
-
if (!Array.isArray(matcherEntries)) continue;
|
|
3712
|
-
const defs = [];
|
|
3713
|
-
for (const rawEntry of matcherEntries) {
|
|
3714
|
-
const parseResult = CodexMatcherEntrySchema.safeParse(rawEntry);
|
|
3715
|
-
if (!parseResult.success) continue;
|
|
3716
|
-
const entry = parseResult.data;
|
|
3717
|
-
const hooks = entry.hooks ?? [];
|
|
3718
|
-
for (const h of hooks) {
|
|
3719
|
-
const hookType = h.type === "command" || h.type === "prompt" ? h.type : "command";
|
|
3720
|
-
defs.push({
|
|
3721
|
-
type: hookType,
|
|
3722
|
-
...h.command !== void 0 && h.command !== null && { command: h.command },
|
|
3723
|
-
...h.timeout !== void 0 && h.timeout !== null && { timeout: h.timeout },
|
|
3724
|
-
...entry.matcher !== void 0 && entry.matcher !== null && entry.matcher !== "" && { matcher: entry.matcher }
|
|
3725
|
-
});
|
|
3726
|
-
}
|
|
3727
|
-
}
|
|
3728
|
-
if (defs.length > 0) {
|
|
3729
|
-
canonical[eventName] = defs;
|
|
3730
|
-
}
|
|
3731
|
-
}
|
|
3732
|
-
return canonical;
|
|
3733
|
-
}
|
|
3672
|
+
var CODEXCLI_CONVERTER_CONFIG = {
|
|
3673
|
+
supportedEvents: CODEXCLI_HOOK_EVENTS,
|
|
3674
|
+
canonicalToToolEventNames: CANONICAL_TO_CODEXCLI_EVENT_NAMES,
|
|
3675
|
+
toolToCanonicalEventNames: CODEXCLI_TO_CANONICAL_EVENT_NAMES,
|
|
3676
|
+
projectDirVar: "",
|
|
3677
|
+
supportedHookTypes: /* @__PURE__ */ new Set(["command"]),
|
|
3678
|
+
passthroughFields: ["name", "description"]
|
|
3679
|
+
};
|
|
3734
3680
|
async function buildCodexConfigTomlContent({ baseDir }) {
|
|
3735
3681
|
const configPath = (0, import_node_path24.join)(baseDir, ".codex", "config.toml");
|
|
3736
3682
|
const existingContent = await readFileContentOrNull(configPath) ?? smolToml2.stringify({});
|
|
3737
|
-
|
|
3683
|
+
let configToml;
|
|
3684
|
+
try {
|
|
3685
|
+
configToml = smolToml2.parse(existingContent);
|
|
3686
|
+
} catch (error) {
|
|
3687
|
+
throw new Error(
|
|
3688
|
+
`Failed to parse existing Codex CLI config at ${configPath}: ${formatError(error)}`,
|
|
3689
|
+
{
|
|
3690
|
+
cause: error
|
|
3691
|
+
}
|
|
3692
|
+
);
|
|
3693
|
+
}
|
|
3738
3694
|
if (typeof configToml.features !== "object" || configToml.features === null) {
|
|
3739
3695
|
configToml.features = {};
|
|
3740
3696
|
}
|
|
@@ -3789,7 +3745,11 @@ var CodexcliHooks = class _CodexcliHooks extends ToolHooks {
|
|
|
3789
3745
|
}) {
|
|
3790
3746
|
const paths = _CodexcliHooks.getSettablePaths({ global });
|
|
3791
3747
|
const config = rulesyncHooks.getJson();
|
|
3792
|
-
const codexHooks =
|
|
3748
|
+
const codexHooks = canonicalToToolHooks({
|
|
3749
|
+
config,
|
|
3750
|
+
toolOverrideHooks: config.codexcli?.hooks,
|
|
3751
|
+
converterConfig: CODEXCLI_CONVERTER_CONFIG
|
|
3752
|
+
});
|
|
3793
3753
|
const fileContent = JSON.stringify({ hooks: codexHooks }, null, 2);
|
|
3794
3754
|
return new _CodexcliHooks({
|
|
3795
3755
|
baseDir,
|
|
@@ -3811,7 +3771,10 @@ var CodexcliHooks = class _CodexcliHooks extends ToolHooks {
|
|
|
3811
3771
|
}
|
|
3812
3772
|
);
|
|
3813
3773
|
}
|
|
3814
|
-
const hooks =
|
|
3774
|
+
const hooks = toolHooksToCanonical({
|
|
3775
|
+
hooks: parsed.hooks,
|
|
3776
|
+
converterConfig: CODEXCLI_CONVERTER_CONFIG
|
|
3777
|
+
});
|
|
3815
3778
|
return this.toRulesyncHooksDefault({
|
|
3816
3779
|
fileContent: JSON.stringify({ version: 1, hooks }, null, 2)
|
|
3817
3780
|
});
|
|
@@ -3832,16 +3795,21 @@ var CodexcliHooks = class _CodexcliHooks extends ToolHooks {
|
|
|
3832
3795
|
validate: false
|
|
3833
3796
|
});
|
|
3834
3797
|
}
|
|
3798
|
+
static async getAuxiliaryFiles({
|
|
3799
|
+
baseDir = process.cwd()
|
|
3800
|
+
} = {}) {
|
|
3801
|
+
return [await CodexcliConfigToml.fromBaseDir({ baseDir })];
|
|
3802
|
+
}
|
|
3835
3803
|
};
|
|
3836
3804
|
|
|
3837
3805
|
// src/features/hooks/copilot-hooks.ts
|
|
3838
3806
|
var import_node_path25 = require("path");
|
|
3839
|
-
var
|
|
3840
|
-
var CopilotHookEntrySchema =
|
|
3841
|
-
type:
|
|
3842
|
-
bash:
|
|
3843
|
-
powershell:
|
|
3844
|
-
timeoutSec:
|
|
3807
|
+
var import_mini16 = require("zod/mini");
|
|
3808
|
+
var CopilotHookEntrySchema = import_mini16.z.looseObject({
|
|
3809
|
+
type: import_mini16.z.string(),
|
|
3810
|
+
bash: import_mini16.z.optional(import_mini16.z.string()),
|
|
3811
|
+
powershell: import_mini16.z.optional(import_mini16.z.string()),
|
|
3812
|
+
timeoutSec: import_mini16.z.optional(import_mini16.z.number())
|
|
3845
3813
|
});
|
|
3846
3814
|
function canonicalToCopilotHooks(config) {
|
|
3847
3815
|
const canonicalSchemaKeys = Object.keys(HookDefinitionSchema.shape);
|
|
@@ -4372,7 +4340,7 @@ var FactorydroidHooks = class _FactorydroidHooks extends ToolHooks {
|
|
|
4372
4340
|
|
|
4373
4341
|
// src/features/hooks/geminicli-hooks.ts
|
|
4374
4342
|
var import_node_path29 = require("path");
|
|
4375
|
-
var
|
|
4343
|
+
var import_mini17 = require("zod/mini");
|
|
4376
4344
|
function canonicalToGeminicliHooks(config) {
|
|
4377
4345
|
const geminiSupported = new Set(GEMINICLI_HOOK_EVENTS);
|
|
4378
4346
|
const sharedHooks = {};
|
|
@@ -4416,16 +4384,16 @@ function canonicalToGeminicliHooks(config) {
|
|
|
4416
4384
|
}
|
|
4417
4385
|
return gemini;
|
|
4418
4386
|
}
|
|
4419
|
-
var GeminiHookEntrySchema =
|
|
4420
|
-
type:
|
|
4421
|
-
command:
|
|
4422
|
-
timeout:
|
|
4423
|
-
name:
|
|
4424
|
-
description:
|
|
4387
|
+
var GeminiHookEntrySchema = import_mini17.z.looseObject({
|
|
4388
|
+
type: import_mini17.z.optional(import_mini17.z.string()),
|
|
4389
|
+
command: import_mini17.z.optional(import_mini17.z.string()),
|
|
4390
|
+
timeout: import_mini17.z.optional(import_mini17.z.number()),
|
|
4391
|
+
name: import_mini17.z.optional(import_mini17.z.string()),
|
|
4392
|
+
description: import_mini17.z.optional(import_mini17.z.string())
|
|
4425
4393
|
});
|
|
4426
|
-
var GeminiMatcherEntrySchema =
|
|
4427
|
-
matcher:
|
|
4428
|
-
hooks:
|
|
4394
|
+
var GeminiMatcherEntrySchema = import_mini17.z.looseObject({
|
|
4395
|
+
matcher: import_mini17.z.optional(import_mini17.z.string()),
|
|
4396
|
+
hooks: import_mini17.z.optional(import_mini17.z.array(GeminiHookEntrySchema))
|
|
4429
4397
|
});
|
|
4430
4398
|
function geminiHooksToCanonical(geminiHooks) {
|
|
4431
4399
|
if (geminiHooks === null || geminiHooks === void 0 || typeof geminiHooks !== "object") {
|
|
@@ -4809,7 +4777,7 @@ var hooksProcessorToolTargetTuple = [
|
|
|
4809
4777
|
"geminicli",
|
|
4810
4778
|
"deepagents"
|
|
4811
4779
|
];
|
|
4812
|
-
var HooksProcessorToolTargetSchema =
|
|
4780
|
+
var HooksProcessorToolTargetSchema = import_mini18.z.enum(hooksProcessorToolTargetTuple);
|
|
4813
4781
|
var toolHooksFactories = /* @__PURE__ */ new Map([
|
|
4814
4782
|
[
|
|
4815
4783
|
"cursor",
|
|
@@ -5068,8 +5036,12 @@ var HooksProcessor = class extends FeatureProcessor {
|
|
|
5068
5036
|
global: this.global
|
|
5069
5037
|
});
|
|
5070
5038
|
const result = [toolHooks];
|
|
5071
|
-
|
|
5072
|
-
|
|
5039
|
+
const auxiliaryFiles = await factory.class.getAuxiliaryFiles?.({
|
|
5040
|
+
baseDir: this.baseDir,
|
|
5041
|
+
global: this.global
|
|
5042
|
+
});
|
|
5043
|
+
if (auxiliaryFiles && auxiliaryFiles.length > 0) {
|
|
5044
|
+
result.push(...auxiliaryFiles);
|
|
5073
5045
|
}
|
|
5074
5046
|
return result;
|
|
5075
5047
|
}
|
|
@@ -5089,7 +5061,7 @@ var HooksProcessor = class extends FeatureProcessor {
|
|
|
5089
5061
|
};
|
|
5090
5062
|
|
|
5091
5063
|
// src/features/ignore/ignore-processor.ts
|
|
5092
|
-
var
|
|
5064
|
+
var import_mini20 = require("zod/mini");
|
|
5093
5065
|
|
|
5094
5066
|
// src/features/ignore/augmentcode-ignore.ts
|
|
5095
5067
|
var import_node_path33 = require("path");
|
|
@@ -5268,12 +5240,12 @@ var AugmentcodeIgnore = class _AugmentcodeIgnore extends ToolIgnore {
|
|
|
5268
5240
|
// src/features/ignore/claudecode-ignore.ts
|
|
5269
5241
|
var import_node_path34 = require("path");
|
|
5270
5242
|
var import_es_toolkit2 = require("es-toolkit");
|
|
5271
|
-
var
|
|
5243
|
+
var import_mini19 = require("zod/mini");
|
|
5272
5244
|
var SHARED_SETTINGS_FILE = "settings.json";
|
|
5273
5245
|
var LOCAL_SETTINGS_FILE = "settings.local.json";
|
|
5274
5246
|
var DEFAULT_FILE_MODE = "shared";
|
|
5275
|
-
var ClaudecodeIgnoreOptionsSchema =
|
|
5276
|
-
fileMode:
|
|
5247
|
+
var ClaudecodeIgnoreOptionsSchema = import_mini19.z.looseObject({
|
|
5248
|
+
fileMode: import_mini19.z.optional(import_mini19.z.enum(["shared", "local"]))
|
|
5277
5249
|
});
|
|
5278
5250
|
var resolveFileMode = (options) => {
|
|
5279
5251
|
if (!options) return DEFAULT_FILE_MODE;
|
|
@@ -6117,7 +6089,7 @@ var ignoreProcessorToolTargets = [
|
|
|
6117
6089
|
"windsurf",
|
|
6118
6090
|
"zed"
|
|
6119
6091
|
];
|
|
6120
|
-
var IgnoreProcessorToolTargetSchema =
|
|
6092
|
+
var IgnoreProcessorToolTargetSchema = import_mini20.z.enum(ignoreProcessorToolTargets);
|
|
6121
6093
|
var toolIgnoreFactories = /* @__PURE__ */ new Map([
|
|
6122
6094
|
["augmentcode", { class: AugmentcodeIgnore }],
|
|
6123
6095
|
["claudecode", { class: ClaudecodeIgnore }],
|
|
@@ -6260,7 +6232,7 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
6260
6232
|
};
|
|
6261
6233
|
|
|
6262
6234
|
// src/features/mcp/mcp-processor.ts
|
|
6263
|
-
var
|
|
6235
|
+
var import_mini25 = require("zod/mini");
|
|
6264
6236
|
|
|
6265
6237
|
// src/features/mcp/claudecode-mcp.ts
|
|
6266
6238
|
var import_node_path47 = require("path");
|
|
@@ -6268,47 +6240,47 @@ var import_node_path47 = require("path");
|
|
|
6268
6240
|
// src/features/mcp/rulesync-mcp.ts
|
|
6269
6241
|
var import_node_path46 = require("path");
|
|
6270
6242
|
var import_object = require("es-toolkit/object");
|
|
6271
|
-
var
|
|
6243
|
+
var import_mini22 = require("zod/mini");
|
|
6272
6244
|
|
|
6273
6245
|
// src/types/mcp.ts
|
|
6274
|
-
var
|
|
6275
|
-
var McpServerSchema =
|
|
6276
|
-
type:
|
|
6277
|
-
command:
|
|
6278
|
-
args:
|
|
6279
|
-
url:
|
|
6280
|
-
httpUrl:
|
|
6281
|
-
env:
|
|
6282
|
-
disabled:
|
|
6283
|
-
networkTimeout:
|
|
6284
|
-
timeout:
|
|
6285
|
-
trust:
|
|
6286
|
-
cwd:
|
|
6287
|
-
transport:
|
|
6288
|
-
alwaysAllow:
|
|
6289
|
-
tools:
|
|
6290
|
-
kiroAutoApprove:
|
|
6291
|
-
kiroAutoBlock:
|
|
6292
|
-
headers:
|
|
6293
|
-
enabledTools:
|
|
6294
|
-
disabledTools:
|
|
6246
|
+
var import_mini21 = require("zod/mini");
|
|
6247
|
+
var McpServerSchema = import_mini21.z.looseObject({
|
|
6248
|
+
type: import_mini21.z.optional(import_mini21.z.enum(["local", "stdio", "sse", "http"])),
|
|
6249
|
+
command: import_mini21.z.optional(import_mini21.z.union([import_mini21.z.string(), import_mini21.z.array(import_mini21.z.string())])),
|
|
6250
|
+
args: import_mini21.z.optional(import_mini21.z.array(import_mini21.z.string())),
|
|
6251
|
+
url: import_mini21.z.optional(import_mini21.z.string()),
|
|
6252
|
+
httpUrl: import_mini21.z.optional(import_mini21.z.string()),
|
|
6253
|
+
env: import_mini21.z.optional(import_mini21.z.record(import_mini21.z.string(), import_mini21.z.string())),
|
|
6254
|
+
disabled: import_mini21.z.optional(import_mini21.z.boolean()),
|
|
6255
|
+
networkTimeout: import_mini21.z.optional(import_mini21.z.number()),
|
|
6256
|
+
timeout: import_mini21.z.optional(import_mini21.z.number()),
|
|
6257
|
+
trust: import_mini21.z.optional(import_mini21.z.boolean()),
|
|
6258
|
+
cwd: import_mini21.z.optional(import_mini21.z.string()),
|
|
6259
|
+
transport: import_mini21.z.optional(import_mini21.z.enum(["local", "stdio", "sse", "http"])),
|
|
6260
|
+
alwaysAllow: import_mini21.z.optional(import_mini21.z.array(import_mini21.z.string())),
|
|
6261
|
+
tools: import_mini21.z.optional(import_mini21.z.array(import_mini21.z.string())),
|
|
6262
|
+
kiroAutoApprove: import_mini21.z.optional(import_mini21.z.array(import_mini21.z.string())),
|
|
6263
|
+
kiroAutoBlock: import_mini21.z.optional(import_mini21.z.array(import_mini21.z.string())),
|
|
6264
|
+
headers: import_mini21.z.optional(import_mini21.z.record(import_mini21.z.string(), import_mini21.z.string())),
|
|
6265
|
+
enabledTools: import_mini21.z.optional(import_mini21.z.array(import_mini21.z.string())),
|
|
6266
|
+
disabledTools: import_mini21.z.optional(import_mini21.z.array(import_mini21.z.string()))
|
|
6295
6267
|
});
|
|
6296
|
-
var McpServersSchema =
|
|
6268
|
+
var McpServersSchema = import_mini21.z.record(import_mini21.z.string(), McpServerSchema);
|
|
6297
6269
|
function isMcpServers(value) {
|
|
6298
6270
|
return value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6299
6271
|
}
|
|
6300
6272
|
|
|
6301
6273
|
// src/features/mcp/rulesync-mcp.ts
|
|
6302
|
-
var RulesyncMcpServerSchema =
|
|
6303
|
-
targets:
|
|
6304
|
-
description:
|
|
6305
|
-
exposed:
|
|
6274
|
+
var RulesyncMcpServerSchema = import_mini22.z.extend(McpServerSchema, {
|
|
6275
|
+
targets: import_mini22.z.optional(RulesyncTargetsSchema),
|
|
6276
|
+
description: import_mini22.z.optional(import_mini22.z.string()),
|
|
6277
|
+
exposed: import_mini22.z.optional(import_mini22.z.boolean())
|
|
6306
6278
|
});
|
|
6307
|
-
var RulesyncMcpConfigSchema =
|
|
6308
|
-
mcpServers:
|
|
6279
|
+
var RulesyncMcpConfigSchema = import_mini22.z.object({
|
|
6280
|
+
mcpServers: import_mini22.z.record(import_mini22.z.string(), RulesyncMcpServerSchema)
|
|
6309
6281
|
});
|
|
6310
|
-
var RulesyncMcpFileSchema =
|
|
6311
|
-
$schema:
|
|
6282
|
+
var RulesyncMcpFileSchema = import_mini22.z.looseObject({
|
|
6283
|
+
$schema: import_mini22.z.optional(import_mini22.z.string()),
|
|
6312
6284
|
...RulesyncMcpConfigSchema.shape
|
|
6313
6285
|
});
|
|
6314
6286
|
var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
|
|
@@ -7511,25 +7483,25 @@ var JunieMcp = class _JunieMcp extends ToolMcp {
|
|
|
7511
7483
|
// src/features/mcp/kilo-mcp.ts
|
|
7512
7484
|
var import_node_path57 = require("path");
|
|
7513
7485
|
var import_jsonc_parser2 = require("jsonc-parser");
|
|
7514
|
-
var
|
|
7515
|
-
var KiloMcpLocalServerSchema =
|
|
7516
|
-
type:
|
|
7517
|
-
command:
|
|
7518
|
-
environment:
|
|
7519
|
-
enabled:
|
|
7520
|
-
cwd:
|
|
7486
|
+
var import_mini23 = require("zod/mini");
|
|
7487
|
+
var KiloMcpLocalServerSchema = import_mini23.z.object({
|
|
7488
|
+
type: import_mini23.z.literal("local"),
|
|
7489
|
+
command: import_mini23.z.array(import_mini23.z.string()),
|
|
7490
|
+
environment: import_mini23.z.optional(import_mini23.z.record(import_mini23.z.string(), import_mini23.z.string())),
|
|
7491
|
+
enabled: import_mini23.z._default(import_mini23.z.boolean(), true),
|
|
7492
|
+
cwd: import_mini23.z.optional(import_mini23.z.string())
|
|
7521
7493
|
});
|
|
7522
|
-
var KiloMcpRemoteServerSchema =
|
|
7523
|
-
type:
|
|
7524
|
-
url:
|
|
7525
|
-
headers:
|
|
7526
|
-
enabled:
|
|
7494
|
+
var KiloMcpRemoteServerSchema = import_mini23.z.object({
|
|
7495
|
+
type: import_mini23.z.literal("remote"),
|
|
7496
|
+
url: import_mini23.z.string(),
|
|
7497
|
+
headers: import_mini23.z.optional(import_mini23.z.record(import_mini23.z.string(), import_mini23.z.string())),
|
|
7498
|
+
enabled: import_mini23.z._default(import_mini23.z.boolean(), true)
|
|
7527
7499
|
});
|
|
7528
|
-
var KiloMcpServerSchema =
|
|
7529
|
-
var KiloConfigSchema =
|
|
7530
|
-
$schema:
|
|
7531
|
-
mcp:
|
|
7532
|
-
tools:
|
|
7500
|
+
var KiloMcpServerSchema = import_mini23.z.union([KiloMcpLocalServerSchema, KiloMcpRemoteServerSchema]);
|
|
7501
|
+
var KiloConfigSchema = import_mini23.z.looseObject({
|
|
7502
|
+
$schema: import_mini23.z.optional(import_mini23.z.string()),
|
|
7503
|
+
mcp: import_mini23.z.optional(import_mini23.z.record(import_mini23.z.string(), KiloMcpServerSchema)),
|
|
7504
|
+
tools: import_mini23.z.optional(import_mini23.z.record(import_mini23.z.string(), import_mini23.z.boolean()))
|
|
7533
7505
|
});
|
|
7534
7506
|
function convertFromKiloFormat(kiloMcp, tools) {
|
|
7535
7507
|
return Object.fromEntries(
|
|
@@ -7826,28 +7798,28 @@ var KiroMcp = class _KiroMcp extends ToolMcp {
|
|
|
7826
7798
|
// src/features/mcp/opencode-mcp.ts
|
|
7827
7799
|
var import_node_path59 = require("path");
|
|
7828
7800
|
var import_jsonc_parser3 = require("jsonc-parser");
|
|
7829
|
-
var
|
|
7830
|
-
var OpencodeMcpLocalServerSchema =
|
|
7831
|
-
type:
|
|
7832
|
-
command:
|
|
7833
|
-
environment:
|
|
7834
|
-
enabled:
|
|
7835
|
-
cwd:
|
|
7801
|
+
var import_mini24 = require("zod/mini");
|
|
7802
|
+
var OpencodeMcpLocalServerSchema = import_mini24.z.object({
|
|
7803
|
+
type: import_mini24.z.literal("local"),
|
|
7804
|
+
command: import_mini24.z.array(import_mini24.z.string()),
|
|
7805
|
+
environment: import_mini24.z.optional(import_mini24.z.record(import_mini24.z.string(), import_mini24.z.string())),
|
|
7806
|
+
enabled: import_mini24.z._default(import_mini24.z.boolean(), true),
|
|
7807
|
+
cwd: import_mini24.z.optional(import_mini24.z.string())
|
|
7836
7808
|
});
|
|
7837
|
-
var OpencodeMcpRemoteServerSchema =
|
|
7838
|
-
type:
|
|
7839
|
-
url:
|
|
7840
|
-
headers:
|
|
7841
|
-
enabled:
|
|
7809
|
+
var OpencodeMcpRemoteServerSchema = import_mini24.z.object({
|
|
7810
|
+
type: import_mini24.z.literal("remote"),
|
|
7811
|
+
url: import_mini24.z.string(),
|
|
7812
|
+
headers: import_mini24.z.optional(import_mini24.z.record(import_mini24.z.string(), import_mini24.z.string())),
|
|
7813
|
+
enabled: import_mini24.z._default(import_mini24.z.boolean(), true)
|
|
7842
7814
|
});
|
|
7843
|
-
var OpencodeMcpServerSchema =
|
|
7815
|
+
var OpencodeMcpServerSchema = import_mini24.z.union([
|
|
7844
7816
|
OpencodeMcpLocalServerSchema,
|
|
7845
7817
|
OpencodeMcpRemoteServerSchema
|
|
7846
7818
|
]);
|
|
7847
|
-
var OpencodeConfigSchema =
|
|
7848
|
-
$schema:
|
|
7849
|
-
mcp:
|
|
7850
|
-
tools:
|
|
7819
|
+
var OpencodeConfigSchema = import_mini24.z.looseObject({
|
|
7820
|
+
$schema: import_mini24.z.optional(import_mini24.z.string()),
|
|
7821
|
+
mcp: import_mini24.z.optional(import_mini24.z.record(import_mini24.z.string(), OpencodeMcpServerSchema)),
|
|
7822
|
+
tools: import_mini24.z.optional(import_mini24.z.record(import_mini24.z.string(), import_mini24.z.boolean()))
|
|
7851
7823
|
});
|
|
7852
7824
|
function convertFromOpencodeFormat(opencodeMcp, tools) {
|
|
7853
7825
|
return Object.fromEntries(
|
|
@@ -8318,7 +8290,7 @@ var mcpProcessorToolTargetTuple = [
|
|
|
8318
8290
|
"roo",
|
|
8319
8291
|
"rovodev"
|
|
8320
8292
|
];
|
|
8321
|
-
var McpProcessorToolTargetSchema =
|
|
8293
|
+
var McpProcessorToolTargetSchema = import_mini25.z.enum(mcpProcessorToolTargetTuple);
|
|
8322
8294
|
var toolMcpFactories = /* @__PURE__ */ new Map([
|
|
8323
8295
|
[
|
|
8324
8296
|
"claudecode",
|
|
@@ -8659,7 +8631,7 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
8659
8631
|
// src/features/rules/rules-processor.ts
|
|
8660
8632
|
var import_node_path132 = require("path");
|
|
8661
8633
|
var import_toon = require("@toon-format/toon");
|
|
8662
|
-
var
|
|
8634
|
+
var import_mini65 = require("zod/mini");
|
|
8663
8635
|
|
|
8664
8636
|
// src/constants/general.ts
|
|
8665
8637
|
var SKILL_FILE_NAME = "SKILL.md";
|
|
@@ -8669,7 +8641,7 @@ var import_node_path65 = require("path");
|
|
|
8669
8641
|
|
|
8670
8642
|
// src/features/skills/simulated-skill.ts
|
|
8671
8643
|
var import_node_path64 = require("path");
|
|
8672
|
-
var
|
|
8644
|
+
var import_mini26 = require("zod/mini");
|
|
8673
8645
|
|
|
8674
8646
|
// src/features/skills/tool-skill.ts
|
|
8675
8647
|
var import_node_path63 = require("path");
|
|
@@ -8906,9 +8878,9 @@ var ToolSkill = class extends AiDir {
|
|
|
8906
8878
|
};
|
|
8907
8879
|
|
|
8908
8880
|
// src/features/skills/simulated-skill.ts
|
|
8909
|
-
var SimulatedSkillFrontmatterSchema =
|
|
8910
|
-
name:
|
|
8911
|
-
description:
|
|
8881
|
+
var SimulatedSkillFrontmatterSchema = import_mini26.z.looseObject({
|
|
8882
|
+
name: import_mini26.z.string(),
|
|
8883
|
+
description: import_mini26.z.string()
|
|
8912
8884
|
});
|
|
8913
8885
|
var SimulatedSkill = class extends ToolSkill {
|
|
8914
8886
|
frontmatter;
|
|
@@ -9135,49 +9107,49 @@ var FactorydroidSkill = class _FactorydroidSkill extends SimulatedSkill {
|
|
|
9135
9107
|
|
|
9136
9108
|
// src/features/skills/rovodev-skill.ts
|
|
9137
9109
|
var import_node_path68 = require("path");
|
|
9138
|
-
var
|
|
9110
|
+
var import_mini28 = require("zod/mini");
|
|
9139
9111
|
|
|
9140
9112
|
// src/features/skills/rulesync-skill.ts
|
|
9141
9113
|
var import_node_path67 = require("path");
|
|
9142
|
-
var
|
|
9143
|
-
var RulesyncSkillFrontmatterSchemaInternal =
|
|
9144
|
-
name:
|
|
9145
|
-
description:
|
|
9146
|
-
targets:
|
|
9147
|
-
claudecode:
|
|
9148
|
-
|
|
9149
|
-
"allowed-tools":
|
|
9150
|
-
model:
|
|
9151
|
-
"disable-model-invocation":
|
|
9114
|
+
var import_mini27 = require("zod/mini");
|
|
9115
|
+
var RulesyncSkillFrontmatterSchemaInternal = import_mini27.z.looseObject({
|
|
9116
|
+
name: import_mini27.z.string(),
|
|
9117
|
+
description: import_mini27.z.string(),
|
|
9118
|
+
targets: import_mini27.z._default(RulesyncTargetsSchema, ["*"]),
|
|
9119
|
+
claudecode: import_mini27.z.optional(
|
|
9120
|
+
import_mini27.z.looseObject({
|
|
9121
|
+
"allowed-tools": import_mini27.z.optional(import_mini27.z.array(import_mini27.z.string())),
|
|
9122
|
+
model: import_mini27.z.optional(import_mini27.z.string()),
|
|
9123
|
+
"disable-model-invocation": import_mini27.z.optional(import_mini27.z.boolean())
|
|
9152
9124
|
})
|
|
9153
9125
|
),
|
|
9154
|
-
codexcli:
|
|
9155
|
-
|
|
9156
|
-
"short-description":
|
|
9126
|
+
codexcli: import_mini27.z.optional(
|
|
9127
|
+
import_mini27.z.looseObject({
|
|
9128
|
+
"short-description": import_mini27.z.optional(import_mini27.z.string())
|
|
9157
9129
|
})
|
|
9158
9130
|
),
|
|
9159
|
-
opencode:
|
|
9160
|
-
|
|
9161
|
-
"allowed-tools":
|
|
9131
|
+
opencode: import_mini27.z.optional(
|
|
9132
|
+
import_mini27.z.looseObject({
|
|
9133
|
+
"allowed-tools": import_mini27.z.optional(import_mini27.z.array(import_mini27.z.string()))
|
|
9162
9134
|
})
|
|
9163
9135
|
),
|
|
9164
|
-
kilo:
|
|
9165
|
-
|
|
9166
|
-
"allowed-tools":
|
|
9136
|
+
kilo: import_mini27.z.optional(
|
|
9137
|
+
import_mini27.z.looseObject({
|
|
9138
|
+
"allowed-tools": import_mini27.z.optional(import_mini27.z.array(import_mini27.z.string()))
|
|
9167
9139
|
})
|
|
9168
9140
|
),
|
|
9169
|
-
deepagents:
|
|
9170
|
-
|
|
9171
|
-
"allowed-tools":
|
|
9141
|
+
deepagents: import_mini27.z.optional(
|
|
9142
|
+
import_mini27.z.looseObject({
|
|
9143
|
+
"allowed-tools": import_mini27.z.optional(import_mini27.z.array(import_mini27.z.string()))
|
|
9172
9144
|
})
|
|
9173
9145
|
),
|
|
9174
|
-
copilot:
|
|
9175
|
-
|
|
9176
|
-
license:
|
|
9146
|
+
copilot: import_mini27.z.optional(
|
|
9147
|
+
import_mini27.z.looseObject({
|
|
9148
|
+
license: import_mini27.z.optional(import_mini27.z.string())
|
|
9177
9149
|
})
|
|
9178
9150
|
),
|
|
9179
|
-
cline:
|
|
9180
|
-
roo:
|
|
9151
|
+
cline: import_mini27.z.optional(import_mini27.z.looseObject({})),
|
|
9152
|
+
roo: import_mini27.z.optional(import_mini27.z.looseObject({}))
|
|
9181
9153
|
});
|
|
9182
9154
|
var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
|
|
9183
9155
|
var RulesyncSkill = class _RulesyncSkill extends AiDir {
|
|
@@ -9274,9 +9246,9 @@ var RulesyncSkill = class _RulesyncSkill extends AiDir {
|
|
|
9274
9246
|
};
|
|
9275
9247
|
|
|
9276
9248
|
// src/features/skills/rovodev-skill.ts
|
|
9277
|
-
var RovodevSkillFrontmatterSchema =
|
|
9278
|
-
name:
|
|
9279
|
-
description:
|
|
9249
|
+
var RovodevSkillFrontmatterSchema = import_mini28.z.looseObject({
|
|
9250
|
+
name: import_mini28.z.string(),
|
|
9251
|
+
description: import_mini28.z.string()
|
|
9280
9252
|
});
|
|
9281
9253
|
var RovodevSkill = class _RovodevSkill extends ToolSkill {
|
|
9282
9254
|
constructor({
|
|
@@ -9448,7 +9420,7 @@ var RovodevSkill = class _RovodevSkill extends ToolSkill {
|
|
|
9448
9420
|
|
|
9449
9421
|
// src/features/skills/skills-processor.ts
|
|
9450
9422
|
var import_node_path87 = require("path");
|
|
9451
|
-
var
|
|
9423
|
+
var import_mini45 = require("zod/mini");
|
|
9452
9424
|
|
|
9453
9425
|
// src/types/dir-feature-processor.ts
|
|
9454
9426
|
var import_node_path69 = require("path");
|
|
@@ -9587,10 +9559,10 @@ var DirFeatureProcessor = class {
|
|
|
9587
9559
|
|
|
9588
9560
|
// src/features/skills/agentsskills-skill.ts
|
|
9589
9561
|
var import_node_path70 = require("path");
|
|
9590
|
-
var
|
|
9591
|
-
var AgentsSkillsSkillFrontmatterSchema =
|
|
9592
|
-
name:
|
|
9593
|
-
description:
|
|
9562
|
+
var import_mini29 = require("zod/mini");
|
|
9563
|
+
var AgentsSkillsSkillFrontmatterSchema = import_mini29.z.looseObject({
|
|
9564
|
+
name: import_mini29.z.string(),
|
|
9565
|
+
description: import_mini29.z.string()
|
|
9594
9566
|
});
|
|
9595
9567
|
var AgentsSkillsSkill = class _AgentsSkillsSkill extends ToolSkill {
|
|
9596
9568
|
constructor({
|
|
@@ -9745,10 +9717,10 @@ var AgentsSkillsSkill = class _AgentsSkillsSkill extends ToolSkill {
|
|
|
9745
9717
|
|
|
9746
9718
|
// src/features/skills/antigravity-skill.ts
|
|
9747
9719
|
var import_node_path71 = require("path");
|
|
9748
|
-
var
|
|
9749
|
-
var AntigravitySkillFrontmatterSchema =
|
|
9750
|
-
name:
|
|
9751
|
-
description:
|
|
9720
|
+
var import_mini30 = require("zod/mini");
|
|
9721
|
+
var AntigravitySkillFrontmatterSchema = import_mini30.z.looseObject({
|
|
9722
|
+
name: import_mini30.z.string(),
|
|
9723
|
+
description: import_mini30.z.string()
|
|
9752
9724
|
});
|
|
9753
9725
|
var AntigravitySkill = class _AntigravitySkill extends ToolSkill {
|
|
9754
9726
|
constructor({
|
|
@@ -9906,13 +9878,13 @@ var AntigravitySkill = class _AntigravitySkill extends ToolSkill {
|
|
|
9906
9878
|
|
|
9907
9879
|
// src/features/skills/claudecode-skill.ts
|
|
9908
9880
|
var import_node_path72 = require("path");
|
|
9909
|
-
var
|
|
9910
|
-
var ClaudecodeSkillFrontmatterSchema =
|
|
9911
|
-
name:
|
|
9912
|
-
description:
|
|
9913
|
-
"allowed-tools":
|
|
9914
|
-
model:
|
|
9915
|
-
"disable-model-invocation":
|
|
9881
|
+
var import_mini31 = require("zod/mini");
|
|
9882
|
+
var ClaudecodeSkillFrontmatterSchema = import_mini31.z.looseObject({
|
|
9883
|
+
name: import_mini31.z.string(),
|
|
9884
|
+
description: import_mini31.z.string(),
|
|
9885
|
+
"allowed-tools": import_mini31.z.optional(import_mini31.z.array(import_mini31.z.string())),
|
|
9886
|
+
model: import_mini31.z.optional(import_mini31.z.string()),
|
|
9887
|
+
"disable-model-invocation": import_mini31.z.optional(import_mini31.z.boolean())
|
|
9916
9888
|
});
|
|
9917
9889
|
var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
9918
9890
|
constructor({
|
|
@@ -10082,10 +10054,10 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
|
10082
10054
|
|
|
10083
10055
|
// src/features/skills/cline-skill.ts
|
|
10084
10056
|
var import_node_path73 = require("path");
|
|
10085
|
-
var
|
|
10086
|
-
var ClineSkillFrontmatterSchema =
|
|
10087
|
-
name:
|
|
10088
|
-
description:
|
|
10057
|
+
var import_mini32 = require("zod/mini");
|
|
10058
|
+
var ClineSkillFrontmatterSchema = import_mini32.z.looseObject({
|
|
10059
|
+
name: import_mini32.z.string(),
|
|
10060
|
+
description: import_mini32.z.string()
|
|
10089
10061
|
});
|
|
10090
10062
|
var ClineSkill = class _ClineSkill extends ToolSkill {
|
|
10091
10063
|
constructor({
|
|
@@ -10255,13 +10227,13 @@ var ClineSkill = class _ClineSkill extends ToolSkill {
|
|
|
10255
10227
|
|
|
10256
10228
|
// src/features/skills/codexcli-skill.ts
|
|
10257
10229
|
var import_node_path74 = require("path");
|
|
10258
|
-
var
|
|
10259
|
-
var CodexCliSkillFrontmatterSchema =
|
|
10260
|
-
name:
|
|
10261
|
-
description:
|
|
10262
|
-
metadata:
|
|
10263
|
-
|
|
10264
|
-
"short-description":
|
|
10230
|
+
var import_mini33 = require("zod/mini");
|
|
10231
|
+
var CodexCliSkillFrontmatterSchema = import_mini33.z.looseObject({
|
|
10232
|
+
name: import_mini33.z.string(),
|
|
10233
|
+
description: import_mini33.z.string(),
|
|
10234
|
+
metadata: import_mini33.z.optional(
|
|
10235
|
+
import_mini33.z.looseObject({
|
|
10236
|
+
"short-description": import_mini33.z.optional(import_mini33.z.string())
|
|
10265
10237
|
})
|
|
10266
10238
|
)
|
|
10267
10239
|
});
|
|
@@ -10426,11 +10398,11 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
|
|
|
10426
10398
|
|
|
10427
10399
|
// src/features/skills/copilot-skill.ts
|
|
10428
10400
|
var import_node_path75 = require("path");
|
|
10429
|
-
var
|
|
10430
|
-
var CopilotSkillFrontmatterSchema =
|
|
10431
|
-
name:
|
|
10432
|
-
description:
|
|
10433
|
-
license:
|
|
10401
|
+
var import_mini34 = require("zod/mini");
|
|
10402
|
+
var CopilotSkillFrontmatterSchema = import_mini34.z.looseObject({
|
|
10403
|
+
name: import_mini34.z.string(),
|
|
10404
|
+
description: import_mini34.z.string(),
|
|
10405
|
+
license: import_mini34.z.optional(import_mini34.z.string())
|
|
10434
10406
|
});
|
|
10435
10407
|
var CopilotSkill = class _CopilotSkill extends ToolSkill {
|
|
10436
10408
|
constructor({
|
|
@@ -10591,10 +10563,10 @@ var CopilotSkill = class _CopilotSkill extends ToolSkill {
|
|
|
10591
10563
|
|
|
10592
10564
|
// src/features/skills/cursor-skill.ts
|
|
10593
10565
|
var import_node_path76 = require("path");
|
|
10594
|
-
var
|
|
10595
|
-
var CursorSkillFrontmatterSchema =
|
|
10596
|
-
name:
|
|
10597
|
-
description:
|
|
10566
|
+
var import_mini35 = require("zod/mini");
|
|
10567
|
+
var CursorSkillFrontmatterSchema = import_mini35.z.looseObject({
|
|
10568
|
+
name: import_mini35.z.string(),
|
|
10569
|
+
description: import_mini35.z.string()
|
|
10598
10570
|
});
|
|
10599
10571
|
var CursorSkill = class _CursorSkill extends ToolSkill {
|
|
10600
10572
|
constructor({
|
|
@@ -10746,11 +10718,11 @@ var CursorSkill = class _CursorSkill extends ToolSkill {
|
|
|
10746
10718
|
|
|
10747
10719
|
// src/features/skills/deepagents-skill.ts
|
|
10748
10720
|
var import_node_path77 = require("path");
|
|
10749
|
-
var
|
|
10750
|
-
var DeepagentsSkillFrontmatterSchema =
|
|
10751
|
-
name:
|
|
10752
|
-
description:
|
|
10753
|
-
"allowed-tools":
|
|
10721
|
+
var import_mini36 = require("zod/mini");
|
|
10722
|
+
var DeepagentsSkillFrontmatterSchema = import_mini36.z.looseObject({
|
|
10723
|
+
name: import_mini36.z.string(),
|
|
10724
|
+
description: import_mini36.z.string(),
|
|
10725
|
+
"allowed-tools": import_mini36.z.optional(import_mini36.z.array(import_mini36.z.string()))
|
|
10754
10726
|
});
|
|
10755
10727
|
var DeepagentsSkill = class _DeepagentsSkill extends ToolSkill {
|
|
10756
10728
|
constructor({
|
|
@@ -10908,10 +10880,10 @@ var DeepagentsSkill = class _DeepagentsSkill extends ToolSkill {
|
|
|
10908
10880
|
|
|
10909
10881
|
// src/features/skills/geminicli-skill.ts
|
|
10910
10882
|
var import_node_path78 = require("path");
|
|
10911
|
-
var
|
|
10912
|
-
var GeminiCliSkillFrontmatterSchema =
|
|
10913
|
-
name:
|
|
10914
|
-
description:
|
|
10883
|
+
var import_mini37 = require("zod/mini");
|
|
10884
|
+
var GeminiCliSkillFrontmatterSchema = import_mini37.z.looseObject({
|
|
10885
|
+
name: import_mini37.z.string(),
|
|
10886
|
+
description: import_mini37.z.string()
|
|
10915
10887
|
});
|
|
10916
10888
|
var GeminiCliSkill = class _GeminiCliSkill extends ToolSkill {
|
|
10917
10889
|
constructor({
|
|
@@ -11065,10 +11037,10 @@ var GeminiCliSkill = class _GeminiCliSkill extends ToolSkill {
|
|
|
11065
11037
|
|
|
11066
11038
|
// src/features/skills/junie-skill.ts
|
|
11067
11039
|
var import_node_path79 = require("path");
|
|
11068
|
-
var
|
|
11069
|
-
var JunieSkillFrontmatterSchema =
|
|
11070
|
-
name:
|
|
11071
|
-
description:
|
|
11040
|
+
var import_mini38 = require("zod/mini");
|
|
11041
|
+
var JunieSkillFrontmatterSchema = import_mini38.z.looseObject({
|
|
11042
|
+
name: import_mini38.z.string(),
|
|
11043
|
+
description: import_mini38.z.string()
|
|
11072
11044
|
});
|
|
11073
11045
|
var JunieSkill = class _JunieSkill extends ToolSkill {
|
|
11074
11046
|
constructor({
|
|
@@ -11241,11 +11213,11 @@ var JunieSkill = class _JunieSkill extends ToolSkill {
|
|
|
11241
11213
|
|
|
11242
11214
|
// src/features/skills/kilo-skill.ts
|
|
11243
11215
|
var import_node_path80 = require("path");
|
|
11244
|
-
var
|
|
11245
|
-
var KiloSkillFrontmatterSchema =
|
|
11246
|
-
name:
|
|
11247
|
-
description:
|
|
11248
|
-
"allowed-tools":
|
|
11216
|
+
var import_mini39 = require("zod/mini");
|
|
11217
|
+
var KiloSkillFrontmatterSchema = import_mini39.z.looseObject({
|
|
11218
|
+
name: import_mini39.z.string(),
|
|
11219
|
+
description: import_mini39.z.string(),
|
|
11220
|
+
"allowed-tools": import_mini39.z.optional(import_mini39.z.array(import_mini39.z.string()))
|
|
11249
11221
|
});
|
|
11250
11222
|
var KiloSkill = class _KiloSkill extends ToolSkill {
|
|
11251
11223
|
constructor({
|
|
@@ -11402,10 +11374,10 @@ var KiloSkill = class _KiloSkill extends ToolSkill {
|
|
|
11402
11374
|
|
|
11403
11375
|
// src/features/skills/kiro-skill.ts
|
|
11404
11376
|
var import_node_path81 = require("path");
|
|
11405
|
-
var
|
|
11406
|
-
var KiroSkillFrontmatterSchema =
|
|
11407
|
-
name:
|
|
11408
|
-
description:
|
|
11377
|
+
var import_mini40 = require("zod/mini");
|
|
11378
|
+
var KiroSkillFrontmatterSchema = import_mini40.z.looseObject({
|
|
11379
|
+
name: import_mini40.z.string(),
|
|
11380
|
+
description: import_mini40.z.string()
|
|
11409
11381
|
});
|
|
11410
11382
|
var KiroSkill = class _KiroSkill extends ToolSkill {
|
|
11411
11383
|
constructor({
|
|
@@ -11579,11 +11551,11 @@ var KiroSkill = class _KiroSkill extends ToolSkill {
|
|
|
11579
11551
|
|
|
11580
11552
|
// src/features/skills/opencode-skill.ts
|
|
11581
11553
|
var import_node_path82 = require("path");
|
|
11582
|
-
var
|
|
11583
|
-
var OpenCodeSkillFrontmatterSchema =
|
|
11584
|
-
name:
|
|
11585
|
-
description:
|
|
11586
|
-
"allowed-tools":
|
|
11554
|
+
var import_mini41 = require("zod/mini");
|
|
11555
|
+
var OpenCodeSkillFrontmatterSchema = import_mini41.z.looseObject({
|
|
11556
|
+
name: import_mini41.z.string(),
|
|
11557
|
+
description: import_mini41.z.string(),
|
|
11558
|
+
"allowed-tools": import_mini41.z.optional(import_mini41.z.array(import_mini41.z.string()))
|
|
11587
11559
|
});
|
|
11588
11560
|
var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
|
|
11589
11561
|
constructor({
|
|
@@ -11740,10 +11712,10 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
|
|
|
11740
11712
|
|
|
11741
11713
|
// src/features/skills/replit-skill.ts
|
|
11742
11714
|
var import_node_path83 = require("path");
|
|
11743
|
-
var
|
|
11744
|
-
var ReplitSkillFrontmatterSchema =
|
|
11745
|
-
name:
|
|
11746
|
-
description:
|
|
11715
|
+
var import_mini42 = require("zod/mini");
|
|
11716
|
+
var ReplitSkillFrontmatterSchema = import_mini42.z.looseObject({
|
|
11717
|
+
name: import_mini42.z.string(),
|
|
11718
|
+
description: import_mini42.z.string()
|
|
11747
11719
|
});
|
|
11748
11720
|
var ReplitSkill = class _ReplitSkill extends ToolSkill {
|
|
11749
11721
|
constructor({
|
|
@@ -11898,10 +11870,10 @@ var ReplitSkill = class _ReplitSkill extends ToolSkill {
|
|
|
11898
11870
|
|
|
11899
11871
|
// src/features/skills/roo-skill.ts
|
|
11900
11872
|
var import_node_path84 = require("path");
|
|
11901
|
-
var
|
|
11902
|
-
var RooSkillFrontmatterSchema =
|
|
11903
|
-
name:
|
|
11904
|
-
description:
|
|
11873
|
+
var import_mini43 = require("zod/mini");
|
|
11874
|
+
var RooSkillFrontmatterSchema = import_mini43.z.looseObject({
|
|
11875
|
+
name: import_mini43.z.string(),
|
|
11876
|
+
description: import_mini43.z.string()
|
|
11905
11877
|
});
|
|
11906
11878
|
var RooSkill = class _RooSkill extends ToolSkill {
|
|
11907
11879
|
constructor({
|
|
@@ -12090,10 +12062,10 @@ async function getLocalSkillDirNames(baseDir) {
|
|
|
12090
12062
|
|
|
12091
12063
|
// src/features/skills/windsurf-skill.ts
|
|
12092
12064
|
var import_node_path86 = require("path");
|
|
12093
|
-
var
|
|
12094
|
-
var WindsurfSkillFrontmatterSchema =
|
|
12095
|
-
name:
|
|
12096
|
-
description:
|
|
12065
|
+
var import_mini44 = require("zod/mini");
|
|
12066
|
+
var WindsurfSkillFrontmatterSchema = import_mini44.z.looseObject({
|
|
12067
|
+
name: import_mini44.z.string(),
|
|
12068
|
+
description: import_mini44.z.string()
|
|
12097
12069
|
});
|
|
12098
12070
|
var WindsurfSkill = class _WindsurfSkill extends ToolSkill {
|
|
12099
12071
|
constructor({
|
|
@@ -12271,7 +12243,7 @@ var skillsProcessorToolTargetTuple = [
|
|
|
12271
12243
|
"rovodev",
|
|
12272
12244
|
"windsurf"
|
|
12273
12245
|
];
|
|
12274
|
-
var SkillsProcessorToolTargetSchema =
|
|
12246
|
+
var SkillsProcessorToolTargetSchema = import_mini45.z.enum(skillsProcessorToolTargetTuple);
|
|
12275
12247
|
var toolSkillFactories = /* @__PURE__ */ new Map([
|
|
12276
12248
|
[
|
|
12277
12249
|
"agentsmd",
|
|
@@ -12650,7 +12622,7 @@ var import_node_path89 = require("path");
|
|
|
12650
12622
|
|
|
12651
12623
|
// src/features/subagents/simulated-subagent.ts
|
|
12652
12624
|
var import_node_path88 = require("path");
|
|
12653
|
-
var
|
|
12625
|
+
var import_mini46 = require("zod/mini");
|
|
12654
12626
|
|
|
12655
12627
|
// src/features/subagents/tool-subagent.ts
|
|
12656
12628
|
var ToolSubagent = class extends ToolFile {
|
|
@@ -12702,9 +12674,9 @@ var ToolSubagent = class extends ToolFile {
|
|
|
12702
12674
|
};
|
|
12703
12675
|
|
|
12704
12676
|
// src/features/subagents/simulated-subagent.ts
|
|
12705
|
-
var SimulatedSubagentFrontmatterSchema =
|
|
12706
|
-
name:
|
|
12707
|
-
description:
|
|
12677
|
+
var SimulatedSubagentFrontmatterSchema = import_mini46.z.object({
|
|
12678
|
+
name: import_mini46.z.string(),
|
|
12679
|
+
description: import_mini46.z.optional(import_mini46.z.string())
|
|
12708
12680
|
});
|
|
12709
12681
|
var SimulatedSubagent = class extends ToolSubagent {
|
|
12710
12682
|
frontmatter;
|
|
@@ -12862,15 +12834,15 @@ var FactorydroidSubagent = class _FactorydroidSubagent extends SimulatedSubagent
|
|
|
12862
12834
|
|
|
12863
12835
|
// src/features/subagents/geminicli-subagent.ts
|
|
12864
12836
|
var import_node_path92 = require("path");
|
|
12865
|
-
var
|
|
12837
|
+
var import_mini48 = require("zod/mini");
|
|
12866
12838
|
|
|
12867
12839
|
// src/features/subagents/rulesync-subagent.ts
|
|
12868
12840
|
var import_node_path91 = require("path");
|
|
12869
|
-
var
|
|
12870
|
-
var RulesyncSubagentFrontmatterSchema =
|
|
12871
|
-
targets:
|
|
12872
|
-
name:
|
|
12873
|
-
description:
|
|
12841
|
+
var import_mini47 = require("zod/mini");
|
|
12842
|
+
var RulesyncSubagentFrontmatterSchema = import_mini47.z.looseObject({
|
|
12843
|
+
targets: import_mini47.z._default(RulesyncTargetsSchema, ["*"]),
|
|
12844
|
+
name: import_mini47.z.string(),
|
|
12845
|
+
description: import_mini47.z.optional(import_mini47.z.string())
|
|
12874
12846
|
});
|
|
12875
12847
|
var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
12876
12848
|
frontmatter;
|
|
@@ -12939,9 +12911,9 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
12939
12911
|
};
|
|
12940
12912
|
|
|
12941
12913
|
// src/features/subagents/geminicli-subagent.ts
|
|
12942
|
-
var GeminiCliSubagentFrontmatterSchema =
|
|
12943
|
-
name:
|
|
12944
|
-
description:
|
|
12914
|
+
var GeminiCliSubagentFrontmatterSchema = import_mini48.z.looseObject({
|
|
12915
|
+
name: import_mini48.z.string(),
|
|
12916
|
+
description: import_mini48.z.optional(import_mini48.z.string())
|
|
12945
12917
|
});
|
|
12946
12918
|
var GeminiCliSubagent = class _GeminiCliSubagent extends ToolSubagent {
|
|
12947
12919
|
frontmatter;
|
|
@@ -13114,10 +13086,10 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
|
|
|
13114
13086
|
|
|
13115
13087
|
// src/features/subagents/rovodev-subagent.ts
|
|
13116
13088
|
var import_node_path94 = require("path");
|
|
13117
|
-
var
|
|
13118
|
-
var RovodevSubagentFrontmatterSchema =
|
|
13119
|
-
name:
|
|
13120
|
-
description:
|
|
13089
|
+
var import_mini49 = require("zod/mini");
|
|
13090
|
+
var RovodevSubagentFrontmatterSchema = import_mini49.z.looseObject({
|
|
13091
|
+
name: import_mini49.z.string(),
|
|
13092
|
+
description: import_mini49.z.optional(import_mini49.z.string())
|
|
13121
13093
|
});
|
|
13122
13094
|
var RovodevSubagent = class _RovodevSubagent extends ToolSubagent {
|
|
13123
13095
|
frontmatter;
|
|
@@ -13259,18 +13231,18 @@ var RovodevSubagent = class _RovodevSubagent extends ToolSubagent {
|
|
|
13259
13231
|
|
|
13260
13232
|
// src/features/subagents/subagents-processor.ts
|
|
13261
13233
|
var import_node_path105 = require("path");
|
|
13262
|
-
var
|
|
13234
|
+
var import_mini58 = require("zod/mini");
|
|
13263
13235
|
|
|
13264
13236
|
// src/features/subagents/claudecode-subagent.ts
|
|
13265
13237
|
var import_node_path95 = require("path");
|
|
13266
|
-
var
|
|
13267
|
-
var ClaudecodeSubagentFrontmatterSchema =
|
|
13268
|
-
name:
|
|
13269
|
-
description:
|
|
13270
|
-
model:
|
|
13271
|
-
tools:
|
|
13272
|
-
permissionMode:
|
|
13273
|
-
skills:
|
|
13238
|
+
var import_mini50 = require("zod/mini");
|
|
13239
|
+
var ClaudecodeSubagentFrontmatterSchema = import_mini50.z.looseObject({
|
|
13240
|
+
name: import_mini50.z.string(),
|
|
13241
|
+
description: import_mini50.z.optional(import_mini50.z.string()),
|
|
13242
|
+
model: import_mini50.z.optional(import_mini50.z.string()),
|
|
13243
|
+
tools: import_mini50.z.optional(import_mini50.z.union([import_mini50.z.string(), import_mini50.z.array(import_mini50.z.string())])),
|
|
13244
|
+
permissionMode: import_mini50.z.optional(import_mini50.z.string()),
|
|
13245
|
+
skills: import_mini50.z.optional(import_mini50.z.union([import_mini50.z.string(), import_mini50.z.array(import_mini50.z.string())]))
|
|
13274
13246
|
});
|
|
13275
13247
|
var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
13276
13248
|
frontmatter;
|
|
@@ -13426,16 +13398,16 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
13426
13398
|
// src/features/subagents/codexcli-subagent.ts
|
|
13427
13399
|
var import_node_path96 = require("path");
|
|
13428
13400
|
var smolToml4 = __toESM(require("smol-toml"), 1);
|
|
13429
|
-
var
|
|
13430
|
-
var CodexCliSubagentTomlSchema =
|
|
13431
|
-
name:
|
|
13432
|
-
description:
|
|
13433
|
-
developer_instructions:
|
|
13434
|
-
model:
|
|
13435
|
-
model_reasoning_effort:
|
|
13436
|
-
sandbox_mode:
|
|
13437
|
-
});
|
|
13438
|
-
function stringifyCodexCliSubagentToml(tomlObj) {
|
|
13401
|
+
var import_mini51 = require("zod/mini");
|
|
13402
|
+
var CodexCliSubagentTomlSchema = import_mini51.z.looseObject({
|
|
13403
|
+
name: import_mini51.z.string(),
|
|
13404
|
+
description: import_mini51.z.optional(import_mini51.z.string()),
|
|
13405
|
+
developer_instructions: import_mini51.z.optional(import_mini51.z.string()),
|
|
13406
|
+
model: import_mini51.z.optional(import_mini51.z.string()),
|
|
13407
|
+
model_reasoning_effort: import_mini51.z.optional(import_mini51.z.string()),
|
|
13408
|
+
sandbox_mode: import_mini51.z.optional(import_mini51.z.string())
|
|
13409
|
+
});
|
|
13410
|
+
function stringifyCodexCliSubagentToml(tomlObj) {
|
|
13439
13411
|
const { developer_instructions, ...restFields } = tomlObj;
|
|
13440
13412
|
const restToml = smolToml4.stringify(restFields).trimEnd();
|
|
13441
13413
|
if (developer_instructions === void 0) {
|
|
@@ -13599,12 +13571,12 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
|
|
|
13599
13571
|
|
|
13600
13572
|
// src/features/subagents/copilot-subagent.ts
|
|
13601
13573
|
var import_node_path97 = require("path");
|
|
13602
|
-
var
|
|
13574
|
+
var import_mini52 = require("zod/mini");
|
|
13603
13575
|
var REQUIRED_TOOL = "agent/runSubagent";
|
|
13604
|
-
var CopilotSubagentFrontmatterSchema =
|
|
13605
|
-
name:
|
|
13606
|
-
description:
|
|
13607
|
-
tools:
|
|
13576
|
+
var CopilotSubagentFrontmatterSchema = import_mini52.z.looseObject({
|
|
13577
|
+
name: import_mini52.z.string(),
|
|
13578
|
+
description: import_mini52.z.optional(import_mini52.z.string()),
|
|
13579
|
+
tools: import_mini52.z.optional(import_mini52.z.union([import_mini52.z.string(), import_mini52.z.array(import_mini52.z.string())]))
|
|
13608
13580
|
});
|
|
13609
13581
|
var normalizeTools = (tools) => {
|
|
13610
13582
|
if (!tools) {
|
|
@@ -13616,6 +13588,21 @@ var ensureRequiredTool = (tools) => {
|
|
|
13616
13588
|
const mergedTools = /* @__PURE__ */ new Set([REQUIRED_TOOL, ...tools]);
|
|
13617
13589
|
return Array.from(mergedTools);
|
|
13618
13590
|
};
|
|
13591
|
+
var toCopilotAgentFilePath = (relativeFilePath) => {
|
|
13592
|
+
if (relativeFilePath.endsWith(".agent.md")) {
|
|
13593
|
+
return relativeFilePath;
|
|
13594
|
+
}
|
|
13595
|
+
if (relativeFilePath.endsWith(".md")) {
|
|
13596
|
+
return relativeFilePath.replace(/\.md$/, ".agent.md");
|
|
13597
|
+
}
|
|
13598
|
+
return relativeFilePath;
|
|
13599
|
+
};
|
|
13600
|
+
var toRulesyncFilePath = (relativeFilePath) => {
|
|
13601
|
+
if (relativeFilePath.endsWith(".agent.md")) {
|
|
13602
|
+
return relativeFilePath.replace(/\.agent\.md$/, ".md");
|
|
13603
|
+
}
|
|
13604
|
+
return relativeFilePath;
|
|
13605
|
+
};
|
|
13619
13606
|
var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
|
|
13620
13607
|
frontmatter;
|
|
13621
13608
|
body;
|
|
@@ -13662,7 +13649,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
|
|
|
13662
13649
|
frontmatter: rulesyncFrontmatter,
|
|
13663
13650
|
body: this.body,
|
|
13664
13651
|
relativeDirPath: RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH,
|
|
13665
|
-
relativeFilePath: this.getRelativeFilePath(),
|
|
13652
|
+
relativeFilePath: toRulesyncFilePath(this.getRelativeFilePath()),
|
|
13666
13653
|
validate: true
|
|
13667
13654
|
});
|
|
13668
13655
|
}
|
|
@@ -13688,16 +13675,12 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
|
|
|
13688
13675
|
const body = rulesyncSubagent.getBody();
|
|
13689
13676
|
const fileContent = stringifyFrontmatter(body, copilotFrontmatter);
|
|
13690
13677
|
const paths = this.getSettablePaths({ global });
|
|
13691
|
-
let relativeFilePath = rulesyncSubagent.getRelativeFilePath();
|
|
13692
|
-
if (!relativeFilePath.endsWith(".agent.md")) {
|
|
13693
|
-
relativeFilePath = relativeFilePath.replace(/\.md$/, ".agent.md");
|
|
13694
|
-
}
|
|
13695
13678
|
return new _CopilotSubagent({
|
|
13696
13679
|
baseDir,
|
|
13697
13680
|
frontmatter: copilotFrontmatter,
|
|
13698
13681
|
body,
|
|
13699
13682
|
relativeDirPath: paths.relativeDirPath,
|
|
13700
|
-
relativeFilePath,
|
|
13683
|
+
relativeFilePath: toCopilotAgentFilePath(rulesyncSubagent.getRelativeFilePath()),
|
|
13701
13684
|
fileContent,
|
|
13702
13685
|
validate,
|
|
13703
13686
|
global
|
|
@@ -13769,10 +13752,10 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
|
|
|
13769
13752
|
|
|
13770
13753
|
// src/features/subagents/cursor-subagent.ts
|
|
13771
13754
|
var import_node_path98 = require("path");
|
|
13772
|
-
var
|
|
13773
|
-
var CursorSubagentFrontmatterSchema =
|
|
13774
|
-
name:
|
|
13775
|
-
description:
|
|
13755
|
+
var import_mini53 = require("zod/mini");
|
|
13756
|
+
var CursorSubagentFrontmatterSchema = import_mini53.z.looseObject({
|
|
13757
|
+
name: import_mini53.z.string(),
|
|
13758
|
+
description: import_mini53.z.optional(import_mini53.z.string())
|
|
13776
13759
|
});
|
|
13777
13760
|
var CursorSubagent = class _CursorSubagent extends ToolSubagent {
|
|
13778
13761
|
frontmatter;
|
|
@@ -13916,11 +13899,11 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
|
|
|
13916
13899
|
|
|
13917
13900
|
// src/features/subagents/deepagents-subagent.ts
|
|
13918
13901
|
var import_node_path99 = require("path");
|
|
13919
|
-
var
|
|
13920
|
-
var DeepagentsSubagentFrontmatterSchema =
|
|
13921
|
-
name:
|
|
13922
|
-
description:
|
|
13923
|
-
model:
|
|
13902
|
+
var import_mini54 = require("zod/mini");
|
|
13903
|
+
var DeepagentsSubagentFrontmatterSchema = import_mini54.z.looseObject({
|
|
13904
|
+
name: import_mini54.z.string(),
|
|
13905
|
+
description: import_mini54.z.optional(import_mini54.z.string()),
|
|
13906
|
+
model: import_mini54.z.optional(import_mini54.z.string())
|
|
13924
13907
|
});
|
|
13925
13908
|
var DeepagentsSubagent = class _DeepagentsSubagent extends ToolSubagent {
|
|
13926
13909
|
frontmatter;
|
|
@@ -14069,10 +14052,10 @@ var DeepagentsSubagent = class _DeepagentsSubagent extends ToolSubagent {
|
|
|
14069
14052
|
|
|
14070
14053
|
// src/features/subagents/junie-subagent.ts
|
|
14071
14054
|
var import_node_path100 = require("path");
|
|
14072
|
-
var
|
|
14073
|
-
var JunieSubagentFrontmatterSchema =
|
|
14074
|
-
name:
|
|
14075
|
-
description:
|
|
14055
|
+
var import_mini55 = require("zod/mini");
|
|
14056
|
+
var JunieSubagentFrontmatterSchema = import_mini55.z.looseObject({
|
|
14057
|
+
name: import_mini55.z.optional(import_mini55.z.string()),
|
|
14058
|
+
description: import_mini55.z.string()
|
|
14076
14059
|
});
|
|
14077
14060
|
var JunieSubagent = class _JunieSubagent extends ToolSubagent {
|
|
14078
14061
|
frontmatter;
|
|
@@ -14230,11 +14213,11 @@ var import_node_path102 = require("path");
|
|
|
14230
14213
|
|
|
14231
14214
|
// src/features/subagents/opencode-style-subagent.ts
|
|
14232
14215
|
var import_node_path101 = require("path");
|
|
14233
|
-
var
|
|
14234
|
-
var OpenCodeStyleSubagentFrontmatterSchema =
|
|
14235
|
-
description:
|
|
14236
|
-
mode:
|
|
14237
|
-
name:
|
|
14216
|
+
var import_mini56 = require("zod/mini");
|
|
14217
|
+
var OpenCodeStyleSubagentFrontmatterSchema = import_mini56.z.looseObject({
|
|
14218
|
+
description: import_mini56.z.optional(import_mini56.z.string()),
|
|
14219
|
+
mode: import_mini56.z._default(import_mini56.z.string(), "subagent"),
|
|
14220
|
+
name: import_mini56.z.optional(import_mini56.z.string())
|
|
14238
14221
|
});
|
|
14239
14222
|
var OpenCodeStyleSubagent = class extends ToolSubagent {
|
|
14240
14223
|
frontmatter;
|
|
@@ -14383,22 +14366,22 @@ var KiloSubagent = class _KiloSubagent extends OpenCodeStyleSubagent {
|
|
|
14383
14366
|
|
|
14384
14367
|
// src/features/subagents/kiro-subagent.ts
|
|
14385
14368
|
var import_node_path103 = require("path");
|
|
14386
|
-
var
|
|
14387
|
-
var KiroCliSubagentJsonSchema =
|
|
14388
|
-
name:
|
|
14389
|
-
description:
|
|
14390
|
-
prompt:
|
|
14391
|
-
tools:
|
|
14392
|
-
toolAliases:
|
|
14393
|
-
toolSettings:
|
|
14394
|
-
toolSchema:
|
|
14395
|
-
hooks:
|
|
14396
|
-
model:
|
|
14397
|
-
mcpServers:
|
|
14398
|
-
useLegacyMcpJson:
|
|
14399
|
-
resources:
|
|
14400
|
-
allowedTools:
|
|
14401
|
-
includeMcpJson:
|
|
14369
|
+
var import_mini57 = require("zod/mini");
|
|
14370
|
+
var KiroCliSubagentJsonSchema = import_mini57.z.looseObject({
|
|
14371
|
+
name: import_mini57.z.string(),
|
|
14372
|
+
description: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.string())),
|
|
14373
|
+
prompt: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.string())),
|
|
14374
|
+
tools: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.array(import_mini57.z.string()))),
|
|
14375
|
+
toolAliases: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.record(import_mini57.z.string(), import_mini57.z.string()))),
|
|
14376
|
+
toolSettings: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.unknown())),
|
|
14377
|
+
toolSchema: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.unknown())),
|
|
14378
|
+
hooks: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.record(import_mini57.z.string(), import_mini57.z.array(import_mini57.z.unknown())))),
|
|
14379
|
+
model: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.string())),
|
|
14380
|
+
mcpServers: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.record(import_mini57.z.string(), import_mini57.z.unknown()))),
|
|
14381
|
+
useLegacyMcpJson: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.boolean())),
|
|
14382
|
+
resources: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.array(import_mini57.z.string()))),
|
|
14383
|
+
allowedTools: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.array(import_mini57.z.string()))),
|
|
14384
|
+
includeMcpJson: import_mini57.z.optional(import_mini57.z.nullable(import_mini57.z.boolean()))
|
|
14402
14385
|
});
|
|
14403
14386
|
var KiroSubagent = class _KiroSubagent extends ToolSubagent {
|
|
14404
14387
|
body;
|
|
@@ -14659,7 +14642,7 @@ var subagentsProcessorToolTargetTuple = [
|
|
|
14659
14642
|
"roo",
|
|
14660
14643
|
"rovodev"
|
|
14661
14644
|
];
|
|
14662
|
-
var SubagentsProcessorToolTargetSchema =
|
|
14645
|
+
var SubagentsProcessorToolTargetSchema = import_mini58.z.enum(subagentsProcessorToolTargetTuple);
|
|
14663
14646
|
var toolSubagentFactories = /* @__PURE__ */ new Map([
|
|
14664
14647
|
[
|
|
14665
14648
|
"agentsmd",
|
|
@@ -14969,42 +14952,42 @@ var import_node_path107 = require("path");
|
|
|
14969
14952
|
|
|
14970
14953
|
// src/features/rules/rulesync-rule.ts
|
|
14971
14954
|
var import_node_path106 = require("path");
|
|
14972
|
-
var
|
|
14973
|
-
var RulesyncRuleFrontmatterSchema =
|
|
14974
|
-
root:
|
|
14975
|
-
localRoot:
|
|
14976
|
-
targets:
|
|
14977
|
-
description:
|
|
14978
|
-
globs:
|
|
14979
|
-
agentsmd:
|
|
14980
|
-
|
|
14955
|
+
var import_mini59 = require("zod/mini");
|
|
14956
|
+
var RulesyncRuleFrontmatterSchema = import_mini59.z.object({
|
|
14957
|
+
root: import_mini59.z.optional(import_mini59.z.boolean()),
|
|
14958
|
+
localRoot: import_mini59.z.optional(import_mini59.z.boolean()),
|
|
14959
|
+
targets: import_mini59.z._default(RulesyncTargetsSchema, ["*"]),
|
|
14960
|
+
description: import_mini59.z.optional(import_mini59.z.string()),
|
|
14961
|
+
globs: import_mini59.z.optional(import_mini59.z.array(import_mini59.z.string())),
|
|
14962
|
+
agentsmd: import_mini59.z.optional(
|
|
14963
|
+
import_mini59.z.looseObject({
|
|
14981
14964
|
// @example "path/to/subproject"
|
|
14982
|
-
subprojectPath:
|
|
14965
|
+
subprojectPath: import_mini59.z.optional(import_mini59.z.string())
|
|
14983
14966
|
})
|
|
14984
14967
|
),
|
|
14985
|
-
claudecode:
|
|
14986
|
-
|
|
14968
|
+
claudecode: import_mini59.z.optional(
|
|
14969
|
+
import_mini59.z.looseObject({
|
|
14987
14970
|
// Glob patterns for conditional rules (takes precedence over globs)
|
|
14988
14971
|
// @example ["src/**/*.ts", "tests/**/*.test.ts"]
|
|
14989
|
-
paths:
|
|
14972
|
+
paths: import_mini59.z.optional(import_mini59.z.array(import_mini59.z.string()))
|
|
14990
14973
|
})
|
|
14991
14974
|
),
|
|
14992
|
-
cursor:
|
|
14993
|
-
|
|
14994
|
-
alwaysApply:
|
|
14995
|
-
description:
|
|
14996
|
-
globs:
|
|
14975
|
+
cursor: import_mini59.z.optional(
|
|
14976
|
+
import_mini59.z.looseObject({
|
|
14977
|
+
alwaysApply: import_mini59.z.optional(import_mini59.z.boolean()),
|
|
14978
|
+
description: import_mini59.z.optional(import_mini59.z.string()),
|
|
14979
|
+
globs: import_mini59.z.optional(import_mini59.z.array(import_mini59.z.string()))
|
|
14997
14980
|
})
|
|
14998
14981
|
),
|
|
14999
|
-
copilot:
|
|
15000
|
-
|
|
15001
|
-
excludeAgent:
|
|
14982
|
+
copilot: import_mini59.z.optional(
|
|
14983
|
+
import_mini59.z.looseObject({
|
|
14984
|
+
excludeAgent: import_mini59.z.optional(import_mini59.z.union([import_mini59.z.literal("code-review"), import_mini59.z.literal("coding-agent")]))
|
|
15002
14985
|
})
|
|
15003
14986
|
),
|
|
15004
|
-
antigravity:
|
|
15005
|
-
|
|
15006
|
-
trigger:
|
|
15007
|
-
globs:
|
|
14987
|
+
antigravity: import_mini59.z.optional(
|
|
14988
|
+
import_mini59.z.looseObject({
|
|
14989
|
+
trigger: import_mini59.z.optional(import_mini59.z.string()),
|
|
14990
|
+
globs: import_mini59.z.optional(import_mini59.z.array(import_mini59.z.string()))
|
|
15008
14991
|
})
|
|
15009
14992
|
)
|
|
15010
14993
|
});
|
|
@@ -15304,20 +15287,20 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
15304
15287
|
|
|
15305
15288
|
// src/features/rules/antigravity-rule.ts
|
|
15306
15289
|
var import_node_path109 = require("path");
|
|
15307
|
-
var
|
|
15308
|
-
var AntigravityRuleFrontmatterSchema =
|
|
15309
|
-
trigger:
|
|
15310
|
-
|
|
15311
|
-
|
|
15312
|
-
|
|
15313
|
-
|
|
15314
|
-
|
|
15315
|
-
|
|
15290
|
+
var import_mini60 = require("zod/mini");
|
|
15291
|
+
var AntigravityRuleFrontmatterSchema = import_mini60.z.looseObject({
|
|
15292
|
+
trigger: import_mini60.z.optional(
|
|
15293
|
+
import_mini60.z.union([
|
|
15294
|
+
import_mini60.z.literal("always_on"),
|
|
15295
|
+
import_mini60.z.literal("glob"),
|
|
15296
|
+
import_mini60.z.literal("manual"),
|
|
15297
|
+
import_mini60.z.literal("model_decision"),
|
|
15298
|
+
import_mini60.z.string()
|
|
15316
15299
|
// accepts any string for forward compatibility
|
|
15317
15300
|
])
|
|
15318
15301
|
),
|
|
15319
|
-
globs:
|
|
15320
|
-
description:
|
|
15302
|
+
globs: import_mini60.z.optional(import_mini60.z.string()),
|
|
15303
|
+
description: import_mini60.z.optional(import_mini60.z.string())
|
|
15321
15304
|
});
|
|
15322
15305
|
function parseGlobsString(globs) {
|
|
15323
15306
|
if (!globs) {
|
|
@@ -15904,9 +15887,9 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
|
|
|
15904
15887
|
|
|
15905
15888
|
// src/features/rules/claudecode-rule.ts
|
|
15906
15889
|
var import_node_path113 = require("path");
|
|
15907
|
-
var
|
|
15908
|
-
var ClaudecodeRuleFrontmatterSchema =
|
|
15909
|
-
paths:
|
|
15890
|
+
var import_mini61 = require("zod/mini");
|
|
15891
|
+
var ClaudecodeRuleFrontmatterSchema = import_mini61.z.object({
|
|
15892
|
+
paths: import_mini61.z.optional(import_mini61.z.array(import_mini61.z.string()))
|
|
15910
15893
|
});
|
|
15911
15894
|
var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
15912
15895
|
frontmatter;
|
|
@@ -16122,9 +16105,9 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
16122
16105
|
|
|
16123
16106
|
// src/features/rules/cline-rule.ts
|
|
16124
16107
|
var import_node_path114 = require("path");
|
|
16125
|
-
var
|
|
16126
|
-
var ClineRuleFrontmatterSchema =
|
|
16127
|
-
description:
|
|
16108
|
+
var import_mini62 = require("zod/mini");
|
|
16109
|
+
var ClineRuleFrontmatterSchema = import_mini62.z.object({
|
|
16110
|
+
description: import_mini62.z.string()
|
|
16128
16111
|
});
|
|
16129
16112
|
var ClineRule = class _ClineRule extends ToolRule {
|
|
16130
16113
|
static getSettablePaths(_options = {}) {
|
|
@@ -16303,11 +16286,11 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
16303
16286
|
|
|
16304
16287
|
// src/features/rules/copilot-rule.ts
|
|
16305
16288
|
var import_node_path116 = require("path");
|
|
16306
|
-
var
|
|
16307
|
-
var CopilotRuleFrontmatterSchema =
|
|
16308
|
-
description:
|
|
16309
|
-
applyTo:
|
|
16310
|
-
excludeAgent:
|
|
16289
|
+
var import_mini63 = require("zod/mini");
|
|
16290
|
+
var CopilotRuleFrontmatterSchema = import_mini63.z.object({
|
|
16291
|
+
description: import_mini63.z.optional(import_mini63.z.string()),
|
|
16292
|
+
applyTo: import_mini63.z.optional(import_mini63.z.string()),
|
|
16293
|
+
excludeAgent: import_mini63.z.optional(import_mini63.z.union([import_mini63.z.literal("code-review"), import_mini63.z.literal("coding-agent")]))
|
|
16311
16294
|
});
|
|
16312
16295
|
var CopilotRule = class _CopilotRule extends ToolRule {
|
|
16313
16296
|
frontmatter;
|
|
@@ -16549,11 +16532,11 @@ var CopilotcliRule = class _CopilotcliRule extends CopilotRule {
|
|
|
16549
16532
|
|
|
16550
16533
|
// src/features/rules/cursor-rule.ts
|
|
16551
16534
|
var import_node_path117 = require("path");
|
|
16552
|
-
var
|
|
16553
|
-
var CursorRuleFrontmatterSchema =
|
|
16554
|
-
description:
|
|
16555
|
-
globs:
|
|
16556
|
-
alwaysApply:
|
|
16535
|
+
var import_mini64 = require("zod/mini");
|
|
16536
|
+
var CursorRuleFrontmatterSchema = import_mini64.z.object({
|
|
16537
|
+
description: import_mini64.z.optional(import_mini64.z.string()),
|
|
16538
|
+
globs: import_mini64.z.optional(import_mini64.z.string()),
|
|
16539
|
+
alwaysApply: import_mini64.z.optional(import_mini64.z.boolean())
|
|
16557
16540
|
});
|
|
16558
16541
|
var CursorRule = class _CursorRule extends ToolRule {
|
|
16559
16542
|
frontmatter;
|
|
@@ -18213,11 +18196,11 @@ var rulesProcessorToolTargets = [
|
|
|
18213
18196
|
"warp",
|
|
18214
18197
|
"windsurf"
|
|
18215
18198
|
];
|
|
18216
|
-
var RulesProcessorToolTargetSchema =
|
|
18199
|
+
var RulesProcessorToolTargetSchema = import_mini65.z.enum(rulesProcessorToolTargets);
|
|
18217
18200
|
var formatRulePaths = (rules) => rules.map((r) => (0, import_node_path132.join)(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
|
|
18218
|
-
var RulesFeatureOptionsSchema =
|
|
18219
|
-
ruleDiscoveryMode:
|
|
18220
|
-
includeLocalRoot:
|
|
18201
|
+
var RulesFeatureOptionsSchema = import_mini65.z.looseObject({
|
|
18202
|
+
ruleDiscoveryMode: import_mini65.z.optional(import_mini65.z.enum(["none", "explicit"])),
|
|
18203
|
+
includeLocalRoot: import_mini65.z.optional(import_mini65.z.boolean())
|
|
18221
18204
|
});
|
|
18222
18205
|
var resolveRuleDiscoveryMode = ({
|
|
18223
18206
|
defaultMode,
|
|
@@ -18238,8 +18221,8 @@ var resolveRuleDiscoveryMode = ({
|
|
|
18238
18221
|
}
|
|
18239
18222
|
return parsed.data.ruleDiscoveryMode === "none" ? "auto" : "toon";
|
|
18240
18223
|
};
|
|
18241
|
-
var IncludeLocalRootSchema =
|
|
18242
|
-
includeLocalRoot:
|
|
18224
|
+
var IncludeLocalRootSchema = import_mini65.z.looseObject({
|
|
18225
|
+
includeLocalRoot: import_mini65.z.optional(import_mini65.z.boolean())
|
|
18243
18226
|
});
|
|
18244
18227
|
var resolveIncludeLocalRoot = (options) => {
|
|
18245
18228
|
if (!options) return true;
|
|
@@ -19182,51 +19165,51 @@ var import_request_error = require("@octokit/request-error");
|
|
|
19182
19165
|
var import_rest = require("@octokit/rest");
|
|
19183
19166
|
|
|
19184
19167
|
// src/types/fetch.ts
|
|
19185
|
-
var
|
|
19168
|
+
var import_mini67 = require("zod/mini");
|
|
19186
19169
|
|
|
19187
19170
|
// src/types/fetch-targets.ts
|
|
19188
|
-
var
|
|
19171
|
+
var import_mini66 = require("zod/mini");
|
|
19189
19172
|
var ALL_FETCH_TARGETS = ["rulesync", ...ALL_TOOL_TARGETS];
|
|
19190
|
-
var FetchTargetSchema =
|
|
19173
|
+
var FetchTargetSchema = import_mini66.z.enum(ALL_FETCH_TARGETS);
|
|
19191
19174
|
|
|
19192
19175
|
// src/types/fetch.ts
|
|
19193
|
-
var ConflictStrategySchema =
|
|
19194
|
-
var GitHubFileTypeSchema =
|
|
19195
|
-
var GitHubFileEntrySchema =
|
|
19196
|
-
name:
|
|
19197
|
-
path:
|
|
19198
|
-
sha:
|
|
19199
|
-
size:
|
|
19176
|
+
var ConflictStrategySchema = import_mini67.z.enum(["skip", "overwrite"]);
|
|
19177
|
+
var GitHubFileTypeSchema = import_mini67.z.enum(["file", "dir", "symlink", "submodule"]);
|
|
19178
|
+
var GitHubFileEntrySchema = import_mini67.z.looseObject({
|
|
19179
|
+
name: import_mini67.z.string(),
|
|
19180
|
+
path: import_mini67.z.string(),
|
|
19181
|
+
sha: import_mini67.z.string(),
|
|
19182
|
+
size: import_mini67.z.number(),
|
|
19200
19183
|
type: GitHubFileTypeSchema,
|
|
19201
|
-
download_url:
|
|
19184
|
+
download_url: import_mini67.z.nullable(import_mini67.z.string())
|
|
19202
19185
|
});
|
|
19203
|
-
var FetchOptionsSchema =
|
|
19204
|
-
target:
|
|
19205
|
-
features:
|
|
19206
|
-
ref:
|
|
19207
|
-
path:
|
|
19208
|
-
output:
|
|
19209
|
-
conflict:
|
|
19210
|
-
token:
|
|
19211
|
-
verbose:
|
|
19212
|
-
silent:
|
|
19186
|
+
var FetchOptionsSchema = import_mini67.z.looseObject({
|
|
19187
|
+
target: import_mini67.z.optional(FetchTargetSchema),
|
|
19188
|
+
features: import_mini67.z.optional(import_mini67.z.array(import_mini67.z.enum(ALL_FEATURES_WITH_WILDCARD))),
|
|
19189
|
+
ref: import_mini67.z.optional(import_mini67.z.string()),
|
|
19190
|
+
path: import_mini67.z.optional(import_mini67.z.string()),
|
|
19191
|
+
output: import_mini67.z.optional(import_mini67.z.string()),
|
|
19192
|
+
conflict: import_mini67.z.optional(ConflictStrategySchema),
|
|
19193
|
+
token: import_mini67.z.optional(import_mini67.z.string()),
|
|
19194
|
+
verbose: import_mini67.z.optional(import_mini67.z.boolean()),
|
|
19195
|
+
silent: import_mini67.z.optional(import_mini67.z.boolean())
|
|
19213
19196
|
});
|
|
19214
|
-
var FetchFileStatusSchema =
|
|
19215
|
-
var GitHubRepoInfoSchema =
|
|
19216
|
-
default_branch:
|
|
19217
|
-
private:
|
|
19197
|
+
var FetchFileStatusSchema = import_mini67.z.enum(["created", "overwritten", "skipped"]);
|
|
19198
|
+
var GitHubRepoInfoSchema = import_mini67.z.looseObject({
|
|
19199
|
+
default_branch: import_mini67.z.string(),
|
|
19200
|
+
private: import_mini67.z.boolean()
|
|
19218
19201
|
});
|
|
19219
|
-
var GitHubReleaseAssetSchema =
|
|
19220
|
-
name:
|
|
19221
|
-
browser_download_url:
|
|
19222
|
-
size:
|
|
19202
|
+
var GitHubReleaseAssetSchema = import_mini67.z.looseObject({
|
|
19203
|
+
name: import_mini67.z.string(),
|
|
19204
|
+
browser_download_url: import_mini67.z.string(),
|
|
19205
|
+
size: import_mini67.z.number()
|
|
19223
19206
|
});
|
|
19224
|
-
var GitHubReleaseSchema =
|
|
19225
|
-
tag_name:
|
|
19226
|
-
name:
|
|
19227
|
-
prerelease:
|
|
19228
|
-
draft:
|
|
19229
|
-
assets:
|
|
19207
|
+
var GitHubReleaseSchema = import_mini67.z.looseObject({
|
|
19208
|
+
tag_name: import_mini67.z.string(),
|
|
19209
|
+
name: import_mini67.z.nullable(import_mini67.z.string()),
|
|
19210
|
+
prerelease: import_mini67.z.boolean(),
|
|
19211
|
+
draft: import_mini67.z.boolean(),
|
|
19212
|
+
assets: import_mini67.z.array(GitHubReleaseAssetSchema)
|
|
19230
19213
|
});
|
|
19231
19214
|
|
|
19232
19215
|
// src/lib/github-client.ts
|
|
@@ -19527,9 +19510,9 @@ async function listDirectoryRecursive(params) {
|
|
|
19527
19510
|
}
|
|
19528
19511
|
|
|
19529
19512
|
// src/types/git-provider.ts
|
|
19530
|
-
var
|
|
19513
|
+
var import_mini68 = require("zod/mini");
|
|
19531
19514
|
var ALL_GIT_PROVIDERS = ["github", "gitlab"];
|
|
19532
|
-
var GitProviderSchema =
|
|
19515
|
+
var GitProviderSchema = import_mini68.z.enum(ALL_GIT_PROVIDERS);
|
|
19533
19516
|
|
|
19534
19517
|
// src/lib/source-parser.ts
|
|
19535
19518
|
var GITHUB_HOSTS = /* @__PURE__ */ new Set(["github.com", "www.github.com"]);
|
|
@@ -20152,7 +20135,7 @@ var import_jsonc_parser4 = require("jsonc-parser");
|
|
|
20152
20135
|
|
|
20153
20136
|
// src/config/config.ts
|
|
20154
20137
|
var import_node_path134 = require("path");
|
|
20155
|
-
var
|
|
20138
|
+
var import_mini69 = require("zod/mini");
|
|
20156
20139
|
|
|
20157
20140
|
// src/utils/validation.ts
|
|
20158
20141
|
function findControlCharacter(value) {
|
|
@@ -20170,49 +20153,55 @@ function hasControlCharacters(value) {
|
|
|
20170
20153
|
|
|
20171
20154
|
// src/config/config.ts
|
|
20172
20155
|
var GITIGNORE_DESTINATION_KEY = "gitignoreDestination";
|
|
20173
|
-
var SourceEntrySchema =
|
|
20174
|
-
source:
|
|
20175
|
-
skills: (0,
|
|
20176
|
-
transport: (0,
|
|
20177
|
-
ref: (0,
|
|
20178
|
-
|
|
20179
|
-
(0,
|
|
20180
|
-
(0,
|
|
20156
|
+
var SourceEntrySchema = import_mini69.z.object({
|
|
20157
|
+
source: import_mini69.z.string().check((0, import_mini69.minLength)(1, "source must be a non-empty string")),
|
|
20158
|
+
skills: (0, import_mini69.optional)(import_mini69.z.array(import_mini69.z.string())),
|
|
20159
|
+
transport: (0, import_mini69.optional)(import_mini69.z.enum(["github", "git"])),
|
|
20160
|
+
ref: (0, import_mini69.optional)(
|
|
20161
|
+
import_mini69.z.string().check(
|
|
20162
|
+
(0, import_mini69.refine)((v) => !v.startsWith("-"), 'ref must not start with "-"'),
|
|
20163
|
+
(0, import_mini69.refine)((v) => !hasControlCharacters(v), "ref must not contain control characters")
|
|
20181
20164
|
)
|
|
20182
20165
|
),
|
|
20183
|
-
path: (0,
|
|
20184
|
-
|
|
20185
|
-
(0,
|
|
20186
|
-
(0,
|
|
20187
|
-
(0,
|
|
20166
|
+
path: (0, import_mini69.optional)(
|
|
20167
|
+
import_mini69.z.string().check(
|
|
20168
|
+
(0, import_mini69.refine)((v) => !v.includes(".."), 'path must not contain ".."'),
|
|
20169
|
+
(0, import_mini69.refine)((v) => !(0, import_node_path134.isAbsolute)(v), "path must not be absolute"),
|
|
20170
|
+
(0, import_mini69.refine)((v) => !hasControlCharacters(v), "path must not contain control characters")
|
|
20188
20171
|
)
|
|
20189
|
-
)
|
|
20172
|
+
),
|
|
20173
|
+
// gh-mode-only fields. Ignored by --mode rulesync. Defaults applied at the
|
|
20174
|
+
// gh install site (`agent` defaults to "github-copilot", `scope` to "project").
|
|
20175
|
+
agent: (0, import_mini69.optional)(
|
|
20176
|
+
import_mini69.z.enum(["github-copilot", "claude-code", "cursor", "codex", "gemini", "antigravity"])
|
|
20177
|
+
),
|
|
20178
|
+
scope: (0, import_mini69.optional)(import_mini69.z.enum(["project", "user"]))
|
|
20190
20179
|
});
|
|
20191
|
-
var ConfigParamsSchema =
|
|
20192
|
-
baseDirs:
|
|
20180
|
+
var ConfigParamsSchema = import_mini69.z.object({
|
|
20181
|
+
baseDirs: import_mini69.z.array(import_mini69.z.string()),
|
|
20193
20182
|
targets: RulesyncConfigTargetsSchema,
|
|
20194
20183
|
features: RulesyncFeaturesSchema,
|
|
20195
|
-
verbose:
|
|
20196
|
-
delete:
|
|
20184
|
+
verbose: import_mini69.z.boolean(),
|
|
20185
|
+
delete: import_mini69.z.boolean(),
|
|
20197
20186
|
// New non-experimental options
|
|
20198
|
-
global: (0,
|
|
20199
|
-
silent: (0,
|
|
20200
|
-
simulateCommands: (0,
|
|
20201
|
-
simulateSubagents: (0,
|
|
20202
|
-
simulateSkills: (0,
|
|
20203
|
-
gitignoreTargetsOnly: (0,
|
|
20204
|
-
gitignoreDestination: (0,
|
|
20205
|
-
dryRun: (0,
|
|
20206
|
-
check: (0,
|
|
20187
|
+
global: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
20188
|
+
silent: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
20189
|
+
simulateCommands: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
20190
|
+
simulateSubagents: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
20191
|
+
simulateSkills: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
20192
|
+
gitignoreTargetsOnly: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
20193
|
+
gitignoreDestination: (0, import_mini69.optional)(GitignoreDestinationSchema),
|
|
20194
|
+
dryRun: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
20195
|
+
check: (0, import_mini69.optional)(import_mini69.z.boolean()),
|
|
20207
20196
|
// Declarative skill sources
|
|
20208
|
-
sources: (0,
|
|
20197
|
+
sources: (0, import_mini69.optional)(import_mini69.z.array(SourceEntrySchema))
|
|
20209
20198
|
});
|
|
20210
|
-
var PartialConfigParamsSchema =
|
|
20211
|
-
var ConfigFileSchema =
|
|
20212
|
-
$schema: (0,
|
|
20213
|
-
...
|
|
20199
|
+
var PartialConfigParamsSchema = import_mini69.z.partial(ConfigParamsSchema);
|
|
20200
|
+
var ConfigFileSchema = import_mini69.z.object({
|
|
20201
|
+
$schema: (0, import_mini69.optional)(import_mini69.z.string()),
|
|
20202
|
+
...import_mini69.z.partial(ConfigParamsSchema).shape
|
|
20214
20203
|
});
|
|
20215
|
-
var RequiredConfigParamsSchema =
|
|
20204
|
+
var RequiredConfigParamsSchema = import_mini69.z.required(ConfigParamsSchema);
|
|
20216
20205
|
var CONFLICTING_TARGET_PAIRS = [
|
|
20217
20206
|
["augmentcode", "augmentcode-legacy"],
|
|
20218
20207
|
["claudecode", "claudecode-legacy"]
|
|
@@ -20702,7 +20691,7 @@ var import_node_path142 = require("path");
|
|
|
20702
20691
|
var import_es_toolkit5 = require("es-toolkit");
|
|
20703
20692
|
|
|
20704
20693
|
// src/features/permissions/permissions-processor.ts
|
|
20705
|
-
var
|
|
20694
|
+
var import_mini74 = require("zod/mini");
|
|
20706
20695
|
|
|
20707
20696
|
// src/features/permissions/claudecode-permissions.ts
|
|
20708
20697
|
var import_node_path137 = require("path");
|
|
@@ -20712,14 +20701,14 @@ var import_es_toolkit4 = require("es-toolkit");
|
|
|
20712
20701
|
var import_node_path136 = require("path");
|
|
20713
20702
|
|
|
20714
20703
|
// src/types/permissions.ts
|
|
20715
|
-
var
|
|
20716
|
-
var PermissionActionSchema =
|
|
20717
|
-
var PermissionRulesSchema =
|
|
20718
|
-
var PermissionsConfigSchema =
|
|
20719
|
-
permission:
|
|
20704
|
+
var import_mini70 = require("zod/mini");
|
|
20705
|
+
var PermissionActionSchema = import_mini70.z.enum(["allow", "ask", "deny"]);
|
|
20706
|
+
var PermissionRulesSchema = import_mini70.z.record(import_mini70.z.string(), PermissionActionSchema);
|
|
20707
|
+
var PermissionsConfigSchema = import_mini70.z.looseObject({
|
|
20708
|
+
permission: import_mini70.z.record(import_mini70.z.string(), PermissionRulesSchema)
|
|
20720
20709
|
});
|
|
20721
|
-
var RulesyncPermissionsFileSchema =
|
|
20722
|
-
$schema:
|
|
20710
|
+
var RulesyncPermissionsFileSchema = import_mini70.z.looseObject({
|
|
20711
|
+
$schema: import_mini70.z.optional(import_mini70.z.string()),
|
|
20723
20712
|
...PermissionsConfigSchema.shape
|
|
20724
20713
|
});
|
|
20725
20714
|
|
|
@@ -21289,7 +21278,7 @@ function mapBashActionToDecision(action) {
|
|
|
21289
21278
|
// src/features/permissions/geminicli-permissions.ts
|
|
21290
21279
|
var import_node_path139 = require("path");
|
|
21291
21280
|
var smolToml6 = __toESM(require("smol-toml"), 1);
|
|
21292
|
-
var
|
|
21281
|
+
var import_mini71 = require("zod/mini");
|
|
21293
21282
|
|
|
21294
21283
|
// src/utils/logger.ts
|
|
21295
21284
|
var BaseLogger = class {
|
|
@@ -21763,14 +21752,14 @@ function regexToGlobPattern(regex) {
|
|
|
21763
21752
|
}
|
|
21764
21753
|
return glob;
|
|
21765
21754
|
}
|
|
21766
|
-
var GeminicliPolicyRuleSchema =
|
|
21767
|
-
toolName:
|
|
21768
|
-
decision:
|
|
21769
|
-
commandPrefix:
|
|
21770
|
-
argsPattern:
|
|
21755
|
+
var GeminicliPolicyRuleSchema = import_mini71.z.looseObject({
|
|
21756
|
+
toolName: import_mini71.z.string(),
|
|
21757
|
+
decision: import_mini71.z.optional(import_mini71.z.unknown()),
|
|
21758
|
+
commandPrefix: import_mini71.z.optional(import_mini71.z.string()),
|
|
21759
|
+
argsPattern: import_mini71.z.optional(import_mini71.z.string())
|
|
21771
21760
|
});
|
|
21772
|
-
var GeminicliPolicyFileSchema =
|
|
21773
|
-
rule:
|
|
21761
|
+
var GeminicliPolicyFileSchema = import_mini71.z.looseObject({
|
|
21762
|
+
rule: import_mini71.z.optional(import_mini71.z.array(import_mini71.z.looseObject({})))
|
|
21774
21763
|
});
|
|
21775
21764
|
function extractRules(parsed, logger5) {
|
|
21776
21765
|
const parsedFile = GeminicliPolicyFileSchema.safeParse(parsed);
|
|
@@ -21806,12 +21795,12 @@ function extractPattern(rule) {
|
|
|
21806
21795
|
|
|
21807
21796
|
// src/features/permissions/kiro-permissions.ts
|
|
21808
21797
|
var import_node_path140 = require("path");
|
|
21809
|
-
var
|
|
21810
|
-
var KiroAgentSchema =
|
|
21811
|
-
allowedTools:
|
|
21812
|
-
toolsSettings:
|
|
21798
|
+
var import_mini72 = require("zod/mini");
|
|
21799
|
+
var KiroAgentSchema = import_mini72.z.looseObject({
|
|
21800
|
+
allowedTools: import_mini72.z.optional(import_mini72.z.array(import_mini72.z.string())),
|
|
21801
|
+
toolsSettings: import_mini72.z.optional(import_mini72.z.record(import_mini72.z.string(), import_mini72.z.unknown()))
|
|
21813
21802
|
});
|
|
21814
|
-
var UnknownRecordSchema =
|
|
21803
|
+
var UnknownRecordSchema = import_mini72.z.record(import_mini72.z.string(), import_mini72.z.unknown());
|
|
21815
21804
|
var KiroPermissions = class _KiroPermissions extends ToolPermissions {
|
|
21816
21805
|
static getSettablePaths(_options = {}) {
|
|
21817
21806
|
return {
|
|
@@ -21964,8 +21953,12 @@ function buildKiroPermissionsFromRulesync({
|
|
|
21964
21953
|
);
|
|
21965
21954
|
continue;
|
|
21966
21955
|
}
|
|
21967
|
-
|
|
21968
|
-
|
|
21956
|
+
const toolName = category === "webfetch" ? "web_fetch" : "web_search";
|
|
21957
|
+
if (action === "allow") {
|
|
21958
|
+
nextAllowedTools.add(toolName);
|
|
21959
|
+
} else {
|
|
21960
|
+
nextAllowedTools.delete(toolName);
|
|
21961
|
+
}
|
|
21969
21962
|
} else {
|
|
21970
21963
|
logger5?.warn(`Kiro permissions do not support category: ${category}. Skipping.`);
|
|
21971
21964
|
}
|
|
@@ -21991,13 +21984,13 @@ function asStringArray(value) {
|
|
|
21991
21984
|
// src/features/permissions/opencode-permissions.ts
|
|
21992
21985
|
var import_node_path141 = require("path");
|
|
21993
21986
|
var import_jsonc_parser5 = require("jsonc-parser");
|
|
21994
|
-
var
|
|
21995
|
-
var OpencodePermissionSchema =
|
|
21996
|
-
|
|
21997
|
-
|
|
21987
|
+
var import_mini73 = require("zod/mini");
|
|
21988
|
+
var OpencodePermissionSchema = import_mini73.z.union([
|
|
21989
|
+
import_mini73.z.enum(["allow", "ask", "deny"]),
|
|
21990
|
+
import_mini73.z.record(import_mini73.z.string(), import_mini73.z.enum(["allow", "ask", "deny"]))
|
|
21998
21991
|
]);
|
|
21999
|
-
var OpencodePermissionsConfigSchema =
|
|
22000
|
-
permission:
|
|
21992
|
+
var OpencodePermissionsConfigSchema = import_mini73.z.looseObject({
|
|
21993
|
+
permission: import_mini73.z.optional(import_mini73.z.record(import_mini73.z.string(), OpencodePermissionSchema))
|
|
22001
21994
|
});
|
|
22002
21995
|
var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
|
|
22003
21996
|
json;
|
|
@@ -22128,7 +22121,7 @@ var permissionsProcessorToolTargetTuple = [
|
|
|
22128
22121
|
"kiro",
|
|
22129
22122
|
"opencode"
|
|
22130
22123
|
];
|
|
22131
|
-
var PermissionsProcessorToolTargetSchema =
|
|
22124
|
+
var PermissionsProcessorToolTargetSchema = import_mini74.z.enum(permissionsProcessorToolTargetTuple);
|
|
22132
22125
|
var toolPermissionsFactories = /* @__PURE__ */ new Map([
|
|
22133
22126
|
[
|
|
22134
22127
|
"claudecode",
|
|
@@ -23893,157 +23886,1315 @@ async function initCommand(logger5) {
|
|
|
23893
23886
|
logger5.info("2. Run 'rulesync generate' to create configuration files");
|
|
23894
23887
|
}
|
|
23895
23888
|
|
|
23896
|
-
// src/lib/
|
|
23889
|
+
// src/lib/apm/apm-install.ts
|
|
23890
|
+
var import_node_crypto = require("crypto");
|
|
23897
23891
|
var import_node_path147 = require("path");
|
|
23898
23892
|
var import_promise2 = require("es-toolkit/promise");
|
|
23899
23893
|
|
|
23900
|
-
// src/lib/
|
|
23901
|
-
var import_node_child_process = require("child_process");
|
|
23894
|
+
// src/lib/apm/apm-lock.ts
|
|
23902
23895
|
var import_node_path145 = require("path");
|
|
23903
|
-
var
|
|
23904
|
-
var
|
|
23905
|
-
var
|
|
23906
|
-
var
|
|
23907
|
-
var
|
|
23908
|
-
var
|
|
23909
|
-
|
|
23910
|
-
|
|
23911
|
-
|
|
23896
|
+
var import_js_yaml3 = require("js-yaml");
|
|
23897
|
+
var import_mini75 = require("zod/mini");
|
|
23898
|
+
var APM_LOCKFILE_FILE_NAME = "rulesync-apm.lock.yaml";
|
|
23899
|
+
var APM_LOCKFILE_VERSION = "1";
|
|
23900
|
+
var RULESYNC_CONTENT_HASH_REGEX = /^sha256:[0-9a-f]{64}$/;
|
|
23901
|
+
var ApmLockDependencySchema = import_mini75.z.looseObject({
|
|
23902
|
+
repo_url: import_mini75.z.string(),
|
|
23903
|
+
resolved_commit: (0, import_mini75.optional)(
|
|
23904
|
+
import_mini75.z.string().check((0, import_mini75.refine)((v) => /^[0-9a-f]{40}$/.test(v), "resolved_commit must be a 40-char hex SHA"))
|
|
23905
|
+
),
|
|
23906
|
+
resolved_ref: (0, import_mini75.optional)(import_mini75.z.string()),
|
|
23907
|
+
version: (0, import_mini75.optional)(import_mini75.z.string()),
|
|
23908
|
+
depth: import_mini75.z.int().check((0, import_mini75.nonnegative)()),
|
|
23909
|
+
resolved_by: (0, import_mini75.optional)(import_mini75.z.string()),
|
|
23910
|
+
package_type: import_mini75.z.string(),
|
|
23911
|
+
// Intentionally loose: the upstream `apm` CLI may write content_hash values
|
|
23912
|
+
// that do not match the strict rulesync format. We accept any string on read
|
|
23913
|
+
// so that a lockfile produced by `apm` round-trips through rulesync without
|
|
23914
|
+
// throwing. Rulesync itself always writes values matching
|
|
23915
|
+
// `RULESYNC_CONTENT_HASH_REGEX`, and `--frozen` integrity checks only
|
|
23916
|
+
// enforce the comparison when the recorded hash matches that shape.
|
|
23917
|
+
content_hash: (0, import_mini75.optional)(import_mini75.z.string()),
|
|
23918
|
+
is_dev: (0, import_mini75.optional)(import_mini75.z.boolean()),
|
|
23919
|
+
deployed_files: import_mini75.z.array(import_mini75.z.string()),
|
|
23920
|
+
source: (0, import_mini75.optional)(import_mini75.z.string()),
|
|
23921
|
+
local_path: (0, import_mini75.optional)(import_mini75.z.string()),
|
|
23922
|
+
virtual_path: (0, import_mini75.optional)(import_mini75.z.string()),
|
|
23923
|
+
is_virtual: (0, import_mini75.optional)(import_mini75.z.boolean())
|
|
23924
|
+
});
|
|
23925
|
+
var ApmLockSchema = import_mini75.z.looseObject({
|
|
23926
|
+
lockfile_version: import_mini75.z.literal("1"),
|
|
23927
|
+
generated_at: import_mini75.z.string(),
|
|
23928
|
+
apm_version: import_mini75.z.string(),
|
|
23929
|
+
dependencies: import_mini75.z.array(ApmLockDependencySchema),
|
|
23930
|
+
mcp_servers: (0, import_mini75.optional)(import_mini75.z.array(import_mini75.z.string()))
|
|
23931
|
+
});
|
|
23932
|
+
function getApmLockPath(baseDir) {
|
|
23933
|
+
return (0, import_node_path145.join)(baseDir, APM_LOCKFILE_FILE_NAME);
|
|
23934
|
+
}
|
|
23935
|
+
function createEmptyApmLock(params) {
|
|
23936
|
+
const base = params.existingLock ? { ...params.existingLock } : {};
|
|
23937
|
+
return {
|
|
23938
|
+
...base,
|
|
23939
|
+
lockfile_version: APM_LOCKFILE_VERSION,
|
|
23940
|
+
generated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
23941
|
+
apm_version: params.apmVersion,
|
|
23942
|
+
dependencies: []
|
|
23943
|
+
};
|
|
23944
|
+
}
|
|
23945
|
+
function parseApmLock(content) {
|
|
23946
|
+
if (!content.trim()) {
|
|
23947
|
+
return null;
|
|
23912
23948
|
}
|
|
23913
|
-
|
|
23914
|
-
|
|
23915
|
-
|
|
23916
|
-
|
|
23917
|
-
|
|
23918
|
-
`Git URL contains control character ${ctrl.hex} at position ${ctrl.position}`
|
|
23919
|
-
);
|
|
23949
|
+
let loaded;
|
|
23950
|
+
try {
|
|
23951
|
+
loaded = (0, import_js_yaml3.load)(content);
|
|
23952
|
+
} catch {
|
|
23953
|
+
return null;
|
|
23920
23954
|
}
|
|
23921
|
-
if (!
|
|
23922
|
-
|
|
23923
|
-
|
|
23955
|
+
if (!loaded || typeof loaded !== "object") {
|
|
23956
|
+
return null;
|
|
23957
|
+
}
|
|
23958
|
+
const parsed = ApmLockSchema.safeParse(loaded);
|
|
23959
|
+
if (!parsed.success) {
|
|
23960
|
+
const issues = parsed.error.issues.map((issue) => ` - ${issue.path.join(".") || "<root>"}: ${issue.message}`).join("\n");
|
|
23961
|
+
throw new Error(`Invalid ${APM_LOCKFILE_FILE_NAME}:
|
|
23962
|
+
${issues}`);
|
|
23963
|
+
}
|
|
23964
|
+
return parsed.data;
|
|
23965
|
+
}
|
|
23966
|
+
async function readApmLock(baseDir) {
|
|
23967
|
+
const path4 = getApmLockPath(baseDir);
|
|
23968
|
+
if (!await fileExists(path4)) {
|
|
23969
|
+
return null;
|
|
23970
|
+
}
|
|
23971
|
+
const content = await readFileContent(path4);
|
|
23972
|
+
return parseApmLock(content);
|
|
23973
|
+
}
|
|
23974
|
+
async function writeApmLock(params) {
|
|
23975
|
+
const path4 = getApmLockPath(params.baseDir);
|
|
23976
|
+
const content = serializeApmLock(params.lock);
|
|
23977
|
+
await writeFileContent(path4, content);
|
|
23978
|
+
}
|
|
23979
|
+
function serializeApmLock(lock) {
|
|
23980
|
+
return (0, import_js_yaml3.dump)(lock, { noRefs: true, lineWidth: -1, sortKeys: false });
|
|
23981
|
+
}
|
|
23982
|
+
function findApmLockDependency(lock, repoUrl) {
|
|
23983
|
+
const target = repoUrl.toLowerCase();
|
|
23984
|
+
return lock.dependencies.find((d) => d.repo_url.toLowerCase() === target);
|
|
23985
|
+
}
|
|
23986
|
+
|
|
23987
|
+
// src/lib/apm/apm-manifest.ts
|
|
23988
|
+
var import_node_path146 = require("path");
|
|
23989
|
+
var import_js_yaml4 = require("js-yaml");
|
|
23990
|
+
var import_mini76 = require("zod/mini");
|
|
23991
|
+
var APM_MANIFEST_FILE_NAME = "apm.yml";
|
|
23992
|
+
var ApmObjectDependencySchema = import_mini76.z.looseObject({
|
|
23993
|
+
git: (0, import_mini76.optional)(import_mini76.z.string()),
|
|
23994
|
+
source: (0, import_mini76.optional)(import_mini76.z.string()),
|
|
23995
|
+
path: (0, import_mini76.optional)(import_mini76.z.string()),
|
|
23996
|
+
ref: (0, import_mini76.optional)(import_mini76.z.string()),
|
|
23997
|
+
alias: (0, import_mini76.optional)(import_mini76.z.string())
|
|
23998
|
+
});
|
|
23999
|
+
var ApmDependencyInputSchema = import_mini76.z.union([import_mini76.z.string(), ApmObjectDependencySchema]);
|
|
24000
|
+
var ApmManifestSchema = import_mini76.z.looseObject({
|
|
24001
|
+
name: (0, import_mini76.optional)(import_mini76.z.string()),
|
|
24002
|
+
version: (0, import_mini76.optional)(import_mini76.z.string()),
|
|
24003
|
+
dependencies: (0, import_mini76.optional)(
|
|
24004
|
+
import_mini76.z.looseObject({
|
|
24005
|
+
apm: (0, import_mini76.optional)(import_mini76.z.array(ApmDependencyInputSchema))
|
|
24006
|
+
})
|
|
24007
|
+
)
|
|
24008
|
+
});
|
|
24009
|
+
function getApmManifestPath(baseDir) {
|
|
24010
|
+
return (0, import_node_path146.join)(baseDir, APM_MANIFEST_FILE_NAME);
|
|
24011
|
+
}
|
|
24012
|
+
async function apmManifestExists(baseDir) {
|
|
24013
|
+
return fileExists(getApmManifestPath(baseDir));
|
|
24014
|
+
}
|
|
24015
|
+
function parseApmManifest(content) {
|
|
24016
|
+
const loaded = (0, import_js_yaml4.load)(content);
|
|
24017
|
+
if (loaded === void 0 || loaded === null) {
|
|
24018
|
+
return { dependencies: [] };
|
|
24019
|
+
}
|
|
24020
|
+
const parsed = ApmManifestSchema.safeParse(loaded);
|
|
24021
|
+
if (!parsed.success) {
|
|
24022
|
+
throw new Error(`Invalid apm.yml: ${parsed.error.message}`);
|
|
24023
|
+
}
|
|
24024
|
+
const raw = parsed.data;
|
|
24025
|
+
const rawDeps = raw.dependencies?.apm ?? [];
|
|
24026
|
+
const dependencies = rawDeps.map(
|
|
24027
|
+
(entry, index) => normalizeDependency(entry, index)
|
|
24028
|
+
);
|
|
24029
|
+
return {
|
|
24030
|
+
name: raw.name,
|
|
24031
|
+
version: raw.version,
|
|
24032
|
+
dependencies
|
|
24033
|
+
};
|
|
24034
|
+
}
|
|
24035
|
+
async function readApmManifest(baseDir) {
|
|
24036
|
+
const path4 = getApmManifestPath(baseDir);
|
|
24037
|
+
const content = await readFileContent(path4);
|
|
24038
|
+
return parseApmManifest(content);
|
|
24039
|
+
}
|
|
24040
|
+
function normalizeDependency(entry, index) {
|
|
24041
|
+
if (typeof entry === "string") {
|
|
24042
|
+
return normalizeStringDependency(entry, index);
|
|
24043
|
+
}
|
|
24044
|
+
const gitUrl = entry.git ?? entry.source;
|
|
24045
|
+
if (!gitUrl) {
|
|
24046
|
+
throw new Error(
|
|
24047
|
+
`apm.yml dependency #${index + 1}: object form requires a "git" field. Received: ${JSON.stringify(entry)}.`
|
|
23924
24048
|
);
|
|
23925
24049
|
}
|
|
23926
|
-
|
|
23927
|
-
|
|
23928
|
-
|
|
24050
|
+
const parsedUrl = parseHttpsGitHubUrl(gitUrl);
|
|
24051
|
+
if (!parsedUrl) {
|
|
24052
|
+
throw new Error(
|
|
24053
|
+
`apm.yml dependency #${index + 1}: unsupported git URL "${gitUrl}". Only HTTPS GitHub URLs (https://github.com/owner/repo[.git]) are supported in this version. SSH, GitLab, Bitbucket, and other hosts are not yet supported.`
|
|
23929
24054
|
);
|
|
23930
24055
|
}
|
|
24056
|
+
if (entry.path !== void 0) {
|
|
24057
|
+
validateSubPath(entry.path, index);
|
|
24058
|
+
}
|
|
24059
|
+
return {
|
|
24060
|
+
gitUrl: parsedUrl.gitUrl,
|
|
24061
|
+
owner: parsedUrl.owner,
|
|
24062
|
+
repo: parsedUrl.repo,
|
|
24063
|
+
ref: entry.ref,
|
|
24064
|
+
path: entry.path,
|
|
24065
|
+
alias: entry.alias
|
|
24066
|
+
};
|
|
23931
24067
|
}
|
|
23932
|
-
function
|
|
23933
|
-
if (
|
|
23934
|
-
throw new
|
|
24068
|
+
function validateSubPath(subPath, index) {
|
|
24069
|
+
if (subPath === "" || subPath.startsWith("/") || subPath.startsWith("\\")) {
|
|
24070
|
+
throw new Error(
|
|
24071
|
+
`apm.yml dependency #${index + 1}: "path" must be a non-empty relative path without a leading slash. Received: ${JSON.stringify(subPath)}.`
|
|
24072
|
+
);
|
|
23935
24073
|
}
|
|
23936
|
-
const
|
|
23937
|
-
if (
|
|
23938
|
-
throw new
|
|
23939
|
-
`
|
|
24074
|
+
const segments = subPath.split(/[/\\]/);
|
|
24075
|
+
if (segments.includes("..")) {
|
|
24076
|
+
throw new Error(
|
|
24077
|
+
`apm.yml dependency #${index + 1}: "path" must not contain ".." segments. Received: ${JSON.stringify(subPath)}.`
|
|
23940
24078
|
);
|
|
23941
24079
|
}
|
|
23942
24080
|
}
|
|
23943
|
-
|
|
23944
|
-
|
|
23945
|
-
if (
|
|
23946
|
-
|
|
23947
|
-
|
|
23948
|
-
|
|
23949
|
-
|
|
23950
|
-
|
|
24081
|
+
function normalizeStringDependency(entry, index) {
|
|
24082
|
+
const trimmed = entry.trim();
|
|
24083
|
+
if (!trimmed) {
|
|
24084
|
+
throw new Error(`apm.yml dependency #${index + 1}: entry must be a non-empty string.`);
|
|
24085
|
+
}
|
|
24086
|
+
rejectUnsupportedShorthand(trimmed, index);
|
|
24087
|
+
if (trimmed.startsWith("https://")) {
|
|
24088
|
+
const [urlPart, refPart2] = splitOnFirst(trimmed, "#");
|
|
24089
|
+
const parsed = parseHttpsGitHubUrl(urlPart);
|
|
24090
|
+
if (!parsed) {
|
|
24091
|
+
throw new Error(
|
|
24092
|
+
`apm.yml dependency #${index + 1}: unsupported URL "${urlPart}". Only HTTPS GitHub URLs (https://github.com/owner/repo[.git]) are supported in this version.`
|
|
24093
|
+
);
|
|
24094
|
+
}
|
|
24095
|
+
return {
|
|
24096
|
+
gitUrl: parsed.gitUrl,
|
|
24097
|
+
owner: parsed.owner,
|
|
24098
|
+
repo: parsed.repo,
|
|
24099
|
+
ref: refPart2 || void 0
|
|
24100
|
+
};
|
|
23951
24101
|
}
|
|
23952
|
-
|
|
23953
|
-
|
|
23954
|
-
|
|
23955
|
-
|
|
23956
|
-
|
|
23957
|
-
|
|
23958
|
-
timeout: GIT_TIMEOUT_MS
|
|
23959
|
-
});
|
|
23960
|
-
const ref = stdout.match(/^ref: refs\/heads\/(.+)\tHEAD$/m)?.[1];
|
|
23961
|
-
const sha = stdout.match(/^([0-9a-f]{40})\tHEAD$/m)?.[1];
|
|
23962
|
-
if (!ref || !sha) throw new GitClientError(`Could not parse default branch from: ${url}`);
|
|
23963
|
-
validateRef(ref);
|
|
23964
|
-
return { ref, sha };
|
|
23965
|
-
} catch (error) {
|
|
23966
|
-
if (error instanceof GitClientError) throw error;
|
|
23967
|
-
throw new GitClientError(`Failed to resolve default ref for ${url}`, error);
|
|
24102
|
+
const [ownerRepo, refPart] = splitOnFirst(trimmed, "#");
|
|
24103
|
+
const slashIndex = ownerRepo.indexOf("/");
|
|
24104
|
+
if (slashIndex === -1 || slashIndex === 0 || slashIndex === ownerRepo.length - 1) {
|
|
24105
|
+
throw new Error(
|
|
24106
|
+
`apm.yml dependency #${index + 1}: shorthand "${entry}" must be in the form "owner/repo[#ref]".`
|
|
24107
|
+
);
|
|
23968
24108
|
}
|
|
23969
|
-
|
|
23970
|
-
|
|
23971
|
-
|
|
23972
|
-
|
|
23973
|
-
await checkGitAvailable();
|
|
23974
|
-
try {
|
|
23975
|
-
const { stdout } = await execFileAsync("git", ["ls-remote", "--", url, ref], {
|
|
23976
|
-
timeout: GIT_TIMEOUT_MS
|
|
23977
|
-
});
|
|
23978
|
-
const sha = stdout.match(/^([0-9a-f]{40})\t/m)?.[1];
|
|
23979
|
-
if (!sha) throw new GitClientError(`Ref "${ref}" not found in ${url}`);
|
|
23980
|
-
return sha;
|
|
23981
|
-
} catch (error) {
|
|
23982
|
-
if (error instanceof GitClientError) throw error;
|
|
23983
|
-
throw new GitClientError(`Failed to resolve ref "${ref}" for ${url}`, error);
|
|
24109
|
+
if (ownerRepo.includes("/", slashIndex + 1)) {
|
|
24110
|
+
throw new Error(
|
|
24111
|
+
`apm.yml dependency #${index + 1}: FQDN shorthand or sub-path shorthand ("${entry}") is not yet supported. Use the object form with an explicit "git" URL.`
|
|
24112
|
+
);
|
|
23984
24113
|
}
|
|
24114
|
+
const owner = ownerRepo.substring(0, slashIndex).toLowerCase();
|
|
24115
|
+
const repo = ownerRepo.substring(slashIndex + 1).toLowerCase();
|
|
24116
|
+
return {
|
|
24117
|
+
gitUrl: `https://github.com/${owner}/${repo}.git`,
|
|
24118
|
+
owner,
|
|
24119
|
+
repo,
|
|
24120
|
+
ref: refPart || void 0
|
|
24121
|
+
};
|
|
23985
24122
|
}
|
|
23986
|
-
|
|
23987
|
-
|
|
23988
|
-
|
|
23989
|
-
|
|
23990
|
-
if (skillsPath.split(/[/\\]/).includes("..") || (0, import_node_path145.isAbsolute)(skillsPath)) {
|
|
23991
|
-
throw new GitClientError(
|
|
23992
|
-
`Invalid skillsPath "${skillsPath}": must be a relative path without ".."`
|
|
24123
|
+
function rejectUnsupportedShorthand(entry, index) {
|
|
24124
|
+
if (entry.startsWith("./") || entry.startsWith("../") || entry.startsWith("/")) {
|
|
24125
|
+
throw new Error(
|
|
24126
|
+
`apm.yml dependency #${index + 1}: local path dependencies ("${entry}") are not yet supported by rulesync.`
|
|
23993
24127
|
);
|
|
23994
24128
|
}
|
|
23995
|
-
|
|
23996
|
-
|
|
23997
|
-
|
|
23998
|
-
`skillsPath contains control character ${ctrl.hex} at position ${ctrl.position}`
|
|
24129
|
+
if (entry.startsWith("git@") || entry.startsWith("ssh://")) {
|
|
24130
|
+
throw new Error(
|
|
24131
|
+
`apm.yml dependency #${index + 1}: SSH URL dependencies ("${entry}") are not yet supported. Use an HTTPS GitHub URL.`
|
|
23999
24132
|
);
|
|
24000
24133
|
}
|
|
24001
|
-
|
|
24002
|
-
|
|
24003
|
-
|
|
24004
|
-
await execFileAsync(
|
|
24005
|
-
"git",
|
|
24006
|
-
[
|
|
24007
|
-
"clone",
|
|
24008
|
-
"--depth",
|
|
24009
|
-
"1",
|
|
24010
|
-
"--branch",
|
|
24011
|
-
ref,
|
|
24012
|
-
"--no-checkout",
|
|
24013
|
-
"--filter=blob:none",
|
|
24014
|
-
"--",
|
|
24015
|
-
url,
|
|
24016
|
-
tmpDir
|
|
24017
|
-
],
|
|
24018
|
-
{ timeout: GIT_TIMEOUT_MS }
|
|
24134
|
+
if (entry.includes("@marketplace")) {
|
|
24135
|
+
throw new Error(
|
|
24136
|
+
`apm.yml dependency #${index + 1}: APM marketplace dependencies ("${entry}") are not yet supported.`
|
|
24019
24137
|
);
|
|
24020
|
-
await execFileAsync("git", ["-C", tmpDir, "sparse-checkout", "set", "--", skillsPath], {
|
|
24021
|
-
timeout: GIT_TIMEOUT_MS
|
|
24022
|
-
});
|
|
24023
|
-
await execFileAsync("git", ["-C", tmpDir, "checkout"], { timeout: GIT_TIMEOUT_MS });
|
|
24024
|
-
const skillsDir = (0, import_node_path145.join)(tmpDir, skillsPath);
|
|
24025
|
-
if (!await directoryExists(skillsDir)) return [];
|
|
24026
|
-
return await walkDirectory(skillsDir, skillsDir, 0, { totalFiles: 0, totalSize: 0 }, logger5);
|
|
24027
|
-
} catch (error) {
|
|
24028
|
-
if (error instanceof GitClientError) throw error;
|
|
24029
|
-
throw new GitClientError(`Failed to fetch skill files from ${url}`, error);
|
|
24030
|
-
} finally {
|
|
24031
|
-
await removeTempDirectory(tmpDir);
|
|
24032
24138
|
}
|
|
24033
24139
|
}
|
|
24034
|
-
|
|
24035
|
-
|
|
24036
|
-
|
|
24037
|
-
|
|
24038
|
-
|
|
24039
|
-
|
|
24040
|
-
|
|
24140
|
+
function parseHttpsGitHubUrl(url) {
|
|
24141
|
+
let parsed;
|
|
24142
|
+
try {
|
|
24143
|
+
parsed = new URL(url);
|
|
24144
|
+
} catch {
|
|
24145
|
+
return null;
|
|
24146
|
+
}
|
|
24147
|
+
const host = parsed.hostname.toLowerCase();
|
|
24148
|
+
if (host !== "github.com" && host !== "www.github.com") {
|
|
24149
|
+
return null;
|
|
24150
|
+
}
|
|
24151
|
+
const segments = parsed.pathname.split("/").filter(Boolean);
|
|
24152
|
+
if (segments.length < 2) {
|
|
24153
|
+
return null;
|
|
24154
|
+
}
|
|
24155
|
+
const rawOwner = segments[0];
|
|
24156
|
+
const rawRepo = segments[1];
|
|
24157
|
+
if (!rawOwner || !rawRepo) {
|
|
24158
|
+
return null;
|
|
24159
|
+
}
|
|
24160
|
+
const owner = rawOwner.toLowerCase();
|
|
24161
|
+
const repo = rawRepo.replace(/\.git$/, "").toLowerCase();
|
|
24162
|
+
return {
|
|
24163
|
+
gitUrl: `https://github.com/${owner}/${repo}.git`,
|
|
24164
|
+
owner,
|
|
24165
|
+
repo
|
|
24166
|
+
};
|
|
24167
|
+
}
|
|
24168
|
+
function splitOnFirst(input, separator) {
|
|
24169
|
+
const idx = input.indexOf(separator);
|
|
24170
|
+
if (idx === -1) return [input, void 0];
|
|
24171
|
+
return [input.substring(0, idx), input.substring(idx + 1)];
|
|
24172
|
+
}
|
|
24173
|
+
|
|
24174
|
+
// src/lib/apm/apm-install.ts
|
|
24175
|
+
var RULESYNC_APM_COMPAT_VERSION = "rulesync-compat/0.1";
|
|
24176
|
+
var APM_PRIMITIVES = [
|
|
24177
|
+
{
|
|
24178
|
+
sourceDir: ".apm/instructions",
|
|
24179
|
+
deployDir: ".github/instructions",
|
|
24180
|
+
packageType: "apm_package"
|
|
24181
|
+
},
|
|
24182
|
+
{
|
|
24183
|
+
sourceDir: ".apm/skills",
|
|
24184
|
+
deployDir: ".github/skills",
|
|
24185
|
+
packageType: "apm_package"
|
|
24186
|
+
}
|
|
24187
|
+
];
|
|
24188
|
+
async function installApm(params) {
|
|
24189
|
+
const { baseDir, options = {}, logger: logger5 } = params;
|
|
24190
|
+
const manifest = await readApmManifest(baseDir);
|
|
24191
|
+
if (manifest.dependencies.length === 0) {
|
|
24192
|
+
logger5.warn("apm.yml has no dependencies.apm entries. Nothing to install.");
|
|
24193
|
+
return { dependenciesProcessed: 0, deployedFileCount: 0, failedDependencyCount: 0 };
|
|
24194
|
+
}
|
|
24195
|
+
const existingLock = await readApmLock(baseDir);
|
|
24196
|
+
if (options.frozen) {
|
|
24197
|
+
if (!existingLock) {
|
|
24198
|
+
throw new Error(
|
|
24199
|
+
"Frozen install failed: rulesync-apm.lock.yaml is missing. Run 'rulesync install --mode apm' to create it."
|
|
24200
|
+
);
|
|
24201
|
+
}
|
|
24202
|
+
const missing = manifest.dependencies.filter(
|
|
24203
|
+
(dep) => !findApmLockDependency(existingLock, canonicalRepoUrl(dep))
|
|
24204
|
+
);
|
|
24205
|
+
if (missing.length > 0) {
|
|
24206
|
+
const names = missing.map((d) => d.gitUrl).join(", ");
|
|
24207
|
+
throw new Error(
|
|
24208
|
+
`Frozen install failed: rulesync-apm.lock.yaml is missing entries for: ${names}. Run 'rulesync install --mode apm' to update the lockfile.`
|
|
24209
|
+
);
|
|
24210
|
+
}
|
|
24211
|
+
const drifted = manifest.dependencies.filter((dep) => {
|
|
24212
|
+
if (dep.ref === void 0) return false;
|
|
24213
|
+
const locked = findApmLockDependency(existingLock, canonicalRepoUrl(dep));
|
|
24214
|
+
return locked?.resolved_ref !== void 0 && locked.resolved_ref !== dep.ref;
|
|
24215
|
+
});
|
|
24216
|
+
if (drifted.length > 0) {
|
|
24217
|
+
const names = drifted.map((d) => {
|
|
24218
|
+
const locked = findApmLockDependency(existingLock, canonicalRepoUrl(d));
|
|
24219
|
+
return `${d.gitUrl} (manifest=${d.ref}, lock=${locked?.resolved_ref})`;
|
|
24220
|
+
}).join(", ");
|
|
24221
|
+
throw new Error(
|
|
24222
|
+
`Frozen install failed: manifest ref does not match rulesync-apm.lock.yaml for: ${names}. Run 'rulesync install --mode apm' to update the lockfile.`
|
|
24223
|
+
);
|
|
24224
|
+
}
|
|
24225
|
+
}
|
|
24226
|
+
const token = GitHubClient.resolveToken(options.token);
|
|
24227
|
+
const client = new GitHubClient({ token });
|
|
24228
|
+
const semaphore = new import_promise2.Semaphore(FETCH_CONCURRENCY_LIMIT);
|
|
24229
|
+
const newLock = createEmptyApmLock({
|
|
24230
|
+
apmVersion: existingLock?.apm_version ?? RULESYNC_APM_COMPAT_VERSION,
|
|
24231
|
+
existingLock
|
|
24232
|
+
});
|
|
24233
|
+
const frozen = options.frozen ?? false;
|
|
24234
|
+
const runOne = async (dep) => {
|
|
24235
|
+
const installed = await installDependency({
|
|
24236
|
+
dep,
|
|
24237
|
+
client,
|
|
24238
|
+
semaphore,
|
|
24239
|
+
baseDir,
|
|
24240
|
+
existingLock,
|
|
24241
|
+
frozen,
|
|
24242
|
+
update: options.update ?? false,
|
|
24243
|
+
logger: logger5
|
|
24244
|
+
});
|
|
24245
|
+
return {
|
|
24246
|
+
status: "ok",
|
|
24247
|
+
lockEntry: installed.lockEntry,
|
|
24248
|
+
deployedCount: installed.deployedFiles.length
|
|
24249
|
+
};
|
|
24250
|
+
};
|
|
24251
|
+
const results = frozen ? await Promise.all(manifest.dependencies.map(runOne)) : await Promise.all(
|
|
24252
|
+
manifest.dependencies.map(async (dep) => {
|
|
24253
|
+
try {
|
|
24254
|
+
return await runOne(dep);
|
|
24255
|
+
} catch (error) {
|
|
24256
|
+
logger5.error(`Failed to install apm dependency "${dep.gitUrl}": ${formatError(error)}`);
|
|
24257
|
+
if (error instanceof GitHubClientError) {
|
|
24258
|
+
logGitHubAuthHints({ error, logger: logger5 });
|
|
24259
|
+
}
|
|
24260
|
+
const previous = existingLock ? findApmLockDependency(existingLock, canonicalRepoUrl(dep)) : void 0;
|
|
24261
|
+
return { status: "failed", previous };
|
|
24262
|
+
}
|
|
24263
|
+
})
|
|
24264
|
+
);
|
|
24265
|
+
let totalDeployed = 0;
|
|
24266
|
+
let failedCount = 0;
|
|
24267
|
+
for (const result of results) {
|
|
24268
|
+
if (result.status === "ok") {
|
|
24269
|
+
newLock.dependencies.push(result.lockEntry);
|
|
24270
|
+
totalDeployed += result.deployedCount;
|
|
24271
|
+
} else {
|
|
24272
|
+
failedCount += 1;
|
|
24273
|
+
if (result.previous) {
|
|
24274
|
+
newLock.dependencies.push(result.previous);
|
|
24275
|
+
}
|
|
24276
|
+
}
|
|
24277
|
+
}
|
|
24278
|
+
if (existingLock) {
|
|
24279
|
+
const newDeployedFiles = new Set(newLock.dependencies.flatMap((d) => d.deployed_files));
|
|
24280
|
+
const toDelete = [];
|
|
24281
|
+
for (const prev of existingLock.dependencies) {
|
|
24282
|
+
for (const deployed of prev.deployed_files) {
|
|
24283
|
+
if (!newDeployedFiles.has(deployed)) {
|
|
24284
|
+
toDelete.push(deployed);
|
|
24285
|
+
}
|
|
24286
|
+
}
|
|
24287
|
+
}
|
|
24288
|
+
for (const relativePath of toDelete) {
|
|
24289
|
+
if (import_node_path147.posix.isAbsolute(relativePath) || relativePath.split(/[/\\]/).includes("..")) {
|
|
24290
|
+
logger5.warn(`Refusing to remove stale apm file with suspicious path: "${relativePath}".`);
|
|
24291
|
+
continue;
|
|
24292
|
+
}
|
|
24293
|
+
try {
|
|
24294
|
+
checkPathTraversal({ relativePath, intendedRootDir: baseDir });
|
|
24295
|
+
} catch {
|
|
24296
|
+
logger5.warn(`Refusing to remove stale apm file outside baseDir: "${relativePath}".`);
|
|
24297
|
+
continue;
|
|
24298
|
+
}
|
|
24299
|
+
const absolute = (0, import_node_path147.join)(baseDir, relativePath);
|
|
24300
|
+
await removeFile(absolute);
|
|
24301
|
+
logger5.debug(`Removed stale apm file: ${relativePath}`);
|
|
24302
|
+
}
|
|
24303
|
+
}
|
|
24304
|
+
if (!frozen) {
|
|
24305
|
+
newLock.generated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
24306
|
+
await writeApmLock({ baseDir, lock: newLock });
|
|
24307
|
+
if (failedCount === 0) {
|
|
24308
|
+
logger5.debug("rulesync-apm.lock.yaml updated.");
|
|
24309
|
+
} else {
|
|
24310
|
+
logger5.warn(
|
|
24311
|
+
`rulesync-apm.lock.yaml written with partially successful installs (${failedCount} dep(s) failed).`
|
|
24312
|
+
);
|
|
24313
|
+
}
|
|
24314
|
+
}
|
|
24315
|
+
return {
|
|
24316
|
+
dependenciesProcessed: manifest.dependencies.length,
|
|
24317
|
+
deployedFileCount: totalDeployed,
|
|
24318
|
+
failedDependencyCount: failedCount
|
|
24319
|
+
};
|
|
24320
|
+
}
|
|
24321
|
+
async function installDependency(params) {
|
|
24322
|
+
const { dep, client, semaphore, baseDir, existingLock, frozen, update, logger: logger5 } = params;
|
|
24323
|
+
const repoUrl = canonicalRepoUrl(dep);
|
|
24324
|
+
const locked = existingLock ? findApmLockDependency(existingLock, repoUrl) : void 0;
|
|
24325
|
+
let resolvedRef;
|
|
24326
|
+
let resolvedSha;
|
|
24327
|
+
if (locked && !update && locked.resolved_commit && locked.resolved_ref) {
|
|
24328
|
+
resolvedRef = locked.resolved_ref;
|
|
24329
|
+
resolvedSha = locked.resolved_commit;
|
|
24330
|
+
logger5.debug(`Using locked commit for ${repoUrl}: ${resolvedSha}`);
|
|
24331
|
+
} else {
|
|
24332
|
+
resolvedRef = dep.ref ?? await client.getDefaultBranch(dep.owner, dep.repo);
|
|
24333
|
+
resolvedSha = await client.resolveRefToSha(dep.owner, dep.repo, resolvedRef);
|
|
24334
|
+
logger5.debug(`Resolved ${repoUrl} ref "${resolvedRef}" -> ${resolvedSha}`);
|
|
24335
|
+
}
|
|
24336
|
+
const deployed = [];
|
|
24337
|
+
for (const primitive of APM_PRIMITIVES) {
|
|
24338
|
+
const remoteBase = dep.path ? toPosixPath(import_node_path147.posix.join(dep.path, primitive.sourceDir)) : primitive.sourceDir;
|
|
24339
|
+
const files = await listPrimitiveFiles({
|
|
24340
|
+
client,
|
|
24341
|
+
semaphore,
|
|
24342
|
+
owner: dep.owner,
|
|
24343
|
+
repo: dep.repo,
|
|
24344
|
+
ref: resolvedSha,
|
|
24345
|
+
remoteBase,
|
|
24346
|
+
logger: logger5
|
|
24347
|
+
});
|
|
24348
|
+
if (files.length === 0) continue;
|
|
24349
|
+
for (const file of files) {
|
|
24350
|
+
if (file.size > MAX_FILE_SIZE) {
|
|
24351
|
+
logger5.warn(
|
|
24352
|
+
`Skipping "${file.path}" from ${repoUrl}: ${(file.size / 1024 / 1024).toFixed(2)}MB exceeds ${MAX_FILE_SIZE / 1024 / 1024}MB limit.`
|
|
24353
|
+
);
|
|
24354
|
+
continue;
|
|
24355
|
+
}
|
|
24356
|
+
const relativeToBase = import_node_path147.posix.relative(remoteBase, toPosixPath(file.path));
|
|
24357
|
+
if (!relativeToBase || relativeToBase.startsWith("..") || import_node_path147.posix.isAbsolute(relativeToBase)) {
|
|
24358
|
+
logger5.warn(
|
|
24359
|
+
`Skipping "${file.path}" from ${repoUrl}: resolved outside of "${remoteBase}".`
|
|
24360
|
+
);
|
|
24361
|
+
continue;
|
|
24362
|
+
}
|
|
24363
|
+
const deployRelative = toPosixPath((0, import_node_path147.join)(primitive.deployDir, relativeToBase));
|
|
24364
|
+
checkPathTraversal({
|
|
24365
|
+
relativePath: deployRelative,
|
|
24366
|
+
intendedRootDir: baseDir
|
|
24367
|
+
});
|
|
24368
|
+
const content = await withSemaphore(
|
|
24369
|
+
semaphore,
|
|
24370
|
+
() => client.getFileContent(dep.owner, dep.repo, file.path, resolvedSha)
|
|
24371
|
+
);
|
|
24372
|
+
const byteLength = Buffer.byteLength(content, "utf8");
|
|
24373
|
+
if (byteLength > MAX_FILE_SIZE) {
|
|
24374
|
+
logger5.warn(
|
|
24375
|
+
`Skipping "${file.path}" from ${repoUrl}: fetched ${(byteLength / 1024 / 1024).toFixed(2)}MB exceeds ${MAX_FILE_SIZE / 1024 / 1024}MB limit.`
|
|
24376
|
+
);
|
|
24377
|
+
continue;
|
|
24378
|
+
}
|
|
24379
|
+
deployed.push({ path: deployRelative, content });
|
|
24380
|
+
if (!frozen) {
|
|
24381
|
+
await writeFileContent((0, import_node_path147.join)(baseDir, deployRelative), content);
|
|
24382
|
+
}
|
|
24383
|
+
}
|
|
24384
|
+
}
|
|
24385
|
+
deployed.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
24386
|
+
const deployedFiles = deployed.map((d) => d.path);
|
|
24387
|
+
const contentHash = computeContentHash(deployed);
|
|
24388
|
+
if (frozen && locked?.content_hash) {
|
|
24389
|
+
if (RULESYNC_CONTENT_HASH_REGEX.test(locked.content_hash)) {
|
|
24390
|
+
if (locked.content_hash !== contentHash) {
|
|
24391
|
+
throw new Error(
|
|
24392
|
+
`content_hash mismatch for ${repoUrl}: lock=${locked.content_hash} computed=${contentHash}. Refuse to trust the deployment under --frozen.`
|
|
24393
|
+
);
|
|
24394
|
+
}
|
|
24395
|
+
} else {
|
|
24396
|
+
logger5.debug(
|
|
24397
|
+
`Skipping content_hash integrity check for ${repoUrl}: recorded hash "${locked.content_hash}" was not written by rulesync.`
|
|
24398
|
+
);
|
|
24399
|
+
}
|
|
24400
|
+
}
|
|
24401
|
+
if (frozen) {
|
|
24402
|
+
for (const { path: deployRelative, content } of deployed) {
|
|
24403
|
+
await writeFileContent((0, import_node_path147.join)(baseDir, deployRelative), content);
|
|
24404
|
+
}
|
|
24405
|
+
}
|
|
24406
|
+
const lockEntry = {
|
|
24407
|
+
repo_url: repoUrl,
|
|
24408
|
+
resolved_commit: resolvedSha,
|
|
24409
|
+
resolved_ref: resolvedRef,
|
|
24410
|
+
depth: 1,
|
|
24411
|
+
package_type: "apm_package",
|
|
24412
|
+
content_hash: contentHash,
|
|
24413
|
+
deployed_files: deployedFiles
|
|
24414
|
+
};
|
|
24415
|
+
if (dep.path) {
|
|
24416
|
+
lockEntry.virtual_path = dep.path;
|
|
24417
|
+
}
|
|
24418
|
+
logger5.info(`Installed ${deployedFiles.length} file(s) from ${repoUrl}@${shortSha(resolvedSha)}`);
|
|
24419
|
+
return { lockEntry, deployedFiles };
|
|
24420
|
+
}
|
|
24421
|
+
function computeContentHash(files) {
|
|
24422
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
24423
|
+
for (const { path: path4, content } of files) {
|
|
24424
|
+
hash.update(path4);
|
|
24425
|
+
hash.update("\0");
|
|
24426
|
+
hash.update(content);
|
|
24427
|
+
hash.update("\0");
|
|
24428
|
+
}
|
|
24429
|
+
return `sha256:${hash.digest("hex")}`;
|
|
24430
|
+
}
|
|
24431
|
+
async function listPrimitiveFiles(params) {
|
|
24432
|
+
const { client, semaphore, owner, repo, ref, remoteBase, logger: logger5 } = params;
|
|
24433
|
+
try {
|
|
24434
|
+
return await listDirectoryRecursive({
|
|
24435
|
+
client,
|
|
24436
|
+
owner,
|
|
24437
|
+
repo,
|
|
24438
|
+
path: remoteBase,
|
|
24439
|
+
ref,
|
|
24440
|
+
semaphore
|
|
24441
|
+
});
|
|
24442
|
+
} catch (error) {
|
|
24443
|
+
if (error instanceof GitHubClientError && error.statusCode === 404) {
|
|
24444
|
+
logger5.debug(`No ${remoteBase}/ in ${owner}/${repo}, skipping.`);
|
|
24445
|
+
return [];
|
|
24446
|
+
}
|
|
24447
|
+
throw error;
|
|
24448
|
+
}
|
|
24449
|
+
}
|
|
24450
|
+
function canonicalRepoUrl(dep) {
|
|
24451
|
+
return `https://github.com/${dep.owner}/${dep.repo}`;
|
|
24452
|
+
}
|
|
24453
|
+
function shortSha(sha) {
|
|
24454
|
+
return sha.substring(0, 7);
|
|
24455
|
+
}
|
|
24456
|
+
|
|
24457
|
+
// src/lib/gh/gh-install.ts
|
|
24458
|
+
var import_node_crypto2 = require("crypto");
|
|
24459
|
+
var import_node_path150 = require("path");
|
|
24460
|
+
var import_promise3 = require("es-toolkit/promise");
|
|
24461
|
+
|
|
24462
|
+
// src/lib/gh/gh-frontmatter.ts
|
|
24463
|
+
var import_js_yaml5 = require("js-yaml");
|
|
24464
|
+
var FRONTMATTER_FENCE = "---";
|
|
24465
|
+
function injectSourceMetadata(params) {
|
|
24466
|
+
const { content, source, repository, ref } = params;
|
|
24467
|
+
const provenance = { source, repository, ref };
|
|
24468
|
+
let openFenceLen;
|
|
24469
|
+
if (content.startsWith(`${FRONTMATTER_FENCE}\r
|
|
24470
|
+
`)) {
|
|
24471
|
+
openFenceLen = 5;
|
|
24472
|
+
} else if (content.startsWith(`${FRONTMATTER_FENCE}
|
|
24473
|
+
`)) {
|
|
24474
|
+
openFenceLen = 4;
|
|
24475
|
+
} else if (content === FRONTMATTER_FENCE) {
|
|
24476
|
+
openFenceLen = 3;
|
|
24477
|
+
} else {
|
|
24478
|
+
const yaml2 = (0, import_js_yaml5.dump)(provenance, { noRefs: true, lineWidth: -1, sortKeys: false });
|
|
24479
|
+
return `${FRONTMATTER_FENCE}
|
|
24480
|
+
${yaml2}${FRONTMATTER_FENCE}
|
|
24481
|
+
${content}`;
|
|
24482
|
+
}
|
|
24483
|
+
const afterOpen = content.substring(openFenceLen);
|
|
24484
|
+
let fmBody;
|
|
24485
|
+
let rest;
|
|
24486
|
+
if (afterOpen.startsWith("---\n") || afterOpen.startsWith("---\r\n") || afterOpen === "---") {
|
|
24487
|
+
fmBody = "";
|
|
24488
|
+
const fenceLen = afterOpen.startsWith("---\r\n") ? 5 : afterOpen === "---" ? 3 : 4;
|
|
24489
|
+
rest = afterOpen.substring(fenceLen);
|
|
24490
|
+
} else {
|
|
24491
|
+
const match = /\n---(\r?\n|$)/.exec(afterOpen);
|
|
24492
|
+
if (!match) {
|
|
24493
|
+
throw new Error("invalid frontmatter");
|
|
24494
|
+
}
|
|
24495
|
+
fmBody = afterOpen.substring(0, match.index);
|
|
24496
|
+
rest = afterOpen.substring(match.index + match[0].length);
|
|
24497
|
+
}
|
|
24498
|
+
let loaded;
|
|
24499
|
+
try {
|
|
24500
|
+
loaded = (0, import_js_yaml5.load)(fmBody);
|
|
24501
|
+
} catch {
|
|
24502
|
+
throw new Error("invalid frontmatter");
|
|
24503
|
+
}
|
|
24504
|
+
if (loaded === null || loaded === void 0) {
|
|
24505
|
+
const yaml2 = (0, import_js_yaml5.dump)(provenance, { noRefs: true, lineWidth: -1, sortKeys: false });
|
|
24506
|
+
return `${FRONTMATTER_FENCE}
|
|
24507
|
+
${yaml2}${FRONTMATTER_FENCE}
|
|
24508
|
+
${rest}`;
|
|
24509
|
+
}
|
|
24510
|
+
if (typeof loaded !== "object" || Array.isArray(loaded)) {
|
|
24511
|
+
throw new Error("invalid frontmatter");
|
|
24512
|
+
}
|
|
24513
|
+
const existing = loaded;
|
|
24514
|
+
const merged = {
|
|
24515
|
+
...existing,
|
|
24516
|
+
...provenance
|
|
24517
|
+
};
|
|
24518
|
+
const yaml = (0, import_js_yaml5.dump)(merged, { noRefs: true, lineWidth: -1, sortKeys: false });
|
|
24519
|
+
return `${FRONTMATTER_FENCE}
|
|
24520
|
+
${yaml}${FRONTMATTER_FENCE}
|
|
24521
|
+
${rest}`;
|
|
24522
|
+
}
|
|
24523
|
+
|
|
24524
|
+
// src/lib/gh/gh-lock.ts
|
|
24525
|
+
var import_node_path148 = require("path");
|
|
24526
|
+
var import_js_yaml6 = require("js-yaml");
|
|
24527
|
+
var import_mini77 = require("zod/mini");
|
|
24528
|
+
var GH_LOCKFILE_FILE_NAME = "rulesync-gh.lock.yaml";
|
|
24529
|
+
var GH_LOCKFILE_VERSION = "1";
|
|
24530
|
+
var RULESYNC_CONTENT_HASH_REGEX2 = /^sha256:[0-9a-f]{64}$/;
|
|
24531
|
+
var ScopeSchema = import_mini77.z.enum(["project", "user"]);
|
|
24532
|
+
var GhLockInstallationSchema = import_mini77.z.looseObject({
|
|
24533
|
+
source: import_mini77.z.string(),
|
|
24534
|
+
owner: import_mini77.z.string(),
|
|
24535
|
+
repo: import_mini77.z.string(),
|
|
24536
|
+
agent: import_mini77.z.string(),
|
|
24537
|
+
scope: ScopeSchema,
|
|
24538
|
+
skill: import_mini77.z.string(),
|
|
24539
|
+
requested_ref: (0, import_mini77.optional)(import_mini77.z.string()),
|
|
24540
|
+
resolved_ref: import_mini77.z.string(),
|
|
24541
|
+
resolved_commit: import_mini77.z.string().check((0, import_mini77.refine)((v) => /^[0-9a-f]{40}$/.test(v), "resolved_commit must be a 40-char hex SHA")),
|
|
24542
|
+
install_dir: import_mini77.z.string(),
|
|
24543
|
+
deployed_files: import_mini77.z.array(import_mini77.z.string()),
|
|
24544
|
+
content_hash: (0, import_mini77.optional)(import_mini77.z.string())
|
|
24545
|
+
});
|
|
24546
|
+
var GhLockSchema = import_mini77.z.looseObject({
|
|
24547
|
+
lockfile_version: import_mini77.z.literal("1"),
|
|
24548
|
+
generated_at: import_mini77.z.string(),
|
|
24549
|
+
installations: import_mini77.z.array(GhLockInstallationSchema)
|
|
24550
|
+
});
|
|
24551
|
+
function getGhLockPath(baseDir) {
|
|
24552
|
+
return (0, import_node_path148.join)(baseDir, GH_LOCKFILE_FILE_NAME);
|
|
24553
|
+
}
|
|
24554
|
+
function createEmptyGhLock(params) {
|
|
24555
|
+
const base = params?.existingLock ? { ...params.existingLock } : {};
|
|
24556
|
+
return {
|
|
24557
|
+
...base,
|
|
24558
|
+
lockfile_version: GH_LOCKFILE_VERSION,
|
|
24559
|
+
generated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24560
|
+
installations: []
|
|
24561
|
+
};
|
|
24562
|
+
}
|
|
24563
|
+
function parseGhLock(content) {
|
|
24564
|
+
if (!content.trim()) {
|
|
24565
|
+
return null;
|
|
24566
|
+
}
|
|
24567
|
+
let loaded;
|
|
24568
|
+
try {
|
|
24569
|
+
loaded = (0, import_js_yaml6.load)(content);
|
|
24570
|
+
} catch {
|
|
24571
|
+
return null;
|
|
24572
|
+
}
|
|
24573
|
+
if (!loaded || typeof loaded !== "object") {
|
|
24574
|
+
return null;
|
|
24575
|
+
}
|
|
24576
|
+
const parsed = GhLockSchema.safeParse(loaded);
|
|
24577
|
+
if (!parsed.success) {
|
|
24578
|
+
const issues = parsed.error.issues.map((issue) => ` - ${issue.path.join(".") || "<root>"}: ${issue.message}`).join("\n");
|
|
24579
|
+
throw new Error(`Invalid ${GH_LOCKFILE_FILE_NAME}:
|
|
24580
|
+
${issues}`);
|
|
24581
|
+
}
|
|
24582
|
+
return parsed.data;
|
|
24583
|
+
}
|
|
24584
|
+
async function readGhLock(baseDir) {
|
|
24585
|
+
const path4 = getGhLockPath(baseDir);
|
|
24586
|
+
if (!await fileExists(path4)) {
|
|
24587
|
+
return null;
|
|
24588
|
+
}
|
|
24589
|
+
const content = await readFileContent(path4);
|
|
24590
|
+
return parseGhLock(content);
|
|
24591
|
+
}
|
|
24592
|
+
async function writeGhLock(params) {
|
|
24593
|
+
const path4 = getGhLockPath(params.baseDir);
|
|
24594
|
+
const content = serializeGhLock(params.lock);
|
|
24595
|
+
await writeFileContent(path4, content);
|
|
24596
|
+
}
|
|
24597
|
+
function serializeGhLock(lock) {
|
|
24598
|
+
return (0, import_js_yaml6.dump)(lock, { noRefs: true, lineWidth: -1, sortKeys: false });
|
|
24599
|
+
}
|
|
24600
|
+
function findGhLockInstallation(lock, params) {
|
|
24601
|
+
const target = params.source.toLowerCase();
|
|
24602
|
+
return lock.installations.find(
|
|
24603
|
+
(i) => i.source.toLowerCase() === target && i.agent === params.agent && i.scope === params.scope && i.skill === params.skill
|
|
24604
|
+
);
|
|
24605
|
+
}
|
|
24606
|
+
|
|
24607
|
+
// src/lib/gh/gh-paths.ts
|
|
24608
|
+
var import_node_path149 = require("path");
|
|
24609
|
+
var GH_AGENTS = [
|
|
24610
|
+
"github-copilot",
|
|
24611
|
+
"claude-code",
|
|
24612
|
+
"cursor",
|
|
24613
|
+
"codex",
|
|
24614
|
+
"gemini",
|
|
24615
|
+
"antigravity"
|
|
24616
|
+
];
|
|
24617
|
+
function relativeInstallDirFor(params) {
|
|
24618
|
+
const { agent, scope } = params;
|
|
24619
|
+
if (scope === "project") {
|
|
24620
|
+
if (agent === "claude-code") {
|
|
24621
|
+
return (0, import_node_path149.join)(".claude", "skills");
|
|
24622
|
+
}
|
|
24623
|
+
return (0, import_node_path149.join)(".agents", "skills");
|
|
24624
|
+
}
|
|
24625
|
+
switch (agent) {
|
|
24626
|
+
case "github-copilot":
|
|
24627
|
+
return (0, import_node_path149.join)(".copilot", "skills");
|
|
24628
|
+
case "claude-code":
|
|
24629
|
+
return (0, import_node_path149.join)(".claude", "skills");
|
|
24630
|
+
case "cursor":
|
|
24631
|
+
return (0, import_node_path149.join)(".cursor", "skills");
|
|
24632
|
+
case "codex":
|
|
24633
|
+
return (0, import_node_path149.join)(".codex", "skills");
|
|
24634
|
+
case "gemini":
|
|
24635
|
+
return (0, import_node_path149.join)(".gemini", "skills");
|
|
24636
|
+
case "antigravity":
|
|
24637
|
+
return (0, import_node_path149.join)(".gemini", "antigravity", "skills");
|
|
24638
|
+
}
|
|
24639
|
+
}
|
|
24640
|
+
|
|
24641
|
+
// src/lib/gh/gh-install.ts
|
|
24642
|
+
var SKILLS_REMOTE_DIR = "skills";
|
|
24643
|
+
var SKILL_FILE_NAME2 = "SKILL.md";
|
|
24644
|
+
async function installGh(params) {
|
|
24645
|
+
const { baseDir, sources, options = {}, logger: logger5 } = params;
|
|
24646
|
+
if (sources.length === 0) {
|
|
24647
|
+
return { sourcesProcessed: 0, installedSkillCount: 0, failedSourceCount: 0 };
|
|
24648
|
+
}
|
|
24649
|
+
const resolvedSources = sources.map((entry) => {
|
|
24650
|
+
const parsed = parseSource(entry.source);
|
|
24651
|
+
if (parsed.provider !== "github") {
|
|
24652
|
+
throw new Error(
|
|
24653
|
+
`--mode gh only supports GitHub sources. "${entry.source}" resolves to provider "${parsed.provider}".`
|
|
24654
|
+
);
|
|
24655
|
+
}
|
|
24656
|
+
if (entry.transport !== void 0 && entry.transport !== "github") {
|
|
24657
|
+
throw new Error(
|
|
24658
|
+
`--mode gh: field "transport" is not supported (got "${entry.transport}" for source "${entry.source}"). Drop the field or switch to --mode rulesync.`
|
|
24659
|
+
);
|
|
24660
|
+
}
|
|
24661
|
+
if (entry.path !== void 0) {
|
|
24662
|
+
throw new Error(
|
|
24663
|
+
`--mode gh: field "path" is not supported for source "${entry.source}". The remote layout is fixed to "skills/<name>/SKILL.md".`
|
|
24664
|
+
);
|
|
24665
|
+
}
|
|
24666
|
+
const agent = entry.agent ?? "github-copilot";
|
|
24667
|
+
if (!GH_AGENTS.includes(agent)) {
|
|
24668
|
+
throw new Error(
|
|
24669
|
+
`--mode gh: unknown agent "${agent}" for source "${entry.source}". Valid agents: ${GH_AGENTS.join(", ")}.`
|
|
24670
|
+
);
|
|
24671
|
+
}
|
|
24672
|
+
const scope = entry.scope ?? "project";
|
|
24673
|
+
return {
|
|
24674
|
+
entry,
|
|
24675
|
+
owner: parsed.owner,
|
|
24676
|
+
repo: parsed.repo,
|
|
24677
|
+
ref: entry.ref ?? parsed.ref,
|
|
24678
|
+
agent,
|
|
24679
|
+
scope
|
|
24680
|
+
};
|
|
24681
|
+
});
|
|
24682
|
+
const existingLock = await readGhLock(baseDir);
|
|
24683
|
+
const frozen = options.frozen ?? false;
|
|
24684
|
+
const update = options.update ?? false;
|
|
24685
|
+
if (frozen && !existingLock) {
|
|
24686
|
+
throw new Error(
|
|
24687
|
+
"Frozen install failed: rulesync-gh.lock.yaml is missing. Run 'rulesync install --mode gh' to create it."
|
|
24688
|
+
);
|
|
24689
|
+
}
|
|
24690
|
+
if (frozen && existingLock) {
|
|
24691
|
+
const uncovered = [];
|
|
24692
|
+
for (const rs of resolvedSources) {
|
|
24693
|
+
const hasAny = existingLock.installations.some(
|
|
24694
|
+
(i) => i.source.toLowerCase() === rs.entry.source.toLowerCase() && i.agent === rs.agent && i.scope === rs.scope
|
|
24695
|
+
);
|
|
24696
|
+
if (!hasAny) {
|
|
24697
|
+
uncovered.push(`${rs.entry.source} (agent=${rs.agent}, scope=${rs.scope})`);
|
|
24698
|
+
}
|
|
24699
|
+
}
|
|
24700
|
+
if (uncovered.length > 0) {
|
|
24701
|
+
throw new Error(
|
|
24702
|
+
`Frozen install failed: rulesync-gh.lock.yaml is missing entries for: ${uncovered.join(", ")}. Run 'rulesync install --mode gh' to update the lockfile.`
|
|
24703
|
+
);
|
|
24704
|
+
}
|
|
24705
|
+
const drifted = [];
|
|
24706
|
+
for (const rs of resolvedSources) {
|
|
24707
|
+
if (!rs.ref) continue;
|
|
24708
|
+
const matches = existingLock.installations.filter(
|
|
24709
|
+
(i) => i.source.toLowerCase() === rs.entry.source.toLowerCase()
|
|
24710
|
+
);
|
|
24711
|
+
for (const m of matches) {
|
|
24712
|
+
if (m.requested_ref !== void 0 && m.requested_ref !== rs.ref) {
|
|
24713
|
+
drifted.push(`${rs.entry.source} (manifest=${rs.ref}, lock=${m.requested_ref})`);
|
|
24714
|
+
break;
|
|
24715
|
+
}
|
|
24716
|
+
}
|
|
24717
|
+
}
|
|
24718
|
+
if (drifted.length > 0) {
|
|
24719
|
+
throw new Error(
|
|
24720
|
+
`Frozen install failed: manifest ref does not match rulesync-gh.lock.yaml for: ${drifted.join(", ")}. Run 'rulesync install --mode gh' to update the lockfile.`
|
|
24721
|
+
);
|
|
24722
|
+
}
|
|
24723
|
+
}
|
|
24724
|
+
const token = GitHubClient.resolveToken(options.token);
|
|
24725
|
+
const client = new GitHubClient({ token });
|
|
24726
|
+
const semaphore = new import_promise3.Semaphore(FETCH_CONCURRENCY_LIMIT);
|
|
24727
|
+
const newLock = createEmptyGhLock({ existingLock });
|
|
24728
|
+
const runOne = async (rs) => {
|
|
24729
|
+
const installations = await installSource({
|
|
24730
|
+
rs,
|
|
24731
|
+
client,
|
|
24732
|
+
semaphore,
|
|
24733
|
+
baseDir,
|
|
24734
|
+
existingLock,
|
|
24735
|
+
frozen,
|
|
24736
|
+
update,
|
|
24737
|
+
logger: logger5
|
|
24738
|
+
});
|
|
24739
|
+
return { status: "ok", installations };
|
|
24740
|
+
};
|
|
24741
|
+
const results = frozen ? await Promise.all(resolvedSources.map(runOne)) : await Promise.all(
|
|
24742
|
+
resolvedSources.map(async (rs) => {
|
|
24743
|
+
try {
|
|
24744
|
+
return await runOne(rs);
|
|
24745
|
+
} catch (error) {
|
|
24746
|
+
logger5.error(`Failed to install gh source "${rs.entry.source}": ${formatError(error)}`);
|
|
24747
|
+
if (error instanceof GitHubClientError) {
|
|
24748
|
+
logGitHubAuthHints({ error, logger: logger5 });
|
|
24749
|
+
}
|
|
24750
|
+
const preserved = existingLock ? existingLock.installations.filter(
|
|
24751
|
+
(i) => i.source.toLowerCase() === rs.entry.source.toLowerCase()
|
|
24752
|
+
) : [];
|
|
24753
|
+
return { status: "failed", preserved };
|
|
24754
|
+
}
|
|
24755
|
+
})
|
|
24756
|
+
);
|
|
24757
|
+
if (frozen) {
|
|
24758
|
+
for (const result of results) {
|
|
24759
|
+
if (result.status !== "ok") continue;
|
|
24760
|
+
for (const inst of result.installations) {
|
|
24761
|
+
for (const d of inst.deployed) {
|
|
24762
|
+
await writeFileContent(d.absolutePath, d.content);
|
|
24763
|
+
}
|
|
24764
|
+
}
|
|
24765
|
+
}
|
|
24766
|
+
}
|
|
24767
|
+
let totalInstalled = 0;
|
|
24768
|
+
let failedCount = 0;
|
|
24769
|
+
for (const result of results) {
|
|
24770
|
+
if (result.status === "ok") {
|
|
24771
|
+
for (const inst of result.installations) {
|
|
24772
|
+
newLock.installations.push(inst.installation);
|
|
24773
|
+
}
|
|
24774
|
+
totalInstalled += result.installations.length;
|
|
24775
|
+
} else {
|
|
24776
|
+
failedCount += 1;
|
|
24777
|
+
for (const preserved of result.preserved) {
|
|
24778
|
+
newLock.installations.push(preserved);
|
|
24779
|
+
}
|
|
24780
|
+
}
|
|
24781
|
+
}
|
|
24782
|
+
if (existingLock) {
|
|
24783
|
+
const newDeployed = /* @__PURE__ */ new Set();
|
|
24784
|
+
for (const inst of newLock.installations) {
|
|
24785
|
+
for (const file of inst.deployed_files) {
|
|
24786
|
+
newDeployed.add(`${inst.scope}::${file}`);
|
|
24787
|
+
}
|
|
24788
|
+
}
|
|
24789
|
+
for (const prev of existingLock.installations) {
|
|
24790
|
+
for (const deployed of prev.deployed_files) {
|
|
24791
|
+
const key = `${prev.scope}::${deployed}`;
|
|
24792
|
+
if (newDeployed.has(key)) continue;
|
|
24793
|
+
await removeStaleFile({
|
|
24794
|
+
relativePath: deployed,
|
|
24795
|
+
scope: prev.scope === "user" ? "user" : "project",
|
|
24796
|
+
baseDir,
|
|
24797
|
+
logger: logger5
|
|
24798
|
+
});
|
|
24799
|
+
}
|
|
24800
|
+
}
|
|
24801
|
+
}
|
|
24802
|
+
if (!frozen) {
|
|
24803
|
+
newLock.generated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
24804
|
+
await writeGhLock({ baseDir, lock: newLock });
|
|
24805
|
+
if (failedCount === 0) {
|
|
24806
|
+
logger5.debug("rulesync-gh.lock.yaml updated.");
|
|
24807
|
+
} else {
|
|
24808
|
+
logger5.warn(
|
|
24809
|
+
`rulesync-gh.lock.yaml written with partially successful installs (${failedCount} source(s) failed).`
|
|
24810
|
+
);
|
|
24811
|
+
}
|
|
24812
|
+
}
|
|
24813
|
+
return {
|
|
24814
|
+
sourcesProcessed: sources.length,
|
|
24815
|
+
installedSkillCount: totalInstalled,
|
|
24816
|
+
failedSourceCount: failedCount
|
|
24817
|
+
};
|
|
24818
|
+
}
|
|
24819
|
+
async function installSource(params) {
|
|
24820
|
+
const { rs, client, semaphore, baseDir, existingLock, frozen, update, logger: logger5 } = params;
|
|
24821
|
+
const { entry, owner, repo, agent, scope } = rs;
|
|
24822
|
+
const sourceKey = entry.source;
|
|
24823
|
+
let resolvedRef;
|
|
24824
|
+
let usedTag = false;
|
|
24825
|
+
if (rs.ref) {
|
|
24826
|
+
resolvedRef = rs.ref;
|
|
24827
|
+
} else {
|
|
24828
|
+
try {
|
|
24829
|
+
const release = await client.getLatestRelease(owner, repo);
|
|
24830
|
+
resolvedRef = release.tag_name;
|
|
24831
|
+
usedTag = true;
|
|
24832
|
+
} catch (error) {
|
|
24833
|
+
if (is404(error)) {
|
|
24834
|
+
resolvedRef = await client.getDefaultBranch(owner, repo);
|
|
24835
|
+
} else {
|
|
24836
|
+
throw error;
|
|
24837
|
+
}
|
|
24838
|
+
}
|
|
24839
|
+
}
|
|
24840
|
+
const resolvedSha = await client.resolveRefToSha(owner, repo, resolvedRef);
|
|
24841
|
+
logger5.debug(`Resolved ${sourceKey} -> ref=${resolvedRef} sha=${resolvedSha}`);
|
|
24842
|
+
let topLevel;
|
|
24843
|
+
try {
|
|
24844
|
+
topLevel = await client.listDirectory(owner, repo, SKILLS_REMOTE_DIR, resolvedSha);
|
|
24845
|
+
} catch (error) {
|
|
24846
|
+
if (is404(error)) {
|
|
24847
|
+
logger5.warn(`No skills/ directory found in ${sourceKey}. Skipping.`);
|
|
24848
|
+
return [];
|
|
24849
|
+
}
|
|
24850
|
+
throw error;
|
|
24851
|
+
}
|
|
24852
|
+
const skillDirs = topLevel.filter((e) => e.type === "dir").map((e) => ({ name: e.name, path: e.path }));
|
|
24853
|
+
const validatedSkills = [];
|
|
24854
|
+
for (const sk of skillDirs) {
|
|
24855
|
+
const info = await withSemaphore(
|
|
24856
|
+
semaphore,
|
|
24857
|
+
() => client.getFileInfo(owner, repo, import_node_path150.posix.join(sk.path, SKILL_FILE_NAME2), resolvedSha)
|
|
24858
|
+
);
|
|
24859
|
+
if (info) {
|
|
24860
|
+
validatedSkills.push(sk);
|
|
24861
|
+
}
|
|
24862
|
+
}
|
|
24863
|
+
let selected = validatedSkills;
|
|
24864
|
+
if (entry.skills && entry.skills.length > 0) {
|
|
24865
|
+
const requested = new Set(entry.skills);
|
|
24866
|
+
selected = validatedSkills.filter((s) => requested.has(s.name));
|
|
24867
|
+
const presentNames = new Set(validatedSkills.map((s) => s.name));
|
|
24868
|
+
for (const want of entry.skills) {
|
|
24869
|
+
if (!presentNames.has(want)) {
|
|
24870
|
+
logger5.warn(`Requested skill "${want}" not found in ${sourceKey} under skills/. Skipping.`);
|
|
24871
|
+
}
|
|
24872
|
+
}
|
|
24873
|
+
}
|
|
24874
|
+
if (frozen && existingLock) {
|
|
24875
|
+
const missing = [];
|
|
24876
|
+
for (const sk of selected) {
|
|
24877
|
+
const locked = findGhLockInstallation(existingLock, {
|
|
24878
|
+
source: sourceKey,
|
|
24879
|
+
agent,
|
|
24880
|
+
scope,
|
|
24881
|
+
skill: sk.name
|
|
24882
|
+
});
|
|
24883
|
+
if (!locked) {
|
|
24884
|
+
missing.push(sk.name);
|
|
24885
|
+
}
|
|
24886
|
+
}
|
|
24887
|
+
if (missing.length > 0) {
|
|
24888
|
+
throw new Error(
|
|
24889
|
+
`Frozen install failed: rulesync-gh.lock.yaml is missing entries for ${sourceKey} (agent=${agent}, scope=${scope}) skills: ${missing.join(", ")}. Run 'rulesync install --mode gh' to update the lockfile.`
|
|
24890
|
+
);
|
|
24891
|
+
}
|
|
24892
|
+
}
|
|
24893
|
+
const results = [];
|
|
24894
|
+
const installRelDir = relativeInstallDirFor({ agent, scope });
|
|
24895
|
+
const scopeRoot = scope === "user" ? getHomeDirectory() : baseDir;
|
|
24896
|
+
const sourceUrl = `https://github.com/${owner}/${repo}`;
|
|
24897
|
+
const repository = `${owner}/${repo}`;
|
|
24898
|
+
const provenanceRef = usedTag ? resolvedRef : resolvedSha;
|
|
24899
|
+
for (const sk of selected) {
|
|
24900
|
+
const locked = existingLock && !update ? findGhLockInstallation(existingLock, {
|
|
24901
|
+
source: sourceKey,
|
|
24902
|
+
agent,
|
|
24903
|
+
scope,
|
|
24904
|
+
skill: sk.name
|
|
24905
|
+
}) : void 0;
|
|
24906
|
+
const allFiles = await listDirectoryRecursive({
|
|
24907
|
+
client,
|
|
24908
|
+
owner,
|
|
24909
|
+
repo,
|
|
24910
|
+
path: sk.path,
|
|
24911
|
+
ref: resolvedSha,
|
|
24912
|
+
semaphore
|
|
24913
|
+
});
|
|
24914
|
+
const deployed = [];
|
|
24915
|
+
for (const file of allFiles) {
|
|
24916
|
+
if (file.size > MAX_FILE_SIZE) {
|
|
24917
|
+
logger5.warn(
|
|
24918
|
+
`Skipping "${file.path}" from ${sourceKey}: ${(file.size / 1024 / 1024).toFixed(2)}MB exceeds ${MAX_FILE_SIZE / 1024 / 1024}MB limit.`
|
|
24919
|
+
);
|
|
24920
|
+
continue;
|
|
24921
|
+
}
|
|
24922
|
+
const relativeToSkill = import_node_path150.posix.relative(sk.path, toPosixPath(file.path));
|
|
24923
|
+
if (!relativeToSkill || relativeToSkill.startsWith("..") || import_node_path150.posix.isAbsolute(relativeToSkill)) {
|
|
24924
|
+
logger5.warn(`Skipping "${file.path}" from ${sourceKey}: resolved outside of "${sk.path}".`);
|
|
24925
|
+
continue;
|
|
24926
|
+
}
|
|
24927
|
+
const deployRelative = toPosixPath((0, import_node_path150.join)(installRelDir, sk.name, relativeToSkill));
|
|
24928
|
+
checkPathTraversal({ relativePath: deployRelative, intendedRootDir: scopeRoot });
|
|
24929
|
+
const installAbs = (0, import_node_path150.join)(scopeRoot, installRelDir);
|
|
24930
|
+
const withinInstallDir = toPosixPath((0, import_node_path150.join)(sk.name, relativeToSkill));
|
|
24931
|
+
checkPathTraversal({ relativePath: withinInstallDir, intendedRootDir: installAbs });
|
|
24932
|
+
let content = await withSemaphore(
|
|
24933
|
+
semaphore,
|
|
24934
|
+
() => client.getFileContent(owner, repo, file.path, resolvedSha)
|
|
24935
|
+
);
|
|
24936
|
+
const byteLength = Buffer.byteLength(content, "utf8");
|
|
24937
|
+
if (byteLength > MAX_FILE_SIZE) {
|
|
24938
|
+
logger5.warn(
|
|
24939
|
+
`Skipping "${file.path}" from ${sourceKey}: fetched ${(byteLength / 1024 / 1024).toFixed(2)}MB exceeds ${MAX_FILE_SIZE / 1024 / 1024}MB limit.`
|
|
24940
|
+
);
|
|
24941
|
+
continue;
|
|
24942
|
+
}
|
|
24943
|
+
if ((0, import_node_path150.basename)(file.path) === SKILL_FILE_NAME2) {
|
|
24944
|
+
try {
|
|
24945
|
+
content = injectSourceMetadata({
|
|
24946
|
+
content,
|
|
24947
|
+
source: sourceUrl,
|
|
24948
|
+
repository,
|
|
24949
|
+
ref: provenanceRef
|
|
24950
|
+
});
|
|
24951
|
+
} catch {
|
|
24952
|
+
logger5.warn(
|
|
24953
|
+
`Frontmatter in ${file.path} (${sourceKey}) is invalid. Prepending a fresh provenance block.`
|
|
24954
|
+
);
|
|
24955
|
+
content = `---
|
|
24956
|
+
source: ${sourceUrl}
|
|
24957
|
+
repository: ${repository}
|
|
24958
|
+
ref: ${provenanceRef}
|
|
24959
|
+
---
|
|
24960
|
+
${content}`;
|
|
24961
|
+
}
|
|
24962
|
+
}
|
|
24963
|
+
const absolutePath = (0, import_node_path150.join)(scopeRoot, deployRelative);
|
|
24964
|
+
deployed.push({ relativeToScopeRoot: deployRelative, absolutePath, content });
|
|
24965
|
+
if (!frozen) {
|
|
24966
|
+
await writeFileContent(absolutePath, content);
|
|
24967
|
+
}
|
|
24968
|
+
}
|
|
24969
|
+
deployed.sort(
|
|
24970
|
+
(a, b) => a.relativeToScopeRoot < b.relativeToScopeRoot ? -1 : a.relativeToScopeRoot > b.relativeToScopeRoot ? 1 : 0
|
|
24971
|
+
);
|
|
24972
|
+
const deployedFiles = deployed.map((d) => d.relativeToScopeRoot);
|
|
24973
|
+
const contentHash = computeContentHash2(deployed);
|
|
24974
|
+
if (frozen && locked?.content_hash) {
|
|
24975
|
+
if (RULESYNC_CONTENT_HASH_REGEX2.test(locked.content_hash)) {
|
|
24976
|
+
if (locked.content_hash !== contentHash) {
|
|
24977
|
+
throw new Error(
|
|
24978
|
+
`content_hash mismatch for ${sourceKey} skill "${sk.name}" (agent=${agent}, scope=${scope}): lock=${locked.content_hash} computed=${contentHash}. Refuse to trust the deployment under --frozen.`
|
|
24979
|
+
);
|
|
24980
|
+
}
|
|
24981
|
+
} else {
|
|
24982
|
+
logger5.debug(
|
|
24983
|
+
`Skipping content_hash integrity check for ${sourceKey} skill "${sk.name}": recorded hash "${locked.content_hash}" was not written by rulesync.`
|
|
24984
|
+
);
|
|
24985
|
+
}
|
|
24986
|
+
}
|
|
24987
|
+
const installation = {
|
|
24988
|
+
source: sourceKey,
|
|
24989
|
+
owner,
|
|
24990
|
+
repo,
|
|
24991
|
+
agent,
|
|
24992
|
+
scope,
|
|
24993
|
+
skill: sk.name,
|
|
24994
|
+
resolved_ref: resolvedRef,
|
|
24995
|
+
resolved_commit: resolvedSha,
|
|
24996
|
+
install_dir: toPosixPath(installRelDir),
|
|
24997
|
+
deployed_files: deployedFiles,
|
|
24998
|
+
content_hash: contentHash
|
|
24999
|
+
};
|
|
25000
|
+
if (rs.ref !== void 0) {
|
|
25001
|
+
installation.requested_ref = rs.ref;
|
|
25002
|
+
}
|
|
25003
|
+
results.push({ installation, deployed });
|
|
25004
|
+
logger5.info(
|
|
25005
|
+
`Installed gh skill "${sk.name}" from ${sourceKey} (agent=${agent}, scope=${scope}, ref=${resolvedRef})`
|
|
25006
|
+
);
|
|
25007
|
+
}
|
|
25008
|
+
return results;
|
|
25009
|
+
}
|
|
25010
|
+
async function removeStaleFile(params) {
|
|
25011
|
+
const { relativePath, scope, baseDir, logger: logger5 } = params;
|
|
25012
|
+
if (import_node_path150.posix.isAbsolute(relativePath) || relativePath.split(/[/\\]/).includes("..")) {
|
|
25013
|
+
logger5.warn(`Refusing to remove stale gh file with suspicious path: "${relativePath}".`);
|
|
25014
|
+
return;
|
|
25015
|
+
}
|
|
25016
|
+
const scopeRoot = scope === "user" ? getHomeDirectory() : baseDir;
|
|
25017
|
+
try {
|
|
25018
|
+
checkPathTraversal({ relativePath, intendedRootDir: scopeRoot });
|
|
25019
|
+
} catch {
|
|
25020
|
+
logger5.warn(`Refusing to remove stale gh file outside ${scope} root: "${relativePath}".`);
|
|
25021
|
+
return;
|
|
25022
|
+
}
|
|
25023
|
+
const absolute = (0, import_node_path150.join)(scopeRoot, relativePath);
|
|
25024
|
+
await removeFile(absolute);
|
|
25025
|
+
logger5.debug(`Removed stale gh file: ${relativePath}`);
|
|
25026
|
+
}
|
|
25027
|
+
function is404(error) {
|
|
25028
|
+
if (error instanceof GitHubClientError && error.statusCode === 404) {
|
|
25029
|
+
return true;
|
|
25030
|
+
}
|
|
25031
|
+
if (typeof error === "object" && error !== null && "statusCode" in error && error.statusCode === 404) {
|
|
25032
|
+
return true;
|
|
25033
|
+
}
|
|
25034
|
+
return false;
|
|
25035
|
+
}
|
|
25036
|
+
function computeContentHash2(files) {
|
|
25037
|
+
const hash = (0, import_node_crypto2.createHash)("sha256");
|
|
25038
|
+
for (const { relativeToScopeRoot, content } of files) {
|
|
25039
|
+
hash.update(relativeToScopeRoot);
|
|
25040
|
+
hash.update("\0");
|
|
25041
|
+
hash.update(content);
|
|
25042
|
+
hash.update("\0");
|
|
25043
|
+
}
|
|
25044
|
+
return `sha256:${hash.digest("hex")}`;
|
|
25045
|
+
}
|
|
25046
|
+
|
|
25047
|
+
// src/lib/sources.ts
|
|
25048
|
+
var import_node_path153 = require("path");
|
|
25049
|
+
var import_promise4 = require("es-toolkit/promise");
|
|
25050
|
+
|
|
25051
|
+
// src/lib/git-client.ts
|
|
25052
|
+
var import_node_child_process = require("child_process");
|
|
25053
|
+
var import_node_path151 = require("path");
|
|
25054
|
+
var import_node_util2 = require("util");
|
|
25055
|
+
var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process.execFile);
|
|
25056
|
+
var GIT_TIMEOUT_MS = 6e4;
|
|
25057
|
+
var ALLOWED_URL_SCHEMES = /^(https?:\/\/|ssh:\/\/|git:\/\/|file:\/\/\/).+$|^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9.-]+:[a-zA-Z0-9_.+/~-]+$/;
|
|
25058
|
+
var INSECURE_URL_SCHEMES = /^(git:\/\/|http:\/\/)/;
|
|
25059
|
+
var GitClientError = class extends Error {
|
|
25060
|
+
constructor(message, cause) {
|
|
25061
|
+
super(message, { cause });
|
|
25062
|
+
this.name = "GitClientError";
|
|
25063
|
+
}
|
|
25064
|
+
};
|
|
25065
|
+
function validateGitUrl(url, options) {
|
|
25066
|
+
const ctrl = findControlCharacter(url);
|
|
25067
|
+
if (ctrl) {
|
|
25068
|
+
throw new GitClientError(
|
|
25069
|
+
`Git URL contains control character ${ctrl.hex} at position ${ctrl.position}`
|
|
25070
|
+
);
|
|
25071
|
+
}
|
|
25072
|
+
if (!ALLOWED_URL_SCHEMES.test(url)) {
|
|
25073
|
+
throw new GitClientError(
|
|
25074
|
+
`Unsupported or unsafe git URL: "${url}". Use https, ssh, git, or file schemes.`
|
|
25075
|
+
);
|
|
25076
|
+
}
|
|
25077
|
+
if (INSECURE_URL_SCHEMES.test(url)) {
|
|
25078
|
+
options?.logger?.warn(
|
|
25079
|
+
`URL "${url}" uses an unencrypted protocol. Consider using https:// or ssh:// instead.`
|
|
25080
|
+
);
|
|
25081
|
+
}
|
|
25082
|
+
}
|
|
25083
|
+
function validateRef(ref) {
|
|
25084
|
+
if (ref.startsWith("-")) {
|
|
25085
|
+
throw new GitClientError(`Ref must not start with "-": "${ref}"`);
|
|
25086
|
+
}
|
|
25087
|
+
const ctrl = findControlCharacter(ref);
|
|
25088
|
+
if (ctrl) {
|
|
25089
|
+
throw new GitClientError(
|
|
25090
|
+
`Ref contains control character ${ctrl.hex} at position ${ctrl.position}`
|
|
25091
|
+
);
|
|
25092
|
+
}
|
|
25093
|
+
}
|
|
25094
|
+
var gitChecked = false;
|
|
25095
|
+
async function checkGitAvailable() {
|
|
25096
|
+
if (gitChecked) return;
|
|
25097
|
+
try {
|
|
25098
|
+
await execFileAsync("git", ["--version"], { timeout: GIT_TIMEOUT_MS });
|
|
25099
|
+
gitChecked = true;
|
|
25100
|
+
} catch {
|
|
25101
|
+
throw new GitClientError("git is not installed or not found in PATH");
|
|
25102
|
+
}
|
|
25103
|
+
}
|
|
25104
|
+
async function resolveDefaultRef(url) {
|
|
25105
|
+
validateGitUrl(url);
|
|
25106
|
+
await checkGitAvailable();
|
|
25107
|
+
try {
|
|
25108
|
+
const { stdout } = await execFileAsync("git", ["ls-remote", "--symref", "--", url, "HEAD"], {
|
|
25109
|
+
timeout: GIT_TIMEOUT_MS
|
|
25110
|
+
});
|
|
25111
|
+
const ref = stdout.match(/^ref: refs\/heads\/(.+)\tHEAD$/m)?.[1];
|
|
25112
|
+
const sha = stdout.match(/^([0-9a-f]{40})\tHEAD$/m)?.[1];
|
|
25113
|
+
if (!ref || !sha) throw new GitClientError(`Could not parse default branch from: ${url}`);
|
|
25114
|
+
validateRef(ref);
|
|
25115
|
+
return { ref, sha };
|
|
25116
|
+
} catch (error) {
|
|
25117
|
+
if (error instanceof GitClientError) throw error;
|
|
25118
|
+
throw new GitClientError(`Failed to resolve default ref for ${url}`, error);
|
|
25119
|
+
}
|
|
25120
|
+
}
|
|
25121
|
+
async function resolveRefToSha(url, ref) {
|
|
25122
|
+
validateGitUrl(url);
|
|
25123
|
+
validateRef(ref);
|
|
25124
|
+
await checkGitAvailable();
|
|
25125
|
+
try {
|
|
25126
|
+
const { stdout } = await execFileAsync("git", ["ls-remote", "--", url, ref], {
|
|
25127
|
+
timeout: GIT_TIMEOUT_MS
|
|
25128
|
+
});
|
|
25129
|
+
const sha = stdout.match(/^([0-9a-f]{40})\t/m)?.[1];
|
|
25130
|
+
if (!sha) throw new GitClientError(`Ref "${ref}" not found in ${url}`);
|
|
25131
|
+
return sha;
|
|
25132
|
+
} catch (error) {
|
|
25133
|
+
if (error instanceof GitClientError) throw error;
|
|
25134
|
+
throw new GitClientError(`Failed to resolve ref "${ref}" for ${url}`, error);
|
|
25135
|
+
}
|
|
25136
|
+
}
|
|
25137
|
+
async function fetchSkillFiles(params) {
|
|
25138
|
+
const { url, ref, skillsPath, logger: logger5 } = params;
|
|
25139
|
+
validateGitUrl(url, { logger: logger5 });
|
|
25140
|
+
validateRef(ref);
|
|
25141
|
+
if (skillsPath.split(/[/\\]/).includes("..") || (0, import_node_path151.isAbsolute)(skillsPath)) {
|
|
25142
|
+
throw new GitClientError(
|
|
25143
|
+
`Invalid skillsPath "${skillsPath}": must be a relative path without ".."`
|
|
25144
|
+
);
|
|
25145
|
+
}
|
|
25146
|
+
const ctrl = findControlCharacter(skillsPath);
|
|
25147
|
+
if (ctrl) {
|
|
25148
|
+
throw new GitClientError(
|
|
25149
|
+
`skillsPath contains control character ${ctrl.hex} at position ${ctrl.position}`
|
|
25150
|
+
);
|
|
25151
|
+
}
|
|
25152
|
+
await checkGitAvailable();
|
|
25153
|
+
const tmpDir = await createTempDirectory("rulesync-git-");
|
|
25154
|
+
try {
|
|
25155
|
+
await execFileAsync(
|
|
25156
|
+
"git",
|
|
25157
|
+
[
|
|
25158
|
+
"clone",
|
|
25159
|
+
"--depth",
|
|
25160
|
+
"1",
|
|
25161
|
+
"--branch",
|
|
25162
|
+
ref,
|
|
25163
|
+
"--no-checkout",
|
|
25164
|
+
"--filter=blob:none",
|
|
25165
|
+
"--",
|
|
25166
|
+
url,
|
|
25167
|
+
tmpDir
|
|
25168
|
+
],
|
|
25169
|
+
{ timeout: GIT_TIMEOUT_MS }
|
|
25170
|
+
);
|
|
25171
|
+
await execFileAsync("git", ["-C", tmpDir, "sparse-checkout", "set", "--", skillsPath], {
|
|
25172
|
+
timeout: GIT_TIMEOUT_MS
|
|
25173
|
+
});
|
|
25174
|
+
await execFileAsync("git", ["-C", tmpDir, "checkout"], { timeout: GIT_TIMEOUT_MS });
|
|
25175
|
+
const skillsDir = (0, import_node_path151.join)(tmpDir, skillsPath);
|
|
25176
|
+
if (!await directoryExists(skillsDir)) return [];
|
|
25177
|
+
return await walkDirectory(skillsDir, skillsDir, 0, { totalFiles: 0, totalSize: 0 }, logger5);
|
|
25178
|
+
} catch (error) {
|
|
25179
|
+
if (error instanceof GitClientError) throw error;
|
|
25180
|
+
throw new GitClientError(`Failed to fetch skill files from ${url}`, error);
|
|
25181
|
+
} finally {
|
|
25182
|
+
await removeTempDirectory(tmpDir);
|
|
25183
|
+
}
|
|
25184
|
+
}
|
|
25185
|
+
var MAX_WALK_DEPTH = 20;
|
|
25186
|
+
var MAX_TOTAL_FILES = 1e4;
|
|
25187
|
+
var MAX_TOTAL_SIZE = 100 * 1024 * 1024;
|
|
25188
|
+
async function walkDirectory(dir, baseDir, depth = 0, ctx = { totalFiles: 0, totalSize: 0 }, logger5) {
|
|
25189
|
+
if (depth > MAX_WALK_DEPTH) {
|
|
25190
|
+
throw new GitClientError(
|
|
25191
|
+
`Directory tree exceeds max depth of ${MAX_WALK_DEPTH}: "${dir}". Aborting to prevent resource exhaustion.`
|
|
24041
25192
|
);
|
|
24042
25193
|
}
|
|
24043
25194
|
const results = [];
|
|
24044
25195
|
for (const name of await listDirectoryFiles(dir)) {
|
|
24045
25196
|
if (name === ".git") continue;
|
|
24046
|
-
const fullPath = (0,
|
|
25197
|
+
const fullPath = (0, import_node_path151.join)(dir, name);
|
|
24047
25198
|
if (await isSymlink(fullPath)) {
|
|
24048
25199
|
logger5?.warn(`Skipping symlink "${fullPath}".`);
|
|
24049
25200
|
continue;
|
|
@@ -24071,36 +25222,36 @@ async function walkDirectory(dir, baseDir, depth = 0, ctx = { totalFiles: 0, tot
|
|
|
24071
25222
|
);
|
|
24072
25223
|
}
|
|
24073
25224
|
const content = await readFileContent(fullPath);
|
|
24074
|
-
results.push({ relativePath: (0,
|
|
25225
|
+
results.push({ relativePath: (0, import_node_path151.relative)(baseDir, fullPath), content, size });
|
|
24075
25226
|
}
|
|
24076
25227
|
}
|
|
24077
25228
|
return results;
|
|
24078
25229
|
}
|
|
24079
25230
|
|
|
24080
25231
|
// src/lib/sources-lock.ts
|
|
24081
|
-
var
|
|
24082
|
-
var
|
|
24083
|
-
var
|
|
25232
|
+
var import_node_crypto3 = require("crypto");
|
|
25233
|
+
var import_node_path152 = require("path");
|
|
25234
|
+
var import_mini78 = require("zod/mini");
|
|
24084
25235
|
var LOCKFILE_VERSION = 1;
|
|
24085
|
-
var LockedSkillSchema =
|
|
24086
|
-
integrity:
|
|
25236
|
+
var LockedSkillSchema = import_mini78.z.object({
|
|
25237
|
+
integrity: import_mini78.z.string()
|
|
24087
25238
|
});
|
|
24088
|
-
var LockedSourceSchema =
|
|
24089
|
-
requestedRef: (0,
|
|
24090
|
-
resolvedRef:
|
|
24091
|
-
resolvedAt: (0,
|
|
24092
|
-
skills:
|
|
25239
|
+
var LockedSourceSchema = import_mini78.z.object({
|
|
25240
|
+
requestedRef: (0, import_mini78.optional)(import_mini78.z.string()),
|
|
25241
|
+
resolvedRef: import_mini78.z.string().check((0, import_mini78.refine)((v) => /^[0-9a-f]{40}$/.test(v), "resolvedRef must be a 40-character hex SHA")),
|
|
25242
|
+
resolvedAt: (0, import_mini78.optional)(import_mini78.z.string()),
|
|
25243
|
+
skills: import_mini78.z.record(import_mini78.z.string(), LockedSkillSchema)
|
|
24093
25244
|
});
|
|
24094
|
-
var SourcesLockSchema =
|
|
24095
|
-
lockfileVersion:
|
|
24096
|
-
sources:
|
|
25245
|
+
var SourcesLockSchema = import_mini78.z.object({
|
|
25246
|
+
lockfileVersion: import_mini78.z.number(),
|
|
25247
|
+
sources: import_mini78.z.record(import_mini78.z.string(), LockedSourceSchema)
|
|
24097
25248
|
});
|
|
24098
|
-
var LegacyLockedSourceSchema =
|
|
24099
|
-
resolvedRef:
|
|
24100
|
-
skills:
|
|
25249
|
+
var LegacyLockedSourceSchema = import_mini78.z.object({
|
|
25250
|
+
resolvedRef: import_mini78.z.string(),
|
|
25251
|
+
skills: import_mini78.z.array(import_mini78.z.string())
|
|
24101
25252
|
});
|
|
24102
|
-
var LegacySourcesLockSchema =
|
|
24103
|
-
sources:
|
|
25253
|
+
var LegacySourcesLockSchema = import_mini78.z.object({
|
|
25254
|
+
sources: import_mini78.z.record(import_mini78.z.string(), LegacyLockedSourceSchema)
|
|
24104
25255
|
});
|
|
24105
25256
|
function migrateLegacyLock(params) {
|
|
24106
25257
|
const { legacy, logger: logger5 } = params;
|
|
@@ -24125,7 +25276,7 @@ function createEmptyLock() {
|
|
|
24125
25276
|
}
|
|
24126
25277
|
async function readLockFile(params) {
|
|
24127
25278
|
const { logger: logger5 } = params;
|
|
24128
|
-
const lockPath = (0,
|
|
25279
|
+
const lockPath = (0, import_node_path152.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
|
|
24129
25280
|
if (!await fileExists(lockPath)) {
|
|
24130
25281
|
logger5.debug("No sources lockfile found, starting fresh.");
|
|
24131
25282
|
return createEmptyLock();
|
|
@@ -24154,13 +25305,13 @@ async function readLockFile(params) {
|
|
|
24154
25305
|
}
|
|
24155
25306
|
async function writeLockFile(params) {
|
|
24156
25307
|
const { logger: logger5 } = params;
|
|
24157
|
-
const lockPath = (0,
|
|
25308
|
+
const lockPath = (0, import_node_path152.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
|
|
24158
25309
|
const content = JSON.stringify(params.lock, null, 2) + "\n";
|
|
24159
25310
|
await writeFileContent(lockPath, content);
|
|
24160
25311
|
logger5.debug(`Wrote sources lockfile to ${lockPath}`);
|
|
24161
25312
|
}
|
|
24162
25313
|
function computeSkillIntegrity(files) {
|
|
24163
|
-
const hash = (0,
|
|
25314
|
+
const hash = (0, import_node_crypto3.createHash)("sha256");
|
|
24164
25315
|
const sorted = files.toSorted((a, b) => a.path.localeCompare(b.path));
|
|
24165
25316
|
for (const file of sorted) {
|
|
24166
25317
|
hash.update(file.path);
|
|
@@ -24328,7 +25479,7 @@ function logGitClientHints(params) {
|
|
|
24328
25479
|
async function checkLockedSkillsExist(curatedDir, skillNames) {
|
|
24329
25480
|
if (skillNames.length === 0) return true;
|
|
24330
25481
|
for (const name of skillNames) {
|
|
24331
|
-
if (!await directoryExists((0,
|
|
25482
|
+
if (!await directoryExists((0, import_node_path153.join)(curatedDir, name))) {
|
|
24332
25483
|
return false;
|
|
24333
25484
|
}
|
|
24334
25485
|
}
|
|
@@ -24336,10 +25487,10 @@ async function checkLockedSkillsExist(curatedDir, skillNames) {
|
|
|
24336
25487
|
}
|
|
24337
25488
|
async function cleanPreviousCuratedSkills(params) {
|
|
24338
25489
|
const { curatedDir, lockedSkillNames, logger: logger5 } = params;
|
|
24339
|
-
const resolvedCuratedDir = (0,
|
|
25490
|
+
const resolvedCuratedDir = (0, import_node_path153.resolve)(curatedDir);
|
|
24340
25491
|
for (const prevSkill of lockedSkillNames) {
|
|
24341
|
-
const prevDir = (0,
|
|
24342
|
-
if (!(0,
|
|
25492
|
+
const prevDir = (0, import_node_path153.join)(curatedDir, prevSkill);
|
|
25493
|
+
if (!(0, import_node_path153.resolve)(prevDir).startsWith(resolvedCuratedDir + import_node_path153.sep)) {
|
|
24343
25494
|
logger5.warn(
|
|
24344
25495
|
`Skipping removal of "${prevSkill}": resolved path is outside the curated directory.`
|
|
24345
25496
|
);
|
|
@@ -24378,9 +25529,9 @@ async function writeSkillAndComputeIntegrity(params) {
|
|
|
24378
25529
|
for (const file of files) {
|
|
24379
25530
|
checkPathTraversal({
|
|
24380
25531
|
relativePath: file.relativePath,
|
|
24381
|
-
intendedRootDir: (0,
|
|
25532
|
+
intendedRootDir: (0, import_node_path153.join)(curatedDir, skillName)
|
|
24382
25533
|
});
|
|
24383
|
-
await writeFileContent((0,
|
|
25534
|
+
await writeFileContent((0, import_node_path153.join)(curatedDir, skillName, file.relativePath), file.content);
|
|
24384
25535
|
written.push({ path: file.relativePath, content: file.content });
|
|
24385
25536
|
}
|
|
24386
25537
|
const integrity = computeSkillIntegrity(written);
|
|
@@ -24424,6 +25575,40 @@ function buildLockUpdate(params) {
|
|
|
24424
25575
|
);
|
|
24425
25576
|
return { updatedLock, fetchedNames };
|
|
24426
25577
|
}
|
|
25578
|
+
function getFirstPathSeparatorIndex(path4) {
|
|
25579
|
+
const slashIndex = path4.indexOf("/");
|
|
25580
|
+
const backslashIndex = path4.indexOf("\\");
|
|
25581
|
+
if (slashIndex === -1) return backslashIndex;
|
|
25582
|
+
if (backslashIndex === -1) return slashIndex;
|
|
25583
|
+
return Math.min(slashIndex, backslashIndex);
|
|
25584
|
+
}
|
|
25585
|
+
function groupRemoteFilesBySkillRoot(params) {
|
|
25586
|
+
const { remoteFiles, skillFilter, isWildcard } = params;
|
|
25587
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
25588
|
+
const rootLevelFiles = [];
|
|
25589
|
+
for (const file of remoteFiles) {
|
|
25590
|
+
const separatorIndex = getFirstPathSeparatorIndex(file.relativePath);
|
|
25591
|
+
if (separatorIndex === -1) {
|
|
25592
|
+
rootLevelFiles.push(file);
|
|
25593
|
+
continue;
|
|
25594
|
+
}
|
|
25595
|
+
const skillName = file.relativePath.substring(0, separatorIndex);
|
|
25596
|
+
if (skillName.length === 0) {
|
|
25597
|
+
continue;
|
|
25598
|
+
}
|
|
25599
|
+
const innerPath = file.relativePath.substring(separatorIndex + 1);
|
|
25600
|
+
const groupedFiles = grouped.get(skillName) ?? [];
|
|
25601
|
+
groupedFiles.push({ relativePath: innerPath, content: file.content });
|
|
25602
|
+
grouped.set(skillName, groupedFiles);
|
|
25603
|
+
}
|
|
25604
|
+
if (grouped.size === 0 && !isWildcard && skillFilter.length === 1) {
|
|
25605
|
+
const [singleSkillName] = skillFilter;
|
|
25606
|
+
if (singleSkillName !== void 0 && rootLevelFiles.length > 0) {
|
|
25607
|
+
grouped.set(singleSkillName, rootLevelFiles);
|
|
25608
|
+
}
|
|
25609
|
+
}
|
|
25610
|
+
return grouped;
|
|
25611
|
+
}
|
|
24427
25612
|
async function fetchSource(params) {
|
|
24428
25613
|
const {
|
|
24429
25614
|
sourceEntry,
|
|
@@ -24457,7 +25642,7 @@ async function fetchSource(params) {
|
|
|
24457
25642
|
ref = resolvedSha;
|
|
24458
25643
|
logger5.debug(`Resolved ${sourceKey} ref "${requestedRef}" to SHA: ${resolvedSha}`);
|
|
24459
25644
|
}
|
|
24460
|
-
const curatedDir = (0,
|
|
25645
|
+
const curatedDir = (0, import_node_path153.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
|
|
24461
25646
|
if (locked && resolvedSha === locked.resolvedRef && !updateSources) {
|
|
24462
25647
|
const allExist = await checkLockedSkillsExist(curatedDir, lockedSkillNames);
|
|
24463
25648
|
if (allExist) {
|
|
@@ -24471,11 +25656,60 @@ async function fetchSource(params) {
|
|
|
24471
25656
|
}
|
|
24472
25657
|
const skillFilter = sourceEntry.skills ?? ["*"];
|
|
24473
25658
|
const isWildcard = skillFilter.length === 1 && skillFilter[0] === "*";
|
|
25659
|
+
const semaphore = new import_promise4.Semaphore(FETCH_CONCURRENCY_LIMIT);
|
|
25660
|
+
const fetchedSkills = {};
|
|
24474
25661
|
const skillsBasePath = parsed.path ?? "skills";
|
|
24475
25662
|
let remoteSkillDirs;
|
|
25663
|
+
let remoteSkillNames = [];
|
|
25664
|
+
let fallbackHandled = false;
|
|
24476
25665
|
try {
|
|
24477
25666
|
const entries = await client.listDirectory(parsed.owner, parsed.repo, skillsBasePath, ref);
|
|
24478
25667
|
remoteSkillDirs = entries.filter((e) => e.type === "dir").map((e) => ({ name: e.name, path: e.path }));
|
|
25668
|
+
if (remoteSkillDirs.length === 0 && !isWildcard && skillFilter.length === 1) {
|
|
25669
|
+
const rootFiles = entries.filter((entry) => entry.type === "file");
|
|
25670
|
+
const rootSkillFiles = [];
|
|
25671
|
+
for (const file of rootFiles) {
|
|
25672
|
+
if (file.size > MAX_FILE_SIZE) {
|
|
25673
|
+
logger5.warn(
|
|
25674
|
+
`Skipping file "${file.path}" (${(file.size / 1024 / 1024).toFixed(2)}MB exceeds ${MAX_FILE_SIZE / 1024 / 1024}MB limit).`
|
|
25675
|
+
);
|
|
25676
|
+
continue;
|
|
25677
|
+
}
|
|
25678
|
+
const content = await withSemaphore(
|
|
25679
|
+
semaphore,
|
|
25680
|
+
() => client.getFileContent(parsed.owner, parsed.repo, file.path, ref)
|
|
25681
|
+
);
|
|
25682
|
+
rootSkillFiles.push({ relativePath: file.name, content });
|
|
25683
|
+
}
|
|
25684
|
+
const groupedRootFiles = groupRemoteFilesBySkillRoot({
|
|
25685
|
+
remoteFiles: rootSkillFiles,
|
|
25686
|
+
skillFilter,
|
|
25687
|
+
isWildcard
|
|
25688
|
+
});
|
|
25689
|
+
const [fallbackSkillName] = groupedRootFiles.keys();
|
|
25690
|
+
if (fallbackSkillName !== void 0) {
|
|
25691
|
+
fallbackHandled = true;
|
|
25692
|
+
remoteSkillNames = [fallbackSkillName];
|
|
25693
|
+
if (!shouldSkipSkill({
|
|
25694
|
+
skillName: fallbackSkillName,
|
|
25695
|
+
sourceKey,
|
|
25696
|
+
localSkillNames,
|
|
25697
|
+
alreadyFetchedSkillNames,
|
|
25698
|
+
logger: logger5
|
|
25699
|
+
})) {
|
|
25700
|
+
fetchedSkills[fallbackSkillName] = await writeSkillAndComputeIntegrity({
|
|
25701
|
+
skillName: fallbackSkillName,
|
|
25702
|
+
files: groupedRootFiles.get(fallbackSkillName) ?? [],
|
|
25703
|
+
curatedDir,
|
|
25704
|
+
locked,
|
|
25705
|
+
resolvedSha,
|
|
25706
|
+
sourceKey,
|
|
25707
|
+
logger: logger5
|
|
25708
|
+
});
|
|
25709
|
+
logger5.debug(`Fetched skill "${fallbackSkillName}" from ${sourceKey}`);
|
|
25710
|
+
}
|
|
25711
|
+
}
|
|
25712
|
+
}
|
|
24479
25713
|
} catch (error) {
|
|
24480
25714
|
if (error instanceof GitHubClientError && error.statusCode === 404) {
|
|
24481
25715
|
logger5.warn(`No skills/ directory found in ${sourceKey}. Skipping.`);
|
|
@@ -24484,8 +25718,9 @@ async function fetchSource(params) {
|
|
|
24484
25718
|
throw error;
|
|
24485
25719
|
}
|
|
24486
25720
|
const filteredDirs = isWildcard ? remoteSkillDirs : remoteSkillDirs.filter((d) => skillFilter.includes(d.name));
|
|
24487
|
-
|
|
24488
|
-
|
|
25721
|
+
if (!fallbackHandled) {
|
|
25722
|
+
remoteSkillNames = filteredDirs.map((d) => d.name);
|
|
25723
|
+
}
|
|
24489
25724
|
if (locked) {
|
|
24490
25725
|
await cleanPreviousCuratedSkills({ curatedDir, lockedSkillNames, logger: logger5 });
|
|
24491
25726
|
}
|
|
@@ -24543,7 +25778,7 @@ async function fetchSource(params) {
|
|
|
24543
25778
|
locked,
|
|
24544
25779
|
requestedRef,
|
|
24545
25780
|
resolvedSha,
|
|
24546
|
-
remoteSkillNames
|
|
25781
|
+
remoteSkillNames,
|
|
24547
25782
|
logger: logger5
|
|
24548
25783
|
});
|
|
24549
25784
|
return {
|
|
@@ -24582,7 +25817,7 @@ async function fetchSourceViaGit(params) {
|
|
|
24582
25817
|
requestedRef = def.ref;
|
|
24583
25818
|
resolvedSha = def.sha;
|
|
24584
25819
|
}
|
|
24585
|
-
const curatedDir = (0,
|
|
25820
|
+
const curatedDir = (0, import_node_path153.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
|
|
24586
25821
|
if (locked && resolvedSha === locked.resolvedRef && !updateSources) {
|
|
24587
25822
|
if (await checkLockedSkillsExist(curatedDir, lockedSkillNames)) {
|
|
24588
25823
|
return { skillCount: 0, fetchedSkillNames: lockedSkillNames, updatedLock: lock };
|
|
@@ -24605,28 +25840,7 @@ async function fetchSourceViaGit(params) {
|
|
|
24605
25840
|
ref: requestedRef,
|
|
24606
25841
|
skillsPath: sourceEntry.path ?? "skills"
|
|
24607
25842
|
});
|
|
24608
|
-
const skillFileMap =
|
|
24609
|
-
for (const file of remoteFiles) {
|
|
24610
|
-
const idx = file.relativePath.indexOf("/");
|
|
24611
|
-
if (idx === -1) continue;
|
|
24612
|
-
const name = file.relativePath.substring(0, idx);
|
|
24613
|
-
const inner = file.relativePath.substring(idx + 1);
|
|
24614
|
-
const arr = skillFileMap.get(name) ?? [];
|
|
24615
|
-
arr.push({ relativePath: inner, content: file.content });
|
|
24616
|
-
skillFileMap.set(name, arr);
|
|
24617
|
-
}
|
|
24618
|
-
if (skillFileMap.size === 0 && !isWildcard && skillFilter.length === 1) {
|
|
24619
|
-
const [singleSkillName] = skillFilter;
|
|
24620
|
-
if (singleSkillName !== void 0) {
|
|
24621
|
-
const rootFiles = remoteFiles.filter((f) => f.relativePath.indexOf("/") === -1);
|
|
24622
|
-
if (rootFiles.length > 0) {
|
|
24623
|
-
skillFileMap.set(
|
|
24624
|
-
singleSkillName,
|
|
24625
|
-
rootFiles.map((f) => ({ relativePath: f.relativePath, content: f.content }))
|
|
24626
|
-
);
|
|
24627
|
-
}
|
|
24628
|
-
}
|
|
24629
|
-
}
|
|
25843
|
+
const skillFileMap = groupRemoteFilesBySkillRoot({ remoteFiles, skillFilter, isWildcard });
|
|
24630
25844
|
const allNames = [...skillFileMap.keys()];
|
|
24631
25845
|
const filteredNames = isWildcard ? allNames : allNames.filter((n) => skillFilter.includes(n));
|
|
24632
25846
|
if (locked) {
|
|
@@ -24671,21 +25885,47 @@ async function fetchSourceViaGit(params) {
|
|
|
24671
25885
|
}
|
|
24672
25886
|
|
|
24673
25887
|
// src/cli/commands/install.ts
|
|
25888
|
+
var INSTALL_MODES = ["rulesync", "apm", "gh"];
|
|
24674
25889
|
async function installCommand(logger5, options) {
|
|
25890
|
+
const mode = options.mode ?? "rulesync";
|
|
25891
|
+
if (mode === "gh") {
|
|
25892
|
+
await runGhInstall(logger5, options);
|
|
25893
|
+
return;
|
|
25894
|
+
}
|
|
25895
|
+
if (mode === "apm") {
|
|
25896
|
+
await runApmInstall(logger5, options);
|
|
25897
|
+
return;
|
|
25898
|
+
}
|
|
25899
|
+
await runRulesyncInstall(logger5, options);
|
|
25900
|
+
}
|
|
25901
|
+
async function runRulesyncInstall(logger5, options) {
|
|
25902
|
+
const baseDir = process.cwd();
|
|
25903
|
+
const apmExists = await apmManifestExists(baseDir);
|
|
24675
25904
|
const config = await ConfigResolver.resolve({
|
|
24676
25905
|
configPath: options.configPath,
|
|
24677
25906
|
verbose: options.verbose,
|
|
24678
25907
|
silent: options.silent
|
|
24679
25908
|
});
|
|
24680
25909
|
const sources = config.getSources();
|
|
25910
|
+
if (apmExists && sources.length > 0) {
|
|
25911
|
+
throw new Error(
|
|
25912
|
+
"Both apm.yml and rulesync.jsonc `sources` are defined. Pass --mode apm or --mode rulesync to disambiguate."
|
|
25913
|
+
);
|
|
25914
|
+
}
|
|
24681
25915
|
if (sources.length === 0) {
|
|
25916
|
+
if (apmExists) {
|
|
25917
|
+
logger5.warn(
|
|
25918
|
+
"No sources defined in rulesync.jsonc, but apm.yml is present. Did you mean --mode apm?"
|
|
25919
|
+
);
|
|
25920
|
+
return;
|
|
25921
|
+
}
|
|
24682
25922
|
logger5.warn("No sources defined in configuration. Nothing to install.");
|
|
24683
25923
|
return;
|
|
24684
25924
|
}
|
|
24685
25925
|
logger5.debug(`Installing skills from ${sources.length} source(s)...`);
|
|
24686
25926
|
const result = await resolveAndFetchSources({
|
|
24687
25927
|
sources,
|
|
24688
|
-
baseDir
|
|
25928
|
+
baseDir,
|
|
24689
25929
|
options: {
|
|
24690
25930
|
updateSources: options.update,
|
|
24691
25931
|
frozen: options.frozen,
|
|
@@ -24705,21 +25945,95 @@ async function installCommand(logger5, options) {
|
|
|
24705
25945
|
logger5.success(`All skills up to date (${result.sourcesProcessed} source(s) checked).`);
|
|
24706
25946
|
}
|
|
24707
25947
|
}
|
|
25948
|
+
async function runApmInstall(logger5, options) {
|
|
25949
|
+
const baseDir = process.cwd();
|
|
25950
|
+
if (!await apmManifestExists(baseDir)) {
|
|
25951
|
+
throw new Error(
|
|
25952
|
+
"--mode apm requires an apm.yml at the project root. Create one or drop --mode apm to fall back to rulesync mode."
|
|
25953
|
+
);
|
|
25954
|
+
}
|
|
25955
|
+
const result = await installApm({
|
|
25956
|
+
baseDir,
|
|
25957
|
+
options: {
|
|
25958
|
+
update: options.update,
|
|
25959
|
+
frozen: options.frozen,
|
|
25960
|
+
token: options.token
|
|
25961
|
+
},
|
|
25962
|
+
logger: logger5
|
|
25963
|
+
});
|
|
25964
|
+
if (logger5.jsonMode) {
|
|
25965
|
+
logger5.captureData("dependenciesProcessed", result.dependenciesProcessed);
|
|
25966
|
+
logger5.captureData("deployedFileCount", result.deployedFileCount);
|
|
25967
|
+
logger5.captureData("failedDependencyCount", result.failedDependencyCount);
|
|
25968
|
+
}
|
|
25969
|
+
if (result.failedDependencyCount > 0) {
|
|
25970
|
+
throw new Error(
|
|
25971
|
+
`Failed to install ${result.failedDependencyCount} of ${result.dependenciesProcessed} apm dependency(ies). See the log above for details.`
|
|
25972
|
+
);
|
|
25973
|
+
}
|
|
25974
|
+
if (result.deployedFileCount > 0) {
|
|
25975
|
+
logger5.success(
|
|
25976
|
+
`Installed ${result.deployedFileCount} file(s) from ${result.dependenciesProcessed} apm dependency(ies).`
|
|
25977
|
+
);
|
|
25978
|
+
} else {
|
|
25979
|
+
logger5.success(`All apm dependencies up to date (${result.dependenciesProcessed} checked).`);
|
|
25980
|
+
}
|
|
25981
|
+
}
|
|
25982
|
+
async function runGhInstall(logger5, options) {
|
|
25983
|
+
const baseDir = process.cwd();
|
|
25984
|
+
const config = await ConfigResolver.resolve({
|
|
25985
|
+
configPath: options.configPath,
|
|
25986
|
+
verbose: options.verbose,
|
|
25987
|
+
silent: options.silent
|
|
25988
|
+
});
|
|
25989
|
+
const sources = config.getSources();
|
|
25990
|
+
if (sources.length === 0) {
|
|
25991
|
+
logger5.warn("No sources defined in configuration. Nothing to install.");
|
|
25992
|
+
return;
|
|
25993
|
+
}
|
|
25994
|
+
const result = await installGh({
|
|
25995
|
+
baseDir,
|
|
25996
|
+
sources,
|
|
25997
|
+
options: {
|
|
25998
|
+
update: options.update,
|
|
25999
|
+
frozen: options.frozen,
|
|
26000
|
+
token: options.token
|
|
26001
|
+
},
|
|
26002
|
+
logger: logger5
|
|
26003
|
+
});
|
|
26004
|
+
if (logger5.jsonMode) {
|
|
26005
|
+
logger5.captureData("sourcesProcessed", result.sourcesProcessed);
|
|
26006
|
+
logger5.captureData("installedSkillCount", result.installedSkillCount);
|
|
26007
|
+
logger5.captureData("failedSourceCount", result.failedSourceCount);
|
|
26008
|
+
}
|
|
26009
|
+
if (result.failedSourceCount > 0) {
|
|
26010
|
+
throw new Error(
|
|
26011
|
+
`Failed to install ${result.failedSourceCount} of ${result.sourcesProcessed} gh source(s). See the log above for details.`
|
|
26012
|
+
);
|
|
26013
|
+
}
|
|
26014
|
+
if (result.installedSkillCount > 0) {
|
|
26015
|
+
logger5.success(
|
|
26016
|
+
`Installed ${result.installedSkillCount} skill(s) from ${result.sourcesProcessed} gh source(s).`
|
|
26017
|
+
);
|
|
26018
|
+
} else {
|
|
26019
|
+
logger5.success(`All gh sources up to date (${result.sourcesProcessed} checked).`);
|
|
26020
|
+
}
|
|
26021
|
+
}
|
|
24708
26022
|
|
|
24709
26023
|
// src/cli/commands/mcp.ts
|
|
24710
26024
|
var import_fastmcp = require("fastmcp");
|
|
24711
26025
|
|
|
24712
26026
|
// src/mcp/tools.ts
|
|
24713
|
-
var
|
|
26027
|
+
var import_mini89 = require("zod/mini");
|
|
24714
26028
|
|
|
24715
26029
|
// src/mcp/commands.ts
|
|
24716
|
-
var
|
|
24717
|
-
var
|
|
26030
|
+
var import_node_path154 = require("path");
|
|
26031
|
+
var import_mini79 = require("zod/mini");
|
|
24718
26032
|
var logger = new ConsoleLogger({ verbose: false, silent: true });
|
|
24719
26033
|
var maxCommandSizeBytes = 1024 * 1024;
|
|
24720
26034
|
var maxCommandsCount = 1e3;
|
|
24721
26035
|
async function listCommands() {
|
|
24722
|
-
const commandsDir = (0,
|
|
26036
|
+
const commandsDir = (0, import_node_path154.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
|
|
24723
26037
|
try {
|
|
24724
26038
|
const files = await listDirectoryFiles(commandsDir);
|
|
24725
26039
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -24735,7 +26049,7 @@ async function listCommands() {
|
|
|
24735
26049
|
});
|
|
24736
26050
|
const frontmatter = command.getFrontmatter();
|
|
24737
26051
|
return {
|
|
24738
|
-
relativePathFromCwd: (0,
|
|
26052
|
+
relativePathFromCwd: (0, import_node_path154.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
|
|
24739
26053
|
frontmatter
|
|
24740
26054
|
};
|
|
24741
26055
|
} catch (error) {
|
|
@@ -24757,13 +26071,13 @@ async function getCommand({ relativePathFromCwd }) {
|
|
|
24757
26071
|
relativePath: relativePathFromCwd,
|
|
24758
26072
|
intendedRootDir: process.cwd()
|
|
24759
26073
|
});
|
|
24760
|
-
const filename = (0,
|
|
26074
|
+
const filename = (0, import_node_path154.basename)(relativePathFromCwd);
|
|
24761
26075
|
try {
|
|
24762
26076
|
const command = await RulesyncCommand.fromFile({
|
|
24763
26077
|
relativeFilePath: filename
|
|
24764
26078
|
});
|
|
24765
26079
|
return {
|
|
24766
|
-
relativePathFromCwd: (0,
|
|
26080
|
+
relativePathFromCwd: (0, import_node_path154.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
|
|
24767
26081
|
frontmatter: command.getFrontmatter(),
|
|
24768
26082
|
body: command.getBody()
|
|
24769
26083
|
};
|
|
@@ -24782,7 +26096,7 @@ async function putCommand({
|
|
|
24782
26096
|
relativePath: relativePathFromCwd,
|
|
24783
26097
|
intendedRootDir: process.cwd()
|
|
24784
26098
|
});
|
|
24785
|
-
const filename = (0,
|
|
26099
|
+
const filename = (0, import_node_path154.basename)(relativePathFromCwd);
|
|
24786
26100
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
24787
26101
|
if (estimatedSize > maxCommandSizeBytes) {
|
|
24788
26102
|
throw new Error(
|
|
@@ -24792,7 +26106,7 @@ async function putCommand({
|
|
|
24792
26106
|
try {
|
|
24793
26107
|
const existingCommands = await listCommands();
|
|
24794
26108
|
const isUpdate = existingCommands.some(
|
|
24795
|
-
(command2) => command2.relativePathFromCwd === (0,
|
|
26109
|
+
(command2) => command2.relativePathFromCwd === (0, import_node_path154.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
|
|
24796
26110
|
);
|
|
24797
26111
|
if (!isUpdate && existingCommands.length >= maxCommandsCount) {
|
|
24798
26112
|
throw new Error(
|
|
@@ -24809,11 +26123,11 @@ async function putCommand({
|
|
|
24809
26123
|
fileContent,
|
|
24810
26124
|
validate: true
|
|
24811
26125
|
});
|
|
24812
|
-
const commandsDir = (0,
|
|
26126
|
+
const commandsDir = (0, import_node_path154.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
|
|
24813
26127
|
await ensureDir(commandsDir);
|
|
24814
26128
|
await writeFileContent(command.getFilePath(), command.getFileContent());
|
|
24815
26129
|
return {
|
|
24816
|
-
relativePathFromCwd: (0,
|
|
26130
|
+
relativePathFromCwd: (0, import_node_path154.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
|
|
24817
26131
|
frontmatter: command.getFrontmatter(),
|
|
24818
26132
|
body: command.getBody()
|
|
24819
26133
|
};
|
|
@@ -24828,12 +26142,12 @@ async function deleteCommand({ relativePathFromCwd }) {
|
|
|
24828
26142
|
relativePath: relativePathFromCwd,
|
|
24829
26143
|
intendedRootDir: process.cwd()
|
|
24830
26144
|
});
|
|
24831
|
-
const filename = (0,
|
|
24832
|
-
const fullPath = (0,
|
|
26145
|
+
const filename = (0, import_node_path154.basename)(relativePathFromCwd);
|
|
26146
|
+
const fullPath = (0, import_node_path154.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
|
|
24833
26147
|
try {
|
|
24834
26148
|
await removeFile(fullPath);
|
|
24835
26149
|
return {
|
|
24836
|
-
relativePathFromCwd: (0,
|
|
26150
|
+
relativePathFromCwd: (0, import_node_path154.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
|
|
24837
26151
|
};
|
|
24838
26152
|
} catch (error) {
|
|
24839
26153
|
throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
|
|
@@ -24842,23 +26156,23 @@ async function deleteCommand({ relativePathFromCwd }) {
|
|
|
24842
26156
|
}
|
|
24843
26157
|
}
|
|
24844
26158
|
var commandToolSchemas = {
|
|
24845
|
-
listCommands:
|
|
24846
|
-
getCommand:
|
|
24847
|
-
relativePathFromCwd:
|
|
26159
|
+
listCommands: import_mini79.z.object({}),
|
|
26160
|
+
getCommand: import_mini79.z.object({
|
|
26161
|
+
relativePathFromCwd: import_mini79.z.string()
|
|
24848
26162
|
}),
|
|
24849
|
-
putCommand:
|
|
24850
|
-
relativePathFromCwd:
|
|
26163
|
+
putCommand: import_mini79.z.object({
|
|
26164
|
+
relativePathFromCwd: import_mini79.z.string(),
|
|
24851
26165
|
frontmatter: RulesyncCommandFrontmatterSchema,
|
|
24852
|
-
body:
|
|
26166
|
+
body: import_mini79.z.string()
|
|
24853
26167
|
}),
|
|
24854
|
-
deleteCommand:
|
|
24855
|
-
relativePathFromCwd:
|
|
26168
|
+
deleteCommand: import_mini79.z.object({
|
|
26169
|
+
relativePathFromCwd: import_mini79.z.string()
|
|
24856
26170
|
})
|
|
24857
26171
|
};
|
|
24858
26172
|
var commandTools = {
|
|
24859
26173
|
listCommands: {
|
|
24860
26174
|
name: "listCommands",
|
|
24861
|
-
description: `List all commands from ${(0,
|
|
26175
|
+
description: `List all commands from ${(0, import_node_path154.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
24862
26176
|
parameters: commandToolSchemas.listCommands,
|
|
24863
26177
|
execute: async () => {
|
|
24864
26178
|
const commands = await listCommands();
|
|
@@ -24900,15 +26214,15 @@ var commandTools = {
|
|
|
24900
26214
|
};
|
|
24901
26215
|
|
|
24902
26216
|
// src/mcp/generate.ts
|
|
24903
|
-
var
|
|
24904
|
-
var generateOptionsSchema =
|
|
24905
|
-
targets:
|
|
24906
|
-
features:
|
|
24907
|
-
delete:
|
|
24908
|
-
global:
|
|
24909
|
-
simulateCommands:
|
|
24910
|
-
simulateSubagents:
|
|
24911
|
-
simulateSkills:
|
|
26217
|
+
var import_mini80 = require("zod/mini");
|
|
26218
|
+
var generateOptionsSchema = import_mini80.z.object({
|
|
26219
|
+
targets: import_mini80.z.optional(import_mini80.z.array(import_mini80.z.string())),
|
|
26220
|
+
features: import_mini80.z.optional(import_mini80.z.array(import_mini80.z.string())),
|
|
26221
|
+
delete: import_mini80.z.optional(import_mini80.z.boolean()),
|
|
26222
|
+
global: import_mini80.z.optional(import_mini80.z.boolean()),
|
|
26223
|
+
simulateCommands: import_mini80.z.optional(import_mini80.z.boolean()),
|
|
26224
|
+
simulateSubagents: import_mini80.z.optional(import_mini80.z.boolean()),
|
|
26225
|
+
simulateSkills: import_mini80.z.optional(import_mini80.z.boolean())
|
|
24912
26226
|
});
|
|
24913
26227
|
async function executeGenerate(options = {}) {
|
|
24914
26228
|
try {
|
|
@@ -24986,12 +26300,139 @@ var generateTools = {
|
|
|
24986
26300
|
}
|
|
24987
26301
|
};
|
|
24988
26302
|
|
|
26303
|
+
// src/mcp/hooks.ts
|
|
26304
|
+
var import_node_path155 = require("path");
|
|
26305
|
+
var import_mini81 = require("zod/mini");
|
|
26306
|
+
var maxHooksSizeBytes = 1024 * 1024;
|
|
26307
|
+
async function getHooksFile() {
|
|
26308
|
+
try {
|
|
26309
|
+
const rulesyncHooks = await RulesyncHooks.fromFile({
|
|
26310
|
+
validate: true
|
|
26311
|
+
});
|
|
26312
|
+
const relativePathFromCwd = (0, import_node_path155.join)(
|
|
26313
|
+
rulesyncHooks.getRelativeDirPath(),
|
|
26314
|
+
rulesyncHooks.getRelativeFilePath()
|
|
26315
|
+
);
|
|
26316
|
+
return {
|
|
26317
|
+
relativePathFromCwd,
|
|
26318
|
+
content: rulesyncHooks.getFileContent()
|
|
26319
|
+
};
|
|
26320
|
+
} catch (error) {
|
|
26321
|
+
throw new Error(
|
|
26322
|
+
`Failed to read hooks file (${RULESYNC_HOOKS_RELATIVE_FILE_PATH}): ${formatError(error)}`,
|
|
26323
|
+
{
|
|
26324
|
+
cause: error
|
|
26325
|
+
}
|
|
26326
|
+
);
|
|
26327
|
+
}
|
|
26328
|
+
}
|
|
26329
|
+
async function putHooksFile({ content }) {
|
|
26330
|
+
if (content.length > maxHooksSizeBytes) {
|
|
26331
|
+
throw new Error(
|
|
26332
|
+
`Hooks file size ${content.length} bytes exceeds maximum ${maxHooksSizeBytes} bytes (1MB) for ${RULESYNC_HOOKS_RELATIVE_FILE_PATH}`
|
|
26333
|
+
);
|
|
26334
|
+
}
|
|
26335
|
+
try {
|
|
26336
|
+
JSON.parse(content);
|
|
26337
|
+
} catch (error) {
|
|
26338
|
+
throw new Error(
|
|
26339
|
+
`Invalid JSON format in hooks file (${RULESYNC_HOOKS_RELATIVE_FILE_PATH}): ${formatError(error)}`,
|
|
26340
|
+
{
|
|
26341
|
+
cause: error
|
|
26342
|
+
}
|
|
26343
|
+
);
|
|
26344
|
+
}
|
|
26345
|
+
try {
|
|
26346
|
+
const baseDir = process.cwd();
|
|
26347
|
+
const paths = RulesyncHooks.getSettablePaths();
|
|
26348
|
+
const relativeDirPath = paths.relativeDirPath;
|
|
26349
|
+
const relativeFilePath = paths.relativeFilePath;
|
|
26350
|
+
const fullPath = (0, import_node_path155.join)(baseDir, relativeDirPath, relativeFilePath);
|
|
26351
|
+
const rulesyncHooks = new RulesyncHooks({
|
|
26352
|
+
baseDir,
|
|
26353
|
+
relativeDirPath,
|
|
26354
|
+
relativeFilePath,
|
|
26355
|
+
fileContent: content,
|
|
26356
|
+
validate: true
|
|
26357
|
+
});
|
|
26358
|
+
await ensureDir((0, import_node_path155.join)(baseDir, relativeDirPath));
|
|
26359
|
+
await writeFileContent(fullPath, content);
|
|
26360
|
+
const relativePathFromCwd = (0, import_node_path155.join)(relativeDirPath, relativeFilePath);
|
|
26361
|
+
return {
|
|
26362
|
+
relativePathFromCwd,
|
|
26363
|
+
content: rulesyncHooks.getFileContent()
|
|
26364
|
+
};
|
|
26365
|
+
} catch (error) {
|
|
26366
|
+
throw new Error(
|
|
26367
|
+
`Failed to write hooks file (${RULESYNC_HOOKS_RELATIVE_FILE_PATH}): ${formatError(error)}`,
|
|
26368
|
+
{
|
|
26369
|
+
cause: error
|
|
26370
|
+
}
|
|
26371
|
+
);
|
|
26372
|
+
}
|
|
26373
|
+
}
|
|
26374
|
+
async function deleteHooksFile() {
|
|
26375
|
+
try {
|
|
26376
|
+
const baseDir = process.cwd();
|
|
26377
|
+
const paths = RulesyncHooks.getSettablePaths();
|
|
26378
|
+
const filePath = (0, import_node_path155.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath);
|
|
26379
|
+
await removeFile(filePath);
|
|
26380
|
+
const relativePathFromCwd = (0, import_node_path155.join)(paths.relativeDirPath, paths.relativeFilePath);
|
|
26381
|
+
return {
|
|
26382
|
+
relativePathFromCwd
|
|
26383
|
+
};
|
|
26384
|
+
} catch (error) {
|
|
26385
|
+
throw new Error(
|
|
26386
|
+
`Failed to delete hooks file (${RULESYNC_HOOKS_RELATIVE_FILE_PATH}): ${formatError(error)}`,
|
|
26387
|
+
{
|
|
26388
|
+
cause: error
|
|
26389
|
+
}
|
|
26390
|
+
);
|
|
26391
|
+
}
|
|
26392
|
+
}
|
|
26393
|
+
var hooksToolSchemas = {
|
|
26394
|
+
getHooksFile: import_mini81.z.object({}),
|
|
26395
|
+
putHooksFile: import_mini81.z.object({
|
|
26396
|
+
content: import_mini81.z.string()
|
|
26397
|
+
}),
|
|
26398
|
+
deleteHooksFile: import_mini81.z.object({})
|
|
26399
|
+
};
|
|
26400
|
+
var hooksTools = {
|
|
26401
|
+
getHooksFile: {
|
|
26402
|
+
name: "getHooksFile",
|
|
26403
|
+
description: `Get the hooks configuration file (${RULESYNC_HOOKS_RELATIVE_FILE_PATH}).`,
|
|
26404
|
+
parameters: hooksToolSchemas.getHooksFile,
|
|
26405
|
+
execute: async () => {
|
|
26406
|
+
const result = await getHooksFile();
|
|
26407
|
+
return JSON.stringify(result, null, 2);
|
|
26408
|
+
}
|
|
26409
|
+
},
|
|
26410
|
+
putHooksFile: {
|
|
26411
|
+
name: "putHooksFile",
|
|
26412
|
+
description: "Create or update the hooks configuration file (upsert operation). content parameter is required and must be valid JSON.",
|
|
26413
|
+
parameters: hooksToolSchemas.putHooksFile,
|
|
26414
|
+
execute: async (args) => {
|
|
26415
|
+
const result = await putHooksFile({ content: args.content });
|
|
26416
|
+
return JSON.stringify(result, null, 2);
|
|
26417
|
+
}
|
|
26418
|
+
},
|
|
26419
|
+
deleteHooksFile: {
|
|
26420
|
+
name: "deleteHooksFile",
|
|
26421
|
+
description: "Delete the hooks configuration file.",
|
|
26422
|
+
parameters: hooksToolSchemas.deleteHooksFile,
|
|
26423
|
+
execute: async () => {
|
|
26424
|
+
const result = await deleteHooksFile();
|
|
26425
|
+
return JSON.stringify(result, null, 2);
|
|
26426
|
+
}
|
|
26427
|
+
}
|
|
26428
|
+
};
|
|
26429
|
+
|
|
24989
26430
|
// src/mcp/ignore.ts
|
|
24990
|
-
var
|
|
24991
|
-
var
|
|
26431
|
+
var import_node_path156 = require("path");
|
|
26432
|
+
var import_mini82 = require("zod/mini");
|
|
24992
26433
|
var maxIgnoreFileSizeBytes = 100 * 1024;
|
|
24993
26434
|
async function getIgnoreFile() {
|
|
24994
|
-
const ignoreFilePath = (0,
|
|
26435
|
+
const ignoreFilePath = (0, import_node_path156.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
24995
26436
|
try {
|
|
24996
26437
|
const content = await readFileContent(ignoreFilePath);
|
|
24997
26438
|
return {
|
|
@@ -25008,7 +26449,7 @@ async function getIgnoreFile() {
|
|
|
25008
26449
|
}
|
|
25009
26450
|
}
|
|
25010
26451
|
async function putIgnoreFile({ content }) {
|
|
25011
|
-
const ignoreFilePath = (0,
|
|
26452
|
+
const ignoreFilePath = (0, import_node_path156.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
25012
26453
|
const contentSizeBytes = Buffer.byteLength(content, "utf8");
|
|
25013
26454
|
if (contentSizeBytes > maxIgnoreFileSizeBytes) {
|
|
25014
26455
|
throw new Error(
|
|
@@ -25032,8 +26473,8 @@ async function putIgnoreFile({ content }) {
|
|
|
25032
26473
|
}
|
|
25033
26474
|
}
|
|
25034
26475
|
async function deleteIgnoreFile() {
|
|
25035
|
-
const aiignorePath = (0,
|
|
25036
|
-
const legacyIgnorePath = (0,
|
|
26476
|
+
const aiignorePath = (0, import_node_path156.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
26477
|
+
const legacyIgnorePath = (0, import_node_path156.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
|
|
25037
26478
|
try {
|
|
25038
26479
|
await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
|
|
25039
26480
|
return {
|
|
@@ -25051,11 +26492,11 @@ async function deleteIgnoreFile() {
|
|
|
25051
26492
|
}
|
|
25052
26493
|
}
|
|
25053
26494
|
var ignoreToolSchemas = {
|
|
25054
|
-
getIgnoreFile:
|
|
25055
|
-
putIgnoreFile:
|
|
25056
|
-
content:
|
|
26495
|
+
getIgnoreFile: import_mini82.z.object({}),
|
|
26496
|
+
putIgnoreFile: import_mini82.z.object({
|
|
26497
|
+
content: import_mini82.z.string()
|
|
25057
26498
|
}),
|
|
25058
|
-
deleteIgnoreFile:
|
|
26499
|
+
deleteIgnoreFile: import_mini82.z.object({})
|
|
25059
26500
|
};
|
|
25060
26501
|
var ignoreTools = {
|
|
25061
26502
|
getIgnoreFile: {
|
|
@@ -25088,11 +26529,11 @@ var ignoreTools = {
|
|
|
25088
26529
|
};
|
|
25089
26530
|
|
|
25090
26531
|
// src/mcp/import.ts
|
|
25091
|
-
var
|
|
25092
|
-
var importOptionsSchema =
|
|
25093
|
-
target:
|
|
25094
|
-
features:
|
|
25095
|
-
global:
|
|
26532
|
+
var import_mini83 = require("zod/mini");
|
|
26533
|
+
var importOptionsSchema = import_mini83.z.object({
|
|
26534
|
+
target: import_mini83.z.string(),
|
|
26535
|
+
features: import_mini83.z.optional(import_mini83.z.array(import_mini83.z.string())),
|
|
26536
|
+
global: import_mini83.z.optional(import_mini83.z.boolean())
|
|
25096
26537
|
});
|
|
25097
26538
|
async function executeImport(options) {
|
|
25098
26539
|
try {
|
|
@@ -25163,15 +26604,15 @@ var importTools = {
|
|
|
25163
26604
|
};
|
|
25164
26605
|
|
|
25165
26606
|
// src/mcp/mcp.ts
|
|
25166
|
-
var
|
|
25167
|
-
var
|
|
26607
|
+
var import_node_path157 = require("path");
|
|
26608
|
+
var import_mini84 = require("zod/mini");
|
|
25168
26609
|
var maxMcpSizeBytes = 1024 * 1024;
|
|
25169
26610
|
async function getMcpFile() {
|
|
25170
26611
|
try {
|
|
25171
26612
|
const rulesyncMcp = await RulesyncMcp.fromFile({
|
|
25172
26613
|
validate: true
|
|
25173
26614
|
});
|
|
25174
|
-
const relativePathFromCwd = (0,
|
|
26615
|
+
const relativePathFromCwd = (0, import_node_path157.join)(
|
|
25175
26616
|
rulesyncMcp.getRelativeDirPath(),
|
|
25176
26617
|
rulesyncMcp.getRelativeFilePath()
|
|
25177
26618
|
);
|
|
@@ -25209,7 +26650,7 @@ async function putMcpFile({ content }) {
|
|
|
25209
26650
|
const paths = RulesyncMcp.getSettablePaths();
|
|
25210
26651
|
const relativeDirPath = paths.recommended.relativeDirPath;
|
|
25211
26652
|
const relativeFilePath = paths.recommended.relativeFilePath;
|
|
25212
|
-
const fullPath = (0,
|
|
26653
|
+
const fullPath = (0, import_node_path157.join)(baseDir, relativeDirPath, relativeFilePath);
|
|
25213
26654
|
const rulesyncMcp = new RulesyncMcp({
|
|
25214
26655
|
baseDir,
|
|
25215
26656
|
relativeDirPath,
|
|
@@ -25217,9 +26658,9 @@ async function putMcpFile({ content }) {
|
|
|
25217
26658
|
fileContent: content,
|
|
25218
26659
|
validate: true
|
|
25219
26660
|
});
|
|
25220
|
-
await ensureDir((0,
|
|
26661
|
+
await ensureDir((0, import_node_path157.join)(baseDir, relativeDirPath));
|
|
25221
26662
|
await writeFileContent(fullPath, content);
|
|
25222
|
-
const relativePathFromCwd = (0,
|
|
26663
|
+
const relativePathFromCwd = (0, import_node_path157.join)(relativeDirPath, relativeFilePath);
|
|
25223
26664
|
return {
|
|
25224
26665
|
relativePathFromCwd,
|
|
25225
26666
|
content: rulesyncMcp.getFileContent()
|
|
@@ -25237,15 +26678,15 @@ async function deleteMcpFile() {
|
|
|
25237
26678
|
try {
|
|
25238
26679
|
const baseDir = process.cwd();
|
|
25239
26680
|
const paths = RulesyncMcp.getSettablePaths();
|
|
25240
|
-
const recommendedPath = (0,
|
|
26681
|
+
const recommendedPath = (0, import_node_path157.join)(
|
|
25241
26682
|
baseDir,
|
|
25242
26683
|
paths.recommended.relativeDirPath,
|
|
25243
26684
|
paths.recommended.relativeFilePath
|
|
25244
26685
|
);
|
|
25245
|
-
const legacyPath = (0,
|
|
26686
|
+
const legacyPath = (0, import_node_path157.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
|
|
25246
26687
|
await removeFile(recommendedPath);
|
|
25247
26688
|
await removeFile(legacyPath);
|
|
25248
|
-
const relativePathFromCwd = (0,
|
|
26689
|
+
const relativePathFromCwd = (0, import_node_path157.join)(
|
|
25249
26690
|
paths.recommended.relativeDirPath,
|
|
25250
26691
|
paths.recommended.relativeFilePath
|
|
25251
26692
|
);
|
|
@@ -25262,11 +26703,11 @@ async function deleteMcpFile() {
|
|
|
25262
26703
|
}
|
|
25263
26704
|
}
|
|
25264
26705
|
var mcpToolSchemas = {
|
|
25265
|
-
getMcpFile:
|
|
25266
|
-
putMcpFile:
|
|
25267
|
-
content:
|
|
26706
|
+
getMcpFile: import_mini84.z.object({}),
|
|
26707
|
+
putMcpFile: import_mini84.z.object({
|
|
26708
|
+
content: import_mini84.z.string()
|
|
25268
26709
|
}),
|
|
25269
|
-
deleteMcpFile:
|
|
26710
|
+
deleteMcpFile: import_mini84.z.object({})
|
|
25270
26711
|
};
|
|
25271
26712
|
var mcpTools = {
|
|
25272
26713
|
getMcpFile: {
|
|
@@ -25298,14 +26739,141 @@ var mcpTools = {
|
|
|
25298
26739
|
}
|
|
25299
26740
|
};
|
|
25300
26741
|
|
|
26742
|
+
// src/mcp/permissions.ts
|
|
26743
|
+
var import_node_path158 = require("path");
|
|
26744
|
+
var import_mini85 = require("zod/mini");
|
|
26745
|
+
var maxPermissionsSizeBytes = 1024 * 1024;
|
|
26746
|
+
async function getPermissionsFile() {
|
|
26747
|
+
try {
|
|
26748
|
+
const rulesyncPermissions = await RulesyncPermissions.fromFile({
|
|
26749
|
+
validate: true
|
|
26750
|
+
});
|
|
26751
|
+
const relativePathFromCwd = (0, import_node_path158.join)(
|
|
26752
|
+
rulesyncPermissions.getRelativeDirPath(),
|
|
26753
|
+
rulesyncPermissions.getRelativeFilePath()
|
|
26754
|
+
);
|
|
26755
|
+
return {
|
|
26756
|
+
relativePathFromCwd,
|
|
26757
|
+
content: rulesyncPermissions.getFileContent()
|
|
26758
|
+
};
|
|
26759
|
+
} catch (error) {
|
|
26760
|
+
throw new Error(
|
|
26761
|
+
`Failed to read permissions file (${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}): ${formatError(error)}`,
|
|
26762
|
+
{
|
|
26763
|
+
cause: error
|
|
26764
|
+
}
|
|
26765
|
+
);
|
|
26766
|
+
}
|
|
26767
|
+
}
|
|
26768
|
+
async function putPermissionsFile({ content }) {
|
|
26769
|
+
if (content.length > maxPermissionsSizeBytes) {
|
|
26770
|
+
throw new Error(
|
|
26771
|
+
`Permissions file size ${content.length} bytes exceeds maximum ${maxPermissionsSizeBytes} bytes (1MB) for ${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}`
|
|
26772
|
+
);
|
|
26773
|
+
}
|
|
26774
|
+
try {
|
|
26775
|
+
JSON.parse(content);
|
|
26776
|
+
} catch (error) {
|
|
26777
|
+
throw new Error(
|
|
26778
|
+
`Invalid JSON format in permissions file (${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}): ${formatError(error)}`,
|
|
26779
|
+
{
|
|
26780
|
+
cause: error
|
|
26781
|
+
}
|
|
26782
|
+
);
|
|
26783
|
+
}
|
|
26784
|
+
try {
|
|
26785
|
+
const baseDir = process.cwd();
|
|
26786
|
+
const paths = RulesyncPermissions.getSettablePaths();
|
|
26787
|
+
const relativeDirPath = paths.relativeDirPath;
|
|
26788
|
+
const relativeFilePath = paths.relativeFilePath;
|
|
26789
|
+
const fullPath = (0, import_node_path158.join)(baseDir, relativeDirPath, relativeFilePath);
|
|
26790
|
+
const rulesyncPermissions = new RulesyncPermissions({
|
|
26791
|
+
baseDir,
|
|
26792
|
+
relativeDirPath,
|
|
26793
|
+
relativeFilePath,
|
|
26794
|
+
fileContent: content,
|
|
26795
|
+
validate: true
|
|
26796
|
+
});
|
|
26797
|
+
await ensureDir((0, import_node_path158.join)(baseDir, relativeDirPath));
|
|
26798
|
+
await writeFileContent(fullPath, content);
|
|
26799
|
+
const relativePathFromCwd = (0, import_node_path158.join)(relativeDirPath, relativeFilePath);
|
|
26800
|
+
return {
|
|
26801
|
+
relativePathFromCwd,
|
|
26802
|
+
content: rulesyncPermissions.getFileContent()
|
|
26803
|
+
};
|
|
26804
|
+
} catch (error) {
|
|
26805
|
+
throw new Error(
|
|
26806
|
+
`Failed to write permissions file (${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}): ${formatError(error)}`,
|
|
26807
|
+
{
|
|
26808
|
+
cause: error
|
|
26809
|
+
}
|
|
26810
|
+
);
|
|
26811
|
+
}
|
|
26812
|
+
}
|
|
26813
|
+
async function deletePermissionsFile() {
|
|
26814
|
+
try {
|
|
26815
|
+
const baseDir = process.cwd();
|
|
26816
|
+
const paths = RulesyncPermissions.getSettablePaths();
|
|
26817
|
+
const filePath = (0, import_node_path158.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath);
|
|
26818
|
+
await removeFile(filePath);
|
|
26819
|
+
const relativePathFromCwd = (0, import_node_path158.join)(paths.relativeDirPath, paths.relativeFilePath);
|
|
26820
|
+
return {
|
|
26821
|
+
relativePathFromCwd
|
|
26822
|
+
};
|
|
26823
|
+
} catch (error) {
|
|
26824
|
+
throw new Error(
|
|
26825
|
+
`Failed to delete permissions file (${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}): ${formatError(error)}`,
|
|
26826
|
+
{
|
|
26827
|
+
cause: error
|
|
26828
|
+
}
|
|
26829
|
+
);
|
|
26830
|
+
}
|
|
26831
|
+
}
|
|
26832
|
+
var permissionsToolSchemas = {
|
|
26833
|
+
getPermissionsFile: import_mini85.z.object({}),
|
|
26834
|
+
putPermissionsFile: import_mini85.z.object({
|
|
26835
|
+
content: import_mini85.z.string()
|
|
26836
|
+
}),
|
|
26837
|
+
deletePermissionsFile: import_mini85.z.object({})
|
|
26838
|
+
};
|
|
26839
|
+
var permissionsTools = {
|
|
26840
|
+
getPermissionsFile: {
|
|
26841
|
+
name: "getPermissionsFile",
|
|
26842
|
+
description: `Get the permissions configuration file (${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}).`,
|
|
26843
|
+
parameters: permissionsToolSchemas.getPermissionsFile,
|
|
26844
|
+
execute: async () => {
|
|
26845
|
+
const result = await getPermissionsFile();
|
|
26846
|
+
return JSON.stringify(result, null, 2);
|
|
26847
|
+
}
|
|
26848
|
+
},
|
|
26849
|
+
putPermissionsFile: {
|
|
26850
|
+
name: "putPermissionsFile",
|
|
26851
|
+
description: "Create or update the permissions configuration file (upsert operation). content parameter is required and must be valid JSON.",
|
|
26852
|
+
parameters: permissionsToolSchemas.putPermissionsFile,
|
|
26853
|
+
execute: async (args) => {
|
|
26854
|
+
const result = await putPermissionsFile({ content: args.content });
|
|
26855
|
+
return JSON.stringify(result, null, 2);
|
|
26856
|
+
}
|
|
26857
|
+
},
|
|
26858
|
+
deletePermissionsFile: {
|
|
26859
|
+
name: "deletePermissionsFile",
|
|
26860
|
+
description: "Delete the permissions configuration file.",
|
|
26861
|
+
parameters: permissionsToolSchemas.deletePermissionsFile,
|
|
26862
|
+
execute: async () => {
|
|
26863
|
+
const result = await deletePermissionsFile();
|
|
26864
|
+
return JSON.stringify(result, null, 2);
|
|
26865
|
+
}
|
|
26866
|
+
}
|
|
26867
|
+
};
|
|
26868
|
+
|
|
25301
26869
|
// src/mcp/rules.ts
|
|
25302
|
-
var
|
|
25303
|
-
var
|
|
26870
|
+
var import_node_path159 = require("path");
|
|
26871
|
+
var import_mini86 = require("zod/mini");
|
|
25304
26872
|
var logger2 = new ConsoleLogger({ verbose: false, silent: true });
|
|
25305
26873
|
var maxRuleSizeBytes = 1024 * 1024;
|
|
25306
26874
|
var maxRulesCount = 1e3;
|
|
25307
26875
|
async function listRules() {
|
|
25308
|
-
const rulesDir = (0,
|
|
26876
|
+
const rulesDir = (0, import_node_path159.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
|
|
25309
26877
|
try {
|
|
25310
26878
|
const files = await listDirectoryFiles(rulesDir);
|
|
25311
26879
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -25318,7 +26886,7 @@ async function listRules() {
|
|
|
25318
26886
|
});
|
|
25319
26887
|
const frontmatter = rule.getFrontmatter();
|
|
25320
26888
|
return {
|
|
25321
|
-
relativePathFromCwd: (0,
|
|
26889
|
+
relativePathFromCwd: (0, import_node_path159.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
|
|
25322
26890
|
frontmatter
|
|
25323
26891
|
};
|
|
25324
26892
|
} catch (error) {
|
|
@@ -25340,14 +26908,14 @@ async function getRule({ relativePathFromCwd }) {
|
|
|
25340
26908
|
relativePath: relativePathFromCwd,
|
|
25341
26909
|
intendedRootDir: process.cwd()
|
|
25342
26910
|
});
|
|
25343
|
-
const filename = (0,
|
|
26911
|
+
const filename = (0, import_node_path159.basename)(relativePathFromCwd);
|
|
25344
26912
|
try {
|
|
25345
26913
|
const rule = await RulesyncRule.fromFile({
|
|
25346
26914
|
relativeFilePath: filename,
|
|
25347
26915
|
validate: true
|
|
25348
26916
|
});
|
|
25349
26917
|
return {
|
|
25350
|
-
relativePathFromCwd: (0,
|
|
26918
|
+
relativePathFromCwd: (0, import_node_path159.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
|
|
25351
26919
|
frontmatter: rule.getFrontmatter(),
|
|
25352
26920
|
body: rule.getBody()
|
|
25353
26921
|
};
|
|
@@ -25366,7 +26934,7 @@ async function putRule({
|
|
|
25366
26934
|
relativePath: relativePathFromCwd,
|
|
25367
26935
|
intendedRootDir: process.cwd()
|
|
25368
26936
|
});
|
|
25369
|
-
const filename = (0,
|
|
26937
|
+
const filename = (0, import_node_path159.basename)(relativePathFromCwd);
|
|
25370
26938
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
25371
26939
|
if (estimatedSize > maxRuleSizeBytes) {
|
|
25372
26940
|
throw new Error(
|
|
@@ -25376,7 +26944,7 @@ async function putRule({
|
|
|
25376
26944
|
try {
|
|
25377
26945
|
const existingRules = await listRules();
|
|
25378
26946
|
const isUpdate = existingRules.some(
|
|
25379
|
-
(rule2) => rule2.relativePathFromCwd === (0,
|
|
26947
|
+
(rule2) => rule2.relativePathFromCwd === (0, import_node_path159.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
|
|
25380
26948
|
);
|
|
25381
26949
|
if (!isUpdate && existingRules.length >= maxRulesCount) {
|
|
25382
26950
|
throw new Error(
|
|
@@ -25391,11 +26959,11 @@ async function putRule({
|
|
|
25391
26959
|
body,
|
|
25392
26960
|
validate: true
|
|
25393
26961
|
});
|
|
25394
|
-
const rulesDir = (0,
|
|
26962
|
+
const rulesDir = (0, import_node_path159.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
|
|
25395
26963
|
await ensureDir(rulesDir);
|
|
25396
26964
|
await writeFileContent(rule.getFilePath(), rule.getFileContent());
|
|
25397
26965
|
return {
|
|
25398
|
-
relativePathFromCwd: (0,
|
|
26966
|
+
relativePathFromCwd: (0, import_node_path159.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
|
|
25399
26967
|
frontmatter: rule.getFrontmatter(),
|
|
25400
26968
|
body: rule.getBody()
|
|
25401
26969
|
};
|
|
@@ -25410,12 +26978,12 @@ async function deleteRule({ relativePathFromCwd }) {
|
|
|
25410
26978
|
relativePath: relativePathFromCwd,
|
|
25411
26979
|
intendedRootDir: process.cwd()
|
|
25412
26980
|
});
|
|
25413
|
-
const filename = (0,
|
|
25414
|
-
const fullPath = (0,
|
|
26981
|
+
const filename = (0, import_node_path159.basename)(relativePathFromCwd);
|
|
26982
|
+
const fullPath = (0, import_node_path159.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
|
|
25415
26983
|
try {
|
|
25416
26984
|
await removeFile(fullPath);
|
|
25417
26985
|
return {
|
|
25418
|
-
relativePathFromCwd: (0,
|
|
26986
|
+
relativePathFromCwd: (0, import_node_path159.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
|
|
25419
26987
|
};
|
|
25420
26988
|
} catch (error) {
|
|
25421
26989
|
throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
|
|
@@ -25424,23 +26992,23 @@ async function deleteRule({ relativePathFromCwd }) {
|
|
|
25424
26992
|
}
|
|
25425
26993
|
}
|
|
25426
26994
|
var ruleToolSchemas = {
|
|
25427
|
-
listRules:
|
|
25428
|
-
getRule:
|
|
25429
|
-
relativePathFromCwd:
|
|
26995
|
+
listRules: import_mini86.z.object({}),
|
|
26996
|
+
getRule: import_mini86.z.object({
|
|
26997
|
+
relativePathFromCwd: import_mini86.z.string()
|
|
25430
26998
|
}),
|
|
25431
|
-
putRule:
|
|
25432
|
-
relativePathFromCwd:
|
|
26999
|
+
putRule: import_mini86.z.object({
|
|
27000
|
+
relativePathFromCwd: import_mini86.z.string(),
|
|
25433
27001
|
frontmatter: RulesyncRuleFrontmatterSchema,
|
|
25434
|
-
body:
|
|
27002
|
+
body: import_mini86.z.string()
|
|
25435
27003
|
}),
|
|
25436
|
-
deleteRule:
|
|
25437
|
-
relativePathFromCwd:
|
|
27004
|
+
deleteRule: import_mini86.z.object({
|
|
27005
|
+
relativePathFromCwd: import_mini86.z.string()
|
|
25438
27006
|
})
|
|
25439
27007
|
};
|
|
25440
27008
|
var ruleTools = {
|
|
25441
27009
|
listRules: {
|
|
25442
27010
|
name: "listRules",
|
|
25443
|
-
description: `List all rules from ${(0,
|
|
27011
|
+
description: `List all rules from ${(0, import_node_path159.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
25444
27012
|
parameters: ruleToolSchemas.listRules,
|
|
25445
27013
|
execute: async () => {
|
|
25446
27014
|
const rules = await listRules();
|
|
@@ -25482,8 +27050,8 @@ var ruleTools = {
|
|
|
25482
27050
|
};
|
|
25483
27051
|
|
|
25484
27052
|
// src/mcp/skills.ts
|
|
25485
|
-
var
|
|
25486
|
-
var
|
|
27053
|
+
var import_node_path160 = require("path");
|
|
27054
|
+
var import_mini87 = require("zod/mini");
|
|
25487
27055
|
var logger3 = new ConsoleLogger({ verbose: false, silent: true });
|
|
25488
27056
|
var maxSkillSizeBytes = 1024 * 1024;
|
|
25489
27057
|
var maxSkillsCount = 1e3;
|
|
@@ -25500,19 +27068,19 @@ function mcpSkillFileToAiDirFile(file) {
|
|
|
25500
27068
|
};
|
|
25501
27069
|
}
|
|
25502
27070
|
function extractDirName(relativeDirPathFromCwd) {
|
|
25503
|
-
const dirName = (0,
|
|
27071
|
+
const dirName = (0, import_node_path160.basename)(relativeDirPathFromCwd);
|
|
25504
27072
|
if (!dirName) {
|
|
25505
27073
|
throw new Error(`Invalid path: ${relativeDirPathFromCwd}`);
|
|
25506
27074
|
}
|
|
25507
27075
|
return dirName;
|
|
25508
27076
|
}
|
|
25509
27077
|
async function listSkills() {
|
|
25510
|
-
const skillsDir = (0,
|
|
27078
|
+
const skillsDir = (0, import_node_path160.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
|
|
25511
27079
|
try {
|
|
25512
|
-
const skillDirPaths = await findFilesByGlobs((0,
|
|
27080
|
+
const skillDirPaths = await findFilesByGlobs((0, import_node_path160.join)(skillsDir, "*"), { type: "dir" });
|
|
25513
27081
|
const skills = await Promise.all(
|
|
25514
27082
|
skillDirPaths.map(async (dirPath) => {
|
|
25515
|
-
const dirName = (0,
|
|
27083
|
+
const dirName = (0, import_node_path160.basename)(dirPath);
|
|
25516
27084
|
if (!dirName) return null;
|
|
25517
27085
|
try {
|
|
25518
27086
|
const skill = await RulesyncSkill.fromDir({
|
|
@@ -25520,7 +27088,7 @@ async function listSkills() {
|
|
|
25520
27088
|
});
|
|
25521
27089
|
const frontmatter = skill.getFrontmatter();
|
|
25522
27090
|
return {
|
|
25523
|
-
relativeDirPathFromCwd: (0,
|
|
27091
|
+
relativeDirPathFromCwd: (0, import_node_path160.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
25524
27092
|
frontmatter
|
|
25525
27093
|
};
|
|
25526
27094
|
} catch (error) {
|
|
@@ -25548,7 +27116,7 @@ async function getSkill({ relativeDirPathFromCwd }) {
|
|
|
25548
27116
|
dirName
|
|
25549
27117
|
});
|
|
25550
27118
|
return {
|
|
25551
|
-
relativeDirPathFromCwd: (0,
|
|
27119
|
+
relativeDirPathFromCwd: (0, import_node_path160.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
25552
27120
|
frontmatter: skill.getFrontmatter(),
|
|
25553
27121
|
body: skill.getBody(),
|
|
25554
27122
|
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
@@ -25582,7 +27150,7 @@ async function putSkill({
|
|
|
25582
27150
|
try {
|
|
25583
27151
|
const existingSkills = await listSkills();
|
|
25584
27152
|
const isUpdate = existingSkills.some(
|
|
25585
|
-
(skill2) => skill2.relativeDirPathFromCwd === (0,
|
|
27153
|
+
(skill2) => skill2.relativeDirPathFromCwd === (0, import_node_path160.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
25586
27154
|
);
|
|
25587
27155
|
if (!isUpdate && existingSkills.length >= maxSkillsCount) {
|
|
25588
27156
|
throw new Error(
|
|
@@ -25599,9 +27167,9 @@ async function putSkill({
|
|
|
25599
27167
|
otherFiles: aiDirFiles,
|
|
25600
27168
|
validate: true
|
|
25601
27169
|
});
|
|
25602
|
-
const skillDirPath = (0,
|
|
27170
|
+
const skillDirPath = (0, import_node_path160.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
25603
27171
|
await ensureDir(skillDirPath);
|
|
25604
|
-
const skillFilePath = (0,
|
|
27172
|
+
const skillFilePath = (0, import_node_path160.join)(skillDirPath, SKILL_FILE_NAME);
|
|
25605
27173
|
const skillFileContent = stringifyFrontmatter(body, frontmatter);
|
|
25606
27174
|
await writeFileContent(skillFilePath, skillFileContent);
|
|
25607
27175
|
for (const file of otherFiles) {
|
|
@@ -25609,15 +27177,15 @@ async function putSkill({
|
|
|
25609
27177
|
relativePath: file.name,
|
|
25610
27178
|
intendedRootDir: skillDirPath
|
|
25611
27179
|
});
|
|
25612
|
-
const filePath = (0,
|
|
25613
|
-
const fileDir = (0,
|
|
27180
|
+
const filePath = (0, import_node_path160.join)(skillDirPath, file.name);
|
|
27181
|
+
const fileDir = (0, import_node_path160.join)(skillDirPath, (0, import_node_path160.dirname)(file.name));
|
|
25614
27182
|
if (fileDir !== skillDirPath) {
|
|
25615
27183
|
await ensureDir(fileDir);
|
|
25616
27184
|
}
|
|
25617
27185
|
await writeFileContent(filePath, file.body);
|
|
25618
27186
|
}
|
|
25619
27187
|
return {
|
|
25620
|
-
relativeDirPathFromCwd: (0,
|
|
27188
|
+
relativeDirPathFromCwd: (0, import_node_path160.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
25621
27189
|
frontmatter: skill.getFrontmatter(),
|
|
25622
27190
|
body: skill.getBody(),
|
|
25623
27191
|
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
@@ -25639,13 +27207,13 @@ async function deleteSkill({
|
|
|
25639
27207
|
intendedRootDir: process.cwd()
|
|
25640
27208
|
});
|
|
25641
27209
|
const dirName = extractDirName(relativeDirPathFromCwd);
|
|
25642
|
-
const skillDirPath = (0,
|
|
27210
|
+
const skillDirPath = (0, import_node_path160.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
25643
27211
|
try {
|
|
25644
27212
|
if (await directoryExists(skillDirPath)) {
|
|
25645
27213
|
await removeDirectory(skillDirPath);
|
|
25646
27214
|
}
|
|
25647
27215
|
return {
|
|
25648
|
-
relativeDirPathFromCwd: (0,
|
|
27216
|
+
relativeDirPathFromCwd: (0, import_node_path160.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
25649
27217
|
};
|
|
25650
27218
|
} catch (error) {
|
|
25651
27219
|
throw new Error(
|
|
@@ -25656,29 +27224,29 @@ async function deleteSkill({
|
|
|
25656
27224
|
);
|
|
25657
27225
|
}
|
|
25658
27226
|
}
|
|
25659
|
-
var McpSkillFileSchema =
|
|
25660
|
-
name:
|
|
25661
|
-
body:
|
|
27227
|
+
var McpSkillFileSchema = import_mini87.z.object({
|
|
27228
|
+
name: import_mini87.z.string(),
|
|
27229
|
+
body: import_mini87.z.string()
|
|
25662
27230
|
});
|
|
25663
27231
|
var skillToolSchemas = {
|
|
25664
|
-
listSkills:
|
|
25665
|
-
getSkill:
|
|
25666
|
-
relativeDirPathFromCwd:
|
|
27232
|
+
listSkills: import_mini87.z.object({}),
|
|
27233
|
+
getSkill: import_mini87.z.object({
|
|
27234
|
+
relativeDirPathFromCwd: import_mini87.z.string()
|
|
25667
27235
|
}),
|
|
25668
|
-
putSkill:
|
|
25669
|
-
relativeDirPathFromCwd:
|
|
27236
|
+
putSkill: import_mini87.z.object({
|
|
27237
|
+
relativeDirPathFromCwd: import_mini87.z.string(),
|
|
25670
27238
|
frontmatter: RulesyncSkillFrontmatterSchema,
|
|
25671
|
-
body:
|
|
25672
|
-
otherFiles:
|
|
27239
|
+
body: import_mini87.z.string(),
|
|
27240
|
+
otherFiles: import_mini87.z.optional(import_mini87.z.array(McpSkillFileSchema))
|
|
25673
27241
|
}),
|
|
25674
|
-
deleteSkill:
|
|
25675
|
-
relativeDirPathFromCwd:
|
|
27242
|
+
deleteSkill: import_mini87.z.object({
|
|
27243
|
+
relativeDirPathFromCwd: import_mini87.z.string()
|
|
25676
27244
|
})
|
|
25677
27245
|
};
|
|
25678
27246
|
var skillTools = {
|
|
25679
27247
|
listSkills: {
|
|
25680
27248
|
name: "listSkills",
|
|
25681
|
-
description: `List all skills from ${(0,
|
|
27249
|
+
description: `List all skills from ${(0, import_node_path160.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
|
|
25682
27250
|
parameters: skillToolSchemas.listSkills,
|
|
25683
27251
|
execute: async () => {
|
|
25684
27252
|
const skills = await listSkills();
|
|
@@ -25721,13 +27289,13 @@ var skillTools = {
|
|
|
25721
27289
|
};
|
|
25722
27290
|
|
|
25723
27291
|
// src/mcp/subagents.ts
|
|
25724
|
-
var
|
|
25725
|
-
var
|
|
27292
|
+
var import_node_path161 = require("path");
|
|
27293
|
+
var import_mini88 = require("zod/mini");
|
|
25726
27294
|
var logger4 = new ConsoleLogger({ verbose: false, silent: true });
|
|
25727
27295
|
var maxSubagentSizeBytes = 1024 * 1024;
|
|
25728
27296
|
var maxSubagentsCount = 1e3;
|
|
25729
27297
|
async function listSubagents() {
|
|
25730
|
-
const subagentsDir = (0,
|
|
27298
|
+
const subagentsDir = (0, import_node_path161.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
25731
27299
|
try {
|
|
25732
27300
|
const files = await listDirectoryFiles(subagentsDir);
|
|
25733
27301
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -25740,7 +27308,7 @@ async function listSubagents() {
|
|
|
25740
27308
|
});
|
|
25741
27309
|
const frontmatter = subagent.getFrontmatter();
|
|
25742
27310
|
return {
|
|
25743
|
-
relativePathFromCwd: (0,
|
|
27311
|
+
relativePathFromCwd: (0, import_node_path161.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
|
|
25744
27312
|
frontmatter
|
|
25745
27313
|
};
|
|
25746
27314
|
} catch (error) {
|
|
@@ -25764,14 +27332,14 @@ async function getSubagent({ relativePathFromCwd }) {
|
|
|
25764
27332
|
relativePath: relativePathFromCwd,
|
|
25765
27333
|
intendedRootDir: process.cwd()
|
|
25766
27334
|
});
|
|
25767
|
-
const filename = (0,
|
|
27335
|
+
const filename = (0, import_node_path161.basename)(relativePathFromCwd);
|
|
25768
27336
|
try {
|
|
25769
27337
|
const subagent = await RulesyncSubagent.fromFile({
|
|
25770
27338
|
relativeFilePath: filename,
|
|
25771
27339
|
validate: true
|
|
25772
27340
|
});
|
|
25773
27341
|
return {
|
|
25774
|
-
relativePathFromCwd: (0,
|
|
27342
|
+
relativePathFromCwd: (0, import_node_path161.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
25775
27343
|
frontmatter: subagent.getFrontmatter(),
|
|
25776
27344
|
body: subagent.getBody()
|
|
25777
27345
|
};
|
|
@@ -25790,7 +27358,7 @@ async function putSubagent({
|
|
|
25790
27358
|
relativePath: relativePathFromCwd,
|
|
25791
27359
|
intendedRootDir: process.cwd()
|
|
25792
27360
|
});
|
|
25793
|
-
const filename = (0,
|
|
27361
|
+
const filename = (0, import_node_path161.basename)(relativePathFromCwd);
|
|
25794
27362
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
25795
27363
|
if (estimatedSize > maxSubagentSizeBytes) {
|
|
25796
27364
|
throw new Error(
|
|
@@ -25800,7 +27368,7 @@ async function putSubagent({
|
|
|
25800
27368
|
try {
|
|
25801
27369
|
const existingSubagents = await listSubagents();
|
|
25802
27370
|
const isUpdate = existingSubagents.some(
|
|
25803
|
-
(subagent2) => subagent2.relativePathFromCwd === (0,
|
|
27371
|
+
(subagent2) => subagent2.relativePathFromCwd === (0, import_node_path161.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
25804
27372
|
);
|
|
25805
27373
|
if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
|
|
25806
27374
|
throw new Error(
|
|
@@ -25815,11 +27383,11 @@ async function putSubagent({
|
|
|
25815
27383
|
body,
|
|
25816
27384
|
validate: true
|
|
25817
27385
|
});
|
|
25818
|
-
const subagentsDir = (0,
|
|
27386
|
+
const subagentsDir = (0, import_node_path161.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
25819
27387
|
await ensureDir(subagentsDir);
|
|
25820
27388
|
await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
|
|
25821
27389
|
return {
|
|
25822
|
-
relativePathFromCwd: (0,
|
|
27390
|
+
relativePathFromCwd: (0, import_node_path161.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
25823
27391
|
frontmatter: subagent.getFrontmatter(),
|
|
25824
27392
|
body: subagent.getBody()
|
|
25825
27393
|
};
|
|
@@ -25834,12 +27402,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
25834
27402
|
relativePath: relativePathFromCwd,
|
|
25835
27403
|
intendedRootDir: process.cwd()
|
|
25836
27404
|
});
|
|
25837
|
-
const filename = (0,
|
|
25838
|
-
const fullPath = (0,
|
|
27405
|
+
const filename = (0, import_node_path161.basename)(relativePathFromCwd);
|
|
27406
|
+
const fullPath = (0, import_node_path161.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
|
|
25839
27407
|
try {
|
|
25840
27408
|
await removeFile(fullPath);
|
|
25841
27409
|
return {
|
|
25842
|
-
relativePathFromCwd: (0,
|
|
27410
|
+
relativePathFromCwd: (0, import_node_path161.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
25843
27411
|
};
|
|
25844
27412
|
} catch (error) {
|
|
25845
27413
|
throw new Error(
|
|
@@ -25851,23 +27419,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
25851
27419
|
}
|
|
25852
27420
|
}
|
|
25853
27421
|
var subagentToolSchemas = {
|
|
25854
|
-
listSubagents:
|
|
25855
|
-
getSubagent:
|
|
25856
|
-
relativePathFromCwd:
|
|
27422
|
+
listSubagents: import_mini88.z.object({}),
|
|
27423
|
+
getSubagent: import_mini88.z.object({
|
|
27424
|
+
relativePathFromCwd: import_mini88.z.string()
|
|
25857
27425
|
}),
|
|
25858
|
-
putSubagent:
|
|
25859
|
-
relativePathFromCwd:
|
|
27426
|
+
putSubagent: import_mini88.z.object({
|
|
27427
|
+
relativePathFromCwd: import_mini88.z.string(),
|
|
25860
27428
|
frontmatter: RulesyncSubagentFrontmatterSchema,
|
|
25861
|
-
body:
|
|
27429
|
+
body: import_mini88.z.string()
|
|
25862
27430
|
}),
|
|
25863
|
-
deleteSubagent:
|
|
25864
|
-
relativePathFromCwd:
|
|
27431
|
+
deleteSubagent: import_mini88.z.object({
|
|
27432
|
+
relativePathFromCwd: import_mini88.z.string()
|
|
25865
27433
|
})
|
|
25866
27434
|
};
|
|
25867
27435
|
var subagentTools = {
|
|
25868
27436
|
listSubagents: {
|
|
25869
27437
|
name: "listSubagents",
|
|
25870
|
-
description: `List all subagents from ${(0,
|
|
27438
|
+
description: `List all subagents from ${(0, import_node_path161.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
25871
27439
|
parameters: subagentToolSchemas.listSubagents,
|
|
25872
27440
|
execute: async () => {
|
|
25873
27441
|
const subagents = await listSubagents();
|
|
@@ -25909,31 +27477,33 @@ var subagentTools = {
|
|
|
25909
27477
|
};
|
|
25910
27478
|
|
|
25911
27479
|
// src/mcp/tools.ts
|
|
25912
|
-
var rulesyncFeatureSchema =
|
|
27480
|
+
var rulesyncFeatureSchema = import_mini89.z.enum([
|
|
25913
27481
|
"rule",
|
|
25914
27482
|
"command",
|
|
25915
27483
|
"subagent",
|
|
25916
27484
|
"skill",
|
|
25917
27485
|
"ignore",
|
|
25918
27486
|
"mcp",
|
|
27487
|
+
"permissions",
|
|
27488
|
+
"hooks",
|
|
25919
27489
|
"generate",
|
|
25920
27490
|
"import"
|
|
25921
27491
|
]);
|
|
25922
|
-
var rulesyncOperationSchema =
|
|
25923
|
-
var skillFileSchema =
|
|
25924
|
-
name:
|
|
25925
|
-
body:
|
|
27492
|
+
var rulesyncOperationSchema = import_mini89.z.enum(["list", "get", "put", "delete", "run"]);
|
|
27493
|
+
var skillFileSchema = import_mini89.z.object({
|
|
27494
|
+
name: import_mini89.z.string(),
|
|
27495
|
+
body: import_mini89.z.string()
|
|
25926
27496
|
});
|
|
25927
|
-
var rulesyncToolSchema =
|
|
27497
|
+
var rulesyncToolSchema = import_mini89.z.object({
|
|
25928
27498
|
feature: rulesyncFeatureSchema,
|
|
25929
27499
|
operation: rulesyncOperationSchema,
|
|
25930
|
-
targetPathFromCwd:
|
|
25931
|
-
frontmatter:
|
|
25932
|
-
body:
|
|
25933
|
-
otherFiles:
|
|
25934
|
-
content:
|
|
25935
|
-
generateOptions:
|
|
25936
|
-
importOptions:
|
|
27500
|
+
targetPathFromCwd: import_mini89.z.optional(import_mini89.z.string()),
|
|
27501
|
+
frontmatter: import_mini89.z.optional(import_mini89.z.unknown()),
|
|
27502
|
+
body: import_mini89.z.optional(import_mini89.z.string()),
|
|
27503
|
+
otherFiles: import_mini89.z.optional(import_mini89.z.array(skillFileSchema)),
|
|
27504
|
+
content: import_mini89.z.optional(import_mini89.z.string()),
|
|
27505
|
+
generateOptions: import_mini89.z.optional(generateOptionsSchema),
|
|
27506
|
+
importOptions: import_mini89.z.optional(importOptionsSchema)
|
|
25937
27507
|
});
|
|
25938
27508
|
var supportedOperationsByFeature = {
|
|
25939
27509
|
rule: ["list", "get", "put", "delete"],
|
|
@@ -25942,6 +27512,8 @@ var supportedOperationsByFeature = {
|
|
|
25942
27512
|
skill: ["list", "get", "put", "delete"],
|
|
25943
27513
|
ignore: ["get", "put", "delete"],
|
|
25944
27514
|
mcp: ["get", "put", "delete"],
|
|
27515
|
+
permissions: ["get", "put", "delete"],
|
|
27516
|
+
hooks: ["get", "put", "delete"],
|
|
25945
27517
|
generate: ["run"],
|
|
25946
27518
|
import: ["run"]
|
|
25947
27519
|
};
|
|
@@ -25991,7 +27563,7 @@ function ensureBody({ body, feature, operation }) {
|
|
|
25991
27563
|
}
|
|
25992
27564
|
var rulesyncTool = {
|
|
25993
27565
|
name: "rulesyncTool",
|
|
25994
|
-
description: "Manage Rulesync files through a single MCP tool. Features: rule/command/subagent/skill support list/get/put/delete; ignore/mcp support get/put/delete only; generate supports run only; import supports run only. Parameters: list requires no targetPathFromCwd (lists all items); get/delete require targetPathFromCwd; put requires targetPathFromCwd, frontmatter, and body (or content for ignore/mcp); generate/run uses generateOptions to configure generation; import/run uses importOptions to configure import.",
|
|
27566
|
+
description: "Manage Rulesync files through a single MCP tool. Features: rule/command/subagent/skill support list/get/put/delete; ignore/mcp/permissions/hooks support get/put/delete only; generate supports run only; import supports run only. Parameters: list requires no targetPathFromCwd (lists all items); get/delete require targetPathFromCwd; put requires targetPathFromCwd, frontmatter, and body (or content for ignore/mcp/permissions/hooks); generate/run uses generateOptions to configure generation; import/run uses importOptions to configure import.",
|
|
25995
27567
|
parameters: rulesyncToolSchema,
|
|
25996
27568
|
execute: async (args) => {
|
|
25997
27569
|
const parsed = rulesyncToolSchema.parse(args);
|
|
@@ -26108,6 +27680,30 @@ var rulesyncTool = {
|
|
|
26108
27680
|
}
|
|
26109
27681
|
return mcpTools.deleteMcpFile.execute();
|
|
26110
27682
|
}
|
|
27683
|
+
case "permissions": {
|
|
27684
|
+
if (parsed.operation === "get") {
|
|
27685
|
+
return permissionsTools.getPermissionsFile.execute();
|
|
27686
|
+
}
|
|
27687
|
+
if (parsed.operation === "put") {
|
|
27688
|
+
if (!parsed.content) {
|
|
27689
|
+
throw new Error("content is required for permissions put operation");
|
|
27690
|
+
}
|
|
27691
|
+
return permissionsTools.putPermissionsFile.execute({ content: parsed.content });
|
|
27692
|
+
}
|
|
27693
|
+
return permissionsTools.deletePermissionsFile.execute();
|
|
27694
|
+
}
|
|
27695
|
+
case "hooks": {
|
|
27696
|
+
if (parsed.operation === "get") {
|
|
27697
|
+
return hooksTools.getHooksFile.execute();
|
|
27698
|
+
}
|
|
27699
|
+
if (parsed.operation === "put") {
|
|
27700
|
+
if (!parsed.content) {
|
|
27701
|
+
throw new Error("content is required for hooks put operation");
|
|
27702
|
+
}
|
|
27703
|
+
return hooksTools.putHooksFile.execute({ content: parsed.content });
|
|
27704
|
+
}
|
|
27705
|
+
return hooksTools.deleteHooksFile.execute();
|
|
27706
|
+
}
|
|
26111
27707
|
case "generate": {
|
|
26112
27708
|
return generateTools.executeGenerate.execute(parsed.generateOptions ?? {});
|
|
26113
27709
|
}
|
|
@@ -26140,7 +27736,7 @@ async function mcpCommand(logger5, { version }) {
|
|
|
26140
27736
|
}
|
|
26141
27737
|
|
|
26142
27738
|
// src/cli/commands/resolve-gitignore-targets.ts
|
|
26143
|
-
var
|
|
27739
|
+
var import_node_path162 = require("path");
|
|
26144
27740
|
var resolveGitignoreTargets = async ({
|
|
26145
27741
|
cliTargets,
|
|
26146
27742
|
cwd = process.cwd()
|
|
@@ -26148,8 +27744,8 @@ var resolveGitignoreTargets = async ({
|
|
|
26148
27744
|
if (cliTargets !== void 0) {
|
|
26149
27745
|
return cliTargets;
|
|
26150
27746
|
}
|
|
26151
|
-
const baseConfigPath = (0,
|
|
26152
|
-
const localConfigPath = (0,
|
|
27747
|
+
const baseConfigPath = (0, import_node_path162.join)(cwd, RULESYNC_CONFIG_RELATIVE_FILE_PATH);
|
|
27748
|
+
const localConfigPath = (0, import_node_path162.join)(cwd, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
|
|
26153
27749
|
const [hasBase, hasLocal] = await Promise.all([
|
|
26154
27750
|
fileExists(baseConfigPath),
|
|
26155
27751
|
fileExists(localConfigPath)
|
|
@@ -26570,7 +28166,7 @@ function wrapCommand({
|
|
|
26570
28166
|
}
|
|
26571
28167
|
|
|
26572
28168
|
// src/cli/index.ts
|
|
26573
|
-
var getVersion = () => "8.
|
|
28169
|
+
var getVersion = () => "8.7.0";
|
|
26574
28170
|
function wrapCommand2(name, errorCode, handler) {
|
|
26575
28171
|
return wrapCommand({ name, errorCode, handler, getVersion });
|
|
26576
28172
|
}
|
|
@@ -26636,12 +28232,18 @@ var main = async () => {
|
|
|
26636
28232
|
await mcpCommand(logger5, { version });
|
|
26637
28233
|
})
|
|
26638
28234
|
);
|
|
26639
|
-
program.command("install").description("Install skills from declarative sources
|
|
28235
|
+
program.command("install").description("Install skills/primitives from declarative sources (rulesync.jsonc) or apm.yml").option(
|
|
28236
|
+
"--mode <mode>",
|
|
28237
|
+
`Install layout to produce (${INSTALL_MODES.join("|")}). Default: rulesync`
|
|
28238
|
+
).option("--update", "Force re-resolve all source refs, ignoring lockfile").option(
|
|
26640
28239
|
"--frozen",
|
|
26641
28240
|
"Fail if lockfile is missing or out of sync (for CI); fetches missing skills using locked refs"
|
|
26642
28241
|
).option("--token <token>", "GitHub token for private repos").option("-c, --config <path>", "Path to configuration file").option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(
|
|
26643
28242
|
wrapCommand2("install", "INSTALL_FAILED", async (logger5, options) => {
|
|
28243
|
+
const rawMode = options.mode;
|
|
28244
|
+
const mode = parseInstallMode(rawMode);
|
|
26644
28245
|
await installCommand(logger5, {
|
|
28246
|
+
mode,
|
|
26645
28247
|
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
26646
28248
|
update: options.update,
|
|
26647
28249
|
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
@@ -26690,6 +28292,14 @@ var main = async () => {
|
|
|
26690
28292
|
);
|
|
26691
28293
|
program.parse();
|
|
26692
28294
|
};
|
|
28295
|
+
function parseInstallMode(raw) {
|
|
28296
|
+
if (raw === void 0) return void 0;
|
|
28297
|
+
const match = INSTALL_MODES.find((m) => m === raw);
|
|
28298
|
+
if (!match) {
|
|
28299
|
+
throw new Error(`Invalid --mode value "${raw}". Expected one of: ${INSTALL_MODES.join(", ")}.`);
|
|
28300
|
+
}
|
|
28301
|
+
return match;
|
|
28302
|
+
}
|
|
26693
28303
|
main().catch((error) => {
|
|
26694
28304
|
console.error(formatError(error));
|
|
26695
28305
|
process.exit(1);
|