rulesync 16.23.0 → 16.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.cjs +25 -19
- package/dist/cli/index.js +25 -19
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-D420jbVB.cjs → import-CI0pN6s5.cjs} +389 -78
- package/dist/{import-DIDEUv63.js → import-DL8paEMP.js} +390 -79
- package/dist/import-DL8paEMP.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +9 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +20 -20
- package/dist/import-DIDEUv63.js.map +0 -1
|
@@ -6633,10 +6633,25 @@ const CursorPermissionsOverrideSchema = z.looseObject({
|
|
|
6633
6633
|
* Tool-scoped override block for Qwen Code. Qwen's `settings.json` exposes
|
|
6634
6634
|
* autonomy/sandbox controls with no canonical permission category — under
|
|
6635
6635
|
* `tools` (`approvalMode` = plan/default/auto-edit/auto/yolo, `autoAccept`,
|
|
6636
|
-
* `sandbox`, `sandboxImage`, `disabled
|
|
6637
|
-
* `
|
|
6638
|
-
* Qwen Code
|
|
6639
|
-
*
|
|
6636
|
+
* `sandbox`, `sandboxImage`, `disabled`, `visible`, `listDirectory`,
|
|
6637
|
+
* `workflowsEnabled`) and `security` (`folderTrust`, `allowedHttpHookUrls`,
|
|
6638
|
+
* `allowPrivateNetworkHooks`, `allowedInsecureVoiceBaseUrls`). Qwen Code strips
|
|
6639
|
+
* `tools.workflowsEnabled`, `security.allowPrivateNetworkHooks` and
|
|
6640
|
+
* `security.allowedInsecureVoiceBaseUrls` out of workspace settings, so generate
|
|
6641
|
+
* skips those three in project scope and announces a granting value in global
|
|
6642
|
+
* scope. `security.allowedHttpHookUrls` (honored in a workspace only while no
|
|
6643
|
+
* higher scope sets it) and `security.folderTrust` (the initial trust decision
|
|
6644
|
+
* is made from user/system settings alone, before the workspace merge) are
|
|
6645
|
+
* written in both scopes, with a note in project scope and an announcement of
|
|
6646
|
+
* any global change. Every other key is honored in either scope, so a write that
|
|
6647
|
+
* changes what the file said is reported in either scope, naming what that key
|
|
6648
|
+
* decides there — the autonomy and containment
|
|
6649
|
+
* controls (`approvalMode`, `autoAccept`, `sandbox`, `sandboxImage`), the
|
|
6650
|
+
* registry controls (`disabled`, `visible`, `listDirectory`), the Auto Mode
|
|
6651
|
+
* classifier config, and, because these groups are loose objects, any key
|
|
6652
|
+
* rulesync does not model. Import flags a scope-dependent key only when it read
|
|
6653
|
+
* the project file, since that is the value a `--global` regenerate would
|
|
6654
|
+
* promote. It also
|
|
6640
6655
|
* exposes `permissions.autoMode` (the Auto Mode classifier config:
|
|
6641
6656
|
* `hints.{allow,softDeny,hardDeny}`, `environment`, `classifyAllShell` — see
|
|
6642
6657
|
* https://qwenlm.github.io/qwen-code-docs/en/users/features/auto-mode/), which
|
|
@@ -22787,8 +22802,10 @@ function definitionsToHermesEntries({ event, sourceEvent = event, definitions, l
|
|
|
22787
22802
|
for (const definition of definitions) {
|
|
22788
22803
|
if ((definition.type ?? "command") !== "command" || typeof definition.command !== "string" || definition.command === "") continue;
|
|
22789
22804
|
const entry = { command: definition.command };
|
|
22790
|
-
if (typeof definition.matcher === "string" && definition.matcher !== "")
|
|
22791
|
-
|
|
22805
|
+
if (typeof definition.matcher === "string" && definition.matcher !== "") {
|
|
22806
|
+
if (supportsMatcher) entry.matcher = definition.matcher;
|
|
22807
|
+
else logger?.warn(`matcher "${definition.matcher}" on "${sourceEvent}" hook will be ignored — Hermes Agent only supports matchers on pre_tool_call/post_tool_call`);
|
|
22808
|
+
}
|
|
22792
22809
|
if (typeof definition.timeout === "number") entry.timeout = definition.timeout;
|
|
22793
22810
|
if (typeof definition.failClosed === "boolean") {
|
|
22794
22811
|
if (event === HERMESAGENT_FAIL_CLOSED_EVENT) entry.fail_closed = definition.failClosed;
|
|
@@ -24016,8 +24033,10 @@ function canonicalToKiroHooks({ config, logger }) {
|
|
|
24016
24033
|
key: eventName
|
|
24017
24034
|
}) ?? eventName;
|
|
24018
24035
|
const entries = buildKiroEntriesForEvent(definitions);
|
|
24019
|
-
if (entries.length > 0)
|
|
24020
|
-
|
|
24036
|
+
if (entries.length > 0) {
|
|
24037
|
+
if (kiro[kiroEventName]) kiro[kiroEventName].push(...entries);
|
|
24038
|
+
else kiro[kiroEventName] = entries;
|
|
24039
|
+
}
|
|
24021
24040
|
}
|
|
24022
24041
|
return kiro;
|
|
24023
24042
|
}
|
|
@@ -24843,8 +24862,10 @@ function canonicalToReasonixHooks({ config, toolOverrideHooks, logger }) {
|
|
|
24843
24862
|
if ((def.type ?? "command") !== "command") continue;
|
|
24844
24863
|
if (typeof def.command !== "string") continue;
|
|
24845
24864
|
const entry = { command: def.command };
|
|
24846
|
-
if (typeof def.matcher === "string" && def.matcher !== "")
|
|
24847
|
-
|
|
24865
|
+
if (typeof def.matcher === "string" && def.matcher !== "") {
|
|
24866
|
+
if (isMatcherEvent) entry.match = def.matcher;
|
|
24867
|
+
else logger?.warn(`matcher "${def.matcher}" on "${event}" hook will be ignored — Reasonix's "${reasonixEvent}" event does not support matchers`);
|
|
24868
|
+
}
|
|
24848
24869
|
if (typeof def.description === "string" && def.description !== "") entry.description = def.description;
|
|
24849
24870
|
if (typeof def.timeout === "number") entry.timeout = Math.round(def.timeout * 1e3);
|
|
24850
24871
|
entries.push(entry);
|
|
@@ -28412,12 +28433,16 @@ function convertFromCodexFormat(codexMcp) {
|
|
|
28412
28433
|
} else if (key === "oauth" && isRecord$1(value)) converted[key] = mapOauthFromCodex(value);
|
|
28413
28434
|
else if (Object.hasOwn(CODEX_TO_RULESYNC_FIELD_MAP, key)) {
|
|
28414
28435
|
const mappedKey = CODEX_TO_RULESYNC_FIELD_MAP[key];
|
|
28415
|
-
if (mappedKey)
|
|
28416
|
-
|
|
28436
|
+
if (mappedKey) {
|
|
28437
|
+
if (isValidRenamedArray(key, value)) converted[mappedKey] = value;
|
|
28438
|
+
else warnWithFallback(void 0, `Ignored malformed array for ${key} in MCP server ${name}`);
|
|
28439
|
+
}
|
|
28417
28440
|
} else if (Object.hasOwn(CODEX_TO_RULESYNC_SCALAR_FIELD_MAP, key)) {
|
|
28418
28441
|
const mappedKey = CODEX_TO_RULESYNC_SCALAR_FIELD_MAP[key];
|
|
28419
|
-
if (mappedKey)
|
|
28420
|
-
|
|
28442
|
+
if (mappedKey) {
|
|
28443
|
+
if (typeof value === "string") converted[mappedKey] = value;
|
|
28444
|
+
else warnWithFallback(void 0, `Ignored malformed value for ${key} in MCP server ${name}: expected a string`);
|
|
28445
|
+
}
|
|
28421
28446
|
} else converted[key] = value;
|
|
28422
28447
|
}
|
|
28423
28448
|
restateCanonicalTransport(converted);
|
|
@@ -28449,12 +28474,16 @@ function convertToCodexFormat(mcpServers) {
|
|
|
28449
28474
|
} else if (key === "oauth" && isRecord$1(value)) converted[key] = mapOauthToCodex(value);
|
|
28450
28475
|
else if (Object.hasOwn(RULESYNC_TO_CODEX_FIELD_MAP, key)) {
|
|
28451
28476
|
const mappedKey = RULESYNC_TO_CODEX_FIELD_MAP[key];
|
|
28452
|
-
if (mappedKey)
|
|
28453
|
-
|
|
28477
|
+
if (mappedKey) {
|
|
28478
|
+
if (isValidRenamedArray(key, value)) converted[mappedKey] = value;
|
|
28479
|
+
else warnWithFallback(void 0, `[CodexCliMcp] Skipping invalid value type for mapped key '${key}': expected string array, got ${typeof value}`);
|
|
28480
|
+
}
|
|
28454
28481
|
} else if (Object.hasOwn(RULESYNC_TO_CODEX_SCALAR_FIELD_MAP, key)) {
|
|
28455
28482
|
const mappedKey = RULESYNC_TO_CODEX_SCALAR_FIELD_MAP[key];
|
|
28456
|
-
if (mappedKey)
|
|
28457
|
-
|
|
28483
|
+
if (mappedKey) {
|
|
28484
|
+
if (typeof value === "string") converted[mappedKey] = value;
|
|
28485
|
+
else warnWithFallback(void 0, `[CodexCliMcp] Skipping invalid value type for mapped key '${key}': expected string, got ${typeof value}`);
|
|
28486
|
+
}
|
|
28458
28487
|
} else converted[key] = value;
|
|
28459
28488
|
}
|
|
28460
28489
|
const previousName = originalNames.get(codexName);
|
|
@@ -28698,8 +28727,10 @@ function resolveRemoteMcpUrl(serverConfig) {
|
|
|
28698
28727
|
/** The `command` array a `local` server is spawned with, `args` merged in. */
|
|
28699
28728
|
function resolveLocalMcpCommand(serverConfig) {
|
|
28700
28729
|
const commandArray = [];
|
|
28701
|
-
if (serverConfig.command)
|
|
28702
|
-
|
|
28730
|
+
if (serverConfig.command) {
|
|
28731
|
+
if (Array.isArray(serverConfig.command)) commandArray.push(...serverConfig.command);
|
|
28732
|
+
else commandArray.push(serverConfig.command);
|
|
28733
|
+
}
|
|
28703
28734
|
if (serverConfig.args) commandArray.push(...serverConfig.args);
|
|
28704
28735
|
return commandArray;
|
|
28705
28736
|
}
|
|
@@ -29236,8 +29267,10 @@ function toDeepagentsServer({ name, server, logger }) {
|
|
|
29236
29267
|
const { enabledTools, disabledTools, type: _type, transport, ...rest } = server;
|
|
29237
29268
|
const converted = { ...rest };
|
|
29238
29269
|
const normalized = normalizeDeepagentsTransport(rawTransport);
|
|
29239
|
-
if (normalized !== void 0)
|
|
29240
|
-
|
|
29270
|
+
if (normalized !== void 0) {
|
|
29271
|
+
if (transport !== void 0) converted.transport = normalized;
|
|
29272
|
+
else converted.type = normalized;
|
|
29273
|
+
}
|
|
29241
29274
|
if (enabledTools !== void 0 && disabledTools !== void 0) return warnAndSkipMcpServer({
|
|
29242
29275
|
toolName: TOOL_NAME,
|
|
29243
29276
|
serverName: name,
|
|
@@ -29252,8 +29285,10 @@ function toDeepagentsServer({ name, server, logger }) {
|
|
|
29252
29285
|
logger
|
|
29253
29286
|
});
|
|
29254
29287
|
converted.allowedTools = enabledTools;
|
|
29255
|
-
} else if (disabledTools !== void 0)
|
|
29256
|
-
|
|
29288
|
+
} else if (disabledTools !== void 0) {
|
|
29289
|
+
if (disabledTools.length === 0) logger?.warn(`${TOOL_NAME} MCP: dropping the empty disabledTools list on "${name}"; it denies nothing, and deepagents rejects the empty form.`);
|
|
29290
|
+
else converted.disabledTools = disabledTools;
|
|
29291
|
+
}
|
|
29257
29292
|
return converted;
|
|
29258
29293
|
}
|
|
29259
29294
|
/** Lift dcode's spellings back into the canonical model. */
|
|
@@ -32190,14 +32225,16 @@ function rulesyncMcpServerToReasonix(name, server, logger) {
|
|
|
32190
32225
|
name,
|
|
32191
32226
|
...type !== void 0 && { type }
|
|
32192
32227
|
};
|
|
32193
|
-
if (server.command !== void 0)
|
|
32194
|
-
|
|
32195
|
-
|
|
32196
|
-
|
|
32197
|
-
|
|
32198
|
-
|
|
32199
|
-
|
|
32200
|
-
|
|
32228
|
+
if (server.command !== void 0) {
|
|
32229
|
+
if (Array.isArray(server.command)) {
|
|
32230
|
+
const [command, ...commandArgs] = server.command;
|
|
32231
|
+
if (command !== void 0) plugin.command = command;
|
|
32232
|
+
const args = [...commandArgs, ...server.args ?? []];
|
|
32233
|
+
if (args.length > 0) plugin.args = args;
|
|
32234
|
+
} else {
|
|
32235
|
+
plugin.command = server.command;
|
|
32236
|
+
if (server.args !== void 0) plugin.args = server.args;
|
|
32237
|
+
}
|
|
32201
32238
|
}
|
|
32202
32239
|
for (const field of REASONIX_PLUGIN_FIELDS) {
|
|
32203
32240
|
if (field === "type" || field === "command" || field === "args") continue;
|
|
@@ -33265,14 +33302,16 @@ function rulesyncMcpServerToVibe(name, server, existing) {
|
|
|
33265
33302
|
name,
|
|
33266
33303
|
...transport !== void 0 && { transport }
|
|
33267
33304
|
};
|
|
33268
|
-
if (server.command !== void 0)
|
|
33269
|
-
|
|
33270
|
-
|
|
33271
|
-
|
|
33272
|
-
|
|
33273
|
-
|
|
33274
|
-
|
|
33275
|
-
|
|
33305
|
+
if (server.command !== void 0) {
|
|
33306
|
+
if (Array.isArray(server.command)) {
|
|
33307
|
+
const [command, ...commandArgs] = server.command;
|
|
33308
|
+
if (command !== void 0) vibeServer.command = command;
|
|
33309
|
+
const args = [...commandArgs, ...server.args ?? []];
|
|
33310
|
+
if (args.length > 0) vibeServer.args = args;
|
|
33311
|
+
} else {
|
|
33312
|
+
vibeServer.command = server.command;
|
|
33313
|
+
if (server.args !== void 0) vibeServer.args = server.args;
|
|
33314
|
+
}
|
|
33276
33315
|
}
|
|
33277
33316
|
const hasStructuredAuth = serverRecord.auth !== void 0;
|
|
33278
33317
|
for (const field of VIBE_MCP_SERVER_FIELDS) {
|
|
@@ -42479,15 +42518,129 @@ const QWEN_OVERRIDE_TOOLS_KEYS = [
|
|
|
42479
42518
|
"sandbox",
|
|
42480
42519
|
"sandboxImage",
|
|
42481
42520
|
"disabled",
|
|
42482
|
-
"visible"
|
|
42521
|
+
"visible",
|
|
42522
|
+
"listDirectory",
|
|
42523
|
+
"workflowsEnabled"
|
|
42483
42524
|
];
|
|
42484
42525
|
const QWEN_OVERRIDE_SECURITY_KEYS = [
|
|
42485
42526
|
"folderTrust",
|
|
42486
42527
|
"allowedHttpHookUrls",
|
|
42487
|
-
"allowPrivateNetworkHooks"
|
|
42528
|
+
"allowPrivateNetworkHooks",
|
|
42529
|
+
"allowedInsecureVoiceBaseUrls"
|
|
42488
42530
|
];
|
|
42489
|
-
|
|
42531
|
+
/**
|
|
42532
|
+
* What each rule means for the two directions, so a key's behavior is declared
|
|
42533
|
+
* once beside its rule rather than spelled out at every branch.
|
|
42534
|
+
*
|
|
42535
|
+
* `stripInProjectScope` separates the keys a project file cannot use at all from
|
|
42536
|
+
* the ones whose project value still does something, just not unconditionally —
|
|
42537
|
+
* only the former are dropped. `announceOnlyGrants` marks the rule whose risk is
|
|
42538
|
+
* a value that turns something on; for the others the dangerous value is often
|
|
42539
|
+
* the falsy one (an empty allow-all list, folder trust switched off, a sandbox
|
|
42540
|
+
* turned off), so every change is announced instead. `announceOnImport` marks
|
|
42541
|
+
* the keys whose meaning depends on the scope they are written in — importing
|
|
42542
|
+
* one and regenerating globally turns a value a workspace could not decide for
|
|
42543
|
+
* itself into one Qwen Code enforces everywhere. `global-machine-wide` keys are
|
|
42544
|
+
* honored identically in either scope, so import neither promotes nor weakens
|
|
42545
|
+
* them and the announcement on the generate side is the control point.
|
|
42546
|
+
* `projectNote` is `null` for a rule that has nothing to say about the project
|
|
42547
|
+
* scope. A `globalNote` here is the rule's default; a key whose meaning the
|
|
42548
|
+
* default does not describe carries its own.
|
|
42549
|
+
*/
|
|
42550
|
+
const QWEN_SCOPE_RULES = {
|
|
42551
|
+
"workspace-stripped": {
|
|
42552
|
+
stripInProjectScope: true,
|
|
42553
|
+
announceOnlyGrants: true,
|
|
42554
|
+
announceOnImport: true,
|
|
42555
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} is only honored in user/system settings, so it is skipped for the project-scoped ${filePath} (a value already in that file is left as it is). Check it if the override arrived with a repository you cloned, and author it in the global scope only if that is a value you want every project on this machine to run under.`,
|
|
42556
|
+
globalNote: "Qwen Code ignores this key in workspace settings so a repository cannot grant it per project; in the global scope it applies to every project on this machine."
|
|
42557
|
+
},
|
|
42558
|
+
"workspace-non-overriding": {
|
|
42559
|
+
stripInProjectScope: false,
|
|
42560
|
+
announceOnlyGrants: false,
|
|
42561
|
+
announceOnImport: true,
|
|
42562
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}, but Qwen Code honors a workspace value for it only while no user, system, or system-defaults scope sets the key — a repository cannot replace the list a user configured in a higher scope. It does replace one written by hand in this same file, and an empty list is Qwen Code's allow-all, so check what it now says. Author it in the global scope if it has to apply unconditionally.`,
|
|
42563
|
+
globalNote: "A global value outranks every repository's own list for this key, and an empty list means allow-all, so this decides where HTTP hooks may send data for every project on this machine."
|
|
42564
|
+
},
|
|
42565
|
+
"user-scope-trust-check": {
|
|
42566
|
+
stripInProjectScope: false,
|
|
42567
|
+
announceOnlyGrants: false,
|
|
42568
|
+
announceOnImport: true,
|
|
42569
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}, but Qwen Code makes the initial trust decision from user and system settings alone, before a workspace file is merged, so a project value cannot decide whether this workspace is trusted (it still drives folder trust once the workspace is trusted). Check it if the override arrived with a repository you cloned, and author it in the global scope only if that is a value you want every project on this machine to run under.`,
|
|
42570
|
+
globalNote: "Qwen Code reads this key from the global scope when it decides whether a workspace is trusted, so this changes which projects on this machine it trusts."
|
|
42571
|
+
},
|
|
42572
|
+
"global-machine-wide": {
|
|
42573
|
+
stripInProjectScope: false,
|
|
42574
|
+
announceOnlyGrants: false,
|
|
42575
|
+
announceOnImport: false,
|
|
42576
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}. Qwen Code honors this key in a workspace file, so it takes effect while you work in this repository. Check it if the override arrived with a repository you cloned.`,
|
|
42577
|
+
globalNote: "Qwen Code honors this key wherever it is written, so in the global scope it settles how much the agent may do unattended — how far approvals are skipped, and whether tool calls are contained at all — for every project on this machine."
|
|
42578
|
+
},
|
|
42579
|
+
unmodeled: {
|
|
42580
|
+
stripInProjectScope: false,
|
|
42581
|
+
announceOnlyGrants: false,
|
|
42582
|
+
announceOnImport: false,
|
|
42583
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}. This is not a key rulesync models, so it cannot say what Qwen Code does with it — and some settings in these groups are potent (\`tools.discoveryCommand\` and \`tools.callCommand\` are spawned as commands when Qwen Code starts). Check it if the override arrived with a repository you cloned.`,
|
|
42584
|
+
globalNote: "This is not a key rulesync models, so it cannot say what Qwen Code does with it — and some settings in these groups are potent (`tools.discoveryCommand` and `tools.callCommand` are spawned as commands when Qwen Code starts). Check what it now says for every project on this machine."
|
|
42585
|
+
}
|
|
42586
|
+
};
|
|
42587
|
+
const QWEN_OVERRIDE_GROUPS = [{
|
|
42588
|
+
groupName: "tools",
|
|
42589
|
+
overrideKeys: QWEN_OVERRIDE_TOOLS_KEYS,
|
|
42590
|
+
scopedKeys: {
|
|
42591
|
+
workflowsEnabled: { rule: "workspace-stripped" },
|
|
42592
|
+
approvalMode: {
|
|
42593
|
+
rule: "global-machine-wide",
|
|
42594
|
+
projectNote: autonomyProjectNote
|
|
42595
|
+
},
|
|
42596
|
+
autoAccept: {
|
|
42597
|
+
rule: "global-machine-wide",
|
|
42598
|
+
projectNote: autonomyProjectNote
|
|
42599
|
+
},
|
|
42600
|
+
sandbox: {
|
|
42601
|
+
rule: "global-machine-wide",
|
|
42602
|
+
projectNote: autonomyProjectNote
|
|
42603
|
+
},
|
|
42604
|
+
sandboxImage: {
|
|
42605
|
+
rule: "global-machine-wide",
|
|
42606
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}, so a sandboxed run in this repository executes inside the named image — check that it is one you trust to run your code.`,
|
|
42607
|
+
globalNote: "Qwen Code honors this key wherever it is written, so in the global scope every sandboxed run on this machine executes inside the named image — check that it is one you trust to run your code."
|
|
42608
|
+
},
|
|
42609
|
+
disabled: {
|
|
42610
|
+
rule: "global-machine-wide",
|
|
42611
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}, replacing the list in that file rather than adding to it, so a name that is gone is a tool the model can call again in this repository unless another scope still disables it.`,
|
|
42612
|
+
globalNote: "Qwen Code honors this key wherever it is written, and the override replaces the list in this file rather than adding to it, so in the global scope this decides which tools stay out of the registry for every project on this machine — dropping a name hands that tool back to the model unless another scope still disables it."
|
|
42613
|
+
},
|
|
42614
|
+
visible: {
|
|
42615
|
+
rule: "global-machine-wide",
|
|
42616
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}, so it decides which deferred tools are visible at startup in this repository.`,
|
|
42617
|
+
globalNote: "Qwen Code honors this key wherever it is written, so in the global scope this decides which deferred tools are visible at startup for every project on this machine."
|
|
42618
|
+
},
|
|
42619
|
+
listDirectory: {
|
|
42620
|
+
rule: "global-machine-wide",
|
|
42621
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}, so it decides whether the built-in \`list_directory\` tool is registered in this repository.`,
|
|
42622
|
+
globalNote: "Qwen Code honors this key wherever it is written, so in the global scope this decides whether the built-in `list_directory` tool is registered for every project on this machine."
|
|
42623
|
+
}
|
|
42624
|
+
}
|
|
42625
|
+
}, {
|
|
42626
|
+
groupName: "security",
|
|
42627
|
+
overrideKeys: QWEN_OVERRIDE_SECURITY_KEYS,
|
|
42628
|
+
scopedKeys: {
|
|
42629
|
+
allowPrivateNetworkHooks: { rule: "workspace-stripped" },
|
|
42630
|
+
allowedInsecureVoiceBaseUrls: {
|
|
42631
|
+
rule: "workspace-stripped",
|
|
42632
|
+
grants: isNonEmptyArray
|
|
42633
|
+
},
|
|
42634
|
+
allowedHttpHookUrls: { rule: "workspace-non-overriding" },
|
|
42635
|
+
folderTrust: { rule: "user-scope-trust-check" }
|
|
42636
|
+
}
|
|
42637
|
+
}];
|
|
42490
42638
|
const QWEN_OVERRIDE_PERMISSIONS_KEYS = ["autoMode"];
|
|
42639
|
+
const QWEN_SCOPED_PERMISSIONS_KEYS = { autoMode: {
|
|
42640
|
+
rule: "global-machine-wide",
|
|
42641
|
+
projectNote: ({ qualifiedKey, quotedValue, filePath }) => `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}, replacing the whole block rather than merging into it, so it rewrites the instructions Auto Mode's classifier follows in this repository — including any deny hint you had configured.`,
|
|
42642
|
+
globalNote: "Qwen Code honors this key wherever it is written, and the override replaces the whole block rather than merging into it, so in the global scope this rewrites the instructions Auto Mode's classifier follows — including any deny hint you had configured — for every project on this machine."
|
|
42643
|
+
} };
|
|
42491
42644
|
function asPlainRecord(value) {
|
|
42492
42645
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
42493
42646
|
}
|
|
@@ -42499,20 +42652,172 @@ function pickQwenOverrideKeys(group, keys) {
|
|
|
42499
42652
|
return picked;
|
|
42500
42653
|
}
|
|
42501
42654
|
/**
|
|
42502
|
-
*
|
|
42503
|
-
*
|
|
42504
|
-
*
|
|
42655
|
+
* Whether a value written for a scoped key actually grants something. Qwen Code
|
|
42656
|
+
* reads the boolean ones with a plain truthiness check, so anything truthy turns
|
|
42657
|
+
* the capability on — `1` and the string `"false"` included, which is why this is
|
|
42658
|
+
* not a `=== true` test. Not all of them are booleans either:
|
|
42659
|
+
* `security.allowedInsecureVoiceBaseUrls` is a list of base URLs, and an empty
|
|
42660
|
+
* list grants nothing.
|
|
42661
|
+
*
|
|
42662
|
+
* Only the rules whose `announceOnlyGrants` is set consult this, because "empty"
|
|
42663
|
+
* does not mean the same thing for every list: an empty
|
|
42664
|
+
* `security.allowedHttpHookUrls` is Qwen Code's allow-all, the widest value there
|
|
42665
|
+
* is, so that key is announced whatever it says.
|
|
42666
|
+
*/
|
|
42667
|
+
function isNonEmptyArray(value) {
|
|
42668
|
+
return Array.isArray(value) && value.length > 0;
|
|
42669
|
+
}
|
|
42670
|
+
/**
|
|
42671
|
+
* Whether a value turns something on, read the way Qwen Code reads it.
|
|
42672
|
+
*
|
|
42673
|
+
* Plain truthiness by default, because that is what Qwen Code applies to these
|
|
42674
|
+
* settings: `1` and the string `"false"` enable them, and so does an empty array
|
|
42675
|
+
* — which is why an empty list cannot be treated as harmless everywhere. A key
|
|
42676
|
+
* whose list Qwen Code matches against, rather than tests for truth, carries its
|
|
42677
|
+
* own `grants` instead.
|
|
42678
|
+
*/
|
|
42679
|
+
function grantsSomething(value, scopedKey) {
|
|
42680
|
+
return (scopedKey?.grants ?? Boolean)(value);
|
|
42681
|
+
}
|
|
42682
|
+
/**
|
|
42683
|
+
* The autonomy and containment controls say the same thing in project scope, so
|
|
42684
|
+
* they share one note rather than repeating it three times.
|
|
42685
|
+
*/
|
|
42686
|
+
function autonomyProjectNote({ qualifiedKey, quotedValue, filePath }) {
|
|
42687
|
+
return `${qualifiedKey} = ${quotedValue} was written to the project-scoped ${filePath}. Qwen Code honors this key in a workspace file, so it settles how far approvals are skipped and whether tool calls are contained while you work in this repository. Check it if the override arrived with a repository you cloned.`;
|
|
42688
|
+
}
|
|
42689
|
+
/**
|
|
42690
|
+
* Quote a `group.key` pair for a warning. The key goes through the same quoting
|
|
42691
|
+
* a value does, because it is one: the override's groups are `z.looseObject`s,
|
|
42692
|
+
* so a key the scope gate names may have been written by whoever authored the
|
|
42693
|
+
* `.rulesync/permissions.jsonc` rather than chosen from a list rulesync knows.
|
|
42694
|
+
* Serializing it — rather than wrapping it in quotes of our own — is what keeps
|
|
42695
|
+
* a key that contains a quote from closing it and continuing the sentence.
|
|
42696
|
+
*/
|
|
42697
|
+
function quoteQualifiedKey({ groupName, key }) {
|
|
42698
|
+
return quoteValueForWarning(`${groupName}.${key}`);
|
|
42699
|
+
}
|
|
42700
|
+
/**
|
|
42701
|
+
* Compare two settings values without letting key order decide the answer, so
|
|
42702
|
+
* re-emitting `{ enabled: true, note: "x" }` as `{ note: "x", enabled: true }`
|
|
42703
|
+
* is not announced as a change.
|
|
42505
42704
|
*/
|
|
42506
|
-
function
|
|
42507
|
-
|
|
42508
|
-
|
|
42509
|
-
|
|
42510
|
-
|
|
42511
|
-
|
|
42512
|
-
|
|
42705
|
+
function stableStringify(value) {
|
|
42706
|
+
return JSON.stringify(value, (_key, nested) => nested !== null && typeof nested === "object" && !Array.isArray(nested) ? Object.fromEntries(Object.entries(nested).toSorted(([left], [right]) => left.localeCompare(right))) : nested) ?? "undefined";
|
|
42707
|
+
}
|
|
42708
|
+
function sameSettingsValue(a, b) {
|
|
42709
|
+
return stableStringify(a) === stableStringify(b);
|
|
42710
|
+
}
|
|
42711
|
+
/**
|
|
42712
|
+
* Apply the scope rules for a settings group's scoped keys.
|
|
42713
|
+
*
|
|
42714
|
+
* Generating project settings drops the keys Qwen Code strips from a workspace
|
|
42715
|
+
* file before the merge — writing one there would be dead configuration — and
|
|
42716
|
+
* explains the keys whose project value is honored only conditionally rather
|
|
42717
|
+
* than dropping those. Either way only the override copy is touched, so a value
|
|
42718
|
+
* the user already wrote into the project file stays where it is.
|
|
42719
|
+
*
|
|
42720
|
+
* Generating global settings keeps every key, and announces the write: the
|
|
42721
|
+
* `.rulesync/permissions.jsonc` carrying it may have arrived with a cloned or
|
|
42722
|
+
* fetched repository, and the global file applies to every project on this
|
|
42723
|
+
* machine. So the new value is named alongside the one it replaces, exactly as
|
|
42724
|
+
* the deepagents startup override announces its own relaxations. Every key the
|
|
42725
|
+
* override writes is announced, not only the ones with a scope rule — the
|
|
42726
|
+
* groups are `z.looseObject`s, so an unmodeled key falls back to the
|
|
42727
|
+
* `unmodeled` rule rather than slipping past the gate that the modeled ones
|
|
42728
|
+
* pass through.
|
|
42729
|
+
*/
|
|
42730
|
+
function scopeOverrideGroup(overrideGroup, { groupName, scopedKeys, existingGroup, global, filePath, logger }) {
|
|
42731
|
+
const scoped = { ...asPlainRecord(overrideGroup) };
|
|
42732
|
+
const previous = asPlainRecord(existingGroup);
|
|
42733
|
+
const rulesByKey = new Map(Object.entries(scopedKeys));
|
|
42734
|
+
for (const key of Object.keys(scoped)) {
|
|
42735
|
+
const value = scoped[key];
|
|
42736
|
+
if (value === void 0) continue;
|
|
42737
|
+
const scopedKey = rulesByKey.get(key);
|
|
42738
|
+
const rule = scopedKey?.rule ?? "unmodeled";
|
|
42739
|
+
const { stripInProjectScope, announceOnlyGrants } = QWEN_SCOPE_RULES[rule];
|
|
42740
|
+
const projectNote = scopedKey?.projectNote ?? QWEN_SCOPE_RULES[rule].projectNote;
|
|
42741
|
+
const globalNote = scopedKey?.globalNote ?? QWEN_SCOPE_RULES[rule].globalNote;
|
|
42742
|
+
const previousValue = Object.hasOwn(previous, key) ? previous[key] : void 0;
|
|
42743
|
+
const unchanged = sameSettingsValue(previousValue, value);
|
|
42744
|
+
if (!global) {
|
|
42745
|
+
if (stripInProjectScope) delete scoped[key];
|
|
42746
|
+
else if (unchanged) continue;
|
|
42747
|
+
if (projectNote) warnWithFallback(logger, `Qwen permissions: ${projectNote({
|
|
42748
|
+
qualifiedKey: quoteQualifiedKey({
|
|
42749
|
+
groupName,
|
|
42750
|
+
key
|
|
42751
|
+
}),
|
|
42752
|
+
quotedValue: quoteValueForWarning(value),
|
|
42753
|
+
filePath
|
|
42754
|
+
})}`);
|
|
42755
|
+
continue;
|
|
42756
|
+
}
|
|
42757
|
+
if (unchanged) continue;
|
|
42758
|
+
if (announceOnlyGrants && !grantsSomething(value, scopedKey)) continue;
|
|
42759
|
+
const replaced = previousValue === void 0 ? "" : ` (was ${quoteValueForWarning(previousValue)})`;
|
|
42760
|
+
warnWithFallback(logger, `Qwen permissions: the qwencode override wrote ${quoteQualifiedKey({
|
|
42761
|
+
groupName,
|
|
42762
|
+
key
|
|
42763
|
+
})} = ${quoteValueForWarning(value)}${replaced} into ${filePath}, your global Qwen Code settings. ${globalNote}`);
|
|
42513
42764
|
}
|
|
42514
42765
|
return scoped;
|
|
42515
42766
|
}
|
|
42767
|
+
/**
|
|
42768
|
+
* Build the `tools`/`security` patch groups contributed by the `qwencode`
|
|
42769
|
+
* override. Each group is shallow-merged over what `settings.json` already has,
|
|
42770
|
+
* after the scope gate has handled the keys Qwen Code honors in one scope only.
|
|
42771
|
+
*/
|
|
42772
|
+
function buildOverrideGroupsPatch({ settings, override, global, filePath, logger }) {
|
|
42773
|
+
const patch = {};
|
|
42774
|
+
for (const { groupName, scopedKeys } of QWEN_OVERRIDE_GROUPS) {
|
|
42775
|
+
const overrideGroup = override?.[groupName];
|
|
42776
|
+
if (overrideGroup === void 0) continue;
|
|
42777
|
+
const existingGroup = settings[groupName];
|
|
42778
|
+
const scoped = scopeOverrideGroup(overrideGroup, {
|
|
42779
|
+
groupName,
|
|
42780
|
+
scopedKeys,
|
|
42781
|
+
existingGroup,
|
|
42782
|
+
global,
|
|
42783
|
+
filePath,
|
|
42784
|
+
logger
|
|
42785
|
+
});
|
|
42786
|
+
const merged = {
|
|
42787
|
+
...asPlainRecord(existingGroup),
|
|
42788
|
+
...scoped
|
|
42789
|
+
};
|
|
42790
|
+
if (Object.keys(merged).length > 0) patch[groupName] = merged;
|
|
42791
|
+
}
|
|
42792
|
+
return patch;
|
|
42793
|
+
}
|
|
42794
|
+
/**
|
|
42795
|
+
* Warn about a scoped key lifted out of a *project* settings file being
|
|
42796
|
+
* imported. The file carries no scope marker, so import keeps the key either
|
|
42797
|
+
* way — but regenerating in the global scope would turn a value a workspace
|
|
42798
|
+
* could not decide for itself into one Qwen Code enforces everywhere, and a
|
|
42799
|
+
* settings file read out of a cloned repository is exactly where such a value
|
|
42800
|
+
* comes from. Importing the global file is the case this has nothing to say
|
|
42801
|
+
* about: the value is already in the scope the warning would send it to.
|
|
42802
|
+
*/
|
|
42803
|
+
function warnAboutImportedScopedKeys(groups) {
|
|
42804
|
+
for (const { groupName, scopedKeys } of QWEN_OVERRIDE_GROUPS) {
|
|
42805
|
+
const group = groups[groupName];
|
|
42806
|
+
for (const [key, scopedKey] of Object.entries(scopedKeys)) {
|
|
42807
|
+
const { rule } = scopedKey;
|
|
42808
|
+
const value = group[key];
|
|
42809
|
+
if (value === void 0) continue;
|
|
42810
|
+
const { announceOnlyGrants, announceOnImport } = QWEN_SCOPE_RULES[rule];
|
|
42811
|
+
if (!announceOnImport) continue;
|
|
42812
|
+
if (announceOnlyGrants && !grantsSomething(value, scopedKey)) continue;
|
|
42813
|
+
const globalNote = scopedKey.globalNote ?? QWEN_SCOPE_RULES[rule].globalNote;
|
|
42814
|
+
moduleLogger$1.warn(`Qwen permissions: imported ${quoteQualifiedKey({
|
|
42815
|
+
groupName,
|
|
42816
|
+
key
|
|
42817
|
+
})} = ${quoteValueForWarning(value)}. ${globalNote} Review it before generating with the global scope.`);
|
|
42818
|
+
}
|
|
42819
|
+
}
|
|
42820
|
+
}
|
|
42516
42821
|
var QwencodePermissions = class QwencodePermissions extends ToolPermissions {
|
|
42517
42822
|
constructor(params) {
|
|
42518
42823
|
super({
|
|
@@ -42541,7 +42846,8 @@ var QwencodePermissions = class QwencodePermissions extends ToolPermissions {
|
|
|
42541
42846
|
relativeDirPath: paths.relativeDirPath,
|
|
42542
42847
|
relativeFilePath: paths.relativeFilePath,
|
|
42543
42848
|
fileContent,
|
|
42544
|
-
validate
|
|
42849
|
+
validate,
|
|
42850
|
+
global
|
|
42545
42851
|
});
|
|
42546
42852
|
}
|
|
42547
42853
|
static async fromRulesyncPermissions({ outputRoot = process.cwd(), rulesyncPermissions, global = false, logger }) {
|
|
@@ -42557,6 +42863,7 @@ var QwencodePermissions = class QwencodePermissions extends ToolPermissions {
|
|
|
42557
42863
|
} catch (error) {
|
|
42558
42864
|
throw new Error(`Failed to parse existing Qwen settings at ${filePath}: ${formatError(error)}`, { cause: error });
|
|
42559
42865
|
}
|
|
42866
|
+
const displayPath = toPosixPath(join(global ? "~" : ".", paths.relativeDirPath, paths.relativeFilePath));
|
|
42560
42867
|
const config = rulesyncPermissions.getJson();
|
|
42561
42868
|
const { allow, ask, deny } = convertRulesyncToQwenPermissions(config);
|
|
42562
42869
|
const managedToolNames = new Set(Object.keys(config.permission).map((category) => toQwenToolName(category)));
|
|
@@ -42575,24 +42882,25 @@ var QwencodePermissions = class QwencodePermissions extends ToolPermissions {
|
|
|
42575
42882
|
if (mergedDeny.length > 0) mergedPermissions.deny = mergedDeny;
|
|
42576
42883
|
else delete mergedPermissions.deny;
|
|
42577
42884
|
const override = config.qwencode;
|
|
42578
|
-
if (override?.autoMode !== void 0)
|
|
42579
|
-
|
|
42580
|
-
|
|
42581
|
-
|
|
42582
|
-
|
|
42583
|
-
};
|
|
42584
|
-
if (override?.security !== void 0) {
|
|
42585
|
-
const scopedSecurity = scopeOverrideSecurity(override.security, {
|
|
42885
|
+
if (override?.autoMode !== void 0) {
|
|
42886
|
+
const scopedAutoMode = scopeOverrideGroup({ autoMode: override.autoMode }, {
|
|
42887
|
+
groupName: "permissions",
|
|
42888
|
+
scopedKeys: QWEN_SCOPED_PERMISSIONS_KEYS,
|
|
42889
|
+
existingGroup: existingPermissions,
|
|
42586
42890
|
global,
|
|
42587
|
-
|
|
42891
|
+
filePath: displayPath,
|
|
42588
42892
|
logger
|
|
42589
42893
|
});
|
|
42590
|
-
|
|
42591
|
-
...asPlainRecord(settings.security),
|
|
42592
|
-
...scopedSecurity
|
|
42593
|
-
};
|
|
42594
|
-
if (Object.keys(mergedSecurity).length > 0) patch.security = mergedSecurity;
|
|
42894
|
+
if (scopedAutoMode.autoMode !== void 0) mergedPermissions.autoMode = scopedAutoMode.autoMode;
|
|
42595
42895
|
}
|
|
42896
|
+
const patch = { permissions: mergedPermissions };
|
|
42897
|
+
Object.assign(patch, buildOverrideGroupsPatch({
|
|
42898
|
+
settings,
|
|
42899
|
+
override,
|
|
42900
|
+
global,
|
|
42901
|
+
filePath: displayPath,
|
|
42902
|
+
logger
|
|
42903
|
+
}));
|
|
42596
42904
|
const fileContent = applySharedConfigPatch({
|
|
42597
42905
|
fileKey: sharedConfigFileKey(paths),
|
|
42598
42906
|
feature: "permissions",
|
|
@@ -42624,16 +42932,17 @@ var QwencodePermissions = class QwencodePermissions extends ToolPermissions {
|
|
|
42624
42932
|
ask: permissions.ask ?? [],
|
|
42625
42933
|
deny: permissions.deny ?? []
|
|
42626
42934
|
});
|
|
42627
|
-
const
|
|
42628
|
-
|
|
42629
|
-
|
|
42630
|
-
|
|
42631
|
-
|
|
42632
|
-
}
|
|
42935
|
+
const overrideGroups = {
|
|
42936
|
+
tools: pickQwenOverrideKeys(settings.tools, QWEN_OVERRIDE_TOOLS_KEYS),
|
|
42937
|
+
security: pickQwenOverrideKeys(settings.security, QWEN_OVERRIDE_SECURITY_KEYS)
|
|
42938
|
+
};
|
|
42939
|
+
if (!this.global) warnAboutImportedScopedKeys(overrideGroups);
|
|
42633
42940
|
const overridePermissions = pickQwenOverrideKeys(settings.permissions, QWEN_OVERRIDE_PERMISSIONS_KEYS);
|
|
42634
42941
|
const qwencodeOverride = {};
|
|
42635
|
-
|
|
42636
|
-
|
|
42942
|
+
for (const { groupName } of QWEN_OVERRIDE_GROUPS) {
|
|
42943
|
+
const group = overrideGroups[groupName];
|
|
42944
|
+
if (Object.keys(group).length > 0) qwencodeOverride[groupName] = group;
|
|
42945
|
+
}
|
|
42637
42946
|
if (overridePermissions.autoMode !== void 0) qwencodeOverride.autoMode = overridePermissions.autoMode;
|
|
42638
42947
|
const result = { ...config };
|
|
42639
42948
|
if (Object.keys(qwencodeOverride).length > 0) result.qwencode = qwencodeOverride;
|
|
@@ -64900,8 +65209,10 @@ var RooRule = class RooRule extends ToolRule {
|
|
|
64900
65209
|
nonRootPath: this.getSettablePaths().nonRoot
|
|
64901
65210
|
});
|
|
64902
65211
|
const mode = rulesyncRule.getFrontmatter().roo?.mode;
|
|
64903
|
-
if (!params.root && mode !== void 0 && mode !== "")
|
|
64904
|
-
|
|
65212
|
+
if (!params.root && mode !== void 0 && mode !== "") {
|
|
65213
|
+
if (!ROO_MODE_SLUG_PATTERN.test(mode)) warnWithFallback(void 0, `Ignoring roo.mode "${mode}" on ${rulesyncRule.getRelativeFilePath()}: a mode slug may contain only letters, digits and hyphens. Writing the rule to ${params.relativeDirPath} instead.`);
|
|
65214
|
+
else params.relativeDirPath = join(dirname(params.relativeDirPath), rooModeRulesDirName(mode));
|
|
65215
|
+
}
|
|
64905
65216
|
return new RooRule(params);
|
|
64906
65217
|
}
|
|
64907
65218
|
/**
|
|
@@ -69137,4 +69448,4 @@ async function importChecksCore(params) {
|
|
|
69137
69448
|
//#endregion
|
|
69138
69449
|
export { RulesyncCheckFrontmatterSchema as $, ALL_TOOL_TARGETS_WITH_WILDCARD as $t, FACTORYDROID_DIR as A, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as An, fileExists as At, RulesyncSkillFrontmatterSchema as B, stripControlCharacters as Bn, readFileContent as Bt, CODEXCLI_BASH_RULES_FILE_NAME as C, RULESYNC_PERMISSIONS_LEGACY_FILE_NAME as Cn, assertDirectoryIfExists as Ct, CLAUDECODE_MEMORIES_DIR_NAME as D, RULESYNC_RULES_RELATIVE_DIR_PATH as Dn, createTempDirectory as Dt, CLAUDECODE_LOCAL_RULE_FILE_NAME as E, RULESYNC_RELATIVE_DIR_PATH as En, checkPathTraversal as Et, AUGMENTCODE_SETTINGS_LOCAL_FILE_NAME as F, formatError as Fn, isSymlink as Ft, RulesyncIgnore as G, removeFileStrict as Gt, RulesyncRuleFrontmatterSchema as H, stripHiddenCharacters as Hn, removeDirectory as Ht, getLocalSkillDirNames as I, truncateText as In, listDirectoryEntryNames as It, resolveRulesyncSourceWritePath as J, runWithDirectoryRollback as Jt, RulesyncHooks as K, removeTempDirectory as Kt, RulesyncSubagent as L, hasDeceptiveHiddenCharacters as Ln, listFilePathsRecursively as Lt, caseFoldIdentity as M, ALL_FEATURES as Mn, getHomeDirectory as Mt, groupSpellingsByCaseFoldedIdentity as N, ALL_FEATURES_WITH_WILDCARD as Nn, isFileNotFoundError as Nt, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as O, RULESYNC_SKILLS_RELATIVE_DIR_PATH as On, directoryExists as Ot, AUGMENTCODE_DIR as P, DEPRECATED_FEATURE_REPLACEMENTS as Pn, isFileSystemError as Pt, RulesyncCheck as Q, ALL_TOOL_TARGETS as Qt, RulesyncSubagentFrontmatterSchema as R, hasEnclosingMarkOutsideKeycap as Rn, listSubdirectoryNames as Rt, ChecksProcessor as S, RULESYNC_PERMISSIONS_FILE_NAME as Sn, applyFileMode as St, CLAUDECODE_DIR as T, RULESYNC_PERMISSIONS_SCHEMA_URL as Tn, assertWritablePathInsideRoot as Tt, RulesyncPermissions as U, removeDirectoryStrict as Ut, RulesyncRule as V, stripControlCharactersKeepingLineFeeds as Vn, readFileContentOrNull as Vt, RulesyncMcp as W, removeFile as Wt, RulesyncCommand as X, writeFileBuffer as Xt, parseJsonc as Y, toPosixPath as Yt, RulesyncCommandFrontmatterSchema as Z, writeFileContent as Zt, IgnoreProcessor as _, RULESYNC_MCP_FILE_NAME as _n, withFallbackLoggerTarget as _t, getProcessorRegistryEntry as a, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as an, mergeInputRootConfigs as at, QWENCODE_DIR as b, RULESYNC_MCP_SCHEMA_URL as bn, CLIError as bt, RulesProcessor as c, RULESYNC_CONFIG_RELATIVE_FILE_PATH as cn, ConfigFileSchema as ct, CODEBUDDY_DIR as d, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as dn, findControlCharacter as dt, PACKAGING_TOOL_TARGETS as en, stringifyFrontmatter as et, CODEBUDDY_LOCAL_RULE_FILE_NAME as f, RULESYNC_HOOKS_FILE_NAME as fn, ConsoleLogger as ft, McpProcessor as g, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as gn, warnOnConflictingFlags as gt, shortenToWidth as h, RULESYNC_IGNORE_RELATIVE_FILE_PATH as hn, fallbackLogger as ht, inspectInputRoots as i, RULESYNC_AIIGNORE_FILE_NAME as in, ConfigResolver as it, FACTORYDROID_SETTINGS_LOCAL_FILE_NAME as j, parseCommaSeparatedList as jn, getFileSize as jt, CLAUDECODE_SKILLS_DIR_PATH as k, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as kn, ensureDir as kt, SubagentsProcessor as l, RULESYNC_CONFIG_SCHEMA_URL as ln, GITIGNORE_DESTINATION_KEY as lt, displayWidthOf as m, RULESYNC_HOOKS_RELATIVE_FILE_PATH as mn, WarningCollectingLogger as mt, formatSourceLoadFailure as n, CURATED_RULES_FEATURE_SUBDIR as nn, SHARED_USER_MANAGED_CONFIG_PATHS as nt, convertFromTool as o, RULESYNC_CHECKS_RELATIVE_DIR_PATH as on, resolveEffectiveInputRoots as ot, ELLIPSIS_WIDTH as p, RULESYNC_HOOKS_LEGACY_FILE_NAME as pn, JsonLogger as pt, getRulesyncSourceCandidates as q, resolvePath as qt, generate as r, MAX_FILE_SIZE as rn, SKILL_FILE_NAME as rt, isPackagingToolTarget as s, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as sn, CONFLICTING_TARGET_PAIRS as st, importFromTool as t, ToolTargetSchema as tn, loadYaml as tt, SkillsProcessor as u, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as un, SourceEntrySchema as ut, HooksProcessor as v, RULESYNC_MCP_LEGACY_FILE_NAME as vn, resetRunWarningState as vt, CODEXCLI_DIR as w, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as wn, assertTreeContainsNoSymlinks as wt, QWENCODE_LOCAL_RULE_FILE_NAME as x, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as xn, ErrorCodes as xt, CommandsProcessor as y, RULESYNC_MCP_RELATIVE_FILE_PATH as yn, withWarnOnceScope as yt, RulesyncSkill as z, quoteForLog as zn, pathEscapesRoot as zt };
|
|
69139
69450
|
|
|
69140
|
-
//# sourceMappingURL=import-
|
|
69451
|
+
//# sourceMappingURL=import-DL8paEMP.js.map
|