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
|
@@ -21766,22 +21766,29 @@ function mergeOpencodeV2Entries({ config, legacyKey, pluralKey, lower }) {
|
|
|
21766
21766
|
const entry = asOpencodeEntries(value);
|
|
21767
21767
|
const lowered = entry === null ? null : lower(entry);
|
|
21768
21768
|
if (Object.hasOwn(merged, name) || lowered === null) continue;
|
|
21769
|
-
|
|
21770
|
-
value: lowered,
|
|
21771
|
-
enumerable: true,
|
|
21772
|
-
configurable: true,
|
|
21773
|
-
writable: true
|
|
21774
|
-
});
|
|
21769
|
+
setOwnEntry(merged, name, lowered);
|
|
21775
21770
|
}
|
|
21776
21771
|
return Object.keys(merged).length > 0 ? merged : legacy;
|
|
21777
21772
|
}
|
|
21778
21773
|
/**
|
|
21774
|
+
* Sets `target[key]` as an own, enumerable property. A plain assignment to a
|
|
21775
|
+
* key named `__proto__` would set the prototype instead.
|
|
21776
|
+
*/
|
|
21777
|
+
function setOwnEntry(target, key, value) {
|
|
21778
|
+
Object.defineProperty(target, key, {
|
|
21779
|
+
value,
|
|
21780
|
+
enumerable: true,
|
|
21781
|
+
configurable: true,
|
|
21782
|
+
writable: true
|
|
21783
|
+
});
|
|
21784
|
+
}
|
|
21785
|
+
/**
|
|
21779
21786
|
* Returns the inline agent entries of an OpenCode config in the V1 `agent`
|
|
21780
21787
|
* shape. Since v1.18.24 OpenCode V1 also reads the V2 `agents` spelling and
|
|
21781
21788
|
* lowers it, so a layout that does so (`readsV2ConfigSpellings`) gets those
|
|
21782
21789
|
* entries too.
|
|
21783
21790
|
*
|
|
21784
|
-
* @see https://github.com/anomalyco/opencode/blob/v1.18.
|
|
21791
|
+
* @see https://github.com/anomalyco/opencode/blob/v1.18.35/packages/opencode/src/config/v2-compat.ts
|
|
21785
21792
|
*/
|
|
21786
21793
|
function getOpencodeAgentEntries({ config, layout = OPENCODE_LAYOUT }) {
|
|
21787
21794
|
if (!layout.readsV2ConfigSpellings) return asOpencodeEntries(config.agent);
|
|
@@ -21800,7 +21807,7 @@ function getOpencodeAgentEntries({ config, layout = OPENCODE_LAYOUT }) {
|
|
|
21800
21807
|
* Other fields are kept: V1 drops a V2 `subagent`, but rulesync reads it as
|
|
21801
21808
|
* `subtask` everywhere (as V2 does), so it is left for the command importer.
|
|
21802
21809
|
*
|
|
21803
|
-
* @see https://github.com/anomalyco/opencode/blob/v1.18.
|
|
21810
|
+
* @see https://github.com/anomalyco/opencode/blob/v1.18.35/packages/opencode/src/config/v2-compat.ts
|
|
21804
21811
|
*/
|
|
21805
21812
|
function getOpencodeCommandEntries({ config, layout = OPENCODE_LAYOUT }) {
|
|
21806
21813
|
if (!layout.readsV2ConfigSpellings) return asOpencodeEntries(config.command);
|
|
@@ -21823,7 +21830,7 @@ function getOpencodeCommandEntries({ config, layout = OPENCODE_LAYOUT }) {
|
|
|
21823
21830
|
* reads V2 spellings, a flat V2 `skills` array is accepted too: its entries
|
|
21824
21831
|
* that are not `http(s)://` URLs are the paths, as OpenCode V1 lowers them.
|
|
21825
21832
|
*
|
|
21826
|
-
* @see https://github.com/anomalyco/opencode/blob/v1.18.
|
|
21833
|
+
* @see https://github.com/anomalyco/opencode/blob/v1.18.35/packages/opencode/src/config/v2-compat.ts
|
|
21827
21834
|
*/
|
|
21828
21835
|
function getOpencodeSkillPaths({ config, layout = OPENCODE_LAYOUT }) {
|
|
21829
21836
|
if (Array.isArray(config.skills)) {
|
|
@@ -21833,6 +21840,160 @@ function getOpencodeSkillPaths({ config, layout = OPENCODE_LAYOUT }) {
|
|
|
21833
21840
|
const skills = asOpencodeEntries(config.skills);
|
|
21834
21841
|
return skills !== null && Array.isArray(skills.paths) ? skills.paths : [];
|
|
21835
21842
|
}
|
|
21843
|
+
/**
|
|
21844
|
+
* Whether a record is itself an MCP server entry rather than a V2 container
|
|
21845
|
+
* (`mcp.servers`, `mcp.timeout`): a server — or a server literally named
|
|
21846
|
+
* `type` / `enabled` — carries a scalar `type` or `enabled`. Mirrors OpenCode
|
|
21847
|
+
* V1's `isDirectServer`.
|
|
21848
|
+
*/
|
|
21849
|
+
function isDirectOpencodeMcpServer(value) {
|
|
21850
|
+
return ["type", "enabled"].some((key) => Object.hasOwn(value, key) && (value[key] === null || typeof value[key] !== "object" || Array.isArray(value[key])));
|
|
21851
|
+
}
|
|
21852
|
+
const OPENCODE_V2_TIMEOUT_KEYS = [
|
|
21853
|
+
"startup",
|
|
21854
|
+
"catalog",
|
|
21855
|
+
"execution"
|
|
21856
|
+
];
|
|
21857
|
+
/**
|
|
21858
|
+
* Whether an MCP server entry uses a V2-only per-server spelling, so that
|
|
21859
|
+
* OpenCode V1 lowers it: `disabled`, `codemode`, an object `timeout`, or a
|
|
21860
|
+
* snake_case `oauth` key.
|
|
21861
|
+
*/
|
|
21862
|
+
function isOpencodeV2NativeServer(value) {
|
|
21863
|
+
const oauth = value.oauth;
|
|
21864
|
+
return Object.hasOwn(value, "disabled") || Object.hasOwn(value, "codemode") || isRecord$1(value.timeout) || isRecord$1(oauth) && [
|
|
21865
|
+
"client_id",
|
|
21866
|
+
"client_secret",
|
|
21867
|
+
"callback_port",
|
|
21868
|
+
"redirect_uri"
|
|
21869
|
+
].some((key) => Object.hasOwn(oauth, key));
|
|
21870
|
+
}
|
|
21871
|
+
/**
|
|
21872
|
+
* Lowers a V2 timeout object (`{ startup, catalog, execution }`) to V1's single
|
|
21873
|
+
* number, the way OpenCode V1 does: only a `catalog` equal to `execution`, with
|
|
21874
|
+
* no `startup`, has a V1 equivalent. Anything else — including a value that is
|
|
21875
|
+
* not a positive integer — is `undefined` (dropped).
|
|
21876
|
+
*/
|
|
21877
|
+
function lowerOpencodeV2Timeout(value) {
|
|
21878
|
+
if (!hasPositiveIntegerTimeouts(value) || value.startup !== void 0 || typeof value.catalog !== "number") return;
|
|
21879
|
+
return value.catalog === value.execution ? value.catalog : void 0;
|
|
21880
|
+
}
|
|
21881
|
+
const OPENCODE_V2_OAUTH_KEYS = /* @__PURE__ */ new Map([
|
|
21882
|
+
["client_id", "clientId"],
|
|
21883
|
+
["client_secret", "clientSecret"],
|
|
21884
|
+
["callback_port", "callbackPort"],
|
|
21885
|
+
["redirect_uri", "redirectUri"]
|
|
21886
|
+
]);
|
|
21887
|
+
/**
|
|
21888
|
+
* V2 `oauth` keys that have no V1 spelling. OpenCode V1 drops them when it
|
|
21889
|
+
* lowers a server, so they are dropped (and reported) here too rather than
|
|
21890
|
+
* being written back as a snake_case key among camelCase ones.
|
|
21891
|
+
*/
|
|
21892
|
+
const OPENCODE_V2_UNSUPPORTED_OAUTH_KEYS = /* @__PURE__ */ new Set(["auth_server_metadata_url"]);
|
|
21893
|
+
function lowerOpencodeV2OAuth(oauth, path, onDropped) {
|
|
21894
|
+
const lowered = {};
|
|
21895
|
+
for (const [key, value] of Object.entries(oauth)) {
|
|
21896
|
+
if (OPENCODE_V2_UNSUPPORTED_OAUTH_KEYS.has(key)) {
|
|
21897
|
+
onDropped?.(`${path}.${key}`, "unsupported");
|
|
21898
|
+
continue;
|
|
21899
|
+
}
|
|
21900
|
+
setOwnEntry(lowered, OPENCODE_V2_OAUTH_KEYS.get(key) ?? key, value);
|
|
21901
|
+
}
|
|
21902
|
+
return lowered;
|
|
21903
|
+
}
|
|
21904
|
+
/**
|
|
21905
|
+
* Lowers one V2-spelled MCP server entry to V1's shape, as OpenCode V1 does:
|
|
21906
|
+
* `disabled` becomes `enabled` (an explicit `enabled` wins), an object
|
|
21907
|
+
* `timeout` becomes a number or is dropped, and snake_case `oauth` keys become
|
|
21908
|
+
* camelCase. `codemode` is kept: Rulesync passes it through where V1 drops it.
|
|
21909
|
+
*
|
|
21910
|
+
* Like V1, only an entry that is a local or remote server is lowered, and one
|
|
21911
|
+
* whose `enabled` or `disabled` is not a boolean is left as it is. Unlike V1,
|
|
21912
|
+
* such an entry is not dropped but passed on, so the schema rejects it loudly.
|
|
21913
|
+
*/
|
|
21914
|
+
function lowerOpencodeV2Server(value, path, onDropped) {
|
|
21915
|
+
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;
|
|
21916
|
+
const { disabled, timeout, ...rest } = value;
|
|
21917
|
+
const lowered = { ...rest };
|
|
21918
|
+
if (!Object.hasOwn(value, "enabled")) lowered.enabled = disabled !== true;
|
|
21919
|
+
else if (value.enabled === disabled) onDropped?.(`${path}.disabled`, "conflict");
|
|
21920
|
+
const lowTimeout = isRecord$1(timeout) ? lowerOpencodeV2Timeout(timeout) : timeout;
|
|
21921
|
+
if (lowTimeout !== void 0) lowered.timeout = lowTimeout;
|
|
21922
|
+
else if (isRecord$1(timeout) && Object.keys(timeout).length > 0) onDropped?.(`${path}.timeout`, "unsupported");
|
|
21923
|
+
if (isRecord$1(value.oauth)) lowered.oauth = lowerOpencodeV2OAuth(value.oauth, `${path}.oauth`, onDropped);
|
|
21924
|
+
return lowered;
|
|
21925
|
+
}
|
|
21926
|
+
function isPositiveInteger(value) {
|
|
21927
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0;
|
|
21928
|
+
}
|
|
21929
|
+
/** Whether each V2 timeout value a record carries is a positive integer. */
|
|
21930
|
+
function hasPositiveIntegerTimeouts(value) {
|
|
21931
|
+
return OPENCODE_V2_TIMEOUT_KEYS.every((key) => value[key] === void 0 || isPositiveInteger(value[key]));
|
|
21932
|
+
}
|
|
21933
|
+
/**
|
|
21934
|
+
* Whether `mcp.timeout` is V2's global timeout object rather than a server
|
|
21935
|
+
* named `timeout`. As in OpenCode V1, each of its values must be a positive
|
|
21936
|
+
* integer; anything else is read as a server, which the schema then rejects.
|
|
21937
|
+
*/
|
|
21938
|
+
function isOpencodeV2GlobalTimeout(value) {
|
|
21939
|
+
return isRecord$1(value) && !isDirectOpencodeMcpServer(value) && (Object.keys(value).length === 0 || OPENCODE_V2_TIMEOUT_KEYS.some((key) => Object.hasOwn(value, key))) && hasPositiveIntegerTimeouts(value);
|
|
21940
|
+
}
|
|
21941
|
+
function getOpencodeV2McpEnvelope(mcp) {
|
|
21942
|
+
const nested = mcp.servers;
|
|
21943
|
+
return isRecord$1(nested) && !isDirectOpencodeMcpServer(nested) ? nested : null;
|
|
21944
|
+
}
|
|
21945
|
+
/**
|
|
21946
|
+
* Returns the paths of the V2-only containers in an OpenCode `mcp` value that
|
|
21947
|
+
* a write in V1's flat shape does not keep: a non-empty `mcp.servers`
|
|
21948
|
+
* envelope, and a non-empty global `mcp.timeout`.
|
|
21949
|
+
*/
|
|
21950
|
+
function findOpencodeV2McpContainers(mcp) {
|
|
21951
|
+
if (!isRecord$1(mcp)) return [];
|
|
21952
|
+
const envelope = getOpencodeV2McpEnvelope(mcp);
|
|
21953
|
+
return [...envelope !== null && Object.keys(envelope).length > 0 ? ["mcp.servers"] : [], ...isOpencodeV2GlobalTimeout(mcp.timeout) && Object.keys(mcp.timeout).length > 0 ? ["mcp.timeout"] : []];
|
|
21954
|
+
}
|
|
21955
|
+
/**
|
|
21956
|
+
* Lowers OpenCode V2 `mcp` spellings found in a V1 config to the flat V1 map,
|
|
21957
|
+
* the way OpenCode V1 itself does since v1.18.24 (`normalizeMcp`):
|
|
21958
|
+
*
|
|
21959
|
+
* - entries of the `mcp.servers` envelope are merged into the map, a flat entry
|
|
21960
|
+
* of the same name winning;
|
|
21961
|
+
* - V2-spelled server entries (`disabled`, an object `timeout`, snake_case
|
|
21962
|
+
* `oauth` keys) are lowered by {@link lowerOpencodeV2Server};
|
|
21963
|
+
* - the global `mcp.timeout` object is skipped. V1 moves it to
|
|
21964
|
+
* `experimental.mcp_timeout`, a default request timeout that has no
|
|
21965
|
+
* canonical counterpart, so it is not read as a server either.
|
|
21966
|
+
*
|
|
21967
|
+
* Unlike V1, an envelope entry that is not a valid server is not dropped: it
|
|
21968
|
+
* is passed on, so the schema rejects it loudly rather than it vanishing
|
|
21969
|
+
* without a word. Each value that is dropped — a non-empty global timeout, a
|
|
21970
|
+
* per-server timeout object or `oauth` key with no V1 equivalent, or an
|
|
21971
|
+
* envelope entry shadowed by a different flat entry — is reported through
|
|
21972
|
+
* `onDropped`.
|
|
21973
|
+
*
|
|
21974
|
+
* @see https://github.com/anomalyco/opencode/blob/v1.18.35/packages/opencode/src/config/v2-compat.ts
|
|
21975
|
+
* @see https://opencode.ai/v2/docs/mcp-servers/
|
|
21976
|
+
*/
|
|
21977
|
+
function lowerOpencodeV2Mcp(mcp, onDropped) {
|
|
21978
|
+
if (!isRecord$1(mcp)) return mcp;
|
|
21979
|
+
const envelope = getOpencodeV2McpEnvelope(mcp);
|
|
21980
|
+
const globalTimeout = isOpencodeV2GlobalTimeout(mcp.timeout);
|
|
21981
|
+
if (findOpencodeV2McpContainers(mcp).includes("mcp.timeout")) onDropped?.("mcp.timeout", "unsupported");
|
|
21982
|
+
const servers = {};
|
|
21983
|
+
for (const [name, value] of Object.entries(mcp)) {
|
|
21984
|
+
if (name === "servers" && envelope !== null || name === "timeout" && globalTimeout) continue;
|
|
21985
|
+
setOwnEntry(servers, name, isRecord$1(value) && isOpencodeV2NativeServer(value) ? lowerOpencodeV2Server(value, `mcp.${name}`, onDropped) : value);
|
|
21986
|
+
}
|
|
21987
|
+
for (const [name, value] of Object.entries(envelope ?? {})) {
|
|
21988
|
+
const path = `mcp.servers.${name}`;
|
|
21989
|
+
if (Object.hasOwn(servers, name)) {
|
|
21990
|
+
if (!(0, node_util.isDeepStrictEqual)(servers[name], value)) onDropped?.(path, "conflict");
|
|
21991
|
+
continue;
|
|
21992
|
+
}
|
|
21993
|
+
setOwnEntry(servers, name, lowerOpencodeV2Server(value, path, onDropped));
|
|
21994
|
+
}
|
|
21995
|
+
return servers;
|
|
21996
|
+
}
|
|
21836
21997
|
/** Matches a string whose entire value is an OpenCode `{file:...}` reference. */
|
|
21837
21998
|
const OPENCODE_FILE_TEMPLATE_PATTERN = /^\s*\{file:(.+?)\}\s*$/;
|
|
21838
21999
|
/**
|
|
@@ -45581,18 +45742,21 @@ var KiroMcp = class KiroMcp extends ToolMcp {
|
|
|
45581
45742
|
};
|
|
45582
45743
|
//#endregion
|
|
45583
45744
|
//#region src/features/mcp/opencode-mcp.ts
|
|
45745
|
+
const OpencodeMcpV2DisabledSchema = zod_mini.z.optional(zod_mini.z.boolean());
|
|
45584
45746
|
const OpencodeMcpLocalServerSchema = zod_mini.z.looseObject({
|
|
45585
45747
|
type: zod_mini.z.literal("local"),
|
|
45586
45748
|
command: zod_mini.z.array(zod_mini.z.string()),
|
|
45587
45749
|
environment: zod_mini.z.optional(zod_mini.z.record(zod_mini.z.string(), zod_mini.z.string())),
|
|
45588
45750
|
enabled: zod_mini.z._default(zod_mini.z.boolean(), true),
|
|
45751
|
+
disabled: OpencodeMcpV2DisabledSchema,
|
|
45589
45752
|
cwd: zod_mini.z.optional(zod_mini.z.string())
|
|
45590
45753
|
});
|
|
45591
45754
|
const OpencodeMcpRemoteServerSchema = zod_mini.z.looseObject({
|
|
45592
45755
|
type: zod_mini.z.literal("remote"),
|
|
45593
45756
|
url: zod_mini.z.string(),
|
|
45594
45757
|
headers: zod_mini.z.optional(zod_mini.z.record(zod_mini.z.string(), zod_mini.z.string())),
|
|
45595
|
-
enabled: zod_mini.z._default(zod_mini.z.boolean(), true)
|
|
45758
|
+
enabled: zod_mini.z._default(zod_mini.z.boolean(), true),
|
|
45759
|
+
disabled: OpencodeMcpV2DisabledSchema
|
|
45596
45760
|
});
|
|
45597
45761
|
const OPENCODE_PASSTHROUGH_SERVER_FIELDS = [
|
|
45598
45762
|
"timeout",
|
|
@@ -45604,7 +45768,7 @@ const OPENCODE_MCP_TRANSPORT_KEYS = [
|
|
|
45604
45768
|
...Object.keys(OpencodeMcpLocalServerSchema.def.shape),
|
|
45605
45769
|
...Object.keys(OpencodeMcpRemoteServerSchema.def.shape),
|
|
45606
45770
|
...OPENCODE_PASSTHROUGH_SERVER_FIELDS
|
|
45607
|
-
].filter((key) => key !== "enabled");
|
|
45771
|
+
].filter((key) => key !== "enabled" && key !== "disabled");
|
|
45608
45772
|
/**
|
|
45609
45773
|
* A bare toggle entry: `{"enabled": <bool>}` with no transport of its own,
|
|
45610
45774
|
* disabling a server another config layer defines. It is the third member of
|
|
@@ -45732,7 +45896,7 @@ const OPENCODE_TOGGLE_KEPT_KEYS = /* @__PURE__ */ new Set([
|
|
|
45732
45896
|
function warnAboutToggleDroppedKeys(serverName, serverConfig, logger) {
|
|
45733
45897
|
const dropped = Object.keys(serverConfig).filter((key) => !OPENCODE_TOGGLE_KEPT_KEYS.has(key));
|
|
45734
45898
|
if (dropped.length === 0) return;
|
|
45735
|
-
logger?.warn(`OpenCode MCP:
|
|
45899
|
+
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.`);
|
|
45736
45900
|
}
|
|
45737
45901
|
/**
|
|
45738
45902
|
* Convert standard MCP format to OpenCode native format
|
|
@@ -45812,9 +45976,35 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45812
45976
|
/** Directory layout; OpenCode forks (MiMo Code) override it. */
|
|
45813
45977
|
static layout = OPENCODE_LAYOUT;
|
|
45814
45978
|
json;
|
|
45815
|
-
|
|
45979
|
+
/**
|
|
45980
|
+
* With a `logger`, the V2 values that lowering the content drops are warned
|
|
45981
|
+
* about (see {@link OpencodeMcp.lowerConfig}); `fromFile` passes one so the
|
|
45982
|
+
* warnings come from the lowering that builds the parsed view rather than
|
|
45983
|
+
* from an extra pass of their own. (`validate()`, which the parent
|
|
45984
|
+
* constructor calls before this view exists, lowers separately and silently.)
|
|
45985
|
+
*/
|
|
45986
|
+
constructor({ logger, ...params }) {
|
|
45816
45987
|
super(params);
|
|
45817
|
-
this.json = OpencodeConfigSchema.parse((0, jsonc_parser.parse)(this.fileContent || "{}"));
|
|
45988
|
+
this.json = OpencodeConfigSchema.parse(this.constructor.lowerConfig((0, jsonc_parser.parse)(this.fileContent || "{}"), logger));
|
|
45989
|
+
}
|
|
45990
|
+
/**
|
|
45991
|
+
* Lowers the OpenCode V2 `mcp` spellings of a parsed config for a layout
|
|
45992
|
+
* that reads them (see {@link lowerOpencodeV2Mcp}), so every reader — import,
|
|
45993
|
+
* the toggle lookup on generate, and the rules feature's `instructions`
|
|
45994
|
+
* write to the same file — accepts a V2-shaped `mcp`. Only the parsed view
|
|
45995
|
+
* is lowered; content written back keeps whatever `mcp` a feature that does
|
|
45996
|
+
* not own the key found there. With a `logger`, each V2 value the lowering
|
|
45997
|
+
* drops is warned about.
|
|
45998
|
+
*/
|
|
45999
|
+
static lowerConfig(json, logger) {
|
|
46000
|
+
if (!this.layout.readsV2ConfigSpellings || !isRecord$1(json) || json.mcp === void 0) return json;
|
|
46001
|
+
return {
|
|
46002
|
+
...json,
|
|
46003
|
+
mcp: lowerOpencodeV2Mcp(json.mcp, (path, reason) => {
|
|
46004
|
+
const quoted = quoteValueForWarning(path);
|
|
46005
|
+
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.`);
|
|
46006
|
+
})
|
|
46007
|
+
};
|
|
45818
46008
|
}
|
|
45819
46009
|
getJson() {
|
|
45820
46010
|
return this.json;
|
|
@@ -45831,7 +46021,7 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45831
46021
|
relativeFilePath: this.layout.jsonFileName
|
|
45832
46022
|
};
|
|
45833
46023
|
}
|
|
45834
|
-
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
46024
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false, logger }) {
|
|
45835
46025
|
const basePaths = this.getSettablePaths({ global });
|
|
45836
46026
|
const jsonDir = (0, node_path.join)(outputRoot, basePaths.relativeDirPath);
|
|
45837
46027
|
let fileContent = null;
|
|
@@ -45853,7 +46043,8 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45853
46043
|
relativeDirPath: basePaths.relativeDirPath,
|
|
45854
46044
|
relativeFilePath,
|
|
45855
46045
|
fileContent: JSON.stringify(newJson, null, 2),
|
|
45856
|
-
validate
|
|
46046
|
+
validate,
|
|
46047
|
+
logger
|
|
45857
46048
|
});
|
|
45858
46049
|
}
|
|
45859
46050
|
static async fromRulesyncMcp({ outputRoot = process.cwd(), rulesyncMcp, validate = true, global = false, logger }) {
|
|
@@ -45872,7 +46063,12 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45872
46063
|
mcpServers: rulesyncMcp.getMcpServers(),
|
|
45873
46064
|
replacement: "{env:$1}"
|
|
45874
46065
|
});
|
|
45875
|
-
const
|
|
46066
|
+
const existingJson = (0, jsonc_parser.parse)(fileContent || "{}");
|
|
46067
|
+
const existingMcp = OpencodeConfigSchema.safeParse(this.lowerConfig(existingJson));
|
|
46068
|
+
if (this.layout.readsV2ConfigSpellings && isRecord$1(existingJson)) {
|
|
46069
|
+
const containers = findOpencodeV2McpContainers(existingJson.mcp);
|
|
46070
|
+
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.`);
|
|
46071
|
+
}
|
|
45876
46072
|
const { mcp: convertedMcp, tools: mcpTools } = convertToOpencodeFormat(transformedServers, (existingMcp.success ? existingMcp.data.mcp : void 0) ?? {}, logger);
|
|
45877
46073
|
return new this({
|
|
45878
46074
|
outputRoot,
|
|
@@ -45972,7 +46168,7 @@ var OpencodeMcp = class extends ToolMcp {
|
|
|
45972
46168
|
}
|
|
45973
46169
|
validate() {
|
|
45974
46170
|
const json = parseJsonc$6(this.fileContent || "{}");
|
|
45975
|
-
const result = OpencodeConfigSchema.safeParse(json);
|
|
46171
|
+
const result = OpencodeConfigSchema.safeParse(this.constructor.lowerConfig(json));
|
|
45976
46172
|
if (!result.success) return {
|
|
45977
46173
|
success: false,
|
|
45978
46174
|
error: result.error
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_import = require("./import-
|
|
2
|
+
const require_import = require("./import-D_SV_C0k.cjs");
|
|
3
3
|
//#region src/index.ts
|
|
4
4
|
async function generate(options = {}) {
|
|
5
5
|
const { silent = true, verbose = false, ...rest } = options;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Rn as ALL_FEATURES, bt as ConsoleLogger, cn as ALL_TOOL_TARGETS, dt as ConfigResolver, i as inspectInputRoots, o as convertFromTool$1, r as generate$1, t as importFromTool$1 } from "./import-
|
|
1
|
+
import { Rn as ALL_FEATURES, bt as ConsoleLogger, cn as ALL_TOOL_TARGETS, dt as ConfigResolver, i as inspectInputRoots, o as convertFromTool$1, r as generate$1, t as importFromTool$1 } from "./import-5-Uennl1.js";
|
|
2
2
|
//#region src/index.ts
|
|
3
3
|
async function generate(options = {}) {
|
|
4
4
|
const { silent = true, verbose = false, ...rest } = options;
|