@agentrules/cli 0.2.0 → 0.2.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/index.js +43 -13
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -162,6 +162,21 @@ function getInstallPath({ platform, type, name, scope = "project" }) {
|
|
|
162
162
|
if (template.includes("{name}") && !name) throw new Error(`Missing name for install path: platform="${platform}" type="${type}" scope="${scope}"`);
|
|
163
163
|
return template.replace("{platformDir}", rootDir).replace("{name}", name ?? "");
|
|
164
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Get the relative install path for a type (without the root directory prefix).
|
|
167
|
+
* Returns the path relative to the platform's root directory.
|
|
168
|
+
*
|
|
169
|
+
* Example: For codex instruction with scope="global", returns "AGENTS.md"
|
|
170
|
+
* (not "~/.codex/AGENTS.md")
|
|
171
|
+
*/
|
|
172
|
+
function getRelativeInstallPath({ platform, type, name, scope = "project" }) {
|
|
173
|
+
const typeConfig = getTypeConfig(platform, type);
|
|
174
|
+
if (!typeConfig) return null;
|
|
175
|
+
const template = scope === "project" ? typeConfig.project : typeConfig.global;
|
|
176
|
+
if (!template) return null;
|
|
177
|
+
if (template.includes("{name}") && !name) throw new Error(`Missing name for install path: platform="${platform}" type="${type}" scope="${scope}"`);
|
|
178
|
+
return template.replace("{platformDir}/", "").replace("{platformDir}", "").replace("{name}", name ?? "");
|
|
179
|
+
}
|
|
165
180
|
|
|
166
181
|
//#endregion
|
|
167
182
|
//#region ../core/src/platform/utils.ts
|
|
@@ -3757,7 +3772,7 @@ function normalizeBundleBase(base) {
|
|
|
3757
3772
|
}
|
|
3758
3773
|
function getBundlePath(base, slug, platform, version$2) {
|
|
3759
3774
|
const prefix = base ? `${base}/` : "";
|
|
3760
|
-
return `${prefix}${STATIC_BUNDLE_DIR}/${slug}/${
|
|
3775
|
+
return `${prefix}${STATIC_BUNDLE_DIR}/${slug}/${version$2}/${platform}.json`;
|
|
3761
3776
|
}
|
|
3762
3777
|
function ensureKnownPlatform(platform, slug) {
|
|
3763
3778
|
if (!isSupportedPlatform(platform)) throw new Error(`Unknown platform "${platform}" in ${slug}. Supported: ${PLATFORM_IDS.join(", ")}`);
|
|
@@ -5534,7 +5549,7 @@ function resolveInstallTarget(platform, type, name, options) {
|
|
|
5534
5549
|
mode: "global",
|
|
5535
5550
|
platform,
|
|
5536
5551
|
platformDir,
|
|
5537
|
-
globalDir,
|
|
5552
|
+
globalDir: globalRoot,
|
|
5538
5553
|
type,
|
|
5539
5554
|
name,
|
|
5540
5555
|
label: `global path ${globalRoot}`
|
|
@@ -5558,17 +5573,20 @@ function resolveInstallTarget(platform, type, name, options) {
|
|
|
5558
5573
|
*
|
|
5559
5574
|
* - Project scope: use file.path directly
|
|
5560
5575
|
* - Global scope:
|
|
5561
|
-
* - If path starts with platformDir:
|
|
5562
|
-
* - If
|
|
5563
|
-
* -
|
|
5576
|
+
* - If path starts with platformDir: strip prefix (target.root is already globalDir)
|
|
5577
|
+
* - If typed bundle and root file: use type template to get relative path
|
|
5578
|
+
* - If freeform bundle and root file: use path as-is (relative to globalDir)
|
|
5579
|
+
*
|
|
5580
|
+
* IMPORTANT: For global scope, this returns RELATIVE paths only.
|
|
5581
|
+
* The caller combines with target.root (which is the expanded globalDir).
|
|
5564
5582
|
*/
|
|
5565
5583
|
function resolvePath(filePath, target) {
|
|
5566
|
-
const { platform, platformDir,
|
|
5584
|
+
const { platform, platformDir, type, name, mode } = target;
|
|
5567
5585
|
if (mode === "project") return filePath;
|
|
5568
5586
|
const platformDirPrefix = `${platformDir}/`;
|
|
5569
|
-
if (filePath.startsWith(platformDirPrefix)) return
|
|
5570
|
-
if (!type) return
|
|
5571
|
-
return
|
|
5587
|
+
if (filePath.startsWith(platformDirPrefix)) return filePath.slice(platformDirPrefix.length);
|
|
5588
|
+
if (!type) return filePath;
|
|
5589
|
+
return getRelativeInstallPath({
|
|
5572
5590
|
platform,
|
|
5573
5591
|
type,
|
|
5574
5592
|
name,
|
|
@@ -5578,12 +5596,22 @@ function resolvePath(filePath, target) {
|
|
|
5578
5596
|
function computeDestinationPath(pathInput, target) {
|
|
5579
5597
|
const normalized = normalizeBundlePath(pathInput);
|
|
5580
5598
|
if (!normalized) throw new Error(`Unable to derive destination for ${pathInput}. The computed relative path is empty.`);
|
|
5599
|
+
validateBundlePath(normalized, pathInput);
|
|
5581
5600
|
const resolvedPath = resolvePath(normalized, target);
|
|
5582
5601
|
if (resolvedPath === null) return null;
|
|
5583
5602
|
const destination = resolve(target.root, resolvedPath);
|
|
5584
5603
|
ensureWithinRoot(destination, target.root);
|
|
5585
5604
|
return destination;
|
|
5586
5605
|
}
|
|
5606
|
+
/**
|
|
5607
|
+
* Validate bundle path for dangerous patterns.
|
|
5608
|
+
* Throws if path contains traversal or home directory references.
|
|
5609
|
+
*/
|
|
5610
|
+
function validateBundlePath(normalized, original) {
|
|
5611
|
+
if (normalized.includes("..")) throw new Error(`Refusing to install file with path traversal: ${original}`);
|
|
5612
|
+
if (normalized.startsWith("~")) throw new Error(`Refusing to install file with home directory reference: ${original}`);
|
|
5613
|
+
if (normalized.includes("/~/") || normalized.includes("\\~\\")) throw new Error(`Refusing to install file with embedded home directory reference: ${original}`);
|
|
5614
|
+
}
|
|
5587
5615
|
function parseInput(input, explicitPlatform, explicitVersion) {
|
|
5588
5616
|
let normalized = input.toLowerCase().trim();
|
|
5589
5617
|
let parsedVersion;
|
|
@@ -6563,11 +6591,13 @@ async function buildRegistry(options) {
|
|
|
6563
6591
|
await mkdir(outputDir, { recursive: true });
|
|
6564
6592
|
const indent$1 = compact ? void 0 : 2;
|
|
6565
6593
|
for (const bundle of result.bundles) {
|
|
6566
|
-
const bundleDir = join(outputDir, STATIC_BUNDLE_DIR, bundle.slug, bundle.platform);
|
|
6567
|
-
await mkdir(bundleDir, { recursive: true });
|
|
6568
6594
|
const bundleJson = JSON.stringify(bundle, null, indent$1);
|
|
6569
|
-
|
|
6570
|
-
await
|
|
6595
|
+
const versionedDir = join(outputDir, STATIC_BUNDLE_DIR, bundle.slug, bundle.version);
|
|
6596
|
+
await mkdir(versionedDir, { recursive: true });
|
|
6597
|
+
await writeFile(join(versionedDir, `${bundle.platform}.json`), bundleJson);
|
|
6598
|
+
const latestDir = join(outputDir, STATIC_BUNDLE_DIR, bundle.slug, LATEST_VERSION);
|
|
6599
|
+
await mkdir(latestDir, { recursive: true });
|
|
6600
|
+
await writeFile(join(latestDir, `${bundle.platform}.json`), bundleJson);
|
|
6571
6601
|
}
|
|
6572
6602
|
for (const rule of result.rules) {
|
|
6573
6603
|
const ruleJson = JSON.stringify(rule, null, indent$1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentrules/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"author": "Brian Cheung <bcheung.dev@gmail.com> (https://github.com/bcheung)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://agentrules.directory",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"clean": "rm -rf node_modules dist .turbo"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@agentrules/core": "0.2.
|
|
56
|
+
"@agentrules/core": "0.2.1",
|
|
57
57
|
"@clack/prompts": "^0.11.0",
|
|
58
58
|
"chalk": "^5.4.1",
|
|
59
59
|
"commander": "^12.1.0",
|