rulesync 16.37.0 → 16.38.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/README.md +1 -1
- package/dist/cli/index.cjs +4 -4
- package/dist/cli/index.js +4 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-BnF2J75x.js → import-BiyWNVZY.js} +394 -36
- package/dist/import-BiyWNVZY.js.map +1 -0
- package/dist/{import-xo5me5dm.cjs → import-DKBaTqsY.cjs} +410 -52
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/import-BnF2J75x.js.map +0 -1
|
@@ -591,6 +591,7 @@ const mcpProcessorToolTargetTuple = [
|
|
|
591
591
|
"junie",
|
|
592
592
|
"musecode",
|
|
593
593
|
"opencode",
|
|
594
|
+
"pool",
|
|
594
595
|
"qwencode",
|
|
595
596
|
"reasonix",
|
|
596
597
|
"roo",
|
|
@@ -3304,6 +3305,8 @@ const SHARED_USER_MANAGED_CONFIG_PATHS = [
|
|
|
3304
3305
|
".grok/config.toml",
|
|
3305
3306
|
".rovodev/config.yml",
|
|
3306
3307
|
".rovodev/mcp.json",
|
|
3308
|
+
".poolside/settings.yaml",
|
|
3309
|
+
".config/poolside/settings.yaml",
|
|
3307
3310
|
".tabnine/agent/settings.json",
|
|
3308
3311
|
".vibe/config.toml",
|
|
3309
3312
|
".zcode/config.json",
|
|
@@ -4353,7 +4356,7 @@ const PI_HOOK_EVENTS = [
|
|
|
4353
4356
|
* adapter. Amp's `agent.start` / `agent.end` events describe the main agent
|
|
4354
4357
|
* turn, not a subagent lifecycle, so they map to `beforeSubmitPrompt` / `stop`.
|
|
4355
4358
|
*
|
|
4356
|
-
* @see https://ampcode.com/
|
|
4359
|
+
* @see https://ampcode.com/docs/plugin-api
|
|
4357
4360
|
*/
|
|
4358
4361
|
const AMP_HOOK_EVENTS = [
|
|
4359
4362
|
"sessionStart",
|
|
@@ -6198,6 +6201,7 @@ const McpServerSchema = z.looseObject({
|
|
|
6198
6201
|
crushOauthClientSecret: z.optional(z.string()),
|
|
6199
6202
|
crushOauthCallbackPort: z.optional(z.int()),
|
|
6200
6203
|
crushSessionless: z.optional(z.boolean()),
|
|
6204
|
+
poolAllow: z.optional(z.array(z.string())),
|
|
6201
6205
|
headers: z.optional(z.record(z.string(), z.string())),
|
|
6202
6206
|
/**
|
|
6203
6207
|
* The canonical per-server tool allowlist.
|
|
@@ -6629,6 +6633,7 @@ var RulesyncMcp = class RulesyncMcp extends RulesyncFile {
|
|
|
6629
6633
|
"crushOauthClientSecret",
|
|
6630
6634
|
"crushOauthCallbackPort",
|
|
6631
6635
|
"crushSessionless",
|
|
6636
|
+
"poolAllow",
|
|
6632
6637
|
"oauth_client_id",
|
|
6633
6638
|
"oauth_client_secret",
|
|
6634
6639
|
"oauth_callback_port",
|
|
@@ -8316,7 +8321,7 @@ const PERMISSION_OVERRIDE_KEY_ALIASES = {
|
|
|
8316
8321
|
* them; treating a segment that carries one as static could name a directory
|
|
8317
8322
|
* that no matched file actually lives under.
|
|
8318
8323
|
*/
|
|
8319
|
-
const GLOB_METACHARACTERS = /[*?[\]{}()!]/;
|
|
8324
|
+
const GLOB_METACHARACTERS$1 = /[*?[\]{}()!]/;
|
|
8320
8325
|
/**
|
|
8321
8326
|
* The directory every file matched by `glob` lives under, or `undefined` when
|
|
8322
8327
|
* the pattern pins down no such directory.
|
|
@@ -8349,7 +8354,7 @@ function getGlobStaticPrefix(glob) {
|
|
|
8349
8354
|
const lastIndex = segments.length - 1;
|
|
8350
8355
|
const prefix = [];
|
|
8351
8356
|
for (const [index, segment] of segments.entries()) {
|
|
8352
|
-
if (segment === "" || GLOB_METACHARACTERS.test(segment)) break;
|
|
8357
|
+
if (segment === "" || GLOB_METACHARACTERS$1.test(segment)) break;
|
|
8353
8358
|
if (segment === ".") continue;
|
|
8354
8359
|
if (index === lastIndex) break;
|
|
8355
8360
|
prefix.push(segment);
|
|
@@ -12924,6 +12929,8 @@ const KIMI_CODE_HOME_CONFIG_SHARED_FILE_KEY = "config.toml";
|
|
|
12924
12929
|
const REASONIX_PROJECT_CONFIG_SHARED_FILE_KEY = "reasonix.toml";
|
|
12925
12930
|
const REASONIX_GLOBAL_CONFIG_SHARED_FILE_KEY = ".reasonix/config.toml";
|
|
12926
12931
|
const ROVODEV_CONFIG_SHARED_FILE_KEY = ".rovodev/config.yml";
|
|
12932
|
+
const POOL_PROJECT_SETTINGS_SHARED_FILE_KEY = ".poolside/settings.yaml";
|
|
12933
|
+
const POOL_GLOBAL_SETTINGS_SHARED_FILE_KEY = ".config/poolside/settings.yaml";
|
|
12927
12934
|
/**
|
|
12928
12935
|
* Build the `SHARED_CONFIG_OWNERSHIP` lookup key from a tool's settable paths.
|
|
12929
12936
|
* Mirrors `sharedFileKey` in `src/lib/shared-file-derive.ts` (kept separate so
|
|
@@ -13005,6 +13012,20 @@ const KIMI_CODE_CONFIG_DECLARATION = {
|
|
|
13005
13012
|
}
|
|
13006
13013
|
};
|
|
13007
13014
|
/**
|
|
13015
|
+
* Pool settings (`.poolside/settings.yaml` / `~/.config/poolside/settings.yaml`):
|
|
13016
|
+
* the user's primary Pool settings file, so an unparseable root fails closed
|
|
13017
|
+
* rather than being replaced with generated output. `mcp_servers` is owned as
|
|
13018
|
+
* a whole key because the MCP writer emits the complete server map.
|
|
13019
|
+
*/
|
|
13020
|
+
const POOL_SETTINGS_DECLARATION = {
|
|
13021
|
+
format: "yaml",
|
|
13022
|
+
invalidRootPolicy: "error",
|
|
13023
|
+
features: { mcp: {
|
|
13024
|
+
kind: "replace-owned-keys",
|
|
13025
|
+
ownedKeys: ["mcp_servers"]
|
|
13026
|
+
} }
|
|
13027
|
+
};
|
|
13028
|
+
/**
|
|
13008
13029
|
* ZCode's settings file, which also carries model/theme/permission keys
|
|
13009
13030
|
* rulesync does not own. Both copies are the user's primary ZCode config, so
|
|
13010
13031
|
* every writer refuses to read-modify-write a file it could not parse rather
|
|
@@ -13109,6 +13130,8 @@ const SHARED_CONFIG_OWNERSHIP = {
|
|
|
13109
13130
|
[HERMES_CONFIG_SHARED_FILE_KEY]: HERMES_CONFIG_DECLARATION,
|
|
13110
13131
|
[HERMES_WIN32_CONFIG_SHARED_FILE_KEY]: HERMES_CONFIG_DECLARATION,
|
|
13111
13132
|
[HERMES_HOME_CONFIG_SHARED_FILE_KEY]: HERMES_CONFIG_DECLARATION,
|
|
13133
|
+
[POOL_PROJECT_SETTINGS_SHARED_FILE_KEY]: POOL_SETTINGS_DECLARATION,
|
|
13134
|
+
[POOL_GLOBAL_SETTINGS_SHARED_FILE_KEY]: POOL_SETTINGS_DECLARATION,
|
|
13112
13135
|
[TAKT_CONFIG_SHARED_FILE_KEY]: {
|
|
13113
13136
|
format: "yaml",
|
|
13114
13137
|
invalidRootPolicy: "error",
|
|
@@ -37094,6 +37117,363 @@ var OpencodeMcp = class OpencodeMcp extends ToolMcp {
|
|
|
37094
37117
|
}
|
|
37095
37118
|
};
|
|
37096
37119
|
//#endregion
|
|
37120
|
+
//#region src/constants/pool-paths.ts
|
|
37121
|
+
/**
|
|
37122
|
+
* Pool (Poolside's coding agent CLI) configuration-layout conventions.
|
|
37123
|
+
*
|
|
37124
|
+
* Pool reads `AGENTS.md` instruction files the same way the AGENTS.md standard
|
|
37125
|
+
* describes them: the personal `~/.config/poolside/AGENTS.md` (Pool itself
|
|
37126
|
+
* honours `XDG_CONFIG_HOME` upstream; rulesync writes only the XDG-default
|
|
37127
|
+
* path), the project-root `AGENTS.md`, and nested per-directory
|
|
37128
|
+
* `AGENTS.md` files from the repository root down through the working
|
|
37129
|
+
* directory, deeper files taking precedence. It skips ignored directories
|
|
37130
|
+
* (`.git/`, `node_modules/`, cache directories, repository ignore rules).
|
|
37131
|
+
*
|
|
37132
|
+
* Skills follow the Agent Skills format (`<name>/SKILL.md` bundles). Pool
|
|
37133
|
+
* scans `.poolside/skills/` (project) and `~/.config/poolside/skills/`
|
|
37134
|
+
* (global) plus the shared `.agents/skills/` / `~/.agents/skills/` roots and
|
|
37135
|
+
* the skill directories of other Agent Skills tools; rulesync writes only the
|
|
37136
|
+
* Pool-specific roots and leaves the shared ones to their own targets.
|
|
37137
|
+
*
|
|
37138
|
+
* @see https://docs.poolside.ai/agent-instructions
|
|
37139
|
+
* @see https://docs.poolside.ai/skills
|
|
37140
|
+
* @see https://github.com/poolsideai/pool
|
|
37141
|
+
*/
|
|
37142
|
+
/** Project-scoped `.poolside/` directory at the project root. */
|
|
37143
|
+
const POOL_DIR = ".poolside";
|
|
37144
|
+
/** Global config directory for Pool, relative to the home directory. */
|
|
37145
|
+
const POOL_GLOBAL_DIR = join(".config", "poolside");
|
|
37146
|
+
/** Project skills root, relative to the project root. */
|
|
37147
|
+
const POOL_SKILLS_DIR_PATH = join(POOL_DIR, "skills");
|
|
37148
|
+
/** Global skills root, relative to the home directory. */
|
|
37149
|
+
const POOL_GLOBAL_SKILLS_DIR_PATH = join(POOL_GLOBAL_DIR, "skills");
|
|
37150
|
+
/**
|
|
37151
|
+
* Pool's settings file name. MCP servers live under the top-level
|
|
37152
|
+
* `mcp_servers` key of `.poolside/settings.yaml` (project, committed) and
|
|
37153
|
+
* `~/.config/poolside/settings.yaml` (global); the untracked
|
|
37154
|
+
* `.poolside/settings.local.yaml` overlay is left to the user.
|
|
37155
|
+
*
|
|
37156
|
+
* @see https://docs.poolside.ai/mcp-servers
|
|
37157
|
+
* @see https://docs.poolside.ai/settings-file-reference
|
|
37158
|
+
*/
|
|
37159
|
+
const POOL_SETTINGS_FILE_NAME = "settings.yaml";
|
|
37160
|
+
/** Top-level key of Pool's settings file that holds the MCP server map. */
|
|
37161
|
+
const POOL_MCP_SERVERS_KEY = "mcp_servers";
|
|
37162
|
+
//#endregion
|
|
37163
|
+
//#region src/features/mcp/pool-mcp.ts
|
|
37164
|
+
/**
|
|
37165
|
+
* Single spelling of the settings.yaml codec/policy, matching the
|
|
37166
|
+
* `SHARED_CONFIG_OWNERSHIP` declaration for both scopes: fail closed on an
|
|
37167
|
+
* unparseable root rather than replacing the user's primary Pool settings with
|
|
37168
|
+
* generated output.
|
|
37169
|
+
*/
|
|
37170
|
+
function parsePoolSettings(fileContent, filePath) {
|
|
37171
|
+
return parseSharedConfig({
|
|
37172
|
+
format: "yaml",
|
|
37173
|
+
fileContent,
|
|
37174
|
+
filePath,
|
|
37175
|
+
invalidRootPolicy: "error"
|
|
37176
|
+
});
|
|
37177
|
+
}
|
|
37178
|
+
/**
|
|
37179
|
+
* The remote transports Pool's `transport.type` accepts. `streamable-http` is
|
|
37180
|
+
* the canonical rulesync name for what Pool calls `http`; everything else is
|
|
37181
|
+
* left to the caller to reject.
|
|
37182
|
+
*
|
|
37183
|
+
* @see https://docs.poolside.ai/mcp-servers
|
|
37184
|
+
*/
|
|
37185
|
+
function asPoolRemoteType(stated, url) {
|
|
37186
|
+
if (stated === "sse") return "sse";
|
|
37187
|
+
if (stated === "http" || stated === "streamable-http") return "http";
|
|
37188
|
+
if (stated === void 0) return /^wss?:\/\//i.test(url) ? void 0 : "http";
|
|
37189
|
+
}
|
|
37190
|
+
/**
|
|
37191
|
+
* Pool spells remote headers as a list of `"Name: value"` strings rather than
|
|
37192
|
+
* a map, so the canonical record is flattened at generate time and split back
|
|
37193
|
+
* at the first `:` on import. A list entry without a `:` names no header and
|
|
37194
|
+
* is dropped with a warning — silently losing what may be a mistyped auth
|
|
37195
|
+
* header would leave the canonical file short of one without a trace.
|
|
37196
|
+
*/
|
|
37197
|
+
function headersRecordToPoolList(headers) {
|
|
37198
|
+
return Object.entries(headers).map(([name, value]) => `${name}: ${value}`);
|
|
37199
|
+
}
|
|
37200
|
+
function poolHeadersListToRecord(serverName, headers) {
|
|
37201
|
+
if (!isStringArray$2(headers)) return void 0;
|
|
37202
|
+
const result = {};
|
|
37203
|
+
for (const entry of headers) {
|
|
37204
|
+
const separator = entry.indexOf(":");
|
|
37205
|
+
const name = separator > 0 ? entry.slice(0, separator).trim() : "";
|
|
37206
|
+
if (name === "" || PROTOTYPE_POLLUTION_KEYS.has(name)) {
|
|
37207
|
+
warnWithFallback(void 0, `Ignored malformed header ${quoteValueForWarning(entry)} in Pool MCP server ${quoteValueForWarning(serverName)}: expected "Name: value"`);
|
|
37208
|
+
continue;
|
|
37209
|
+
}
|
|
37210
|
+
result[name] = entry.slice(separator + 1).trim();
|
|
37211
|
+
}
|
|
37212
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
37213
|
+
}
|
|
37214
|
+
/**
|
|
37215
|
+
* Pool's `deny`/`enabled_tools` entries are glob patterns, while the canonical
|
|
37216
|
+
* `enabledTools`/`disabledTools` lists are literal tool names that the other
|
|
37217
|
+
* targets match verbatim. A pattern therefore imports as a name that matches
|
|
37218
|
+
* nothing elsewhere — a `deny` that quietly stops denying is the case worth
|
|
37219
|
+
* calling out — so it is copied as-is but warned about. `allow` is exempt: it
|
|
37220
|
+
* imports to the Pool-only `poolAllow`, where globs are exactly what Pool
|
|
37221
|
+
* expects and no other tool ever reads them.
|
|
37222
|
+
*/
|
|
37223
|
+
const GLOB_METACHARACTERS = /[*?[]/;
|
|
37224
|
+
/** Patterns named in the glob warning before the rest collapse to `(+N more)`. */
|
|
37225
|
+
const MAX_LISTED_GLOB_PATTERNS = 10;
|
|
37226
|
+
function importPoolToolList({ serverName, poolKey, value, warnOnGlobs }) {
|
|
37227
|
+
if (!isStringArray$2(value)) {
|
|
37228
|
+
warnWithFallback(void 0, `Ignored malformed value for ${poolKey} in Pool MCP server ${quoteValueForWarning(serverName)}: expected a list of strings`);
|
|
37229
|
+
return;
|
|
37230
|
+
}
|
|
37231
|
+
if (!warnOnGlobs) return value;
|
|
37232
|
+
const patterns = value.filter((entry) => GLOB_METACHARACTERS.test(entry));
|
|
37233
|
+
if (patterns.length > 0) {
|
|
37234
|
+
const listed = patterns.slice(0, MAX_LISTED_GLOB_PATTERNS).map(quoteValueForWarning);
|
|
37235
|
+
const overflow = patterns.length - listed.length;
|
|
37236
|
+
const shown = overflow > 0 ? `${listed.join(", ")} (+${overflow} more)` : listed.join(", ");
|
|
37237
|
+
warnWithFallback(void 0, `${poolKey} in Pool MCP server ${quoteValueForWarning(serverName)} contains glob patterns (${shown}); other tools match the imported tool names literally`);
|
|
37238
|
+
}
|
|
37239
|
+
return value;
|
|
37240
|
+
}
|
|
37241
|
+
/**
|
|
37242
|
+
* Pool's `transport` block for a remote server, or `null` (after a warning)
|
|
37243
|
+
* when the server has no url or names a transport Pool cannot reach.
|
|
37244
|
+
*/
|
|
37245
|
+
function toPoolTransport(name, config, logger) {
|
|
37246
|
+
const url = resolveRemoteMcpUrl(config);
|
|
37247
|
+
if (!url) return warnAndSkipMcpServer({
|
|
37248
|
+
toolName: "Pool",
|
|
37249
|
+
serverName: name,
|
|
37250
|
+
reason: "a remote transport without a url",
|
|
37251
|
+
logger
|
|
37252
|
+
});
|
|
37253
|
+
const stated = config.type ?? config.transport;
|
|
37254
|
+
const type = asPoolRemoteType(stated, url);
|
|
37255
|
+
if (type === void 0) return warnAndSkipMcpServer({
|
|
37256
|
+
toolName: "Pool",
|
|
37257
|
+
serverName: name,
|
|
37258
|
+
reason: stated === void 0 ? "a WebSocket url, which Pool's remote transports (http and sse) cannot reach" : `the "${stated}" transport, which Pool does not offer for remote servers (only http and sse)`,
|
|
37259
|
+
logger
|
|
37260
|
+
});
|
|
37261
|
+
const transport = {
|
|
37262
|
+
type,
|
|
37263
|
+
url
|
|
37264
|
+
};
|
|
37265
|
+
if (config.headers && Object.keys(config.headers).length > 0) transport.headers = headersRecordToPoolList(config.headers);
|
|
37266
|
+
return transport;
|
|
37267
|
+
}
|
|
37268
|
+
/**
|
|
37269
|
+
* The transport-specific part of a Pool server entry: a `transport` block for
|
|
37270
|
+
* remote servers, `command`/`args`/`cwd` for stdio ones. `null` (after a
|
|
37271
|
+
* warning) when the server cannot be written.
|
|
37272
|
+
*/
|
|
37273
|
+
function toPoolTransportFields(name, config, logger) {
|
|
37274
|
+
if (isRemoteMcpServer(config)) {
|
|
37275
|
+
const transport = toPoolTransport(name, config, logger);
|
|
37276
|
+
return transport === null ? null : { transport };
|
|
37277
|
+
}
|
|
37278
|
+
const [command, ...args] = resolveLocalMcpCommand(config);
|
|
37279
|
+
if (!command) return warnAndSkipMcpServer({
|
|
37280
|
+
toolName: "Pool",
|
|
37281
|
+
serverName: name,
|
|
37282
|
+
reason: "a stdio transport without a command",
|
|
37283
|
+
logger
|
|
37284
|
+
});
|
|
37285
|
+
const fields = {
|
|
37286
|
+
command,
|
|
37287
|
+
args
|
|
37288
|
+
};
|
|
37289
|
+
if (config.cwd) fields.cwd = config.cwd;
|
|
37290
|
+
return fields;
|
|
37291
|
+
}
|
|
37292
|
+
/**
|
|
37293
|
+
* The fields shared by stdio and remote entries. Tool filters map onto Pool's
|
|
37294
|
+
* own switches — `enabledTools` becomes `enabled_tools` (the tools Pool
|
|
37295
|
+
* exposes at all) and `disabledTools` becomes `deny` (patterns agents may
|
|
37296
|
+
* never use); the Pool-only approval allowlist is authored as `poolAllow` and
|
|
37297
|
+
* written as `allow`. `disabled: true` is spelled the same on both sides.
|
|
37298
|
+
*/
|
|
37299
|
+
function toPoolCommonFields(config) {
|
|
37300
|
+
const fields = {};
|
|
37301
|
+
if (config.env && Object.keys(config.env).length > 0) fields.env = config.env;
|
|
37302
|
+
if (config.enabledTools && config.enabledTools.length > 0) fields.enabled_tools = config.enabledTools;
|
|
37303
|
+
if (config.poolAllow && config.poolAllow.length > 0) fields.allow = config.poolAllow;
|
|
37304
|
+
if (config.disabledTools && config.disabledTools.length > 0) fields.deny = config.disabledTools;
|
|
37305
|
+
if (config.disabled === true) fields.disabled = true;
|
|
37306
|
+
return fields;
|
|
37307
|
+
}
|
|
37308
|
+
/**
|
|
37309
|
+
* Convert canonical rulesync servers to Pool's native `mcp_servers` shape:
|
|
37310
|
+
* stdio servers carry `command`/`args`/`cwd`/`env`, remote servers carry a
|
|
37311
|
+
* `transport` block (`type` of `http` or `sse`, `url`, optional `headers`
|
|
37312
|
+
* list) plus optional `env`; see `toPoolCommonFields` for the tool filters.
|
|
37313
|
+
*
|
|
37314
|
+
* @see https://docs.poolside.ai/mcp-servers
|
|
37315
|
+
*/
|
|
37316
|
+
function convertToPoolFormat(mcpServers, logger) {
|
|
37317
|
+
const result = {};
|
|
37318
|
+
for (const [name, config] of Object.entries(mcpServers)) {
|
|
37319
|
+
if (PROTOTYPE_POLLUTION_KEYS.has(name)) continue;
|
|
37320
|
+
if (!isRecord$1(config)) continue;
|
|
37321
|
+
if (declaresNoTransport(config)) {
|
|
37322
|
+
warnAndSkipMcpServer({
|
|
37323
|
+
toolName: "Pool",
|
|
37324
|
+
serverName: name,
|
|
37325
|
+
reason: "no transport",
|
|
37326
|
+
logger
|
|
37327
|
+
});
|
|
37328
|
+
continue;
|
|
37329
|
+
}
|
|
37330
|
+
const transportFields = toPoolTransportFields(name, config, logger);
|
|
37331
|
+
if (transportFields === null) continue;
|
|
37332
|
+
result[name] = {
|
|
37333
|
+
...transportFields,
|
|
37334
|
+
...toPoolCommonFields(config)
|
|
37335
|
+
};
|
|
37336
|
+
}
|
|
37337
|
+
return result;
|
|
37338
|
+
}
|
|
37339
|
+
const POOL_TO_CANONICAL_TOOL_LIST_KEYS = {
|
|
37340
|
+
enabled_tools: "enabledTools",
|
|
37341
|
+
deny: "disabledTools",
|
|
37342
|
+
allow: "poolAllow"
|
|
37343
|
+
};
|
|
37344
|
+
/**
|
|
37345
|
+
* Convert Pool's native `mcp_servers` shape back to canonical rulesync
|
|
37346
|
+
* servers: the `transport` block is flattened to `type`/`url`/`headers`,
|
|
37347
|
+
* `enabled_tools` maps back to `enabledTools`, `deny` to `disabledTools` and
|
|
37348
|
+
* `allow` to the namespaced `poolAllow` (see `McpServerSchema`). Unknown keys
|
|
37349
|
+
* pass through untouched so an import keeps whatever a hand-authored entry
|
|
37350
|
+
* declared; generation back out is a whitelist, so only the keys
|
|
37351
|
+
* `convertToPoolFormat` writes are re-emitted.
|
|
37352
|
+
*/
|
|
37353
|
+
function convertFromPoolFormat(poolServers) {
|
|
37354
|
+
const result = {};
|
|
37355
|
+
for (const [name, config] of Object.entries(poolServers)) {
|
|
37356
|
+
if (PROTOTYPE_POLLUTION_KEYS.has(name) || !isRecord$1(config)) continue;
|
|
37357
|
+
const converted = {};
|
|
37358
|
+
for (const [key, value] of Object.entries(config)) {
|
|
37359
|
+
if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
|
|
37360
|
+
if (key === "transport") {
|
|
37361
|
+
if (!isRecord$1(value)) continue;
|
|
37362
|
+
if (typeof value.type === "string") converted.type = value.type;
|
|
37363
|
+
if (typeof value.url === "string") converted.url = value.url;
|
|
37364
|
+
const headers = poolHeadersListToRecord(name, value.headers);
|
|
37365
|
+
if (headers) converted.headers = headers;
|
|
37366
|
+
continue;
|
|
37367
|
+
}
|
|
37368
|
+
const canonicalKey = Object.hasOwn(POOL_TO_CANONICAL_TOOL_LIST_KEYS, key) ? POOL_TO_CANONICAL_TOOL_LIST_KEYS[key] : void 0;
|
|
37369
|
+
if (canonicalKey) {
|
|
37370
|
+
const list = importPoolToolList({
|
|
37371
|
+
serverName: name,
|
|
37372
|
+
poolKey: key,
|
|
37373
|
+
value,
|
|
37374
|
+
warnOnGlobs: canonicalKey !== "poolAllow"
|
|
37375
|
+
});
|
|
37376
|
+
if (list) converted[canonicalKey] = list;
|
|
37377
|
+
continue;
|
|
37378
|
+
}
|
|
37379
|
+
converted[key] = value;
|
|
37380
|
+
}
|
|
37381
|
+
result[name] = converted;
|
|
37382
|
+
}
|
|
37383
|
+
return result;
|
|
37384
|
+
}
|
|
37385
|
+
/**
|
|
37386
|
+
* Pool MCP servers.
|
|
37387
|
+
*
|
|
37388
|
+
* Pool reads MCP servers from the `mcp_servers` block of its settings file:
|
|
37389
|
+
* `<project>/.poolside/settings.yaml` at project scope (shared and committed)
|
|
37390
|
+
* and `~/.config/poolside/settings.yaml` at user scope. The untracked
|
|
37391
|
+
* `.poolside/settings.local.yaml` overlay, which Pool layers on top of both,
|
|
37392
|
+
* is left to the user. Every other top-level settings key is preserved and
|
|
37393
|
+
* the file is never deleted.
|
|
37394
|
+
*
|
|
37395
|
+
* @see https://docs.poolside.ai/mcp-servers
|
|
37396
|
+
* @see https://docs.poolside.ai/settings-file-reference
|
|
37397
|
+
*/
|
|
37398
|
+
var PoolMcp = class PoolMcp extends ToolMcp {
|
|
37399
|
+
settings;
|
|
37400
|
+
constructor(params) {
|
|
37401
|
+
super(params);
|
|
37402
|
+
this.settings = parsePoolSettings(this.fileContent ?? "", join(this.relativeDirPath, this.relativeFilePath));
|
|
37403
|
+
}
|
|
37404
|
+
getSettings() {
|
|
37405
|
+
return this.settings;
|
|
37406
|
+
}
|
|
37407
|
+
isDeletable() {
|
|
37408
|
+
return false;
|
|
37409
|
+
}
|
|
37410
|
+
static getSettablePaths({ global = false } = {}) {
|
|
37411
|
+
return {
|
|
37412
|
+
relativeDirPath: global ? POOL_GLOBAL_DIR : POOL_DIR,
|
|
37413
|
+
relativeFilePath: POOL_SETTINGS_FILE_NAME
|
|
37414
|
+
};
|
|
37415
|
+
}
|
|
37416
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
37417
|
+
const paths = this.getSettablePaths({ global });
|
|
37418
|
+
const fileContent = await readFileContentOrNull(join(outputRoot, paths.relativeDirPath, paths.relativeFilePath)) ?? "";
|
|
37419
|
+
return new PoolMcp({
|
|
37420
|
+
outputRoot,
|
|
37421
|
+
relativeDirPath: paths.relativeDirPath,
|
|
37422
|
+
relativeFilePath: paths.relativeFilePath,
|
|
37423
|
+
fileContent,
|
|
37424
|
+
validate,
|
|
37425
|
+
global
|
|
37426
|
+
});
|
|
37427
|
+
}
|
|
37428
|
+
static async fromRulesyncMcp({ outputRoot = process.cwd(), rulesyncMcp, validate = true, global = false, logger }) {
|
|
37429
|
+
const paths = this.getSettablePaths({ global });
|
|
37430
|
+
const filePath = join(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
|
|
37431
|
+
const existingContent = await readFileContentOrNull(filePath) ?? "";
|
|
37432
|
+
const converted = convertToPoolFormat(Object.fromEntries(Object.entries(rulesyncMcp.getMcpServers()).map(([serverName, serverConfig]) => {
|
|
37433
|
+
const rawServer = rulesyncMcp.getRawMcpServer(serverName);
|
|
37434
|
+
const poolAllow = isRecord$1(rawServer) ? rawServer.poolAllow : void 0;
|
|
37435
|
+
return [serverName, {
|
|
37436
|
+
...serverConfig,
|
|
37437
|
+
...isStringArray$2(poolAllow) && { poolAllow }
|
|
37438
|
+
}];
|
|
37439
|
+
})), logger);
|
|
37440
|
+
return new PoolMcp({
|
|
37441
|
+
outputRoot,
|
|
37442
|
+
relativeDirPath: paths.relativeDirPath,
|
|
37443
|
+
relativeFilePath: paths.relativeFilePath,
|
|
37444
|
+
fileContent: applySharedConfigPatch({
|
|
37445
|
+
fileKey: sharedConfigFileKey(paths),
|
|
37446
|
+
feature: "mcp",
|
|
37447
|
+
existingContent,
|
|
37448
|
+
patch: { [POOL_MCP_SERVERS_KEY]: converted },
|
|
37449
|
+
filePath
|
|
37450
|
+
}),
|
|
37451
|
+
validate,
|
|
37452
|
+
global
|
|
37453
|
+
});
|
|
37454
|
+
}
|
|
37455
|
+
toRulesyncMcp() {
|
|
37456
|
+
const converted = convertFromPoolFormat(isRecord$1(this.settings["mcp_servers"]) ? this.settings[POOL_MCP_SERVERS_KEY] : {});
|
|
37457
|
+
return this.toRulesyncMcpDefault({ fileContent: JSON.stringify({ mcpServers: converted }, null, 2) });
|
|
37458
|
+
}
|
|
37459
|
+
validate() {
|
|
37460
|
+
return {
|
|
37461
|
+
success: true,
|
|
37462
|
+
error: null
|
|
37463
|
+
};
|
|
37464
|
+
}
|
|
37465
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
37466
|
+
return new PoolMcp({
|
|
37467
|
+
outputRoot,
|
|
37468
|
+
relativeDirPath,
|
|
37469
|
+
relativeFilePath,
|
|
37470
|
+
fileContent: "",
|
|
37471
|
+
validate: false,
|
|
37472
|
+
global
|
|
37473
|
+
});
|
|
37474
|
+
}
|
|
37475
|
+
};
|
|
37476
|
+
//#endregion
|
|
37097
37477
|
//#region src/features/mcp/qwencode-mcp.ts
|
|
37098
37478
|
/**
|
|
37099
37479
|
* Map rulesync's canonical per-server tool filters to Qwen Code's field names.
|
|
@@ -39541,6 +39921,15 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
39541
39921
|
supportsDisabledTools: true
|
|
39542
39922
|
}
|
|
39543
39923
|
}],
|
|
39924
|
+
["pool", {
|
|
39925
|
+
class: PoolMcp,
|
|
39926
|
+
meta: {
|
|
39927
|
+
supportsProject: true,
|
|
39928
|
+
supportsGlobal: true,
|
|
39929
|
+
supportsEnabledTools: true,
|
|
39930
|
+
supportsDisabledTools: true
|
|
39931
|
+
}
|
|
39932
|
+
}],
|
|
39544
39933
|
["qwencode", {
|
|
39545
39934
|
class: QwencodeMcp,
|
|
39546
39935
|
meta: {
|
|
@@ -56762,7 +57151,7 @@ const AmpSkillFrontmatterSchema = z.looseObject({
|
|
|
56762
57151
|
* Amp natively reads Agent Skills following the open standard: a directory with a
|
|
56763
57152
|
* `SKILL.md` carrying `name`/`description` frontmatter, scoped to the project
|
|
56764
57153
|
* (`.agents/skills/`) and user-wide (`~/.config/agents/skills/`).
|
|
56765
|
-
* @see https://ampcode.com/
|
|
57154
|
+
* @see https://ampcode.com/docs/customize/skills
|
|
56766
57155
|
*/
|
|
56767
57156
|
var AmpSkill = class AmpSkill extends ToolSkill {
|
|
56768
57157
|
constructor({ outputRoot = process.cwd(), relativeDirPath = AMP_SKILLS_PROJECT_DIR, dirName, frontmatter, body, otherFiles = [], validate = true, global = false }) {
|
|
@@ -61731,37 +62120,6 @@ var PiSkill = class PiSkill extends ToolSkill {
|
|
|
61731
62120
|
}
|
|
61732
62121
|
};
|
|
61733
62122
|
//#endregion
|
|
61734
|
-
//#region src/constants/pool-paths.ts
|
|
61735
|
-
/**
|
|
61736
|
-
* Pool (Poolside's coding agent CLI) configuration-layout conventions.
|
|
61737
|
-
*
|
|
61738
|
-
* Pool reads `AGENTS.md` instruction files the same way the AGENTS.md standard
|
|
61739
|
-
* describes them: the personal `~/.config/poolside/AGENTS.md` (Pool itself
|
|
61740
|
-
* honours `XDG_CONFIG_HOME` upstream; rulesync writes only the XDG-default
|
|
61741
|
-
* path), the project-root `AGENTS.md`, and nested per-directory
|
|
61742
|
-
* `AGENTS.md` files from the repository root down through the working
|
|
61743
|
-
* directory, deeper files taking precedence. It skips ignored directories
|
|
61744
|
-
* (`.git/`, `node_modules/`, cache directories, repository ignore rules).
|
|
61745
|
-
*
|
|
61746
|
-
* Skills follow the Agent Skills format (`<name>/SKILL.md` bundles). Pool
|
|
61747
|
-
* scans `.poolside/skills/` (project) and `~/.config/poolside/skills/`
|
|
61748
|
-
* (global) plus the shared `.agents/skills/` / `~/.agents/skills/` roots and
|
|
61749
|
-
* the skill directories of other Agent Skills tools; rulesync writes only the
|
|
61750
|
-
* Pool-specific roots and leaves the shared ones to their own targets.
|
|
61751
|
-
*
|
|
61752
|
-
* @see https://docs.poolside.ai/agent-instructions
|
|
61753
|
-
* @see https://docs.poolside.ai/skills
|
|
61754
|
-
* @see https://github.com/poolsideai/pool
|
|
61755
|
-
*/
|
|
61756
|
-
/** Project-scoped `.poolside/` directory at the project root. */
|
|
61757
|
-
const POOL_DIR = ".poolside";
|
|
61758
|
-
/** Global config directory for Pool, relative to the home directory. */
|
|
61759
|
-
const POOL_GLOBAL_DIR = join(".config", "poolside");
|
|
61760
|
-
/** Project skills root, relative to the project root. */
|
|
61761
|
-
const POOL_SKILLS_DIR_PATH = join(POOL_DIR, "skills");
|
|
61762
|
-
/** Global skills root, relative to the home directory. */
|
|
61763
|
-
const POOL_GLOBAL_SKILLS_DIR_PATH = join(POOL_GLOBAL_DIR, "skills");
|
|
61764
|
-
//#endregion
|
|
61765
62123
|
//#region src/features/skills/pool-skill.ts
|
|
61766
62124
|
const PoolSkillFrontmatterSchema = z.looseObject({
|
|
61767
62125
|
name: z.string(),
|
|
@@ -80589,4 +80947,4 @@ async function importChecksCore(params) {
|
|
|
80589
80947
|
//#endregion
|
|
80590
80948
|
export { RulesyncCommand as $, toPosixPath as $t, CLAUDECODE_MEMORIES_DIR_NAME as A, RULESYNC_XDG_CONFIG_HOME_DEFAULT_DIR_NAME as An, checkPathTraversal as At, RulesyncSubagent as B, stripControlCharacters as Bn, listDirectoryEntryNames as Bt, COMMANDCODE_DIR as C, RULESYNC_PERMISSIONS_SCHEMA_URL as Cn, withWarnOnceScope as Ct, CODEXCLI_DIR as D, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as Dn, assertDirectoryIfExists as Dt, CODEXCLI_BASH_RULES_FILE_NAME as E, RULESYNC_SKILLS_RELATIVE_DIR_PATH as En, applyFileMode as Et, caseFoldIdentity as F, formatError as Fn, getFileSize as Ft, RulesyncRuleFrontmatterSchema as G, readFileContentOrNull as Gt, RulesyncSkill as H, stripHiddenCharacters as Hn, listSubdirectoryNames as Ht, groupSpellingsByCaseFoldedIdentity as I, truncateText as In, getHomeDirectory as It, RulesyncIgnore as J, removeFile as Jt, RulesyncPermissions as K, removeDirectory as Kt, AUGMENTCODE_DIR as L, hasDeceptiveHiddenCharacters as Ln, isFileNotFoundError as Lt, CLAUDECODE_SKILLS_DIR_PATH as M, ALL_FEATURES as Mn, directoryExists as Mt, FACTORYDROID_DIR as N, ALL_FEATURES_WITH_WILDCARD as Nn, ensureDir as Nt, CLAUDECODE_DIR as O, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as On, assertTreeContainsNoSymlinks as Ot, FACTORYDROID_SETTINGS_LOCAL_FILE_NAME as P, DEPRECATED_FEATURE_REPLACEMENTS as Pn, fileExists as Pt, parseJsonc as Q, runWithDirectoryRollback as Qt, AUGMENTCODE_SETTINGS_LOCAL_FILE_NAME as R, hasEnclosingMarkOutsideKeycap as Rn, isFileSystemError as Rt, QWENCODE_LOCAL_RULE_FILE_NAME as S, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as Sn, resetRunWarningState as St, ChecksProcessor as T, RULESYNC_RULES_RELATIVE_DIR_PATH as Tn, ErrorCodes as Tt, RulesyncSkillFrontmatterSchema as U, pathEscapesRoot as Ut, RulesyncSubagentFrontmatterSchema as V, stripControlCharactersKeepingLineFeeds as Vn, listFilePathsRecursively as Vt, RulesyncRule as W, readFileContent as Wt, getRulesyncSourceCandidates as X, removeTempDirectory as Xt, RulesyncHooks as Y, removeFileStrict as Yt, resolveRulesyncSourceWritePath as Z, resolvePath as Zt, IgnoreProcessor as _, RULESYNC_IGNORE_RELATIVE_FILE_PATH as _n, JsonLogger as _t, getProcessorRegistryEntry as a, ToolTargetSchema as an, SHARED_USER_MANAGED_CONFIG_PATHS as at, CommandsProcessor as b, RULESYNC_MCP_SCHEMA_URL as bn, warnOnConflictingFlags as bt, RulesProcessor as c, MAX_FILE_SIZE as cn, mergeInputRootConfigs as ct, CODEBUDDY_DIR as d, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as dn, ConfigFileSchema as dt, writeFileBuffer as en, RulesyncCommandFrontmatterSchema as et, CODEBUDDY_LOCAL_RULE_FILE_NAME as f, RULESYNC_CONFIG_RELATIVE_FILE_PATH as fn, GITIGNORE_DESTINATION_KEY as ft, McpProcessor as g, RULESYNC_HOOKS_RELATIVE_FILE_PATH as gn, ConsoleLogger as gt, shortenToWidth as h, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as hn, findControlCharacter as ht, inspectInputRoots as i, PACKAGING_TOOL_TARGETS as in, loadYaml as it, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as j, parseCommaSeparatedList as jn, createTempDirectory as jt, CLAUDECODE_LOCAL_RULE_FILE_NAME as k, RULESYNC_USER_CONFIG_DIR_NAME as kn, assertWritablePathInsideRoot as kt, SubagentsProcessor as l, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as ln, resolveEffectiveInputRoots as lt, displayWidthOf as m, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as mn, assertTargetsFeaturesExclusive as mt, formatSourceLoadFailure as n, ALL_TOOL_TARGETS as nn, RulesyncCheckFrontmatterSchema as nt, convertFromTool as o, CURATED_RULES_FEATURE_SUBDIR as on, SKILL_FILE_NAME as ot, ELLIPSIS_WIDTH as p, RULESYNC_CONFIG_SCHEMA_URL as pn, SourceEntrySchema as pt, RulesyncMcp as q, removeDirectoryStrict as qt, generate as r, ALL_TOOL_TARGETS_WITH_WILDCARD as rn, stringifyFrontmatter as rt, isPackagingToolTarget as s, FEATURE_SOURCE_TREE_ENTRIES as sn, ConfigResolver as st, importFromTool as t, writeFileContent as tn, RulesyncCheck as tt, SkillsProcessor as u, RULESYNC_CHECKS_RELATIVE_DIR_PATH as un, CONFLICTING_TARGET_PAIRS as ut, HooksProcessor as v, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as vn, WarningCollectingLogger as vt, COMMANDCODE_SETTINGS_LOCAL_FILE_NAME as w, RULESYNC_RELATIVE_DIR_PATH as wn, CLIError as wt, QWENCODE_DIR as x, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as xn, withFallbackLoggerTarget as xt, CRUSH_LOCAL_RULE_FILE_NAME as y, RULESYNC_MCP_RELATIVE_FILE_PATH as yn, fallbackLogger as yt, getLocalSkillDirNames as z, quoteForLog as zn, isSymlink as zt };
|
|
80591
80949
|
|
|
80592
|
-
//# sourceMappingURL=import-
|
|
80950
|
+
//# sourceMappingURL=import-BiyWNVZY.js.map
|