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.
@@ -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/manual/plugin-api
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/manual
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-BnF2J75x.js.map
80950
+ //# sourceMappingURL=import-BiyWNVZY.js.map