compose-agentsmd 1.0.0 → 1.0.1
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/compose-agents.js +26 -31
- package/package.json +9 -3
- package/tools/compose-agents.js +2 -0
- package/tools/compose-agents.cjs +0 -2
package/dist/compose-agents.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
9
4
|
const DEFAULT_RULESET_NAME = "agent-ruleset.json";
|
|
10
5
|
const DEFAULT_RULES_ROOT = "agent-rules/rules";
|
|
11
6
|
const DEFAULT_GLOBAL_DIR = "global";
|
|
@@ -87,27 +82,27 @@ const normalizeTrailingWhitespace = (content) => content.replace(/\s+$/u, "");
|
|
|
87
82
|
const normalizePath = (filePath) => filePath.replace(/\\/g, "/");
|
|
88
83
|
const isNonEmptyString = (value) => typeof value === "string" && value.trim() !== "";
|
|
89
84
|
const resolveFrom = (baseDir, targetPath) => {
|
|
90
|
-
if (
|
|
85
|
+
if (path.isAbsolute(targetPath)) {
|
|
91
86
|
return targetPath;
|
|
92
87
|
}
|
|
93
|
-
return
|
|
88
|
+
return path.resolve(baseDir, targetPath);
|
|
94
89
|
};
|
|
95
90
|
const ensureFileExists = (filePath) => {
|
|
96
|
-
if (!
|
|
91
|
+
if (!fs.existsSync(filePath)) {
|
|
97
92
|
throw new Error(`Missing file: ${filePath}`);
|
|
98
93
|
}
|
|
99
94
|
};
|
|
100
95
|
const ensureDirectoryExists = (dirPath) => {
|
|
101
|
-
if (!
|
|
96
|
+
if (!fs.existsSync(dirPath)) {
|
|
102
97
|
throw new Error(`Missing directory: ${dirPath}`);
|
|
103
98
|
}
|
|
104
|
-
const stat =
|
|
99
|
+
const stat = fs.statSync(dirPath);
|
|
105
100
|
if (!stat.isDirectory()) {
|
|
106
101
|
throw new Error(`Not a directory: ${dirPath}`);
|
|
107
102
|
}
|
|
108
103
|
};
|
|
109
104
|
const readJsonFile = (filePath) => {
|
|
110
|
-
const raw =
|
|
105
|
+
const raw = fs.readFileSync(filePath, "utf8");
|
|
111
106
|
return JSON.parse(raw);
|
|
112
107
|
};
|
|
113
108
|
const readProjectRuleset = (rulesetPath) => {
|
|
@@ -151,19 +146,19 @@ const resolveRulesRoot = (rulesetDir, projectRuleset, options) => {
|
|
|
151
146
|
if (isNonEmptyString(projectRuleset.rulesRoot)) {
|
|
152
147
|
return resolveFrom(rulesetDir, projectRuleset.rulesRoot);
|
|
153
148
|
}
|
|
154
|
-
return
|
|
149
|
+
return path.resolve(rulesetDir, DEFAULT_RULES_ROOT);
|
|
155
150
|
};
|
|
156
151
|
const resolveGlobalRoot = (rulesRoot, projectRuleset) => {
|
|
157
152
|
const globalDirName = isNonEmptyString(projectRuleset.globalDir)
|
|
158
153
|
? projectRuleset.globalDir
|
|
159
154
|
: DEFAULT_GLOBAL_DIR;
|
|
160
|
-
return
|
|
155
|
+
return path.resolve(rulesRoot, globalDirName);
|
|
161
156
|
};
|
|
162
157
|
const resolveDomainsRoot = (rulesRoot, projectRuleset) => {
|
|
163
158
|
const domainsDirName = isNonEmptyString(projectRuleset.domainsDir)
|
|
164
159
|
? projectRuleset.domainsDir
|
|
165
160
|
: DEFAULT_DOMAINS_DIR;
|
|
166
|
-
return
|
|
161
|
+
return path.resolve(rulesRoot, domainsDirName);
|
|
167
162
|
};
|
|
168
163
|
const collectMarkdownFiles = (rootDir) => {
|
|
169
164
|
ensureDirectoryExists(rootDir);
|
|
@@ -174,27 +169,27 @@ const collectMarkdownFiles = (rootDir) => {
|
|
|
174
169
|
if (!currentDir) {
|
|
175
170
|
continue;
|
|
176
171
|
}
|
|
177
|
-
const entries =
|
|
172
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
178
173
|
for (const entry of entries) {
|
|
179
|
-
const entryPath =
|
|
174
|
+
const entryPath = path.join(currentDir, entry.name);
|
|
180
175
|
if (entry.isDirectory()) {
|
|
181
176
|
pending.push(entryPath);
|
|
182
177
|
continue;
|
|
183
178
|
}
|
|
184
|
-
if (entry.isFile() &&
|
|
179
|
+
if (entry.isFile() && path.extname(entry.name).toLowerCase() === ".md") {
|
|
185
180
|
results.push(entryPath);
|
|
186
181
|
}
|
|
187
182
|
}
|
|
188
183
|
}
|
|
189
184
|
return results.sort((a, b) => {
|
|
190
|
-
const relA = normalizePath(
|
|
191
|
-
const relB = normalizePath(
|
|
185
|
+
const relA = normalizePath(path.relative(rootDir, a));
|
|
186
|
+
const relB = normalizePath(path.relative(rootDir, b));
|
|
192
187
|
return relA.localeCompare(relB);
|
|
193
188
|
});
|
|
194
189
|
};
|
|
195
190
|
const addRulePaths = (rulePaths, resolvedRules, seenRules) => {
|
|
196
191
|
for (const rulePath of rulePaths) {
|
|
197
|
-
const resolvedRulePath =
|
|
192
|
+
const resolvedRulePath = path.resolve(rulePath);
|
|
198
193
|
if (seenRules.has(resolvedRulePath)) {
|
|
199
194
|
continue;
|
|
200
195
|
}
|
|
@@ -204,7 +199,7 @@ const addRulePaths = (rulePaths, resolvedRules, seenRules) => {
|
|
|
204
199
|
}
|
|
205
200
|
};
|
|
206
201
|
const composeRuleset = (rulesetPath, rootDir, options) => {
|
|
207
|
-
const rulesetDir =
|
|
202
|
+
const rulesetDir = path.dirname(rulesetPath);
|
|
208
203
|
const projectRuleset = readProjectRuleset(rulesetPath);
|
|
209
204
|
const outputFileName = projectRuleset.output ?? DEFAULT_OUTPUT;
|
|
210
205
|
const outputPath = resolveFrom(rulesetDir, outputFileName);
|
|
@@ -219,18 +214,18 @@ const composeRuleset = (rulesetPath, rootDir, options) => {
|
|
|
219
214
|
addRulePaths(collectMarkdownFiles(globalRoot), resolvedRules, seenRules);
|
|
220
215
|
const domains = Array.isArray(projectRuleset.domains) ? projectRuleset.domains : [];
|
|
221
216
|
for (const domain of domains) {
|
|
222
|
-
const domainRoot =
|
|
217
|
+
const domainRoot = path.resolve(domainsRoot, domain);
|
|
223
218
|
addRulePaths(collectMarkdownFiles(domainRoot), resolvedRules, seenRules);
|
|
224
219
|
}
|
|
225
220
|
const directRules = Array.isArray(projectRuleset.rules) ? projectRuleset.rules : [];
|
|
226
221
|
const directRulePaths = directRules.map((rulePath) => resolveFrom(rulesetDir, rulePath));
|
|
227
222
|
addRulePaths(directRulePaths, resolvedRules, seenRules);
|
|
228
|
-
const parts = resolvedRules.map((rulePath) => normalizeTrailingWhitespace(
|
|
223
|
+
const parts = resolvedRules.map((rulePath) => normalizeTrailingWhitespace(fs.readFileSync(rulePath, "utf8")));
|
|
229
224
|
const lintHeader = "<!-- markdownlint-disable MD025 -->";
|
|
230
225
|
const output = `${lintHeader}\n${parts.join("\n\n")}\n`;
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
return normalizePath(
|
|
226
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
227
|
+
fs.writeFileSync(outputPath, output, "utf8");
|
|
228
|
+
return normalizePath(path.relative(rootDir, outputPath));
|
|
234
229
|
};
|
|
235
230
|
const findRulesetFiles = (rootDir, rulesetName) => {
|
|
236
231
|
const results = [];
|
|
@@ -240,9 +235,9 @@ const findRulesetFiles = (rootDir, rulesetName) => {
|
|
|
240
235
|
if (!currentDir) {
|
|
241
236
|
continue;
|
|
242
237
|
}
|
|
243
|
-
const entries =
|
|
238
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
244
239
|
for (const entry of entries) {
|
|
245
|
-
const entryPath =
|
|
240
|
+
const entryPath = path.join(currentDir, entry.name);
|
|
246
241
|
if (entry.isDirectory()) {
|
|
247
242
|
if (DEFAULT_IGNORE_DIRS.has(entry.name)) {
|
|
248
243
|
continue;
|
|
@@ -271,7 +266,7 @@ const main = () => {
|
|
|
271
266
|
process.stdout.write(`${usage}\n`);
|
|
272
267
|
return;
|
|
273
268
|
}
|
|
274
|
-
const rootDir = args.root ?
|
|
269
|
+
const rootDir = args.root ? path.resolve(args.root) : process.cwd();
|
|
275
270
|
const rulesetName = args.rulesetName || DEFAULT_RULESET_NAME;
|
|
276
271
|
const rulesetFiles = getRulesetFiles(rootDir, args.ruleset, rulesetName);
|
|
277
272
|
if (rulesetFiles.length === 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compose-agentsmd",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "CLI tools for composing per-project AGENTS.md files from modular rule sets",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -18,17 +18,23 @@
|
|
|
18
18
|
"cli",
|
|
19
19
|
"markdown"
|
|
20
20
|
],
|
|
21
|
-
"type": "
|
|
21
|
+
"type": "module",
|
|
22
22
|
"bin": {
|
|
23
23
|
"compose-agentsmd": "dist/compose-agents.js"
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
"dist",
|
|
27
|
-
"tools"
|
|
27
|
+
"tools",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE"
|
|
28
30
|
],
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
29
34
|
"scripts": {
|
|
30
35
|
"build": "tsc -p tsconfig.json",
|
|
31
36
|
"lint": "tsc -p tsconfig.json --noEmit",
|
|
37
|
+
"prepare": "npm run build",
|
|
32
38
|
"prepack": "npm run build",
|
|
33
39
|
"test": "npm run build && node --test",
|
|
34
40
|
"compose": "npm run build && node dist/compose-agents.js"
|
package/tools/compose-agents.cjs
DELETED