compose-agentsmd 3.2.4 → 3.2.5

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.
@@ -44,6 +44,14 @@ const parseArgs = (argv) => {
44
44
  args.verbose = true;
45
45
  continue;
46
46
  }
47
+ if (arg === "--quiet" || arg === "-q") {
48
+ args.quiet = true;
49
+ continue;
50
+ }
51
+ if (arg === "--json") {
52
+ args.json = true;
53
+ continue;
54
+ }
47
55
  if (arg === "--root") {
48
56
  const value = readValueArg(remaining, i, "--root");
49
57
  args.root = value;
@@ -536,8 +544,10 @@ const composeRuleset = (rulesetPath, rootDir, options) => {
536
544
  const lintHeader = "<!-- markdownlint-disable MD025 -->";
537
545
  const toolRules = normalizeTrailingWhitespace(TOOL_RULES);
538
546
  const output = `${lintHeader}\n${[toolRules, ...parts].join("\n\n")}\n`;
539
- fs.mkdirSync(path.dirname(outputPath), { recursive: true });
540
- fs.writeFileSync(outputPath, output, "utf8");
547
+ if (!options.dryRun) {
548
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
549
+ fs.writeFileSync(outputPath, output, "utf8");
550
+ }
541
551
  return normalizePath(path.relative(rootDir, outputPath));
542
552
  };
543
553
  const LOCAL_RULES_TEMPLATE = "# Local Rules\n\n- Add project-specific instructions here.\n";
@@ -641,9 +651,22 @@ const initProject = async (args, rootDir, rulesetName) => {
641
651
  plan.push({ action: "create", path: outputPath });
642
652
  }
643
653
  }
644
- process.stdout.write(formatPlan(plan, rootDir));
654
+ if (!args.quiet && !args.json) {
655
+ process.stdout.write(formatPlan(plan, rootDir));
656
+ }
645
657
  if (args.dryRun) {
646
- process.stdout.write("Dry run: no changes made.\n");
658
+ if (args.json) {
659
+ process.stdout.write(JSON.stringify({
660
+ dryRun: true,
661
+ plan: plan.map((item) => ({
662
+ action: item.action,
663
+ path: normalizePath(path.relative(rootDir, item.path))
664
+ }))
665
+ }, null, 2) + "\n");
666
+ }
667
+ else if (!args.quiet) {
668
+ process.stdout.write("Dry run: no changes made.\n");
669
+ }
647
670
  return;
648
671
  }
649
672
  await confirmInit(args);
@@ -653,15 +676,28 @@ const initProject = async (args, rootDir, rulesetName) => {
653
676
  fs.mkdirSync(path.dirname(extraPath), { recursive: true });
654
677
  fs.writeFileSync(extraPath, LOCAL_RULES_TEMPLATE, "utf8");
655
678
  }
656
- process.stdout.write(`Initialized ruleset:\n- ${normalizePath(path.relative(rootDir, rulesetPath))}\n`);
657
- if (extraToWrite.length > 0) {
658
- process.stdout.write(`Initialized local rules:\n${extraToWrite
659
- .map((filePath) => `- ${normalizePath(path.relative(rootDir, filePath))}`)
660
- .join("\n")}\n`);
661
- }
679
+ let composedOutput;
662
680
  if (args.compose) {
663
- const output = composeRuleset(rulesetPath, rootDir, { refresh: args.refresh ?? false });
664
- process.stdout.write(`Composed AGENTS.md:\n- ${output}\n`);
681
+ composedOutput = composeRuleset(rulesetPath, rootDir, { refresh: args.refresh ?? false });
682
+ }
683
+ if (args.json) {
684
+ process.stdout.write(JSON.stringify({
685
+ initialized: [normalizePath(path.relative(rootDir, rulesetPath))],
686
+ localRules: extraToWrite.map((filePath) => normalizePath(path.relative(rootDir, filePath))),
687
+ composed: composedOutput ? [composedOutput] : [],
688
+ dryRun: false
689
+ }, null, 2) + "\n");
690
+ }
691
+ else if (!args.quiet) {
692
+ process.stdout.write(`Initialized ruleset:\n- ${normalizePath(path.relative(rootDir, rulesetPath))}\n`);
693
+ if (extraToWrite.length > 0) {
694
+ process.stdout.write(`Initialized local rules:\n${extraToWrite
695
+ .map((filePath) => `- ${normalizePath(path.relative(rootDir, filePath))}`)
696
+ .join("\n")}\n`);
697
+ }
698
+ if (composedOutput) {
699
+ process.stdout.write(`Composed AGENTS.md:\n- ${composedOutput}\n`);
700
+ }
665
701
  }
666
702
  };
667
703
  const getRulesetFiles = (rootDir, specificRuleset, rulesetName) => {
@@ -731,8 +767,13 @@ const main = async () => {
731
767
  const rulesetDir = path.dirname(rulesetPath);
732
768
  const ruleset = readProjectRuleset(rulesetPath);
733
769
  applyRulesFromWorkspace(rulesetDir, ruleset.source);
734
- const output = composeRuleset(rulesetPath, rootDir, { refresh: true });
735
- process.stdout.write(`Composed AGENTS.md:\n- ${output}\n`);
770
+ const output = composeRuleset(rulesetPath, rootDir, { refresh: true, dryRun: args.dryRun });
771
+ if (args.json) {
772
+ process.stdout.write(JSON.stringify({ composed: [output], dryRun: !!args.dryRun }, null, 2) + "\n");
773
+ }
774
+ else if (!args.quiet) {
775
+ process.stdout.write(`Composed AGENTS.md:\n- ${output}\n`);
776
+ }
736
777
  return;
737
778
  }
738
779
  if (rulesetFiles.length === 0) {
@@ -741,8 +782,13 @@ const main = async () => {
741
782
  }
742
783
  const outputs = rulesetFiles
743
784
  .sort()
744
- .map((rulesetPath) => composeRuleset(rulesetPath, rootDir, { refresh: args.refresh }));
745
- process.stdout.write(`Composed AGENTS.md:\n${outputs.map((file) => `- ${file}`).join("\n")}\n`);
785
+ .map((rulesetPath) => composeRuleset(rulesetPath, rootDir, { refresh: args.refresh, dryRun: args.dryRun }));
786
+ if (args.json) {
787
+ process.stdout.write(JSON.stringify({ composed: outputs, dryRun: !!args.dryRun }, null, 2) + "\n");
788
+ }
789
+ else if (!args.quiet) {
790
+ process.stdout.write(`Composed AGENTS.md:\n${outputs.map((file) => `- ${file}`).join("\n")}\n`);
791
+ }
746
792
  };
747
793
  const run = async () => {
748
794
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compose-agentsmd",
3
- "version": "3.2.4",
3
+ "version": "3.2.5",
4
4
  "description": "CLI tools for composing per-project AGENTS.md files from modular rule sets",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,7 +1,11 @@
1
1
  # Tool Rules (compose-agentsmd)
2
2
  - Before starting any work, run `compose-agentsmd` from the project root.
3
+ - `compose-agentsmd` intentionally regenerates `AGENTS.md`; any resulting `AGENTS.md` diff is expected and must not be treated as an unexpected external change.
4
+ - If `compose-agentsmd` is not available, install it via npm: `npm install -g compose-agentsmd`.
3
5
  - To update shared rules, run `compose-agentsmd edit-rules`, edit the workspace rules, then run `compose-agentsmd apply-rules`.
4
6
  - Do not edit `AGENTS.md` directly; update the source rules and regenerate.
7
+ - `tools/tool-rules.md` is the shared rule source for all repositories that use compose-agentsmd.
8
+ - Before applying any rule updates, present the planned changes first (prefer a colorized diff-style preview), ask for explicit approval, then make the edits.
5
9
  - These tool rules live in tools/tool-rules.md in the compose-agentsmd repository; do not duplicate them in global rule modules.
6
10
  - When updating rules, include a colorized diff-style summary in the final response. Use `git diff --stat` first, then include the raw ANSI-colored output of `git diff --color=always` (no sanitizing or reformatting), and limit the output to the rule files that changed.
7
11
  - Also provide a short, copy-pasteable command the user can run to view the diff in the same format. Use absolute paths so it works regardless of the current working directory, and scope it to the changed rule files.
package/tools/usage.txt CHANGED
@@ -1,9 +1,11 @@
1
- Usage: compose-agentsmd [edit-rules|apply-rules|init] [--root <path>] [--ruleset <path>] [--ruleset-name <name>] [--source <source>] [--domains <list>] [--extra <list>] [--output <file>] [--no-domains] [--no-extra] [--no-global] [--compose] [--dry-run] [--yes] [--force] [--refresh] [--clear-cache] [--version|-V] [--verbose|-v] [--help|-h]
1
+ Usage: compose-agentsmd [edit-rules|apply-rules|init] [--root <path>] [--ruleset <path>] [--ruleset-name <name>] [--source <source>] [--domains <list>] [--extra <list>] [--output <file>] [--no-domains] [--no-extra] [--no-global] [--compose] [--dry-run] [--yes] [--force] [--refresh] [--clear-cache] [--version|-V] [--verbose|-v] [--quiet|-q] [--json] [--help|-h]
2
2
 
3
3
  Options:
4
4
  --help, -h Show help and exit
5
5
  --version, -V Show version and exit
6
6
  --verbose, -v Show verbose diagnostics
7
+ --quiet, -q Suppress non-error human-readable output (JSON output is not suppressed)
8
+ --json Output machine-readable JSON (takes precedence over --quiet)
7
9
  --root <path> Project root directory (default: current working directory)
8
10
  --ruleset <path> Only compose a single ruleset file
9
11
  --ruleset-name <name> Ruleset filename in the project root (default: agent-ruleset.json)