rulesync 37.0.0 → 37.1.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/cli/index.cjs +3 -3
- package/dist/cli/index.js +3 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-BPSwSahy.js → import-BsEFYJsg.js} +461 -32
- package/dist/{import-BPSwSahy.js.map → import-BsEFYJsg.js.map} +1 -1
- package/dist/{import-S70XttcD.cjs → import-DYYG88Rs.cjs} +460 -31
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -7895,14 +7895,53 @@ const COPILOT_DEFAULT_PERMISSION_MODES = [
|
|
|
7895
7895
|
"autoApprove",
|
|
7896
7896
|
"autopilot"
|
|
7897
7897
|
];
|
|
7898
|
+
/** `chat.agent.sandbox.enabled`: `"off"` or `"on"`. */
|
|
7899
|
+
const CopilotSandboxEnabledSchema = z.enum(["off", "on"]);
|
|
7900
|
+
/** `chat.agent.sandbox.fileSystem.userConfiguredPaths`. */
|
|
7901
|
+
const CopilotSandboxUserConfiguredPathsSchema = z.strictObject({
|
|
7902
|
+
readwritePaths: z.optional(z.array(z.string())),
|
|
7903
|
+
readonlyPaths: z.optional(z.array(z.string())),
|
|
7904
|
+
deniedPaths: z.optional(z.array(z.string()))
|
|
7905
|
+
});
|
|
7906
|
+
/**
|
|
7907
|
+
* The Agent Host sandbox settings VS Code 1.141 settled on, as a nested object
|
|
7908
|
+
* whose path mirrors the dotted setting key under `chat.agent.sandbox.` — e.g.
|
|
7909
|
+
* `network.allowNetwork` writes `chat.agent.sandbox.network.allowNetwork`.
|
|
7910
|
+
* Only the documented, registered keys are accepted; the deprecated 1.138
|
|
7911
|
+
* shapes (`chat.agent.sandbox.allowNetwork`, `.fileSystem.linux|mac|windows`)
|
|
7912
|
+
* are not modeled, since the Agent Host ignores them.
|
|
7913
|
+
*
|
|
7914
|
+
* @see https://code.visualstudio.com/docs/agents/run/agent-sandboxing
|
|
7915
|
+
* @see https://code.visualstudio.com/docs/agents/reference/ai-settings
|
|
7916
|
+
*/
|
|
7917
|
+
const CopilotSandboxSchema = z.strictObject({
|
|
7918
|
+
enabled: z.optional(CopilotSandboxEnabledSchema),
|
|
7919
|
+
network: z.optional(z.strictObject({
|
|
7920
|
+
allowNetwork: z.optional(z.boolean()),
|
|
7921
|
+
allowLocalNetwork: z.optional(z.boolean())
|
|
7922
|
+
})),
|
|
7923
|
+
allowUnsandboxedCommands: z.optional(z.boolean()),
|
|
7924
|
+
mcpServers: z.optional(z.boolean()),
|
|
7925
|
+
lspServers: z.optional(z.boolean()),
|
|
7926
|
+
credentials: z.optional(z.strictObject({
|
|
7927
|
+
authenticategit: z.optional(z.boolean()),
|
|
7928
|
+
authenticategh: z.optional(z.boolean())
|
|
7929
|
+
})),
|
|
7930
|
+
fileSystem: z.optional(z.strictObject({
|
|
7931
|
+
allowDevToolAccess: z.optional(z.boolean()),
|
|
7932
|
+
userConfiguredPaths: z.optional(CopilotSandboxUserConfiguredPathsSchema)
|
|
7933
|
+
}))
|
|
7934
|
+
});
|
|
7898
7935
|
/**
|
|
7899
7936
|
* Tool-scoped override block for GitHub Copilot in VS Code.
|
|
7900
7937
|
* `defaultPermissionMode` writes the workspace `chat.permissions.default`
|
|
7901
|
-
* setting,
|
|
7938
|
+
* setting, and `sandbox` writes the `chat.agent.sandbox.*` settings; neither
|
|
7939
|
+
* has a canonical category.
|
|
7902
7940
|
*/
|
|
7903
7941
|
const CopilotPermissionsOverrideSchema = z.looseObject({
|
|
7904
7942
|
permission: z.optional(ToolScopedPermissionSchema),
|
|
7905
|
-
defaultPermissionMode: z.optional(z.enum(COPILOT_DEFAULT_PERMISSION_MODES))
|
|
7943
|
+
defaultPermissionMode: z.optional(z.enum(COPILOT_DEFAULT_PERMISSION_MODES)),
|
|
7944
|
+
sandbox: z.optional(CopilotSandboxSchema)
|
|
7906
7945
|
});
|
|
7907
7946
|
/**
|
|
7908
7947
|
* oh-my-pi's `tools.approvalMode` values: the tool tiers it auto-approves
|
|
@@ -12874,6 +12913,16 @@ const SHARED_CONFIG_OWNERSHIP = {
|
|
|
12874
12913
|
"chat.tools.edits.autoApprove",
|
|
12875
12914
|
"chat.tools.urls.autoApprove",
|
|
12876
12915
|
"chat.permissions.default",
|
|
12916
|
+
"chat.agent.sandbox.enabled",
|
|
12917
|
+
"chat.agent.sandbox.network.allowNetwork",
|
|
12918
|
+
"chat.agent.sandbox.network.allowLocalNetwork",
|
|
12919
|
+
"chat.agent.sandbox.allowUnsandboxedCommands",
|
|
12920
|
+
"chat.agent.sandbox.mcpServers",
|
|
12921
|
+
"chat.agent.sandbox.lspServers",
|
|
12922
|
+
"chat.agent.sandbox.credentials.authenticategit",
|
|
12923
|
+
"chat.agent.sandbox.credentials.authenticategh",
|
|
12924
|
+
"chat.agent.sandbox.fileSystem.allowDevToolAccess",
|
|
12925
|
+
"chat.agent.sandbox.fileSystem.userConfiguredPaths",
|
|
12877
12926
|
"zoo-code.allowedCommands",
|
|
12878
12927
|
"zoo-code.deniedCommands",
|
|
12879
12928
|
"roo-cline.allowedCommands",
|
|
@@ -28036,8 +28085,34 @@ function collectOwnedRefs({ generatedHooks, shape }) {
|
|
|
28036
28085
|
}
|
|
28037
28086
|
return owned;
|
|
28038
28087
|
}
|
|
28088
|
+
/**
|
|
28089
|
+
* The merge keeps every unowned existing handler where it is. Some tools key
|
|
28090
|
+
* state by position — Codex CLI persists a hook's trust review under its event,
|
|
28091
|
+
* matcher group index and handler index — so moving a handler the user already
|
|
28092
|
+
* reviewed would silently change which hook that review belongs to. Hence:
|
|
28093
|
+
* - an unowned existing handler stays at its index;
|
|
28094
|
+
* - a newly generated handler is appended to the first existing group with its
|
|
28095
|
+
* matcher and group-level keys, or in a new group after the existing ones;
|
|
28096
|
+
* - within a group, the slots rulesync's own handlers occupy (including the
|
|
28097
|
+
* appended ones) are filled in generated order, so reordering the sources
|
|
28098
|
+
* still reorders the generated handlers, which matters wherever handlers
|
|
28099
|
+
* run in order (a Qwen Code `sequential` group, a Cursor list).
|
|
28100
|
+
*
|
|
28101
|
+
* A retracted handler, or a group left empty by retractions, is still removed,
|
|
28102
|
+
* which shifts whatever follows it in the same list; that is unavoidable
|
|
28103
|
+
* without leaving a placeholder behind.
|
|
28104
|
+
*/
|
|
28039
28105
|
function mergeMatcherGroups({ existing, generated, event, seen, previouslyOwned, logger }) {
|
|
28040
|
-
const
|
|
28106
|
+
const pending = createPendingGenerated();
|
|
28107
|
+
for (const group of generated) if (isMatcherGroup(group)) addPending({
|
|
28108
|
+
pending,
|
|
28109
|
+
handlers: group.hooks,
|
|
28110
|
+
event,
|
|
28111
|
+
matcher: matcherKey(group.matcher),
|
|
28112
|
+
attributes: groupAttributesKey(group)
|
|
28113
|
+
});
|
|
28114
|
+
const merged = [];
|
|
28115
|
+
const homes = /* @__PURE__ */ new Map();
|
|
28041
28116
|
for (const group of existing) {
|
|
28042
28117
|
if (!isMatcherGroup(group)) {
|
|
28043
28118
|
warnSkip({
|
|
@@ -28048,27 +28123,57 @@ function mergeMatcherGroups({ existing, generated, event, seen, previouslyOwned,
|
|
|
28048
28123
|
continue;
|
|
28049
28124
|
}
|
|
28050
28125
|
const matcher = matcherKey(group.matcher);
|
|
28051
|
-
const
|
|
28052
|
-
|
|
28126
|
+
const hooks = keepExistingHandlers({
|
|
28127
|
+
handlers: group.hooks,
|
|
28053
28128
|
event,
|
|
28054
28129
|
matcher,
|
|
28130
|
+
attributes: groupAttributesKey(group),
|
|
28131
|
+
pending,
|
|
28055
28132
|
seen,
|
|
28056
28133
|
previouslyOwned,
|
|
28057
28134
|
logger
|
|
28058
|
-
})
|
|
28059
|
-
if (
|
|
28060
|
-
const
|
|
28061
|
-
const target = merged.find((candidate) => isMatcherGroup(candidate) && matcherKey(candidate.matcher) === matcher && groupAttributesKey(candidate) === attributes);
|
|
28062
|
-
if (target !== void 0 && isMatcherGroup(target)) target.hooks.push(...preserved);
|
|
28063
|
-
else merged.push({
|
|
28135
|
+
});
|
|
28136
|
+
if (hooks.length === 0) continue;
|
|
28137
|
+
const kept = {
|
|
28064
28138
|
...omitPrototypePollutionKeys(group),
|
|
28065
|
-
hooks
|
|
28139
|
+
hooks
|
|
28140
|
+
};
|
|
28141
|
+
merged.push(kept);
|
|
28142
|
+
const home = groupSlotKey(group);
|
|
28143
|
+
if (!homes.has(home)) homes.set(home, kept);
|
|
28144
|
+
}
|
|
28145
|
+
for (const group of generated) {
|
|
28146
|
+
if (!isMatcherGroup(group)) {
|
|
28147
|
+
merged.push(group);
|
|
28148
|
+
continue;
|
|
28149
|
+
}
|
|
28150
|
+
const remaining = group.hooks.filter((handler) => !pending.placed.has(handler));
|
|
28151
|
+
if (remaining.length === 0) continue;
|
|
28152
|
+
const home = homes.get(groupSlotKey(group));
|
|
28153
|
+
if (home === void 0) merged.push({
|
|
28154
|
+
...group,
|
|
28155
|
+
hooks: remaining
|
|
28066
28156
|
});
|
|
28157
|
+
else home.hooks.push(...remaining);
|
|
28067
28158
|
}
|
|
28159
|
+
const order = generatedOrder(generated.flatMap((group) => isMatcherGroup(group) ? group.hooks : []));
|
|
28160
|
+
for (const group of merged) if (isMatcherGroup(group)) orderGeneratedSlots({
|
|
28161
|
+
handlers: group.hooks,
|
|
28162
|
+
order
|
|
28163
|
+
});
|
|
28068
28164
|
return merged;
|
|
28069
28165
|
}
|
|
28166
|
+
/** The flat-list counterpart of {@link mergeMatcherGroups}, with the same positional rules. */
|
|
28070
28167
|
function mergeFlatHandlers({ existing, generated, event, seen, previouslyOwned, logger }) {
|
|
28071
|
-
const
|
|
28168
|
+
const pending = createPendingGenerated();
|
|
28169
|
+
addPending({
|
|
28170
|
+
pending,
|
|
28171
|
+
handlers: generated,
|
|
28172
|
+
event,
|
|
28173
|
+
matcher: void 0,
|
|
28174
|
+
attributes: ""
|
|
28175
|
+
});
|
|
28176
|
+
const flat = [];
|
|
28072
28177
|
for (const handler of existing) {
|
|
28073
28178
|
if (isMatcherGroup(handler)) {
|
|
28074
28179
|
warnSkip({
|
|
@@ -28078,17 +28183,93 @@ function mergeFlatHandlers({ existing, generated, event, seen, previouslyOwned,
|
|
|
28078
28183
|
});
|
|
28079
28184
|
continue;
|
|
28080
28185
|
}
|
|
28081
|
-
|
|
28186
|
+
flat.push(handler);
|
|
28187
|
+
}
|
|
28188
|
+
const merged = keepExistingHandlers({
|
|
28189
|
+
handlers: flat,
|
|
28190
|
+
event,
|
|
28191
|
+
matcher: void 0,
|
|
28192
|
+
attributes: "",
|
|
28193
|
+
pending,
|
|
28194
|
+
seen,
|
|
28195
|
+
previouslyOwned,
|
|
28196
|
+
logger
|
|
28197
|
+
});
|
|
28198
|
+
merged.push(...generated.filter((handler) => !pending.placed.has(handler)));
|
|
28199
|
+
orderGeneratedSlots({
|
|
28200
|
+
handlers: merged,
|
|
28201
|
+
order: generatedOrder(generated)
|
|
28202
|
+
});
|
|
28203
|
+
return merged;
|
|
28204
|
+
}
|
|
28205
|
+
/** Each generated handler's position in the generated list, by object identity. */
|
|
28206
|
+
function generatedOrder(handlers) {
|
|
28207
|
+
const order = /* @__PURE__ */ new Map();
|
|
28208
|
+
for (const [index, handler] of handlers.entries()) if (isPlainObject$1(handler)) order.set(handler, index);
|
|
28209
|
+
return order;
|
|
28210
|
+
}
|
|
28211
|
+
/**
|
|
28212
|
+
* Rewrite, in place, the slots of `handlers` that hold generated handlers so
|
|
28213
|
+
* they follow the generated order. Every other slot — an unowned handler — is
|
|
28214
|
+
* left at its index.
|
|
28215
|
+
*/
|
|
28216
|
+
function orderGeneratedSlots({ handlers, order }) {
|
|
28217
|
+
const slots = [];
|
|
28218
|
+
for (const [index, handler] of handlers.entries()) if (order.has(handler)) slots.push(index);
|
|
28219
|
+
const sorted = slots.map((index) => handlers[index]).toSorted((left, right) => (order.get(left) ?? 0) - (order.get(right) ?? 0));
|
|
28220
|
+
for (const [position, index] of slots.entries()) handlers[index] = sorted[position];
|
|
28221
|
+
}
|
|
28222
|
+
function createPendingGenerated() {
|
|
28223
|
+
return {
|
|
28224
|
+
byKey: /* @__PURE__ */ new Map(),
|
|
28225
|
+
placed: /* @__PURE__ */ new Set()
|
|
28226
|
+
};
|
|
28227
|
+
}
|
|
28228
|
+
function addPending({ pending, handlers, event, matcher, attributes }) {
|
|
28229
|
+
for (const handler of handlers) {
|
|
28230
|
+
if (!isPlainObject$1(handler)) continue;
|
|
28231
|
+
const key = pendingKey({
|
|
28232
|
+
event,
|
|
28233
|
+
matcher,
|
|
28234
|
+
attributes,
|
|
28235
|
+
handler
|
|
28236
|
+
});
|
|
28237
|
+
const queue = pending.byKey.get(key);
|
|
28238
|
+
if (queue === void 0) pending.byKey.set(key, [handler]);
|
|
28239
|
+
else queue.push(handler);
|
|
28240
|
+
}
|
|
28241
|
+
}
|
|
28242
|
+
/**
|
|
28243
|
+
* Walk one existing list in order and decide each handler: replaced in place
|
|
28244
|
+
* by its generated copy, kept as unowned, or dropped (retracted or duplicate).
|
|
28245
|
+
*/
|
|
28246
|
+
function keepExistingHandlers({ handlers, event, matcher, attributes, pending, seen, previouslyOwned, logger }) {
|
|
28247
|
+
const kept = [];
|
|
28248
|
+
for (const handler of handlers) {
|
|
28249
|
+
if (isPlainObject$1(handler)) {
|
|
28250
|
+
const key = pendingKey({
|
|
28251
|
+
event,
|
|
28252
|
+
matcher,
|
|
28253
|
+
attributes,
|
|
28254
|
+
handler
|
|
28255
|
+
});
|
|
28256
|
+
const generated = pending.byKey.get(key)?.shift();
|
|
28257
|
+
if (generated !== void 0) {
|
|
28258
|
+
pending.placed.add(generated);
|
|
28259
|
+
kept.push(generated);
|
|
28260
|
+
continue;
|
|
28261
|
+
}
|
|
28262
|
+
}
|
|
28263
|
+
if (shouldPreserve({
|
|
28082
28264
|
handler,
|
|
28083
28265
|
event,
|
|
28084
|
-
matcher
|
|
28266
|
+
matcher,
|
|
28085
28267
|
seen,
|
|
28086
28268
|
previouslyOwned,
|
|
28087
28269
|
logger
|
|
28088
|
-
}))
|
|
28089
|
-
preserved.push(cloneHandler(handler));
|
|
28270
|
+
})) kept.push(cloneHandler(handler));
|
|
28090
28271
|
}
|
|
28091
|
-
return
|
|
28272
|
+
return kept;
|
|
28092
28273
|
}
|
|
28093
28274
|
function isMatcherGroup(value) {
|
|
28094
28275
|
return isPlainObject$1(value) && Array.isArray(value.hooks);
|
|
@@ -28179,10 +28360,35 @@ function stableStringify$1(value) {
|
|
|
28179
28360
|
function matcherKey(matcher) {
|
|
28180
28361
|
return matcher === void 0 ? "" : stableStringify$1(matcher);
|
|
28181
28362
|
}
|
|
28182
|
-
|
|
28363
|
+
function pendingKey({ event, matcher, attributes, handler }) {
|
|
28364
|
+
const key = ownedHookKey({
|
|
28365
|
+
event,
|
|
28366
|
+
matcher,
|
|
28367
|
+
identity: handlerIdentity(handler)
|
|
28368
|
+
});
|
|
28369
|
+
return JSON.stringify([key, attributes]);
|
|
28370
|
+
}
|
|
28371
|
+
/** Groups that share a matcher and attributes are interchangeable homes for a handler. */
|
|
28372
|
+
function groupSlotKey(group) {
|
|
28373
|
+
return JSON.stringify([matcherKey(group.matcher), groupAttributesKey(group)]);
|
|
28374
|
+
}
|
|
28375
|
+
/** Group-level keys whose default value is known, so an explicit default can be ignored. */
|
|
28376
|
+
const GROUP_ATTRIBUTE_DEFAULTS = Object.freeze({
|
|
28377
|
+
__proto__: null,
|
|
28378
|
+
sequential: false
|
|
28379
|
+
});
|
|
28380
|
+
/**
|
|
28381
|
+
* The stable form of a matcher group's keys other than `matcher` and `hooks`.
|
|
28382
|
+
*
|
|
28383
|
+
* A key set to its known default is the same group as one that omits it:
|
|
28384
|
+
* Qwen Code's `sequential` defaults to `false` and rulesync emits it only when
|
|
28385
|
+
* `true`, so an explicit `sequential: false` (or any `undefined` key) is
|
|
28386
|
+
* dropped before comparing. Other `false` values are kept, since their default
|
|
28387
|
+
* is not known here.
|
|
28388
|
+
*/
|
|
28183
28389
|
function groupAttributesKey(group) {
|
|
28184
28390
|
const { matcher: _matcher, hooks: _hooks, ...attributes } = group;
|
|
28185
|
-
return stableStringify$1(attributes);
|
|
28391
|
+
return stableStringify$1(Object.fromEntries(Object.entries(attributes).filter(([key, value]) => value !== void 0 && GROUP_ATTRIBUTE_DEFAULTS[key] !== value)));
|
|
28186
28392
|
}
|
|
28187
28393
|
function warnSkip({ logger, event, expected }) {
|
|
28188
28394
|
logger?.warn(`Skipping existing hook entry on ${event}: expected ${expected}`);
|
|
@@ -42651,9 +42857,11 @@ var CopilotcliMcp = class CopilotcliMcp extends ToolMcp {
|
|
|
42651
42857
|
outputRoot,
|
|
42652
42858
|
global
|
|
42653
42859
|
});
|
|
42860
|
+
const existingDisabled = settings.document?.disabledMcpServers;
|
|
42861
|
+
const offSwitchBlocker = settings.document === null ? "cannot be parsed" : existingDisabled !== void 0 && !isStringArray$1(existingDisabled) ? "has a disabledMcpServers value that is not an array of server names" : void 0;
|
|
42654
42862
|
const copilotCliMcpServers = addTypeField(Object.fromEntries(Object.entries(rulesyncMcp.getMcpServers()).filter(([name, server]) => {
|
|
42655
|
-
if (server.disabled !== true ||
|
|
42656
|
-
logger?.warn(`[CopilotcliMcp] Skipping disabled MCP server "${name}": ${join(settings.paths.relativeDirPath, settings.paths.relativeFilePath)}
|
|
42863
|
+
if (server.disabled !== true || offSwitchBlocker === void 0) return true;
|
|
42864
|
+
logger?.warn(`[CopilotcliMcp] Skipping disabled MCP server "${name}": ${join(settings.paths.relativeDirPath, settings.paths.relativeFilePath)} ${offSwitchBlocker}, so disabledMcpServers cannot be written to switch it off.`);
|
|
42657
42865
|
return false;
|
|
42658
42866
|
})), logger);
|
|
42659
42867
|
const mcpJson = {
|
|
@@ -42683,7 +42891,8 @@ var CopilotcliMcp = class CopilotcliMcp extends ToolMcp {
|
|
|
42683
42891
|
* Copilot CLI actually consults: an MCP file entry has no `disabled` field.
|
|
42684
42892
|
* rulesync owns the toggle for the servers it writes; names it does not
|
|
42685
42893
|
* manage keep their existing state. The file is not created or touched when
|
|
42686
|
-
* there is nothing to disable and nothing to retract
|
|
42894
|
+
* there is nothing to disable and nothing to retract, nor when the existing
|
|
42895
|
+
* `disabledMcpServers` is not a string array (left as is, with a warning).
|
|
42687
42896
|
*/
|
|
42688
42897
|
static async getAuxiliaryFiles({ outputRoot = process.cwd(), global = false, rulesyncMcp, logger }) {
|
|
42689
42898
|
const servers = rulesyncMcp.forTarget({
|
|
@@ -42701,7 +42910,11 @@ var CopilotcliMcp = class CopilotcliMcp extends ToolMcp {
|
|
|
42701
42910
|
return [];
|
|
42702
42911
|
}
|
|
42703
42912
|
const existing = settings.document.disabledMcpServers;
|
|
42704
|
-
|
|
42913
|
+
if (existing !== void 0 && !isStringArray$1(existing)) {
|
|
42914
|
+
logger?.warn(`Skipping the Copilot CLI disabledMcpServers update: the existing value is not an array of server names. Fix it in ${join(settings.paths.relativeDirPath, settings.paths.relativeFilePath)} so rulesync can manage the toggle.`);
|
|
42915
|
+
return [];
|
|
42916
|
+
}
|
|
42917
|
+
const existingDisabled = existing ?? [];
|
|
42705
42918
|
const managedNameSet = new Set(managedNames);
|
|
42706
42919
|
const reEnabled = existingDisabled.filter((name) => managedNameSet.has(name) && !disabledNames.includes(name));
|
|
42707
42920
|
if (reEnabled.length > 0) logger?.warn(`Copilot CLI MCP: re-enabling ${reEnabled.join(", ")} — the canonical config does not mark ${reEnabled.length === 1 ? "it" : "them"} disabled. Set "disabled": true in .rulesync/mcp.jsonc to keep a managed server off.`);
|
|
@@ -56707,7 +56920,7 @@ function convertClaudeToRulesyncPermissions(params) {
|
|
|
56707
56920
|
* (https://docs.cline.bot/cli/cli-reference). The output is still generated for
|
|
56708
56921
|
* compatibility, with a deprecation warning on every generation.
|
|
56709
56922
|
*/
|
|
56710
|
-
const CLINE_PERMISSIONS_DEPRECATION_WARNING = "
|
|
56923
|
+
const CLINE_PERMISSIONS_DEPRECATION_WARNING = "The Cline permissions output (.cline/command-permissions.json) is deprecated. No Cline CLI 3 release reads CLINE_COMMAND_PERMISSIONS, so the generated allow/deny lists are not enforced by current Cline releases. To block shell commands in Cline, use a preToolUse hook (rulesync hooks feature, cline target) that cancels the run_commands calls you do not allow. Note that a hook returning `cancel: true` stops the whole Cline task, not just that one tool call (https://github.com/cline/cline/issues/14697). See https://docs.cline.bot/cli/cli-reference.";
|
|
56711
56924
|
const ClineCommandPermissionsSchema = z.looseObject({
|
|
56712
56925
|
allow: z.optional(z.array(z.string())),
|
|
56713
56926
|
deny: z.optional(z.array(z.string())),
|
|
@@ -60223,6 +60436,193 @@ const AUTO_APPROVE_KEYS = {
|
|
|
60223
60436
|
* @see https://code.visualstudio.com/docs/agents/reference/ai-settings
|
|
60224
60437
|
*/
|
|
60225
60438
|
const DEFAULT_PERMISSION_MODE_KEY = "chat.permissions.default";
|
|
60439
|
+
/**
|
|
60440
|
+
* The prefix every Agent Host sandbox setting shares. A `copilot.sandbox` leaf
|
|
60441
|
+
* at path `a.b` is written to `chat.agent.sandbox.a.b`.
|
|
60442
|
+
*/
|
|
60443
|
+
const SANDBOX_KEY_PREFIX = "chat.agent.sandbox.";
|
|
60444
|
+
/**
|
|
60445
|
+
* The `copilot.sandbox` leaves rulesync manages, each a flat VS Code setting
|
|
60446
|
+
* (`SANDBOX_KEY_PREFIX` + the dotted path) with the value shape VS Code
|
|
60447
|
+
* registers for it. The shape is re-checked on import, so a hand-written value
|
|
60448
|
+
* VS Code would not accept is skipped instead of failing the whole import.
|
|
60449
|
+
*
|
|
60450
|
+
* @see https://code.visualstudio.com/docs/agents/run/agent-sandboxing
|
|
60451
|
+
* @see https://code.visualstudio.com/docs/agents/reference/ai-settings
|
|
60452
|
+
*/
|
|
60453
|
+
const SANDBOX_LEAVES = [
|
|
60454
|
+
{
|
|
60455
|
+
path: ["enabled"],
|
|
60456
|
+
schema: CopilotSandboxEnabledSchema,
|
|
60457
|
+
normalize: (value) => value === true ? "on" : value === false ? "off" : value
|
|
60458
|
+
},
|
|
60459
|
+
{
|
|
60460
|
+
path: ["network", "allowNetwork"],
|
|
60461
|
+
schema: z.boolean()
|
|
60462
|
+
},
|
|
60463
|
+
{
|
|
60464
|
+
path: ["network", "allowLocalNetwork"],
|
|
60465
|
+
schema: z.boolean()
|
|
60466
|
+
},
|
|
60467
|
+
{
|
|
60468
|
+
path: ["allowUnsandboxedCommands"],
|
|
60469
|
+
schema: z.boolean()
|
|
60470
|
+
},
|
|
60471
|
+
{
|
|
60472
|
+
path: ["mcpServers"],
|
|
60473
|
+
schema: z.boolean()
|
|
60474
|
+
},
|
|
60475
|
+
{
|
|
60476
|
+
path: ["lspServers"],
|
|
60477
|
+
schema: z.boolean()
|
|
60478
|
+
},
|
|
60479
|
+
{
|
|
60480
|
+
path: ["credentials", "authenticategit"],
|
|
60481
|
+
schema: z.boolean()
|
|
60482
|
+
},
|
|
60483
|
+
{
|
|
60484
|
+
path: ["credentials", "authenticategh"],
|
|
60485
|
+
schema: z.boolean()
|
|
60486
|
+
},
|
|
60487
|
+
{
|
|
60488
|
+
path: ["fileSystem", "allowDevToolAccess"],
|
|
60489
|
+
schema: z.boolean()
|
|
60490
|
+
},
|
|
60491
|
+
{
|
|
60492
|
+
path: ["fileSystem", "userConfiguredPaths"],
|
|
60493
|
+
schema: CopilotSandboxUserConfiguredPathsSchema
|
|
60494
|
+
}
|
|
60495
|
+
];
|
|
60496
|
+
const USER_CONFIGURED_PATHS_KEY = `${SANDBOX_KEY_PREFIX}fileSystem.userConfiguredPaths`;
|
|
60497
|
+
/**
|
|
60498
|
+
* `copilot.sandbox` values that loosen the Agent Host sandbox. They are still
|
|
60499
|
+
* written — a sandbox policy is the user's call — but never silently. Each
|
|
60500
|
+
* `widens` names the value that does *not* loosen anything and reports the
|
|
60501
|
+
* rest, so an unexpected value is reported rather than ignored.
|
|
60502
|
+
*
|
|
60503
|
+
* @see https://code.visualstudio.com/docs/agents/run/agent-sandboxing
|
|
60504
|
+
*/
|
|
60505
|
+
const COPILOT_TRUST_AFFECTING_SANDBOX_PATHS = [
|
|
60506
|
+
{
|
|
60507
|
+
path: ["enabled"],
|
|
60508
|
+
reason: "turns the sandbox off, so agent terminal commands run unconfined",
|
|
60509
|
+
widens: (value) => value !== "on"
|
|
60510
|
+
},
|
|
60511
|
+
{
|
|
60512
|
+
path: ["network", "allowNetwork"],
|
|
60513
|
+
reason: "lets sandboxed commands reach the external network",
|
|
60514
|
+
widens: isNotFalse
|
|
60515
|
+
},
|
|
60516
|
+
{
|
|
60517
|
+
path: ["network", "allowLocalNetwork"],
|
|
60518
|
+
reason: "lets sandboxed commands reach local network resources",
|
|
60519
|
+
widens: isNotFalse
|
|
60520
|
+
},
|
|
60521
|
+
{
|
|
60522
|
+
path: ["allowUnsandboxedCommands"],
|
|
60523
|
+
reason: "lets the agent ask to run a blocked command outside the sandbox",
|
|
60524
|
+
widens: isNotFalse
|
|
60525
|
+
},
|
|
60526
|
+
{
|
|
60527
|
+
path: ["mcpServers"],
|
|
60528
|
+
reason: "runs locally launched MCP servers outside the sandbox",
|
|
60529
|
+
widens: isNotTrue
|
|
60530
|
+
},
|
|
60531
|
+
{
|
|
60532
|
+
path: ["lspServers"],
|
|
60533
|
+
reason: "runs language servers outside the sandbox",
|
|
60534
|
+
widens: isNotTrue
|
|
60535
|
+
},
|
|
60536
|
+
{
|
|
60537
|
+
path: ["credentials", "authenticategit"],
|
|
60538
|
+
reason: "hands your Git credentials to sandboxed commands",
|
|
60539
|
+
widens: isNotFalse
|
|
60540
|
+
},
|
|
60541
|
+
{
|
|
60542
|
+
path: ["credentials", "authenticategh"],
|
|
60543
|
+
reason: "hands your GitHub CLI authentication to sandboxed commands",
|
|
60544
|
+
widens: isNotFalse
|
|
60545
|
+
},
|
|
60546
|
+
{
|
|
60547
|
+
path: ["fileSystem", "allowDevToolAccess"],
|
|
60548
|
+
reason: "grants sandboxed commands developer-tool directories, which can hold credentials such as registry tokens",
|
|
60549
|
+
widens: isNotFalse
|
|
60550
|
+
},
|
|
60551
|
+
{
|
|
60552
|
+
path: [
|
|
60553
|
+
"fileSystem",
|
|
60554
|
+
"userConfiguredPaths",
|
|
60555
|
+
"readwritePaths"
|
|
60556
|
+
],
|
|
60557
|
+
reason: "adds paths sandboxed commands may write to, outside the working directory",
|
|
60558
|
+
widens: isNonEmptyList
|
|
60559
|
+
},
|
|
60560
|
+
{
|
|
60561
|
+
path: [
|
|
60562
|
+
"fileSystem",
|
|
60563
|
+
"userConfiguredPaths",
|
|
60564
|
+
"readonlyPaths"
|
|
60565
|
+
],
|
|
60566
|
+
reason: "adds paths sandboxed commands may read, outside the working directory",
|
|
60567
|
+
widens: isNonEmptyList
|
|
60568
|
+
}
|
|
60569
|
+
];
|
|
60570
|
+
const COPILOT_TOOL_LABEL = "GitHub Copilot";
|
|
60571
|
+
function sandboxKey(path) {
|
|
60572
|
+
return `${SANDBOX_KEY_PREFIX}${path.join(".")}`;
|
|
60573
|
+
}
|
|
60574
|
+
/**
|
|
60575
|
+
* Patch entries for every `copilot.sandbox` leaf the canonical config states.
|
|
60576
|
+
* Leaves it does not state are left as the file has them, so authoring only
|
|
60577
|
+
* `network.allowNetwork` never disturbs a hand-written `enabled`. The
|
|
60578
|
+
* `userConfiguredPaths` object merges per list for the same reason: authoring
|
|
60579
|
+
* `readwritePaths` keeps a hand-written `deniedPaths`, which would otherwise be
|
|
60580
|
+
* a restriction lost without a word.
|
|
60581
|
+
*/
|
|
60582
|
+
function buildSandboxPatch({ sandbox, existingSettings }) {
|
|
60583
|
+
const patch = {};
|
|
60584
|
+
for (const { path } of SANDBOX_LEAVES) {
|
|
60585
|
+
const value = readSandboxPath({
|
|
60586
|
+
sandbox,
|
|
60587
|
+
path
|
|
60588
|
+
});
|
|
60589
|
+
if (value === void 0 || value === UNREADABLE_SANDBOX_PATH) continue;
|
|
60590
|
+
const key = sandboxKey(path);
|
|
60591
|
+
if (key === USER_CONFIGURED_PATHS_KEY && isPlainObject$1(value)) {
|
|
60592
|
+
const existing = existingSettings[key];
|
|
60593
|
+
patch[key] = {
|
|
60594
|
+
...isPlainObject$1(existing) ? existing : {},
|
|
60595
|
+
...value
|
|
60596
|
+
};
|
|
60597
|
+
continue;
|
|
60598
|
+
}
|
|
60599
|
+
patch[key] = value;
|
|
60600
|
+
}
|
|
60601
|
+
return patch;
|
|
60602
|
+
}
|
|
60603
|
+
/**
|
|
60604
|
+
* Lift every managed `chat.agent.sandbox.*` key the file holds back into a
|
|
60605
|
+
* nested `copilot.sandbox` object. A value whose shape VS Code would reject is
|
|
60606
|
+
* skipped; the write path leaves it in place.
|
|
60607
|
+
*/
|
|
60608
|
+
function readSandboxFromSettings(settings) {
|
|
60609
|
+
const sandbox = {};
|
|
60610
|
+
for (const { path, schema, normalize } of SANDBOX_LEAVES) {
|
|
60611
|
+
const value = settings[sandboxKey(path)];
|
|
60612
|
+
const parsed = schema.safeParse(normalize === void 0 ? value : normalize(value));
|
|
60613
|
+
if (!parsed.success) continue;
|
|
60614
|
+
let cursor = sandbox;
|
|
60615
|
+
for (const segment of path.slice(0, -1)) {
|
|
60616
|
+
const next = cursor[segment];
|
|
60617
|
+
const child = isPlainObject$1(next) ? next : {};
|
|
60618
|
+
cursor[segment] = child;
|
|
60619
|
+
cursor = child;
|
|
60620
|
+
}
|
|
60621
|
+
const leaf = path[path.length - 1];
|
|
60622
|
+
if (leaf !== void 0) cursor[leaf] = parsed.data;
|
|
60623
|
+
}
|
|
60624
|
+
return Object.keys(sandbox).length > 0 ? sandbox : void 0;
|
|
60625
|
+
}
|
|
60226
60626
|
function isCopilotDefaultPermissionMode(value) {
|
|
60227
60627
|
return COPILOT_DEFAULT_PERMISSION_MODES.some((mode) => mode === value);
|
|
60228
60628
|
}
|
|
@@ -60267,7 +60667,9 @@ function buildAutoApproveValue(rules) {
|
|
|
60267
60667
|
* hand-written edits or urls map.
|
|
60268
60668
|
* The `copilot.defaultPermissionMode` override writes `chat.permissions.default`
|
|
60269
60669
|
* (the starting permission level of new chat sessions); without it the key is
|
|
60270
|
-
* left untouched.
|
|
60670
|
+
* left untouched. The `copilot.sandbox` override writes the Agent Host sandbox
|
|
60671
|
+
* settings (`chat.agent.sandbox.*`, see {@link SANDBOX_LEAVES}) per key, and
|
|
60672
|
+
* warns about every value it writes that loosens the sandbox.
|
|
60271
60673
|
* Only project scope is modeled: VS Code's user-scope settings.json lives at a
|
|
60272
60674
|
* platform-dependent path outside rulesync's home-relative global model.
|
|
60273
60675
|
*/
|
|
@@ -60315,6 +60717,26 @@ var CopilotPermissions = class CopilotPermissions extends ToolPermissions {
|
|
|
60315
60717
|
}
|
|
60316
60718
|
const defaultPermissionMode = config.copilot?.defaultPermissionMode;
|
|
60317
60719
|
if (defaultPermissionMode !== void 0) patch[DEFAULT_PERMISSION_MODE_KEY] = defaultPermissionMode;
|
|
60720
|
+
const sandbox = config.copilot?.sandbox;
|
|
60721
|
+
if (sandbox !== void 0) {
|
|
60722
|
+
Object.assign(patch, buildSandboxPatch({
|
|
60723
|
+
sandbox,
|
|
60724
|
+
existingSettings: parseSharedConfig({
|
|
60725
|
+
format: "jsonc",
|
|
60726
|
+
fileContent: existingContent,
|
|
60727
|
+
filePath
|
|
60728
|
+
})
|
|
60729
|
+
}));
|
|
60730
|
+
warnOnTrustAffectingEntries({
|
|
60731
|
+
toolLabel: COPILOT_TOOL_LABEL,
|
|
60732
|
+
entries: collectTrustAffectingSandboxPaths({
|
|
60733
|
+
sandbox,
|
|
60734
|
+
paths: COPILOT_TRUST_AFFECTING_SANDBOX_PATHS
|
|
60735
|
+
}),
|
|
60736
|
+
relativeFilePath: join(paths.relativeDirPath, paths.relativeFilePath),
|
|
60737
|
+
logger
|
|
60738
|
+
});
|
|
60739
|
+
}
|
|
60318
60740
|
return new CopilotPermissions({
|
|
60319
60741
|
outputRoot,
|
|
60320
60742
|
relativeDirPath: paths.relativeDirPath,
|
|
@@ -60351,9 +60773,14 @@ var CopilotPermissions = class CopilotPermissions extends ToolPermissions {
|
|
|
60351
60773
|
if (Object.keys(rules).length > 0) permission[category] = rules;
|
|
60352
60774
|
}
|
|
60353
60775
|
const defaultPermissionMode = settings[DEFAULT_PERMISSION_MODE_KEY];
|
|
60776
|
+
const sandbox = readSandboxFromSettings(settings);
|
|
60777
|
+
const copilot = {
|
|
60778
|
+
...isCopilotDefaultPermissionMode(defaultPermissionMode) && { defaultPermissionMode },
|
|
60779
|
+
...sandbox !== void 0 && { sandbox }
|
|
60780
|
+
};
|
|
60354
60781
|
return this.toRulesyncPermissionsDefault({ fileContent: JSON.stringify({
|
|
60355
60782
|
permission,
|
|
60356
|
-
...
|
|
60783
|
+
...Object.keys(copilot).length > 0 && { copilot }
|
|
60357
60784
|
}, null, 2) });
|
|
60358
60785
|
}
|
|
60359
60786
|
validate() {
|
|
@@ -99629,9 +100056,10 @@ const toolRuleFactories = /* @__PURE__ */ new Map([
|
|
|
99629
100056
|
collisionPolicy: "fold",
|
|
99630
100057
|
projectInstructionBudget: {
|
|
99631
100058
|
bytes: CODEXCLI_PROJECT_DOC_MAX_BYTES,
|
|
99632
|
-
remedy: "Codex CLI stops reading project `AGENTS.md` files once their combined size on the root-to-working-directory chain reaches `project_doc_max_bytes` (32 KiB by default) and silently drops the rest. Move directory-scoped rules into nested `AGENTS.md` files with `agentsmd.subprojectPath` (or `deriveSubprojectPathFromGlobs: true` in rulesync.jsonc), trim the rules, or raise `project_doc_max_bytes` in `.codex/config.toml
|
|
100059
|
+
remedy: "Codex CLI stops reading project `AGENTS.md` files once their combined size on the root-to-working-directory chain reaches `project_doc_max_bytes` (32 KiB by default) and silently drops the rest. Move directory-scoped rules into nested `AGENTS.md` files with `agentsmd.subprojectPath` (or `deriveSubprojectPathFromGlobs: true` in rulesync.jsonc), trim the rules, or raise `project_doc_max_bytes` in `.codex/config.toml` (Codex reads that file only if the project is trusted).",
|
|
99633
100060
|
readConfiguredBytes: readCodexcliProjectDocMaxBytes,
|
|
99634
|
-
configuredSource: "`project_doc_max_bytes` in `.codex/config.toml`"
|
|
100061
|
+
configuredSource: "`project_doc_max_bytes` in `.codex/config.toml` (honored only if the project is trusted)",
|
|
100062
|
+
defaultLimitHint: "Rulesync does not read `~/.codex/config.toml`; ignore this warning if you already raised `project_doc_max_bytes` there."
|
|
99635
100063
|
}
|
|
99636
100064
|
}
|
|
99637
100065
|
}],
|
|
@@ -100210,6 +100638,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
100210
100638
|
const configuredBytes = await budget.readConfiguredBytes?.(this.outputRoot);
|
|
100211
100639
|
const limitBytes = configuredBytes ?? budget.bytes;
|
|
100212
100640
|
const limitLabel = budget.readConfiguredBytes === void 0 ? `${limitBytes}-byte limit` : configuredBytes === void 0 ? `${limitBytes}-byte default limit` : `${limitBytes}-byte limit set by ${budget.configuredSource ?? "the tool config"}`;
|
|
100641
|
+
const remedy = configuredBytes === void 0 && budget.defaultLimitHint !== void 0 ? `${budget.remedy} ${budget.defaultLimitHint}` : budget.remedy;
|
|
100213
100642
|
const files = toolRules.map((rule) => ({
|
|
100214
100643
|
dir: normalizeRelativeDir(rule.getRelativeDirPath()),
|
|
100215
100644
|
path: toPosixPath(join(rule.getRelativeDirPath(), rule.getRelativeFilePath())),
|
|
@@ -100220,7 +100649,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
100220
100649
|
const rootFiles = files.filter(({ dir }) => dir === ".");
|
|
100221
100650
|
const rootBytes = rootFiles.reduce((sum, { bytes }) => sum + bytes, 0);
|
|
100222
100651
|
if (rootBytes > limitBytes) {
|
|
100223
|
-
this.logger.warn(`The generated ${this.toolTarget} root instruction file${location} (${rootFiles.map(({ path }) => path).join(", ")}) is ${rootBytes} bytes, over the ${limitLabel}. ${
|
|
100652
|
+
this.logger.warn(`The generated ${this.toolTarget} root instruction file${location} (${rootFiles.map(({ path }) => path).join(", ")}) is ${rootBytes} bytes, over the ${limitLabel}. ${remedy}`);
|
|
100224
100653
|
return;
|
|
100225
100654
|
}
|
|
100226
100655
|
const reportedDirs = [];
|
|
@@ -100231,7 +100660,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
100231
100660
|
const chainBytes = chain.reduce((sum, { bytes }) => sum + bytes, 0);
|
|
100232
100661
|
if (chainBytes > limitBytes) {
|
|
100233
100662
|
reportedDirs.push(file.dir);
|
|
100234
|
-
this.logger.warn(`The generated ${this.toolTarget} instruction files${location} loaded while working in '${file.dir}' (${chain.map(({ path }) => path).join(", ")}) total ${chainBytes} bytes, over the ${limitLabel} (as is every directory below it). ${
|
|
100663
|
+
this.logger.warn(`The generated ${this.toolTarget} instruction files${location} loaded while working in '${file.dir}' (${chain.map(({ path }) => path).join(", ")}) total ${chainBytes} bytes, over the ${limitLabel} (as is every directory below it). ${remedy}`);
|
|
100235
100664
|
}
|
|
100236
100665
|
}
|
|
100237
100666
|
}
|
|
@@ -104136,4 +104565,4 @@ async function importChecksCore(params) {
|
|
|
104136
104565
|
//#endregion
|
|
104137
104566
|
export { RulesyncHooks as $, removeDirectoryStrict as $t, groupSpellingsByCaseFoldedIdentity as A, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as An, applyFileMode as At, QWENCODE_LOCAL_RULE_FILE_NAME as B, parseCommaSeparatedList as Bn, getFileSizeAndExecutableBit as Bt, COMMANDCODE_SETTINGS_LOCAL_FILE_NAME as C, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as Cn, fallbackLogger as Ct, FACTORYDROID_DIR as D, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as Dn, withWarnOnceScope as Dt, ChecksProcessor as E, RULESYNC_IGNORE_RELATIVE_FILE_PATH as En, resetRunWarningState as Et, CLAUDECODE_LOCAL_RULE_FILE_NAME as F, RULESYNC_SKILLS_RELATIVE_DIR_PATH as Fn, createTempDirectory as Ft, RulesyncSubagentFrontmatterSchema as G, truncateText as Gn, listDirectoryEntryNames as Gt, AUGMENTCODE_SETTINGS_LOCAL_FILE_NAME as H, ALL_FEATURES_WITH_WILDCARD as Hn, isFileNotFoundError as Ht, CLAUDECODE_MEMORIES_DIR_NAME as I, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as In, directoryExists as It, RulesyncRule as J, quoteForLog as Jn, pathEscapesRoot as Jt, RulesyncSkill as K, hasDeceptiveHiddenCharacters as Kn, listFilePathsRecursively as Kt, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as L, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as Ln, ensureDir as Lt, CODEXCLI_DIR as M, RULESYNC_PERMISSIONS_SCHEMA_URL as Mn, assertTreeContainsNoSymlinks as Mt, CLAUDECODE_AGENT_MEMORY_LOCAL_DIR_NAME as N, RULESYNC_RELATIVE_DIR_PATH as Nn, assertWritablePathInsideRoot as Nt, FACTORYDROID_SETTINGS_LOCAL_FILE_NAME as O, RULESYNC_MCP_RELATIVE_FILE_PATH as On, CLIError as Ot, CLAUDECODE_DIR as P, RULESYNC_RULES_RELATIVE_DIR_PATH as Pn, checkPathTraversal as Pt, RulesyncIgnore as Q, removeDirectory as Qt, CLAUDECODE_SKILLS_DIR_PATH as R, RULESYNC_USER_CONFIG_DIR_NAME as Rn, fileExists as Rt, COMMANDCODE_DIR as S, RULESYNC_CONFIG_SCHEMA_URL as Sn, WarningCollectingLogger as St, CODEBUDDY_LOCAL_RULE_FILE_NAME as T, RULESYNC_HOOKS_RELATIVE_FILE_PATH as Tn, withFallbackLoggerTarget as Tt, getLocalSkillDirNames as U, DEPRECATED_FEATURE_REPLACEMENTS as Un, isFileSystemError as Ut, AUGMENTCODE_DIR as V, ALL_FEATURES as Vn, getHomeDirectory as Vt, RulesyncSubagent as W, formatError as Wn, isSymlink as Wt, RulesyncPermissions as X, stripControlCharactersKeepingLineFeeds as Xn, readFileContent as Xt, RulesyncRuleFrontmatterSchema as Y, stripControlCharacters as Yn, posixRelativePathEscapesRoot as Yt, RulesyncMcp as Z, stripHiddenCharacters as Zn, readFileContentOrNull as Zt, LETTACODE_DIR as _, MAX_FILE_SIZE as _n, SourceEntrySchema as _t, getProcessorRegistryEntry as a, runWithDirectoryRollback as an, RulesyncCheck as at, CommandsProcessor as b, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as bn, ConsoleLogger as bt, RulesProcessor as c, writeFileBuffer as cn, loadYaml as ct, ELLIPSIS_WIDTH as d, ALL_TOOL_TARGETS as dn, ConfigResolver as dt, removeFile as en, getRulesyncSourceCandidates as et, displayWidthOf as f, ALL_TOOL_TARGETS_WITH_WILDCARD as fn, mergeInputRootConfigs as ft, HooksProcessor as g, FEATURE_SOURCE_TREE_ENTRIES as gn, GITIGNORE_DESTINATION_KEY as gt, IgnoreProcessor as h, CURATED_RULES_FEATURE_SUBDIR as hn, ConfigFileSchema as ht, inspectInputRoots as i, resolvedRelativePath as in, RulesyncCommandFrontmatterSchema as it, CODEXCLI_BASH_RULES_FILE_NAME as j, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as jn, assertDirectoryIfExists as jt, caseFoldIdentity as k, RULESYNC_MCP_SCHEMA_URL as kn, ErrorCodes as kt, SubagentsProcessor as l, writeFileContent as ln, SHARED_USER_MANAGED_CONFIG_PATHS as lt, McpProcessor as m, ToolTargetSchema as mn, CONFLICTING_TARGET_PAIRS as mt, formatSourceLoadFailure as n, removeTempDirectory as nn, parseJsonc as nt, convertFromTool as o, splitPathSegments as on, RulesyncCheckFrontmatterSchema as ot, shortenToWidth as p, PACKAGING_TOOL_TARGETS as pn, resolveEffectiveInputRoots as pt, RulesyncSkillFrontmatterSchema as q, hasEnclosingMarkOutsideKeycap as qn, listSubdirectoryNames as qt, generate as r, resolvePath as rn, RulesyncCommand as rt, isPackagingToolTarget as s, toPosixPath as sn, stringifyFrontmatter as st, importFromTool as t, removeFileStrict as tn, resolveRulesyncSourceWritePath as tt, SkillsProcessor as u, mapWithConcurrency as un, SKILL_FILE_NAME as ut, LETTACODE_SETTINGS_LOCAL_FILE_NAME as v, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as vn, assertTargetsFeaturesExclusive as vt, CODEBUDDY_DIR as w, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as wn, warnOnConflictingFlags as wt, REASONIX_LOCAL_RULE_FILE_NAME as x, RULESYNC_CONFIG_RELATIVE_FILE_PATH as xn, JsonLogger as xt, CRUSH_LOCAL_RULE_FILE_NAME as y, RULESYNC_CHECKS_RELATIVE_DIR_PATH as yn, findControlCharacter as yt, QWENCODE_DIR as z, RULESYNC_XDG_CONFIG_HOME_DEFAULT_DIR_NAME as zn, findFilesByGlobs as zt };
|
|
104138
104567
|
|
|
104139
|
-
//# sourceMappingURL=import-
|
|
104568
|
+
//# sourceMappingURL=import-BsEFYJsg.js.map
|