compose-agentsmd 3.1.0 → 3.2.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 +38 -2
- package/dist/compose-agents.js +288 -12
- package/package.json +1 -1
- package/tools/usage.txt +16 -5
package/README.md
CHANGED
|
@@ -34,6 +34,24 @@ The tool reads `agent-ruleset.json` from the given root directory (default: curr
|
|
|
34
34
|
|
|
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
|
|
|
37
|
+
## Setup (init)
|
|
38
|
+
|
|
39
|
+
For a project that does not have a ruleset yet, bootstrap one with `init`:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
compose-agentsmd init --root path/to/project --yes
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Defaults:
|
|
46
|
+
|
|
47
|
+
- `source`: `github:owner/repo@latest`
|
|
48
|
+
- `domains`: empty
|
|
49
|
+
- `extra`: empty
|
|
50
|
+
- `global`: omitted (defaults to `true`)
|
|
51
|
+
- `output`: `AGENTS.md`
|
|
52
|
+
|
|
53
|
+
Use `--dry-run` to preview actions, `--force` to overwrite existing files, and `--compose` to generate `AGENTS.md` immediately.
|
|
54
|
+
|
|
37
55
|
## Updating shared rules
|
|
38
56
|
|
|
39
57
|
For GitHub sources, the tool keeps two locations:
|
|
@@ -53,11 +71,17 @@ compose-agentsmd apply-rules
|
|
|
53
71
|
|
|
54
72
|
## Project ruleset format
|
|
55
73
|
|
|
56
|
-
|
|
74
|
+
Ruleset files accept JSON with `//` or `/* */` comments.
|
|
75
|
+
|
|
76
|
+
```jsonc
|
|
57
77
|
{
|
|
58
|
-
|
|
78
|
+
// Rules source. Use github:owner/repo@ref or a local path.
|
|
79
|
+
"source": "github:owner/repo@latest",
|
|
80
|
+
// Domain folders under rules/domains.
|
|
59
81
|
"domains": ["node", "unreal"],
|
|
82
|
+
// Additional local rule files to append.
|
|
60
83
|
"extra": ["agent-rules-local/custom.md"],
|
|
84
|
+
// Output file name.
|
|
61
85
|
"output": "AGENTS.md"
|
|
62
86
|
}
|
|
63
87
|
```
|
|
@@ -87,8 +111,20 @@ Remote sources are cached under `~/.agentsmd/cache/<owner>/<repo>/<ref>/`. Use `
|
|
|
87
111
|
- `--clear-cache`: remove cached remote rules and exit
|
|
88
112
|
- `--version` / `-V`: show version and exit
|
|
89
113
|
- `--verbose` / `-v`: show verbose diagnostics
|
|
114
|
+
- `--source <source>`: rules source for `init`
|
|
115
|
+
- `--domains <list>`: comma-separated domains for `init`
|
|
116
|
+
- `--extra <list>`: comma-separated extra rules for `init`
|
|
117
|
+
- `--output <file>`: output filename for `init`
|
|
118
|
+
- `--no-domains`: initialize with no domains
|
|
119
|
+
- `--no-extra`: initialize without extra rule files
|
|
120
|
+
- `--no-global`: initialize without global rules
|
|
121
|
+
- `--compose`: compose `AGENTS.md` after `init`
|
|
122
|
+
- `--dry-run`: show init plan without writing files
|
|
123
|
+
- `--yes`: skip init confirmation prompt
|
|
124
|
+
- `--force`: overwrite existing files during init
|
|
90
125
|
- `edit-rules`: prepare or locate a writable rules workspace
|
|
91
126
|
- `apply-rules`: push workspace changes (if GitHub source) and regenerate rules with refresh
|
|
127
|
+
- `init`: generate a new ruleset and optional local rules file
|
|
92
128
|
|
|
93
129
|
## Development
|
|
94
130
|
|
package/dist/compose-agents.js
CHANGED
|
@@ -3,18 +3,22 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import { execFileSync } from "node:child_process";
|
|
6
|
+
import readline from "node:readline";
|
|
6
7
|
import { Ajv } from "ajv";
|
|
7
8
|
const DEFAULT_RULESET_NAME = "agent-ruleset.json";
|
|
8
9
|
const DEFAULT_OUTPUT = "AGENTS.md";
|
|
9
10
|
const DEFAULT_CACHE_ROOT = path.join(os.homedir(), ".agentsmd", "cache");
|
|
10
11
|
const DEFAULT_WORKSPACE_ROOT = path.join(os.homedir(), ".agentsmd", "workspace");
|
|
12
|
+
const DEFAULT_INIT_SOURCE = "github:owner/repo@latest";
|
|
13
|
+
const DEFAULT_INIT_DOMAINS = [];
|
|
14
|
+
const DEFAULT_INIT_EXTRA = [];
|
|
11
15
|
const RULESET_SCHEMA_PATH = new URL("../agent-ruleset.schema.json", import.meta.url);
|
|
12
16
|
const PACKAGE_JSON_PATH = new URL("../package.json", import.meta.url);
|
|
13
17
|
const TOOL_RULES_PATH = new URL("../tools/tool-rules.md", import.meta.url);
|
|
14
18
|
const USAGE_PATH = new URL("../tools/usage.txt", import.meta.url);
|
|
15
19
|
const parseArgs = (argv) => {
|
|
16
20
|
const args = {};
|
|
17
|
-
const knownCommands = new Set(["edit-rules", "apply-rules"]);
|
|
21
|
+
const knownCommands = new Set(["edit-rules", "apply-rules", "init"]);
|
|
18
22
|
const remaining = [...argv];
|
|
19
23
|
if (remaining.length > 0 && knownCommands.has(remaining[0])) {
|
|
20
24
|
args.command = remaining.shift();
|
|
@@ -68,6 +72,70 @@ const parseArgs = (argv) => {
|
|
|
68
72
|
args.clearCache = true;
|
|
69
73
|
continue;
|
|
70
74
|
}
|
|
75
|
+
if (arg === "--source") {
|
|
76
|
+
const value = remaining[i + 1];
|
|
77
|
+
if (!value) {
|
|
78
|
+
throw new Error("Missing value for --source");
|
|
79
|
+
}
|
|
80
|
+
args.source = value;
|
|
81
|
+
i += 1;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (arg === "--domains") {
|
|
85
|
+
const value = remaining[i + 1];
|
|
86
|
+
if (!value) {
|
|
87
|
+
throw new Error("Missing value for --domains");
|
|
88
|
+
}
|
|
89
|
+
args.domains = [...(args.domains ?? []), ...value.split(",").map((entry) => entry.trim())];
|
|
90
|
+
i += 1;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (arg === "--no-domains") {
|
|
94
|
+
args.domains = [];
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (arg === "--extra") {
|
|
98
|
+
const value = remaining[i + 1];
|
|
99
|
+
if (!value) {
|
|
100
|
+
throw new Error("Missing value for --extra");
|
|
101
|
+
}
|
|
102
|
+
args.extra = [...(args.extra ?? []), ...value.split(",").map((entry) => entry.trim())];
|
|
103
|
+
i += 1;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (arg === "--no-extra") {
|
|
107
|
+
args.extra = [];
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (arg === "--output") {
|
|
111
|
+
const value = remaining[i + 1];
|
|
112
|
+
if (!value) {
|
|
113
|
+
throw new Error("Missing value for --output");
|
|
114
|
+
}
|
|
115
|
+
args.output = value;
|
|
116
|
+
i += 1;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (arg === "--no-global") {
|
|
120
|
+
args.global = false;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (arg === "--compose") {
|
|
124
|
+
args.compose = true;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (arg === "--dry-run") {
|
|
128
|
+
args.dryRun = true;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (arg === "--yes") {
|
|
132
|
+
args.yes = true;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (arg === "--force") {
|
|
136
|
+
args.force = true;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
71
139
|
throw new Error(`Unknown argument: ${arg}`);
|
|
72
140
|
}
|
|
73
141
|
return args;
|
|
@@ -75,6 +143,23 @@ const parseArgs = (argv) => {
|
|
|
75
143
|
const normalizeTrailingWhitespace = (content) => content.replace(/\s+$/u, "");
|
|
76
144
|
const normalizePath = (filePath) => filePath.replace(/\\/g, "/");
|
|
77
145
|
const isNonEmptyString = (value) => typeof value === "string" && value.trim() !== "";
|
|
146
|
+
const normalizeListOption = (values, label) => {
|
|
147
|
+
if (!values) {
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
const trimmed = values.map((value) => value.trim());
|
|
151
|
+
if (trimmed.some((value) => value.length === 0)) {
|
|
152
|
+
throw new Error(`Invalid value for ${label}`);
|
|
153
|
+
}
|
|
154
|
+
return [...new Set(trimmed)];
|
|
155
|
+
};
|
|
156
|
+
const askQuestion = (prompt) => new Promise((resolve) => {
|
|
157
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
158
|
+
rl.question(prompt, (answer) => {
|
|
159
|
+
rl.close();
|
|
160
|
+
resolve(answer);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
78
163
|
const usage = normalizeTrailingWhitespace(fs.readFileSync(USAGE_PATH, "utf8"));
|
|
79
164
|
const packageJson = JSON.parse(fs.readFileSync(PACKAGE_JSON_PATH, "utf8"));
|
|
80
165
|
const getVersion = () => packageJson.version ?? "unknown";
|
|
@@ -121,9 +206,69 @@ const ensureDirectoryExists = (dirPath) => {
|
|
|
121
206
|
throw new Error(`Not a directory: ${dirPath}`);
|
|
122
207
|
}
|
|
123
208
|
};
|
|
209
|
+
const stripJsonComments = (input) => {
|
|
210
|
+
let output = "";
|
|
211
|
+
let inString = false;
|
|
212
|
+
let stringChar = "";
|
|
213
|
+
let escaping = false;
|
|
214
|
+
let inLineComment = false;
|
|
215
|
+
let inBlockComment = false;
|
|
216
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
217
|
+
const char = input[i];
|
|
218
|
+
const next = input[i + 1];
|
|
219
|
+
if (inLineComment) {
|
|
220
|
+
if (char === "\n") {
|
|
221
|
+
inLineComment = false;
|
|
222
|
+
output += char;
|
|
223
|
+
}
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (inBlockComment) {
|
|
227
|
+
if (char === "*" && next === "/") {
|
|
228
|
+
inBlockComment = false;
|
|
229
|
+
i += 1;
|
|
230
|
+
}
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (inString) {
|
|
234
|
+
output += char;
|
|
235
|
+
if (escaping) {
|
|
236
|
+
escaping = false;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (char === "\\") {
|
|
240
|
+
escaping = true;
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (char === stringChar) {
|
|
244
|
+
inString = false;
|
|
245
|
+
stringChar = "";
|
|
246
|
+
}
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (char === "/" && next === "/") {
|
|
250
|
+
inLineComment = true;
|
|
251
|
+
i += 1;
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (char === "/" && next === "*") {
|
|
255
|
+
inBlockComment = true;
|
|
256
|
+
i += 1;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (char === "\"" || char === "'") {
|
|
260
|
+
inString = true;
|
|
261
|
+
stringChar = char;
|
|
262
|
+
output += char;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
output += char;
|
|
266
|
+
}
|
|
267
|
+
return output;
|
|
268
|
+
};
|
|
124
269
|
const readJsonFile = (filePath) => {
|
|
125
270
|
const raw = fs.readFileSync(filePath, "utf8");
|
|
126
|
-
return JSON.parse(raw);
|
|
271
|
+
return JSON.parse(stripJsonComments(raw));
|
|
127
272
|
};
|
|
128
273
|
const readProjectRuleset = (rulesetPath) => {
|
|
129
274
|
const parsed = readJsonFile(rulesetPath);
|
|
@@ -390,6 +535,130 @@ const composeRuleset = (rulesetPath, rootDir, options) => {
|
|
|
390
535
|
fs.writeFileSync(outputPath, output, "utf8");
|
|
391
536
|
return normalizePath(path.relative(rootDir, outputPath));
|
|
392
537
|
};
|
|
538
|
+
const LOCAL_RULES_TEMPLATE = "# Local Rules\n\n- Add project-specific instructions here.\n";
|
|
539
|
+
const buildInitRuleset = (args) => {
|
|
540
|
+
const domains = normalizeListOption(args.domains, "--domains");
|
|
541
|
+
const extra = normalizeListOption(args.extra, "--extra");
|
|
542
|
+
const ruleset = {
|
|
543
|
+
source: args.source ?? DEFAULT_INIT_SOURCE,
|
|
544
|
+
output: args.output ?? DEFAULT_OUTPUT
|
|
545
|
+
};
|
|
546
|
+
if (args.global === false) {
|
|
547
|
+
ruleset.global = false;
|
|
548
|
+
}
|
|
549
|
+
const resolvedDomains = domains ?? DEFAULT_INIT_DOMAINS;
|
|
550
|
+
if (resolvedDomains.length > 0) {
|
|
551
|
+
ruleset.domains = resolvedDomains;
|
|
552
|
+
}
|
|
553
|
+
const resolvedExtra = extra ?? DEFAULT_INIT_EXTRA;
|
|
554
|
+
if (resolvedExtra.length > 0) {
|
|
555
|
+
ruleset.extra = resolvedExtra;
|
|
556
|
+
}
|
|
557
|
+
return ruleset;
|
|
558
|
+
};
|
|
559
|
+
const formatInitRuleset = (ruleset) => {
|
|
560
|
+
const domainsValue = JSON.stringify(ruleset.domains ?? []);
|
|
561
|
+
const extraValue = JSON.stringify(ruleset.extra ?? []);
|
|
562
|
+
const lines = [
|
|
563
|
+
"{",
|
|
564
|
+
' // Rules source. Use github:owner/repo@ref or a local path.',
|
|
565
|
+
` "source": "${ruleset.source}",`,
|
|
566
|
+
' // Domain folders under rules/domains.',
|
|
567
|
+
` "domains": ${domainsValue},`,
|
|
568
|
+
' // Additional local rule files to append.',
|
|
569
|
+
` "extra": ${extraValue},`
|
|
570
|
+
];
|
|
571
|
+
if (ruleset.global === false) {
|
|
572
|
+
lines.push(' // Include rules/global from the source.');
|
|
573
|
+
lines.push(' "global": false,');
|
|
574
|
+
}
|
|
575
|
+
lines.push(' // Output file name.');
|
|
576
|
+
lines.push(` "output": "${ruleset.output ?? DEFAULT_OUTPUT}"`);
|
|
577
|
+
lines.push("}");
|
|
578
|
+
return `${lines.join("\n")}\n`;
|
|
579
|
+
};
|
|
580
|
+
const formatPlan = (items, rootDir) => {
|
|
581
|
+
const lines = items.map((item) => {
|
|
582
|
+
const verb = item.action === "overwrite" ? "Overwrite" : "Create";
|
|
583
|
+
const relative = normalizePath(path.relative(rootDir, item.path));
|
|
584
|
+
return `- ${verb}: ${relative}`;
|
|
585
|
+
});
|
|
586
|
+
return `Init plan:\n${lines.join("\n")}\n`;
|
|
587
|
+
};
|
|
588
|
+
const confirmInit = async (args) => {
|
|
589
|
+
if (args.dryRun || args.yes) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
if (!process.stdin.isTTY) {
|
|
593
|
+
throw new Error("Confirmation required. Re-run with --yes to continue.");
|
|
594
|
+
}
|
|
595
|
+
const answer = await askQuestion("Proceed with init? [y/N] ");
|
|
596
|
+
if (!/^y(es)?$/iu.test(answer.trim())) {
|
|
597
|
+
throw new Error("Init aborted.");
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
const initProject = async (args, rootDir, rulesetName) => {
|
|
601
|
+
const rulesetPath = args.ruleset ? resolveFrom(rootDir, args.ruleset) : path.join(rootDir, rulesetName);
|
|
602
|
+
const rulesetDir = path.dirname(rulesetPath);
|
|
603
|
+
const ruleset = buildInitRuleset(args);
|
|
604
|
+
const outputPath = resolveFrom(rulesetDir, ruleset.output ?? DEFAULT_OUTPUT);
|
|
605
|
+
const plan = [];
|
|
606
|
+
if (fs.existsSync(rulesetPath)) {
|
|
607
|
+
if (!args.force) {
|
|
608
|
+
throw new Error(`Ruleset already exists: ${normalizePath(rulesetPath)}`);
|
|
609
|
+
}
|
|
610
|
+
plan.push({ action: "overwrite", path: rulesetPath });
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
plan.push({ action: "create", path: rulesetPath });
|
|
614
|
+
}
|
|
615
|
+
const extraFiles = (ruleset.extra ?? []).map((rulePath) => resolveFrom(rulesetDir, rulePath));
|
|
616
|
+
const extraToWrite = [];
|
|
617
|
+
for (const extraPath of extraFiles) {
|
|
618
|
+
if (fs.existsSync(extraPath)) {
|
|
619
|
+
if (args.force) {
|
|
620
|
+
plan.push({ action: "overwrite", path: extraPath });
|
|
621
|
+
extraToWrite.push(extraPath);
|
|
622
|
+
}
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
plan.push({ action: "create", path: extraPath });
|
|
626
|
+
extraToWrite.push(extraPath);
|
|
627
|
+
}
|
|
628
|
+
if (args.compose) {
|
|
629
|
+
if (fs.existsSync(outputPath)) {
|
|
630
|
+
if (!args.force) {
|
|
631
|
+
throw new Error(`Output already exists: ${normalizePath(outputPath)} (use --force to overwrite)`);
|
|
632
|
+
}
|
|
633
|
+
plan.push({ action: "overwrite", path: outputPath });
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
plan.push({ action: "create", path: outputPath });
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
process.stdout.write(formatPlan(plan, rootDir));
|
|
640
|
+
if (args.dryRun) {
|
|
641
|
+
process.stdout.write("Dry run: no changes made.\n");
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
await confirmInit(args);
|
|
645
|
+
fs.mkdirSync(path.dirname(rulesetPath), { recursive: true });
|
|
646
|
+
fs.writeFileSync(`${rulesetPath}`, formatInitRuleset(ruleset), "utf8");
|
|
647
|
+
for (const extraPath of extraToWrite) {
|
|
648
|
+
fs.mkdirSync(path.dirname(extraPath), { recursive: true });
|
|
649
|
+
fs.writeFileSync(extraPath, LOCAL_RULES_TEMPLATE, "utf8");
|
|
650
|
+
}
|
|
651
|
+
process.stdout.write(`Initialized ruleset:\n- ${normalizePath(path.relative(rootDir, rulesetPath))}\n`);
|
|
652
|
+
if (extraToWrite.length > 0) {
|
|
653
|
+
process.stdout.write(`Initialized local rules:\n${extraToWrite
|
|
654
|
+
.map((filePath) => `- ${normalizePath(path.relative(rootDir, filePath))}`)
|
|
655
|
+
.join("\n")}\n`);
|
|
656
|
+
}
|
|
657
|
+
if (args.compose) {
|
|
658
|
+
const output = composeRuleset(rulesetPath, rootDir, { refresh: args.refresh ?? false });
|
|
659
|
+
process.stdout.write(`Composed AGENTS.md:\n- ${output}\n`);
|
|
660
|
+
}
|
|
661
|
+
};
|
|
393
662
|
const getRulesetFiles = (rootDir, specificRuleset, rulesetName) => {
|
|
394
663
|
if (specificRuleset) {
|
|
395
664
|
const resolved = resolveFrom(rootDir, specificRuleset);
|
|
@@ -409,7 +678,7 @@ const ensureSingleRuleset = (rulesetFiles, rootDir, rulesetName) => {
|
|
|
409
678
|
}
|
|
410
679
|
return rulesetFiles[0];
|
|
411
680
|
};
|
|
412
|
-
const main = () => {
|
|
681
|
+
const main = async () => {
|
|
413
682
|
const args = parseArgs(process.argv.slice(2));
|
|
414
683
|
if (args.version) {
|
|
415
684
|
process.stdout.write(`${getVersion()}\n`);
|
|
@@ -448,6 +717,10 @@ const main = () => {
|
|
|
448
717
|
process.stdout.write(`Rules workspace: ${workspaceRoot}\n`);
|
|
449
718
|
return;
|
|
450
719
|
}
|
|
720
|
+
if (command === "init") {
|
|
721
|
+
await initProject(args, rootDir, rulesetName);
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
451
724
|
if (command === "apply-rules") {
|
|
452
725
|
const rulesetPath = ensureSingleRuleset(rulesetFiles, rootDir, rulesetName);
|
|
453
726
|
const rulesetDir = path.dirname(rulesetPath);
|
|
@@ -466,12 +739,15 @@ const main = () => {
|
|
|
466
739
|
.map((rulesetPath) => composeRuleset(rulesetPath, rootDir, { refresh: args.refresh }));
|
|
467
740
|
process.stdout.write(`Composed AGENTS.md:\n${outputs.map((file) => `- ${file}`).join("\n")}\n`);
|
|
468
741
|
};
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
742
|
+
const run = async () => {
|
|
743
|
+
try {
|
|
744
|
+
await main();
|
|
745
|
+
}
|
|
746
|
+
catch (error) {
|
|
747
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
748
|
+
process.stderr.write(`${message}\n`);
|
|
749
|
+
process.stderr.write(`${usage}\n`);
|
|
750
|
+
process.exit(1);
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
void run();
|
package/package.json
CHANGED
package/tools/usage.txt
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
|
-
Usage: compose-agentsmd [edit-rules|apply-rules] [--root <path>] [--ruleset <path>] [--ruleset-name <name>] [--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] [--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
|
-
--root <path>
|
|
8
|
-
--ruleset <path>
|
|
7
|
+
--root <path> Project root directory (default: current working directory)
|
|
8
|
+
--ruleset <path> Only compose a single ruleset file
|
|
9
9
|
--ruleset-name <name> Ruleset filename in the project root (default: agent-ruleset.json)
|
|
10
|
-
--
|
|
11
|
-
--
|
|
10
|
+
--source <source> Rules source for init (default: github:owner/repo@latest)
|
|
11
|
+
--domains <list> Comma-separated domains for init (default: none)
|
|
12
|
+
--extra <list> Comma-separated extra rules for init
|
|
13
|
+
--output <file> Output filename for init (default: AGENTS.md)
|
|
14
|
+
--no-domains Initialize with no domains
|
|
15
|
+
--no-extra Initialize without extra rule files
|
|
16
|
+
--no-global Initialize without global rules
|
|
17
|
+
--compose Compose AGENTS.md after init
|
|
18
|
+
--dry-run Show init plan without writing files
|
|
19
|
+
--yes Skip init confirmation prompt
|
|
20
|
+
--force Overwrite existing files during init
|
|
21
|
+
--refresh Refresh cached remote rules
|
|
22
|
+
--clear-cache Remove cached remote rules and exit
|