rulesync 32.0.0 → 33.0.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 +23 -5
- package/dist/cli/index.js +23 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-DgKWnDni.js → import-5-Uennl1.js} +215 -19
- package/dist/{import-DgKWnDni.js.map → import-5-Uennl1.js.map} +1 -1
- package/dist/{import-Bmb7ofrF.cjs → import-D_SV_C0k.cjs} +214 -18
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -21744,22 +21744,29 @@ function mergeOpencodeV2Entries({ config, legacyKey, pluralKey, lower }) {
|
|
|
21744
21744
|
const entry = asOpencodeEntries(value);
|
|
21745
21745
|
const lowered = entry === null ? null : lower(entry);
|
|
21746
21746
|
if (Object.hasOwn(merged, name) || lowered === null) continue;
|
|
21747
|
-
|
|
21748
|
-
value: lowered,
|
|
21749
|
-
enumerable: true,
|
|
21750
|
-
configurable: true,
|
|
21751
|
-
writable: true
|
|
21752
|
-
});
|
|
21747
|
+
setOwnEntry(merged, name, lowered);
|
|
21753
21748
|
}
|
|
21754
21749
|
return Object.keys(merged).length > 0 ? merged : legacy;
|
|
21755
21750
|
}
|
|
21756
21751
|
/**
|
|
21752
|
+
* Sets `target[key]` as an own, enumerable property. A plain assignment to a
|
|
21753
|
+
* key named `__proto__` would set the prototype instead.
|
|
21754
|
+
*/
|
|
21755
|
+
function setOwnEntry(target, key, value) {
|
|
21756
|
+
Object.defineProperty(target, key, {
|
|
21757
|
+
value,
|
|
21758
|
+
enumerable: true,
|
|
21759
|
+
configurable: true,
|
|
21760
|
+
writable: true
|
|
21761
|
+
});
|
|
21762
|
+
}
|
|
21763
|
+
/**
|
|
21757
21764
|
* Returns the inline agent entries of an OpenCode config in the V1 `agent`
|
|
21758
21765
|
* shape. Since v1.18.24 OpenCode V1 also reads the V2 `agents` spelling and
|
|
21759
21766
|
* lowers it, so a layout that does so (`readsV2ConfigSpellings`) gets those
|
|
21760
21767
|
* entries too.
|
|
21761
21768
|
*
|
|
21762
|
-
* @see https://github.com/anomalyco/opencode/blob/v1.18.
|
|
21769
|
+
* @see https://github.com/anomalyco/opencode/blob/v1.18.35/packages/opencode/src/config/v2-compat.ts
|
|
21763
21770
|
*/
|
|
21764
21771
|
function getOpencodeAgentEntries({ config, layout = OPENCODE_LAYOUT }) {
|
|
21765
21772
|
if (!layout.readsV2ConfigSpellings) return asOpencodeEntries(config.agent);
|
|
@@ -21778,7 +21785,7 @@ function getOpencodeAgentEntries({ config, layout = OPENCODE_LAYOUT }) {
|
|
|
21778
21785
|
* Other fields are kept: V1 drops a V2 `subagent`, but rulesync reads it as
|
|
21779
21786
|
* `subtask` everywhere (as V2 does), so it is left for the command importer.
|
|
21780
21787
|
*
|
|
21781
|
-
* @see https://github.com/anomalyco/opencode/blob/v1.18.
|
|
21788
|
+
* @see https://github.com/anomalyco/opencode/blob/v1.18.35/packages/opencode/src/config/v2-compat.ts
|
|
21782
21789
|
*/
|
|
21783
21790
|
function getOpencodeCommandEntries({ config, layout = OPENCODE_LAYOUT }) {
|
|
21784
21791
|
if (!layout.readsV2ConfigSpellings) return asOpencodeEntries(config.command);
|
|
@@ -21801,7 +21808,7 @@ function getOpencodeCommandEntries({ config, layout = OPENCODE_LAYOUT }) {
|
|
|
21801
21808
|
* reads V2 spellings, a flat V2 `skills` array is accepted too: its entries
|
|
21802
21809
|
* that are not `http(s)://` URLs are the paths, as OpenCode V1 lowers them.
|
|
21803
21810
|
*
|
|
21804
|
-
* @see https://github.com/anomalyco/opencode/blob/v1.18.
|
|
21811
|
+
* @see https://github.com/anomalyco/opencode/blob/v1.18.35/packages/opencode/src/config/v2-compat.ts
|
|
21805
21812
|
*/
|
|
21806
21813
|
function getOpencodeSkillPaths({ config, layout = OPENCODE_LAYOUT }) {
|
|
21807
21814
|
if (Array.isArray(config.skills)) {
|
|
@@ -21811,6 +21818,160 @@ function getOpencodeSkillPaths({ config, layout = OPENCODE_LAYOUT }) {
|
|
|
21811
21818
|
const skills = asOpencodeEntries(config.skills);
|
|
21812
21819
|
return skills !== null && Array.isArray(skills.paths) ? skills.paths : [];
|
|
21813
21820
|
}
|
|
21821
|
+
/**
|
|
21822
|
+
* Whether a record is itself an MCP server entry rather than a V2 container
|
|
21823
|
+
* (`mcp.servers`, `mcp.timeout`): a server — or a server literally named
|
|
21824
|
+
* `type` / `enabled` — carries a scalar `type` or `enabled`. Mirrors OpenCode
|
|
21825
|
+
* V1's `isDirectServer`.
|
|
21826
|
+
*/
|
|
21827
|
+
function isDirectOpencodeMcpServer(value) {
|
|
21828
|
+
return ["type", "enabled"].some((key) => Object.hasOwn(value, key) && (value[key] === null || typeof value[key] !== "object" || Array.isArray(value[key])));
|
|
21829
|
+
}
|
|
21830
|
+
const OPENCODE_V2_TIMEOUT_KEYS = [
|
|
21831
|
+
"startup",
|
|
21832
|
+
"catalog",
|
|
21833
|
+
"execution"
|
|
21834
|
+
];
|
|
21835
|
+
/**
|
|
21836
|
+
* Whether an MCP server entry uses a V2-only per-server spelling, so that
|
|
21837
|
+
* OpenCode V1 lowers it: `disabled`, `codemode`, an object `timeout`, or a
|
|
21838
|
+
* snake_case `oauth` key.
|
|
21839
|
+
*/
|
|
21840
|
+
function isOpencodeV2NativeServer(value) {
|
|
21841
|
+
const oauth = value.oauth;
|
|
21842
|
+
return Object.hasOwn(value, "disabled") || Object.hasOwn(value, "codemode") || isRecord$1(value.timeout) || isRecord$1(oauth) && [
|
|
21843
|
+
"client_id",
|
|
21844
|
+
"client_secret",
|
|
21845
|
+
"callback_port",
|
|
21846
|
+
"redirect_uri"
|
|
21847
|
+
].some((key) => Object.hasOwn(oauth, key));
|
|
21848
|
+
}
|
|
21849
|
+
/**
|
|
21850
|
+
* Lowers a V2 timeout object (`{ startup, catalog, execution }`) to V1's single
|
|
21851
|
+
* number, the way OpenCode V1 does: only a `catalog` equal to `execution`, with
|
|
21852
|
+
* no `startup`, has a V1 equivalent. Anything else — including a value that is
|
|
21853
|
+
* not a positive integer — is `undefined` (dropped).
|
|
21854
|
+
*/
|
|
21855
|
+
function lowerOpencodeV2Timeout(value) {
|
|
21856
|
+
if (!hasPositiveIntegerTimeouts(value) || value.startup !== void 0 || typeof value.catalog !== "number") return;
|
|
21857
|
+
return value.catalog === value.execution ? value.catalog : void 0;
|
|
21858
|
+
}
|
|
21859
|
+
const OPENCODE_V2_OAUTH_KEYS = /* @__PURE__ */ new Map([
|
|
21860
|
+
["client_id", "clientId"],
|
|
21861
|
+
["client_secret", "clientSecret"],
|
|
21862
|
+
["callback_port", "callbackPort"],
|
|
21863
|
+
["redirect_uri", "redirectUri"]
|
|
21864
|
+
]);
|
|
21865
|
+
/**
|
|
21866
|
+
* V2 `oauth` keys that have no V1 spelling. OpenCode V1 drops them when it
|
|
21867
|
+
* lowers a server, so they are dropped (and reported) here too rather than
|
|
21868
|
+
* being written back as a snake_case key among camelCase ones.
|
|
21869
|
+
*/
|
|
21870
|
+
const OPENCODE_V2_UNSUPPORTED_OAUTH_KEYS = /* @__PURE__ */ new Set(["auth_server_metadata_url"]);
|
|
21871
|
+
function lowerOpencodeV2OAuth(oauth, path, onDropped) {
|
|
21872
|
+
const lowered = {};
|
|
21873
|
+
for (const [key, value] of Object.entries(oauth)) {
|
|
21874
|
+
if (OPENCODE_V2_UNSUPPORTED_OAUTH_KEYS.has(key)) {
|
|
21875
|
+
onDropped?.(`${path}.${key}`, "unsupported");
|
|
21876
|
+
continue;
|
|
21877
|
+
}
|
|
21878
|
+
setOwnEntry(lowered, OPENCODE_V2_OAUTH_KEYS.get(key) ?? key, value);
|
|
21879
|
+
}
|
|
21880
|
+
return lowered;
|
|
21881
|
+
}
|
|
21882
|
+
/**
|
|
21883
|
+
* Lowers one V2-spelled MCP server entry to V1's shape, as OpenCode V1 does:
|
|
21884
|
+
* `disabled` becomes `enabled` (an explicit `enabled` wins), an object
|
|
21885
|
+
* `timeout` becomes a number or is dropped, and snake_case `oauth` keys become
|
|
21886
|
+
* camelCase. `codemode` is kept: Rulesync passes it through where V1 drops it.
|
|
21887
|
+
*
|
|
21888
|
+
* Like V1, only an entry that is a local or remote server is lowered, and one
|
|
21889
|
+
* whose `enabled` or `disabled` is not a boolean is left as it is. Unlike V1,
|
|
21890
|
+
* such an entry is not dropped but passed on, so the schema rejects it loudly.
|
|
21891
|
+
*/
|
|
21892
|
+
function lowerOpencodeV2Server(value, path, onDropped) {
|
|
21893
|
+
if (!isRecord$1(value) || value.type !== "local" && value.type !== "remote" || Object.hasOwn(value, "enabled") && typeof value.enabled !== "boolean" || Object.hasOwn(value, "disabled") && typeof value.disabled !== "boolean") return value;
|
|
21894
|
+
const { disabled, timeout, ...rest } = value;
|
|
21895
|
+
const lowered = { ...rest };
|
|
21896
|
+
if (!Object.hasOwn(value, "enabled")) lowered.enabled = disabled !== true;
|
|
21897
|
+
else if (value.enabled === disabled) onDropped?.(`${path}.disabled`, "conflict");
|
|
21898
|
+
const lowTimeout = isRecord$1(timeout) ? lowerOpencodeV2Timeout(timeout) : timeout;
|
|
21899
|
+
if (lowTimeout !== void 0) lowered.timeout = lowTimeout;
|
|
21900
|
+
else if (isRecord$1(timeout) && Object.keys(timeout).length > 0) onDropped?.(`${path}.timeout`, "unsupported");
|
|
21901
|
+
if (isRecord$1(value.oauth)) lowered.oauth = lowerOpencodeV2OAuth(value.oauth, `${path}.oauth`, onDropped);
|
|
21902
|
+
return lowered;
|
|
21903
|
+
}
|
|
21904
|
+
function isPositiveInteger(value) {
|
|
21905
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0;
|
|
21906
|
+
}
|
|
21907
|
+
/** Whether each V2 timeout value a record carries is a positive integer. */
|
|
21908
|
+
function hasPositiveIntegerTimeouts(value) {
|
|
21909
|
+
return OPENCODE_V2_TIMEOUT_KEYS.every((key) => value[key] === void 0 || isPositiveInteger(value[key]));
|
|
21910
|
+
}
|
|
21911
|
+
/**
|
|
21912
|
+
* Whether `mcp.timeout` is V2's global timeout object rather than a server
|
|
21913
|
+
* named `timeout`. As in OpenCode V1, each of its values must be a positive
|
|
21914
|
+
* integer; anything else is read as a server, which the schema then rejects.
|
|
21915
|
+
*/
|
|
21916
|
+
function isOpencodeV2GlobalTimeout(value) {
|
|
21917
|
+
return isRecord$1(value) && !isDirectOpencodeMcpServer(value) && (Object.keys(value).length === 0 || OPENCODE_V2_TIMEOUT_KEYS.some((key) => Object.hasOwn(value, key))) && hasPositiveIntegerTimeouts(value);
|
|
21918
|
+
}
|
|
21919
|
+
function getOpencodeV2McpEnvelope(mcp) {
|
|
21920
|
+
const nested = mcp.servers;
|
|
21921
|
+
return isRecord$1(nested) && !isDirectOpencodeMcpServer(nested) ? nested : null;
|
|
21922
|
+
}
|
|
21923
|
+
/**
|
|
21924
|
+
* Returns the paths of the V2-only containers in an OpenCode `mcp` value that
|
|
21925
|
+
* a write in V1's flat shape does not keep: a non-empty `mcp.servers`
|
|
21926
|
+
* envelope, and a non-empty global `mcp.timeout`.
|
|
21927
|
+
*/
|
|
21928
|
+
function findOpencodeV2McpContainers(mcp) {
|
|
21929
|
+
if (!isRecord$1(mcp)) return [];
|
|
21930
|
+
const envelope = getOpencodeV2McpEnvelope(mcp);
|
|
21931
|
+
return [...envelope !== null && Object.keys(envelope).length > 0 ? ["mcp.servers"] : [], ...isOpencodeV2GlobalTimeout(mcp.timeout) && Object.keys(mcp.timeout).length > 0 ? ["mcp.timeout"] : []];
|
|
21932
|
+
}
|
|
21933
|
+
/**
|
|
21934
|
+
* Lowers OpenCode V2 `mcp` spellings found in a V1 config to the flat V1 map,
|
|
21935
|
+
* the way OpenCode V1 itself does since v1.18.24 (`normalizeMcp`):
|
|
21936
|
+
*
|
|
21937
|
+
* - entries of the `mcp.servers` envelope are merged into the map, a flat entry
|
|
21938
|
+
* of the same name winning;
|
|
21939
|
+
* - V2-spelled server entries (`disabled`, an object `timeout`, snake_case
|
|
21940
|
+
* `oauth` keys) are lowered by {@link lowerOpencodeV2Server};
|
|
21941
|
+
* - the global `mcp.timeout` object is skipped. V1 moves it to
|
|
21942
|
+
* `experimental.mcp_timeout`, a default request timeout that has no
|
|
21943
|
+
* canonical counterpart, so it is not read as a server either.
|
|
21944
|
+
*
|
|
21945
|
+
* Unlike V1, an envelope entry that is not a valid server is not dropped: it
|
|
21946
|
+
* is passed on, so the schema rejects it loudly rather than it vanishing
|
|
21947
|
+
* without a word. Each value that is dropped — a non-empty global timeout, a
|
|
21948
|
+
* per-server timeout object or `oauth` key with no V1 equivalent, or an
|
|
21949
|
+
* envelope entry shadowed by a different flat entry — is reported through
|
|
21950
|
+
* `onDropped`.
|
|
21951
|
+
*
|
|
21952
|
+
* @see https://github.com/anomalyco/opencode/blob/v1.18.35/packages/opencode/src/config/v2-compat.ts
|
|
21953
|
+
* @see https://opencode.ai/v2/docs/mcp-servers/
|
|
21954
|
+
*/
|
|
21955
|
+
function lowerOpencodeV2Mcp(mcp, onDropped) {
|
|
21956
|
+
if (!isRecord$1(mcp)) return mcp;
|
|
21957
|
+
const envelope = getOpencodeV2McpEnvelope(mcp);
|
|
21958
|
+
const globalTimeout = isOpencodeV2GlobalTimeout(mcp.timeout);
|
|
21959
|
+
if (findOpencodeV2McpContainers(mcp).includes("mcp.timeout")) onDropped?.("mcp.timeout", "unsupported");
|
|
21960
|
+
const servers = {};
|
|
21961
|
+
for (const [name, value] of Object.entries(mcp)) {
|
|
21962
|
+
if (name === "servers" && envelope !== null || name === "timeout" && globalTimeout) continue;
|
|
21963
|
+
setOwnEntry(servers, name, isRecord$1(value) && isOpencodeV2NativeServer(value) ? lowerOpencodeV2Server(value, `mcp.${name}`, onDropped) : value);
|
|
21964
|
+
}
|
|
21965
|
+
for (const [name, value] of Object.entries(envelope ?? {})) {
|
|
21966
|
+
const path = `mcp.servers.${name}`;
|
|
21967
|
+
if (Object.hasOwn(servers, name)) {
|
|
21968
|
+
if (!isDeepStrictEqual(servers[name], value)) onDropped?.(path, "conflict");
|
|
21969
|
+
continue;
|
|
21970
|
+
}
|
|
21971
|
+
setOwnEntry(servers, name, lowerOpencodeV2Server(value, path, onDropped));
|
|
21972
|
+
}
|
|
21973
|
+
return servers;
|
|
21974
|
+
}
|
|
21814
21975
|
/** Matches a string whose entire value is an OpenCode `{file:...}` reference. */
|
|
21815
21976
|
const OPENCODE_FILE_TEMPLATE_PATTERN = /^\s*\{file:(.+?)\}\s*$/;
|
|
21816
21977
|
/**
|
|
@@ -45559,18 +45720,21 @@ var KiroMcp = class KiroMcp extends ToolMcp {
|
|
|
45559
45720
|
};
|
|
45560
45721
|
//#endregion
|
|
45561
45722
|
//#region src/features/mcp/opencode-mcp.ts
|
|
45723
|
+
const OpencodeMcpV2DisabledSchema = z.optional(z.boolean());
|
|
45562
45724
|
const OpencodeMcpLocalServerSchema = z.looseObject({
|
|
45563
45725
|
type: z.literal("local"),
|
|
45564
45726
|
command: z.array(z.string()),
|
|
45565
45727
|
environment: z.optional(z.record(z.string(), z.string())),
|
|
45566
45728
|
enabled: z._default(z.boolean(), true),
|
|
45729
|
+
disabled: OpencodeMcpV2DisabledSchema,
|
|
45567
45730
|
cwd: z.optional(z.string())
|
|
45568
45731
|
});
|
|
45569
45732
|
const OpencodeMcpRemoteServerSchema = z.looseObject({
|
|
45570
45733
|
type: z.literal("remote"),
|
|
45571
45734
|
url: z.string(),
|
|
45572
45735
|
headers: z.optional(z.record(z.string(), z.string())),
|
|
45573
|
-
enabled: z._default(z.boolean(), true)
|
|
45736
|
+
enabled: z._default(z.boolean(), true),
|
|
45737
|
+
disabled: OpencodeMcpV2DisabledSchema
|
|
45574
45738
|
});
|
|
45575
45739
|
const OPENCODE_PASSTHROUGH_SERVER_FIELDS = [
|
|
45576
45740
|
"timeout",
|
|
@@ -45582,7 +45746,7 @@ const OPENCODE_MCP_TRANSPORT_KEYS = [
|
|
|
45582
45746
|
...Object.keys(OpencodeMcpLocalServerSchema.def.shape),
|
|
45583
45747
|
...Object.keys(OpencodeMcpRemoteServerSchema.def.shape),
|
|
45584
45748
|
...OPENCODE_PASSTHROUGH_SERVER_FIELDS
|
|
45585
|
-
].filter((key) => key !== "enabled");
|
|
45749
|
+
].filter((key) => key !== "enabled" && key !== "disabled");
|
|
45586
45750
|
/**
|
|
45587
45751
|
* A bare toggle entry: `{"enabled": <bool>}` with no transport of its own,
|
|
45588
45752
|
* disabling a server another config layer defines. It is the third member of
|
|
@@ -45710,7 +45874,7 @@ const OPENCODE_TOGGLE_KEPT_KEYS = /* @__PURE__ */ new Set([
|
|
|
45710
45874
|
function warnAboutToggleDroppedKeys(serverName, serverConfig, logger) {
|
|
45711
45875
|
const dropped = Object.keys(serverConfig).filter((key) => !OPENCODE_TOGGLE_KEPT_KEYS.has(key));
|
|
45712
45876
|
if (dropped.length === 0) return;
|
|
45713
|
-
logger?.warn(`OpenCode MCP:
|
|
45877
|
+
logger?.warn(`OpenCode MCP: ${quoteValueForWarning(serverName)} declares no transport, so it is written as a toggle entry and ${dropped.toSorted().map(quoteValueForWarning).join(", ")} ${dropped.length === 1 ? "is" : "are"} dropped.`);
|
|
45714
45878
|
}
|
|
45715
45879
|
/**
|
|
45716
45880
|
* Convert standard MCP format to OpenCode native format
|
|
@@ -45790,9 +45954,35 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45790
45954
|
/** Directory layout; OpenCode forks (MiMo Code) override it. */
|
|
45791
45955
|
static layout = OPENCODE_LAYOUT;
|
|
45792
45956
|
json;
|
|
45793
|
-
|
|
45957
|
+
/**
|
|
45958
|
+
* With a `logger`, the V2 values that lowering the content drops are warned
|
|
45959
|
+
* about (see {@link OpencodeMcp.lowerConfig}); `fromFile` passes one so the
|
|
45960
|
+
* warnings come from the lowering that builds the parsed view rather than
|
|
45961
|
+
* from an extra pass of their own. (`validate()`, which the parent
|
|
45962
|
+
* constructor calls before this view exists, lowers separately and silently.)
|
|
45963
|
+
*/
|
|
45964
|
+
constructor({ logger, ...params }) {
|
|
45794
45965
|
super(params);
|
|
45795
|
-
this.json = OpencodeConfigSchema.parse(parse$1(this.fileContent || "{}"));
|
|
45966
|
+
this.json = OpencodeConfigSchema.parse(this.constructor.lowerConfig(parse$1(this.fileContent || "{}"), logger));
|
|
45967
|
+
}
|
|
45968
|
+
/**
|
|
45969
|
+
* Lowers the OpenCode V2 `mcp` spellings of a parsed config for a layout
|
|
45970
|
+
* that reads them (see {@link lowerOpencodeV2Mcp}), so every reader — import,
|
|
45971
|
+
* the toggle lookup on generate, and the rules feature's `instructions`
|
|
45972
|
+
* write to the same file — accepts a V2-shaped `mcp`. Only the parsed view
|
|
45973
|
+
* is lowered; content written back keeps whatever `mcp` a feature that does
|
|
45974
|
+
* not own the key found there. With a `logger`, each V2 value the lowering
|
|
45975
|
+
* drops is warned about.
|
|
45976
|
+
*/
|
|
45977
|
+
static lowerConfig(json, logger) {
|
|
45978
|
+
if (!this.layout.readsV2ConfigSpellings || !isRecord$1(json) || json.mcp === void 0) return json;
|
|
45979
|
+
return {
|
|
45980
|
+
...json,
|
|
45981
|
+
mcp: lowerOpencodeV2Mcp(json.mcp, (path, reason) => {
|
|
45982
|
+
const quoted = quoteValueForWarning(path);
|
|
45983
|
+
logger?.warn(reason === "conflict" ? `OpenCode MCP: ${quoted} conflicts with a V1 value that takes precedence (the flat "mcp" entry of the same name, or "enabled"), so it is dropped on import.` : `OpenCode MCP: ${quoted} has no Rulesync equivalent, so it is dropped on import.`);
|
|
45984
|
+
})
|
|
45985
|
+
};
|
|
45796
45986
|
}
|
|
45797
45987
|
getJson() {
|
|
45798
45988
|
return this.json;
|
|
@@ -45809,7 +45999,7 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45809
45999
|
relativeFilePath: this.layout.jsonFileName
|
|
45810
46000
|
};
|
|
45811
46001
|
}
|
|
45812
|
-
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
46002
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false, logger }) {
|
|
45813
46003
|
const basePaths = this.getSettablePaths({ global });
|
|
45814
46004
|
const jsonDir = join(outputRoot, basePaths.relativeDirPath);
|
|
45815
46005
|
let fileContent = null;
|
|
@@ -45831,7 +46021,8 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45831
46021
|
relativeDirPath: basePaths.relativeDirPath,
|
|
45832
46022
|
relativeFilePath,
|
|
45833
46023
|
fileContent: JSON.stringify(newJson, null, 2),
|
|
45834
|
-
validate
|
|
46024
|
+
validate,
|
|
46025
|
+
logger
|
|
45835
46026
|
});
|
|
45836
46027
|
}
|
|
45837
46028
|
static async fromRulesyncMcp({ outputRoot = process.cwd(), rulesyncMcp, validate = true, global = false, logger }) {
|
|
@@ -45850,7 +46041,12 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45850
46041
|
mcpServers: rulesyncMcp.getMcpServers(),
|
|
45851
46042
|
replacement: "{env:$1}"
|
|
45852
46043
|
});
|
|
45853
|
-
const
|
|
46044
|
+
const existingJson = parse$1(fileContent || "{}");
|
|
46045
|
+
const existingMcp = OpencodeConfigSchema.safeParse(this.lowerConfig(existingJson));
|
|
46046
|
+
if (this.layout.readsV2ConfigSpellings && isRecord$1(existingJson)) {
|
|
46047
|
+
const containers = findOpencodeV2McpContainers(existingJson.mcp);
|
|
46048
|
+
if (containers.length > 0) logger?.warn(`OpenCode MCP: the whole "mcp" key is rewritten in the flat V1 shape, so ${containers.map(quoteValueForWarning).join(" and ")} ${containers.length === 1 ? "is" : "are"} not kept.`);
|
|
46049
|
+
}
|
|
45854
46050
|
const { mcp: convertedMcp, tools: mcpTools } = convertToOpencodeFormat(transformedServers, (existingMcp.success ? existingMcp.data.mcp : void 0) ?? {}, logger);
|
|
45855
46051
|
return new this({
|
|
45856
46052
|
outputRoot,
|
|
@@ -45950,7 +46146,7 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45950
46146
|
}
|
|
45951
46147
|
validate() {
|
|
45952
46148
|
const json = parseJsonc(this.fileContent || "{}");
|
|
45953
|
-
const result = OpencodeConfigSchema.safeParse(json);
|
|
46149
|
+
const result = OpencodeConfigSchema.safeParse(this.constructor.lowerConfig(json));
|
|
45954
46150
|
if (!result.success) return {
|
|
45955
46151
|
success: false,
|
|
45956
46152
|
error: result.error
|
|
@@ -101732,4 +101928,4 @@ async function importChecksCore(params) {
|
|
|
101732
101928
|
//#endregion
|
|
101733
101929
|
export { RulesyncHooks as $, removeFile as $t, groupSpellingsByCaseFoldedIdentity as A, RULESYNC_RELATIVE_DIR_PATH as An, applyFileMode as At, QWENCODE_LOCAL_RULE_FILE_NAME as B, DEPRECATED_FEATURE_REPLACEMENTS as Bn, getFileSize as Bt, COMMANDCODE_SETTINGS_LOCAL_FILE_NAME as C, RULESYNC_IGNORE_RELATIVE_FILE_PATH as Cn, fallbackLogger as Ct, FACTORYDROID_DIR as D, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as Dn, withWarnOnceScope as Dt, ChecksProcessor as E, RULESYNC_MCP_SCHEMA_URL as En, resetRunWarningState as Et, CLAUDECODE_LOCAL_RULE_FILE_NAME as F, RULESYNC_USER_CONFIG_DIR_NAME as Fn, createTempDirectory as Ft, RulesyncSubagentFrontmatterSchema as G, quoteForLog as Gn, listDirectoryEntryNames as Gt, AUGMENTCODE_SETTINGS_LOCAL_FILE_NAME as H, truncateText as Hn, isFileNotFoundError as Ht, CLAUDECODE_MEMORIES_DIR_NAME as I, RULESYNC_XDG_CONFIG_HOME_DEFAULT_DIR_NAME as In, directoryExists as It, RulesyncRule as J, stripHiddenCharacters as Jn, pathEscapesRoot as Jt, RulesyncSkill as K, stripControlCharacters as Kn, listFilePathsRecursively as Kt, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as L, parseCommaSeparatedList as Ln, ensureDir as Lt, CODEXCLI_DIR as M, RULESYNC_SKILLS_RELATIVE_DIR_PATH as Mn, assertTreeContainsNoSymlinks as Mt, CLAUDECODE_AGENT_MEMORY_LOCAL_DIR_NAME as N, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as Nn, assertWritablePathInsideRoot as Nt, FACTORYDROID_SETTINGS_LOCAL_FILE_NAME as O, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as On, CLIError as Ot, CLAUDECODE_DIR as P, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as Pn, checkPathTraversal as Pt, RulesyncIgnore as Q, removeDirectoryStrict as Qt, CLAUDECODE_SKILLS_DIR_PATH as R, ALL_FEATURES as Rn, fileExists as Rt, COMMANDCODE_DIR as S, RULESYNC_HOOKS_RELATIVE_FILE_PATH as Sn, WarningCollectingLogger as St, CODEBUDDY_LOCAL_RULE_FILE_NAME as T, RULESYNC_MCP_RELATIVE_FILE_PATH as Tn, withFallbackLoggerTarget as Tt, getLocalSkillDirNames as U, hasDeceptiveHiddenCharacters as Un, isFileSystemError as Ut, AUGMENTCODE_DIR as V, formatError as Vn, getHomeDirectory as Vt, RulesyncSubagent as W, hasEnclosingMarkOutsideKeycap as Wn, isSymlink as Wt, RulesyncPermissions as X, readFileContentOrNull as Xt, RulesyncRuleFrontmatterSchema as Y, readFileContent as Yt, RulesyncMcp as Z, removeDirectory as Zt, LETTACODE_DIR as _, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as _n, SourceEntrySchema as _t, getProcessorRegistryEntry as a, toPosixPath as an, RulesyncCheck as at, CommandsProcessor as b, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as bn, ConsoleLogger as bt, RulesProcessor as c, ALL_TOOL_TARGETS as cn, loadYaml as ct, ELLIPSIS_WIDTH as d, ToolTargetSchema as dn, ConfigResolver as dt, removeFileStrict as en, getRulesyncSourceCandidates as et, displayWidthOf as f, CURATED_RULES_FEATURE_SUBDIR as fn, mergeInputRootConfigs as ft, HooksProcessor as g, RULESYNC_CHECKS_RELATIVE_DIR_PATH as gn, GITIGNORE_DESTINATION_KEY as gt, IgnoreProcessor as h, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as hn, ConfigFileSchema as ht, inspectInputRoots as i, splitPathSegments as in, RulesyncCommandFrontmatterSchema as it, CODEXCLI_BASH_RULES_FILE_NAME as j, RULESYNC_RULES_RELATIVE_DIR_PATH as jn, assertDirectoryIfExists as jt, caseFoldIdentity as k, RULESYNC_PERMISSIONS_SCHEMA_URL as kn, ErrorCodes as kt, SubagentsProcessor as l, ALL_TOOL_TARGETS_WITH_WILDCARD as ln, SHARED_USER_MANAGED_CONFIG_PATHS as lt, McpProcessor as m, MAX_FILE_SIZE as mn, CONFLICTING_TARGET_PAIRS as mt, formatSourceLoadFailure as n, resolvePath as nn, parseJsonc as nt, convertFromTool as o, writeFileBuffer as on, RulesyncCheckFrontmatterSchema as ot, shortenToWidth as p, FEATURE_SOURCE_TREE_ENTRIES as pn, resolveEffectiveInputRoots as pt, RulesyncSkillFrontmatterSchema as q, stripControlCharactersKeepingLineFeeds as qn, listSubdirectoryNames as qt, generate as r, runWithDirectoryRollback as rn, RulesyncCommand as rt, isPackagingToolTarget as s, writeFileContent as sn, stringifyFrontmatter as st, importFromTool as t, removeTempDirectory as tn, resolveRulesyncSourceWritePath as tt, SkillsProcessor as u, PACKAGING_TOOL_TARGETS as un, SKILL_FILE_NAME as ut, LETTACODE_SETTINGS_LOCAL_FILE_NAME as v, RULESYNC_CONFIG_RELATIVE_FILE_PATH as vn, assertTargetsFeaturesExclusive as vt, CODEBUDDY_DIR as w, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as wn, warnOnConflictingFlags as wt, REASONIX_LOCAL_RULE_FILE_NAME as x, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as xn, JsonLogger as xt, CRUSH_LOCAL_RULE_FILE_NAME as y, RULESYNC_CONFIG_SCHEMA_URL as yn, findControlCharacter as yt, QWENCODE_DIR as z, ALL_FEATURES_WITH_WILDCARD as zn, findFilesByGlobs as zt };
|
|
101734
101930
|
|
|
101735
|
-
//# sourceMappingURL=import-
|
|
101931
|
+
//# sourceMappingURL=import-5-Uennl1.js.map
|