rulesync 8.24.1 → 8.26.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.js CHANGED
@@ -79,7 +79,7 @@ import {
79
79
  stringifyFrontmatter,
80
80
  toPosixPath,
81
81
  writeFileContent
82
- } from "../chunk-YM6XKTQO.js";
82
+ } from "../chunk-XKXN32Q2.js";
83
83
 
84
84
  // src/cli/index.ts
85
85
  import { Command } from "commander";
@@ -1273,6 +1273,9 @@ var GITIGNORE_ENTRY_REGISTRY = [
1273
1273
  // AGENTS.md
1274
1274
  { target: ["agentsmd", "pi", "warp"], feature: "rules", entry: "**/AGENTS.md" },
1275
1275
  { target: "agentsmd", feature: "rules", entry: "**/.agents/" },
1276
+ // Amp
1277
+ // Amp reads Agent Skills from the shared `.agents/skills/` project tree.
1278
+ { target: "amp", feature: "skills", entry: "**/.agents/skills/" },
1276
1279
  // Antigravity (IDE + CLI, Antigravity 2.0)
1277
1280
  // Both targets share the `.agents/` project tree; the CLI additionally
1278
1281
  // writes a root `GEMINI.md`. Global-scope paths (under the home directory)
@@ -1306,8 +1309,10 @@ var GITIGNORE_ENTRY_REGISTRY = [
1306
1309
  // Augment Code
1307
1310
  { target: "augmentcode", feature: "rules", entry: "**/.augment/rules/" },
1308
1311
  { target: "augmentcode", feature: "rules", entry: "**/.augment-guidelines" },
1312
+ { target: "augmentcode", feature: "commands", entry: "**/.augment/commands/" },
1309
1313
  { target: "augmentcode", feature: "ignore", entry: "**/.augmentignore" },
1310
1314
  { target: "augmentcode", feature: "permissions", entry: "**/.augment/settings.json" },
1315
+ { target: "augmentcode", feature: "hooks", entry: "**/.augment/settings.json" },
1311
1316
  // Claude Code
1312
1317
  { target: "claudecode", feature: "rules", entry: "**/CLAUDE.md" },
1313
1318
  { target: "claudecode", feature: "rules", entry: "**/CLAUDE.local.md" },
@@ -1396,6 +1401,8 @@ var GITIGNORE_ENTRY_REGISTRY = [
1396
1401
  { target: "goose", feature: "rules", entry: "**/.goosehints" },
1397
1402
  { target: "goose", feature: "rules", entry: "**/.goose/" },
1398
1403
  { target: "goose", feature: "ignore", entry: "**/.gooseignore" },
1404
+ // Goose lifecycle hooks plugin (.agents/plugins/<name>/hooks/hooks.json)
1405
+ { target: "goose", feature: "hooks", entry: "**/.agents/plugins/" },
1399
1406
  // GitHub Copilot
1400
1407
  {
1401
1408
  target: ["copilot", "copilotcli"],
@@ -1437,7 +1444,7 @@ var GITIGNORE_ENTRY_REGISTRY = [
1437
1444
  { target: "kilo", feature: "skills", entry: "**/.kilo/skills/" },
1438
1445
  { target: "kilo", feature: "commands", entry: "**/.kilo/workflows/" },
1439
1446
  { target: "kilo", feature: "mcp", entry: "**/.kilo/mcp.json" },
1440
- { target: "kilo", feature: "ignore", entry: "**/.kiloignore" },
1447
+ { target: "kilo", feature: "ignore", entry: "**/.kilocodeignore" },
1441
1448
  // No `**/kilo.jsonc` entry: structurally identical to `opencode.jsonc` (no
1442
1449
  // entry). The Kilo translator preserves non-permissions Kilo settings on
1443
1450
  // round-trip, so the file is intended to be checked in by the user — adding
@@ -1452,9 +1459,9 @@ var GITIGNORE_ENTRY_REGISTRY = [
1452
1459
  // Keep this after ignore entries like "**/.aiignore" so the exception remains effective.
1453
1460
  { target: "common", feature: "general", entry: "!.rulesync/.aiignore" },
1454
1461
  // OpenCode
1455
- { target: "opencode", feature: "commands", entry: "**/.opencode/command/" },
1456
- { target: "opencode", feature: "subagents", entry: "**/.opencode/agent/" },
1457
- { target: "opencode", feature: "skills", entry: "**/.opencode/skill/" },
1462
+ { target: "opencode", feature: "commands", entry: "**/.opencode/commands/" },
1463
+ { target: "opencode", feature: "subagents", entry: "**/.opencode/agents/" },
1464
+ { target: "opencode", feature: "skills", entry: "**/.opencode/skills/" },
1458
1465
  { target: "opencode", feature: "mcp", entry: "**/.opencode/plugins/" },
1459
1466
  { target: "opencode", feature: "general", entry: "**/.opencode/memories/" },
1460
1467
  {
@@ -1468,6 +1475,7 @@ var GITIGNORE_ENTRY_REGISTRY = [
1468
1475
  { target: "pi", feature: "skills", entry: "**/.pi/skills/" },
1469
1476
  // Qwen Code
1470
1477
  { target: "qwencode", feature: "rules", entry: "**/QWEN.md" },
1478
+ { target: "qwencode", feature: "ignore", entry: "**/.qwenignore" },
1471
1479
  { target: "qwencode", feature: "general", entry: "**/.qwen/memories/" },
1472
1480
  { target: "qwencode", feature: "permissions", entry: "**/.qwen/settings.json" },
1473
1481
  // Replit
@@ -1502,13 +1510,20 @@ var GITIGNORE_ENTRY_REGISTRY = [
1502
1510
  { target: "takt", feature: "general", entry: "**/.takt/tasks/" },
1503
1511
  { target: "takt", feature: "general", entry: "**/.takt/.cache/" },
1504
1512
  { target: "takt", feature: "general", entry: "**/.takt/config.yaml" },
1505
- // Windsurf
1506
- { target: "windsurf", feature: "skills", entry: "**/.windsurf/skills/" },
1507
- { target: "windsurf", feature: "skills", entry: "**/.codeium/windsurf/skills/" },
1513
+ // Devin (Devin Desktop). Since the rebrand (v3.0.12, 2026-06-02), project
1514
+ // rules/workflows/skills live under `.devin/`; MCP and hooks keep their
1515
+ // `.devin/` paths and the global skills path is unchanged.
1516
+ { target: "devin", feature: "rules", entry: "**/.devin/rules/" },
1517
+ { target: "devin", feature: "commands", entry: "**/.devin/workflows/" },
1518
+ { target: "devin", feature: "mcp", entry: "**/.windsurf/mcp_config.json" },
1519
+ { target: "devin", feature: "hooks", entry: "**/.windsurf/hooks.json" },
1520
+ { target: "devin", feature: "skills", entry: "**/.devin/skills/" },
1521
+ { target: "devin", feature: "skills", entry: "**/.codeium/windsurf/skills/" },
1508
1522
  // Warp
1509
1523
  // `/init` now writes `AGENTS.md` (handled by the shared AGENTS.md entry above).
1510
1524
  { target: "warp", feature: "rules", entry: "**/.warp/" },
1511
1525
  { target: "warp", feature: "mcp", entry: "**/.warp/.mcp.json" },
1526
+ { target: "warp", feature: "skills", entry: "**/.warp/skills/" },
1512
1527
  // Zed
1513
1528
  // `.rules` is the project rules file. `.agents/skills/` is shared with the
1514
1529
  // antigravity targets (already registered above); re-tagging it for `zed`
@@ -4507,7 +4522,6 @@ async function executeConvert(options) {
4507
4522
  }
4508
4523
  const config = await ConfigResolver.resolve({
4509
4524
  targets: [fromTool, ...toTools],
4510
- // eslint-disable-next-line no-type-assertion/no-type-assertion
4511
4525
  features: options.features ?? ["*"],
4512
4526
  global: options.global,
4513
4527
  dryRun: options.dryRun,
@@ -4587,9 +4601,7 @@ async function executeGenerate(options = {}) {
4587
4601
  };
4588
4602
  }
4589
4603
  const config = await ConfigResolver.resolve({
4590
- // eslint-disable-next-line no-type-assertion/no-type-assertion
4591
4604
  targets: options.targets,
4592
- // eslint-disable-next-line no-type-assertion/no-type-assertion
4593
4605
  features: options.features,
4594
4606
  delete: options.delete,
4595
4607
  global: options.global,
@@ -4611,11 +4623,21 @@ async function executeGenerate(options = {}) {
4611
4623
  };
4612
4624
  }
4613
4625
  }
4626
+ function buildGenerateMessage(params) {
4627
+ const { totalCount, config } = params;
4628
+ const targets = config.getTargets().join(", ");
4629
+ const features = config.getFeatures().join(", ");
4630
+ if (totalCount > 0) {
4631
+ return `Generated ${totalCount} file(s) for targets [${targets}] and features [${features}].`;
4632
+ }
4633
+ return `No files needed updating for targets [${targets}] and features [${features}]. 'generate' only writes files whose content changed, so a totalCount of 0 means the outputs are already up to date \u2014 this is a successful no-op, not a failure.`;
4634
+ }
4614
4635
  function buildSuccessResponse2(params) {
4615
4636
  const { generateResult, config } = params;
4616
4637
  const totalCount = calculateTotalCount(generateResult);
4617
4638
  return {
4618
4639
  success: true,
4640
+ message: buildGenerateMessage({ totalCount, config }),
4619
4641
  result: {
4620
4642
  rulesCount: generateResult.rulesCount,
4621
4643
  ignoreCount: generateResult.ignoreCount,
@@ -4644,7 +4666,7 @@ var generateToolSchemas = {
4644
4666
  var generateTools = {
4645
4667
  executeGenerate: {
4646
4668
  name: "executeGenerate",
4647
- description: "Execute the rulesync generate command to create output files for AI tools. Uses rulesync.jsonc settings by default, but options can override them.",
4669
+ description: "Execute the rulesync generate command to create output files for AI tools. Uses rulesync.jsonc settings by default, but options can override them. Idempotent: only files whose content changed are written, so a totalCount of 0 means the outputs are already up to date (a successful no-op), not a failure. See the 'message' field for a human-readable summary.",
4648
4670
  parameters: generateToolSchemas.executeGenerate,
4649
4671
  execute: async (options = {}) => {
4650
4672
  const result = await executeGenerate(options);
@@ -4897,9 +4919,7 @@ async function executeImport(options) {
4897
4919
  };
4898
4920
  }
4899
4921
  const config = await ConfigResolver.resolve({
4900
- // eslint-disable-next-line no-type-assertion/no-type-assertion
4901
4922
  targets: [options.target],
4902
- // eslint-disable-next-line no-type-assertion/no-type-assertion
4903
4923
  features: options.features,
4904
4924
  global: options.global,
4905
4925
  // Always use default outputRoots (process.cwd()) and configPath
@@ -6090,7 +6110,6 @@ var rulesyncTool = {
6090
6110
  async function mcpCommand(logger5, { version }) {
6091
6111
  const server = new FastMCP({
6092
6112
  name: "Rulesync MCP Server",
6093
- // eslint-disable-next-line no-type-assertion/no-type-assertion
6094
6113
  version,
6095
6114
  instructions: "This server handles Rulesync files including rules, commands, MCP, ignore files, subagents and skills for any AI agents. It should be used when you need those files."
6096
6115
  });
@@ -6269,10 +6288,7 @@ async function downloadFile(url, destPath) {
6269
6288
  }
6270
6289
  const fileStream = fs.createWriteStream(destPath);
6271
6290
  let downloadedBytes = 0;
6272
- const bodyReader = Readable.fromWeb(
6273
- // eslint-disable-next-line no-type-assertion/no-type-assertion
6274
- response.body
6275
- );
6291
+ const bodyReader = Readable.fromWeb(response.body);
6276
6292
  const sizeChecker = new Transform({
6277
6293
  transform(chunk, _encoding, callback) {
6278
6294
  downloadedBytes += chunk.length;
@@ -6532,7 +6548,7 @@ function wrapCommand({
6532
6548
  }
6533
6549
 
6534
6550
  // src/cli/index.ts
6535
- var getVersion = () => "8.24.1";
6551
+ var getVersion = () => "8.26.0";
6536
6552
  function wrapCommand2(name, errorCode, handler) {
6537
6553
  return wrapCommand({ name, errorCode, handler, getVersion });
6538
6554
  }
@@ -6625,17 +6641,11 @@ var main = async () => {
6625
6641
  const mode = parseInstallMode(rawMode);
6626
6642
  await installCommand(logger5, {
6627
6643
  mode,
6628
- // eslint-disable-next-line no-type-assertion/no-type-assertion
6629
6644
  update: options.update,
6630
- // eslint-disable-next-line no-type-assertion/no-type-assertion
6631
6645
  frozen: options.frozen,
6632
- // eslint-disable-next-line no-type-assertion/no-type-assertion
6633
6646
  token: options.token,
6634
- // eslint-disable-next-line no-type-assertion/no-type-assertion
6635
6647
  configPath: options.config,
6636
- // eslint-disable-next-line no-type-assertion/no-type-assertion
6637
6648
  verbose: options.verbose,
6638
- // eslint-disable-next-line no-type-assertion/no-type-assertion
6639
6649
  silent: options.silent
6640
6650
  });
6641
6651
  })