compose-agentsmd 3.2.6 → 3.2.7
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 +2 -0
- package/dist/compose-agents.js +59 -10
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -35,6 +35,8 @@ The tool reads `agent-ruleset.json` from the given root directory (default: curr
|
|
|
35
35
|
The tool prepends a small "Tool Rules" block to every generated `AGENTS.md` so agents know how to regenerate or update rules.
|
|
36
36
|
Each composed rule section is also prefixed with the source file path that produced it.
|
|
37
37
|
|
|
38
|
+
When the output file is `AGENTS.md`, the CLI also prints a unified diff for `AGENTS.md` when it changes (and prints `AGENTS.md unchanged.` when it does not). This works even when the project is not under git. `--quiet` and `--json` suppress this output.
|
|
39
|
+
|
|
38
40
|
## Setup (init)
|
|
39
41
|
|
|
40
42
|
For a project that does not have a ruleset yet, bootstrap one with `init`:
|
package/dist/compose-agents.js
CHANGED
|
@@ -5,6 +5,7 @@ import os from "node:os";
|
|
|
5
5
|
import { execFileSync } from "node:child_process";
|
|
6
6
|
import readline from "node:readline";
|
|
7
7
|
import { Ajv } from "ajv";
|
|
8
|
+
import { createTwoFilesPatch } from "diff";
|
|
8
9
|
const DEFAULT_RULESET_NAME = "agent-ruleset.json";
|
|
9
10
|
const DEFAULT_OUTPUT = "AGENTS.md";
|
|
10
11
|
const DEFAULT_CACHE_ROOT = path.join(os.homedir(), ".agentsmd", "cache");
|
|
@@ -520,6 +521,7 @@ const composeRuleset = (rulesetPath, rootDir, options) => {
|
|
|
520
521
|
const projectRuleset = readProjectRuleset(rulesetPath);
|
|
521
522
|
const outputFileName = projectRuleset.output ?? DEFAULT_OUTPUT;
|
|
522
523
|
const outputPath = resolveFrom(rulesetDir, outputFileName);
|
|
524
|
+
const composedOutputPath = normalizePath(path.relative(rootDir, outputPath));
|
|
523
525
|
const { rulesRoot, resolvedRef } = resolveRulesRoot(rulesetDir, projectRuleset.source, options.refresh ?? false);
|
|
524
526
|
const globalRoot = path.join(rulesRoot, "global");
|
|
525
527
|
const domainsRoot = path.join(rulesRoot, "domains");
|
|
@@ -544,11 +546,42 @@ const composeRuleset = (rulesetPath, rootDir, options) => {
|
|
|
544
546
|
const lintHeader = "<!-- markdownlint-disable MD025 -->";
|
|
545
547
|
const toolRules = normalizeTrailingWhitespace(TOOL_RULES);
|
|
546
548
|
const output = `${lintHeader}\n${[toolRules, ...parts].join("\n\n")}\n`;
|
|
549
|
+
let agentsMdDiff;
|
|
550
|
+
if (options.emitAgentsMdDiff && path.basename(outputPath) === DEFAULT_OUTPUT) {
|
|
551
|
+
const before = fs.existsSync(outputPath) ? fs.readFileSync(outputPath, "utf8") : "";
|
|
552
|
+
if (before === output) {
|
|
553
|
+
agentsMdDiff = { status: "unchanged" };
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
agentsMdDiff = {
|
|
557
|
+
status: "updated",
|
|
558
|
+
patch: createTwoFilesPatch(`a/${composedOutputPath}`, `b/${composedOutputPath}`, before, output, "", "", { context: 3 })
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
}
|
|
547
562
|
if (!options.dryRun) {
|
|
548
563
|
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
549
564
|
fs.writeFileSync(outputPath, output, "utf8");
|
|
550
565
|
}
|
|
551
|
-
return
|
|
566
|
+
return { output: composedOutputPath, agentsMdDiff };
|
|
567
|
+
};
|
|
568
|
+
const printAgentsMdDiffIfPresent = (result) => {
|
|
569
|
+
if (!result.agentsMdDiff) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
if (result.agentsMdDiff.status === "unchanged") {
|
|
573
|
+
process.stdout.write("AGENTS.md unchanged.\n");
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
process.stdout.write("AGENTS.md updated. ACTION (agent): refresh rule recognition from the diff below.\n");
|
|
577
|
+
process.stdout.write("--- BEGIN DIFF ---\n");
|
|
578
|
+
if (result.agentsMdDiff.patch) {
|
|
579
|
+
process.stdout.write(result.agentsMdDiff.patch);
|
|
580
|
+
if (!result.agentsMdDiff.patch.endsWith("\n")) {
|
|
581
|
+
process.stdout.write("\n");
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
process.stdout.write("--- END DIFF ---\n");
|
|
552
585
|
};
|
|
553
586
|
const LOCAL_RULES_TEMPLATE = "# Local Rules\n\n- Add project-specific instructions here.\n";
|
|
554
587
|
const buildInitRuleset = (args) => {
|
|
@@ -678,13 +711,16 @@ const initProject = async (args, rootDir, rulesetName) => {
|
|
|
678
711
|
}
|
|
679
712
|
let composedOutput;
|
|
680
713
|
if (args.compose) {
|
|
681
|
-
composedOutput = composeRuleset(rulesetPath, rootDir, {
|
|
714
|
+
composedOutput = composeRuleset(rulesetPath, rootDir, {
|
|
715
|
+
refresh: args.refresh ?? false,
|
|
716
|
+
emitAgentsMdDiff: !args.quiet && !args.json
|
|
717
|
+
});
|
|
682
718
|
}
|
|
683
719
|
if (args.json) {
|
|
684
720
|
process.stdout.write(JSON.stringify({
|
|
685
721
|
initialized: [normalizePath(path.relative(rootDir, rulesetPath))],
|
|
686
722
|
localRules: extraToWrite.map((filePath) => normalizePath(path.relative(rootDir, filePath))),
|
|
687
|
-
composed: composedOutput ? [composedOutput] : [],
|
|
723
|
+
composed: composedOutput ? [composedOutput.output] : [],
|
|
688
724
|
dryRun: false
|
|
689
725
|
}, null, 2) + "\n");
|
|
690
726
|
}
|
|
@@ -696,7 +732,8 @@ const initProject = async (args, rootDir, rulesetName) => {
|
|
|
696
732
|
.join("\n")}\n`);
|
|
697
733
|
}
|
|
698
734
|
if (composedOutput) {
|
|
699
|
-
process.stdout.write(`Composed AGENTS.md:\n- ${composedOutput}\n`);
|
|
735
|
+
process.stdout.write(`Composed AGENTS.md:\n- ${composedOutput.output}\n`);
|
|
736
|
+
printAgentsMdDiffIfPresent(composedOutput);
|
|
700
737
|
}
|
|
701
738
|
}
|
|
702
739
|
};
|
|
@@ -777,12 +814,17 @@ const main = async () => {
|
|
|
777
814
|
const rulesetDir = path.dirname(rulesetPath);
|
|
778
815
|
const ruleset = readProjectRuleset(rulesetPath);
|
|
779
816
|
applyRulesFromWorkspace(rulesetDir, ruleset.source);
|
|
780
|
-
const output = composeRuleset(rulesetPath, rootDir, {
|
|
817
|
+
const output = composeRuleset(rulesetPath, rootDir, {
|
|
818
|
+
refresh: true,
|
|
819
|
+
dryRun: args.dryRun,
|
|
820
|
+
emitAgentsMdDiff: !args.quiet && !args.json
|
|
821
|
+
});
|
|
781
822
|
if (args.json) {
|
|
782
|
-
process.stdout.write(JSON.stringify({ composed: [output], dryRun: !!args.dryRun }, null, 2) + "\n");
|
|
823
|
+
process.stdout.write(JSON.stringify({ composed: [output.output], dryRun: !!args.dryRun }, null, 2) + "\n");
|
|
783
824
|
}
|
|
784
825
|
else if (!args.quiet) {
|
|
785
|
-
process.stdout.write(`Composed AGENTS.md:\n- ${output}\n`);
|
|
826
|
+
process.stdout.write(`Composed AGENTS.md:\n- ${output.output}\n`);
|
|
827
|
+
printAgentsMdDiffIfPresent(output);
|
|
786
828
|
}
|
|
787
829
|
return;
|
|
788
830
|
}
|
|
@@ -792,12 +834,19 @@ const main = async () => {
|
|
|
792
834
|
}
|
|
793
835
|
const outputs = rulesetFiles
|
|
794
836
|
.sort()
|
|
795
|
-
.map((rulesetPath) => composeRuleset(rulesetPath, rootDir, {
|
|
837
|
+
.map((rulesetPath) => composeRuleset(rulesetPath, rootDir, {
|
|
838
|
+
refresh: args.refresh,
|
|
839
|
+
dryRun: args.dryRun,
|
|
840
|
+
emitAgentsMdDiff: !args.quiet && !args.json
|
|
841
|
+
}));
|
|
796
842
|
if (args.json) {
|
|
797
|
-
process.stdout.write(JSON.stringify({ composed: outputs, dryRun: !!args.dryRun }, null, 2) + "\n");
|
|
843
|
+
process.stdout.write(JSON.stringify({ composed: outputs.map((result) => result.output), dryRun: !!args.dryRun }, null, 2) + "\n");
|
|
798
844
|
}
|
|
799
845
|
else if (!args.quiet) {
|
|
800
|
-
process.stdout.write(`Composed AGENTS.md:\n${outputs.map((
|
|
846
|
+
process.stdout.write(`Composed AGENTS.md:\n${outputs.map((result) => `- ${result.output}`).join("\n")}\n`);
|
|
847
|
+
for (const result of outputs) {
|
|
848
|
+
printAgentsMdDiffIfPresent(result);
|
|
849
|
+
}
|
|
801
850
|
}
|
|
802
851
|
};
|
|
803
852
|
const run = async () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compose-agentsmd",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.7",
|
|
4
4
|
"description": "CLI tools for composing per-project AGENTS.md files from modular rule sets",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"typescript": "^5.7.3"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"ajv": "^8.17.1"
|
|
51
|
+
"ajv": "^8.17.1",
|
|
52
|
+
"diff": "^8.0.3"
|
|
52
53
|
}
|
|
53
54
|
}
|