rulesync 8.15.0 → 8.16.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-UMJWBQ2X.js → chunk-DOWXY74I.js} +232 -33
- package/dist/cli/index.cjs +236 -34
- package/dist/cli/index.js +6 -3
- package/dist/index.cjs +231 -32
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/cli/index.cjs
CHANGED
|
@@ -282,7 +282,8 @@ function validateOutputRoot(outputRoot) {
|
|
|
282
282
|
throw new Error("outputRoot cannot be an empty string");
|
|
283
283
|
}
|
|
284
284
|
if ((0, import_node_path2.isAbsolute)(outputRoot)) {
|
|
285
|
-
const
|
|
285
|
+
const separatorRegex = process.platform === "win32" ? /[/\\]/ : /\//;
|
|
286
|
+
const segments = outputRoot.split(separatorRegex);
|
|
286
287
|
if (segments.includes("..")) {
|
|
287
288
|
throw new Error(`Path traversal detected: ${outputRoot}`);
|
|
288
289
|
}
|
|
@@ -4858,7 +4859,9 @@ async function buildCodexConfigTomlContent({
|
|
|
4858
4859
|
if (typeof configToml.features !== "object" || configToml.features === null) {
|
|
4859
4860
|
configToml.features = {};
|
|
4860
4861
|
}
|
|
4861
|
-
|
|
4862
|
+
const features = configToml.features;
|
|
4863
|
+
delete features.codex_hooks;
|
|
4864
|
+
features.hooks = true;
|
|
4862
4865
|
return smolToml2.stringify(configToml);
|
|
4863
4866
|
}
|
|
4864
4867
|
var CodexcliConfigToml = class _CodexcliConfigToml extends ToolFile {
|
|
@@ -10125,6 +10128,7 @@ var ToolPermissions = class extends ToolFile {
|
|
|
10125
10128
|
};
|
|
10126
10129
|
|
|
10127
10130
|
// src/features/permissions/augmentcode-permissions.ts
|
|
10131
|
+
var moduleLogger = new ConsoleLogger();
|
|
10128
10132
|
var AugmentPermissionTypeSchema = import_mini30.z.enum(["allow", "deny", "ask-user"]);
|
|
10129
10133
|
var AugmentToolPermissionSchema = import_mini30.z.looseObject({
|
|
10130
10134
|
toolName: import_mini30.z.string(),
|
|
@@ -10216,6 +10220,33 @@ function shellRegexToGlob(regex) {
|
|
|
10216
10220
|
}
|
|
10217
10221
|
return glob;
|
|
10218
10222
|
}
|
|
10223
|
+
function isShellRegexRoundtrippable(regex) {
|
|
10224
|
+
if (!regex.startsWith("^") || !regex.endsWith("$")) {
|
|
10225
|
+
return false;
|
|
10226
|
+
}
|
|
10227
|
+
const body = regex.slice(1, -1);
|
|
10228
|
+
let i = 0;
|
|
10229
|
+
while (i < body.length) {
|
|
10230
|
+
const ch = body[i];
|
|
10231
|
+
if (ch === "\\" && i + 1 < body.length) {
|
|
10232
|
+
i += 2;
|
|
10233
|
+
continue;
|
|
10234
|
+
}
|
|
10235
|
+
if (ch === "." && body[i + 1] === "*") {
|
|
10236
|
+
i += 2;
|
|
10237
|
+
continue;
|
|
10238
|
+
}
|
|
10239
|
+
if (ch === ".") {
|
|
10240
|
+
i += 1;
|
|
10241
|
+
continue;
|
|
10242
|
+
}
|
|
10243
|
+
if (/[$^|+?*(){}[\]]/.test(ch ?? "")) {
|
|
10244
|
+
return false;
|
|
10245
|
+
}
|
|
10246
|
+
i += 1;
|
|
10247
|
+
}
|
|
10248
|
+
return true;
|
|
10249
|
+
}
|
|
10219
10250
|
var MANAGED_AUGMENT_TOOL_NAMES = new Set(Object.values(CANONICAL_TO_AUGMENT_TOOL_NAMES));
|
|
10220
10251
|
var AugmentcodePermissions = class _AugmentcodePermissions extends ToolPermissions {
|
|
10221
10252
|
constructor(params) {
|
|
@@ -10223,6 +10254,12 @@ var AugmentcodePermissions = class _AugmentcodePermissions extends ToolPermissio
|
|
|
10223
10254
|
...params,
|
|
10224
10255
|
fileContent: params.fileContent ?? "{}"
|
|
10225
10256
|
});
|
|
10257
|
+
if (params.validate) {
|
|
10258
|
+
const result = this.validate();
|
|
10259
|
+
if (!result.success) {
|
|
10260
|
+
throw result.error;
|
|
10261
|
+
}
|
|
10262
|
+
}
|
|
10226
10263
|
}
|
|
10227
10264
|
isDeletable() {
|
|
10228
10265
|
return false;
|
|
@@ -10316,14 +10353,27 @@ var AugmentcodePermissions = class _AugmentcodePermissions extends ToolPermissio
|
|
|
10316
10353
|
);
|
|
10317
10354
|
}
|
|
10318
10355
|
const config = convertAugmentToRulesyncPermissions({
|
|
10319
|
-
entries: settings.toolPermissions ?? []
|
|
10356
|
+
entries: settings.toolPermissions ?? [],
|
|
10357
|
+
logger: moduleLogger
|
|
10320
10358
|
});
|
|
10321
10359
|
return this.toRulesyncPermissionsDefault({
|
|
10322
10360
|
fileContent: JSON.stringify(config, null, 2)
|
|
10323
10361
|
});
|
|
10324
10362
|
}
|
|
10325
10363
|
validate() {
|
|
10326
|
-
|
|
10364
|
+
try {
|
|
10365
|
+
const parsed = JSON.parse(this.fileContent || "{}");
|
|
10366
|
+
const result = AugmentSettingsSchema.safeParse(parsed);
|
|
10367
|
+
if (!result.success) {
|
|
10368
|
+
return { success: false, error: result.error };
|
|
10369
|
+
}
|
|
10370
|
+
return { success: true, error: null };
|
|
10371
|
+
} catch (error) {
|
|
10372
|
+
return {
|
|
10373
|
+
success: false,
|
|
10374
|
+
error: new Error(`Failed to parse AugmentCode permissions JSON: ${formatError(error)}`)
|
|
10375
|
+
};
|
|
10376
|
+
}
|
|
10327
10377
|
}
|
|
10328
10378
|
static forDeletion({
|
|
10329
10379
|
outputRoot = process.cwd(),
|
|
@@ -10421,7 +10471,8 @@ function sortAugmentEntries(entries) {
|
|
|
10421
10471
|
return decorated.map((d) => d.entry);
|
|
10422
10472
|
}
|
|
10423
10473
|
function convertAugmentToRulesyncPermissions({
|
|
10424
|
-
entries
|
|
10474
|
+
entries,
|
|
10475
|
+
logger: logger5
|
|
10425
10476
|
}) {
|
|
10426
10477
|
const actionPriority = {
|
|
10427
10478
|
deny: 2,
|
|
@@ -10432,7 +10483,27 @@ function convertAugmentToRulesyncPermissions({
|
|
|
10432
10483
|
for (const entry of entries) {
|
|
10433
10484
|
const canonical = toCanonicalToolName(entry.toolName);
|
|
10434
10485
|
const action = augmentTypeToAction(entry.permission.type);
|
|
10435
|
-
|
|
10486
|
+
let pattern;
|
|
10487
|
+
if (entry.toolName === "launch-process" && entry.shellInputRegex) {
|
|
10488
|
+
const regex = entry.shellInputRegex;
|
|
10489
|
+
if (isShellRegexRoundtrippable(regex)) {
|
|
10490
|
+
pattern = shellRegexToGlob(regex);
|
|
10491
|
+
} else {
|
|
10492
|
+
if (action === "deny") {
|
|
10493
|
+
logger5?.warn(
|
|
10494
|
+
`AugmentCode permissions: shellInputRegex '${regex}' on tool '${entry.toolName}' is not faithfully roundtrippable to a glob. Importing as the catch-all '*' pattern (fail-closed) so the deny rule cannot be silently narrowed on regenerate.`
|
|
10495
|
+
);
|
|
10496
|
+
pattern = "*";
|
|
10497
|
+
} else {
|
|
10498
|
+
pattern = shellRegexToGlob(regex);
|
|
10499
|
+
logger5?.warn(
|
|
10500
|
+
`AugmentCode permissions: shellInputRegex '${regex}' on tool '${entry.toolName}' is not faithfully roundtrippable to a glob. Importing as glob '${pattern}'; the rule may match a different set of inputs after regenerate.`
|
|
10501
|
+
);
|
|
10502
|
+
}
|
|
10503
|
+
}
|
|
10504
|
+
} else {
|
|
10505
|
+
pattern = "*";
|
|
10506
|
+
}
|
|
10436
10507
|
if (!permission[canonical]) {
|
|
10437
10508
|
permission[canonical] = {};
|
|
10438
10509
|
}
|
|
@@ -10687,6 +10758,12 @@ var ClinePermissions = class _ClinePermissions extends ToolPermissions {
|
|
|
10687
10758
|
...params,
|
|
10688
10759
|
fileContent: params.fileContent ?? "{}"
|
|
10689
10760
|
});
|
|
10761
|
+
if (params.validate) {
|
|
10762
|
+
const result = this.validate();
|
|
10763
|
+
if (!result.success) {
|
|
10764
|
+
throw result.error;
|
|
10765
|
+
}
|
|
10766
|
+
}
|
|
10690
10767
|
}
|
|
10691
10768
|
isDeletable() {
|
|
10692
10769
|
return false;
|
|
@@ -10825,7 +10902,19 @@ var ClinePermissions = class _ClinePermissions extends ToolPermissions {
|
|
|
10825
10902
|
});
|
|
10826
10903
|
}
|
|
10827
10904
|
validate() {
|
|
10828
|
-
|
|
10905
|
+
try {
|
|
10906
|
+
const parsed = JSON.parse(this.fileContent || "{}");
|
|
10907
|
+
const result = ClineCommandPermissionsSchema.safeParse(parsed);
|
|
10908
|
+
if (!result.success) {
|
|
10909
|
+
return { success: false, error: result.error };
|
|
10910
|
+
}
|
|
10911
|
+
return { success: true, error: null };
|
|
10912
|
+
} catch (error) {
|
|
10913
|
+
return {
|
|
10914
|
+
success: false,
|
|
10915
|
+
error: new Error(`Failed to parse Cline permissions JSON: ${formatError(error)}`)
|
|
10916
|
+
};
|
|
10917
|
+
}
|
|
10829
10918
|
}
|
|
10830
10919
|
static forDeletion({
|
|
10831
10920
|
outputRoot = process.cwd(),
|
|
@@ -10847,6 +10936,8 @@ var import_node_path71 = require("path");
|
|
|
10847
10936
|
var smolToml4 = __toESM(require("smol-toml"), 1);
|
|
10848
10937
|
var RULESYNC_PROFILE_NAME = "rulesync";
|
|
10849
10938
|
var RULESYNC_BASH_RULES_FILE_NAME = "rulesync.rules";
|
|
10939
|
+
var CODEX_PROJECT_ROOTS_KEY = ":project_roots";
|
|
10940
|
+
var CODEX_GLOB_SCAN_MAX_DEPTH = 8;
|
|
10850
10941
|
var CodexcliPermissions = class _CodexcliPermissions extends ToolPermissions {
|
|
10851
10942
|
static getSettablePaths(_options = {}) {
|
|
10852
10943
|
return {
|
|
@@ -10957,17 +11048,28 @@ function convertRulesyncToCodexProfile({
|
|
|
10957
11048
|
logger: logger5
|
|
10958
11049
|
}) {
|
|
10959
11050
|
const filesystem = {};
|
|
11051
|
+
const projectRootFilesystem = {};
|
|
10960
11052
|
const domains = {};
|
|
10961
11053
|
for (const [toolName, rules] of Object.entries(config.permission)) {
|
|
10962
11054
|
if (toolName === "read") {
|
|
10963
11055
|
for (const [pattern, action] of Object.entries(rules)) {
|
|
10964
|
-
|
|
11056
|
+
addFilesystemRule({
|
|
11057
|
+
filesystem,
|
|
11058
|
+
projectRootFilesystem,
|
|
11059
|
+
pattern,
|
|
11060
|
+
access: mapReadAction(action)
|
|
11061
|
+
});
|
|
10965
11062
|
}
|
|
10966
11063
|
continue;
|
|
10967
11064
|
}
|
|
10968
11065
|
if (toolName === "edit" || toolName === "write") {
|
|
10969
11066
|
for (const [pattern, action] of Object.entries(rules)) {
|
|
10970
|
-
|
|
11067
|
+
addFilesystemRule({
|
|
11068
|
+
filesystem,
|
|
11069
|
+
projectRootFilesystem,
|
|
11070
|
+
pattern,
|
|
11071
|
+
access: mapWriteAction(action)
|
|
11072
|
+
});
|
|
10971
11073
|
}
|
|
10972
11074
|
continue;
|
|
10973
11075
|
}
|
|
@@ -10987,6 +11089,12 @@ function convertRulesyncToCodexProfile({
|
|
|
10987
11089
|
`Codex CLI permissions support only read/edit/write/webfetch categories. Skipping: ${toolName}`
|
|
10988
11090
|
);
|
|
10989
11091
|
}
|
|
11092
|
+
if (Object.keys(projectRootFilesystem).length > 0) {
|
|
11093
|
+
if (Object.keys(projectRootFilesystem).some((pattern) => pattern.includes("**"))) {
|
|
11094
|
+
filesystem.glob_scan_max_depth = CODEX_GLOB_SCAN_MAX_DEPTH;
|
|
11095
|
+
}
|
|
11096
|
+
filesystem[CODEX_PROJECT_ROOTS_KEY] = projectRootFilesystem;
|
|
11097
|
+
}
|
|
10990
11098
|
return {
|
|
10991
11099
|
...Object.keys(filesystem).length > 0 ? { filesystem } : {},
|
|
10992
11100
|
...Object.keys(domains).length > 0 ? { network: { domains } } : {}
|
|
@@ -10998,13 +11106,14 @@ function convertCodexProfileToRulesync(profile) {
|
|
|
10998
11106
|
permission.read = {};
|
|
10999
11107
|
permission.edit = {};
|
|
11000
11108
|
for (const [pattern, access] of Object.entries(profile.filesystem)) {
|
|
11001
|
-
if (access
|
|
11002
|
-
permission
|
|
11003
|
-
|
|
11004
|
-
}
|
|
11005
|
-
|
|
11006
|
-
|
|
11007
|
-
|
|
11109
|
+
if (isCodexFilesystemAccess(access)) {
|
|
11110
|
+
addRulesyncFilesystemRule(permission, pattern, access);
|
|
11111
|
+
continue;
|
|
11112
|
+
}
|
|
11113
|
+
if (isCodexFilesystemRuleTable(access)) {
|
|
11114
|
+
for (const [nestedPattern, nestedAccess] of Object.entries(access)) {
|
|
11115
|
+
addRulesyncFilesystemRule(permission, nestedPattern, nestedAccess);
|
|
11116
|
+
}
|
|
11008
11117
|
}
|
|
11009
11118
|
}
|
|
11010
11119
|
}
|
|
@@ -11027,6 +11136,35 @@ function toCodexProfile(value) {
|
|
|
11027
11136
|
...domains ? { network: { domains } } : {}
|
|
11028
11137
|
};
|
|
11029
11138
|
}
|
|
11139
|
+
function addFilesystemRule({
|
|
11140
|
+
filesystem,
|
|
11141
|
+
projectRootFilesystem,
|
|
11142
|
+
pattern,
|
|
11143
|
+
access
|
|
11144
|
+
}) {
|
|
11145
|
+
if (canBeCodexFilesystemRoot(pattern)) {
|
|
11146
|
+
filesystem[pattern] = access;
|
|
11147
|
+
return;
|
|
11148
|
+
}
|
|
11149
|
+
projectRootFilesystem[pattern] = access;
|
|
11150
|
+
}
|
|
11151
|
+
function canBeCodexFilesystemRoot(pattern) {
|
|
11152
|
+
return (0, import_node_path71.isAbsolute)(pattern) || /^[A-Za-z]:[\\/]/.test(pattern) || pattern.startsWith("~/") || pattern === "~" || pattern.startsWith(":");
|
|
11153
|
+
}
|
|
11154
|
+
function addRulesyncFilesystemRule(permission, pattern, access) {
|
|
11155
|
+
if (access === "none") {
|
|
11156
|
+
permission.read ??= {};
|
|
11157
|
+
permission.edit ??= {};
|
|
11158
|
+
permission.read[pattern] = "deny";
|
|
11159
|
+
permission.edit[pattern] = "deny";
|
|
11160
|
+
} else if (access === "read") {
|
|
11161
|
+
permission.read ??= {};
|
|
11162
|
+
permission.read[pattern] = "allow";
|
|
11163
|
+
} else {
|
|
11164
|
+
permission.edit ??= {};
|
|
11165
|
+
permission.edit[pattern] = "allow";
|
|
11166
|
+
}
|
|
11167
|
+
}
|
|
11030
11168
|
function toMutableTable(value) {
|
|
11031
11169
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
11032
11170
|
return {};
|
|
@@ -11037,8 +11175,33 @@ function toFilesystemRecord(value) {
|
|
|
11037
11175
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
11038
11176
|
const result = {};
|
|
11039
11177
|
for (const [key, raw] of Object.entries(value)) {
|
|
11040
|
-
if (
|
|
11041
|
-
|
|
11178
|
+
if (isCodexFilesystemAccess(raw)) {
|
|
11179
|
+
result[key] = raw;
|
|
11180
|
+
continue;
|
|
11181
|
+
}
|
|
11182
|
+
if (key === "glob_scan_max_depth" && typeof raw === "number") {
|
|
11183
|
+
result[key] = raw;
|
|
11184
|
+
continue;
|
|
11185
|
+
}
|
|
11186
|
+
const nested = toCodexFilesystemRuleTable(raw);
|
|
11187
|
+
if (nested) {
|
|
11188
|
+
result[key] = nested;
|
|
11189
|
+
}
|
|
11190
|
+
}
|
|
11191
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
11192
|
+
}
|
|
11193
|
+
function isCodexFilesystemAccess(value) {
|
|
11194
|
+
return value === "read" || value === "write" || value === "none";
|
|
11195
|
+
}
|
|
11196
|
+
function isCodexFilesystemRuleTable(value) {
|
|
11197
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
11198
|
+
return Object.values(value).every(isCodexFilesystemAccess);
|
|
11199
|
+
}
|
|
11200
|
+
function toCodexFilesystemRuleTable(value) {
|
|
11201
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
11202
|
+
const result = {};
|
|
11203
|
+
for (const [key, raw] of Object.entries(value)) {
|
|
11204
|
+
if (isCodexFilesystemAccess(raw)) {
|
|
11042
11205
|
result[key] = raw;
|
|
11043
11206
|
}
|
|
11044
11207
|
}
|
|
@@ -11418,7 +11581,7 @@ var RESERVED_OBJECT_KEYS = /* @__PURE__ */ new Set([
|
|
|
11418
11581
|
"constructor",
|
|
11419
11582
|
"prototype"
|
|
11420
11583
|
]);
|
|
11421
|
-
var
|
|
11584
|
+
var moduleLogger2 = new ConsoleLogger();
|
|
11422
11585
|
var GeminicliPermissions = class _GeminicliPermissions extends ToolPermissions {
|
|
11423
11586
|
static getSettablePaths(_options = {}) {
|
|
11424
11587
|
return {
|
|
@@ -11447,7 +11610,7 @@ var GeminicliPermissions = class _GeminicliPermissions extends ToolPermissions {
|
|
|
11447
11610
|
rulesyncPermissions,
|
|
11448
11611
|
validate = true,
|
|
11449
11612
|
global = false,
|
|
11450
|
-
logger: logger5 =
|
|
11613
|
+
logger: logger5 = moduleLogger2
|
|
11451
11614
|
}) {
|
|
11452
11615
|
const paths = this.getSettablePaths({ global });
|
|
11453
11616
|
const fileContent = buildGeminicliPolicyContent(rulesyncPermissions.getJson(), logger5);
|
|
@@ -11472,31 +11635,31 @@ var GeminicliPermissions = class _GeminicliPermissions extends ToolPermissions {
|
|
|
11472
11635
|
{ cause: error }
|
|
11473
11636
|
);
|
|
11474
11637
|
}
|
|
11475
|
-
const rules = extractRules(parsed,
|
|
11638
|
+
const rules = extractRules(parsed, moduleLogger2);
|
|
11476
11639
|
for (const [index, rule] of rules.entries()) {
|
|
11477
11640
|
const mappedCategory = Object.hasOwn(GEMINICLI_TO_RULESYNC_TOOL_NAME, rule.toolName) ? GEMINICLI_TO_RULESYNC_TOOL_NAME[rule.toolName] : void 0;
|
|
11478
11641
|
const category = mappedCategory ?? rule.toolName;
|
|
11479
11642
|
if (RESERVED_OBJECT_KEYS.has(category)) {
|
|
11480
|
-
|
|
11643
|
+
moduleLogger2.warn(
|
|
11481
11644
|
`Skipping rule #${index} in ${this.getRelativeFilePath()}: toolName "${rule.toolName}" maps to a reserved object key ("${category}") and would risk prototype pollution.`
|
|
11482
11645
|
);
|
|
11483
11646
|
continue;
|
|
11484
11647
|
}
|
|
11485
11648
|
const action = mapFromGeminicliDecision(rule.decision);
|
|
11486
11649
|
if (!action) {
|
|
11487
|
-
|
|
11650
|
+
moduleLogger2.warn(
|
|
11488
11651
|
`Skipping rule #${index} (toolName="${rule.toolName}", commandPrefix=${JSON.stringify(rule.commandPrefix)}, argsPattern=${JSON.stringify(rule.argsPattern)}) in ${this.getRelativeFilePath()}: unknown decision ${JSON.stringify(rule.decision)}`
|
|
11489
11652
|
);
|
|
11490
11653
|
continue;
|
|
11491
11654
|
}
|
|
11492
11655
|
if (rule.toolName === "run_shell_command" && rule.commandPrefix !== void 0 && rule.argsPattern !== void 0) {
|
|
11493
|
-
|
|
11656
|
+
moduleLogger2.warn(
|
|
11494
11657
|
`Rule #${index} in ${this.getRelativeFilePath()} sets both commandPrefix and argsPattern; rulesync will honor argsPattern and ignore commandPrefix=${JSON.stringify(rule.commandPrefix)}.`
|
|
11495
11658
|
);
|
|
11496
11659
|
}
|
|
11497
11660
|
const pattern = extractPattern(rule);
|
|
11498
11661
|
if (RESERVED_OBJECT_KEYS.has(pattern)) {
|
|
11499
|
-
|
|
11662
|
+
moduleLogger2.warn(
|
|
11500
11663
|
`Skipping rule #${index} in ${this.getRelativeFilePath()}: pattern "${pattern}" is a reserved object key.`
|
|
11501
11664
|
);
|
|
11502
11665
|
continue;
|
|
@@ -12265,7 +12428,7 @@ var QwenSettingsPermissionsSchema = import_mini36.z.looseObject({
|
|
|
12265
12428
|
var QwenSettingsSchema = import_mini36.z.looseObject({
|
|
12266
12429
|
permissions: import_mini36.z.optional(QwenSettingsPermissionsSchema)
|
|
12267
12430
|
});
|
|
12268
|
-
var
|
|
12431
|
+
var moduleLogger3 = new ConsoleLogger();
|
|
12269
12432
|
var CANONICAL_TO_QWEN_TOOL_NAMES = {
|
|
12270
12433
|
bash: "Bash",
|
|
12271
12434
|
read: "Read",
|
|
@@ -12320,6 +12483,12 @@ var QwencodePermissions = class _QwencodePermissions extends ToolPermissions {
|
|
|
12320
12483
|
...params,
|
|
12321
12484
|
fileContent: params.fileContent ?? "{}"
|
|
12322
12485
|
});
|
|
12486
|
+
if (params.validate) {
|
|
12487
|
+
const result = this.validate();
|
|
12488
|
+
if (!result.success) {
|
|
12489
|
+
throw result.error;
|
|
12490
|
+
}
|
|
12491
|
+
}
|
|
12323
12492
|
}
|
|
12324
12493
|
isDeletable() {
|
|
12325
12494
|
return false;
|
|
@@ -12441,7 +12610,19 @@ var QwencodePermissions = class _QwencodePermissions extends ToolPermissions {
|
|
|
12441
12610
|
});
|
|
12442
12611
|
}
|
|
12443
12612
|
validate() {
|
|
12444
|
-
|
|
12613
|
+
try {
|
|
12614
|
+
const parsed = JSON.parse(this.fileContent || "{}");
|
|
12615
|
+
const result = QwenSettingsSchema.safeParse(parsed);
|
|
12616
|
+
if (!result.success) {
|
|
12617
|
+
return { success: false, error: result.error };
|
|
12618
|
+
}
|
|
12619
|
+
return { success: true, error: null };
|
|
12620
|
+
} catch (error) {
|
|
12621
|
+
return {
|
|
12622
|
+
success: false,
|
|
12623
|
+
error: new Error(`Failed to parse Qwen permissions JSON: ${formatError(error)}`)
|
|
12624
|
+
};
|
|
12625
|
+
}
|
|
12445
12626
|
}
|
|
12446
12627
|
static forDeletion({
|
|
12447
12628
|
outputRoot = process.cwd(),
|
|
@@ -12482,7 +12663,7 @@ function convertRulesyncToQwenPermissions(config) {
|
|
|
12482
12663
|
}
|
|
12483
12664
|
function convertQwenToRulesyncPermissions(params) {
|
|
12484
12665
|
const permission = {};
|
|
12485
|
-
const logger5 = params.logger ??
|
|
12666
|
+
const logger5 = params.logger ?? moduleLogger3;
|
|
12486
12667
|
const processEntries = (entries, action) => {
|
|
12487
12668
|
for (const entry of entries) {
|
|
12488
12669
|
const parsed = parseQwenPermissionEntry(entry, { logger: logger5 });
|
|
@@ -13234,7 +13415,8 @@ var RulesyncSkillFrontmatterSchemaInternal = import_mini39.z.looseObject({
|
|
|
13234
13415
|
"allowed-tools": import_mini39.z.optional(import_mini39.z.array(import_mini39.z.string())),
|
|
13235
13416
|
model: import_mini39.z.optional(import_mini39.z.string()),
|
|
13236
13417
|
"disable-model-invocation": import_mini39.z.optional(import_mini39.z.boolean()),
|
|
13237
|
-
"scheduled-task": import_mini39.z.optional(import_mini39.z.boolean())
|
|
13418
|
+
"scheduled-task": import_mini39.z.optional(import_mini39.z.boolean()),
|
|
13419
|
+
paths: import_mini39.z.optional(import_mini39.z.union([import_mini39.z.string(), import_mini39.z.array(import_mini39.z.string())]))
|
|
13238
13420
|
})
|
|
13239
13421
|
),
|
|
13240
13422
|
codexcli: import_mini39.z.optional(
|
|
@@ -14009,7 +14191,8 @@ var ClaudecodeSkillFrontmatterSchema = import_mini43.z.looseObject({
|
|
|
14009
14191
|
description: import_mini43.z.string(),
|
|
14010
14192
|
"allowed-tools": import_mini43.z.optional(import_mini43.z.array(import_mini43.z.string())),
|
|
14011
14193
|
model: import_mini43.z.optional(import_mini43.z.string()),
|
|
14012
|
-
"disable-model-invocation": import_mini43.z.optional(import_mini43.z.boolean())
|
|
14194
|
+
"disable-model-invocation": import_mini43.z.optional(import_mini43.z.boolean()),
|
|
14195
|
+
paths: import_mini43.z.optional(import_mini43.z.union([import_mini43.z.string(), import_mini43.z.array(import_mini43.z.string())]))
|
|
14013
14196
|
});
|
|
14014
14197
|
var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
14015
14198
|
constructor({
|
|
@@ -14082,6 +14265,7 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
|
14082
14265
|
...frontmatter["disable-model-invocation"] !== void 0 && {
|
|
14083
14266
|
"disable-model-invocation": frontmatter["disable-model-invocation"]
|
|
14084
14267
|
},
|
|
14268
|
+
...frontmatter.paths !== void 0 && { paths: frontmatter.paths },
|
|
14085
14269
|
...this.relativeDirPath === CLAUDE_SCHEDULED_TASKS_DIR_PATH && { "scheduled-task": true }
|
|
14086
14270
|
};
|
|
14087
14271
|
const rulesyncFrontmatter = {
|
|
@@ -14119,6 +14303,9 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
|
14119
14303
|
},
|
|
14120
14304
|
...rulesyncFrontmatter.claudecode?.["disable-model-invocation"] !== void 0 && {
|
|
14121
14305
|
"disable-model-invocation": rulesyncFrontmatter.claudecode["disable-model-invocation"]
|
|
14306
|
+
},
|
|
14307
|
+
...rulesyncFrontmatter.claudecode?.paths !== void 0 && {
|
|
14308
|
+
paths: rulesyncFrontmatter.claudecode.paths
|
|
14122
14309
|
}
|
|
14123
14310
|
};
|
|
14124
14311
|
const settablePaths = _ClaudecodeSkill.getSettablePaths({ global });
|
|
@@ -21063,6 +21250,8 @@ var CopilotRuleFrontmatterSchema = import_mini77.z.object({
|
|
|
21063
21250
|
applyTo: import_mini77.z.optional(import_mini77.z.string()),
|
|
21064
21251
|
excludeAgent: import_mini77.z.optional(import_mini77.z.union([import_mini77.z.literal("code-review"), import_mini77.z.literal("coding-agent")]))
|
|
21065
21252
|
});
|
|
21253
|
+
var normalizeRelativePath = (path5) => path5.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
21254
|
+
var sameRelativePath = (leftDir, leftFile, rightDir, rightFile) => normalizeRelativePath((0, import_node_path136.join)(leftDir, leftFile)) === normalizeRelativePath((0, import_node_path136.join)(rightDir, rightFile));
|
|
21066
21255
|
var CopilotRule = class _CopilotRule extends ToolRule {
|
|
21067
21256
|
frontmatter;
|
|
21068
21257
|
body;
|
|
@@ -21180,7 +21369,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
21180
21369
|
global = false
|
|
21181
21370
|
}) {
|
|
21182
21371
|
const paths = this.getSettablePaths({ global });
|
|
21183
|
-
const isRoot = relativeDirPath ? (
|
|
21372
|
+
const isRoot = relativeDirPath ? sameRelativePath(
|
|
21373
|
+
relativeDirPath,
|
|
21374
|
+
relativeFilePath,
|
|
21375
|
+
paths.root.relativeDirPath,
|
|
21376
|
+
paths.root.relativeFilePath
|
|
21377
|
+
) : relativeFilePath === paths.root.relativeFilePath;
|
|
21184
21378
|
const resolvedRelativeDirPath = relativeDirPath ?? (isRoot ? paths.root.relativeDirPath : paths.nonRoot?.relativeDirPath ?? paths.root.relativeDirPath);
|
|
21185
21379
|
if (isRoot) {
|
|
21186
21380
|
const relativePath2 = (0, import_node_path136.join)(paths.root.relativeDirPath, paths.root.relativeFilePath);
|
|
@@ -21224,7 +21418,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
21224
21418
|
global = false
|
|
21225
21419
|
}) {
|
|
21226
21420
|
const paths = this.getSettablePaths({ global });
|
|
21227
|
-
const isRoot = (
|
|
21421
|
+
const isRoot = sameRelativePath(
|
|
21422
|
+
relativeDirPath,
|
|
21423
|
+
relativeFilePath,
|
|
21424
|
+
paths.root.relativeDirPath,
|
|
21425
|
+
paths.root.relativeFilePath
|
|
21426
|
+
);
|
|
21228
21427
|
return new _CopilotRule({
|
|
21229
21428
|
outputRoot,
|
|
21230
21429
|
relativeDirPath,
|
|
@@ -26171,7 +26370,10 @@ var GITIGNORE_ENTRY_REGISTRY = [
|
|
|
26171
26370
|
{ target: "kilo", feature: "commands", entry: "**/.kilo/workflows/" },
|
|
26172
26371
|
{ target: "kilo", feature: "mcp", entry: "**/.kilo/mcp.json" },
|
|
26173
26372
|
{ target: "kilo", feature: "ignore", entry: "**/.kiloignore" },
|
|
26174
|
-
|
|
26373
|
+
// No `**/kilo.jsonc` entry: structurally identical to `opencode.jsonc` (no
|
|
26374
|
+
// entry). The Kilo translator preserves non-permissions Kilo settings on
|
|
26375
|
+
// round-trip, so the file is intended to be checked in by the user — adding
|
|
26376
|
+
// `**/kilo.jsonc` would be too aggressive.
|
|
26175
26377
|
// Kiro
|
|
26176
26378
|
{ target: "kiro", feature: "rules", entry: "**/.kiro/steering/" },
|
|
26177
26379
|
{ target: "kiro", feature: "commands", entry: "**/.kiro/prompts/" },
|
|
@@ -31509,7 +31711,7 @@ function wrapCommand({
|
|
|
31509
31711
|
}
|
|
31510
31712
|
|
|
31511
31713
|
// src/cli/index.ts
|
|
31512
|
-
var getVersion = () => "8.
|
|
31714
|
+
var getVersion = () => "8.16.0";
|
|
31513
31715
|
function wrapCommand2(name, errorCode, handler) {
|
|
31514
31716
|
return wrapCommand({ name, errorCode, handler, getVersion });
|
|
31515
31717
|
}
|
package/dist/cli/index.js
CHANGED
|
@@ -79,7 +79,7 @@ import {
|
|
|
79
79
|
stringifyFrontmatter,
|
|
80
80
|
toPosixPath,
|
|
81
81
|
writeFileContent
|
|
82
|
-
} from "../chunk-
|
|
82
|
+
} from "../chunk-DOWXY74I.js";
|
|
83
83
|
|
|
84
84
|
// src/cli/index.ts
|
|
85
85
|
import { Command } from "commander";
|
|
@@ -1408,7 +1408,10 @@ var GITIGNORE_ENTRY_REGISTRY = [
|
|
|
1408
1408
|
{ target: "kilo", feature: "commands", entry: "**/.kilo/workflows/" },
|
|
1409
1409
|
{ target: "kilo", feature: "mcp", entry: "**/.kilo/mcp.json" },
|
|
1410
1410
|
{ target: "kilo", feature: "ignore", entry: "**/.kiloignore" },
|
|
1411
|
-
|
|
1411
|
+
// No `**/kilo.jsonc` entry: structurally identical to `opencode.jsonc` (no
|
|
1412
|
+
// entry). The Kilo translator preserves non-permissions Kilo settings on
|
|
1413
|
+
// round-trip, so the file is intended to be checked in by the user — adding
|
|
1414
|
+
// `**/kilo.jsonc` would be too aggressive.
|
|
1412
1415
|
// Kiro
|
|
1413
1416
|
{ target: "kiro", feature: "rules", entry: "**/.kiro/steering/" },
|
|
1414
1417
|
{ target: "kiro", feature: "commands", entry: "**/.kiro/prompts/" },
|
|
@@ -6482,7 +6485,7 @@ function wrapCommand({
|
|
|
6482
6485
|
}
|
|
6483
6486
|
|
|
6484
6487
|
// src/cli/index.ts
|
|
6485
|
-
var getVersion = () => "8.
|
|
6488
|
+
var getVersion = () => "8.16.0";
|
|
6486
6489
|
function wrapCommand2(name, errorCode, handler) {
|
|
6487
6490
|
return wrapCommand({ name, errorCode, handler, getVersion });
|
|
6488
6491
|
}
|